Commit graph

22 commits

Author SHA1 Message Date
Tim Ledbetter
f05bc7c0cd LibWeb: Implement dominant-baseline for SVG text
This property determines the default baseline used to align content
within the given box.
2026-02-26 09:23:23 +01:00
Aliaksandr Kalenik
b41ed92505 LibWeb: Remove Document.h include from Layout/Viewport.h
Move the inline dom_node() method to Viewport.cpp so the header no
longer needs the full Document definition. Add explicit includes to
files that relied on the transitive dependency.
2026-02-08 18:51:13 +01:00
Aliaksandr Kalenik
e190f3ec23 LibWeb: Compute SVG mask/clip transforms using layout tree hierarchy
No observable behavior change — this is a refactoring of how SVG
transforms are computed for mask and clip content.

Previously, SVGGraphicsElement::get_transform() computed accumulated
transforms by walking the DOM tree. This didn't work correctly for masks
and clips because their DOM structure differs from layout: in the DOM,
mask/clip elements are siblings or ancestors of their targets, but in
the layout tree they become children of the target element. Walking the
DOM tree caused transforms from the target's ancestors to incorrectly
leak into mask/clip content.

The fix walks the layout tree instead of the DOM tree, which means
transform computation must happen during layout (where we have access to
the layout tree structure) rather than on-demand from the DOM element.
This moves the logic to SVGFormattingContext and removes get_transform()
since it can no longer serve its purpose — the DOM element only provides
element_transform() for its own transform now.

During layout, we walk up the layout tree and stop at mask/clip
boundaries, ensuring mask/clip content stays in its own coordinate
space. The target's accumulated transform is applied separately at paint
time.
2026-02-05 09:00:56 +01:00
Aliaksandr Kalenik
c3bc64d1cc LibWeb: Fix SVG viewport_size compounding in nested clips
When userSpaceOnUse clips are nested inside objectBoundingBox masks,
the viewport_size was compounding incorrectly because it was calculated
after content scaling by m_parent_viewbox_transform. For userSpaceOnUse
clips (which have no viewBox), the fallback to content_width() returned
the already-scaled value, causing sizes to explode with each nesting
level.

Fix by calculating viewport dimensions before the scaling block. This
ensures m_viewport_size represents the coordinate system dimensions,
not the final pixel dimensions.
2026-01-23 16:23:06 +01:00
Aliaksandr Kalenik
ccffc42d6a LibWeb: Add debug tracing for FormattingContext::run() calls
Add optional tracing that prints a tree visualization of formatting
context `run()` invocations. This is useful for debugging layout issues
where you need to understand the nesting and order of layout passes,
or why a box receives unexpected available space.

Example output:
```
├─ BFC <Viewport<#document>> run(definite(800) x definite(600))
│ ├─ BFC <BlockContainer<HTML>> run(definite(800) x indefinite)
│ │ ├─ IFC <BlockContainer(anonymous)> run(definite(800) x indefinite)
│ │ ├─ GFC <Box<DIV.grid>> run(definite(800) x indefinite)
│ │ │ ├─ BFC <BlockContainer<DIV.item>> run(definite(400) x indefinite)
```
2026-01-09 08:12:21 +01:00
Jelle Raaijmakers
2c5beeabe3 LibWeb: Improve support for SVG text positioning attributes
Previously, we only supported very basic numbers and a single level of
text positioning support in the `x`, `y`, `dx` and `dy` attributes in
`<text>` and `<tspan>` SVG elements.

This improves our support for them in the following ways:

  * Any `length-percentage` or `number` type value is accepted;
  * Nested `<text>` and `<tspan>` use the 'current text position'
    concept to determine where the next text run should go;
  * We expose the attributes' values through the API.

Though we still do not support:

  * Applying the `rotate` attribute;
  * Applying transformations on a per-character basis.
  * Proper horizontal and vertical glyph advancing (we just use the path
    bounding box for now).
2025-11-20 23:15:24 +01:00
Jelle Raaijmakers
beb1d60714 LibWeb: Simplify calculation of the SVG viewbox transform
We don't need to construct a new AffineTransform and multiply that by
yet another AffineTransform; we can simply translate and scale the
transform that's already in place. No functional changes.
2025-10-27 16:42:27 -07:00
InvalidUsernameException
9d7689ecd8 LibWeb: Do not stomp over content size of SVGs
When displaying SVGs inside a navigable directly, we want to display
them in the size specified by their width and height attributes instead
of stretching them to the viewport as layout normally would.

