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.
Our bilinear scaling logic worked well for upscaling, but during
downscaling the bitmap was often shifted one pixel to the bottom right.
This is a common problem, described here in more detail:
https://bartwronski.com/2021/02/15/bilinear-down-upsampling-pixel-grids-and-that-half-pixel-offset/
Fix it by calculating coordinate shift values that align the pixel's
boundaries between the source and target pixels before selecting the
source pixels to interpolate.
This is a reimplementation of draw_triangle that manages without
floating point arithmetic.
It's most important property, compared to the previous implementation is
that rotating the same triangle 90 degrees won't drastically change the
appearance of that triangle. (it did before)
If you wanted to upscale an image, you had two options:
- use Nearest Neighbor: it's probably a good choice. The image stays
sharp.. unless you aren't using integer scales.
- use Bilinear blending, but this on the other hand, doesn't handle
upscaling well. It just blurs everything.
But what if we could take the best of both of them and make the image
sharp on integers and just blur it a little when needed?
Well, there's Smooth Pixels!
This mode is similar to the Bilinear Blend, with the main difference
is that the blend ratio is multiplied by the current scale, so the blur
on corners can be only 1px wide.
From my testing this mode doesn't handles downscaling as good as the
Bilinear blending though.
The added precision of doubles is most likely not needed here and floats
are usually cheaper than doubles, so lets always stick to them.
This also simplifies some calls to sin+cos to AK:sincos and a call to
atan(1/x) to atan2(1,x) to avoid a division.
Previously draw_text_run only passed a single code point to
draw_glyph_or_emoji. This lead e.g. to broken unicode flag support.
Improve this by passing along the code_point iterator, so the emoji code
can detect the correct emojis and advance it as needed.
This API does:
- Take a Utf8View
- Take the starting point on the baseline as its input coordinate
This API does not:
- Align the text
- Wrap the text
- Elide too-long text into "..."
This reverts commit 2b2915656d.
While this adjustment is bogus, it is currently responsible for putting
CenterLeft aligned scalable text in the right position.
This is going to take a bunch of work to get right.
There was an off-by-one bug in `Painter::do_draw_scaled_bitmap` where
the last column and row of the source bitmap would be skipped. This was
especially visible in PixelPaint when zooming in and out on smaller
images.
Instead of the top/left of the pixel, we now use the bottom/right side
of the pixel as a threshold to stop drawing.