Skip to content

fix(textfield): cursor position drifts on wide Cyrillic glyphs (ы, ш, щ, ж) #211

Description

@kolkov

Bug

Cursor position in TextField drifts rightward when typing wide Cyrillic characters (ы, ш, щ, ж). Narrow Latin characters track correctly. After 10+ wide characters the drift reaches 5-10px.

Reproduce

  1. go run ./examples/gallery/
  2. Click TextField
  3. Type ыыыыыыыыыыыыыыыыыы (hold ы key)
  4. Cursor visually drifts ahead of the actual insertion point

Root Cause

Two separate bugs in two repos:

1. Base offset rounding mismatch (ui)

DrawText rounds the starting X position: math.Round(contentRect.Min.X) (internal/render/canvas.go:488).
CursorX uses raw contentRect.Min.X without rounding (internal/textmetrics/textmetrics.go:35).

Creates a constant cursor-to-text offset of up to 0.5px.

2. Per-glyph hinted/raw advance mismatch (gg#479)

MeasureTextface.Advance() returns raw unhinted per-glyph advances (text/face.go:88).
DrawTextdrawGlyphshintedOrRawAdvance() returns TT-hinted advances (text/draw.go:136).

Hinting adjusts wide Cyrillic characters (ш: 3 vertical stems, щ: 4, ж: 5) to pixel grid. Each glyph 0.5-1px wider/narrower than raw advance. After 10 characters → 5-10px cumulative drift.

GPU GlyphMask path is NOT affected — both measurement and rendering use raw advances.

Enterprise reference

Flutter (TextPainter + HarfBuzz), Qt (QFontMetrics + QTextEngine), Chrome (Font::width + ShapeResult) — all use a single shaped result for both rendering and cursor positioning.

Fix

Environment

  • Windows 10, Vulkan backend
  • v0.1.50+ (main, post SceneCache refactoring)
  • Inter font (has TT bytecode hints)
  • Default hinting: HintingFull

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions