Skip to content

Prepare text pipeline for future Pretext integration#492

Merged
wieslawsoltes merged 5 commits into
masterfrom
pretext-preparation-refactor
Apr 15, 2026
Merged

Prepare text pipeline for future Pretext integration#492
wieslawsoltes merged 5 commits into
masterfrom
pretext-preparation-refactor

Conversation

@wieslawsoltes
Copy link
Copy Markdown
Owner

PR Summary: Prepare Svg.Skia Text Pipeline For Future Pretext Integration

Overview

This change prepares Svg.Skia for a future Pretext-backed text preparation layer without introducing any runtime dependency on Pretext and without modifying upstream PretextSharp.

The refactor keeps SVG-specific placement and rendering ownership in SvgSceneTextCompiler, but extracts an internal prepared-text boundary that can eventually host a different preparation and measurement implementation.

Why

The current text pipeline in SvgSceneTextCompiler mixes several concerns in the same area:

  • flat text preparation
  • repeated width measurement
  • cached codepoint advance measurement
  • sequential run aggregation
  • SVG-specific placement and rendering

That coupling makes it hard to introduce a future prepared-text engine safely. The goal of this PR is to separate the preparation and measurement boundary first, while preserving the existing SVG behavior.

What Changed

1. Added a prepared-text abstraction

A new internal partial file, src/Svg.SceneGraph/SvgSceneTextCompiler.PreparedText.cs, introduces:

  • ISvgPreparedTextEngine
  • PreparedFlatTextRun
  • PreparedSequentialText
  • PreparedSequentialRun
  • CurrentSvgPreparedTextEngine

The default implementation still delegates to the current Svg.Skia text-measurement behavior. No Pretext APIs are referenced.

2. Moved flat-run preparation and cache ownership behind that abstraction

The prepared-text engine now owns the boundary for:

  • full advance measurement
  • natural width measurement
  • natural codepoint advance measurement
  • sequential run preparation
  • local prepared-text cache clearing

The existing top-level helpers in SvgSceneTextCompiler now delegate to the prepared-text engine instead of owning the measurement policy directly.

3. Routed sequential fast paths through prepared sequential text

Sequential measurement and alignment paths now use prepared sequential text when they need aggregate run advances:

  • sequential clip-path generation
  • sequential draw path for non-left alignment
  • sequential measurement path
  • sequential total-advance helper

This keeps behavior unchanged while reducing duplication around repeated sequential width probes.

4. Preserved existing fast-path behavior

During review, the refactor was tightened to avoid unintended slowdowns or fallback regressions:

  • left-aligned sequential draw still avoids unnecessary prepared-text work
  • sequential preparation no longer computes natural codepoint advances for every run
  • MeasureSequentialTextRuns(...) now falls back to summing per-run advances instead of returning 0 if preparation fails

Tests Added

tests/Svg.Skia.UnitTests/SvgSceneTextCompilerTests.cs now includes coverage for:

  • flat-run preparation returning the expected advance, natural width, and codepoint advances
  • sequential preparation returning per-run advances for flat nested text
  • sequential preparation rejecting positioned tspan barriers
  • a regression guard proving sequential preparation does not require prefix-based codepoint measurement

Behavioral Scope

This PR is intentionally limited to preparation and measurement refactoring.

It does not change ownership of:

  • textPath
  • per-glyph x/y/dx/dy
  • rotation handling
  • vertical layout semantics
  • textLength placement rules
  • SVG font outline rendering
  • final draw/shaping ownership

Those remain in the existing Svg.Skia text engine.

Commit Breakdown

  1. 0c7a8c4c3 Add Pretext feasibility plan

    • Adds the feasibility analysis and staged refactor plan.
  2. 5b5200b92 Extract prepared text engine

    • Introduces the internal prepared-text abstraction.
    • Moves measurement/cache concerns behind the abstraction.
    • Routes sequential measurement/alignment through prepared sequential text.
  3. 924e57639 Add prepared text compiler tests

    • Adds focused unit coverage for the new abstraction boundary and regression scenarios.

Validation

The final state was verified with:

  • dotnet build Svg.Skia.slnx -c Release
  • dotnet test tests/Svg.Skia.UnitTests/Svg.Skia.UnitTests.csproj -f net10.0 -c Release --no-restore --filter "FullyQualifiedName~SvgSceneTextCompilerTests"
  • dotnet test Svg.Skia.slnx -c Release

Observed final result:

  • focused SvgSceneTextCompilerTests: 12 passed
  • full Svg.Skia.UnitTests: 1628 passed, 593 skipped, 2221 total
  • full solution test run: passed

Risks / Follow-up

This PR improves the integration boundary, but it does not yet provide a drop-in alternative prepared-text engine. The next safe steps would be:

  • add more targeted benchmarks around repeated measurement scenarios
  • decide whether cache clearing should be wired into broader model-level cache lifecycle
  • introduce an experimental alternative implementation only after external version and backend constraints are resolved

Notes

  • No upstream PretextSharp changes are required or included here.
  • The existing dirty externals/SVG submodule state was left untouched.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant