ICC::Profile deletes these objects via base class pointers, so this
is needed that destructors in the subclasses get called.
(Found by asan on CI when adding test coverage.)
This patch adds a "GlyphPage" cache which stores the mapping between
code points and glyph IDs in a segmented table of "pages".
This makes Font::glyph_id_for_code_point() significantly faster by
not reparsing the font tables every time you call it.
In the future, we can add more information to GlyphPage (such as
horizontal metrics for each glyph) to further reduce time spent in
text layout and painting.
`Stream` will be qualified as `AK::Stream` until we remove the
`Core::Stream` namespace. `IODevice` now reuses the `SeekMode` that is
defined by `SeekableStream`, since defining its own would require us to
qualify it with `AK::SeekMode` everywhere.
Most jpegs that use multi-tag ICCs are in CMYK format, so running
`icc` on them still produces
Runtime error: Unsupported number of components in SOF
but it no longer prints several
jpg: Ignoring ICC profile spanning several chunks (1/9)
lines before that.
(And if I manually comment out that error message, the profile
is printed fine. But we can't decode the actual pixel data yet.)
s15Fixed16Number and XYZNumber are somewhat awkwardly duplicated
in both Profile.cpp and TagTypes.cpp. Other than that, this is a
pure code move.
No behavior change.
This probably won't be the final API for getting color spaces
from images, since some formats just store an "is sRGB?" flag
instead of a full profile. Instead, once everything works,
we probably want to give every Bitmap a pointer to some
color space abstraction.
But we can always change this later, once things are further along
and better understood.
As the different Cmap encoding records are guaranteed to be sorted by
their platform ID, we would previously prefer the Macintosh platform
because of its lower ID value. However, this platform is split up into
a lot of encoding formats for different languages, and usually only
English is included. This meant that we could not handle most unicode
characters anymore.
The Windows platform now takes precedence again, as it can handle
arbitrary code points in its supported encodings.
This solution is still far from perfect, but it makes this regression
disappear for now.
Add a targeted quirk for the one known file where this is violated.
Adding that quirk is a bit of a bummer, since that means all client
code of this class now needs to deal with the possibility that
'cprt' and 'desc' aren't 'mluc' for v4 files. But if that code wants
to handle v2 files, it needs to deal with that anyways, so it's
really just a bit of a bummer and not more.
This adds checking for all tags where ICCProfile can parse the type.
Over time, more of this needs implementing -- at least lut8Type,
lut16Type, lutAToBType, and lutBToAType, since these are used by
required tags.
What _is_ checked for the most part matches the spec, but it's possible
that the spec text is aspirational and that profiles in the wild don't
fully match it.
I've run the current checks against these profiles:
find \
~/src/Compact-ICC-Profiles \
/{System/,}Library/ColorSync \
-name '*.icc' \
-exec echo {} \; \
-exec Build/lagom/icc {} \;
...and against 3 hand-selected icc files I locally extracted from jpegs.
This identified 3 cases where the spec text is too strict for reality.
I added comments for these for now. Eventually, I'd like to try to still
enforce these types, and have a profile-id-based quirks list for which
they aren't enforced. It's possible that that won't be feasible, but
it's probably better to start out to strict and then relax over time
than the other way round.
This patch adds the following some convenience functions:
- Lines do now support rotated(), scaled() and translated()
- AntiAliasingPainter has now a draw_line function that takes a
FloatLine as argument
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.
Several tags can refer to the same TagData. In particular, the
rTRC, gTRC, bTRC tags usually all three refer to the same curve.
Curve objects can be large, so allocate only a single TagData
object in that case and make all tags point to it.
(If we end up storing some cache in the curve object later on,
this will also increase the effectiveness of that cache.)
This reduces reliance on the peek operation, which the generic stream
implementation does not support.
This also corrects the naming, since "tag" wasn't entirely correct for
some of the operations, where the tag takes up only part of a byte, with
the rest being reserved for data.