Class: Fontisan::Tables::Cblc
- Inherits:
-
Binary::BaseRecord
- Object
- BinData::Record
- Binary::BaseRecord
- Fontisan::Tables::Cblc
- Defined in:
- lib/fontisan/tables/cblc.rb
Overview
CBLC (Color Bitmap Location) table.
CBLC indexes glyph IDs into CBDT byte offsets across one or more bitmap strikes (each strike = a ppem + bit depth combination). For each strike, a list of IndexSubTable records describes how to locate the bitmap of each glyph in a contiguous glyph range.
Layout:
uint32 version (0x00020000 or 0x00030000)
uint32 num_sizes (number of BitmapSize records)
CblcBitmapSize[num_sizes] (48 bytes each)
IndexSubTableArray entries (8 bytes each, per BitmapSize)
IndexSubTable records (variable, format-specific)
This model parses the header + BitmapSize records via BinData, then lazily walks the IndexSubTableArray / IndexSubTable structures on demand so callers can iterate [(gid, strike) → CBDT location] pairs.
Reference: OpenType CBLC specification. https://learn.microsoft.com/en-us/typography/opentype/spec/cblc
Constant Summary collapse
- TAG =
"CBLC"- VERSION_2_0 =
CBLC v2.0 — original release
0x00020000- VERSION_3_0 =
CBLC v3.0 — adds PNG image format support
0x00030000
Instance Method Summary collapse
-
#bitmap_offset_for_gid(glyph_id, ppem) ⇒ CblcGlyphBitmapLocation?
Locate a glyph's CBDT bitmap at a specific ppem.
-
#each_glyph_location {|CblcGlyphBitmapLocation| ... } ⇒ Enumerator
Iterate every (glyph_id, strike) → CblcGlyphBitmapLocation pair across all strikes.
-
#glyph_ids_with_bitmaps ⇒ Array<Integer>
All glyph IDs that have any bitmap across every strike.
-
#index_sub_tables ⇒ Array<CblcIndexSubTable>
All IndexSubTable records across every strike.
-
#num_strikes ⇒ Integer
Number of bitmap strikes.
-
#ppem_sizes ⇒ Array<Integer>
All available ppem sizes across every strike.
-
#strikes_for_glyph(glyph_id) ⇒ Array<CblcBitmapSize>
Strikes that cover a given glyph ID.
-
#strikes_for_ppem(ppem) ⇒ Array<CblcBitmapSize>
Strikes that match a specific ppem.
-
#sub_tables_for(strike) ⇒ Array<CblcIndexSubTable>
Iterate every IndexSubTable in a single strike.
-
#valid? ⇒ Boolean
Whether the CBLC header is one fontisan understands and at least the header fields parsed successfully.
Methods inherited from Binary::BaseRecord
Instance Method Details
#bitmap_offset_for_gid(glyph_id, ppem) ⇒ CblcGlyphBitmapLocation?
Locate a glyph's CBDT bitmap at a specific ppem.
72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/fontisan/tables/cblc.rb', line 72 def bitmap_offset_for_gid(glyph_id, ppem) strike = bitmap_sizes.find do |s| s.ppem == ppem && s.includes_glyph?(glyph_id) end return nil unless strike sub_tables_for(strike).each do |sub| loc = sub.locations.find { |l| l.glyph_id == glyph_id } return loc if loc end nil end |
#each_glyph_location {|CblcGlyphBitmapLocation| ... } ⇒ Enumerator
Iterate every (glyph_id, strike) → CblcGlyphBitmapLocation pair across all strikes. Each strike's IndexSubTables are walked in turn so the caller sees every glyph's CBDT location exactly once per strike.
52 53 54 55 56 57 58 |
# File 'lib/fontisan/tables/cblc.rb', line 52 def each_glyph_location(&block) return enum_for(:each_glyph_location) unless block index_sub_tables.each do |sub| sub.locations.each(&block) end end |
#glyph_ids_with_bitmaps ⇒ Array<Integer>
All glyph IDs that have any bitmap across every strike.
139 140 141 |
# File 'lib/fontisan/tables/cblc.rb', line 139 def glyph_ids_with_bitmaps bitmap_sizes.flat_map { |s| s.glyph_range.to_a }.uniq.sort end |
#index_sub_tables ⇒ Array<CblcIndexSubTable>
All IndexSubTable records across every strike.
63 64 65 |
# File 'lib/fontisan/tables/cblc.rb', line 63 def index_sub_tables @index_sub_tables ||= bitmap_sizes.flat_map { |s| sub_tables_for(s) } end |
#num_strikes ⇒ Integer
Number of bitmap strikes.
116 117 118 |
# File 'lib/fontisan/tables/cblc.rb', line 116 def num_strikes num_sizes end |
#ppem_sizes ⇒ Array<Integer>
All available ppem sizes across every strike.
109 110 111 |
# File 'lib/fontisan/tables/cblc.rb', line 109 def ppem_sizes bitmap_sizes.map(&:ppem).uniq.sort end |
#strikes_for_glyph(glyph_id) ⇒ Array<CblcBitmapSize>
Strikes that cover a given glyph ID.
124 125 126 |
# File 'lib/fontisan/tables/cblc.rb', line 124 def strikes_for_glyph(glyph_id) bitmap_sizes.select { |s| s.includes_glyph?(glyph_id) } end |
#strikes_for_ppem(ppem) ⇒ Array<CblcBitmapSize>
Strikes that match a specific ppem.
132 133 134 |
# File 'lib/fontisan/tables/cblc.rb', line 132 def strikes_for_ppem(ppem) bitmap_sizes.select { |s| s.ppem == ppem } end |
#sub_tables_for(strike) ⇒ Array<CblcIndexSubTable>
Iterate every IndexSubTable in a single strike.
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/fontisan/tables/cblc.rb', line 89 def sub_tables_for(strike) return [] if strike.number_of_index_subtables.zero? array_offset = strike.index_subtable_array_offset entries = read_index_subtable_array(strike, array_offset) entries.map do |entry| absolute = array_offset + entry.additional_offset_to_index_subtable CblcIndexSubTable.parse( raw_data, index_subtable_offset: absolute, first_glyph_index: entry.first_glyph_index, last_glyph_index: entry.last_glyph_index, ) end end |
#valid? ⇒ Boolean
Whether the CBLC header is one fontisan understands and at least the header fields parsed successfully.
147 148 149 150 151 152 |
# File 'lib/fontisan/tables/cblc.rb', line 147 def valid? return false if version.nil? return false unless [VERSION_2_0, VERSION_3_0].include?(version) true end |