Commit graph

20 commits

Author SHA1 Message Date
Michael Niksa 70867df077
Scale box drawing glyphs to fit cells for visual bliss (#5743)
## Summary of the Pull Request
Identifies and scales glyphs in the box and line drawing ranges U+2500-U+259F to fit their cells.

## PR Checklist
* [x] Closes #455
* [x] I work here.
* [x] Manual tests. This is all graphical.
* [x] Metric ton of comments
* [x] Math spreadsheet included in PR.
* [x] Double check RTL glyphs.
* [x] Why is there the extra pixel?
* [x] Scrolling the mouse wheel check is done.
* [x] Not drawing outline?
* [x] Am core contributor. Roar.
* [x] Try suppressing negative scale factors and see if that gets rid of weird shading.

## Detailed Description of the Pull Request / Additional comments

### Background
- We want the Terminal to be fast at drawing. To be fast at drawing, we perform differential drawing, or only drawing what is different from the previous frame. We use DXGI's `Present1` method to help us with this as it helps us compose only the deltas onto the previous frame at drawing time and assists us in scrolling regions from the previous frame without intervention. However, it only works on strictly integer pixel row heights.
- Most of the hit testing and size-calculation logic in both the `conhost` and the Terminal products are based on the size of an individual cell. Historically, a cell was always dictated in a `COORD` structure, or two `SHORT` values... which are integers. As such, when we specify the space for any individual glyph to be displayed inside our terminal drawing region, we want it to fall perfectly inside of an integer box to ensure all these other algorithms work correctly and continue to do so.
- Finally, we want the Terminal to have font fallback and locate glyphs that aren't in the primary selected font from any other font it can find on the system that contains the glyph, per DirectWrite's font fallback mechanisms. These glyphs won't necessarily have the same font or glyph metrics as the base font, but we need them to fit inside the same cell dimensions as if they did because the hit testing and other algorithms aren't aware of which particular font is sourcing each glyph, just the dimensions of the bounding box per cell.

### How does Terminal deal with this?
- When we select a font, we perform some calculations using the design metrics of the font and glyphs to determine how we could fit them inside a cell with integer dimensions. Our process here is that we take the requested font size (which is generally a proxy for height), find the matching glyph width for that height then round it to an integer. We back convert from that now integer width to a height value which is almost certainly now a floating point number. But because we need an integer box value, we add line padding above and below the glyphs to ensure that the height is an integer as well as the width. Finally, we don't add the padding strictly equally. We attempt to align the English baseline of the glyph box directly onto an integer pixel multiple so most characters sit crisply on a line when displayed. 
- Note that fonts and their glyphs have a prescribed baseline, line gap, and advance values. We use those as guidelines to get us started, but then to meet our requirements, we pad out from those. This results in fonts that should be properly authored showing gaps. It also results in fonts that are improperly authored looking even worse than they normally would.

### Now how does block and line drawing come in?
- Block and Line drawing glyphs are generally authored so they will look fine when the font and glyph metrics are followed exactly as prescribed by the font. (For some fonts, this still isn't true and we want them to look fine anyway.)
- When we add additional padding or rounding to make glyphs fit inside of a cell, we can be adding more space than was prescribed around these glyphs. This can cause a gap to be visible.
- Additionally, when we move things like baselines to land on a perfect integer pixel, we may be drawing a glyph lower in the bounding box than was prescribed originally.

### And how do we solve it?
- We identify all glyphs in the line and block drawing ranges.
- We find the bounding boxes of both the cell and the glyph.
- We compare the height of the glyph to the height of the cell to see if we need to scale. We prescribe a scale transform if the glyph wouldn't be tall enough to fit the box. (We leave it alone otherwise as some glyphs intentionally overscan the box and scaling them can cause banding effects.)
- We inspect the overhang/underhang above and below the boxes and translate transform them (slide them) so they cover the entire cell area.
- We repeat the previous two steps but in the horizontal direction.

## Validation Steps Performed
- See these commments:
   - https://github.com/microsoft/terminal/issues/455#issuecomment-620248375
   - https://github.com/microsoft/terminal/issues/455#issuecomment-621533916
   - https://github.com/microsoft/terminal/issues/455#issuecomment-622585453

Also see the below one with more screenshots:
   - https://github.com/microsoft/terminal/pull/5743#issuecomment-624940567
2020-05-08 14:09:32 -07:00
Moshe Schorr 9c52920612
Fix RTL regression (fixes #4779) (#5734)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
## Summary of the Pull Request
This fixes the RTL regression caused in #4747. We create the rectangle taking the direction (through the BiDi Level) into account, and then the rendering works again. The GlyphRun shaping could still probably use some work to be a polished thingy, and there are still issues with RTL getting chopped up a lot when there's font fallback going on, but this fixes the regression, and it's now functional again.

<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> 
## References
#4779 #4747 

<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Closes #4779
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Requires documentation to be updated
* [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx

<!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
The baseline is actually direction dependent. So when it was being initialized, the unconditional baseline as left broke it, setting the box off to right of the text. We just check if the `GlyphRun->bidiLevel` is set, and if so, we adjust it so that the baseline lines up with the right, not with the left.

<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
![image](https://user-images.githubusercontent.com/16987694/80968891-681cbc00-8e21-11ea-9e5c-9b7cf6d78d53.png)
2020-05-04 16:14:44 +00:00
Mike Griese c803893c22
Use grayscale AA always on non-opaque backgrounds (#5277)
## Summary of the Pull Request

When we're on acrylic, we can't have cleartype text unfortunately. This PR changes the DX renderer to force cleartype runs of text that are on a non-opaque background to use grayscale AA instead.

## References

Here are some of the URLS I was referencing as writing this:

* https://stackoverflow.com/q/23587787
* https://docs.microsoft.com/en-us/windows/win32/direct2d/supported-pixel-formats-and-alpha-modes#cleartype-and-alpha-modes
* https://devblogs.microsoft.com/oldnewthing/20150129-00/?p=44803
* https://docs.microsoft.com/en-us/windows/win32/api/d2d1/ne-d2d1-d2d1_layer_options
* https://docs.microsoft.com/en-us/windows/win32/direct2d/direct2d-layers-overview#d2d1_layer_parameters1-and-d2d1_layer_options1
* https://docs.microsoft.com/en-us/windows/win32/api/dcommon/ne-dcommon-d2d1_alpha_mode?redirectedfrom=MSDN#cleartype-and-alpha-modes
* https://stackoverflow.com/a/26523006

Additionally:
* This was introduced in #4711 

## PR Checklist
* [x] Closes #5098
* [x] I work here
* [ ] Tests added/passed
* [n/a] Requires documentation to be updated

## Detailed Description of the Pull Request / Additional comments

Basically, if you use cleartype on a light background, what you'll get today is the text foreground color _added_ to the background. This will make the text look basically invisible. 

So, what I did was use some trickery with `PushLayer` to basically create a layer where the text would be forced to render in grayscale AA. I only enable this layer pushing business when both:
  * The user has enabled cleartype text
  * The background opacity < 1.0

This plumbs some information through from the TermControl to the DX Renderer to make this smooth.

## Validation Steps Performed

Opened both cleartype and grayscale panes SxS, and messed with the opacity liberally.
2020-04-24 17:16:34 +00:00
Carlos Zamora 28d108bf32
Set DxRenderer non-text alias mode (#5149)
There are two antialias modes that can be set on the ID2D1RenderTarget:
- one for text/glyph drawing [1]
- one for everything else [2]
We had to configure that in the RenderTarget.

Additionally, when clipping the background color rect, we need to make
sure that's aliased too. [3]

## References
[1] ID2D1RenderTarget::SetTextAntialiasMode
    https://docs.microsoft.com/en-us/windows/win32/api/d2d1/nf-d2d1-id2d1rendertarget-settextantialiasmode
[2] ID2D1RenderTarget::SetAntialiasMode
    https://docs.microsoft.com/en-us/windows/win32/api/d2d1/nf-d2d1-id2d1rendertarget-setantialiasmode)
[3] ID2D1CommandSink::PushAxisAlignedClip
    https://docs.microsoft.com/en-us/windows/win32/api/d2d1_1/nf-d2d1_1-id2d1commandsink-pushaxisalignedclip)

## Validation
Open and interact with midnight commander with the display scaling set
to...
- 100%
- 125%
- 150%
- 175%
- 200%

Closes #3626
2020-03-28 00:15:50 +00:00
Michael Niksa 671110c88a
Clip text to within the row we expect (#4671)
## Summary of the Pull Request
Adjusts `DrawGlyphRun` method inside DirectX renderer to restrict text
to be clipped within the boundaries of the row.

## PR Checklist
* [x] Closes #1703
* [x] I work here.
* [x] No tests.
* [x] No docs.
* [x] I am core contributor.

## Detailed Description of the Pull Request / Additional comments
For whatever reason, some of these shade glyphs near U+2591 tend to
extend way above the height of where we expect they should. This didn't
look like a problem in conhost because it clipped every draw inside the
bounds. This therefore applies the same clip logic as people don't
really expect text to pour out of the box.

It could, theoretically, get us into trouble later should someone
attempt zalgo text. But doing zalgo text is more of a silliness that
varies in behavior across rendering platforms anyway.

## Validation Steps Performed
- Ran the old conhost GDI renderer and observed
- Ran the new Terminal DX renderer and observed
- Made the code change
- Observed that the height and approximate display characteristics of
  the U+2591 shade and neighboring characters now matches with the conhost
  GDI style to stay within its lane.
2020-02-21 00:57:14 +00:00
Chester Liu c274b38dcc dx: don't check the OS version multiple times (#3480) 2019-11-08 14:14:46 -08:00
Michael Niksa 7b47f4601d remove null check from glyph run drawing as it's truly optional (#2791)
Fixes #2724.
2019-09-17 10:25:22 -07:00
Michael Niksa d8ff47a0d3 Some of the PR feedback. 2019-09-05 17:21:54 -07:00
Michael Niksa 244fb72fee C26490, no reinterpret_cast. Just use the actual struct and copy instead of relying on the wink/nudge fact they're defined the same way. 2019-09-03 15:09:30 -07:00
Michael Niksa d8bc94f13c forgot all return paths to _FillRectangle. 2019-09-03 13:30:03 -07:00
Michael Niksa bbdfdf91eb C26462, const local variables that are unchanged. 2019-09-03 10:04:30 -07:00
Michael Niksa d5d7cf420d C26494, uninitalized local variables 2019-09-03 10:02:18 -07:00
Michael Niksa 30e8e7f3a3 C26429, symbols not tested for nullness. 2019-09-03 08:46:24 -07:00
Michael Niksa 4f1157c044 C26447,C26440 - is noexcept but can throw or doesn't throw but not noexcept 2019-08-29 15:23:07 -07:00
Michael Niksa 8c3a629b52 C26481, don't use pointer arithemetic. use span. 2019-08-29 14:08:47 -07:00
Michael Niksa c63289b114 C26493, no C-style casts. 2019-08-29 12:45:16 -07:00
Michael Niksa b33a59816e C26496, mark const if it's never written after creation 2019-08-29 11:27:39 -07:00
Daniel Griffen 0219781753 Allow the DX rendering engine to run on Windows 7 (#1274)
Certain DirectX features are unavailable on windows 7. The important ones as they are used in the DX renderer are color font rendering and fallback font support. Color fonts did not exist at all on windows 7 so running basic glyphrun rendering should work just fine.

Fallback font support was not exposed to the user in windows 7, making dealing with them difficult. Rather than try to get some workarounds to properly enable it I have opted to just conditionally disable the support on windows 7.
2019-07-11 15:20:15 -07:00
adiviness 9b92986b49
add clang-format conf to the project, format the c++ code (#1141) 2019-06-11 13:27:09 -07:00
Dustin Howett d4d59fa339 Initial release of the Windows Terminal source code
This commit introduces all of the Windows Terminal and Console Host source,
under the MIT license.
2019-05-02 15:29:04 -07:00