Bug 1769965 - Convert stroke properties (width, dashes) to device pixels when passing them to the gfxContext. r=emilio

This makes the context-value option for stroke width and dash properties in SVG glyphs work
consistently in non-1.0 devicePixelRatio situations (e.g. browser zoom, high-dpi displays).

Differential Revision: https://phabricator.services.mozilla.com/D146886
This commit is contained in:
Jonathan Kew 2022-05-21 15:42:16 +00:00
parent a3577de2cd
commit ef035224b2
3 changed files with 16 additions and 10 deletions

View File

@ -411,16 +411,17 @@ AntialiasMode gfxContext::CurrentAntialiasMode() const {
return CurrentState().aaMode;
}
void gfxContext::SetDash(const Float* dashes, int ndash, Float offset) {
void gfxContext::SetDash(const Float* dashes, int ndash, Float offset,
Float devPxScale) {
CURRENTSTATE_CHANGED()
AzureState& state = CurrentState();
state.dashPattern.SetLength(ndash);
for (int i = 0; i < ndash; i++) {
state.dashPattern[i] = dashes[i];
state.dashPattern[i] = dashes[i] * devPxScale;
}
state.strokeOptions.mDashLength = ndash;
state.strokeOptions.mDashOffset = offset;
state.strokeOptions.mDashOffset = offset * devPxScale;
state.strokeOptions.mDashPattern =
ndash ? state.dashPattern.Elements() : nullptr;
}

View File

@ -309,7 +309,11 @@ class gfxContext final {
** Line Properties
**/
void SetDash(const Float* dashes, int ndash, Float offset);
// Set the dash pattern, applying devPxScale to convert passed-in lengths
// to device pixels (used by the SVGUtils::SetupStrokeGeometry caller,
// which has the desired dash pattern in CSS px).
void SetDash(const Float* dashes, int ndash, Float offset, Float devPxScale);
// Return true if dashing is set, false if it's not enabled or the
// context is in an error state. |offset| can be nullptr to mean
// "don't care".

View File

@ -1524,12 +1524,16 @@ void SVGUtils::SetupStrokeGeometry(nsIFrame* aFrame, gfxContext* aContext,
return;
}
aContext->SetLineWidth(strokeOptions.mLineWidth);
// SVGContentUtils::GetStrokeOptions gets the stroke options in CSS px;
// convert to device pixels for gfxContext.
float devPxPerCSSPx = aFrame->PresContext()->CSSToDevPixelScale().scale;
aContext->SetLineWidth(strokeOptions.mLineWidth * devPxPerCSSPx);
aContext->SetLineCap(strokeOptions.mLineCap);
aContext->SetMiterLimit(strokeOptions.mMiterLimit);
aContext->SetLineJoin(strokeOptions.mLineJoin);
aContext->SetDash(strokeOptions.mDashPattern, strokeOptions.mDashLength,
strokeOptions.mDashOffset);
strokeOptions.mDashOffset, devPxPerCSSPx);
}
uint16_t SVGUtils::GetGeometryHitTestFlags(nsIFrame* aFrame) {
@ -1647,10 +1651,7 @@ nsRect SVGUtils::ToCanvasBounds(const gfxRect& aUserspaceRect,
}
gfxMatrix SVGUtils::GetCSSPxToDevPxMatrix(nsIFrame* aNonSVGFrame) {
int32_t appUnitsPerDevPixel =
aNonSVGFrame->PresContext()->AppUnitsPerDevPixel();
float devPxPerCSSPx =
1 / nsPresContext::AppUnitsToFloatCSSPixels(appUnitsPerDevPixel);
float devPxPerCSSPx = aNonSVGFrame->PresContext()->CSSToDevPixelScale().scale;
return gfxMatrix(devPxPerCSSPx, 0.0, 0.0, devPxPerCSSPx, 0.0, 0.0);
}