PDF allows for named destinations to be provided as string. These can be
either found in the Dests dictionary in the document catalogue (as
already implemented), or in the Name Tree specified by the Dests key in
the Names dictionary of the document catalogue (missing).
This commit adds this missing case. Once the named destination is found
in the name tree, its value is interpreted just like in the first case,
so a new utility method encapsulates the common behavior.
Name Trees are hierarchical, string-keyed, sorted-by-key dictionary
structures in PDF where each node (except the root) specifies the bounds
of the values it holds, and either its kids (more nodes) or the
key/value pairs it contains.
This commit implements a series of lookup calls for finding a key in
such name trees. This implementation follows the tree as needed on each
lookup, but if that becomes inefficient in the long run we can switch to
creating a HashMap with all the contents, which as a drawback will
require more memory.
Being both of them containers, these classes already offered a set of
methods to retrieve an inner element by key or index, respectively, with
different methods for the different subtypes of the PDF::Object type
returning the element cast to the correct type pointer. On top of
that, DictObject offered an additional method to obtain an element as an
Object pointer.
While these methods were useful, they have some shortcomings:
* They always take a Document pointer to first perform an object
resolution, in case the element is a Reference. This is not always
necessary though, as there are values that are always meant to be
immediate, and hence the resolution lookup adds overhead.
* There was no easy way to get an individual Object element from an
ArrayObject like there is in DictObject. This makes it difficult to
obtain such values, as one first needs to call dict.get() to get a
Value, then cast it manually to a NonnullRefPtr<Object>.
This commit fixes these two issues by:
* Adding a new method that returns an Object for a given index.
* Adding overloads for this new method, and all the existing methods
described above, that do *not* take a Document, and therefore do
*not* perform an object resolution lookup.
This functionality was previously part of the resolve_to() Document
method, and thus only available only when resolving objects through the
Document class. There are many use cases where this casting can be used,
but no resolution is needed.
This commit moves this functionality into a new cast_to function, and
makes the resolve_to function call it internally. With this new function
in place we can now offer new versions of DictObject::get_* and
ArrayObject::get_*_at that don't perform Document resolution
unnecessarily when not required.
Destination arrays contain a page number, a mode name, and parameters
specific to that mode. In many cases these parameters can be set to
"null", which our code wasn't taking into consideration.
This commit parses these parameters taking into account whether they are
null or actual numbers, and stores them as Optional<float> instead of
plain floats. The parameters are not yet used anywhere else other than
when formatting a Destination object, so the change is fairly small.
Use this helper function in various places to replace the old code of
acquiring the SpinlockProtected<RefPtr<Jail>> of a Process to do that
validation.
It is now possible to scale the current layer using the move tool from
all four corners of the layer boundary. Previously scaling was only
possible from the bottom right of the image.
This is required for me to be able to build both Serenity and
Ladybird from the same repo. Without this the two builds seem to
stomp on each other, then fail to link.
Repeatedly allocation a new Card object is unnecessary, and makes
propagating OOM awkward. We also don't need a full card, just which
suit/rank it is and its position. So, let's save all the extra
allocation and just paint the card bitmap directly.
For example, in Solitaire, the vertical normal stacks cover the suit of
all but the topmost card in the stack. To see the suit of covered cards
the user currently has to move the cards on top of them out of the way.
This adds an API for games to set a card at a location to be previewed,
which will draw that card on top of all other cards without moving it.
This patch also updates corresponding functions from
`LibFileSystemAccessServerClient`.
From the FileSystemAccessClient point of view, it only makes the server
take `Core::Stream::OpenMode` instead of `Core::OpenMode`. So, `enum`
conversions only happen within deprecated functions and not in the new
`Core::Stream` friendly API.
On the server side, it just removes two usages of `Core::File::open()`.
Generic PR actions include opening a PR, submit review comments, adding
new commits, etc. This prevents the reviewer and PR submitter from
having to manually bounce the labels back and forth in the general
case. The reviewer also may not have permission to set labels, meaning
the reviewer won't be able to update the labels accordingly themselves.
This does not handle more subjective labels such as pr-is-blocked and
pr-unclear. Unfortunately, there does not seem to be a GitHub Actions
trigger for when a PR has merge conflicts, so the pr-has-conflicts
label cannot be automatically applied.
Co-authored-by: kleines Filmröllchen <filmroellchen@serenityos.org>
No need to use a TextLayout here, we can just count the number of lines
and multiply that by the font's preferred line height.
In addition to being much simpler, it also fixes a bug where labels were
got too tall if we calculated their preferred height before assigning
a final width to them.
This is achieved by simplifying the logic in TextLayout. We get rid
of all the various ways that the layout bounding rect can get cropped.
Then we make sure to use the right pixel metrics.
Finally we use the font's own line gap metrics instead of hard-coding 4.
The end result is that text painted with vector fonts now gets pretty
reasonable vertical alignment in most cases.