-
Notifications
You must be signed in to change notification settings - Fork 8.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support rendering of underline style and color #16097
Support rendering of underline style and color #16097
Conversation
I would be OK if you chose not to do this since we're deprecating DX... but maybe porting it to the AtlasEngine @lhecker can probably explain why/what. |
It's amazing how you make changes to these complex parts of our code base. I'll have to review it at some future time though because I'm currently working on another complex issue.
Yeah the DX engine will be replaced in the near term. If you want to, you can simplify the I'm not 100% sure how it would look like. The solutions others have come up with on https://www.shadertoy.com/ have various flaws. There's https://math.stackexchange.com/questions/514820/distance-between-point-and-sine-wave which results in something like https://www.shadertoy.com/view/Md3yRH |
If you add this to the end of float centerY = 300.0f;
float displayScale = 1.5f; // I use a 150% display scale monitor
float scaleX = 1.5f / displayScale;
float scaleY = displayScale;
float width = displayScale * 0.25f;
float4 col = float4(0.8, 0.5, 0.2, 1);
float s = sin(data.position.x * scaleX);
float d = abs(centerY - data.position.y + s * scaleY);
float a = 1 - saturate(d - width);
color = alphaBlendPremultiplied(color, col * a); you get a sine wave. Even though the distance to the sine curve ( FYI (and you might know this already) you can set this: #define ATLAS_DEBUG_CONTINUOUS_REDRAW 1 and use OpenConsole with |
The snippet you shared is arguably better than the current approach in this PR. To my eyes, they have exactly the same anti-aliasing effect as seen on the curly wave generated using D2D, and I'm amazed that this is even possible 😲
I think going with your approach will simplify things a lot. There is an added benefit that, wide and tall variants can be generated just by tweaking the Ohh, and thanks for the tip regarding |
I didn't expect that. I think at lower line widths my HLSL code might not work that well though, because it only has vertical anti-aliasing (and no horizontal). But I do think it works sufficiently well, so if you don't mind, I think we should go with the HLSL approach, because it simplifies the code. We should probably scale the wave based on the font size instead of display scale so that zooming the font size works as expected, so maybe we can do something like: float scaleX = 3.0f / underlineWidth;
float scaleY = 1.5f / underlineWidth;
float width = scaleY * 0.25f; Since this scaleY code is then very specific to Let me know if you have any questions whatsoever. Don't worry about the details - I can clean up the code at a later time, if needed. 🙂 |
While editing my comment I realized that getting the centerY might be problematic. I think you'll have to add a new member to |
I think we can club some of the font settings specific to class BackendD3D
{
private:
struct FontRenderSettings
{
ShadingType textShadingType = ShadingType::Default,
til::CoordType ligatureOverhangTriggerLeft = 0,
til::CoordType ligatureOverhangTriggerRight = 0,
f32 curlyUnderlineWaviness = 0.28f,
FontDecorationPosition curlyUnderline;
float cleartypeEnhancedContrast = 0,
float grayscaleEnhancedContrast = 0,
// Possibly this too
bool fontChangedResetGlyphAtlas = false
};
} It's okay if we move things in a separate PR, but should I at least create |
I feel somewhat impartial about that. I personally don't mind the many members at the moment, but I think that grouping them by their use would be useful. So, if you'd like to group them, please feel free to do so. 🙂 |
I just grabbed your build output and played with it for a bit. I love it. It's so cool! |
Ready for review! 😀 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Just a couple nits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Absolutely brilliant. Thank you. I'm so proud to bring this into conhost for Windows, too 😁
@lhecker, you had one outstanding comment about changing up some math, but you signed off so I'm gonna call it fine? Explain further if there's changes to make!
const auto maxCurlyLinePeakHeight = maxCurlyLinePeakHeightEm * font.fontSize; | ||
auto curlyLinePeakHeight = std::min(cellBottomGap, maxCurlyLinePeakHeight); | ||
|
||
// When it's too small to be curly, make it straight. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clever!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi guys,
Something isn't right here: I can't see curly underlines until I change font size to at least 35 in conhost or 20 in WT, which is huge even on a full HD screen:
It's definitely not too small to be curly yet:
wezterm (8.0)
Technically it's not too small if the wave height is at least 2 pixels:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to be the case for me too when using a 1440p monitor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Curly line is only drawn when there's enough space for it 1 - space between (singly) underline and Cell bottom. If we don't do this, the curly line will always be rendered, but it would be clipped, which wouldn't look nice (or correct) 😅
For example, when using Courier New (font):
When WT draws Curlyline:
When it doesn't:
I'd love to help you guys 😀, but can you file an issue for this? We can discuss in detail what might be causing this issue at those font sizes. Also, make sure to add font name (and other details that might be helpful) for repro.
Footnotes
-
To get a rough idea of how much space is available between cell bottom and underlines is to select the cell where the underline is drawn. Cell area is highlighted by the selection, and you can see how much space is available between cell bottom and underline baseline. This works on Conhost too (even better since you can scroll to increase fontsize, and the selection is preserved). ↩
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you file an issue for this?
Sure, #16288
Add support for underline style and color in the renderer > [!IMPORTANT] > The PR adds underline style and color feature to AtlasEngine (WT) and GDIRenderer (Conhost) only. After the underline style and color feature addition to Conpty, this PR takes it further and add support for rendering them to the screen! Out of five underline styles, we already supported rendering for 3 of those types (Singly, Doubly, Dotted) in some form in our (Atlas) renderer. The PR adds the remaining types, namely, Dashed and Curly underlines support to the renderer. - All renderer engines now receive both gridline and underline color, and the latter is used for drawing the underlines. **When no underline color is set, we use the foreground color.** - Curly underline is rendered using `sin()` within the pixel shader. - To draw underlines for DECDWL and DECDHL, we send the line rendition scale within `QuadInstance`'s texcoord attribute. - In GDI renderer, dashed and dotted underline is drawn using `HPEN` with a desired style. Curly line is a cubic Bezier that draws one wave per cell. ## PR Checklist - ✅ Set the underline color to underlines only, without affecting the gridline color. - ❌ Port to DX renderer. (Not planned as DX renderer soon to be replaced by **AtlasEngine**) - ✅ Port underline coloring and style to GDI renderer (Conhost). - ✅ Wide/Tall `CurlyUnderline` variant for `DECDWL`/`DECDHL`. Closes #7228 (cherry picked from commit e268c1c) Service-Card-Id: 91349180 Service-Version: 1.19
Add support for underline style and color in the renderer
Important
The PR adds underline style and color feature to AtlasEngine (WT) and GDIRenderer (Conhost) only.
After the underline style and color feature addition to Conpty, this PR takes it further and add support for rendering them to the screen!
Out of five underline styles, we already supported rendering for 3 of those types (Singly, Doubly, Dotted) in some form in our (Atlas) renderer. The PR adds the remaining types, namely, Dashed and Curly underlines support to the renderer.
sin()
within the pixel shader.QuadInstance
's texcoord attribute.HPEN
with a desired style. Curly line is a cubic Bezier that draws one wave per cell.PR Checklist
CurlyUnderline
variant forDECDWL
/DECDHL
.Closes #7228