NEW311597
getStartPositionOfChar WPT is failing
https://bugs.webkit.org/show_bug.cgi?id=311597
Summary getStartPositionOfChar WPT is failing
Attachments
Karl Dubost
Comment 1 2026-04-06 15:53:31 PDT
The WPT test svg/text/scripted/getstartpositionofchar.html fails in Safari for all four vertical writing modes (vertical-rl, vertical-lr, sideways-rl, sideways-lr). Chrome and Firefox pass. The test creates <text> elements at x=100 y=100 with 10px Ahem font in vertical writing modes, then checks that getStartPositionOfChar and getEndPositionOfChar return positions that advance by the font size (10px) for each character along the block direction. For vertical-rl, vertical-lr, and sideways-rl, getEndPositionOfChar(0).y should equal getStartPositionOfChar(0).y + 10 but returns the same value as getStartPositionOfChar(0).y. The end position is not advancing by the glyph height in vertical modes. For sideways-lr, getEndPositionOfChar(0).y should equal getStartPositionOfChar(0).y - 10 but also returns the same value. Found when working on Bug 311553 This is a pre-existing issue unrelated to dominant-baseline handling. The query API correctly returns positions for horizontal text but fails to account for glyph advance in the vertical direction.
Karl Dubost
Comment 2 2026-04-06 16:10:41 PDT
The query API at SVGTextQuery.cpp:399-403 computes the end position for vertical text by adding metrics.height() to fragment.y. SVGTextMetrics::measureCharacterRange() https://searchfox.org/wubkat/rev/4b927e49756cc0415a795b42b81fc9ab95c5813d/Source/WebCore/rendering/svg/SVGTextMetrics.cpp#28-40 ```cpp SVGTextMetrics::SVGTextMetrics(const RenderSVGInlineText& textRenderer, const TextRun& run) { float scalingFactor = textRenderer.scalingFactor(); ASSERT(scalingFactor); const FontCascade& scaledFont = textRenderer.scaledFont(); // Calculate width/height using the scaled font, divide this result by the scalingFactor afterwards. m_width = scaledFont.width(run) / scalingFactor; m_height = scaledFont.metricsOfPrimaryFont().height() / scalingFactor; m_length = static_cast<unsigned>(run.length()); } ``` (SVGTextMetrics.cpp:28-40) computes: * the horizontal glyph advance with m_width = scaledFont.width(run) * the font line height (ascent + descent), a fixed value with m_height = scaledFont.metricsOfPrimaryFont().height() The TextRun is always constructed as horizontal text (SVGTextMetrics.cpp:42-56), regardless of writing mode. https://searchfox.org/wubkat/rev/4b927e49756cc0415a795b42b81fc9ab95c5813d/Source/WebCore/rendering/svg/SVGTextMetrics.cpp#42-56 ```cpp TextRun SVGTextMetrics::constructTextRun(const RenderSVGInlineText& text, unsigned position, unsigned length) { const RenderStyle& style = text.style(); TextRun run(StringView(text.text()).substring(position, length), 0, /* xPos, only relevant with allowTabs=true */ 0, /* padding, only relevant for justified text, not relevant for SVG */ ExpansionBehavior::allowRightOnly(), style.writingMode().bidiDirection(), isOverride(style.unicodeBidi()) /* directionalOverride */); // We handle letter & word spacing ourselves. run.disableSpacing(); return run; } ``` Two potential issues: 1. For vertical text, the per-character advance along y is the glyph width (horizontal advance rotated), not the font line height. The query should probably use metrics.width() for vertical advance instead of metrics.height(). 2. The fragment structure for vertical text may already position each character at its final y — in which case adding metrics on top double-counts the advance. need to heck the actual fragment structure (how many fragments, what positions) for vertical text, and the actual metric values returned by measureCharacterRange.
Radar WebKit Bug Importer
Comment 3 2026-04-13 15:43:11 PDT
Note You need to log in before you can comment on or make changes to this bug.