Skip to content
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

Adjusts High DPI scaling to enable differential rendering #5345

Merged
merged 47 commits into from
Apr 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
7e8f039
Start moving dx renderer onto bitmap.
miniksa Mar 23, 2020
b46b5d0
it works!
miniksa Mar 23, 2020
78c1bc1
try to get present1 working and get mad because std::vector<bool> is …
miniksa Mar 23, 2020
39d67e3
Merge branch 'master' into dev/miniksa/dx_bitmap
miniksa Mar 30, 2020
777524a
Change invalidation to full rows to restore ligature drawing.
miniksa Mar 30, 2020
a15af9b
Add tests for til and round out the operators.
miniksa Mar 30, 2020
ac01c0b
code format
miniksa Mar 30, 2020
c478983
code format and audit mode.
miniksa Mar 31, 2020
f39b352
Dustin's suggestion about helper for invalidating rectangles .
miniksa Apr 1, 2020
0d863c2
Fix selection issues.
miniksa Apr 1, 2020
ea8e379
Restore scrolling by appropriately scaling dirty rectangles from cell…
miniksa Apr 1, 2020
1d72e6b
Don't redraw everything. We're competent enough at scrolling in the D…
miniksa Apr 1, 2020
1d51d86
Report the delta when scroll buffer circles as there is no implicit v…
miniksa Apr 3, 2020
b8c66dd
Invalidate all with retro terminal effects experimental feature turne…
miniksa Apr 3, 2020
1e5e4eb
Don't use incremental drawing parameters on the first frame. Just use…
miniksa Apr 3, 2020
46e526c
Add compensation for High DPI. Not perfect but way better.
miniksa Apr 6, 2020
f11c7a1
Remove unused constructor in float. Add scale tests to Rectangle (rem…
miniksa Apr 8, 2020
162b516
Tests for rectangle constructors from floats + code formatting pass.
miniksa Apr 8, 2020
45f8144
change to constexpr
miniksa Apr 8, 2020
351dc9c
GetClient for composition now uses size scale factor directly (and I …
miniksa Apr 8, 2020
d42f609
Adjust the present1/present logic so it will retry if present1 fails …
miniksa Apr 10, 2020
3e060e6
Literally clear everything, including the gutters, when the complete …
miniksa Apr 10, 2020
4eddc8d
Fix selection invalidation issues. This was always broken but the nat…
miniksa Apr 10, 2020
f22577d
Fix issue with algorithm around re-using known previous viewport as r…
miniksa Apr 10, 2020
f4b39ec
code format
miniksa Apr 10, 2020
8abf479
Use GDI Classic measuring mode to eliminate blended half-pixels at th…
miniksa Apr 10, 2020
d0e6dd1
separate concerns between updating viewport and scrolling.
miniksa Apr 10, 2020
b06720a
Disable incremental for High DPI as it doesn't work with the implicit…
miniksa Apr 10, 2020
1207e80
Put natural rendering back.
miniksa Apr 10, 2020
24ecd5b
Actually lock in selection code so it doesn't pull the rug out from u…
miniksa Apr 10, 2020
0d5cfc7
Adjust DxRenderer and TerminalControl to change the area of concern o…
miniksa Apr 13, 2020
e476e5c
Remove block on incremental rendering for High DPI. Remove scale comp…
miniksa Apr 13, 2020
f8b6b72
Merge branch 'master' into dev/miniksa/dpi
miniksa Apr 13, 2020
05bd203
rearrange items in terminalcontrol to not show delta. use scaling on …
miniksa Apr 13, 2020
f4ddf1f
code format
miniksa Apr 13, 2020
d330a00
remember previous scale transform and resize/recreate if different.
miniksa Apr 13, 2020
767f491
Run dpi change through the font trigger in render base.
miniksa Apr 13, 2020
9a5d257
wpf: Save the scale for HWND as well (avoid flicker); fix HTML
DHowett Apr 15, 2020
ca7ccf3
uia: fix dip/dpx calculations now that controls are in DPX
DHowett Apr 15, 2020
79fdf25
Merge branch 'master' into dev/miniksa/dpi
miniksa Apr 20, 2020
cbe389f
Various Differential Drawing fixes for #5345 (#5427)
zadjii-msft Apr 20, 2020
acb9f4c
Remove tests against internal rectangle in BitmapTests as it is no lo…
miniksa Apr 20, 2020
e11d6a7
Add some til tests for the til things that Mike introduced.
miniksa Apr 20, 2020
3d4b978
Typo.
miniksa Apr 20, 2020
ec614ab
Code format.
miniksa Apr 20, 2020
4094d9b
Audit mode noexcept/constexpr possible.
miniksa Apr 20, 2020
4337cf5
oops, missed these two foundation structs.
miniksa Apr 20, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/cascadia/PublicTerminalCore/HwndTerminal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -724,7 +724,7 @@ HRESULT HwndTerminal::_CopyTextToSystemClipboard(const TextBuffer::TextAndColor&
if (fAlsoCopyFormatting)
{
const auto& fontData = _actualFont;
int const iFontHeightPoints = fontData.GetUnscaledSize().Y * 72 / this->_currentDpi;
int const iFontHeightPoints = fontData.GetUnscaledSize().Y; // this renderer uses points already
const COLORREF bgColor = _terminal->GetBackgroundColor(_terminal->GetDefaultBrushColors());

std::string HTMLToPlaceOnClip = TextBuffer::GenHTML(rows, iFontHeightPoints, fontData.GetFaceName(), bgColor, "Hwnd Console Host");
Expand Down
77 changes: 47 additions & 30 deletions src/cascadia/TerminalControl/TSFInputControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,52 +175,69 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
auto fontArgs = winrt::make_self<FontInfoEventArgs>();
_CurrentFontInfoHandlers(*this, *fontArgs);

const auto fontWidth = fontArgs->FontSize().Width;
const auto fontHeight = fontArgs->FontSize().Height;
const til::size fontSize{ til::math::flooring, fontArgs->FontSize() };

// Convert text buffer cursor position to client coordinate position within the window
COORD clientCursorPos;
clientCursorPos.X = ::base::ClampMul(_currentTerminalCursorPos.x(), ::base::ClampedNumeric<ptrdiff_t>(fontWidth));
clientCursorPos.Y = ::base::ClampMul(_currentTerminalCursorPos.y(), ::base::ClampedNumeric<ptrdiff_t>(fontHeight));
// Convert text buffer cursor position to client coordinate position
// within the window. This point is in _pixels_
const til::point clientCursorPos{ _currentTerminalCursorPos * fontSize };
Copy link
Member

Choose a reason for hiding this comment

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

I've been out of the til::point/size loop for a bit, so correct me if I'm wrong. Can't this throw if we get an overflow?


// position textblock to cursor position
Canvas().SetLeft(TextBlock(), clientCursorPos.X);
Canvas().SetTop(TextBlock(), clientCursorPos.Y);
// Get scale factor for view
const double scaleFactor = DisplayInformation::GetForCurrentView().RawPixelsPerViewPixel();

const til::point clientCursorInDips{ clientCursorPos / scaleFactor };

// Position our TextBlock at the cursor position
Canvas().SetLeft(TextBlock(), clientCursorInDips.x<double>());
Canvas().SetTop(TextBlock(), clientCursorInDips.y<double>());

// calculate FontSize in pixels from Points
const double fontSizePx = (fontSize.height<double>() * 72) / USER_DEFAULT_SCREEN_DPI;

// calculate FontSize in pixels from DPIs
const double fontSizePx = (fontHeight * 72) / USER_DEFAULT_SCREEN_DPI;
TextBlock().FontSize(fontSizePx);
// Make sure to unscale the font size to correct for DPI! XAML needs
// things in DIPs, and the fontSize is in pixels.
TextBlock().FontSize(fontSizePx / scaleFactor);
Comment on lines +196 to +198
Copy link
Member

Choose a reason for hiding this comment

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

(unrelated to this PR, more for discussion) Should we eventually do what we did with COORD and create two new til structs to always know when we're in DIPs vs pixels? Or would that be overkill.

TextBlock().FontFamily(Media::FontFamily(fontArgs->FontFace()));

const auto widthToTerminalEnd = _currentCanvasWidth - ::base::ClampedNumeric<double>(clientCursorPos.X);
const auto widthToTerminalEnd = _currentCanvasWidth - clientCursorInDips.x<double>();
// Make sure that we're setting the MaxWidth to a positive number - a
// negative number here will crash us in mysterious ways with a useless
// stack trace
const auto newMaxWidth = std::max<double>(0.0, widthToTerminalEnd);
TextBlock().MaxWidth(newMaxWidth);

// Get window in screen coordinates, this is the entire window including tabs
const auto windowBounds = CoreWindow::GetForCurrentThread().Bounds();
// Get window in screen coordinates, this is the entire window including
// tabs. THIS IS IN DIPs
const auto windowBounds{ CoreWindow::GetForCurrentThread().Bounds() };
const til::point windowOrigin{ til::math::flooring, windowBounds };

// Convert from client coordinate to screen coordinate by adding window position
COORD screenCursorPos;
screenCursorPos.X = ::base::ClampAdd(clientCursorPos.X, ::base::ClampedNumeric<short>(windowBounds.X));
screenCursorPos.Y = ::base::ClampAdd(clientCursorPos.Y, ::base::ClampedNumeric<short>(windowBounds.Y));
// Get the offset (margin + tabs, etc..) of the control within the window
const til::point controlOrigin{ til::math::flooring,
this->TransformToVisual(nullptr).TransformPoint(Point(0, 0)) };

// get any offset (margin + tabs, etc..) of the control within the window
const auto offsetPoint = this->TransformToVisual(nullptr).TransformPoint(winrt::Windows::Foundation::Point(0, 0));
// The controlAbsoluteOrigin is the origin of the control relative to
// the origin of the displays. THIS IS IN DIPs
const til::point controlAbsoluteOrigin{ windowOrigin + controlOrigin };

// add the margin offsets if any
screenCursorPos.X = ::base::ClampAdd(screenCursorPos.X, ::base::ClampedNumeric<short>(offsetPoint.X));
screenCursorPos.Y = ::base::ClampAdd(screenCursorPos.Y, ::base::ClampedNumeric<short>(offsetPoint.Y));
// Convert the control origin to pixels
const til::point scaledFrameOrigin = controlAbsoluteOrigin * scaleFactor;

// Get scale factor for view
const double scaleFactor = DisplayInformation::GetForCurrentView().RawPixelsPerViewPixel();
const auto yOffset = ::base::ClampedNumeric<float>(_currentTextBlockHeight) - fontHeight;
const auto textBottom = ::base::ClampedNumeric<float>(screenCursorPos.Y) + yOffset;
// Get the location of the cursor in the display, in pixels.
til::point screenCursorPos{ scaledFrameOrigin + clientCursorPos };

// GH #5007 - make sure to account for wrapping the IME composition at
// the right side of the viewport.
const ptrdiff_t textBlockHeight = ::base::ClampMul(_currentTextBlockHeight, scaleFactor);

// Get the bounds of the composition text, in pixels.
const til::rectangle textBounds{ til::point{ screenCursorPos.x(), screenCursorPos.y() },
til::size{ 0, textBlockHeight } };

_currentTextBounds = textBounds;

_currentTextBounds = ScaleRect(Rect(screenCursorPos.X, textBottom, 0, fontHeight), scaleFactor);
_currentControlBounds = ScaleRect(Rect(screenCursorPos.X, screenCursorPos.Y, 0, fontHeight), scaleFactor);
_currentControlBounds = Rect(screenCursorPos.x<float>(),
screenCursorPos.y<float>(),
0,
fontSize.height<float>());
}

// Method Description:
Expand Down
Loading