commit d4927b88663c8cfac60eb8a3c5fddbe843ce4af4
parent c2168d7fb8942ae962c2464c1ca6199b5370bedb
Author: Jonathan Kew <jkew@mozilla.com>
Date: Fri, 17 Oct 2025 21:48:29 +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:
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-70;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