Commit Graph

621 Commits

Author SHA1 Message Date
InvalidUsernameException
ce2c4a3417 LibGfx+LibWeb: Fix compile errors in clang-cl from recent header cleanup
The recent commits 28ba610f32 and
70c4ed261f adjusted some include
directives to avoid excessive recompilation when changing some header
files. This has broken compilation with clang-cl on Windows without
getting noticed before the PRs were merged.
2025-11-30 08:45:29 -05:00
InvalidUsernameException
1f8a42c367 LibGfx: Add a test for bitmap export
The verified pixel output in this test just reflects currently observed
behavior, I have not verified that all cases output the correct data wrt
what the spec expects.
2025-11-28 18:32:48 +01:00
InvalidUsernameException
a81e407c44 LibWeb: Do not crash when converting a bitmap to RGB888
This makes it so that we can visit satellite and hybrid view on
maps.apple.com. Previously this would crash from a bounds check due to
us asking Skia to write 32bpp RGBx8888 data into a buffer sized for
24bpp RGB888.
2025-11-28 18:32:48 +01:00
InvalidUsernameException
9e60dc57b4 LibGfx: Add FIXME about potentially incorrect alpha handling 2025-11-28 18:32:48 +01:00
InvalidUsernameException
6847185d9a LibGfx: Mask alpha values when setting pixels on non-alpha bitmaps
This is not technically necessary, presumably the bitmap type does not
offer any guarantees about what values are stored in the alpha component
for non-alpha pixel formats.

