According to the WebIDL specification, any leading underscores in
identifier names are ignored. A leading underscore is used when an
identifier would otherwise be a reserved word.
Rather than try to lay out masks normally, this updates the TreeBuilder
to create layout nodes for masks as a child of their user (i.e. the
masked element). This allows each use of a mask to be laid out
differently, which makes supporting `maskContentUnits=objectBoundingBox`
fairly easy.
The `SVGFormattingContext` is then updated to lay out masks last (as
their sizing may depend on their parent), and treats them like
viewports.
This is pretty ad-hoc, but the SVG specification does not give any
guidance on how to actually implement this.
When navigating to about:srcdoc we try to populate the session history
by calling populate_session_history_entry_document, if the resource is
an about:srcdoc this method will rely on the document_resource in the
SessionHistoryEntry to have a String in order for it call the right
method to create navigation params.
However when navigating to about:srcdoc directly, document_resource
will have an Empty, this leads populate_session_history_entry_document
to call the wrong method to create navigation params.
This fixes the issue by populating document_resource with an empty
string if it has an Empty and we're dealing with an about:srcdoc.
Issue: #23216
Instead of crashing with a TODO() on half of the test cases generated by
Domato, let's just return a zeroed-out SVGAnimatedLength or
SVGAnimatedNumber from getters that return them.
We'll eventually have to implement these correctly, but crashing is not
productive since it blocks us from finding other issues.
The loop that was supposed to check the chain of previous or next
siblings had a logic mistake where it would never traverse the chain,
so we would get stuck looking at the immediate sibling forever.
After removing an iframe from the DOM, its contentWindow will be
detached from its browsing context, per spec.
Because the contentWindow is still accessible, we cannot assume that
Window objects always have an associated browsing context.
This needs to be fixed in the spec, but let's add a sensible null check
in the meantime.
Since SVG gradients can reference each other, we have to keep track of
visited gradients when traversing the link chain, or we will recurse
infinitely when there's a reference cycle.
Instead of creating a generic Layout::Box, make a BlockContainer. This
allows them to be laid out by BFC, which is better than nothing(?),
even if it's not going to be correct at all.
Normally, assigning to e.g document.body.onload will forward to
window.onload. However, in a detached DOM tree, there is no associated
window, so we have nowhere to forward to, making this a no-op.
The bulk of this change is making Document::window() return a nullable
pointer, as documents created by DOMParser or DOMImplementation do not
have an associated window object, and so must be able to return null
from here.
That's not actually a DOM invariant, just something the HTML parser
refuses to build. You can still construct table-less th and td elements
using the DOM API.
If the "MMR" bit is set, the generic region decoding procedure just
uses ITU-T T.6 (2D CCITT), which we already have an implementation of.
In practice, this is used almost never in .jbig2 files and in none of
the PDFs I have.
The two files that do use MMR are:
1.) JBIG2_ConformanceData-A20180829/F01_200_TT9.jb2
2) 042_3.jb2 from the ghostpdl tests
The first uses an immediate _lossless_ generic region, which we don't
implement yet (but I think it should just forward to the normal
immediate generic region code? Not in this commit, though). The second
uses a regular immediate generic region, and we can decode it now:
Build/lagom/bin/image -o out.png \
path/to/ghostpdl/tests/jbig2/042_3.jb2
While IMO, the change makes sense on its own as flattening this function
will just duplicate the code from `draw_glyph()` with no benefits, this
is not what motivated this patch.
When compiling with debug information and ASAN, GCC 13.2 would issue
this warning:
Userland/Libraries/LibGfx/Painter.cpp: In member function ‘void Gfx::Pai
nter::draw_glyph(Gfx::FloatPoint, u32, Gfx::Color)’:
Userland/Libraries/LibGfx/Painter.cpp:1354:14: note: variable tracking s
ize limit exceeded with ‘-fvar-tracking-assignments’, retrying without
1354 | FLATTEN void Painter::draw_glyph(FloatPoint point, u32 code_poin
t, Color color)
| ^~~~~~~
From what I've read online, this is caused by some limit on the number
of symbols in the compiler's internal data structures. People at Google
have fixed this warning by splitting functions:
https://codereview.chromium.org/1164893003
While getting us rid of the warning, it also drastically improves
compilation time. Going from 1min27 to 59s on my machine.
Performance handles the document origin time correctly, and prevents
these times from being unusually large. Also initialize the
DocumentTimeline time in the constructor, since these can be created
from JS.
With this, `image` can convert any jbig2 file, as long as it's
black (or white), and LibPDF can draw jbig2 files (again, as long
as they only contain a single color stored in just a
PageInformation segment).
Also make scan_for_page_size() not early return, so that it has the
same behavior as the main decoding look. (Multiple page information
segments for a single page are likely invalid and don't happen in
practice, so this is mostly an academic change.)
Add a BitBuffer class to store the bit image data, and introduce a
Page struct for storing data associated with a page. We currently
only handle a single page, but a) this makes it easier to decode
multiple pages in the future if we want b) it makes the code easier
to understand.
7.4.8.2 Page bitmap height:
"In some cases, this value may not be known at the time that the page
information segment is written. In this case, this field must contain
0xFFFFFFFF, and the actual page height may be communicated later, once
it is known."
Sounds like the spec guarantees that that's the number of the first
page.
(In practice, all but one of all jbig2 files I've found contain just
page 1. PDFs almost always contain just page 1, and very rarely a
page 0 for globally shared parameters.)
If the provided ID is smaller than the corner clipping vector, we would
shrink the vector to match. This causes a crash when we have nested
PaintContext instances (as these IDs are allocated by PaintContext),
each of which perform radius painting.
This is seen on https://www.strava.com/login when it loads a reCAPTCHA.
The outer div has a border radius, which contains the reCAPTCHA in an
iframe. That iframe contains an SVG which also has a border radius.
Now, if an element belongs to a shadow tree, we use only the style
sheets from the corresponding shadow root during style computation,
instead of using all available style sheets as was the case
previously.
The only exception is the user agent style sheets, which are still
taken into account for all elements.
Tests/LibWeb/Layout/input/input-element-with-display-inline.html
is affected because style of document no longer affects shadow tree
of input element, like it is supposed to be.
Co-authored-by: Simon Wanner <simon+git@skyrising.xyz>
Doing that will allow us to get a list of style sheets for each shadow
root from StyleComputer without having to traverse the entire tree in
upcoming changes.
If a style element belongs to a shadow tree, its CSSStyleSheet is now
added to the corresponding ShadowRoot instead of the document.
Co-authored-by: Simon Wanner <simon+git@skyrising.xyz>
This patch also makes FlexFormattingContext::calculate_static_position
use computed values for margins and borders, since this function may be
called before the box's state has been finalized.
This allows `file` to correctly print the dimensions of a .jbig2 file,
and it allows us to write a test that covers much of all the code
written so far.
Several ramifications:
* /JBIG2Globals is an indirect reference, which means we now need
a Document for unfiltering. (Technically, other decode parameters
can also be indirect objects and we should use the Document to
resolve() those too, but in practice it only seems to be needed
for /JBIG2Globals.)
* Since /JBIG2Globals are so rare, we just parse once for each
image that use them, and decode_embedded() now receives a
Vector<ReadonlyBytes> with all sections of sequences of
segments.
* Internally, decode_segment_headers() is now called several times
for embedded JBIG2s with multiple such sections (e.g. PDFs with
/JBIG2Globals).
* That means `data` is now no longer part of JBIG2LoadingContext
and things get slightly reshuffled due to this.
This completes the LibPDF part of JBIG2 support. Once LibGfx
implements actual decoding of JBIG2s, things should start to
Just Work in PDFs.
They're in different places for Sequential/Embedded (right after
the header) and RandomAccess (which has all headers first, followed
by all data bits next).
We don't do anything with the data yet, but now everything's in
place to actually process segment data.
Except for /JBIG2Globals, which we bail out on for now. In my 1000
files, 13 use JBIG2, and of those, 2 use JBIG2Globals (0000372.pdf e.g.
page 11 and 0000857.pdf e.g. page 1), and only one (the latter) of the
two uses the same JBIG2Globals stream for more than a single image.
JBIG2ImageDecoderPlugin cannot decode the data yet, so no behavior
change, but with `#define JBIG2_DEBUG 1` at the top of that file,
it now prints segment header info for PDFs containing JBIG2 data :^)