-
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
Prepare til wrappers for migrating off of SMALL_RECT #11902
Conversation
99e7ea2
to
568c52b
Compare
568c52b
to
21e912d
Compare
@@ -0,0 +1,851 @@ | |||
// Copyright (c) Microsoft Corporation. |
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.
(note for reviewers) Use a diff tool (I used text-compare.com) to compare rect.h to rectangle.h and make your life easier haha.
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.
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.
53/76
Honestly, it all looks good. Most of it seems to be a result of removing the implicit conversion stuff.
@@ -287,16 +287,16 @@ void UiaTextRangeBase::_expandToEnclosingUnit(TextUnit unit) | |||
// If we're past document end, | |||
// set us to ONE BEFORE the document end. | |||
// This allows us to expand properly. | |||
if (bufferSize.CompareInBounds(_start, documentEnd, true) >= 0) | |||
if (bufferSize.CompareInBounds(_start, documentEnd.to_win32_coord(), true) >= 0) |
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.
idk if this is in your other PR, but I'd like this to eventually just be replaced with _start >= documentEnd
where both are til::point
.
Not really anything to do with your current change, but seems relevant for the "big-picture"
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.
Ah I didn't realize that. I could try and replace it.
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.
Yup! Just about all of the CompareInBounds
calls are a little overkill. They actually are the cause of a lot of FAILFAST
issues we've had in accessibility code. We may even be able to remove the extra bool parameter off of CompareInBounds if we make this happen. That's why I get really excited as we adopt til::point
more in our codebase haha
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.
72/76. Mostly tests are left. I also want to re-review the til::rect changes themselves. Looking good! :)
// Create rectangular block representing where the cursor can fill. | ||
D2D1_RECT_F rect = til::rectangle{ til::point{ options.coordCursor } }.scale_up(glyphSize); |
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.
scale_up(til::size)
seemed useful here. What was the particular reason to remove it?
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.
I found this code in particular so incredibly hard to thoroughly understand that I changed it into this C-style code. In order to understand the existing code you have to know that:
til::point
has a constructor forCOORD
(options.coordCursor
)til::rectangle
has a constructor for a point without size, which creates a rectangle at that origin of size 1x1scale_up
multiplies the size of the rectangle, but not the origintil::rectangle
implicitly turns into aD2D1_RECT_F
using a conversion operator
The interaction between the second and third point were very confusing for me and it took me more time to understand that code than I'd like to admit. 😄 I'd be fine with this code:
D2D1_RECT_F rect = til::rectangle{ til::point{ options.coordCursor }, glyphSize };
But at that point I asked myself why you'd want to construct a til::rectangle anyways, just to turn it into a D2D1_RECT_F
right after. If you'd like me to use that alternative code anyways, I'd be absolutely fine doing so of course! But personally I preferred the C-style code.
const auto real = relative / GetCurrentDpiScale(); | ||
const auto scale = GetCurrentDpiScale(); | ||
const til::point real{ til::math::flooring, relative.x / scale, relative.y / scale }; |
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.
Why can't we keep relative/GetCurrentDpiScale()
?
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.
The previous code didn't specify the exact til::math::*
rounding mode to use. This one does.
This fixes at least one bug in our code where we use til::point / float
, which implicitly does a flooring narrow, instead of a more appropriate til::math::round
.
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.
Finally finished! 🎉🥳 Looks great! Excited to see this land 🙂
Most of the changes are really just...
til::rectangle
-->til::rect
- implicit --> explicit conversion
So going through most of these files are pretty easy. Anything that isn't that, I've pointed out and you've done a good job of explaining your reasoning.
I like details::extract
. It's a nice way to simplify a lot of the assignment and add some "built-in" validation.
Great work my dude 👍
cbbed89
to
6b0f328
Compare
This comment has been minimized.
This comment has been minimized.
6b0f328
to
1bf8011
Compare
I've rebased the last commit a few times so that there's only one additional commit to review since my initial one. |
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.
You know, I'm not sure I'm qualified to be the person to give the second ✔️ on the til
stuff. Most of this looks fine. The GenerateTests.ps1
one definitely needs fixing. But I think I'd be more comfortable with @miniksa / @DHowett's approval, since they wrote most of these originally.
I personally really liked the implicit conversions, I feel like that was a part of what made til
so magic. But if we need to get rid of them, then I get it. So long as there's still magic constructors from anything
to the til types, then I'll be happy.
const auto distanceSquared = dx * dx + dy * dy; | ||
const auto maxDistanceSquared = w * w / 16; // (w /4)^2 | ||
|
||
if (distanceSquared >= maxDistanceSquared) |
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.
is there any meaningful difference in behavior (besides just not doing a sqrt
call) here by comparing squared distances vs the original?
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.
No. Unless I made a weird mistake, the functionality is exactly the same. 🙂
The change is necessary since the old code wouldn't compile otherwise. Since a change was necessary I changed the distance check to a simpler standard distance check. In my experience it's rather unusual to use sqrt for that.
It's safer to just square the other side of the equation - no NANs & no explicit static_cast casts (which would've been necessary here).
src/interactivity/win32/ut_interactivity_win32/GeneratedUiaTextRangeMovementTests.g.cpp
Show resolved
Hide resolved
I agree with this sentiment.
But after Leonard was explaining to me that the implicits were making a whole bunch of errors and thrashing... I can live with the change to be more explicit. I meant to eliminate bug factories with the til types, not turn them into one. |
e949c5b
to
9037412
Compare
Sorry for the force-push! I wanted to ensure that people who have reviewed before only need to review a single new commit.
|
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.
Let's do this!
Hello @lhecker! Because this pull request has the p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (
|
🎉 Handy links: |
This commit makes the following changes to
til::point/size/rectangle
for the following reasons:
rectangle
intorect
This will make the naming consistent with a later
small_rect
structas well as the existing Win32 POINT/SIZE/RECT structs.
int32_t
instead ofptrdiff_t
Provides a consistent behavior between x86 and x64, preventing accidental
errors on x86, as it's less rigorously tested than x64. Additionally it
improves interop with MIDL3 which only supports fixed width integer types.
gsl::narrow_error
Makes the behavior of our code more consistent.
constexpr
Because why not.
This is a complex and controversial topic. My reasons are: You can't Ctrl+F
for an implicit conversion. This breaks most non-IDE engines, like the one on
GitHub or those we have internally at MS. This is important for me as these
implicit conversion operators aren't cost free. Narrowing integers itself,
as well as the boundary checks that need to be done have a certain,
fixed overhead each time. Additionally the lack of noexcept prevents
many advanced compiler optimizations. Removing their use entirely
drops conhost's code segment size by around ~6.5%.
References
Preliminary work for #4015.
PR Checklist
Validation Steps Performed
I'm mostly relying on our unit tests here. Both OpenConsole and WT appear to work fine.