commit 2d8fef47e55b10b5ecd2cc151a72c9d632b43773
parent 271b5ba4ac199f3b2981fc9f0a62bc4ba9da31d5
Author: longsonr <longsonr@gmail.com>
Date: Tue, 25 Nov 2025 12:05:28 +0000
Bug 2000458 - getExtentOfChar should take dominant-baseline into account r=jwatt
Differential Revision: https://phabricator.services.mozilla.com/D273725
Diffstat:
2 files changed, 23 insertions(+), 4 deletions(-)
diff --git a/layout/svg/SVGTextFrame.cpp b/layout/svg/SVGTextFrame.cpp
@@ -259,7 +259,8 @@ static bool IsGlyphPositioningAttribute(nsAtom* aAttribute) {
* @param aTextRun The text run of aFrame.
* @param aDominantBaseline The dominant-baseline value to use.
*/
-static nscoord GetBaselinePosition(nsTextFrame* aFrame, gfxTextRun* aTextRun,
+static nscoord GetBaselinePosition(nsTextFrame* aFrame,
+ const gfxTextRun* aTextRun,
StyleDominantBaseline aDominantBaseline,
float aFontSizeScaleFactor) {
WritingMode writingMode = aFrame->GetWritingMode();
@@ -2080,6 +2081,13 @@ class MOZ_STACK_CLASS CharIterator {
bool IsAfterSubtree() const { return mFrameIterator.IsAfterSubtree(); }
/**
+ * Returns the iterator's computed dominant-baseline value.
+ */
+ StyleDominantBaseline DominantBaseline() const {
+ return mFrameIterator.DominantBaseline();
+ }
+
+ /**
* Returns whether the current character is a skipped character.
*/
bool IsOriginalCharSkipped() const {
@@ -4028,15 +4036,18 @@ already_AddRefed<SVGRect> SVGTextFrame::GetExtentOfChar(nsIContent* aContent,
m.PreRotate(mPositions[startIndex].mAngle);
m.PreScale(1 / mFontSizeScaleFactor, 1 / mFontSizeScaleFactor);
+ nscoord baseline = GetBaselinePosition(
+ textFrame, textRun, it.DominantBaseline(), mFontSizeScaleFactor);
+
gfxRect glyphRect;
if (textRun->IsVertical()) {
glyphRect = gfxRect(
- -presContext->AppUnitsToGfxUnits(descent) * cssPxPerDevPx, x,
+ -presContext->AppUnitsToGfxUnits(baseline) * cssPxPerDevPx, x,
presContext->AppUnitsToGfxUnits(ascent + descent) * cssPxPerDevPx,
advance);
} else {
glyphRect = gfxRect(
- x, -presContext->AppUnitsToGfxUnits(ascent) * cssPxPerDevPx, advance,
+ x, -presContext->AppUnitsToGfxUnits(baseline) * cssPxPerDevPx, advance,
presContext->AppUnitsToGfxUnits(ascent + descent) * cssPxPerDevPx);
}
diff --git a/testing/web-platform/tests/svg/text/scripted/getextentofchar.html b/testing/web-platform/tests/svg/text/scripted/getextentofchar.html
@@ -5,8 +5,9 @@
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<svg width="800" height="600">
+<svg width="800" height="200">
<text><tspan id="tspan1" x="50 150 100" y="100">abc</tspan></text>
+<text dominant-baseline="hanging"><tspan id="tspan2" x="50" y="150">abc</tspan></text>
</svg>
<script>
@@ -17,4 +18,11 @@ test(() => {
assert_equals(element.getExtentOfChar(1).x, 150);
assert_equals(element.getExtentOfChar(2).x, 100);
}, 'Multiple chunks in a tspan');
+
+test(() => {
+ const element = document.querySelector('#tspan2');
+ assert_equals(element.getNumberOfChars(), 3);
+ assert_equals(element.getExtentOfChar(0).x, 50);
+ assert_approx_equals(element.getExtentOfChar(0).y, 147.5, 1);
+}, 'With dominant-baseline');
</script>