summaryrefslogtreecommitdiff
path: root/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp')
-rw-r--r--thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp61
1 files changed, 46 insertions, 15 deletions
diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp b/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp
index 254ee2d008..c5e5df893e 100644
--- a/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp
+++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -61,12 +61,6 @@
/* Internal Class Implementation */
/************************************************************************/
-struct Box
-{
- float x, y, w, h;
-};
-
-
static bool _appendShape(SvgNode* node, Shape* shape, const Box& vBox, const string& svgPath);
static unique_ptr<Scene> _sceneBuildHelper(const SvgNode* node, const Box& vBox, const string& svgPath, bool mask, int depth, bool* isMaskWhite = nullptr);
@@ -255,7 +249,6 @@ static void _applyComposition(Paint* paint, const SvgNode* node, const Box& vBox
node->style->clipPath.applying = true;
auto comp = Shape::gen();
- if (node->transform) comp->transform(*node->transform);
auto child = compNode->child.data;
auto valid = false; //Composite only when valid shapes are existed
@@ -264,6 +257,12 @@ static void _applyComposition(Paint* paint, const SvgNode* node, const Box& vBox
if (_appendChildShape(*child, comp.get(), vBox, svgPath)) valid = true;
}
+ if (node->transform) {
+ auto m = comp->transform();
+ m = mathMultiply(node->transform, &m);
+ comp->transform(m);
+ }
+
if (valid) paint->composite(move(comp), CompositeMethod::ClipPath);
node->style->clipPath.applying = false;
@@ -331,6 +330,8 @@ static void _applyProperty(SvgNode* node, Shape* vg, const Box& vBox, const stri
//Apply the fill rule
vg->fill((tvg::FillRule)style->fill.fillRule);
+ //Rendering order
+ vg->order(!style->paintOrder);
//Apply node opacity
if (style->opacity < 255) vg->opacity(style->opacity);
@@ -444,9 +445,11 @@ enum class imageMimeTypeEncoding
base64 = 0x1,
utf8 = 0x2
};
+
constexpr imageMimeTypeEncoding operator|(imageMimeTypeEncoding a, imageMimeTypeEncoding b) {
return static_cast<imageMimeTypeEncoding>(static_cast<int>(a) | static_cast<int>(b));
}
+
constexpr bool operator&(imageMimeTypeEncoding a, imageMimeTypeEncoding b) {
return (static_cast<int>(a) & static_cast<int>(b));
}
@@ -755,24 +758,45 @@ static unique_ptr<Scene> _sceneBuildHelper(const SvgNode* node, const Box& vBox,
}
+static void _updateInvalidViewSize(const Scene* scene, Box& vBox, float& w, float& h, SvgViewFlag viewFlag)
+{
+ bool validWidth = (viewFlag & SvgViewFlag::Width);
+ bool validHeight = (viewFlag & SvgViewFlag::Height);
+
+ float x, y;
+ scene->bounds(&x, &y, &vBox.w, &vBox.h, false);
+ if (!validWidth && !validHeight) {
+ vBox.x = x;
+ vBox.y = y;
+ } else {
+ if (validWidth) vBox.w = w;
+ if (validHeight) vBox.h = h;
+ }
+
+ //the size would have 1x1 or percentage values.
+ if (!validWidth) w *= vBox.w;
+ if (!validHeight) h *= vBox.h;
+}
+
/************************************************************************/
/* External Class Implementation */
/************************************************************************/
-unique_ptr<Scene> svgSceneBuild(SvgNode* node, float vx, float vy, float vw, float vh, float w, float h, AspectRatioAlign align, AspectRatioMeetOrSlice meetOrSlice, const string& svgPath)
+unique_ptr<Scene> svgSceneBuild(SvgLoaderData& loaderData, Box vBox, float w, float h, AspectRatioAlign align, AspectRatioMeetOrSlice meetOrSlice, const string& svgPath, SvgViewFlag viewFlag)
{
//TODO: aspect ratio is valid only if viewBox was set
- if (!node || (node->type != SvgNodeType::Doc)) return nullptr;
+ if (!loaderData.doc || (loaderData.doc->type != SvgNodeType::Doc)) return nullptr;
- Box vBox = {vx, vy, vw, vh};
- auto docNode = _sceneBuildHelper(node, vBox, svgPath, false, 0);
+ auto docNode = _sceneBuildHelper(loaderData.doc, vBox, svgPath, false, 0);
- if (!mathEqual(w, vw) || !mathEqual(h, vh)) {
+ if (!(viewFlag & SvgViewFlag::Viewbox)) _updateInvalidViewSize(docNode.get(), vBox, w, h, viewFlag);
+
+ if (!mathEqual(w, vBox.w) || !mathEqual(h, vBox.h)) {
Matrix m = _calculateAspectRatioMatrix(align, meetOrSlice, w, h, vBox);
docNode->transform(m);
- } else if (!mathZero(vx) || !mathZero(vy)) {
- docNode->translate(-vx, -vy);
+ } else if (!mathZero(vBox.x) || !mathZero(vBox.y)) {
+ docNode->translate(-vBox.x, -vBox.y);
}
auto viewBoxClip = Shape::gen();
@@ -786,5 +810,12 @@ unique_ptr<Scene> svgSceneBuild(SvgNode* node, float vx, float vy, float vw, flo
auto root = Scene::gen();
root->push(move(compositeLayer));
+ loaderData.doc->node.doc.vx = vBox.x;
+ loaderData.doc->node.doc.vy = vBox.y;
+ loaderData.doc->node.doc.vw = vBox.w;
+ loaderData.doc->node.doc.vh = vBox.h;
+ loaderData.doc->node.doc.w = w;
+ loaderData.doc->node.doc.h = h;
+
return root;
}