[PR #16475] Put the final touches on GDI's underlines #30931

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

Original Pull Request: https://github.com/microsoft/terminal/pull/16475

State: closed
Merged: Yes


While #16444 left wavy lines in an amazing state already, there were
a few more things that could be done to make GDI look more consistent
with other well known Windows applications.

But before that, a couple unrelated, but helpful changes were made:

  • GdiEngine::UpdateFont was heavily modified to do all calculations
    in floats. All modern CPUs have fast FPUs and even the fairly slow
    lroundf function is so fast (relatively) nowadays that in a cold
    path like this, we can liberally call it to convert back to ints.
    This makes intermediate calculation more accurate and consistent.
  • GdiEngine::PaintBufferGridLines was exception-unsafe due to its
    use of a std::vector with catch clause and this PR fixes that.
    Additionally, the vector was swapped out with a til::small_vector
    to reduce heap allocations. (Arena allocators!)
  • RenderingTests was updated to cover styled underlines

With that in place, these improvements were done:

  • Word's double-underline algorithm was ported over from AtlasEngine.
    It uses a half underline-width (aka thinLineWidth) which will now
    also be used for wavy lines to make them look a bit more filigrane.
  • The Bézier curve for wavy/curly underlines was modified to use
    control points at (0.5,0.5) and (0.5,-0.5) respectively. This results
    in a maxima at y=0.1414 which is much closer to a sine curve with a
    maxima at 1/(2pi) = 0.1592. Previously, the maxima was a lot higher
    (roughly 4x) depending on the aspect ratio of the glyphs.
  • Wavy underlines don't depend on the aspect ratio of glyphs anymore.
    This previously led to several problems depending on the exact font.
    The old renderer would draw exactly 3 periods of the wave into
    each cell which would also ensure continuity between cells.
    Unfortunately, this meant that waves could look inconsistent.
    The new approach always uses the aforementioned sine-like waves.
  • The wavy underline offset was clamped so that it's never outside of
    bounds of a line. This avoids clipping.

Validation Steps Performed

  • Compile RenderingTests and run it
  • Using Consolas, MS Gothic and Cascadia Code while Ctrl+Scrolling
    up and down works as expected without clipping
**Original Pull Request:** https://github.com/microsoft/terminal/pull/16475 **State:** closed **Merged:** Yes --- While #16444 left wavy lines in an amazing state already, there were a few more things that could be done to make GDI look more consistent with other well known Windows applications. But before that, a couple unrelated, but helpful changes were made: * `GdiEngine::UpdateFont` was heavily modified to do all calculations in floats. All modern CPUs have fast FPUs and even the fairly slow `lroundf` function is so fast (relatively) nowadays that in a cold path like this, we can liberally call it to convert back to `int`s. This makes intermediate calculation more accurate and consistent. * `GdiEngine::PaintBufferGridLines` was exception-unsafe due to its use of a `std::vector` with catch clause and this PR fixes that. Additionally, the vector was swapped out with a `til::small_vector` to reduce heap allocations. (Arena allocators!) * RenderingTests was updated to cover styled underlines With that in place, these improvements were done: * Word's double-underline algorithm was ported over from `AtlasEngine`. It uses a half underline-width (aka `thinLineWidth`) which will now also be used for wavy lines to make them look a bit more filigrane. * The Bézier curve for wavy/curly underlines was modified to use control points at (0.5,0.5) and (0.5,-0.5) respectively. This results in a maxima at y=0.1414 which is much closer to a sine curve with a maxima at 1/(2pi) = 0.1592. Previously, the maxima was a lot higher (roughly 4x) depending on the aspect ratio of the glyphs. * Wavy underlines don't depend on the aspect ratio of glyphs anymore. This previously led to several problems depending on the exact font. The old renderer would draw exactly 3 periods of the wave into each cell which would also ensure continuity between cells. Unfortunately, this meant that waves could look inconsistent. The new approach always uses the aforementioned sine-like waves. * The wavy underline offset was clamped so that it's never outside of bounds of a line. This avoids clipping. ## Validation Steps Performed * Compile RenderingTests and run it * Using Consolas, MS Gothic and Cascadia Code while Ctrl+Scrolling up and down works as expected without clipping ✅
claunia added the pull-request label 2026-01-31 09:43:53 +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#30931