Previously we were inconsistent by generating code for enum definitions
but not generating code for dictionaries. With future changes to the
IDL generator to expose helpers to convert to and from IDL values
this produced circular depdendencies. To solve this problem, also
generate the dictionary definitions in bindings headers.
DecodedImageFrame only wraps a ref-counted Bitmap and color-space
metadata. The frame object itself does not provide shared mutable
state or lifetime ownership beyond those members, so ref-counting it
adds an unnecessary layer of indirection.
DecodedImageFrame now owns decoded bitmap pixels directly, so the
separate ImmutableBitmap wrapper no longer carries useful semantics.
Remove the class and pass decoded image frames or bitmaps at the
boundaries where pixels are actually required.
The Skia image cache now keys off DecodedImageFrame, matching the
display-list commands that paint decoded images. Video frames stay
owned by LibMedia, with the explicit YUV-to-bitmap conversion living
at HTMLVideoElement's decoded-frame entry point for canvas and WebGL
callers.
Decoded image data should not continue to traffic in ImmutableBitmap now
that the bitmap wrapper is being retired. Introduce DecodedImageFrame as
the paintable decoded-image unit and store a Bitmap plus ColorSpace in
it directly.
Thread the new frame type through decoded image data, display-list
image commands, filters, canvas drawImage, patterns, WebGL texture
upload, and CSS/SVG image consumers. ImmutableBitmap remains only at
the legacy boundaries that still need it, such as HTML video snapshots
and callers that explicitly ask for a bitmap snapshot.
This keeps color-space ownership with the decoded frame while making
the expensive or legacy ImmutableBitmap path explicit at the few call
sites that still need it.
ImmutableBitmap still owned the helper that read pixels from a
PaintingSurface and wrapped the result as an ImmutableBitmap. That kept
a surface readback operation attached to the type we are trying to
remove, even though the snapshot is really a property of the painting
surface.
Add PaintingSurface::snapshot_bitmap() as the explicit readback path.
The remaining callers now wrap that bitmap in ImmutableBitmap only at
the places that still need the old abstraction. Canvas serialization
also uses the same helper, so the BGRA8888 premultiplied snapshot
policy has a single owner.
Decoded video frames should own their planar YUV data and color space
directly. Keeping that storage behind ImmutableBitmap gave a
still-image abstraction media-specific behavior and made calls like
bitmap() potentially allocate and convert a whole video frame.
Move YUV ownership into Media::VideoFrame, where the lifetime naturally
follows media playback, and remove the YUV-backed mode from
ImmutableBitmap. This commit intentionally keeps the visible Web paint
path on ExternalContentSource by converting the current frame back to
an ImmutableBitmap where Web still expects one.
Callers that need pixels now ask the frame to convert explicitly. That
preserves behavior for canvas and bitmap consumers while making the
expensive YUV-to-pixel path visible at the call site instead of
hiding it behind ImmutableBitmap::bitmap().
Previously, the LibWeb bindings generator would output multiple per
interface files like Prototype/Constructor/Namespace/GlobalMixin
depending on the contents of that IDL file.
This complicates the build system as it means that it does not know
what files will be generated without knowledge of the contents of that
IDL file.
Instead, for each IDL file only generate a single Bindings/<IDLFile>.h
and Bindings/<IDLFile>.cpp.
Canvases belonging to `OffscreenCanvas` and disconnected
`HTMLCanvasElement`s use a LRC based on the initial canvas context font
size of 10px.
This will be covered by WPT tests in a later commit once we expose the
absolutized value in the font getter
This introduces two new top-level `ValueParsingContext`s,
`OnScreenCanvasContextFontValue` and `CanvasContextGenericValue`, while
these are handled the same for now, there is a distinction is whether or
not they allow tree counting functions (which will come in a later
commit)
Previously we simply serialized a concatenation of the longhand
properties, now we use the correct `font` serialization logic
implemented within `ShorthandStyleValue::serialize`
When setting to a non-string value (i.e. a `CanvasGradient` or
`CanvasPattern`) we would accidentally update the fill style instead of
the stroke style.
When a canvas belongs to a detached document (e.g. one created via
document.implementation.createHTMLDocument()), document->window()
returns null, causing a null pointer crash in set_font.
Use Length::ResolutionContext::for_document() instead of for_window(),
which handles the no-navigable case gracefully and is already the
recommended pattern (per existing FIXME in Length.h). This also fixes
the same crash path via fillText, strokeText, and measureText which
trigger lazy font initialization through set_font.
Fixes#8515.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Previously we computed font properties separately from other properties
for two reasons:
1) These font properties were computed using a different length
resolution context than the rest of the properties.
2) These properties were required to be computed before creating the
length resolution context for the rest of the properties.
The first issue was solved in the previous commit by introducing a
generic method to get the computation context for a property, and
the second is solved in this commit by computing properties in the
required order.
This simplifies the code a bit and opens up some opportunities for
optimization.
When a WebGL canvas is used as a CanvasImageSource, the underlying
PaintingSurface may not yet reflect the most recent GL commands.
This caused drawImage() to capture stale or empty content unless
gl.flush() was called manually from JS.
Call HTMLCanvasElement::present() before creating the snapshot so
that WebGL content is properly synchronized with the surface prior
to readback.
Fix#7901
Remove 11 heavy includes from Document.h that were only needed for
pointer/reference types (already forward-declared in Forward.h), and
extract the nested ViewportClient interface to a standalone header.
This reduces Document.h's recompilation cascade from ~1228 files to
~717 files (42% reduction). Headers like BrowsingContext.h that were
previously transitively included see even larger improvements (from
~1228 down to ~73 dependents).
Previously we would resolve font features
(https://drafts.csswg.org/css-fonts-4/#feature-variation-precedence)
per element, while this works for the current subset of the font feature
resolution algorithm that we support, some as yet unimplemented parts
require us to know whether we are resolving against a CSS @font-face
rule, and if so which one (e.g. applying descriptors from the @font-face
rule, deciding which @font-feature-values rules to apply, etc).
To achieve this we store the data required to resolve font features in a
struct and pass that to `FontComputer` which resolves the font features
and stores them with the computed `Font`.
We no longer need to invalidate the font shaping cache when features
change since the features are defined per font (and therefore won't ever
change).
This saves us from having our own color conversion code, which was
taking up a fair amount of time in VideoDataProvider. With this change,
we should be able to play high resolution videos without interruptions
on machines where the CPU can keep up with decoding.
In order to make this change, ImmutableBitmap is now able to be
constructed with YUV data instead of an RBG bitmap. It holds onto a
YUVData instance that stores the buffers of image data, since Skia
itself doesn't take ownership of them.
In order to support greater than 8 bits of color depth, we normalize
the 10- or 12-bit color values into a 16-bit range.
This adds visit_edges(Cell::Visitor&) methods to various helper structs
that contain GC pointers, and makes sure they are called from owning
GC-heap-allocated objects as needed.
These were found by our Clang plugin after expanding its capabilities.
The added rules will be enforced by CI going forward.
It is not guaranteed that inherited classes have the same address as the
base of the derived class. In that case a reinterpret cast leads to
undefined behavior. This occured on msvc ABI. See:
https://godbolt.org/z/jGeEW3c48
Co-authored-by: ayeteadoe <ayeteadoe@gmail.com>
Font computation and loading is distinct enough from style computation
that it makes more sense to have this in it's own class.
This will be useful later when we move the font loading process to
`ComputedProperties` in order to respect animated values.
Since we resolve any relative lengths at compute time there's no need
for the value to be passed around as a `NumberOrCalculated` and we can
just resolve it within `ComputedProperties::font_variation_settings`.
The only place this is used it is used with value_or so there's no need
to return it is an `Optional`.
This is only used for loading fonts (which occurs during style
computation) so there's no need to store it in `ComputedValues`
Integrates the new `FontVariationSettings` from LibGfx into LibWeb to
enable initial variable font functionality. Currently, only the `wght`
(weight) axis is fully supported and tested. This update also introduces
support for the CSS `font-variation-settings` property.
When direction is 'rtl':
- textAlign='start' now aligns text to the right
- textAlign='end' now aligns text to the left
Fixes the FIXME at CanvasRenderingContext2D.cpp:283
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.
In this case, we should just draw a line from the last point in the
path to the start point. Previously, a division by zero caused nothing
to be drawn.
Since we now have access to the `AbstractElement` through the
`ComputationContext` we can just set the flag that this element relies
on tree counting functions directly, no need to pass this struct around.
Passing the `AbstractElement` rather than the
`TreeCountingFunctionResolutionContext` allows us to only compute the
resolution context when necessary (i.e. when we actually need to resolve
a tree counting function)