Commit Graph

57416 Commits

Author SHA1 Message Date
MacDue
809c5b0b03 LibWeb: Add initial support for SVG <textPath>
This patch adds basic support for the SVG `<textPath>`, so it supports
placing text along a path, but none of the extra attributes for
controlling the layout of the text. This is enough to correctly display
the MDN example.
2023-12-19 21:29:03 +01:00
MacDue
d327104910 LibGfx: Add Path::place_text_along(text, font)
This method returns a new path with the input text placed along the edge
of the original path.
2023-12-19 21:29:03 +01:00
MacDue
8713968165 LibGfx: Preserve path order while splitting cubic/quadratic beziers
This changes the splitting to use a stack, which ensures the resulting
line segments follow the path in order. This will be important for SVG
`<textPath>`s which place text along a path.
2023-12-19 21:29:03 +01:00
Aliaksandr Kalenik
b2abd1dd05 LibWeb: Resolve box shadow data for paintable boxes during layout
Step towards making the paintable tree independent of the layout tree.
2023-12-19 21:08:51 +01:00
Andrew Kaster
f68c67bf3f LibWeb: Implement MessagePort.postMessage closer to the spec
Use a LocalSocket to represent the connection between two message ports.

The concept of the port message queue is still missing, however. When
that concept is implemented, the "steps" in step 7 of the message port
transfer steps will need to send the serialized data over the connected
socketpair and run in the event loop of the process that holds onto the
other side of the message port. Doing this should allow centralizing the
behavior of postMessage for Window, MessagePorts and Workers.
2023-12-19 21:08:05 +01:00
Andrew Kaster
c7f7ee2c4b headless-browser: Log current test when WebContent crashes 2023-12-19 21:08:05 +01:00
Andrew Kaster
82ec1ea75e LibJS: Provide better assertion for empty execution context stack
When calling `running_execution_context` from other VM APIs, and the
execution context stack is empty, the verification message is inlined
from AK::Vector. Add a specific VERIFY to `running_execution_context` to
help diagnose this issue better.
2023-12-19 21:08:05 +01:00
Lucas CHOLLET
64912d4d02 LibGfx/TIFF: Add support for images with CCITT3 1D compression
This compression (tag Compression=2) is not very popular on its own, but
a base to implement CCITT3 2D and CCITT4 compressions.

As the format has no real benefits, it is quite hard to find an app that
accepts tho encode that for you. So I used the following program that
calls `libtiff` directly:
```cpp
#include <vector>
#include <cstdlib>
#include <iostream>

#include <tiffio.h>

// An array containing 0 and 1 of length width * height.
extern std::vector<uint8_t> array;
int main() {
    // From: https://stackoverflow.com/a/34257789

    TIFF *image = TIFFOpen("input.tif", "w");
    int const width = 400;
    int const height = 300;
    TIFFSetField(image, TIFFTAG_IMAGEWIDTH, width);
    TIFFSetField(image, TIFFTAG_IMAGELENGTH, height);
    TIFFSetField(image, TIFFTAG_PHOTOMETRIC, 0);
    TIFFSetField(image, TIFFTAG_COMPRESSION, COMPRESSION_CCITTRLE);

    TIFFSetField(image, TIFFTAG_BITSPERSAMPLE, 1);
    TIFFSetField(image, TIFFTAG_SAMPLESPERPIXEL, 1);
    TIFFSetField(image, TIFFTAG_ROWSPERSTRIP, 1);

    std::vector<uint8_t> scan_line(width / 8 + 8, 0);
    int count = 0;
    for (int i = 0; i < height; i++) {
        std::fill(scan_line.begin(), scan_line.end(), 0);
        for (int x = 0; x < width; ++x) {
            uint8_t eight_pixels = scan_line.at(x / 8);
            eight_pixels = eight_pixels << 1;
            eight_pixels |= !array.at(i * width + x);
            scan_line.at(x / 8) = eight_pixels;
        }
        int bytes = int(width / 8.0 + 0.5);
        if (TIFFWriteScanline(image, scan_line.data(), i, bytes) != 1)
            std::cerr << "Something went wrong\n";
    }

    TIFFClose(image);
}
```
2023-12-19 21:01:24 +01:00
Lucas CHOLLET
7266d8c35d LibGfx/TIFF: Correctly upscale samples with a resolution lower than 8
As pointed out by @nico, while doing a right-shift to downscale is fine,
a left-shift to upscale gives wrong results. As an example, imagine a 2-
bits value containing 3, left-shifting it would give 192 instead of 255.
2023-12-19 21:01:24 +01:00
Aliaksandr Kalenik
fc9a8c77d5 headless-browser: Update m_viewport_rect after changing scroll offset 2023-12-19 20:59:52 +01:00
Aliaksandr Kalenik
c5d91dce8b LibWeb: Scroll to the "start" in Document::scroll_to_fragment()
Implements spec comment.
2023-12-19 20:59:52 +01:00
Aliaksandr Kalenik
7458c27c4b WebContent: Pre-emptively update viewport offset on request to scroll 2023-12-19 20:59:52 +01:00
Andrew Kaster
d361221657 LibJS+LibWeb: Add JS::Value constructor for `JS::Handle<T>`
Similar to the constructors for ``JS::{Nonnull}GCPtr<T>``, this helper
avoids unnecessary .ptr() clutter when we want to construct Values.
2023-12-19 09:21:55 -07:00
Aliaksandr Kalenik
9624eca116 LibWeb+LibWebView+WebContent: Remove unused request_scroll_into_view
`Element::scroll_into_view()` is supposed to be used instead.
2023-12-19 10:45:07 +01:00
Aliaksandr Kalenik
f6f80a1a72 LibWeb: Scroll to "nearest" instead of "start" in set_focused_element()
Fixes a bug when after clicking on a button/click the page is scrolled
to start of the element.
2023-12-19 10:45:07 +01:00
Aliaksandr Kalenik
cda1d886df LibWeb: Fix not working Element::scroll_an_element_into_view()
Fixes following mistakes:
- "scrolling box" for a document is not `scrollable_overflow_rect()`
   but size of viewport (initial containing block, like spec says).
