Skip to content

Add LineMetrics and per-line measurement API#499

Merged
JimBobSquarePants merged 5 commits into
mainfrom
js/linemetrics
Feb 28, 2026
Merged

Add LineMetrics and per-line measurement API#499
JimBobSquarePants merged 5 commits into
mainfrom
js/linemetrics

Conversation

@JimBobSquarePants
Copy link
Copy Markdown
Member

Prerequisites

  • I have written a descriptive pull-request title
  • I have verified that there are no overlapping pull-requests open
  • I have verified that I am following matches the existing coding patterns and practice as demonstrated in the repository. These follow strict Stylecop rules 👮.
  • I have provided test coverage for my change (where applicable)

Description

This pull request introduces improvements and refactoring to the text layout logic in the SixLabors.Fonts library, focusing on more accurate handling of line spacing and alignment for both horizontal and vertical text layouts. It also adds a new LineMetrics struct to encapsulate line measurement details and exposes additional internal APIs for better testability and extensibility.

Text layout and alignment improvements:

  • Refactored line spacing and centering calculations in TextLayout.cs for horizontal, vertical, and mixed vertical layout methods, ensuring glyphs are properly centered within extra space created by LineSpacing. This addresses previous inaccuracies in how line spacing affected glyph placement. [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]

  • Added new internal methods CalculateLineOffsetX and CalculateLineOffsetY to centralize and clarify line alignment logic for both axes, improving maintainability and correctness of text alignment calculations.

API and structure enhancements:

  • Added a new LineMetrics struct in LineMetrics.cs to encapsulate measured metrics for a single laid-out text line, supporting both horizontal and vertical layouts.

  • Exposed ProcessText as an internal method in TextLayout.cs to facilitate testing and internal usage.

Glyph layout and metric tracking:

  • Updated the TextLine class to track an additional metric, ScaledMaxDelta, for more precise line box calculations, and ensured LineSpacing is applied when storing line heights. [1] [2] [3] [4]

Minor fixes and code clarity:

  • Cleaned up variable names and comments, and fixed minor logic issues (such as ensuring correct buffer sizing and centering calculations), contributing to overall code clarity and robustness. [1] [2] [3] [4]

Let me know if you want a deeper dive into any of these changes or need help understanding how the new alignment logic works!

@codecov
Copy link
Copy Markdown

codecov Bot commented Feb 28, 2026

Codecov Report

❌ Patch coverage is 66.94915% with 39 lines in your changes missing coverage. Please review.
✅ Project coverage is 83%. Comparing base (6078cd5) to head (461d46c).
⚠️ Report is 17 commits behind head on main.

Files with missing lines Patch % Lines
src/SixLabors.Fonts/TextLayout.cs 48% 29 Missing and 3 partials ⚠️
src/SixLabors.Fonts/TextMeasurer.cs 83% 3 Missing and 4 partials ⚠️
Additional details and impacted files
@@          Coverage Diff           @@
##            main    #499    +/-   ##
======================================
  Coverage     83%     83%            
======================================
  Files        272     274     +2     
  Lines      18929   19184   +255     
  Branches    2676    2719    +43     
======================================
+ Hits       15836   16081   +245     
- Misses      2422    2426     +4     
- Partials     671     677     +6     
Flag Coverage Δ
unittests 83% <66%> (+<1%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces the LineMetrics struct and a new TextMeasurer.GetLineMetrics() API for per-line measurement. It also refactors line spacing and alignment calculations in TextLayout.cs to correctly apply LineSpacing by baking it into the stored line height at glyph-addition time (rather than multiplying later during layout), and adds CalculateLineOffsetX/Y helper methods for alignment computation.

Changes:

  • Adds LineMetrics struct and TextMeasurer.GetLineMetrics(string/ReadOnlySpan<char>, TextOptions) public API
  • Refactors line height and alignment calculations in horizontal, vertical, and mixed vertical layout methods to eliminate double-application of LineSpacing
  • Adds ScaledMaxDelta tracking to TextLine and GlyphLayoutData to support accurate guide-line positioning in GetLineMetrics

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
src/SixLabors.Fonts/LineMetrics.cs New struct encapsulating per-line typographic metrics
src/SixLabors.Fonts/TextMeasurer.cs New GetLineMetrics overloads; CountLines refactored to use ProcessText
src/SixLabors.Fonts/TextLayout.cs ProcessText made internal; LineSpacing baked into stored height; CalculateLineOffsetX/Y helpers added; ScaledMaxDelta tracking added
tests/SixLabors.Fonts.Tests/TextLayoutTestUtilities.cs Added beforeAction/afterAction hooks to TestLayout
tests/SixLabors.Fonts.Tests/Issues/Issues_353.cs New visual regression test for GetLineMetrics with guide-line drawing
tests/Images/ReferenceOutput/Test_Issue_353_400.png Reference image for the new test
.github/workflows/build-and-test.yml Upgraded Codecov action to v5; added required token

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/SixLabors.Fonts.Tests/TextLayoutTestUtilities.cs
Comment thread tests/SixLabors.Fonts.Tests/Issues/Issues_353.cs Outdated
Comment thread src/SixLabors.Fonts/TextMeasurer.cs
Comment thread tests/SixLabors.Fonts.Tests/Issues/Issues_353.cs Outdated
Comment thread src/SixLabors.Fonts/TextLayout.cs Outdated
Comment thread src/SixLabors.Fonts/TextLayout.cs Outdated
Comment thread tests/SixLabors.Fonts.Tests/Issues/Issues_353.cs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants