From 3b58e04ff4529710e459a937826d03fd1895a308 Mon Sep 17 00:00:00 2001 From: Carlos Zamora Date: Tue, 11 Feb 2020 13:58:20 -0800 Subject: [PATCH] Fix UiaTextRange Misaligned Bounding Rects (#4497) ## Summary of the Pull Request Forgot to include the scaling factor. Also went ahead and used chromium math for this portion. ## References ## PR Checklist * [x] Closes #2551 * [x] CLA signed. ## Validation Steps Performed Tested on 200% display and 100% display. Rects are aligned on both. --- src/cascadia/TerminalControl/UiaTextRange.cpp | 53 ++++++++++++++++--- 1 file changed, 46 insertions(+), 7 deletions(-) diff --git a/src/cascadia/TerminalControl/UiaTextRange.cpp b/src/cascadia/TerminalControl/UiaTextRange.cpp index 45e907bd856..6f572b1a489 100644 --- a/src/cascadia/TerminalControl/UiaTextRange.cpp +++ b/src/cascadia/TerminalControl/UiaTextRange.cpp @@ -8,6 +8,7 @@ using namespace Microsoft::Terminal; using namespace Microsoft::Console::Types; using namespace Microsoft::WRL; +using namespace winrt::Windows::Graphics::Display; HRESULT UiaTextRange::GetSelectionRanges(_In_ IUiaData* pData, _In_ IRawElementProviderSimple* pProvider, @@ -121,21 +122,59 @@ void UiaTextRange::_TranslatePointToScreen(LPPOINT clientPoint) const { auto provider = static_cast(_pProvider); + auto includeOffsets = [](long clientPos, double termControlPos, double padding, double scaleFactor) { + auto result = base::ClampedNumeric(clientPos); + result += padding; + result *= scaleFactor; + result += termControlPos; + return result; + }; + // update based on TermControl location (important for Panes) UiaRect boundingRect; THROW_IF_FAILED(provider->get_BoundingRectangle(&boundingRect)); - clientPoint->x += gsl::narrow(boundingRect.left); - clientPoint->y += gsl::narrow(boundingRect.top); // update based on TermControl padding - auto padding = provider->GetPadding(); - clientPoint->x += gsl::narrow(padding.Left); - clientPoint->y += gsl::narrow(padding.Top); + const auto padding = provider->GetPadding(); + + // Get scale factor for display + const auto scaleFactor = DisplayInformation::GetForCurrentView().RawPixelsPerViewPixel(); + + clientPoint->x = includeOffsets(clientPoint->x, boundingRect.left, padding.Left, scaleFactor); + clientPoint->y = includeOffsets(clientPoint->y, boundingRect.top, padding.Top, scaleFactor); } -void UiaTextRange::_TranslatePointFromScreen(LPPOINT /*screenPoint*/) const +// Method Description: +// - Transform coordinates relative to the screen to relative to the client +// Arguments: +// - screenPoint: coordinates relative to the screen where +// (0,0) is the top-left of the screen +// Return Value: +// - +void UiaTextRange::_TranslatePointFromScreen(LPPOINT screenPoint) const { - // TODO GitHub #2103: NON-HWND IMPLEMENTATION OF SCREENTOCLIENT() + auto provider = static_cast(_pProvider); + + auto includeOffsets = [](long screenPos, double termControlPos, double padding, double scaleFactor) { + auto result = base::ClampedNumeric(screenPos); + result -= termControlPos; + result /= scaleFactor; + result -= padding; + return result; + }; + + // update based on TermControl location (important for Panes) + UiaRect boundingRect; + THROW_IF_FAILED(provider->get_BoundingRectangle(&boundingRect)); + + // update based on TermControl padding + const auto padding = provider->GetPadding(); + + // Get scale factor for display + const auto scaleFactor = DisplayInformation::GetForCurrentView().RawPixelsPerViewPixel(); + + screenPoint->x = includeOffsets(screenPoint->x, boundingRect.left, padding.Left, scaleFactor); + screenPoint->y = includeOffsets(screenPoint->y, boundingRect.top, padding.Top, scaleFactor); } const COORD UiaTextRange::_getScreenFontSize() const