tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 165c9f04a88e3d694b4d06f72d2c3492d69f8aec
parent 685b45182095a24670a2e8a7bba4f228d0641e7e
Author: Jonathan Kew <jkew@mozilla.com>
Date:   Sat, 18 Oct 2025 07:26:09 +0000

Bug 1994197 - patch 4 - Also use integer nscoords for textrun ascent/descent metrics and bounding box. r=firefox-svg-reviewers,longsonr

Differential Revision: https://phabricator.services.mozilla.com/D268561

Diffstat:
Mdom/canvas/CanvasRenderingContext2D.cpp | 11+++++++----
Mgfx/src/nsFontMetrics.cpp | 8++++----
Mgfx/thebes/gfxFont.cpp | 90++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Mgfx/thebes/gfxFont.h | 11++++++-----
Mgfx/thebes/gfxGlyphExtents.cpp | 6+++---
Mgfx/thebes/gfxGlyphExtents.h | 10+++++-----
Mgfx/thebes/gfxTextRun.cpp | 12++++++------
Mlayout/generic/nsTextFrame.cpp | 48+++++++++++++++++++++---------------------------
Mlayout/generic/nsTextFrame.h | 2+-
Mlayout/mathml/nsMathMLChar.cpp | 8++++----
Mlayout/svg/SVGTextFrame.cpp | 17+++++++----------
Dtesting/web-platform/meta/css/css-values/ch-unit-012.html.ini | 3---
Mtesting/web-platform/meta/css/css-writing-modes/text-combine-upright-gen-con-001.html.ini | 1+
Mtesting/web-platform/mozilla/meta/mathml/tables/dir-6a.html.ini | 1+
14 files changed, 116 insertions(+), 112 deletions(-)

diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp @@ -4736,8 +4736,10 @@ struct MOZ_STACK_CLASS CanvasBidiProcessor final // this only measures the height; the total width is gotten from the // the return value of ProcessText. if (mDoMeasureBoundingBox) { - textRunMetrics.mBoundingBox.Scale(1.0 / mAppUnitsPerDevPixel); - mBoundingBox = mBoundingBox.Union(textRunMetrics.mBoundingBox); + // The bounding box is tracked in device pixels. + gfxRect bbox = nsLayoutUtils::RectToGfxRect(textRunMetrics.mBoundingBox, + mAppUnitsPerDevPixel); + mBoundingBox = mBoundingBox.Union(bbox); } return textRunMetrics.mAdvanceWidth; @@ -5233,7 +5235,7 @@ UniquePtr<TextMetrics> CanvasRenderingContext2D::DrawOrMeasureText( // based on the text position and advance. if (!doCalculateBounds) { processor.mBoundingBox.width = totalWidth; - processor.mBoundingBox.MoveBy(gfxPoint(processor.mPt.x, processor.mPt.y)); + processor.mBoundingBox.MoveBy(processor.mPt.x, processor.mPt.y); } processor.mPt.x *= processor.mAppUnitsPerDevPixel; @@ -5286,7 +5288,8 @@ UniquePtr<TextMetrics> CanvasRenderingContext2D::DrawOrMeasureText( if (aOp == CanvasRenderingContext2D::TextDrawOperation::FILL && !doCalculateBounds) { - RedrawUser(boundingBox); + RedrawUser(gfxRect(boundingBox.x, boundingBox.y, boundingBox.width, + boundingBox.height)); } else { Redraw(); } diff --git a/gfx/src/nsFontMetrics.cpp b/gfx/src/nsFontMetrics.cpp @@ -399,10 +399,10 @@ static nsBoundingMetrics GetTextBoundingMetrics( gfxTextRun::Metrics theMetrics = textRun->MeasureText( gfxTextRun::Range(0, aLength), aType, aDrawTarget, &provider); - m.leftBearing = NSToCoordFloor(theMetrics.mBoundingBox.X()); - m.rightBearing = NSToCoordCeil(theMetrics.mBoundingBox.XMost()); - m.ascent = NSToCoordCeil(-theMetrics.mBoundingBox.Y()); - m.descent = NSToCoordCeil(theMetrics.mBoundingBox.YMost()); + m.leftBearing = theMetrics.mBoundingBox.X(); + m.rightBearing = theMetrics.mBoundingBox.XMost(); + m.ascent = -theMetrics.mBoundingBox.Y(); + m.descent = theMetrics.mBoundingBox.YMost(); m.width = theMetrics.mAdvanceWidth; } return m; diff --git a/gfx/thebes/gfxFont.cpp b/gfx/thebes/gfxFont.cpp @@ -32,6 +32,7 @@ #include "gfxUserFontSet.h" #include "nsCRT.h" #include "nsContentUtils.h" +#include "nsLayoutUtils.h" #include "nsSpecialCasingData.h" #include "nsTextRunTransformations.h" #include "nsUGenCategory.h" @@ -962,11 +963,11 @@ void gfxFont::RunMetrics::CombineWith(const RunMetrics& aOther, mAscent = std::max(mAscent, aOther.mAscent); mDescent = std::max(mDescent, aOther.mDescent); if (aOtherIsOnLeft) { - mBoundingBox = (mBoundingBox + gfxPoint(aOther.mAdvanceWidth, 0)) + mBoundingBox = (mBoundingBox + nsPoint(aOther.mAdvanceWidth, 0)) .Union(aOther.mBoundingBox); } else { mBoundingBox = - mBoundingBox.Union(aOther.mBoundingBox + gfxPoint(mAdvanceWidth, 0)); + mBoundingBox.Union(aOther.mBoundingBox + nsPoint(mAdvanceWidth, 0)); } mAdvanceWidth = NSCoordSaturatingAdd(mAdvanceWidth, aOther.mAdvanceWidth); } @@ -2874,7 +2875,7 @@ bool gfxFont::HasColorGlyphFor(uint32_t aCh, uint32_t aNextCh) { return false; } -static void UnionRange(gfxFloat aX, gfxFloat* aDestMin, gfxFloat* aDestMax) { +static void UnionRange(nscoord aX, nscoord* aDestMin, nscoord* aDestMax) { *aDestMin = std::min(*aDestMin, aX); *aDestMax = std::max(*aDestMax, aX); } @@ -2895,7 +2896,7 @@ bool gfxFont::IsSpaceGlyphInvisible(DrawTarget* aRefDrawTarget, GetAdjustedSize() >= 1.0) { gfxGlyphExtents* extents = GetOrCreateGlyphExtents(aTextRun->GetAppUnitsPerDevUnit()); - gfxRect glyphExtents; + nsRect glyphExtents; flag = extents->GetTightGlyphExtentsAppUnits( this, aRefDrawTarget, GetSpaceGlyph(), &glyphExtents) && glyphExtents.IsEmpty() @@ -2911,7 +2912,7 @@ bool gfxFont::MeasureGlyphs(const gfxTextRun* aTextRun, uint32_t aStart, DrawTarget* aRefDrawTarget, Spacing* aSpacing, gfxGlyphExtents* aExtents, bool aIsRTL, bool aNeedsGlyphExtents, RunMetrics& aMetrics, - gfxFloat* aAdvanceMin, gfxFloat* aAdvanceMax) { + nscoord* aAdvanceMin, nscoord* aAdvanceMax) { const gfxTextRun::CompressedGlyph* charGlyphs = aTextRun->GetCharacterGlyphs(); uint32_t spaceGlyph = GetSpaceGlyph(); @@ -2935,7 +2936,7 @@ bool gfxFont::MeasureGlyphs(const gfxTextRun* aTextRun, uint32_t aStart, gfxFontEntry::LazyFlag flag = mFontEntry->mSpaceGlyphIsInvisible; if (flag == gfxFontEntry::LazyFlag::Uninitialized && GetAdjustedSize() >= 1.0) { - gfxRect glyphExtents; + nsRect glyphExtents; flag = aExtents->GetTightGlyphExtentsAppUnitsLocked( this, aRefDrawTarget, spaceGlyph, &glyphExtents) && glyphExtents.IsEmpty() @@ -2958,11 +2959,11 @@ bool gfxFont::MeasureGlyphs(const gfxTextRun* aTextRun, uint32_t aStart, UnionRange(x, aAdvanceMin, aAdvanceMax); UnionRange(x + extentsWidth, aAdvanceMin, aAdvanceMax); } else { - gfxRect glyphRect; + nsRect glyphRect; if (!aExtents->GetTightGlyphExtentsAppUnitsLocked( this, aRefDrawTarget, glyphIndex, &glyphRect)) { - glyphRect = gfxRect(0, aMetrics.mBoundingBox.Y(), advance, - aMetrics.mBoundingBox.Height()); + glyphRect = nsRect(0, aMetrics.mBoundingBox.Y(), advance, + aMetrics.mBoundingBox.Height()); } if (aIsRTL) { // In effect, swap left and right sidebearings of the glyph, for @@ -2985,15 +2986,15 @@ bool gfxFont::MeasureGlyphs(const gfxTextRun* aTextRun, uint32_t aStart, uint32_t j; for (j = 0; j < glyphCount; ++j, ++details) { uint32_t glyphIndex = details->mGlyphID; - double advance = details->mAdvance; - gfxRect glyphRect; + nscoord advance = details->mAdvance; + nsRect glyphRect; if (glyphData->IsMissing() || !aExtents->GetTightGlyphExtentsAppUnitsLocked( this, aRefDrawTarget, glyphIndex, &glyphRect)) { // We might have failed to get glyph extents due to // OOM or something - glyphRect = gfxRect(0, -aMetrics.mAscent, advance, - aMetrics.mAscent + aMetrics.mDescent); + glyphRect = nsRect(0, -aMetrics.mAscent, advance, + aMetrics.mAscent + aMetrics.mDescent); } if (aIsRTL) { // Swap left/right sidebearings of the glyph, because we're doing @@ -3054,9 +3055,9 @@ bool gfxFont::MeasureGlyphs(const gfxTextRun* aTextRun, uint32_t aStart, "detailedGlyph record should not be missing!"); uint32_t j; for (j = 0; j < glyphCount; ++j, ++details) { - double advance = details->mAdvance; - gfxRect glyphRect(0, -aMetrics.mAscent, advance, - aMetrics.mAscent + aMetrics.mDescent); + nscoord advance = details->mAdvance; + nsRect glyphRect(0, -aMetrics.mAscent, advance, + aMetrics.mAscent + aMetrics.mDescent); if (aIsRTL) { // Swap left/right sidebearings of the glyph, because we're doing // mirrored measurement. @@ -3124,7 +3125,7 @@ gfxFont::RunMetrics gfxFont::Measure(const gfxTextRun* aTextRun, : nsFontMetrics::eHorizontal; const gfxFont::Metrics& fontMetrics = GetMetrics(orientation); - gfxFloat baselineOffset = 0; + nscoord baselineOffset = 0; if (aTextRun->UseCenterBaseline() && orientation == nsFontMetrics::eHorizontal) { // For a horizontal font being used in vertical writing mode with @@ -3136,23 +3137,25 @@ gfxFont::RunMetrics gfxFont::Measure(const gfxTextRun* aTextRun, // XXX Eventually we should probably use the BASE table, if present. // But it usually isn't, so we need an ad hoc adjustment for now. baselineOffset = - appUnitsPerDevUnit * (fontMetrics.emAscent - fontMetrics.emDescent) / 2; + NSToCoordRound(appUnitsPerDevUnit * + (fontMetrics.emAscent - fontMetrics.emDescent) / 2.0); } RunMetrics metrics; - metrics.mAscent = fontMetrics.maxAscent * appUnitsPerDevUnit; - metrics.mDescent = fontMetrics.maxDescent * appUnitsPerDevUnit; + metrics.mAscent = NSToCoordRound(fontMetrics.maxAscent * appUnitsPerDevUnit); + metrics.mDescent = + NSToCoordRound(fontMetrics.maxDescent * appUnitsPerDevUnit); if (aStart == aEnd) { // exit now before we look at aSpacing[0], which is undefined metrics.mAscent -= baselineOffset; metrics.mDescent += baselineOffset; metrics.mBoundingBox = - gfxRect(0, -metrics.mAscent, 0, metrics.mAscent + metrics.mDescent); + nsRect(0, -metrics.mAscent, 0, metrics.mAscent + metrics.mDescent); return metrics; } - gfxFloat advanceMin = 0, advanceMax = 0; + nscoord advanceMin = 0, advanceMax = 0; bool isRTL = aTextRun->IsRightToLeft(); bool needsGlyphExtents = NeedsGlyphExtents(this, aTextRun); gfxGlyphExtents* extents = @@ -3177,8 +3180,8 @@ gfxFont::RunMetrics gfxFont::Measure(const gfxTextRun* aTextRun, metrics.mBoundingBox.SetEmpty(); } else if (aBoundingBoxType == LOOSE_INK_EXTENTS) { UnionRange(metrics.mAdvanceWidth, &advanceMin, &advanceMax); - gfxRect fontBox(advanceMin, -metrics.mAscent, advanceMax - advanceMin, - metrics.mAscent + metrics.mDescent); + nsRect fontBox(advanceMin, -metrics.mAscent, advanceMax - advanceMin, + metrics.mAscent + metrics.mDescent); metrics.mBoundingBox = metrics.mBoundingBox.Union(fontBox); } @@ -3209,9 +3212,10 @@ gfxFont::RunMetrics gfxFont::Measure(const gfxTextRun* aTextRun, extendRightEdge = skew < 0.0 ? ceil(-skew * metrics.mBoundingBox.YMost()) : ceil(skew * -metrics.mBoundingBox.Y()); } - metrics.mBoundingBox.SetWidth(metrics.mBoundingBox.Width() + - extendLeftEdge + extendRightEdge); - metrics.mBoundingBox.MoveByX(-extendLeftEdge); + metrics.mBoundingBox.SetWidth( + metrics.mBoundingBox.Width() + + NSToCoordRound(extendLeftEdge + extendRightEdge)); + metrics.mBoundingBox.MoveByX(NSToCoordRound(-extendLeftEdge)); } if (baselineOffset != 0) { @@ -4111,16 +4115,27 @@ gfxGlyphExtents* gfxFont::GetOrCreateGlyphExtents(int32_t aAppUnitsPerDevUnit) { return glyphExtents; } +// Helper to convert device-pixel bounds to nsRect using aAppPerDev factor. +// Note: not using nsLayoutUtils::RoundGfxRectToAppRect here because it +// has different rounding behavior (using Rect::ScaleRoundOut rather than +// rounding the individual fields), which affects MathML glyph placement. +template <class T> +static inline nsRect ToAppRect(const T& aBounds, int32_t aAppPerDev) { + return nsRect(NSToCoordRound(aBounds.X() * aAppPerDev), + NSToCoordRound(aBounds.Y() * aAppPerDev), + NSToCoordRound(aBounds.Width() * aAppPerDev), + NSToCoordRound(aBounds.Height() * aAppPerDev)); +} + void gfxFont::SetupGlyphExtents(DrawTarget* aDrawTarget, uint32_t aGlyphID, bool aNeedTight, gfxGlyphExtents* aExtents) { + int32_t appUnitsPerDevUnit = aExtents->GetAppUnitsPerDevUnit(); gfxRect svgBounds; if (mFontEntry->TryGetSVGData(this) && mFontEntry->HasSVGGlyph(aGlyphID) && mFontEntry->GetSVGGlyphExtents(aDrawTarget, aGlyphID, GetAdjustedSize(), &svgBounds)) { - gfxFloat d2a = aExtents->GetAppUnitsPerDevUnit(); - aExtents->SetTightGlyphExtents( - aGlyphID, gfxRect(svgBounds.X() * d2a, svgBounds.Y() * d2a, - svgBounds.Width() * d2a, svgBounds.Height() * d2a)); + aExtents->SetTightGlyphExtents(aGlyphID, + ToAppRect(svgBounds, appUnitsPerDevUnit)); return; } @@ -4133,10 +4148,8 @@ void gfxFont::SetupGlyphExtents(DrawTarget* aDrawTarget, uint32_t aGlyphID, mFontEntry->mCOLR, shaper->GetHBFont(), aGlyphID, aDrawTarget, scaledFont, mFUnitsConvFactor); if (!r.IsEmpty()) { - gfxFloat d2a = aExtents->GetAppUnitsPerDevUnit(); - aExtents->SetTightGlyphExtents( - aGlyphID, gfxRect(r.X() * d2a, r.Y() * d2a, r.Width() * d2a, - r.Height() * d2a)); + aExtents->SetTightGlyphExtents(aGlyphID, + ToAppRect(r, appUnitsPerDevUnit)); return; } } @@ -4146,7 +4159,6 @@ void gfxFont::SetupGlyphExtents(DrawTarget* aDrawTarget, uint32_t aGlyphID, GetGlyphBounds(aGlyphID, &bounds, mAntialiasOption == kAntialiasNone); const Metrics& fontMetrics = GetMetrics(nsFontMetrics::eHorizontal); - int32_t appUnitsPerDevUnit = aExtents->GetAppUnitsPerDevUnit(); if (!aNeedTight && bounds.x >= 0.0 && bounds.y >= -fontMetrics.maxAscent && bounds.height + bounds.y <= fontMetrics.maxDescent) { uint32_t appUnitsWidth = @@ -4163,10 +4175,8 @@ void gfxFont::SetupGlyphExtents(DrawTarget* aDrawTarget, uint32_t aGlyphID, } #endif - gfxFloat d2a = appUnitsPerDevUnit; - aExtents->SetTightGlyphExtents( - aGlyphID, gfxRect(bounds.x * d2a, bounds.y * d2a, bounds.width * d2a, - bounds.height * d2a)); + aExtents->SetTightGlyphExtents(aGlyphID, + ToAppRect(bounds, appUnitsPerDevUnit)); } // Try to initialize font metrics by reading sfnt tables directly; diff --git a/gfx/thebes/gfxFont.h b/gfx/thebes/gfxFont.h @@ -1658,8 +1658,9 @@ class gfxFont { nscoord mBefore; nscoord mAfter; }; + /** - * Metrics for a particular string + * Metrics for a particular string. These are in appUnits. */ struct RunMetrics { void CombineWith(const RunMetrics& aOther, bool aOtherIsOnLeft); @@ -1671,8 +1672,8 @@ class gfxFont { nscoord mAdvanceWidth = 0; // For zero-width substrings, these must be zero! - gfxFloat mAscent = 0.0; // always non-negative - gfxFloat mDescent = 0.0; // always non-negative + nscoord mAscent = 0; // always non-negative + nscoord mDescent = 0; // always non-negative // Bounding box that is guaranteed to include everything drawn. // If a tight boundingBox was requested when these metrics were @@ -1680,7 +1681,7 @@ class gfxFont { // "loose" and may be larger than the true bounding box. // Coordinates are relative to the baseline left origin, so typically // mBoundingBox.y == -mAscent - gfxRect mBoundingBox; + nsRect mBoundingBox; }; /** @@ -1956,7 +1957,7 @@ class gfxFont { DrawTarget* aRefDrawTarget, Spacing* aSpacing, gfxGlyphExtents* aExtents, bool aIsRTL, bool aNeedsGlyphExtents, RunMetrics& aMetrics, - gfxFloat* aAdvanceMin, gfxFloat* aAdvanceMax); + nscoord* aAdvanceMin, nscoord* aAdvanceMax); bool MeasureGlyphs(const gfxTextRun* aTextRun, uint32_t aStart, uint32_t aEnd, BoundingBoxType aBoundingBoxType, diff --git a/gfx/thebes/gfxGlyphExtents.cpp b/gfx/thebes/gfxGlyphExtents.cpp @@ -35,7 +35,7 @@ gfxGlyphExtents::~gfxGlyphExtents() { bool gfxGlyphExtents::GetTightGlyphExtentsAppUnitsLocked( gfxFont* aFont, DrawTarget* aDrawTarget, uint32_t aGlyphID, - gfxRect* aExtents) { + nsRect* aExtents) { HashEntry* entry = mTightGlyphExtents.GetEntry(aGlyphID); if (!entry) { // Some functions higher up in the call chain deliberately pass in a @@ -64,7 +64,7 @@ bool gfxGlyphExtents::GetTightGlyphExtentsAppUnitsLocked( } } - *aExtents = gfxRect(entry->x, entry->y, entry->width, entry->height); + *aExtents = nsRect(entry->x, entry->y, entry->width, entry->height); return true; } @@ -127,7 +127,7 @@ void gfxGlyphExtents::GlyphWidths::Set(uint32_t aGlyphID, uint16_t aWidth) { } void gfxGlyphExtents::SetTightGlyphExtents(uint32_t aGlyphID, - const gfxRect& aExtentsAppUnits) { + const nsRect& aExtentsAppUnits) { AutoWriteLock lock(mLock); HashEntry* entry = mTightGlyphExtents.PutEntry(aGlyphID); if (!entry) { diff --git a/gfx/thebes/gfxGlyphExtents.h b/gfx/thebes/gfxGlyphExtents.h @@ -77,10 +77,10 @@ class gfxGlyphExtents { // and extents were not (successfully) prefetched. bool GetTightGlyphExtentsAppUnitsLocked(gfxFont* aFont, DrawTarget* aDrawTarget, - uint32_t aGlyphID, gfxRect* aExtents) + uint32_t aGlyphID, nsRect* aExtents) MOZ_REQUIRES_SHARED(mLock); bool GetTightGlyphExtentsAppUnits(gfxFont* aFont, DrawTarget* aDrawTarget, - uint32_t aGlyphID, gfxRect* aExtents) { + uint32_t aGlyphID, nsRect* aExtents) { mozilla::AutoReadLock lock(mLock); return GetTightGlyphExtentsAppUnitsLocked(aFont, aDrawTarget, aGlyphID, aExtents); @@ -90,7 +90,7 @@ class gfxGlyphExtents { mozilla::AutoWriteLock lock(mLock); mContainedGlyphWidths.Set(aGlyphID, aWidth); } - void SetTightGlyphExtents(uint32_t aGlyphID, const gfxRect& aExtentsAppUnits); + void SetTightGlyphExtents(uint32_t aGlyphID, const nsRect& aExtentsAppUnits); int32_t GetAppUnitsPerDevUnit() { return mAppUnitsPerDevUnit; } @@ -103,7 +103,7 @@ class gfxGlyphExtents { // When constructing a new entry in the hashtable, we'll leave this // blank. The caller of Put() will fill this in. explicit HashEntry(KeyTypePointer aPtr) - : nsUint32HashKey(aPtr), x(0.0), y(0.0), width(0.0), height(0.0) {} + : nsUint32HashKey(aPtr), x(0), y(0), width(0), height(0) {} HashEntry(HashEntry&& aOther) : nsUint32HashKey(std::move(aOther)), x(aOther.x), @@ -111,7 +111,7 @@ class gfxGlyphExtents { width(aOther.width), height(aOther.height) {} - float x, y, width, height; + nscoord x, y, width, height; }; enum { diff --git a/gfx/thebes/gfxTextRun.cpp b/gfx/thebes/gfxTextRun.cpp @@ -29,6 +29,7 @@ #include "mozilla/StaticPresData.h" #include "mozilla/UniquePtr.h" #include "mozilla/Unused.h" +#include "nsLayoutUtils.h" #include "nsStyleConsts.h" #include "nsStyleUtil.h" #include "nsUnicodeProperties.h" @@ -552,12 +553,11 @@ struct MOZ_STACK_CLASS BufferAlphaColor { ~BufferAlphaColor() = default; - void PushSolidColor(const gfxRect& aBounds, const DeviceColor& aAlphaColor, + void PushSolidColor(const nsRect& aBounds, const DeviceColor& aAlphaColor, uint32_t appsPerDevUnit) { mContext->Save(); - mContext->SnappedClip(gfxRect( - aBounds.X() / appsPerDevUnit, aBounds.Y() / appsPerDevUnit, - aBounds.Width() / appsPerDevUnit, aBounds.Height() / appsPerDevUnit)); + mContext->SnappedClip( + nsLayoutUtils::RectToGfxRect(aBounds, appsPerDevUnit)); mContext->SetDeviceColor( DeviceColor(aAlphaColor.r, aAlphaColor.g, aAlphaColor.b)); mContext->PushGroupForBlendBack(gfxContentType::COLOR_ALPHA, aAlphaColor.a); @@ -676,9 +676,9 @@ void gfxTextRun::Draw(const Range aRange, const gfx::Point aPt, aParams.provider); if (IsRightToLeft()) { metrics.mBoundingBox.MoveBy( - gfxPoint(aPt.x - metrics.mAdvanceWidth, aPt.y)); + nsPoint(aPt.x - metrics.mAdvanceWidth, aPt.y)); } else { - metrics.mBoundingBox.MoveBy(gfxPoint(aPt.x, aPt.y)); + metrics.mBoundingBox.MoveBy(nsPoint(aPt.x, aPt.y)); } gotMetrics = true; } diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp @@ -6570,7 +6570,8 @@ static void AddHyphenToMetrics(nsTextFrame* aTextFrame, bool aIsRightToLeft, void nsTextFrame::PaintOneShadow(const PaintShadowParams& aParams, const StyleSimpleShadow& aShadowDetails, - gfxRect& aBoundingBox, uint32_t aBlurFlags) { + const gfxRect& aBoundingBox, + uint32_t aBlurFlags) { AUTO_PROFILER_LABEL("nsTextFrame::PaintOneShadow", GRAPHICS); nsPoint shadowOffset(aShadowDetails.horizontal.ToAppUnits(), @@ -7374,8 +7375,8 @@ void nsTextFrame::PaintShadows(Span<const StyleSimpleShadow> aShadows, aParams.context->GetDrawTarget()); } // Add bounds of text decorations - gfxRect decorationRect(0, -shadowMetrics.mAscent, shadowMetrics.mAdvanceWidth, - shadowMetrics.mAscent + shadowMetrics.mDescent); + nsRect decorationRect(0, -shadowMetrics.mAscent, shadowMetrics.mAdvanceWidth, + shadowMetrics.mAscent + shadowMetrics.mDescent); shadowMetrics.mBoundingBox.UnionRect(shadowMetrics.mBoundingBox, decorationRect); @@ -7399,7 +7400,12 @@ void nsTextFrame::PaintShadows(Span<const StyleSimpleShadow> aShadows, } for (const auto& shadow : Reversed(aShadows)) { - PaintOneShadow(aParams, shadow, shadowMetrics.mBoundingBox, blurFlags); + PaintOneShadow( + aParams, shadow, + gfxRect(shadowMetrics.mBoundingBox.x, shadowMetrics.mBoundingBox.y, + shadowMetrics.mBoundingBox.width, + shadowMetrics.mBoundingBox.height), + blurFlags); } } @@ -9874,15 +9880,6 @@ nsIFrame::SizeComputationResult nsTextFrame::ComputeSize( AspectRatioUsage::None}; } -static nsRect RoundOut(const gfxRect& aRect) { - nsRect r; - r.x = NSToCoordFloor(aRect.X()); - r.y = NSToCoordFloor(aRect.Y()); - r.width = NSToCoordCeil(aRect.XMost()) - r.x; - r.height = NSToCoordCeil(aRect.YMost()) - r.y; - return r; -} - nsRect nsTextFrame::ComputeTightBounds(DrawTarget* aDrawTarget) const { if (Style()->HasTextDecorationLines() || HasAnyStateBits(TEXT_HYPHEN_BREAK)) { // This is conservative, but OK. @@ -9908,7 +9905,7 @@ nsRect nsTextFrame::ComputeTightBounds(DrawTarget* aDrawTarget) const { } // mAscent should be the same as metrics.mAscent, but it's what we use to // paint so that's the one we'll use. - nsRect boundingBox = RoundOut(metrics.mBoundingBox); + nsRect boundingBox = metrics.mBoundingBox; boundingBox += nsPoint(0, mAscent); if (mTextRun->IsVertical()) { // Swap line-relative textMetrics dimensions to physical coordinates. @@ -9933,8 +9930,8 @@ nsresult nsTextFrame::GetPrefWidthTightBounds(gfxContext* aContext, nscoord* aX, ComputeTransformedRange(provider), gfxFont::TIGHT_HINTED_OUTLINE_EXTENTS, aContext->GetDrawTarget(), &provider); // Round it like nsTextFrame::ComputeTightBounds() to ensure consistency. - *aX = NSToCoordFloor(metrics.mBoundingBox.x); - *aXMost = NSToCoordCeil(metrics.mBoundingBox.XMost()); + *aX = metrics.mBoundingBox.x; + *aXMost = metrics.mBoundingBox.XMost(); return NS_OK; } @@ -10687,10 +10684,8 @@ void nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth, // first-letter frames should use the tight bounding box metrics for // ascent/descent for good drop-cap effects if (HasAnyStateBits(TEXT_FIRST_LETTER)) { - textMetrics.mAscent = - std::max(gfxFloat(0.0), -textMetrics.mBoundingBox.Y()); - textMetrics.mDescent = - std::max(gfxFloat(0.0), textMetrics.mBoundingBox.YMost()); + textMetrics.mAscent = std::max(0, -textMetrics.mBoundingBox.Y()); + textMetrics.mDescent = std::max(0, textMetrics.mBoundingBox.YMost()); } // Setup metrics for caller @@ -10708,8 +10703,8 @@ void nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth, finalSize.BSize(wm) = 0; fontBaseline = 0; } else if (boundingBoxType != gfxFont::LOOSE_INK_EXTENTS) { - fontBaseline = NSToCoordCeil(textMetrics.mAscent); - const auto size = fontBaseline + NSToCoordCeil(textMetrics.mDescent); + fontBaseline = textMetrics.mAscent; + const auto size = fontBaseline + textMetrics.mDescent; // Use actual text metrics for floating first letter frame. aMetrics.SetBlockStartAscent(wm.IsAlphabeticalBaseline() ? fontBaseline : size / 2); @@ -10723,10 +10718,9 @@ void nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth, wm.IsLineInverted() ? fm->MaxDescent() : fm->MaxAscent(); nscoord fontDescent = wm.IsLineInverted() ? fm->MaxAscent() : fm->MaxDescent(); - fontBaseline = std::max(NSToCoordCeil(textMetrics.mAscent), fontAscent); + fontBaseline = std::max(textMetrics.mAscent, fontAscent); const auto size = - fontBaseline + - std::max(NSToCoordCeil(textMetrics.mDescent), fontDescent); + fontBaseline + std::max(textMetrics.mDescent, fontDescent); aMetrics.SetBlockStartAscent(wm.IsAlphabeticalBaseline() ? fontBaseline : size / 2); finalSize.BSize(wm) = size; @@ -10822,7 +10816,7 @@ void nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth, mAscent = fontBaseline; // Handle text that runs outside its normal bounds. - nsRect boundingBox = RoundOut(textMetrics.mBoundingBox); + nsRect boundingBox = textMetrics.mBoundingBox; if (mTextRun->IsVertical()) { // Swap line-relative textMetrics dimensions to physical coordinates. std::swap(boundingBox.x, boundingBox.y); @@ -11080,7 +11074,7 @@ OverflowAreas nsTextFrame::RecomputeOverflow(nsIFrame* aBlockFrame, if (GetWritingMode().IsLineInverted()) { textMetrics.mBoundingBox.y = -textMetrics.mBoundingBox.YMost(); } - nsRect boundingBox = RoundOut(textMetrics.mBoundingBox); + nsRect boundingBox = textMetrics.mBoundingBox; boundingBox += nsPoint(0, mAscent); if (mTextRun->IsVertical()) { // Swap line-relative textMetrics dimensions to physical coordinates. diff --git a/layout/generic/nsTextFrame.h b/layout/generic/nsTextFrame.h @@ -937,7 +937,7 @@ class nsTextFrame : public nsIFrame { void PaintOneShadow(const PaintShadowParams& aParams, const mozilla::StyleSimpleShadow& aShadowDetails, - gfxRect& aBoundingBox, uint32_t aBlurFlags); + const gfxRect& aBoundingBox, uint32_t aBlurFlags); void PaintShadows(mozilla::Span<const mozilla::StyleSimpleShadow>, const PaintShadowParams& aParams); diff --git a/layout/mathml/nsMathMLChar.cpp b/layout/mathml/nsMathMLChar.cpp @@ -885,10 +885,10 @@ static nsBoundingMetrics MeasureTextRun(DrawTarget* aDrawTarget, aTextRun->MeasureText(gfxFont::TIGHT_HINTED_OUTLINE_EXTENTS, aDrawTarget); nsBoundingMetrics bm; - bm.leftBearing = NSToCoordFloor(metrics.mBoundingBox.X()); - bm.rightBearing = NSToCoordCeil(metrics.mBoundingBox.XMost()); - bm.ascent = NSToCoordCeil(-metrics.mBoundingBox.Y()); - bm.descent = NSToCoordCeil(metrics.mBoundingBox.YMost()); + bm.leftBearing = metrics.mBoundingBox.X(); + bm.rightBearing = metrics.mBoundingBox.XMost(); + bm.ascent = -metrics.mBoundingBox.Y(); + bm.descent = metrics.mBoundingBox.YMost(); bm.width = metrics.mAdvanceWidth; return bm; diff --git a/layout/svg/SVGTextFrame.cpp b/layout/svg/SVGTextFrame.cpp @@ -850,19 +850,18 @@ SVGBBox TextRenderedRun::GetRunUserSpaceRect(nsPresContext* aContext, gfxTextRun::Metrics metrics = textRun->MeasureText( range, gfxFont::LOOSE_INK_EXTENTS, nullptr, &provider); // Make sure it includes the font-box. - gfxRect fontBox(0, -metrics.mAscent, metrics.mAdvanceWidth, - metrics.mAscent + metrics.mDescent); + nsRect fontBox(0, -metrics.mAscent, metrics.mAdvanceWidth, + metrics.mAscent + metrics.mDescent); metrics.mBoundingBox.UnionRect(metrics.mBoundingBox, fontBox); // Determine the rectangle that covers the rendered run's fill, // taking into account the measured overflow due to decorations. - nscoord baseline = - NSToCoordRoundWithClamp(metrics.mBoundingBox.y + metrics.mAscent); - gfxFloat x, width; + nscoord baseline = metrics.mBoundingBox.y + metrics.mAscent; + nscoord x, width; if (aFlags & eNoHorizontalOverflow) { - x = 0.0; + x = 0; width = textRun->GetAdvanceWidth(range, &provider); - if (width < 0.0) { + if (width < 0) { x = width; width = -width; } @@ -870,9 +869,7 @@ SVGBBox TextRenderedRun::GetRunUserSpaceRect(nsPresContext* aContext, x = metrics.mBoundingBox.x; width = metrics.mBoundingBox.width; } - nsRect fillInAppUnits(NSToCoordRoundWithClamp(x), baseline, - NSToCoordRoundWithClamp(width), - NSToCoordRoundWithClamp(metrics.mBoundingBox.height)); + nsRect fillInAppUnits(x, baseline, width, metrics.mBoundingBox.height); fillInAppUnits.Inflate(inkOverflow); if (textRun->IsVertical()) { // Swap line-relative textMetrics dimensions to physical coordinates. diff --git a/testing/web-platform/meta/css/css-values/ch-unit-012.html.ini b/testing/web-platform/meta/css/css-values/ch-unit-012.html.ini @@ -1,3 +0,0 @@ -[ch-unit-012.html] - expected: - if (os == "android") and swgl: FAIL diff --git a/testing/web-platform/meta/css/css-writing-modes/text-combine-upright-gen-con-001.html.ini b/testing/web-platform/meta/css/css-writing-modes/text-combine-upright-gen-con-001.html.ini @@ -2,5 +2,6 @@ fuzzy: if os == "linux": maxDifference=0-255;totalPixels=0-60 if os == "android": maxDifference=0-92;totalPixels=0-93 + if os == "win": maxDifference=0-72;totalPixels=0-67 expected: PASS diff --git a/testing/web-platform/mozilla/meta/mathml/tables/dir-6a.html.ini b/testing/web-platform/mozilla/meta/mathml/tables/dir-6a.html.ini @@ -1,3 +1,4 @@ [dir-6a.html] fuzzy: if (os == "mac"): maxDifference=0-135;totalPixels=0-56 + if (os == "win"): maxDifference=0-92;totalPixels=0-41