Class: Fontisan::Woff2::CollectionDecoder
- Inherits:
-
Object
- Object
- Fontisan::Woff2::CollectionDecoder
- Defined in:
- lib/fontisan/woff2/collection_decoder.rb
Overview
Decodes a WOFF2 font collection per spec section 4.2. This is the decoder counterpart of CollectionEncoder.
Layout parsed:
[WOFF2Header (48 bytes, flavor = 'ttcf')]
[TableDirectory] # one entry per unique table
[CollectionDirectory] # CollectionHeader + N CollectionFontEntry
[CompressedFontData] # single brotli stream of all tables
Each CollectionFontEntry references tables in the TableDirectory via indices. The decoder yields one reconstructed font per entry, with glyf/loca reconstruction per spec section 5.1/5.3 applied.
Reference: W3C WOFF2 spec, section 4.2.
Defined Under Namespace
Classes: FontEntry, TableEntry
Constant Summary collapse
- TTC_FLAVOR =
'ttcf'
0x74746366
Instance Method Summary collapse
-
#decode ⇒ Array<Hash{Symbol => Object}>
Decode the WOFF2 collection, returning one Hash per font containing the reconstructed table data ready to assemble into an SFNT.
-
#initialize(data) ⇒ CollectionDecoder
constructor
A new instance of CollectionDecoder.
Constructor Details
#initialize(data) ⇒ CollectionDecoder
Returns a new instance of CollectionDecoder.
32 33 34 |
# File 'lib/fontisan/woff2/collection_decoder.rb', line 32 def initialize(data) @data = data.dup.force_encoding(Encoding::BINARY) end |
Instance Method Details
#decode ⇒ Array<Hash{Symbol => Object}>
Decode the WOFF2 collection, returning one Hash per font containing the reconstructed table data ready to assemble into an SFNT.
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/fontisan/woff2/collection_decoder.rb', line 41 def decode validate_signature! validate_collection_flavor! table_entries, post_dir_pos = read_table_directory font_entries, post_coll_pos = read_collection_directory(post_dir_pos) decompressed = decompress_table_data(post_coll_pos) # Replace each table entry's raw_bytes by slicing from the # decompressed stream at its cumulative offset. cursor = 0 table_entries.each do |e| len = e.transform_length || e.orig_length e.raw_bytes = decompressed[cursor, len] cursor += len end # For each font, gather its tables and reconstruct glyf/loca when # the glyf was transformed. font_entries.map do |fe| font_tables = {} fe.table_indices.each do |idx| entry = table_entries.fetch(idx) font_tables[entry.tag] = entry.raw_bytes end reconstruct_glyf_loca!(font_tables) if font_tables.key?("glyf") { flavor: fe.flavor, tables: font_tables } end end |