CSSPixelFraction::to_float() and to_double() were converting to
CSSPixels (6-bit fixed-point) before converting to float/double,
which truncated the result to 1/64 precision. For example, 500/2500
(= 0.2) became 12/64 (= 0.1875).
Fix by dividing the numerator and denominator as floats/doubles
directly, which is what every other browser engine does when
converting layout units to floating-point ratios.
This was an oversight in the original CSSPixelFraction implementation
(commit 8cd1f65507). The class was designed for lossless comparison
and multiply-then-divide operations (which stay in CSSPixels land),
and the to_float/to_double methods were convenience additions that
took the easy path through CSSPixels conversion without considering
the precision loss.
Make CSSPixels::to_float(), to_double(), and to_int() constexpr inline
instead of out-of-line in the .cpp file. These are trivial one-liners
called in very hot painting paths.
Also optimize DevicePixelConverter::rounded_device_rect() to work
directly with CSSPixels values instead of constructing an intermediate
Rect<double> and scaling it.
When the mouse is dragged from inside a scrollable container to outside
of it, we now automatically scroll the container so the selection can be
extended. Scroll speed scales with the distance past the scrollport
edge, capped at a maximum. Edges close to the viewport boundary get a
wider activation zone so the speed ramp works predictably even when the
mouse has limited room to move.
The logic is encapsulated in AutoScrollHandler, which EventHandler
creates lazily on mouse selection start.
We've historically asserted that no "saturated" size values end up as
final metrics for boxes in layout. This always had a chance of producing
false positives, since you can trivially create extremely large boxes
with CSS.
The reason we had those assertions was to catch bugs in our own engine
code where we'd incorrectly end up with non-finite values in layout
algorithms. At this point, we've found and fixed all known bugs of that
nature, and what remains are a bunch of false positives on pages that
create very large scrollable areas, iframes etc.
So, let's change it! We now clamp content width and height of boxes to
17895700 pixels, apparently the same cap as Firefox uses.
There's also the issue of calc() being able to produce non-finite
values. Note that we don't clamp the result of calc() directly, but
instead just clamp values when assigning them to content sizes.
Fixes#645.
Fixes#1236.
Fixes#1249.
Fixes#1908.
Fixes#3057.