- comparing edges of "scrolling box" with edges of target element
  does not make any sense because "scrolling box" edges are relative
  to page while result of `get_bounding_client_rect()` is relative
  to viewport.
2023-12-19 10:45:07 +01:00
Aliaksandr Kalenik
a93ab25487 headless-browser: Implement on_scroll_to_point and on_scroll_by_delta
Without these callbacks "scroll" events are not emitted so we can't
write tests for scrolling.
2023-12-19 10:45:07 +01:00
Andreas Kling
b27a62488c AK: Add ByteString::must_from_utf8(StringView) for Jakt 2023-12-18 12:41:25 +01:00
Lucas CHOLLET
5b62d877f2 LibGfx/TIFF: Parse more common tags
These tags are either part of the baseline specification or included by
default by GIMP when exporting TIFF files. Note that we don't add
support for them in the decoder yet. This commit only allows us to parse
the metadata and display it gracefully.
2023-12-18 07:14:11 +01:00
Aliaksandr Kalenik
bd08b1815f LibWeb: Implement border radius corner clipping in GPU painter
It is implemented in the way identical to how it works in CPU painter:
1. SampleUnderCorners command saves pixels within corners into a
   texture.
2. BlitCornerClipping command uses the texture prepared earlier to
   restore pixels within corners.
2023-12-17 23:12:48 +01:00
Aliaksandr Kalenik
177e7df1c5 LibWeb: Move border radius sampling config preparation into a function
In upcoming changes this code is going to be reused in GPU painter.
2023-12-17 23:12:48 +01:00
Bastiaan van der Plaat
a05fd28b7b LibWeb: Move use pseudo element styles from TreeBuilder to StyleComputer
The styling of elements using the `use_pseudo_element()` was only
applied on layout. When an element style was recomputed later that
styling was not overruled with the pseudo element selector styles.
This moves the styling override from `TreeBuilder.cpp` to
`StyleComputer.cpp`. Now the styles are always correctly applied.
I also removed the method `property_id_by_index()` because it was
not needed anymore.

Als some calls to `invalidate_layout()` in the Meter, Progress and
Select elements where not needed anymore because the style values
are update on the changing of the style attribute.

This fixes issue #22278.
2023-12-17 23:12:34 +01:00
Jesús "gsus" Lapastora
7578620f25 AK/StringUtils: Ensure needle positions don't overlap in replace
Previously, `replace` used `find_all` to find all of the positions to
replace. But `find_all` finds all the *overlapping* instances of the
needle, while `replace` assumed that the next position was always at
least `needle.length()` away from the last one. This led to crashes like
https://github.com/SerenityOS/jakt/issues/1159.
2023-12-17 12:00:48 -07:00
Ali Mohammad Pur
5e1499d104 Everywhere: Rename {Deprecated => Byte}String
This commit un-deprecates DeprecatedString, and repurposes it as a byte
string.
As the null state has already been removed, there are no other
particularly hairy blockers in repurposing this type as a byte string
(what it _really_ is).

