This improves fill_path() performance by adding an API to the painter
that allows painting an entire scanline rather than just a pixel.
With this paths can be clipped a scanline at a time rather than each
pixel, removing a fair amount of checks.
Along with optimized clipping, this can now use a fast_u32_fill() to
paint all but the subpixels of a scanline if a solid color with no
alpha channel is used (which is quite common in SVGs).
This reduces scrolling around on svg.html from 21% in set_pixel() and
19% in fill_path() to just 7.8% in fill_path (with set_pixel()
eliminated). Now fill_path() is far from the slowest code when
scrolling the page.
This class had slightly confusing semantics and the added weirdness
doesn't seem worth it just so we can say "." instead of "->" when
iterating over a vector of NNRPs.
This patch replaces NonnullRefPtrVector<T> with Vector<NNRP<T>>.
Ultimately, we should find a way to route all emoji access through
the font code, but for now, this patch adds a special case for fonts
that are known to have embedded color bitmaps so we can test them.
This patch does three things:
- Font::has_color_bitmaps() (true if CBLC and CBDT are present)
- Glyph now knows when its bitmap comes from a color bitmap font
- Painter draws color bitmap glyphs with the appropriate scaling etc
This API is used by LibWeb's text painter. Bring it up to date with the
glyph width computations performed in draw_text_line() used by other GUI
applications.
This reverts commit eb1ef59603c13c43b87c099c43c4d118dc8441f6.
The idea of saving clip box to apply it to handle `overflow: hidden`
turned out to break painting if box is painted before it's containing
block (it is possible if box has negative z-index).
For example, consider the Pirate Flag emoji, which is the code point
sequence U+1F3F4 U+200D U+2620 U+FE0F. Our current emoji resolution does
not consider U+200D (Zero Width Joiner) as part of an emoji sequence.
Therefore fonts like Katica, which have a glyph for U+1F3F4, will draw
that glyph without checking if we have an emoji bitmap.
This removes some hard-coded code points and consults the UCD's code
point properties for emoji sequence components and variation selectors.
This recognizes the ZWJ code point as part of an emoji sequence.
Currently, we compute the width of text one code point at a time. This
ignores grapheme clusters (emoji in particular). One effect of this is
when highlighting a multi-code point emoji. We will errantly increase
the highlight rect to the sum of all code point widths, rather than
just the width of the resolved emoji bitmap.
The new Painter::set_clip_rect(IntRect) API was able to make the clip
rect larger than the underlying target bitmap. This was not good, as it
could make it possible to draw outside the bitmap memory.
Fixes a crash when viewing https://twinings.co.uk/ in the browser. :^)
Previously checkerboard patterns were anchored to the top left of the
bitmap they were being drawn into.
This makes the transparency grid in PixelPaint static relative to the
canvas when panning.
This means fill_path() now paints the scanlines its self rather than
calling draw_line() which easily allows each pixel along the scanline
to have a different color.
This moves the CSS gradient painting to the painter creating:
- Painter::fill_rect_with_linear_gradient()
- Painter::fill_rect_with_conic_gradient()
- Painter::fill_rect_with_radial_gradient()
This has a few benefits:
- The gradients can now easily respect the painter scale
- The Painter::fill_pixels() escape hatch can be removed
- We can remove the old fixed color stop gradient code
- The old functions are now just a shim
- Anywhere can now easily use this gradient painting code!
This only leaves the color stop resolution in LibWeb (which is fine).
Just means in LibGfx you have to actually specify color stop positions.
(Also while here add a small optimization to avoid generating
excessively long gradient lines)
This is achieved by simplifying the logic in TextLayout. We get rid
of all the various ways that the layout bounding rect can get cropped.
Then we make sure to use the right pixel metrics.
Finally we use the font's own line gap metrics instead of hard-coding 4.
The end result is that text painted with vector fonts now gets pretty
reasonable vertical alignment in most cases.
This function fills a region of pixels with the result of a callback
function. This is an alternative to a for loop that repeatedly calls
Painter::set_pixel(), which can get very expensive due to the clipping
checks set_pixel() does each call.
Without this change, the upcoming LibWeb pixel types will require a
silly doubled conversion in some places.
eg: `some_rect.to_type<int>().to_type<float>()`
With these overloads, we can get away with `some_rect.to_type<int>()`.
Gfx::Color is always 4 bytes (it's just a wrapper over u32) it's less
work just to pass the color directly.
This also updates IPCCompiler to prevent from generating
Gfx::Color const &, which makes replacement easier.
This will make it easier to support both string types at the same time
while we convert code, and tracking down remaining uses.
One big exception is Value::to_string() in LibJS, where the name is
dictated by the ToString AO.
We have a new, improved string type coming up in AK (OOM aware, no null
state), and while it's going to use UTF-8, the name UTF8String is a
mouthful - so let's free up the String name by renaming the existing
class.
Making the old one have an annoying name will hopefully also help with
quick adoption :^)
This PR adds resize ability to PixelPaint as per issue 11862.
The previous behaviour was to always rescale the canvas when
resizing an image. This adds a checkbox to toggle between
rescaling, and resizing which blits the existing canvas to
the top left of the new, resized canvas.
As part of this, a new ScalingMode is added to
LibGfx - None.
Doesn't use them in libc headers so that those don't have to pull in
AK/Platform.h.
AK_COMPILER_GCC is set _only_ for gcc, not for clang too. (__GNUC__ is
defined in clang builds as well.) Using AK_COMPILER_GCC simplifies
things some.
AK_COMPILER_CLANG isn't as much of a win, other than that it's
consistent with AK_COMPILER_GCC.
This will be needed so we can apply filter effects to the backdrop
of an element in LibWeb.
This now also allows getting a crop of a bitmap in a different format
than the source bitmap. This is for if the painter's bitmap does not
have an alpha channel, but you want to ensure the cropped bitmap does.
In some artificial full screen blitting profiling, I've seen `memcpy`
take up about 4% fewer samples each time I measure. It seems like
`fast_u32_copy` is not as fast as it'd like to believe.