However, when doing so, we need to actually check that the SVG we are
laying out is indeed directly inside the navigable. Otherwise we just
blindly overwrite whatever content sizes have been calculated by layout
code for e.g. SVG elements inlined somewhere in an HTML document.

Due to the way this was written originally, the bug was not very
noticable. The code overwrote the content width/height with the computed
width/height, which was often still correct in the sense that those two
had the same value. However, content size may also be the result of
{min,max}-{width,height} constraints, which can make it differ from the
computed values.

This bug was likely a regression introduced in
f5e01192cc.
2025-09-24 11:25:43 +01:00
Tim Ledbetter
7dade36d96 LibWeb: Ensure SVG image element respects viewBox
Previously, any active viewBox was ignored by SVG image elements.
2025-09-01 13:28:35 +01:00
Tim Ledbetter
ea41aba6c7 LibWeb: Move common SVGViewport code into an SVGFitToViewBox class
Special handling for SVGClipPathElement and SVGMaskElement, which use a
a ViewBox and PreserveAspectRatio value internally, has been moved to
`SVGFormattingContext`.
2025-08-28 15:42:56 +02:00
Tim Ledbetter
aadd563592 LibWeb: Replace usages of dynamic_cast with as and as_if 2025-08-22 20:26:09 +02:00
Timothy Flynn
04d32deb52 LibWeb: Port SVGFormattingContext to UTF-16 2025-08-05 15:13:36 +02:00
Andreas Kling
4e23882995 LibWeb: Use foreignObject's own size as available space inside it
This ensures that percentages resolve against the foreignObject's size
instead of the size of its containing block.

This makes user profile pictures clip correctly in the "Friends" view
of the Discord app.
2025-07-12 14:11:41 +02:00
Andreas Kling
aae0b52403 LibWeb: Resolve mask/clip in foreignObject's own coordinate space
We were neglecting to resolve these correctly, which caused them to get
the same metrics as the nearest viewport above the foreignObject.
2025-07-09 14:36:08 +02:00
Andreas Kling
f5f3cd041a LibWeb: Apply SVG viewbox transform to foreignObject elements 2025-07-09 14:36:08 +02:00
Andreas Kling
b4708510fb LibWeb: Layout foreignObject as block-level element with hidden overflow
This is according to the default user-agent style from the SVG2 spec.

In order for this to work correctly, we also have to assign width and
height to foreignObject boxes during SVG layout, since they are handled
manually by SVGFormattingContext.
2025-07-09 14:36:08 +02:00
Aliaksandr Kalenik
8e2d1559ec LibGfx: Join ScaledFont into Font
Since ScaledFont is the only class inherited from Font we could simply
merge them.
2025-04-21 09:51:16 +02:00
Aliaksandr Kalenik
667cb01b60 LibWeb: Fix layout mode propagation in SVGFormattingContext 2025-03-09 18:40:37 +01:00
Timothy Flynn
27478ec7d4 Everywhere: Run clang-format
The following command was used to clang-format these files:

    clang-format-19 -i $(find . \
        -not \( -path "./\.*" -prune \) \
        -not \( -path "./Build/*" -prune \) \
        -not \( -path "./Toolchain/*" -prune \) \
        -type f -name "*.cpp" -o -name "*.mm" -o -name "*.h")
2024-12-28 05:39:32 -08:00
Manuel Zahariev
f5e01192cc LibWeb: Layout standalone SVG document with specified dimensions
Before, standalone SVG documents were stretched to fit the agent
viewport.
2024-12-13 15:02:49 +00:00
Sam Atkins
ebc91686b5 LibWeb/Layout: Add FIXMEs where we're using the wrong font
It's not clear how to address these right now, so add a FIXME to make
them easier to find and address later.
2024-12-06 02:57:34 +01:00
Timothy Flynn
93712b24bf Everywhere: Hoist the Libraries folder to the top-level 2024-11-10 12:50:45 +01:00
Renamed from Userland/Libraries/LibWeb/Layout/SVGFormattingContext.cpp (Browse further)