This commit is auto-generated:
  $ xs=$(ack -l \bDeprecatedString\b\|deprecated_string AK Userland \
    Meta Ports Ladybird Tests Kernel)
  $ perl -pie 's/\bDeprecatedString\b/ByteString/g;
    s/deprecated_string/byte_string/g' $xs
  $ clang-format --style=file -i \
    $(git diff --name-only | grep \.cpp\|\.h)
  $ gn format $(git ls-files '*.gn' '*.gni')
2023-12-17 18:25:10 +03:30
Aliaksandr Kalenik
38d62563b3 LibAccelGfx: Fix stack use after scope in GlyphAtlas::update() 2023-12-17 14:55:41 +01:00
Ali Mohammad Pur
36f0499cc8 LibLine: Use grapheme clusters for cursor management
This makes using the line editor much nicer when multi-code-point
graphemes are present in the input (e.g. flag emojis, or some cjk
glyphs), and avoids messing up the buffer when deleting text, or
cursoring around.
2023-12-16 22:11:43 +01:00
Ali Mohammad Pur
99cc0514a7 LibLine: Don't compare byte and code point counts of the input text
This commit fixes the odd state after pasting some text containing
multibyte code points.
This also increases the input buffer size, as reading 16 bytes at a time
felt slightly laggy when pasting a large number of emojis :^)
2023-12-16 22:11:43 +01:00
Andreas Kling
e28ac74e0b LibWeb: Queue a task to proceed after module map entry finishes fetching
We were doing this synchronously, which was unsafe in that caused us to
re-enter the module map entry setting code while iterating over the
map's entries.

The fix is simply to do what the spec says and queue up a task. This way
the processing gets deferred to a later time.

To avoid stepping into this problem again, I've also added a reentrancy
check in ModuleMap.

This fixes a sporadic crash in HTML::ModuleMap::add() caught by ASAN.
In particular, this was happening regularly on https://shopify.com/
2023-12-16 20:47:16 +01:00
Aliaksandr Kalenik
2753075830 LibWeb: Do not crash when svg mask calculation failed
Currently `calculate_mask()` fails to create bitmap when
`maskContentUnits="objectBoundingBox"` is present.

Fixes https://github.com/SerenityOS/serenity/issues/22316
2023-12-16 19:48:36 +01:00
Aliaksandr Kalenik
4c81414b14 LibWeb: Fix division by zero in auto-fit/fill track calculation in GFC
Fixes https://github.com/SerenityOS/serenity/issues/22319
2023-12-16 19:39:44 +01:00
Aliaksandr Kalenik
4a2a37275e LibAccelGfx: Remove ability to change target canvas in painter
It is easier to build painter assuming target canvas won't change and
we don't use this api anyway :)
2023-12-16 19:39:36 +01:00
Aliaksandr Kalenik
161082e282 LibAccelGfx+LibWeb: Explicitly pass OpenGL context to Painter
Let's not assume there is one global OpenGL context because it might
change once we will start creating >1 page inside single WebContent
process or contexts for WebGL.
2023-12-16 19:39:36 +01:00
Andreas Kling
ed1ade0534 LibJS: Don't crash in CyclicModule::evaluate() when this == m_cycle_root
The spec allows this scenario, so I don't know why we would want to
assert that it doesn't happen.

Fixes #22317

Also, -1 crash, +1 pass on test262 :^)
2023-12-16 19:39:23 +01:00
Sönke Holz
ac79ab0b45 Kernel/riscv64: Specify correct alignment for FPUState struct
The signal handling code (and possibly other code as well) expects this
struct to have an alignment of 16 bytes, as it pushes this struct on the
stack.
2023-12-16 18:21:03 +01:00
Aliaksandr Kalenik
7d757fefeb LibWeb: Remove FIXME if paintable is missing in getBoundingClientRect()
We should not print FIXME when paintable is missing (display: none)
because that means actually we can't to get a rect.
2023-12-16 16:11:15 +01:00
Aliaksandr Kalenik
8f8ec37d58 LibWeb: Add missing paintable null check in get_bounding_client_rect()
Fixes crashing on https://github.com/
2023-12-16 16:11:15 +01:00
Aliaksandr Kalenik
f361b8c000 LibWeb: Make private RecordingPainter::state()
Removes usage of `RecordingPainter::state()` and makes it private.

