A few closely-related changes:
- Move our definitions of the OpenType spec's "data types" into their
own header file.
- Add definitions for the integer types there too, for completeness.
(Plus Uint16 matches the spec term, and is less verbose than
BigEndian<u16>.)
- Include Traits for the non-BigEndian types so that we can read them
from Streams. (BigEndian<integer-type> already has this.)
- Use the integer types in our struct definitions.
As a bonus, this fixes a bug in Hmtx, which read the left-side bearings
as i16 instead of BigEndian<i16>.
Do more checks at load time, including categorizing the subtables and
producing our own directory of them.
The format for Kern is a little complicated, so use a Stream instead of
manual offsets.
Maxp had the shared fields duplicated, and OS2 embedded each version's
struct in the next. Instead, let's use inheritance to avoid duplicating
shared fields while still allowing them to be directly accessed.
While I'm at it, rename the Maxp and GPOS table structs to just be
VersionX_Y, because they're not ambiguous with anything else.
LibGfx: Rename GPOSHeader to HeaderVersion1_0
Because there's a version 1.1 as well, which we'll eventually want to
support.
At first glance this looks like it holds the memory that the various
slices point into... but it actually doesn't own that memory. Nobody
uses m_buffer, so it serves no purpose.
Some of these are odd sizes. We managed not to insert padding because
BigEndian is itself marked as packed, but let's be explicit instead of
relying on that. :^)
This updates fonts so rather than rastering directly to a bitmap, you
can extract paths for glyphs. This is then used to implement a
Gfx::Path::text("some text", font) API, that if given a vector font
appends the path of the text to your Gfx::Path. This then allows
arbitrary manipulation of the text (rotation, skewing, etc), paving the
way for Word Art in Serenity.
An error is now returned if `numTables` is zero or greater than 4096.
While this isn't explicitly mentioned in the specification, subsequent
calculations will be incorrect if the value falls outside this range.
This commit limits `WOFF::Header::num_tables` to 4096. This limitation
is not explicitly mentioned in the specification, but allowing numbers
larger than this results in an overflow when calculating
`search_range` and `range_shift`.
Previously, `load_from_memory()` just took a raw pointer to the data,
and then manually calculated offsets from that pointer. Instead, let's
use the MappedFile we already have, to stream in the data, to make
things a bit safer. We also now check that the entire file's data was
read, since if there was data left over, then either the file is bad or
we've done something wrong.
I've moved the code directly into `try_load_from_mapped_file()` since
`load_from_memory()` was only called from there. The extra indirection
wasn't adding anything.