Bug 1668844 - Fix markerUnits=strokeWidth combined with non-scaling-stroke r=emilio

Differential Revision: https://phabricator.services.mozilla.com/D92242
This commit is contained in:
longsonr 2020-10-03 04:32:21 +00:00
Родитель 2408479ab7
Коммит da8bcd93da
3 изменённых файлов: 48 добавлений и 21 удалений

Просмотреть файл

@ -744,29 +744,52 @@ void SVGGeometryFrame::PaintMarkers(gfxContext& aContext,
const gfxMatrix& aTransform, const gfxMatrix& aTransform,
imgDrawingParams& aImgParams) { imgDrawingParams& aImgParams) {
auto* element = static_cast<SVGGeometryElement*>(GetContent()); auto* element = static_cast<SVGGeometryElement*>(GetContent());
if (!element->IsMarkable()) {
if (element->IsMarkable()) { return;
SVGMarkerFrame* markerFrames[SVGMark::eTypeCount]; }
if (SVGObserverUtils::GetAndObserveMarkers(this, &markerFrames)) { SVGMarkerFrame* markerFrames[SVGMark::eTypeCount];
nsTArray<SVGMark> marks; if (!SVGObserverUtils::GetAndObserveMarkers(this, &markerFrames)) {
element->GetMarkPoints(&marks); return;
if (uint32_t num = marks.Length()) { }
SVGContextPaint* contextPaint = nsTArray<SVGMark> marks;
SVGContextPaint::GetContextPaint(GetContent()); element->GetMarkPoints(&marks);
float strokeWidth = SVGUtils::GetStrokeWidth(this, contextPaint); if (marks.IsEmpty()) {
for (uint32_t i = 0; i < num; i++) { return;
const SVGMark& mark = marks[i]; }
SVGMarkerFrame* frame = markerFrames[mark.type]; float strokeWidth = GetStrokeWidthForMarkers();
if (frame) { for (const SVGMark& mark : marks) {
frame->PaintMark(aContext, aTransform, this, mark, strokeWidth, if (auto* frame = markerFrames[mark.type]) {
aImgParams); frame->PaintMark(aContext, aTransform, this, mark, strokeWidth,
} aImgParams);
}
}
} }
} }
} }
float SVGGeometryFrame::GetStrokeWidthForMarkers() {
float strokeWidth = SVGUtils::GetStrokeWidth(
this, SVGContextPaint::GetContextPaint(GetContent()));
gfxMatrix userToOuterSVG;
if (SVGUtils::GetNonScalingStrokeTransform(this, &userToOuterSVG)) {
// We're not interested in any translation here so we can treat this as
// Singular Value Decomposition (SVD) of a 2 x 2 matrix. That would give us
// sx and sy values as the X and Y scales. The value we want is the XY
// scale i.e. the normalised hypotenuse, which is sqrt(sx^2 + sy^2) /
// sqrt(2). If we use the formulae from
// https://scicomp.stackexchange.com/a/14103, we discover that the
// normalised hypotenuse is simply the square root of the sum of the squares
// of all the 2D matrix elements divided by sqrt(2).
//
// Note that this may need adjusting to support 3D transforms properly.
strokeWidth /= float(sqrt(userToOuterSVG._11 * userToOuterSVG._11 +
userToOuterSVG._12 * userToOuterSVG._12 +
userToOuterSVG._21 * userToOuterSVG._21 +
userToOuterSVG._22 * userToOuterSVG._22) /
M_SQRT2);
}
return strokeWidth;
}
uint16_t SVGGeometryFrame::GetHitTestFlags() { uint16_t SVGGeometryFrame::GetHitTestFlags() {
return SVGUtils::GetGeometryHitTestFlags(this); return SVGUtils::GetGeometryHitTestFlags(this);
} }

Просмотреть файл

@ -137,6 +137,12 @@ class SVGGeometryFrame : public nsIFrame, public ISVGDisplayableFrame {
*/ */
void PaintMarkers(gfxContext& aContext, const gfxMatrix& aTransform, void PaintMarkers(gfxContext& aContext, const gfxMatrix& aTransform,
imgDrawingParams& aImgParams); imgDrawingParams& aImgParams);
/*
* Get the stroke width that markers should use, accounting for
* non-scaling stroke.
*/
float GetStrokeWidthForMarkers();
}; };
//---------------------------------------------------------------------- //----------------------------------------------------------------------

Просмотреть файл

@ -1,2 +0,0 @@
[marker-units-strokewidth-non-scaling-stroke.svg]
expected: FAIL