diff --git a/src/pagx/svg/SVGImporter.cpp b/src/pagx/svg/SVGImporter.cpp index b351bc25be..8be5fadffb 100644 --- a/src/pagx/svg/SVGImporter.cpp +++ b/src/pagx/svg/SVGImporter.cpp @@ -443,8 +443,10 @@ Layer* SVGParserContext::convertToLayer(const std::shared_ptr& element, auto maskLayer = convertMaskElement(maskIt->second, inheritedStyle); if (maskLayer) { layer->mask = maskLayer; - // SVG masks use luminance by default. - layer->maskType = MaskType::Luminance; + // SVG mask-type property determines how the mask is computed. + // Default is "luminance" (uses luminance of mask content); "alpha" uses alpha channel. + std::string maskTypeStr = getAttribute(maskIt->second, "mask-type"); + layer->maskType = (maskTypeStr == "alpha") ? MaskType::Alpha : MaskType::Luminance; // Add mask layer as invisible layer to the document. _maskLayers.push_back(maskLayer); } @@ -1817,6 +1819,15 @@ void SVGParserContext::addFillStroke(const std::shared_ptr& element, auto strokeNode = _document->makeNode(); + // Determine effective stroke-opacity. Applies to both url() and solid color strokes. + std::string strokeOpacity = getAttribute(element, "stroke-opacity"); + if (strokeOpacity.empty()) { + strokeOpacity = inheritedStyle.strokeOpacity; + } + if (!strokeOpacity.empty()) { + strokeNode->alpha = strtof(strokeOpacity.c_str(), nullptr); + } + if (stroke.compare(0, 4, "url(") == 0) { std::string refId = resolveUrl(stroke); // Use getColorSourceForRef which handles reference counting. @@ -1826,15 +1837,6 @@ void SVGParserContext::addFillStroke(const std::shared_ptr& element, } strokeNode->color = getColorSourceForRef(refId, shapeBounds); } else { - // Determine effective stroke-opacity. - std::string strokeOpacity = getAttribute(element, "stroke-opacity"); - if (strokeOpacity.empty()) { - strokeOpacity = inheritedStyle.strokeOpacity; - } - if (!strokeOpacity.empty()) { - strokeNode->alpha = strtof(strokeOpacity.c_str(), nullptr); - } - // Convert color to SolidColor for PAGX compatibility. // SolidColor is always inlined (no id). Color parsedColor = parseColor(stroke); @@ -2792,6 +2794,12 @@ static bool isSimpleShapeLayer(const Layer* layer, const Element*& outGeometry, if (!layer || layer->contents.size() != 2) { return false; } + // Invisible layers (e.g., mask reference layers) must not be merged with visible layers, + // even when they share the same geometry. Otherwise the visible layer's painter would be + // pulled into the invisible layer and disappear from the final output. + if (!layer->visible) { + return false; + } if (!layer->children.empty() || !layer->filters.empty() || !layer->styles.empty()) { return false; } diff --git a/test/baseline/version.json b/test/baseline/version.json index fb22ceedbc..123c1b662f 100644 --- a/test/baseline/version.json +++ b/test/baseline/version.json @@ -8812,8 +8812,8 @@ "spec_trim_path": "eb9361216", "svg_Baseline": "73083086", "svg_ColorPicker": "eb9361216", - "svg_Guidelines": "14d4d93b7", - "svg_Overview": "451bc13e", + "svg_Guidelines": "cc18a22e", + "svg_Overview": "cc18a22e", "svg_Switch": "73083086", "svg_UIkit": "eb9361216", "svg_blur": "b4fef60e9",