There is no need to run full table layout if we are only interested in
calculating its width.
This change reduces compute_table_box_width_inside_table_wrapper()
from ~30% to ~15% in profiles of "File changed" pages on github.
This URL library ends up being a relatively fundamental base library of
the system, as LibCore depends on LibURL.
This change has two main benefits:
* Moving AK back more towards being an agnostic library that can
be used between the kernel and userspace. URL has never really fit
that description - and is not used in the kernel.
* URL _should_ depend on LibUnicode, as it needs punnycode support.
However, it's not really possible to do this inside of AK as it can't
depend on any external library. This change brings us a little closer
to being able to do that, but unfortunately we aren't there quite
yet, as the code generators depend on LibCore.
Instead of wrapping every entry in Optional, use the null state of the
style pointer for the same purpose.
This shrinks StyleProperties by 1752 bytes per instance.
Instead of a gigantic array with space for every possible CSS property
being animated at the same time.
This shrinks StyleProperties by 3480 bytes per instance.
Instead of TextPaintable fragments being an offset+length view into the
layout node, they are now a view into the paintable instead.
This removes an awkward time window where we'd have bogus state in text
fragments after layout invalidation but before relayout. It also makes
the code slightly nicer in general, since there's less mixing of layout
and painting concepts.
Instead, just rely on the invalidation and lazy relayout that happens as
a consequence of mutating the DOM.
This allows multiple keystrokes to coalesce into a single relayout if
necessary, dramatically improving performance when typing text into
form fields on complex pages.
Before this change, we were not detaching paintables from DOM nodes
within shadow subtrees.
This appears to be the main reason that keyboard editing was doing
immediate forced relayout: doing a full layout invalidation meant we'd
build a new layout tree, which then hid the problem with with
still-attached paintables.
By detaching them before committing a new layout, we make it possible
for keyboard editing to just use normal relayout, instead of full forced
invalidation & relayout.
CharacterData nodes and their subclasses (most commonly Text) don't have
style, as style is specific to Elements. So there's no need to mark them
for a style update when their content is programmatically changed.
Previously, we returned from the value setter if the specified value
was above the max value. This is not required, as the getter clamps the
returned value to the max value.
Rather than make path segments virtual and refcounted let's store
`Gfx::Path`s as a list of `FloatPoints` and a separate list of commands.
This reduces the size of paths, for example, a `MoveTo` goes from 24
bytes to 9 bytes (one point + a single byte command), and removes a
layer of indirection when accessing segments. A nice little bonus is
transforming a path can now be done by applying the transform to all
points in the path (without looking at the commands).
Alongside this there's been a few minor API changes:
- `path.segments()` has been removed
* All current uses could be replaced by a new `path.is_empty()` API
* There's also now an iterator for looping over `Gfx::Path` segments
- `path.add_path(other_path)` has been removed
* This was a duplicate of `path.append_path(other_path)`
- `path.ensure_subpath(point)` has been removed
* Had one use and is equivalent to an `is_empty()` check + `move_to()`
- `path.close()` and `path.close_all_subpaths()` assume an implicit
`moveto 0,0` if there's no `moveto` at the start of a path (for
consistency with `path.segmentize_path()`).
Only the last point could change behaviour (though in LibWeb/SVGs all
paths start with a `moveto` as per the spec, it's only possible to
construct a path without a starting `moveto` via LibGfx APIs).
"TPGD" is short for "Typical Prediction for Generic Direct coding",
and the "ON" bit turns it on. In this mode, before decoding a line,
we decode a single bit first that controls if the current line is
just a copy of the previous line. If so, the line's pixels aren't
encoded, the decoder just copies the previous line.
I created this by running
jbig2 -i Tests/LibGfx/test-inputs/bmp/bitmap -f bmp \
-o bitmap -F jb2 -ini tpgdon.ini
where tpgdon.ini contained:
-Gen -Seg 1
-Gen -Param -TpGDon 1
See previous commits in this directory for details on the `jbig2` tool.
Sadly, the TPGDON writing path in `jbig2` wasn't implemented yet,
so I had to add this. See the PR that added this commit for my
local diff to `jbig2`.
I'm somewhat confident that my change to `jbig2` (and hence the
image added in this commit) is correct because:
1. `jbig2` succeeds in converting this file to a bmp file,
while it failed without my patch (the decoding codepath in
`jbig2` does have TPGDON support)
2. Other pdf viewers display the output of
`Meta/jbig2_to_pdf.py -o foo.pdf path/to/bitmap-tpgdon.jbig2 399 400`
the same way we do
Most image viewers can't display JBIG2 files.
All PDF viewers can display JBIG2 files.
This is useful for checking that PDF viewers render JBIG2 files the
same way we do.
These are standalone applications meant to be run by the user directly,
as opposed to other libexec processes which are programmatically forked
by the browser. To do this, we simply remove these processes from the
`ladybird_helper_processes` list. We must also explicitly list the
dependencies for these processes.
Text can be rendered in various ways in PDFs: Filled, stroked,
both filled and stroked, set as clipping path, hidden, or
some combinations thereof.
We don't implement any of this at the moment except "filled".
Hidden text is used in scanned documents: The image of the scan is
drawn in the background, and then OCRd text is "drawn" as hidden
on top of the scanned bitmap. That way, the (hidden) text can be
selected and copied, and it looks like you're selecting text from
the scanned bitmap. Find-in-page also works similarly. (We currently
have neither text selection nor find-in-page, but one day we will.)
Now that we have pretty good support for CCITT and are growing some
support for JBIG2, we now draw both the scanned background image
as well as the foreground text. They're not always perfectly aligned.
This change makes it so that we don't render text that's marked as
hidden. (We still do most of the coordinate math, which will probably
come in handy at some point when we implement text selection.)
This makes these scanned documents appear as they're supposed to
appear (at least in documents where we manage to decode the background
bitmap).
This also adds a debug option to force rendering of hidden text.
Before this change, we would wake up on every event loop iteration to
drive animations in single-frame images. This was a complete waste of
time and caused 100% CPU usage on our main GitHub repo page.
With this change, CPU usage is ~1% when idle on the same page. :^)