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



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

def bitmap_sizes
  @bitmap_sizes
end

#num_sizesInteger (readonly)

Returns Number of bitmap size records.

Returns:

  • (Integer)

    Number of bitmap size records



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

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



153
154
155
# File 'lib/fontisan/tables/cblc.rb', line 153

def raw_data
  @raw_data
end

#versionInteger (readonly)

Returns CBLC version.

Returns:

  • (Integer)

    CBLC version



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

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



159
160
161
162
163
164
165
166
# File 'lib/fontisan/tables/cblc.rb', line 159

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



222
223
224
# File 'lib/fontisan/tables/cblc.rb', line 222

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



206
207
208
209
210
# File 'lib/fontisan/tables/cblc.rb', line 206

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



237
238
239
# File 'lib/fontisan/tables/cblc.rb', line 237

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:



172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/fontisan/tables/cblc.rb', line 172

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



215
216
217
# File 'lib/fontisan/tables/cblc.rb', line 215

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

#strikesArray<BitmapSize>

Get bitmap strikes (sizes)

Returns:



189
190
191
# File 'lib/fontisan/tables/cblc.rb', line 189

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



230
231
232
# File 'lib/fontisan/tables/cblc.rb', line 230

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:



197
198
199
# File 'lib/fontisan/tables/cblc.rb', line 197

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

#valid?Boolean

Validate the CBLC table structure

Returns:

  • (Boolean)

    True if valid



244
245
246
247
248
249
250
251
# File 'lib/fontisan/tables/cblc.rb', line 244

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