Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 19 additions & 11 deletions src/pagx/svg/SVGImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -443,8 +443,10 @@ Layer* SVGParserContext::convertToLayer(const std::shared_ptr<DOMNode>& 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);
}
Expand Down Expand Up @@ -1817,6 +1819,15 @@ void SVGParserContext::addFillStroke(const std::shared_ptr<DOMNode>& element,

auto strokeNode = _document->makeNode<Stroke>();

// 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.
Expand All @@ -1826,15 +1837,6 @@ void SVGParserContext::addFillStroke(const std::shared_ptr<DOMNode>& 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);
Expand Down Expand Up @@ -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;
}
Expand Down
4 changes: 2 additions & 2 deletions test/baseline/version.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Loading