If the for loop's body is not block terminated, we will generate a Jump
to the end block which will block terminate the body. Then, we ended
the lexical variable scope if needed. However, since the body is now
block terminated, the "LeaveLexicalEnvironment" instruction that is
generated by end_variable_scope is now dropped on the floor.
This fixes this by moving it to the beginning of the end block.
Previously we only did this if the body block was not terminated.
If it was, all future codegen would happen in this block terminated
body block until another switch occurred, dropping all generated
instructions in this time on the floor.
newlib has an extra character slot at the beginning to enable some
macro tricks that cause a warning when someone passes a type that's not
"int" into a ctype function. Our deviation from this causes issues for
LLVM.
Previously we were hand-writing all the Zlib and raw Deflated data
structures here, but now PNGs will be compressed using ZlibCompressor
which will actually try to compress something! :^)
Note that we don't do any filtering that should help compress data even
more, but even now the results are pretty good:
- screenshots of my Serenity desktop are take now about 55 KiB, where
previously it was 3 MiB.
- re-encoding NASA photo of the Earth[1] to PNG shows a 2x improvement
(34.3 MiB -> 16.5 MiB).
[1]: https://commons.wikimedia.org/wiki/File:The_Blue_Marble_(remastered).jpg
When swapping both values to perform the actual calculation, we need to
consider that `A + B == B + A`, but `A - B != B - A`, so turn it into
`-B + A`.
Co-Authored-By: Sam Atkins <atkinssj@serenityos.org>
These functions were changed to synchronous in #13870 but
the async_ versions were still being called. This led to
frequent crashes when loading local files in Browser.
The new min_content_size value is to be set by the subclasses, it is
then used to determine if the scrollbars should be shown after a
resize, but before the content size will be calculated by the following
layout pass.
This function is intended to propagate layout changes upwards in the
widget hierarchy. Widgets that can know what to do with this
information without causing a full layout invalidation (i.e. just
because one of their child widgets changed layout/size, doesn't
necessairily mean that they have to change their layout/size) can
override this and prevent a full relayout and redraw.
The default size for label is always a compromise, no matter what value
is chosen, some layouts will require local manual overrides.
Having the preferred size be opportunistic_grow in both directions seems
like it's currently the option that works without modification in most
cases.
This commit adds some finagling and shrinking of the corner bitmap
to handle drawing shadows on elements where the shadow radius >
half the width or height of the element. Previously things would
go horribly wrong when this happend.
There could still be some edge cases, but things seem to be working
fairly well now.
This fixes a issue due to the background/border painting using
.to_rounded<int>() to get an IntRect, but shadow painting was using
enclosing_int_rect().
enclosing_int_rect() uses some floors/ceils and does not always match
.to_rounded<int>().
This now allows passing a 'fill_color' to the blur, any fully
transparent pixels will be replaced with this color (with the alpha
set to 0).
For box-shadows, if this color is set to the same as the shadow,
the issues around the fringes are fixed. This also fixes some places
where dark shadows appeared light / the wrong color.
With this change the blur no longer dominates the profile. On my PC
it is down to 27% (which is the same as the AA ellipse painting).
The box-shadow.html test page now also feels more responsive.
This adds an implementation of StackBlur which is a very efficient
blur that closely approximates a gaussian blur. It has a number of
benefits over the existing FastBoxBlurFilter:
1. It's faster (~half the pixel lookups of a single box blur pass)
2. It only requires a single pass over image to produce good results
- (Rather than the 3 the box blur requires)
3. It only needs to allocate a buffer of `blur_radius * 2 + 1` colors
- These easily fits on the stack for any reasonable radius
For a detailed explanation of the algorithm check out this link:
https://observablehq.com/@jobleonard/mario-klingemans-stackblur
Previously we forwarded all event handler attributes to Window from
these two elements, however, we are only supposed to forward blur,
error, focus, load, resize and scroll.
Before this, the spacers were handled as just another child widget, and
as such could take away space from real widgets when growing.
This also fixes the problem of effectively 0 sized spacers, that doubled
the spacing between the widgets they were placed between.