No behavior change intended.
2023-12-16 15:10:07 +01:00
Aliaksandr Kalenik
55c483b763 LibAccelGfx: Add missing bind_target_canvas() in Painter::clear() 2023-12-16 14:35:47 +01:00
Andreas Kling
1e90379008 LibJS: Introduce "dictionary" mode for object shapes
This is similar to "unique" shapes, which were removed in commit
3d92c26445.

The key difference is that dictionary shapes don't have a serial number,
but instead have a "cacheable" flag.

Shapes become dictionaries after 64 transitions have occurred, at which
point no further transitions occur.

As long as properties are only added to a dictionary shape, it remains
cacheable. (Since if we've cached the shape pointer in an IC somewhere,
we know the IC is still valid.)

Deleting a property from a dictionary shape causes it to become an
uncacheable dictionary.

Note that deleting a property from a non-dictionary shape still performs
a delete transition.

This fixes an issue on Discord where Object.freeze() would eventually
OOM us, since they add more than 16000 properties to a single object
before freezing it.

It also yields a 15% speedup on Octane/pdfjs.js :^)
2023-12-16 14:25:58 +01:00
Timothy Flynn
8255a1a5ee Ladybird/Qt: Enable SQLServer for cookie storage by default
It was disabled by default for issues that have since been fixed.
Primarily: 14091f32c6
2023-12-16 13:32:04 +01:00
Timothy Flynn
acf7044544 Ladybird/Qt: Use RequestServer as the networking backend by default
This will let us find and fix any RequestServer issues more easily. Qt
networking is still available via command line.
2023-12-16 13:32:04 +01:00
Idan Horowitz
662143e0a9 Kernel: Resolve deadlock in MasterPTY due to mutex in spinlock scope
MasterPTY::read called DoubleBuffer::read which takes a mutex (which
may block) while holding m_slave's spinlock. If it did block, and was
later rescheduled on a different physical CPU, we would deadlock on
re-locking m_slave inside the unblock callback. (Since our recursive
spinlock implementation is processor based and not process based)
2023-12-16 12:55:41 +01:00
Idan Horowitz
ab06a76920 Kernel: Resolve lock-inversion based deadlock in MasterPTY & BlockSet
MasterPTY's double buffer unblock callback would take m_slave's
spinlock and then call evaluate_block_conditions() which would take
BlockerSet's spinlock, while on the other hand, BlockerSet's
add_blocker would take BlockerSet's spinlock, and then call
should_add_blocker, which would call unblock_if_conditions_are_met,
which would then call should_unblock, which will finally call
MasterPTY::can_read() which will take m_slave's spinlock.
Resolve this by moving the call to evaluate_block_conditions() out of
the scope of m_slave's spinlock, as there's no need to hold the lock
while calling it anyways.
2023-12-16 12:55:41 +01:00
Aliaksandr Kalenik
4534a43aae Ladybird/Qt: Apply to_content_position after scaling event coordinates
Fixes regression introduced in b73ae80d8b
2023-12-16 12:55:29 +01:00
Nico Weber
f2f07c3a80 LibPDF: Replace if (a) VERIFY(0) with VERIFY(!a)
No behavior change.
2023-12-16 12:39:56 +01:00
Nico Weber
ee74bc2538 LibPDF: Tolerate 0-sized Subrs in PS1 font subprograms
This regressed in 2b3a41be74 in #18031.

Fixes a crash rendering page 2 and onward of
https://pyx-project.org/presentation_dantemv35_en.pdf
2023-12-16 12:39:56 +01:00
Bastiaan van der Plaat
b73ae80d8b LibWeb: Refactor WebContentServer mouse input message to DevicePixel 2023-12-16 11:08:51 +01:00
Bastiaan van der Plaat
1f171cb60b LibWeb: Add support for the meta key modifier 2023-12-15 23:19:23 +00:00
Vladimir Shakhov
e2391105a1 LibWeb: Call process_session_history_traversal_queue on history update
Spec declares that the updates to history should be synchronous on
initial page load and on history pushState/replaceState.
2023-12-15 22:11:49 +01:00
Andreas Kling
9793d69d4f LibWeb: Make HTML::Window::page() return a Page& 2023-12-15 22:04:46 +01:00