The Compat Font Format specification (Adobe's Technical Note #5176) is
used by PDF's Type1C fonts to store their data. While being similar in
spirit to PS1 Type 1 Font Programs, it was designed for a more compact
representation and thus space reduction (but an increment on
complexity). It also shares most of the charstring encoding logic, which
is why the CFF class also inherits from Type1FontProgram.
This initial implementation is still lacking many details, e.g.:
* It doesn't include all the built-in CFF SIDs
* It doesn't support CFF-provided SIDs (defaults those glyphs to the
space character)
* More checks in general
The Type1FontProgram logic was based on the Adobe Type 1 Font Format; in
particular, it implemented the CharStrings Dictionary section
(charstring decoding, and most commands). In the case of Type1, these
charstrings are read from a PS1 diciontary, with one entry per character
in the font's charset. This has served us well for Type1 font rendering.
When implementing Type1C font rendering, this wasn't enough. Type1C PDF
fonts are specified in embedded CFF (Compact Font File) streams, which
also contain a charstring dictionary with an entry for each character in
the font's charset. These entries can be slightly different from those
in a PS1 Font Program though: depending on a flag in the CFF, the
entries will be encoded either in the original charstring format from
the Adobe Type 1 Font Format, or in the "Type 2 Charstring Format"
(Adobe's Technical Note #1577). This new format is for the most part a
super-set of the original, with small differences, all in the name of
making the representation as compact as possible:
* The glyph's width is not specified via a separate command; instead
it's an optional additional argument to the first command of the
charstring stream (and even then, it's only the *difference* to a
nominal character width specified in the CFF).
* The interpretation of a 4-byte number is different from Type 1: in
Type 1 this is a 4-byte unsigned integer, whereas in Type 1 it's a
fixed decimal with 16 bits of fractional part.
* Many commands accept a variable set of arguments, so they can draw
more than one line/curve on a single go. These are all
retro-compatible with Type 1's commands.
All these changes are implemented in this patch in a
backwards-compatible way. To ensure Type 1/2 behavior is accessed, a new
parameter indicates which behavior is desired when decoding the
charstring stream.
I also took the chance to centralise some logic that was previously
duplicated across the parse_glyph function. Common lambdas capture the
logic for moving to, or drawing a line/curve to a given point and
updating the glyph state. Similarly, some command logic, including
reading parameters, are shared by several commands. Finally, I've
re-organised the cases in the main switch to group together related
commands.
We are planning to add support for CFF fonts to read Type1 fonts, and
therefore much of the logic already found in PS1FontProgram will be
useful for representing the Type1 fonts read from CFF.
This commit moves the PS1-independent bits of PS1FontProgram into a new
Type1FontProgram base class that can be used as the base for CFF-based
Type1 fonts in the future. The Type1Font class uses this new type now
instead of storing a PS1FontProgram pointer. While doing this
refactoring I also took care of making some minor adjustments to the
PS1FontProgram API, namely:
* Its create() method is static and returns a
NonnullRefPtr<Type1FontProgram>.
* Many (all?) of the parse_* methods are now static.
* Added const where possible.
Notably, the Type1FontProgram also contains at the moment the code that
parses the CharString data from the PS1 program. This logic is very
similar in CFF files, so after some minor adjustments later on it should
be possible to reuse most of it.
This might not be an issue at the moment, but moved-from objects are
usually in a unspecifed but valid state, meaning that we shouldn't read
from them.
This commit expands the functionality of the "Crop Image to Content"
and "Crop Layer to Content" features by allowing them to detect and
crop the background color of an image instead of just cropping
transparent pixels.
The background color is determined by looking at the corner pixels of
the image. If no background color is found, the old behavior of
cropping transparent pixels is retained.
This makes sure that the aarch64 disk image also contains the correct
dynamic shared objects, specifically libgcc_s.so.1, as that one is a
dynamic dependency of every aarch64 executable.
To unify the x86_64 and aarch64 code paths, this commit just installs
everything from the compilers lib directory into the disk image lib
directory. This also happens for the Clang toolchain. This copies a few
extra files related to libsupc++ and libstdc++, increasing the size of
the disk image by 1.6MB. However, we were already copying libstdc++.a
manually anyway.
Without this tag, executables that link libgcc_s.so.1, which is every
executable, end up with the host path to libgcc_s.so.1 as the path for
the dynamic dependency (DT_NEEDED) of the executable. By making sure
that the libgcc_s.so.1 shared object includes the DT_SONAME tag, the
path to libgcc_s.so.1 dynamic dependency will only contain the basename,
instead of the absolute host path.
`Process::get_name()` and `Process::set_name()` are basically the same
as `get_process_name()` and `set_process_name()`, except making use of
convenient Serenity standard types and returning ErrorOr, instead of
char* and errno shenanigans.
`Process::set_name()` has an optional `SetThreadName` parameter, for
when you also want to set the thread's name to the same thing. That's
true for the two places that use `set_process_name()`.
The spec names are still a bit cryptic ("deviceMfgDescTag"
for "device manufacturer description"), but less cryptic than
just the fourcc.
There's a private tag area, so this will only print the spec name
of tags in the current spec. Private tags are in active use, e.g.:
$ icc /Library/ColorSync/Profiles/WebSafeColors.icc
...
Unknown tag ('dscm'): type 'mluc', offset 312, size 1490
(That's a v2 file. In v2, 'desc' has that strange textDescriptionType.
In v4, 'desc' has type 'mluc' -- but in v2, it didn't yet, so Apple
invented the private 'dscm' tag which has the description as an 'mluc'.)
Also add a function to map each tag signature to its name,
that is a function that maps e.g. measurementTag to "measurementTag"sv.
To implement this without too much repetition, use an x-macro.
I used pdftotext on the icc v4 spec to extract the list of tags,
and then manually cleaned it up a bit:
https://github.com/nico/hack/blob/main/icc-tags.txt
I then converted that to an x-macro using vim macros.
There is a problem with current approach where overflow clip rectange is
calculated by aggregating intersection of absolute padding boxes of
boxes in containing block chain that resulting rectangle doesn't
respect transform properties.
To solve this problem `PaintableBox` is changed to store clip rectangle
saved from painter because it does respect transform properties of all
previously applied clip rectangles.
Here .to_string() was being called, which gives an ErrorOr<String>,
then .value() was called on that without any checks. Cases like this
should at least be .release_value_but_fixme_should_propagate_errors()
which makes it clear the error is ignored, but here it's easy to
propagate.
This was converted to an enumeration for Intl.NumberFormat V3 in commit
33698b9615, but the default value was not
updated (and it's a bit surprising it compiled at all, given that this
is an 'enum class').
Besides from a general check if a file's directory has write
permissions, this also checks if the directory has set a sticky bit,
meaning that only file owners and the directory owner can remove or move
files in such directory. It's being used in /tmp for example.
This is the same address that the x86_64 kernel runs at, and allows us
to run the kernel at a high virtual memory address. Since we now run
completely in high virtual memory, we can also unmap the identity
mapping. Additionally some changes in MMU.cpp are required to
successfully boot.