Class: HexaPDF::Font::TrueType::Table::CmapSubtable

Inherits:
Object
  • Object
show all
Defined in:
lib/hexapdf/font/true_type/table/cmap_subtable.rb

Overview

Generic base class for all cmap subtables.

cmap format 8.0 is currently not implemented because use of the format is discouraged in the specification and no font with a format 8.0 cmap subtable was available for testing.

The preferred cmap format is 12.0 because it supports all of Unicode and allows for fast and memory efficient code-to-gid as well as gid-to-code mappings.

See:

Defined Under Namespace

Modules: Format0, Format10, Format12, Format2, Format4, Format6

Constant Summary collapse

PLATFORM_UNICODE =

The platform identifier for Unicode.

0
PLATFORM_MICROSOFT =

The platform identifier for Microsoft.

3

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(platform_id, encoding_id) ⇒ CmapSubtable

Creates a new subtable.



87
88
89
90
91
92
93
94
95
# File 'lib/hexapdf/font/true_type/table/cmap_subtable.rb', line 87

def initialize(platform_id, encoding_id)
  @platform_id = platform_id
  @encoding_id = encoding_id
  @supported = true
  @code_map = {}
  @gid_map = {}
  @format = nil
  @language = 0
end

Instance Attribute Details

#code_mapObject

The complete code map.

Is only fully initialized for existing fonts when a mapping is first accessed via #[].



78
79
80
# File 'lib/hexapdf/font/true_type/table/cmap_subtable.rb', line 78

def code_map
  @code_map
end

#encoding_idObject

The platform-specific encoding identifier.



67
68
69
# File 'lib/hexapdf/font/true_type/table/cmap_subtable.rb', line 67

def encoding_id
  @encoding_id
end

#formatObject (readonly)

The cmap format or nil if the subtable wasn’t read from a file.



70
71
72
# File 'lib/hexapdf/font/true_type/table/cmap_subtable.rb', line 70

def format
  @format
end

#gid_mapObject

The complete gid map.

Is only fully initialized for existing fonts when a mapping is first accessed via #gid_to_code.



84
85
86
# File 'lib/hexapdf/font/true_type/table/cmap_subtable.rb', line 84

def gid_map
  @gid_map
end

#languageObject

The language code.



73
74
75
# File 'lib/hexapdf/font/true_type/table/cmap_subtable.rb', line 73

def language
  @language
end

#platform_idObject

The platform identifier.



64
65
66
# File 'lib/hexapdf/font/true_type/table/cmap_subtable.rb', line 64

def platform_id
  @platform_id
end

Instance Method Details

#[](code) ⇒ Object

Returns the glyph index for the given character code or nil if the character code is not mapped.



105
106
107
# File 'lib/hexapdf/font/true_type/table/cmap_subtable.rb', line 105

def [](code)
  @code_map[code]
end

#gid_to_code(gid) ⇒ Object

Returns a character code for the given glyph index or nil if the given glyph index does not exist or is not mapped to a character code.

Note that some fonts map multiple character codes to the same glyph (e.g. hyphen and minus), i.e. the code-to-glyph mapping is surjective but not injective! In such a case one of the available character codes is returned.



115
116
117
# File 'lib/hexapdf/font/true_type/table/cmap_subtable.rb', line 115

def gid_to_code(gid)
  @gid_map[gid]
end

#inspectObject

:nodoc:



162
163
164
165
# File 'lib/hexapdf/font/true_type/table/cmap_subtable.rb', line 162

def inspect #:nodoc:
  "#<#{self.class.name} (#{platform_id}, #{encoding_id}, #{language}, " \
    "#{format.inspect})>"
end

#parse(io, offset) ⇒ Object

:call-seq:

subtable.parse!(io, offset)     => true or false

Parses the cmap subtable from the IO at the given offset.

If the subtable format is supported, the information is used to populate this object and true is returned. Otherwise nothing is done and false is returned.



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/hexapdf/font/true_type/table/cmap_subtable.rb', line 126

def parse(io, offset)
  io.pos = offset
  @format = io.read(2).unpack1('n')
  if [8, 10, 12].include?(@format)
    io.pos += 2
    length, @language = io.read(8).unpack('N2')
  elsif [0, 2, 4, 6].include?(@format)
    length, @language = io.read(4).unpack('n2')
  end

  return false unless [0, 2, 4, 6, 10, 12].include?(@format)
  offset = io.pos
  @code_map = lambda do |code|
    parse_mapping(io, offset, length)
    @code_map[code]
  end
  @gid_map = lambda do |gid|
    parse_mapping(io, offset, length)
    @gid_map[gid]
  end
  true
end

#unicode?Boolean

Returns true if this subtable contains a Unicode cmap.

Returns:

  • (Boolean)


98
99
100
101
# File 'lib/hexapdf/font/true_type/table/cmap_subtable.rb', line 98

def unicode?
  (platform_id == PLATFORM_MICROSOFT && (encoding_id == 1 || encoding_id == 10)) ||
    platform_id == PLATFORM_UNICODE
end