But the previous behavior meant that `set_pixel()` would produce
different values in the alpha component depending on whether the bitmap
format was RGBx or BGRx (i.e. `color.alpha()` vs. 0x00), which can be a
bit confusing.
2025-11-28 18:32:48 +01:00
InvalidUsernameException
88c4814de6 LibGfx+LibWeb: Extract bitmap-to-buffer conversion into LibGfx
This factors the conversion logic to be independent from WebGL code,
allowing us to write unit tests for it that can run in CI (since WebGL
can't run in CI).
2025-11-28 18:32:48 +01:00
InvalidUsernameException
fa181c2be8 LibGfx: Do not over-promise what type gets returned 2025-11-28 18:32:48 +01:00
InvalidUsernameException
7c315ef67f Everywhere: Unify naming of RGBA-like colors
The `Bitmap` type was referring to to its internal pixel format by a
name that represents the order of the color components as they are layed
out in memory. Contrary, the `Color` type was using a naming that where
the name represents the order of the components from most to least
significant byte when viewed as a unsigned 32bit integer. This is
confusing as you have to keep remembering which mental model to use
depending on which code you work with.

To unify the two, the naming of RGBA-like colors in the `Color` type has
been adjusted to match the one from the Bitmap type. This seems to be
generally in line with how web APIs think about these types:
* `ImageData.pixelFormat` can be `rgba-8unorm` backed by a
  `Uint8ClamedArray`, but there is no pixel format backed by a 32bit
  unsigned type.
* WebGL can use format `RGBA` with type `UNSIGNED_BYTE`, but there is no
  such format with type `UNSIGNED_INT`.

Additionally, it appears that other browsers and browser-adjacent
libraries also think similarly about these types:
* Firefox:
  https://github.com/mozilla-firefox/firefox/blob/main/gfx/2d/Types.h
* WebKit:
  https://github.com/WebKit/WebKit/blob/main/Source/WebCore/platform/graphics/PixelFormat.h
* Skia:
  https://chromium.googlesource.com/skia/+/refs/heads/main/include/core/SkColorType.h

This has the not so nice side effect that APIs that interact with these
types through 32bit unsigned integers now have the component order
inverted due to little-endian byte order. E.g. specifying a color as hex
constant needs to be done as `0xAABBGGRR` if it is to be treated as
RGBA8888.

We could alleviate this by providing endian-independent APIs to callers.
But I suspect long-term we might want to think differently about bitmap
data anyway, e.g. to better support HDR in the future. However, such
changes would be more involved than just unifying the naming as done
here. So I considered that out of scope for now.
2025-11-28 18:32:48 +01:00
InvalidUsernameException
07f61f2cec LibGfx: Remove redundant enum
With the templatized overload of set_pixel() gone, there is no reason to
have two separate enums anymore.
2025-11-28 18:32:48 +01:00
InvalidUsernameException
645052b87e LibGfx: Remove some unused function overloads 2025-11-28 18:32:48 +01:00
InvalidUsernameException
28ba610f32 Everywhere: Avoid large rebuilds when editing (Immutable)Bitmap headers
This reduces the number of recompiled files as follow:
- Bitmap.h: 1309 -> 101
- ImmutableBitmap.h: 1218 -> 75
2025-11-28 18:32:48 +01:00
InvalidUsernameException
40f089a043 LibGfx: Sort source files alphabetically 2025-11-28 18:32:48 +01:00
InvalidUsernameException
bc44203744 LibGfx+Tests: Load bmp files with unpremultiplied alpha
From what I can tell BMP files with an alpha channel always store
unpremultiplied alpha. So let's load them as such to avoid rendering
artifacts from using the wrong alpha type.
2025-11-28 17:00:29 +01:00
Jelle Raaijmakers
3b7eede694 LibGfx: Report premultiplied alpha type for opaque Skia surfaces
We don't discern between opaque and non-opaque alpha types in LibGfx,
which at some point we might need to do. But for now, assume all opaque
Skia surfaces have premultiplied alpha.

Fixes #6892.
2025-11-26 09:24:38 +01:00
ayeteadoe
59c963f98f Meta+LibGfx: Remove fontconfig dependency on Windows
Previously when launching a UI process and/or a WebContent process on
Windows, the following message would be output to the console:

Fontconfig error: Cannot load default config file: No such file: (null)

Apparently on Windows, you have to provide a font .conf file to
fontconfig explicitly. Since we are not doing that, the default fonts
that are backed off to are not ideal.

Similar to how we aren't using fontconfig on Android, Windows also has
native font infrastructure in terms of both a collection of System
installed fonts as well as skia support for font managers that use
native Windows APIs. With that, we can remove the usage of fontconfig
entirely and improve the fonts used on websites like ladybird.org or
google.com.
2025-11-22 07:51:55 -05:00
Tim Ledbetter
36c6079dbc LibWeb+LibGfx: Implement SVGFEMorphologyElement
This filter primitive is used to erode or dilate an image.
2025-11-15 16:08:53 +01:00
Jelle Raaijmakers
3f6cbeb87e LibGfx+LibWeb: Use mipmaps for downscaling images
This changes Gfx::ScalingMode to reflect the three modes of scaling we
support using Skia, which makes it a bit easier to reason about the mode
to select. New is ::BilinearMipmap, which uses linear interpolation
between mipmap levels to produce higher quality downscaled images.

The cubic resampling options Mitchell and its sibling CatmullRom both
produced weird artifacts or resulted in a worse quality than
BilinearMipmap when downscaling. We might not have been using these
correctly, but the new ::BilinearMipmap method seems to mirror what
Chrome uses for downscaled images.
2025-11-12 15:59:01 +01:00
Jelle Raaijmakers
b4810f47a3 LibWeb: Hook up SVG component transfer filter to Skia 2025-11-09 01:22:48 +01:00
Andreas Kling
baa9b6cc34 LibWeb: Prefer non-emoji font when deciding width of space between words
This fixes an issue where having an emoji font first in the font-family
cascade list would cause us to get the space width from the emoji font
as well.

We now look at adjacent text chunks when deciding which font to use for
space widths, instead of just blindly obeying the font-family value.
2025-11-06 23:42:01 +01:00
Andreas Kling
0fc0c84856 LibGfx: Add Font API to determine if it's (probably) an emoji font
This uses some heuristics since I don't think there's a simple way to
determine if something is "an emoji font".
2025-11-06 23:42:01 +01:00
Tim Ledbetter
713191a078 LibGfx: Remove unused alpha premultiplication functions 2025-11-05 15:39:14 +01:00
Tim Ledbetter
d37eb3de32 LibGfx: Use Skia to speed up alpha conversions on Linux 2025-11-05 15:39:14 +01:00
Tim Ledbetter
706d075835 LibGfx: Don't attempt alpha conversion for opaque images 2025-11-05 15:39:14 +01:00
Aliaksandr Kalenik
ed921b66f5 LibGfx+LibWeb: Delete unused Line class and Rect methods 2025-11-04 23:16:02 +01:00
norbiros
aa5b3ff95a LibGfx: Pass font variation settings to HarfBuzz
Enhance `Font::harfbuzz_font()` to include font variation information
when creating HarfBuzz fonts. This required updating the `Font` struct
to store details about font variations.

I wasn’t aware of this, but it also fixed some visual artifacts with
variable fonts, so big thanks to @Lubrsi for the suggestion!
2025-11-04 21:44:32 +01:00
norbiros
489381698f LibGfx: Introduce FontVariationSettings
This change lays the groundwork for variable font support in LibWeb.
FontVariationSettings enables customization of existing font axes such
as weight (wght) and width (wdth).
2025-11-04 21:44:32 +01:00
norbiros
a01360832c LibGfx: Implement comparison operator and hash function for FourCC 2025-11-04 21:44:32 +01:00
Tim Ledbetter
e1ff1e2095 LibWeb: Implement CanvasPattern.setTransform()
This method applies the given transformation matrix to a pattern.
2025-10-27 16:41:02 -07:00
Tim Ledbetter
8854bb62c6 LibGfx: Use CSS sRGB serialization for canvas fill styles 2025-10-26 18:55:22 +01:00
Tim Ledbetter
ebd802f6fc LibWeb+LibGfx: Move CSS sRGB color serialization function to LibGfx 2025-10-26 18:55:22 +01:00
Jelle Raaijmakers
86725de23d LibGfx: Use correct include path for SkImage.h
Fixes our flatpak builds.
2025-10-24 12:44:24 +02:00
Andreas Kling
4f684bb4c9 LibGfx: Don't create AnonymousBuffer for each bitmap in BitmapSequence
When decoding a BitmapSequence received over IPC, we were creating an
AnonymousBuffer for each bitmap and then making a Gfx::Bitmap wrapper
around it.

This was unnecessarily using up one file descriptor per bitmap, and also
wasting a lot of memory for small bitmaps since we always allocated at
least one VM page.

This patch changes the BitmapSequence decoder to use malloc memory
instead, saving file descriptors and using less memory overall.
2025-10-24 08:52:53 +02:00
Tim Ledbetter
017e8a5b8d LibGfx: Add a method to reset a Painter to its initial state 2025-10-23 18:52:36 +02:00
Jelle Raaijmakers
62ae4e878f LibWeb: Implement support for drawing with CanvasPattern
We already had the API, but drawing to the canvas was not affected by
any created CanvasPattern. This moves CanvasPatternPaintStyle to LibGfx
so we don't have to reach into LibWeb, and implements the plumbing to
let Skia use images as a fill pattern.
2025-10-23 13:20:03 +01:00
Undefine
40bc1c0eb5 LibGfx: Enable Vulkan shared images and WebGL on FreeBSD 2025-10-22 13:54:54 +02:00
Undefine
bfa86f7961 LibGfx: Use PkgConfig to find libdrm
On FreeBSD the libdrm headers are not in a standard location so this
makes the include more portable.
2025-10-22 13:54:54 +02:00
Tim Ledbetter
7db73118e9 LibWeb+LibGfx: Draw shadows for stroke joins and caps 2025-10-21 18:55:08 +02:00
Tim Ledbetter
0516c414d4 LibWeb: Don't draw shadows for transparent gradient fills 2025-10-21 18:55:08 +02:00
aplefull
5df216218b LibGfx: Correctly determine when to invert CMYK
We should invert CMYK data only if color space is JCS_CMYK and either
there is no Adobe marker, or the Adobe transform is 0. Transform 2
indicates YCCK data, which we should not invert.
2025-10-15 21:50:16 +02:00
Tim Ledbetter
e55060ef6e LibWeb: Support the display-p3-linear color space in color functions 2025-10-15 18:40:48 +02:00
ayeteadoe
0d5136ae5c LibWeb: Add support for bitmap scaling in createImageBitmap() 2025-10-14 12:19:33 +02:00
Aliaksandr Kalenik
7ba34e8bd1 LibGfx: Implement AffineTransform::to_matrix() 2025-10-10 15:37:45 +02:00
Lorenz A
1e6ac54b75 LibGfx+LibWeb: Don't display Glyphs that are not on the path 2025-10-08 03:34:53 +01:00
Zaggy1024
1ae7ecc3e9 LibGfx: Free the harfbuzz buffer when measuring text width
I spotted this leak when WebContent was exiting with ASan enabled on a
page with a media element. MediaPaintable calls Gfx::Font::width(),
which calls through to measure_text_width(), which then drops an
hb_buffer_t* without freeing it.
2025-10-03 09:22:22 +02:00
aplefull
b3bdb202f8 LibGfx: Allow decoding of GIFs with empty LZW data
The decoder was requiring GIF files to be at least 32 bytes, but the
actual minimum for a valid GIF is only 26 bytes:
- 6 bytes for the header
- 7 bytes for the Logical Screen Descriptor
- 10 bytes for the Image Descriptor
- 2 bytes for the LZW minimum code size and block terminator
- 1 byte for the GIF trailer

This change allows us to load minimal 1x1 GIFs with empty LZW data.
They are commonly used on the web as transparent placeholders with
minimal file size.
2025-10-02 11:04:35 +02:00
Tim Ledbetter
a00e7cb20b LibWeb: Implement <feComposite> SVG filter 2025-09-30 22:33:12 +01:00
Andreas Kling
321809320b LibWeb+LibGfx: Remove Path::close_all_subpaths()
As it turns out, SkPath already behaves the way we need for SVG and HTML
canvas elements. Less work for us, yay! This removes a 5% item from the
profile when scrolling on https://imdb.com/

Note that there's a tiny screenshot test expectation change due to
minor antialiasing differences when we no longer do our redundant
subpath modifications.
2025-09-25 21:42:52 +02:00
Aliaksandr Kalenik
719a50c9bf LibWeb: Don't emit Push{Pop}StackingContext without visible effect
Before this change we would emit PushStackingContext/PopStackingContext
display list items regardless of whether the stacking context had any
transform/opacity/clip effects.

Display list size on https://x.com/ladybirdbrowser is reduced from ~2700
to ~800 items.
2025-09-23 19:05:01 +02:00
Aliaksandr Kalenik
2cf10981af LibGfx+LibWeb: Implement GlyphRun::bounding_rect()
Allows us to skip painting of glyph runs lying outside of viewport.
2025-09-23 17:55:32 +02:00
Andreas Kling
4eca3781c7 LibGfx: Add fast_is<T> optimization for Typeface and TypefaceSkia 2025-09-22 15:00:50 +02:00