Class: Fontisan::Tables::Svg

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

Overview

SVG (Scalable Vector Graphics) table parser

The SVG table contains embedded SVG documents for glyphs, typically used for color emoji or graphic elements. Each document can cover a range of glyph IDs and may be compressed with gzip.

SVG Table Structure: “‘ SVG Table = Header (10 bytes)

+ Document Index
+ SVG Documents

“‘

Header (10 bytes):

  • version (uint16): Table version (0)

  • svgDocumentListOffset (uint32): Offset to SVG Document Index

  • reserved (uint32): Reserved, set to 0

Document Index:

  • numEntries (uint16): Number of SVG Document Index Entries

  • entries: Array of SVG Document Index Entries

SVG Document Index Entry (12 bytes):

  • startGlyphID (uint16): First glyph ID

  • endGlyphID (uint16): Last glyph ID (inclusive)

  • svgDocOffset (uint32): Offset to SVG document

  • svgDocLength (uint32): Length of SVG document

SVG documents may be compressed with gzip (identified by magic bytes 0x1f 0x8b).

Reference: OpenType SVG specification docs.microsoft.com/en-us/typography/opentype/spec/svg

Examples:

Reading an SVG table

data = font.table_data['SVG ']
svg = Fontisan::Tables::Svg.read(data)
svg_content = svg.svg_for_glyph(42)
puts "Glyph 42 SVG: #{svg_content}"

Defined Under Namespace

Classes: SvgDocumentRecord

Constant Summary collapse

TAG =

OpenType table tag for SVG (note: includes trailing space)

"SVG "

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#document_recordsArray<SvgDocumentRecord> (readonly)

Returns Parsed document records.

Returns:



88
89
90
# File 'lib/fontisan/tables/svg.rb', line 88

def document_records
  @document_records
end

#num_entriesInteger (readonly)

Returns Number of SVG document entries.

Returns:

  • (Integer)

    Number of SVG document entries



85
86
87
# File 'lib/fontisan/tables/svg.rb', line 85

def num_entries
  @num_entries
end

#raw_dataString (readonly)

Returns Raw binary data for the entire SVG table.

Returns:

  • (String)

    Raw binary data for the entire SVG table



91
92
93
# File 'lib/fontisan/tables/svg.rb', line 91

def raw_data
  @raw_data
end

#svg_document_list_offsetInteger (readonly)

Returns Offset to SVG Document Index.

Returns:

  • (Integer)

    Offset to SVG Document Index



82
83
84
# File 'lib/fontisan/tables/svg.rb', line 82

def svg_document_list_offset
  @svg_document_list_offset
end

#versionInteger (readonly)

Returns SVG table version (0).

Returns:

  • (Integer)

    SVG table version (0)



79
80
81
# File 'lib/fontisan/tables/svg.rb', line 79

def version
  @version
end

Class Method Details

.read(io) ⇒ Svg

Override read to parse SVG structure

Parameters:

  • io (IO, String)

    Binary data to read

Returns:

  • (Svg)

    Parsed SVG table



97
98
99
100
101
102
103
104
# File 'lib/fontisan/tables/svg.rb', line 97

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

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

Instance Method Details

#glyph_ids_with_svgArray<Integer>

Get all glyph IDs that have SVG data

Returns:

  • (Array<Integer>)

    Array of glyph IDs with SVG



150
151
152
153
154
# File 'lib/fontisan/tables/svg.rb', line 150

def glyph_ids_with_svg
  document_records.flat_map do |record|
    record.glyph_range.to_a
  end
end

#has_svg_for_glyph?(glyph_id) ⇒ Boolean

Check if glyph has SVG data

Parameters:

  • glyph_id (Integer)

    Glyph ID to check

Returns:

  • (Boolean)

    True if glyph has SVG



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

def has_svg_for_glyph?(glyph_id)
  !find_document_record(glyph_id).nil?
end

#num_svg_documentsInteger

Get the number of SVG documents in this table

Returns:

  • (Integer)

    Number of SVG documents



159
160
161
# File 'lib/fontisan/tables/svg.rb', line 159

def num_svg_documents
  num_entries
end

#parse!(data) ⇒ Object

Parse the SVG table structure

Parameters:

  • data (String)

    Binary data for the SVG table

Raises:



110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/fontisan/tables/svg.rb', line 110

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

  # Parse SVG header (10 bytes)
  parse_header(io)
  validate_header!

  # Parse document index
  parse_document_index(io)
rescue StandardError => e
  raise CorruptedTableError, "Failed to parse SVG table: #{e.message}"
end

#svg_for_glyph(glyph_id) ⇒ String?

Get SVG document for a specific glyph ID

Returns the SVG XML content for the specified glyph. Automatically decompresses gzipped content. Returns nil if glyph has no SVG data.

Parameters:

  • glyph_id (Integer)

    Glyph ID to look up

Returns:

  • (String, nil)

    SVG XML content or nil



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

def svg_for_glyph(glyph_id)
  record = find_document_record(glyph_id)
  return nil unless record

  extract_svg_document(record)
end

#valid?Boolean

Validate the SVG table structure

Returns:

  • (Boolean)

    True if valid



166
167
168
169
170
171
172
173
# File 'lib/fontisan/tables/svg.rb', line 166

def valid?
  return false if version.nil?
  return false if version != 0 # Only version 0 supported
  return false if num_entries.nil? || num_entries.negative?
  return false unless document_records

  true
end