Class: Fontisan::Tables::Cblc

Inherits:
Binary::BaseRecord show all
Defined in:
lib/fontisan/tables/cblc.rb

Overview

CBLC (Color Bitmap Location) table parser

The CBLC table contains location information for bitmap glyphs at various sizes (strikes). It works together with the CBDT table which contains the actual bitmap data.

CBLC Table Structure: “‘ CBLC Table = Header (8 bytes)

+ BitmapSize Records (48 bytes each)

“‘

Header (8 bytes):

  • version (uint32): Table version (0x00020000 or 0x00030000)

  • numSizes (uint32): Number of BitmapSize records

Each BitmapSize record (48 bytes) contains:

  • indexSubTableArrayOffset (uint32): Offset to index subtable array

  • indexTablesSize (uint32): Size of index subtables

  • numberOfIndexSubTables (uint32): Number of index subtables

  • colorRef (uint32): Not used, set to 0

  • hori (SbitLineMetrics, 12 bytes): Horizontal line metrics

  • vert (SbitLineMetrics, 12 bytes): Vertical line metrics

  • startGlyphIndex (uint16): First glyph ID in strike

  • endGlyphIndex (uint16): Last glyph ID in strike

  • ppemX (uint8): Horizontal pixels per em

  • ppemY (uint8): Vertical pixels per em

  • bitDepth (uint8): Bit depth (1, 2, 4, 8, 32)

  • flags (int8): Flags

Reference: OpenType CBLC specification docs.microsoft.com/en-us/typography/opentype/spec/cblc

Examples:

Reading a CBLC table

data = font.table_data['CBLC']
cblc = Fontisan::Tables::Cblc.read(data)
strikes = cblc.strikes
puts "Font has #{strikes.length} bitmap strikes"

Defined Under Namespace

Classes: BitmapSize, SbitLineMetrics

Constant Summary collapse

TAG =

OpenType table tag for CBLC

"CBLC"
VERSION_2_0 =

Supported CBLC versions

0x00020000
VERSION_3_0 =
0x00030000

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#bitmap_sizesArray<BitmapSize> (readonly)

Returns Parsed bitmap size records.

Returns:

  • (Array<BitmapSize>)

    Parsed bitmap size records



146
147
148
# File 'lib/fontisan/tables/cblc.rb', line 146

def bitmap_sizes
  @bitmap_sizes
end

#num_sizesInteger (readonly)

Returns Number of bitmap size records.

Returns:

  • (Integer)

    Number of bitmap size records



143
144
145
# File 'lib/fontisan/tables/cblc.rb', line 143

def num_sizes
  @num_sizes
end

#raw_dataString (readonly)

Returns Raw binary data for the entire CBLC table.

Returns:

  • (String)

    Raw binary data for the entire CBLC table



149
150
151
# File 'lib/fontisan/tables/cblc.rb', line 149

def raw_data
  @raw_data
end

#versionInteger (readonly)

Returns CBLC version.

Returns:

  • (Integer)

    CBLC version



140
141
142
# File 'lib/fontisan/tables/cblc.rb', line 140

def version
  @version
end

Class Method Details

.read(io) ⇒ Cblc

Override read to parse CBLC structure

Parameters:

  • io (IO, String)

    Binary data to read

Returns:

  • (Cblc)

    Parsed CBLC table



155
156
157
158
159
160
161
162
# File 'lib/fontisan/tables/cblc.rb', line 155

def self.read(io)
  cblc = new
  return cblc if io.nil?

  data = io.is_a?(String) ? io : io.read
  cblc.parse!(data)
  cblc
end

Instance Method Details

#glyph_ids_with_bitmapsArray<Integer>

Get all glyph IDs that have bitmaps across all strikes

Returns:

  • (Array<Integer>)

    Array of glyph IDs



218
219
220
# File 'lib/fontisan/tables/cblc.rb', line 218

def glyph_ids_with_bitmaps
  strikes.flat_map { |strike| strike.glyph_range.to_a }.uniq.sort
end

#has_bitmap_for_glyph?(glyph_id, ppem) ⇒ Boolean

Check if glyph has bitmap at ppem size

Parameters:

  • glyph_id (Integer)

    Glyph ID

  • ppem (Integer)

    Pixels per em

Returns:

  • (Boolean)

    True if glyph has bitmap



202
203
204
205
206
# File 'lib/fontisan/tables/cblc.rb', line 202

def has_bitmap_for_glyph?(glyph_id, ppem)
  strikes_for_ppem(ppem).any? do |strike|
    strike.includes_glyph?(glyph_id)
  end
end

#num_strikesInteger

Get the number of bitmap strikes

Returns:

  • (Integer)

    Number of strikes



233
234
235
# File 'lib/fontisan/tables/cblc.rb', line 233

def num_strikes
  num_sizes || 0
end

#parse!(data) ⇒ Object

Parse the CBLC table structure

Parameters:

  • data (String)

    Binary data for the CBLC table

Raises:



168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/fontisan/tables/cblc.rb', line 168

def parse!(data)
  @raw_data = data
  io = StringIO.new(data)

  # Parse CBLC header (8 bytes)
  parse_header(io)
  validate_header!

  # Parse bitmap size records
  parse_bitmap_sizes(io)
rescue StandardError => e
  raise CorruptedTableError, "Failed to parse CBLC table: #{e.message}"
end

#ppem_sizesArray<Integer>

Get all available ppem sizes

Returns:

  • (Array<Integer>)

    Sorted array of ppem sizes



211
212
213
# File 'lib/fontisan/tables/cblc.rb', line 211

def ppem_sizes
  strikes.map(&:ppem).uniq.sort
end

#strikesArray<BitmapSize>

Get bitmap strikes (sizes)

Returns:



185
186
187
# File 'lib/fontisan/tables/cblc.rb', line 185

def strikes
  bitmap_sizes || []
end

#strikes_for_glyph(glyph_id) ⇒ Array<BitmapSize>

Get strikes that include a specific glyph ID

Parameters:

  • glyph_id (Integer)

    Glyph ID

Returns:

  • (Array<BitmapSize>)

    Strikes containing glyph



226
227
228
# File 'lib/fontisan/tables/cblc.rb', line 226

def strikes_for_glyph(glyph_id)
  strikes.select { |strike| strike.includes_glyph?(glyph_id) }
end

#strikes_for_ppem(ppem) ⇒ Array<BitmapSize>

Get strikes for specific ppem size

Parameters:

  • ppem (Integer)

    Pixels per em

Returns:



193
194
195
# File 'lib/fontisan/tables/cblc.rb', line 193

def strikes_for_ppem(ppem)
  strikes.select { |size| size.ppem == ppem }
end

#valid?Boolean

Validate the CBLC table structure

Returns:

  • (Boolean)

    True if valid



240
241
242
243
244
245
246
247
# File 'lib/fontisan/tables/cblc.rb', line 240

def valid?
  return false if version.nil?
  return false unless [VERSION_2_0, VERSION_3_0].include?(version)
  return false if num_sizes.nil? || num_sizes.negative?
  return false unless bitmap_sizes

  true
end