summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibWeb/Painting
AgeCommit message (Collapse)Author
2023-05-24LibWeb: Make CSSPixels and Length use 64-bit (double) floating pointAndreas Kling
This fixes a plethora of rounding problems on many websites. In the future, we may want to replace this with fixed-point arithmetic (bug #18566) for performance (and consistency with other engines), but in the meantime this makes the web look a bit better. :^) There's a lot more things that could be converted to doubles, which would reduce the amount of casting necessary in this patch. We can do that incrementally, however.
2023-05-23LibWeb: Don't draw text fragments that would be clipped by the painterAndreas Kling
This avoids a ton of work when painting large documents. Even though it would eventually get clipped by the painter anyway, by bailing out earlier, we avoid a lot more work (UTF-8 iteration, OpenType lookups, etc). It would be even nicer if we could skip entire line boxes, but we don't have a fast way to get the bounding rect of a line box at the moment.
2023-05-23LibGfx+Everywhere: Change `Gfx::Rect` to be endpoint exclusiveJelle Raaijmakers
Previously, calling `.right()` on a `Gfx::Rect` would return the last column's coordinate still inside the rectangle, or `left + width - 1`. This is called 'endpoint inclusive' and does not make a lot of sense for `Gfx::Rect<float>` where a rectangle of width 5 at position (0, 0) would return 4 as its right side. This same problem exists for `.bottom()`. This changes `Gfx::Rect` to be endpoint exclusive, which gives us the nice property that `width = right - left` and `height = bottom - top`. It enables us to treat `Gfx::Rect<int>` and `Gfx::Rect<float>` exactly the same. All users of `Gfx::Rect` have been updated accordingly.
2023-05-22LibWeb: Tidy up apply_clip_overflow_rect() a littleMacDue
Avoid possible null optional dereference when creating border radius clipper, and avoid creating clipper if the clip rect is empty (which prevents some debug spam). Also remove an unnecessary lambda.
2023-05-21LibWeb: Have ImageProvider bitmap getter take optional size argumentAndreas Kling
This allows the painting subsystem to request a bitmap with the exact size needed for painting, instead of being limited to "just give me a bitmap" (which was perfectly enough for raster images, but not for vector graphics).
2023-05-20LibWeb: Implement SVG opacity propertiesMacDue
This implements the stop-opacity, fill-opacity, and stroke-opacity properties (in CSS). This replaces the existing more ad-hoc fill-opacity attribute handling.
2023-05-19LibWeb: Use box sampling instead of bilinear scaling when downscalingJelle Raaijmakers
As a heuristic, either the width or height of the scaled image should decrease for box sampling to be used. Otherwise, we use bilinear scaling.
2023-05-19Revert "LibWeb: Use box sampling instead of bilinear scaling when downscaling"Andreas Kling
This reverts commit b79fd3d1a90f959d71e8d1b56ad9f8c088681e78.
2023-05-19LibWeb: Use box sampling instead of bilinear scaling when downscalingJelle Raaijmakers
As a heuristic, either the width or height of the scaled image should decrease for box sampling to be used. Otherwise, we use bilinear scaling.
2023-05-16LibWeb: Propagate non-primary mouse button clicks on video elementsTimothy Flynn
Otherwise, returning "no" here will disallow the browser process from showing a context menu, as the event handler will bail early.
2023-05-15LibWeb: Fix iframes flickering on window resizeAndreas Kling
After finishing layout, iframe layout boxes (FrameBox) get notified about their new size by LayoutState::commit(). This information is forwarded to the nested browsing context, where it can be used for layout of the nested document. The problem here was that we notified the FrameBox twice. Once when assigning the used offset to its paintable, and once when assigning its size. Because the offset was assigned first, we ended up telling the FrameBox "btw, your size is 0x0". This caused us to throw away all the layout information we had for the nested document. We'd then say "actually, your size is 300x200" (or something) but by then it was already too late, and we had to do a full relayout. This caused iframes to flicker as every time their containing document was laid out, we'd nuke the iframe layout and redo it (on a zero timer). The fix is pleasantly simple: we didn't need to inform the nested document of its offset in the containing document's layout anyway. Only its size is relevant. So we can simply remove the first call, which removes the bogus 0x0 temporary size. Note that iframes may still flicker if they change size in the containing document. That's a separate issue that will require more finesse to solve. However, this fixes a very noticeable common case.
2023-05-13LibWeb: Don't force HTMLImageElement to have a legacy ImageLoaderAndreas Kling
We achieve this by adding a new Layout::ImageProvider class and having both HTMLImageElement and HTMLObjectElement inherit from it. The HTML spec is vague on how object image loading should work, which is why this first pass is focusing on image elements.
2023-05-13LibWeb: Implement enough of "update the image data" to load imagesAndreas Kling
This first pass is enough to get us: - Image loading via fetch - Source selection via srcset and sizes attributes
2023-05-09LibWeb: Move image viewport awareness from ImageBox to ImagePaintableAndreas Kling
Images being aware of being visible inside the viewport is a painting concern, not a layout concern.
2023-05-06LibWeb: Use the new to_px() helpers in CSS, SVG and layout codeAndreas Kling
There should be no behavior change from this, only slightly less verbosity. :^)
2023-05-06LibWeb: Propagate errors from StyleValue constructionSam Atkins
Turns out we create a lot of these, mostly from places that don't return ErrorOr. The yak stack grows.
2023-04-30LibGfx+Userland: Merge FrameShape and FrameShadow into FrameStylethankyouverycool
Previously, Frames could set both these properties along with a thickness to confusing effect: Most shapes of the same shadowing only differentiated at a thickness >= 2, and some not at all. This led to a lot of creative but ultimately superfluous choices in the code. Instead let's streamline our options, automate thickness, and get the right look without so much guesswork. Plain shadowing has been consolidated into a single Plain style, and 0 thickness can be had by setting style to NoFrame.
2023-04-28LibWeb: Resolve and paint SVG gradient fillsMacDue
This bit is mostly ad-hoc for now. This simply turns fill: url(#grad1) into document().get_element_by_id('grad1') then resolves the gradient. This seems to do the trick for most use cases, but this is not attempting to follow the spec yet to keep things simple.
2023-04-25LibWeb+WebContent: Make document background and Viewport transparentSigmund Lahn
This means iframes are transparent by default (as in firefox/chrome). Painting the outermost canvas background is moved to the PageHost.
2023-04-23LibWeb: Paint video timestamps using CSS/device pixel-aware scaled fontsTimothy Flynn
The timestamp text was very tiny on a HiDPI display.
2023-04-21LibWeb: Implement HTMLVideoElement representation closer to the specTimothy Flynn
The representation is used to indicate whether the layout node should paint a video frame, the video's poster, or a "transparent black" box.
2023-04-21LibWeb: Track decoded video frame positions along with the frame imageTimothy Flynn
This will be needed by the layout node, which may change what is painted when the position of the frame image is not the same as the element's current time.
2023-04-20LibWeb: Use device pixels to translate NestedBrowsingContextPaintableAliaksandr Kalenik
Fix translation of iframes when pixel size is not 1.0.
2023-04-20LibWeb/Painting: Move-assign value in set_containing_line_box_fragmentLinus Groh
An Optional<Layout::LineBoxFragmentCoordinate> is 24 bytes, which isn't small enough to pass by value and then copy.
2023-04-20LibWeb/Painting: Remove redundant 'Painting::' namespace prefixesLinus Groh
2023-04-20LibWeb: Rename remaining paint_box variables to paintable_boxLinus Groh
These don't match the type name, which is confusing.
2023-04-20LibWeb/Layout: Rename Box::{paint => paintable}_box()Linus Groh
It returns a PaintableBox, not a 'PaintBox'.
2023-04-20LibWeb/Painting: Rename StackingContext::paintable{ => _box}()Linus Groh
It returns a PaintableBox, not any Paintable.
2023-04-19LibWeb: Rename BrowsingContextContainer => NavigableContainerAndreas Kling
The "browsing context container" concept in the HTML spec has been replaced with "navigable container". Renaming this is the first step of many towards implementing the new world. Co-authored-by: Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
2023-04-19LibWeb: Make SVG <g> elements generate a SVGGraphicsPaintableAndreas Kling
...instead of defaulting to a PaintableBox. This way it gets the same behavior as other SVG boxes during paint.
2023-04-18LibWeb: Render HTMLVideoElement controls when scripting is disabledTimothy Flynn
The spec recommends exposing the user agent interface when scripting is disabled on the media element.
2023-04-17LibWeb: Clip SVG content to parent <svg> element bounding boxMacDue
2023-04-17LibWeb: Update the media playback time for clicks on the media timelineTimothy Flynn
When clicking on the media timeline, compute the percentage along the timeline's width the user clicked, and set the playback time to the same percentage of the video's duration.
2023-04-17LibWeb: Restrict toggling video playback to certain areas in a videoTimothy Flynn
When the control bar is shown, do not toggle playback when clicking on the control bar, unless the click target is the playback button. This will let us implement clicking on the timeline to seek. Note that this requires caching some layout rects on the video element. We need to remember where the corresponding layout boxes are, and we can't cache them on the layout box, as that may be destroyed any time.
2023-04-17LibWeb: Implement converting a DevicePixelRect to a CSSPixelRectTimothy Flynn
Which also requires converting a DevicePixelSize to a CSSPixelSize.
2023-04-15LibWeb: Scale SVG stroke-width based on viewboxMacDue
This fixes the clipping of strokes in quite a few cases and now fixes the Gartic Phone logo :^) (Layout test updated but no visible changes there)
2023-04-12LibWeb: Don't try to paint SVG elements transformed to zero sizeMacDue
Otherwise, the Gfx::Painter will get choked up on NaNs and start infinitely splitting paths till it OOMs.
2023-04-12LibWeb: Use (transformed) path bounding quad for SVG path hit testingMacDue
This is needed for hit testing the directional arrows on the Street View office tour, and generally makes SVG hit testing more precise. Note: The rough bounding box is hit test first, so this should not be a load more overhead.
2023-04-12LibWeb: Apply CSS scaling to SVG elementsMacDue
Not sure why this was not done before, not now it works easily :^)
2023-04-12LibWeb: Apply SVG transform to path when painting (SVG) elementsMacDue
This also combines the viewbox mapping into the same transform and reuses some code by using Path::copy_transformed() rather than manually mapping each segment of the path.
2023-04-12LibWeb: Make SC hit testing more closely follow reverse paint orderMacDue
Previously, we would hit test positioned elements, then stacking contexts with z-index 0, as two seperate steps. This did not really follow the reverse paint order, where positioned elements and stacking contexts with z-index 0 are painted during the same tree transversal. This commit updates for_each_in_subtree_of_type_within_same_stacking_context_in_reverse() to return the stacking contexts it comes across too, but not recurse into them. This more closely follows the paint order. This fixes examples such as: <div id="a" style="width: 10px; height: 10px"> <div id="b" style="position: absolute; width: 10px; height: 10px"> <div style="position: absolute; width: 10px; height: 10px; z-index: 0" > <div id="c" style="width: 100%; height: 100%; background-color:red;" onclick="alert('You Win!')"> </div> </div> </div> </div> Where previously the onclick on #c would never fire as hit testing always stopped at #b. This is reduced from Google Street View, which becomes interactable after this commit.
2023-04-11LibWeb: Paint a media timeline on HTMLVideoElement layout nodesTimothy Flynn
2023-04-11LibWeb: Move VideoPaintable's cached mouse position to HTMLVideoElementTimothy Flynn
The layout node, and therefore the painting box, is frequently destroyed and recreated. This causes us to forget the cached mouse position we use to highlight media controls. Move this cached position to the DOM node instead, which survives relayout.
2023-04-11LibWeb: Tweak the color used for hovered media controlsTimothy Flynn
The link color is what closely resembled the color I was going for on the machine I originally developed the controls on. But turns out this is a very dark blue on most Serenity themes. Instead, hard-code the original intended color, which is a lighter blue.
2023-04-10LibWeb: Convert video control dimensions from CSSPixels to DevicePixelsTimothy Flynn
Rather than storing static DevicePixels dimensions, treat the desired pixel sizes as CSSPixels and convert them to DevicePixels. This was originally developed on a mac with a device-to-CSS-pixel ratio of 2. Running it on another machine with a ratio of 1 made the controls appear huge.
2023-04-08LibWeb: Begin painting video controls on HTMLVideoElement layout nodesTimothy Flynn
If the video element has a 'controls' attribute, we now paint some basic video controls over the video element. If no frame has been decoded yet, we paint a play button on the center of the element. If a frame has been decoded, we paint that frame and paint a control bar on the bottom of the frame. This control bar currently only contains a play/pause button, depending on the video's playback state. We will only paint the control bar if the video is paused or hovered.
2023-04-07LibWeb: Create a basic layout node for HTMLVideoElementTimothy Flynn
2023-04-01LibWeb: Use scaled font when painting list item markersMacDue
This now uses the current font (rather than the painter's default) and scales it correctly. This is not perfect though as just naviely doing .draw_text() here does not follow the proper text layout logic so this is misaligned (by a pixel or two) with the text in the <li>.
2023-04-01LibWeb: Use scaled font when painting text shadowsMacDue
This fixes painting text shadows at non-100% zoom.
2023-04-01LibWeb: Add .scaled_font() helper to Layout::NodeMacDue
This returns the font scaled for the current zoom level.