Class: Fontisan::TrueTypeCollection
- Inherits:
-
BinData::Record
- Object
- BinData::Record
- Fontisan::TrueTypeCollection
- Defined in:
- lib/fontisan/true_type_collection.rb
Overview
TrueType Collection domain object using BinData
Represents a complete TrueType Collection file using BinData’s declarative DSL for binary structure definition. The structure definition IS the documentation, and BinData handles all low-level reading/writing.
Class Method Summary collapse
-
.from_file(path) ⇒ TrueTypeCollection
Read TrueType Collection from a file.
Instance Method Summary collapse
-
#collection_info(io, path) ⇒ CollectionInfo
Get comprehensive collection metadata.
-
#extract_fonts(io) ⇒ Array<TrueTypeFont>
Extract fonts as TrueTypeFont objects.
-
#font(index, io, mode: LoadingModes::FULL) ⇒ TrueTypeFont?
Get a single font from the collection (Fontisan extension).
-
#font_count ⇒ Integer
Get font count (Fontisan extension).
-
#list_fonts(io) ⇒ CollectionListInfo
List all fonts in the collection with basic metadata.
-
#valid? ⇒ Boolean
Validate format correctness.
-
#version ⇒ Object
Get the TTC version as a single integer.
Class Method Details
.from_file(path) ⇒ TrueTypeCollection
Read TrueType Collection from a file
35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/fontisan/true_type_collection.rb', line 35 def self.from_file(path) if path.nil? || path.to_s.empty? raise ArgumentError, "path cannot be nil or empty" end raise Errno::ENOENT, "File not found: #{path}" unless File.exist?(path) File.open(path, "rb") { |io| read(io) } rescue BinData::ValidityError => e raise "Invalid TTC file: #{e.}" rescue EOFError => e raise "Invalid TTC file: unexpected end of file - #{e.}" end |
Instance Method Details
#collection_info(io, path) ⇒ CollectionInfo
Get comprehensive collection metadata
Returns a CollectionInfo model with header information, offsets, and table sharing statistics. This is the API method used by the ‘info` command for collections.
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/fontisan/true_type_collection.rb', line 178 def collection_info(io, path) require_relative "models/collection_info" require_relative "models/table_sharing_info" # Calculate table sharing statistics table_sharing = calculate_table_sharing(io) # Get file size file_size = path ? File.size(path) : 0 Models::CollectionInfo.new( collection_path: path, collection_format: "TTC", ttc_tag: tag, major_version: major_version, minor_version: minor_version, num_fonts: num_fonts, font_offsets: font_offsets.to_a, file_size_bytes: file_size, table_sharing: table_sharing, ) end |
#extract_fonts(io) ⇒ Array<TrueTypeFont>
Extract fonts as TrueTypeFont objects
Reads each font from the TTC file and returns them as TrueTypeFont objects.
55 56 57 58 59 60 61 |
# File 'lib/fontisan/true_type_collection.rb', line 55 def extract_fonts(io) require_relative "true_type_font" font_offsets.map do |offset| TrueTypeFont.from_ttc(io, offset) end end |
#font(index, io, mode: LoadingModes::FULL) ⇒ TrueTypeFont?
Get a single font from the collection (Fontisan extension)
69 70 71 72 73 74 |
# File 'lib/fontisan/true_type_collection.rb', line 69 def font(index, io, mode: LoadingModes::FULL) return nil if index >= num_fonts require_relative "true_type_font" TrueTypeFont.from_ttc(io, font_offsets[index], mode: mode) end |
#font_count ⇒ Integer
Get font count (Fontisan extension)
79 80 81 |
# File 'lib/fontisan/true_type_collection.rb', line 79 def font_count num_fonts end |
#list_fonts(io) ⇒ CollectionListInfo
List all fonts in the collection with basic metadata
Returns a CollectionListInfo model containing summaries of all fonts. This is the API method used by the ‘ls` command for collections.
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/fontisan/true_type_collection.rb', line 113 def list_fonts(io) require_relative "models/collection_list_info" require_relative "models/collection_font_summary" require_relative "true_type_font" require_relative "tables/name" fonts = font_offsets.map.with_index do |offset, index| font = TrueTypeFont.from_ttc(io, offset) # Extract basic font info name_table = font.table("name") post_table = font.table("post") family_name = name_table&.english_name(Tables::Name::FAMILY) || "Unknown" subfamily_name = name_table&.english_name(Tables::Name::SUBFAMILY) || "Regular" postscript_name = name_table&.english_name(Tables::Name::POSTSCRIPT_NAME) || "Unknown" # Determine font format sfnt = font.header.sfnt_version font_format = case sfnt when 0x00010000, 0x74727565 # 0x74727565 = 'true' "TrueType" when 0x4F54544F # 'OTTO' "OpenType" else "Unknown" end num_glyphs = post_table&.glyph_names&.length || 0 num_tables = font.table_names.length Models::CollectionFontSummary.new( index: index, family_name: family_name, subfamily_name: subfamily_name, postscript_name: postscript_name, font_format: font_format, num_glyphs: num_glyphs, num_tables: num_tables, ) end Models::CollectionListInfo.new( collection_path: nil, # Will be set by command num_fonts: num_fonts, fonts: fonts, ) end |
#valid? ⇒ Boolean
Validate format correctness
86 87 88 89 90 |
# File 'lib/fontisan/true_type_collection.rb', line 86 def valid? tag == Constants::TTC_TAG && num_fonts.positive? && font_offsets.length == num_fonts rescue StandardError false end |
#version ⇒ Object
Get the TTC version as a single integer
@return [Integer] Version number (e.g., 0x00010000 for version 1.0)
95 96 97 |
# File 'lib/fontisan/true_type_collection.rb', line 95 def version (major_version << 16) | minor_version end |