diff options
Diffstat (limited to 'thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp')
-rw-r--r-- | thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp | 61 |
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; } |