[PR #4747] [MERGED] Improve glyph scaling correction #25924

Open
opened 2026-01-31 09:12:40 +00:00 by claunia · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/microsoft/terminal/pull/4747
Author: @miniksa
Created: 2/28/2020
Status: Merged
Merged: 3/2/2020
Merged by: @undefined

Base: masterHead: dev/miniksa/layout_2


📝 Commits (10+)

  • f892200 Don't split surrogate pairs when breaking runs for scaling. Affects emoji rendering. #4704
  • 98b483c merge #4438 by @milizhang
  • b490847 Allows sum of all advances for glyphs used in these columns to be considered for the column space allocated. Applies excess pen advance space to the final one only.
  • 98dcba9 Use struct for scale corrections. Move them to use correct index (text, not glyph). Provide length to corrections as well. Change scaling down algorithm to be based on advances we already know. Correct remaining advance distances to deal with multiple glyph clusters.
  • ec1d4fc Put 0s for the columns on a piece of text bigger than one char.
  • c7d5a95 Add a bunch of comments. Delete a bunch of old code.
  • 799a144 Don't need surrogate fix anymore with col fix.
  • cf8d0d4 Rewrite algorithm and add tons of comments to attempt to make it easier to understand in regards to indexes/offsets.
  • f5c90cb fix analysis warnings.
  • e557af4 typo

📊 Changes

3 files changed (+276 additions, -54 deletions)

View changed files

📝 src/renderer/dx/CustomTextLayout.cpp (+267 -52)
📝 src/renderer/dx/CustomTextLayout.h (+8 -1)
📝 src/renderer/dx/DxRenderer.cpp (+1 -1)

📄 Description

Summary of the Pull Request

  • Improves the correction of the scaling and spacing that is applied to
    glyphs if they are too large or too small for the number of columns that
    the text buffer is expecting

References

PR Checklist

Detailed Description of the Pull Request / Additional comments

  • The _CorrectGlyphRun function now walks through and uses the
    _glyphClusters map to determine the text span and glyph span for each
    cluster so it can be considered as a single unit for scaling.
  • The total number of columns expected across the entire cluster
    text/glyph unit is considered for the available spacing for drawing
  • The total glyph advances are summed to see how much space they will
    take
  • If more space than necessary to draw, all glyphs in the cluster are
    offset into the center and the extra space is padded onto the advance of
    the last glyph in the range.
  • If less space than necessary to draw, the entire cluster is marked for
    shrinking as a single unit by providing the initial text index and
    length (that is back-mapped out of the glyph run) up to the parent
    function so it can use the _SetCurrentRun and _SplitCurrentRun
    existing functions (which operate on text) to split the run into pieces
    and only scale the one glyph cluster, not things next to it as well.
  • The scale factor chosen for shrinking is now based on the proportion
    of the advances instead of going through some font math wizardry
  • The parent that calls the run splitting functions now checks to not
    attempt to split off text after the cluster if it's already at the end.
    This was @DHowett-MSFT's crash.
  • The split run function has been corrected to fix the glyphStart
    position of the back half (it failed to += instead of = which
    resulted in duplicated text, sometimes).
  • Surrogate pair emoji were not allocating an appropriate number of
    _textClusterColumns. The constructor has been updated such that the
    trailing half of surrogate pairs gets a 0 column width (as the lead is
    marked appropriately by the GetColumns() function). This was the
    exception thrown.
  • The _glyphScaleCorrections array stored up over the calls to
    _CorrectGlyphRun now uses a struct ScaleCorrection as we're up to 3
    values.
  • The ScaleCorrection values are named to clearly indicate they're in
    relation to the original text span, not the glyph spans.
  • The values that are used to construct ScaleCorrections within
    _CorrectGlyphRun have been double checked and corrected to not
    accidentally use glyph index/counts when text index/counts are what's
    required.

Validation Steps Performed

  • Tested the utf82.txt file from one of the linked bugs. Looked
    specifically at Burmese through Thai to ensure restoration (for the most
    part) of the behavior
  • Ensured that U+1f3e0 emoji (🏠) continues to draw correctly
  • Checked Fixedsys Excelsior font to ensure it's not shrinking the line
    with its ligatures
  • Checked ligatureness of Cascadia Code font
  • Checked combining characters U+0300-U+0304 with a capital A

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/microsoft/terminal/pull/4747 **Author:** [@miniksa](https://github.com/miniksa) **Created:** 2/28/2020 **Status:** ✅ Merged **Merged:** 3/2/2020 **Merged by:** [@undefined](undefined) **Base:** `master` ← **Head:** `dev/miniksa/layout_2` --- ### 📝 Commits (10+) - [`f892200`](https://github.com/microsoft/terminal/commit/f89220041d82d1c360830937139e271ffc890c3a) Don't split surrogate pairs when breaking runs for scaling. Affects emoji rendering. #4704 - [`98b483c`](https://github.com/microsoft/terminal/commit/98b483c8ee92ac6f7b4c57db035dd31e33a141ca) merge #4438 by @milizhang - [`b490847`](https://github.com/microsoft/terminal/commit/b49084718e66837667569ef65920500fa057e4d0) Allows sum of all advances for glyphs used in these columns to be considered for the column space allocated. Applies excess pen advance space to the final one only. - [`98dcba9`](https://github.com/microsoft/terminal/commit/98dcba94d098db7aa5bcc3f074141f60a8acd94b) Use struct for scale corrections. Move them to use correct index (text, not glyph). Provide length to corrections as well. Change scaling down algorithm to be based on advances we already know. Correct remaining advance distances to deal with multiple glyph clusters. - [`ec1d4fc`](https://github.com/microsoft/terminal/commit/ec1d4fc2f084f360a40058b8ad7552c21a57b5db) Put 0s for the columns on a piece of text bigger than one char. - [`c7d5a95`](https://github.com/microsoft/terminal/commit/c7d5a95a12e9e89a4baf282033e6dc1ae7f73abf) Add a bunch of comments. Delete a bunch of old code. - [`799a144`](https://github.com/microsoft/terminal/commit/799a144682ac772fa4f200b8a28f0f24b61a76ea) Don't need surrogate fix anymore with col fix. - [`cf8d0d4`](https://github.com/microsoft/terminal/commit/cf8d0d4ef144c86b5b69390c70e3b106a78b9266) Rewrite algorithm and add tons of comments to attempt to make it easier to understand in regards to indexes/offsets. - [`f5c90cb`](https://github.com/microsoft/terminal/commit/f5c90cb0d05ae8320113ce0608869956f0b8df35) fix analysis warnings. - [`e557af4`](https://github.com/microsoft/terminal/commit/e557af4d27e66aa91cecd21bc29ec6ac28497404) typo ### 📊 Changes **3 files changed** (+276 additions, -54 deletions) <details> <summary>View changed files</summary> 📝 `src/renderer/dx/CustomTextLayout.cpp` (+267 -52) 📝 `src/renderer/dx/CustomTextLayout.h` (+8 -1) 📝 `src/renderer/dx/DxRenderer.cpp` (+1 -1) </details> ### 📄 Description ## Summary of the Pull Request - Improves the correction of the scaling and spacing that is applied to glyphs if they are too large or too small for the number of columns that the text buffer is expecting ## References - Supersedes #4438 Co-authored-by: Mili (Yi) Zhang <milizhang@gmail.com> - Related to #4704 (#4731) ## PR Checklist * [x] Closes #696 * [x] Closes #4375 * [x] Closes #4708 * [x] Closes a crash that @DHowett-MSFT complained about with `"x" * ($Host.UI.RawUI.BufferSize.Width - 1) + "`u{241b}"` * [x] Eliminates an exception getting thrown with the U+1F3E0 emoji in `_CorrectGlyphRun` * [x] Corrects several graphical issues that occurred after #4731 was merged to master (weird repeats and splits of runs) * [x] I work here. * [x] Tested manually versus given scenarios. * [x] Documentation written into comments in the code. * [x] I'm a core contributor. ## Detailed Description of the Pull Request / Additional comments - The `_CorrectGlyphRun` function now walks through and uses the `_glyphClusters` map to determine the text span and glyph span for each cluster so it can be considered as a single unit for scaling. - The total number of columns expected across the entire cluster text/glyph unit is considered for the available spacing for drawing - The total glyph advances are summed to see how much space they will take - If more space than necessary to draw, all glyphs in the cluster are offset into the center and the extra space is padded onto the advance of the last glyph in the range. - If less space than necessary to draw, the entire cluster is marked for shrinking as a single unit by providing the initial text index and length (that is back-mapped out of the glyph run) up to the parent function so it can use the `_SetCurrentRun` and `_SplitCurrentRun` existing functions (which operate on text) to split the run into pieces and only scale the one glyph cluster, not things next to it as well. - The scale factor chosen for shrinking is now based on the proportion of the advances instead of going through some font math wizardry - The parent that calls the run splitting functions now checks to not attempt to split off text after the cluster if it's already at the end. This was @DHowett-MSFT's crash. - The split run function has been corrected to fix the `glyphStart` position of the back half (it failed to `+=` instead of `=` which resulted in duplicated text, sometimes). - Surrogate pair emoji were not allocating an appropriate number of `_textClusterColumns`. The constructor has been updated such that the trailing half of surrogate pairs gets a 0 column width (as the lead is marked appropriately by the `GetColumns()` function). This was the exception thrown. - The `_glyphScaleCorrections` array stored up over the calls to `_CorrectGlyphRun` now uses a struct `ScaleCorrection` as we're up to 3 values. - The `ScaleCorrection` values are named to clearly indicate they're in relation to the original text span, not the glyph spans. - The values that are used to construct `ScaleCorrection`s within `_CorrectGlyphRun` have been double checked and corrected to not accidentally use glyph index/counts when text index/counts are what's required. ## Validation Steps Performed - Tested the utf82.txt file from one of the linked bugs. Looked specifically at Burmese through Thai to ensure restoration (for the most part) of the behavior - Ensured that U+1f3e0 emoji (🏠) continues to draw correctly - Checked Fixedsys Excelsior font to ensure it's not shrinking the line with its ligatures - Checked ligatureness of Cascadia Code font - Checked combining characters U+0300-U+0304 with a capital A --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
claunia added the pull-request label 2026-01-31 09:12:40 +00:00
Sign in to join this conversation.
No Label pull-request
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#25924