Class: Fontisan::Tables::Cbdt

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

Overview

CBDT (Color Bitmap Data) table parser

The CBDT table contains the actual bitmap data for color glyphs. It works together with the CBLC table which provides the location information for finding bitmaps in this table.

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

+ Bitmap Data (variable length)

“‘

Header (8 bytes):

  • majorVersion (uint16): Major version (2 or 3)

  • minorVersion (uint16): Minor version (0)

  • reserved (uint32): Reserved, set to 0

The bitmap data format depends on the index subtable format in CBLC. Common formats include:

  • Format 17: Small metrics, PNG data

  • Format 18: Big metrics, PNG data

  • Format 19: Metrics in CBLC, PNG data

This parser provides low-level access to bitmap data. For proper bitmap extraction, use together with CBLC table which contains the index.

Reference: OpenType CBDT specification docs.microsoft.com/en-us/typography/opentype/spec/cbdt

Examples:

Reading a CBDT table

data = font.table_data['CBDT']
cbdt = Fontisan::Tables::Cbdt.read(data)
bitmap_data = cbdt.bitmap_data_at(offset, length)

Constant Summary collapse

TAG =

OpenType table tag for CBDT

"CBDT"
VERSION_2_0 =

Supported CBDT versions

0x0002_0000
VERSION_3_0 =
0x0003_0000

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#major_versionInteger (readonly)

Returns Major version (2 or 3).

Returns:

  • (Integer)

    Major version (2 or 3)



50
51
52
# File 'lib/fontisan/tables/cbdt.rb', line 50

def major_version
  @major_version
end

#minor_versionInteger (readonly)

Returns Minor version (0).

Returns:

  • (Integer)

    Minor version (0)



53
54
55
# File 'lib/fontisan/tables/cbdt.rb', line 53

def minor_version
  @minor_version
end

#raw_dataString (readonly)

Returns Raw binary data for the entire CBDT table.

Returns:

  • (String)

    Raw binary data for the entire CBDT table



56
57
58
# File 'lib/fontisan/tables/cbdt.rb', line 56

def raw_data
  @raw_data
end

Class Method Details

.read(io) ⇒ Cbdt

Override read to parse CBDT structure

Parameters:

  • io (IO, String)

    Binary data to read

Returns:

  • (Cbdt)

    Parsed CBDT table



62
63
64
65
66
67
68
69
# File 'lib/fontisan/tables/cbdt.rb', line 62

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

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

Instance Method Details

#bitmap_data_at(offset, length) ⇒ String?

Get bitmap data at specific offset and length

Used together with CBLC index to extract bitmap data.

Parameters:

  • offset (Integer)

    Offset from start of table

  • length (Integer)

    Length of bitmap data

Returns:

  • (String, nil)

    Binary bitmap data or nil



93
94
95
96
97
98
99
# File 'lib/fontisan/tables/cbdt.rb', line 93

def bitmap_data_at(offset, length)
  return nil if offset.nil? || length.nil?
  return nil if offset.negative? || length.negative?
  return nil if offset + length > raw_data.length

  raw_data[offset, length]
end

#data_sizeInteger

Get table data size

Returns:

  • (Integer)

    Size of CBDT table in bytes



113
114
115
# File 'lib/fontisan/tables/cbdt.rb', line 113

def data_size
  raw_data&.length || 0
end

#parse!(data) ⇒ Object

Parse the CBDT table structure

Parameters:

  • data (String)

    Binary data for the CBDT table

Raises:



75
76
77
78
79
80
81
82
83
84
# File 'lib/fontisan/tables/cbdt.rb', line 75

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

  # Parse CBDT header (8 bytes)
  parse_header(io)
  validate_header!
rescue StandardError => e
  raise CorruptedTableError, "Failed to parse CBDT table: #{e.message}"
end

#valid?Boolean

Validate the CBDT table structure

Returns:

  • (Boolean)

    True if valid



131
132
133
134
135
136
137
138
# File 'lib/fontisan/tables/cbdt.rb', line 131

def valid?
  return false if major_version.nil? || minor_version.nil?
  return false unless [2, 3].include?(major_version)
  return false unless minor_version.zero?
  return false unless raw_data

  true
end

#valid_offset?(offset) ⇒ Boolean

Check if offset is valid for this table

Parameters:

  • offset (Integer)

    Offset to check

Returns:

  • (Boolean)

    True if offset is within table bounds



121
122
123
124
125
126
# File 'lib/fontisan/tables/cbdt.rb', line 121

def valid_offset?(offset)
  return false if offset.nil? || offset.negative?
  return false if raw_data.nil?

  offset < raw_data.length
end

#versionInteger

Get combined version number

Returns:

  • (Integer)

    Combined version (e.g., 0x00020000 for v2.0)



104
105
106
107
108
# File 'lib/fontisan/tables/cbdt.rb', line 104

def version
  return nil if major_version.nil? || minor_version.nil?

  (major_version << 16) | minor_version
end