mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-26 09:30:24 +00:00
LibGfx/OpenType: Add scaffolding for CBDT and CBLC tables
This commit is contained in:
parent
e6131e45e2
commit
bca35bee6d
Notes:
sideshowbarker
2024-07-17 01:06:10 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/bca35bee6d
3 changed files with 177 additions and 3 deletions
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Srimanta Barua <srimanta.barua1@gmail.com>
|
||||
* Copyright (c) 2021-2022, Andreas Kling <kling@serenityos.org>
|
||||
* Copyright (c) 2021-2023, Andreas Kling <kling@serenityos.org>
|
||||
* Copyright (c) 2022, Jelle Raaijmakers <jelle@gmta.nl>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
|
@ -409,6 +409,8 @@ ErrorOr<NonnullRefPtr<Font>> Font::try_load_from_offset(ReadonlyBytes buffer, u3
|
|||
Optional<Kern> opt_kern = {};
|
||||
Optional<Fpgm> opt_fpgm = {};
|
||||
Optional<Prep> opt_prep = {};
|
||||
Optional<CBLC> cblc;
|
||||
Optional<CBDT> cbdt;
|
||||
|
||||
auto num_tables = be_u16(buffer.offset_pointer(offset + (u32)Offsets::NumTables));
|
||||
if (buffer.size() < offset + (u32)Sizes::OffsetTable + num_tables * (u32)Sizes::TableRecord)
|
||||
|
@ -453,6 +455,10 @@ ErrorOr<NonnullRefPtr<Font>> Font::try_load_from_offset(ReadonlyBytes buffer, u3
|
|||
opt_fpgm_slice = buffer_here;
|
||||
} else if (tag == tag_from_str("prep")) {
|
||||
opt_prep_slice = buffer_here;
|
||||
} else if (tag == tag_from_str("CBLC")) {
|
||||
cblc = TRY(CBLC::from_slice(buffer_here));
|
||||
} else if (tag == tag_from_str("CBDT")) {
|
||||
cbdt = TRY(CBDT::from_slice(buffer_here));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -537,7 +543,22 @@ ErrorOr<NonnullRefPtr<Font>> Font::try_load_from_offset(ReadonlyBytes buffer, u3
|
|||
}
|
||||
}
|
||||
|
||||
return adopt_ref(*new Font(move(buffer), move(head), move(name), move(hhea), move(maxp), move(hmtx), move(cmap), move(loca), move(glyf), move(os2), move(kern), move(fpgm), move(prep)));
|
||||
return adopt_ref(*new Font(
|
||||
move(buffer),
|
||||
move(head),
|
||||
move(name),
|
||||
move(hhea),
|
||||
move(maxp),
|
||||
move(hmtx),
|
||||
move(cmap),
|
||||
move(loca),
|
||||
move(glyf),
|
||||
move(os2),
|
||||
move(kern),
|
||||
move(fpgm),
|
||||
move(prep),
|
||||
move(cblc),
|
||||
move(cbdt)));
|
||||
}
|
||||
|
||||
Gfx::ScaledFontMetrics Font::metrics([[maybe_unused]] float x_scale, float y_scale) const
|
||||
|
|
|
@ -59,7 +59,22 @@ private:
|
|||
|
||||
static ErrorOr<NonnullRefPtr<Font>> try_load_from_offset(ReadonlyBytes, unsigned index = 0);
|
||||
|
||||
Font(ReadonlyBytes bytes, Head&& head, Name&& name, Hhea&& hhea, Maxp&& maxp, Hmtx&& hmtx, Cmap&& cmap, Optional<Loca>&& loca, Optional<Glyf>&& glyf, Optional<OS2> os2, Optional<Kern>&& kern, Optional<Fpgm> fpgm, Optional<Prep> prep)
|
||||
Font(
|
||||
ReadonlyBytes bytes,
|
||||
Head&& head,
|
||||
Name&& name,
|
||||
Hhea&& hhea,
|
||||
Maxp&& maxp,
|
||||
Hmtx&& hmtx,
|
||||
Cmap&& cmap,
|
||||
Optional<Loca>&& loca,
|
||||
Optional<Glyf>&& glyf,
|
||||
Optional<OS2> os2,
|
||||
Optional<Kern>&& kern,
|
||||
Optional<Fpgm> fpgm,
|
||||
Optional<Prep> prep,
|
||||
Optional<CBLC> cblc,
|
||||
Optional<CBDT> cbdt)
|
||||
: m_buffer(move(bytes))
|
||||
, m_head(move(head))
|
||||
, m_name(move(name))
|
||||
|
@ -73,6 +88,8 @@ private:
|
|||
, m_kern(move(kern))
|
||||
, m_fpgm(move(fpgm))
|
||||
, m_prep(move(prep))
|
||||
, m_cblc(move(cblc))
|
||||
, m_cbdt(move(cbdt))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -93,6 +110,8 @@ private:
|
|||
Optional<Kern> m_kern;
|
||||
Optional<Fpgm> m_fpgm;
|
||||
Optional<Prep> m_prep;
|
||||
Optional<CBLC> m_cblc;
|
||||
Optional<CBDT> m_cbdt;
|
||||
|
||||
// This cache stores information per code point.
|
||||
// It's segmented into pages with data about 256 code points each.
|
||||
|
|
|
@ -37,6 +37,7 @@ using FWord = BigEndian<i16>;
|
|||
using UFWord = BigEndian<u16>;
|
||||
using Tag = BigEndian<u32>;
|
||||
using Offset16 = BigEndian<u16>;
|
||||
using Offset32 = BigEndian<u32>;
|
||||
|
||||
// https://learn.microsoft.com/en-us/typography/opentype/spec/head
|
||||
// head: Font Header Table
|
||||
|
@ -399,4 +400,137 @@ private:
|
|||
FixedArray<size_t> m_subtable_offsets;
|
||||
};
|
||||
|
||||
// https://learn.microsoft.com/en-us/typography/opentype/spec/eblc
|
||||
// EBLC — Embedded Bitmap Location Table
|
||||
class EBLC {
|
||||
public:
|
||||
// https://learn.microsoft.com/en-us/typography/opentype/spec/eblc#sbitlinemetrics-record
|
||||
struct SbitLineMetrics {
|
||||
i8 ascender {};
|
||||
i8 descender {};
|
||||
u8 width_max {};
|
||||
i8 caret_slope_numerator {};
|
||||
i8 caret_slope_denominator {};
|
||||
i8 caret_offset {};
|
||||
i8 min_origin_sb {};
|
||||
i8 min_advance_sb {};
|
||||
i8 max_before_bl {};
|
||||
i8 min_after_bl {};
|
||||
i8 pad1 {};
|
||||
i8 pad2 {};
|
||||
};
|
||||
|
||||
// https://learn.microsoft.com/en-us/typography/opentype/spec/eblc#indexsubtablearray
|
||||
struct IndexSubTableArray {
|
||||
BigEndian<u16> first_glyph_index;
|
||||
BigEndian<u16> last_glyph_index;
|
||||
Offset32 additional_offset_to_index_subtable;
|
||||
};
|
||||
|
||||
// https://learn.microsoft.com/en-us/typography/opentype/spec/eblc#indexsubheader
|
||||
struct IndexSubHeader {
|
||||
BigEndian<u16> index_format;
|
||||
BigEndian<u16> image_format;
|
||||
Offset32 image_data_offset;
|
||||
};
|
||||
|
||||
// https://learn.microsoft.com/en-us/typography/opentype/spec/eblc#indexsubtable1-variable-metrics-glyphs-with-4-byte-offsets
|
||||
// IndexSubTable1: variable-metrics glyphs with 4-byte offsets
|
||||
struct IndexSubTable1 {
|
||||
IndexSubHeader header;
|
||||
Offset32 sbit_offsets[];
|
||||
};
|
||||
};
|
||||
|
||||
// https://learn.microsoft.com/en-us/typography/opentype/spec/cblc
|
||||
// CBLC — Color Bitmap Location Table
|
||||
class CBLC {
|
||||
public:
|
||||
// https://learn.microsoft.com/en-us/typography/opentype/spec/cblc#bitmapsize-record
|
||||
struct BitmapSize {
|
||||
Offset32 index_subtable_array_offset;
|
||||
BigEndian<u32> index_tables_size;
|
||||
BigEndian<u32> number_of_index_subtables;
|
||||
BigEndian<u32> color_ref;
|
||||
EBLC::SbitLineMetrics hori;
|
||||
EBLC::SbitLineMetrics vert;
|
||||
BigEndian<u16> start_glyph_index;
|
||||
BigEndian<u16> end_glyph_index;
|
||||
u8 ppem_x {};
|
||||
u8 ppem_y {};
|
||||
u8 bit_depth {};
|
||||
i8 flags {};
|
||||
};
|
||||
|
||||
// https://learn.microsoft.com/en-us/typography/opentype/spec/cblc#cblcheader
|
||||
struct CblcHeader {
|
||||
BigEndian<u16> major_version;
|
||||
BigEndian<u16> minor_version;
|
||||
BigEndian<u32> num_sizes;
|
||||
BitmapSize bitmap_sizes[];
|
||||
};
|
||||
|
||||
CblcHeader const& header() const { return *bit_cast<CblcHeader const*>(m_slice.data()); }
|
||||
ReadonlySpan<BitmapSize> bitmap_sizes() const { return { header().bitmap_sizes, header().num_sizes }; }
|
||||
Optional<BitmapSize const&> bitmap_size_for_glyph_id(u32 glyph_id) const;
|
||||
|
||||
static ErrorOr<CBLC> from_slice(ReadonlyBytes);
|
||||
ReadonlyBytes bytes() const { return m_slice; }
|
||||
|
||||
Optional<EBLC::IndexSubHeader const&> index_subtable_for_glyph_id(u32 glyph_id, u16& first_glyph_index, u16& last_glyph_index) const;
|
||||
|
||||
private:
|
||||
explicit CBLC(ReadonlyBytes slice)
|
||||
: m_slice(slice)
|
||||
{
|
||||
}
|
||||
|
||||
ReadonlyBytes m_slice;
|
||||
};
|
||||
|
||||
// https://learn.microsoft.com/en-us/typography/opentype/spec/ebdt
|
||||
// EBDT — Embedded Bitmap Data Table
|
||||
class EBDT {
|
||||
public:
|
||||
// https://learn.microsoft.com/en-us/typography/opentype/spec/ebdt#smallglyphmetrics
|
||||
struct SmallGlyphMetrics {
|
||||
u8 height {};
|
||||
u8 width {};
|
||||
i8 bearing_x {};
|
||||
i8 bearing_y {};
|
||||
u8 advance {};
|
||||
};
|
||||
};
|
||||
|
||||
// https://learn.microsoft.com/en-us/typography/opentype/spec/cbdt
|
||||
// CBDT — Color Bitmap Data Table
|
||||
class CBDT {
|
||||
public:
|
||||
// https://learn.microsoft.com/en-us/typography/opentype/spec/cbdt#table-structure
|
||||
struct CbdtHeader {
|
||||
BigEndian<u16> major_version;
|
||||
BigEndian<u16> minor_version;
|
||||
};
|
||||
|
||||
// https://learn.microsoft.com/en-us/typography/opentype/spec/cbdt#format-17-small-metrics-png-image-data
|
||||
struct Format17 {
|
||||
EBDT::SmallGlyphMetrics glyph_metrics;
|
||||
BigEndian<u32> data_len;
|
||||
u8 data[];
|
||||
};
|
||||
|
||||
static ErrorOr<CBDT> from_slice(ReadonlyBytes);
|
||||
ReadonlyBytes bytes() const { return m_slice; }
|
||||
|
||||
CbdtHeader const& header() const { return *bit_cast<CbdtHeader const*>(m_slice.data()); }
|
||||
|
||||
private:
|
||||
explicit CBDT(ReadonlyBytes slice)
|
||||
: m_slice(slice)
|
||||
{
|
||||
}
|
||||
|
||||
ReadonlyBytes m_slice;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue