Class: HexaPDF::Font::TrueTypeWrapper
- Inherits:
-
Object
- Object
- HexaPDF::Font::TrueTypeWrapper
- Defined in:
- lib/hexapdf/font/true_type_wrapper.rb
Overview
This class wraps a generic TrueType font object and provides the methods needed for working with the font in a PDF context.
TrueType fonts can be represented in two ways in PDF: As a simple font with Subtype TrueType or as a composite font using a Type2 CIDFont. The wrapper only supports the composite font case because:
-
By using a composite font more than 256 characters can be encoded with one font object.
-
Fonts for vertical writing can potentially be used.
-
The PDF specification recommends using a composite font (see PDF2.0 s9.9.1 at the end).
Additionally, TrueType fonts are always embedded.
Instance Attribute Summary collapse
-
#pdf_object ⇒ Object
readonly
Returns the PDF object associated with the wrapper.
-
#wrapped_font ⇒ Object
readonly
Returns the wrapped TrueType font object.
Instance Method Summary collapse
-
#bold? ⇒ Boolean
Returns
true
if the font contains bold glyphs. -
#custom_glyph(id, string) ⇒ Object
Returns a custom Glyph object which represents the given
string
via the given glyphid
. -
#decode_codepoint(codepoint) ⇒ Object
Returns a glyph object for the given Unicode codepoint.
-
#decode_utf8(str) ⇒ Object
Returns an array of glyph objects representing the characters in the UTF-8 encoded string.
-
#encode(glyph) ⇒ Object
Encodes the glyph and returns the code string.
-
#font_type ⇒ Object
Returns the type of the font, i.e.
-
#glyph(id, str = nil) ⇒ Object
Returns a Glyph object for the given glyph ID and
str
pair. -
#initialize(document, font, pdf_object: nil, subset: true) ⇒ TrueTypeWrapper
constructor
Creates a new object wrapping the TrueType font for the PDF document.
-
#italic? ⇒ Boolean
Returns
true
if the font contains glyphs with an incline (italic or slant). -
#scaling_factor ⇒ Object
Returns the scaling factor for converting font units into PDF units.
-
#subset? ⇒ Boolean
Returns
true
if the wrapped TrueType font will be subset.
Constructor Details
#initialize(document, font, pdf_object: nil, subset: true) ⇒ TrueTypeWrapper
Creates a new object wrapping the TrueType font for the PDF document.
The optional argument pdf_object
can be used to set the PDF font object that this wrapper should be associated with. If no object is set, a suitable one is automatically created.
If subset
is true, the font is subset.
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/hexapdf/font/true_type_wrapper.rb', line 144 def initialize(document, font, pdf_object: nil, subset: true) @wrapped_font = font @subsetter = (subset ? HexaPDF::Font::TrueType::Subsetter.new(font) : nil) @cmap = font[:cmap].preferred_table if @cmap.nil? raise HexaPDF::Error, "No mapping table for Unicode characters found for TTF " \ "font #{font.full_name}" end @pdf_object = pdf_object || create_pdf_object(document) @id_to_glyph = {} @codepoint_to_glyph = {} @encoded_glyphs = {} @last_char_code = 0 end |
Instance Attribute Details
#pdf_object ⇒ Object (readonly)
Returns the PDF object associated with the wrapper.
136 137 138 |
# File 'lib/hexapdf/font/true_type_wrapper.rb', line 136 def pdf_object @pdf_object end |
#wrapped_font ⇒ Object (readonly)
Returns the wrapped TrueType font object.
133 134 135 |
# File 'lib/hexapdf/font/true_type_wrapper.rb', line 133 def wrapped_font @wrapped_font end |
Instance Method Details
#bold? ⇒ Boolean
Returns true
if the font contains bold glyphs.
173 174 175 |
# File 'lib/hexapdf/font/true_type_wrapper.rb', line 173 def bold? @wrapped_font.weight > 500 end |
#custom_glyph(id, string) ⇒ Object
Returns a custom Glyph object which represents the given string
via the given glyph id
.
This functionality can be used to associate a single glyph id with multiple, different strings for replacement glyph purposes. When used in such a way, the used glyph id is often 0 which represents the missing glyph.
208 209 210 211 212 213 |
# File 'lib/hexapdf/font/true_type_wrapper.rb', line 208 def custom_glyph(id, string) if id < 0 || id >= @wrapped_font[:maxp].num_glyphs raise HexaPDF::Error, "Glyph ID #{id} is invalid for font '#{@wrapped_font.full_name}'" end Glyph.new(self, id, string) end |
#decode_codepoint(codepoint) ⇒ Object
Returns a glyph object for the given Unicode codepoint.
The configuration option ‘font.on_missing_glyph’ is invoked if no glyph for a given codepoint is available.
226 227 228 229 230 231 232 233 |
# File 'lib/hexapdf/font/true_type_wrapper.rb', line 226 def decode_codepoint(codepoint) @codepoint_to_glyph[codepoint] ||= if (gid = @cmap[codepoint]) glyph(gid, +'' << codepoint) else @pdf_object.document.config['font.on_missing_glyph'].call(+'' << codepoint, self) end end |
#decode_utf8(str) ⇒ Object
Returns an array of glyph objects representing the characters in the UTF-8 encoded string.
See #decode_codepoint for details.
218 219 220 |
# File 'lib/hexapdf/font/true_type_wrapper.rb', line 218 def decode_utf8(str) str.codepoints.map! {|c| @codepoint_to_glyph[c] || decode_codepoint(c) } end |
#encode(glyph) ⇒ Object
Encodes the glyph and returns the code string.
236 237 238 239 240 241 242 243 244 245 246 247 248 249 |
# File 'lib/hexapdf/font/true_type_wrapper.rb', line 236 def encode(glyph) (@encoded_glyphs[glyph] ||= begin raise HexaPDF::MissingGlyphError.new(glyph) if glyph.kind_of?(InvalidGlyph) @subsetter.use_glyph(glyph.id) if @subsetter @last_char_code += 1 # Handle codes for ASCII characters \r (13), (, ) (40, 41) and \ (92) specially so that # they never appear in the output (PDF serialization would need to escape them) if @last_char_code == 13 || @last_char_code == 40 || @last_char_code == 92 @last_char_code += (@last_char_code == 40 ? 2 : 1) end [[@last_char_code].pack('n'), @last_char_code] end)[0] end |
#font_type ⇒ Object
Returns the type of the font, i.e. :TrueType.
163 164 165 |
# File 'lib/hexapdf/font/true_type_wrapper.rb', line 163 def font_type :TrueType end |
#glyph(id, str = nil) ⇒ Object
Returns a Glyph object for the given glyph ID and str
pair.
The optional argument str
should be the string representation of the glyph. It is possible that multiple strings map to the same glyph (e.g. hyphen and soft-hyphen could be represented by the same glyph).
Note: Although this method is public, it should normally not be used by application code!
194 195 196 197 198 199 200 201 |
# File 'lib/hexapdf/font/true_type_wrapper.rb', line 194 def glyph(id, str = nil) @id_to_glyph[[id, str]] ||= if id >= 0 && id < @wrapped_font[:maxp].num_glyphs Glyph.new(self, id, str || (+'' << (@cmap.gid_to_code(id) || 0xFFFD))) else @pdf_object.document.config['font.on_missing_glyph'].call("\u{FFFD}", self) end end |
#italic? ⇒ Boolean
Returns true
if the font contains glyphs with an incline (italic or slant).
178 179 180 |
# File 'lib/hexapdf/font/true_type_wrapper.rb', line 178 def italic? @wrapped_font.italic_angle.to_i != 0 end |
#scaling_factor ⇒ Object
Returns the scaling factor for converting font units into PDF units.
168 169 170 |
# File 'lib/hexapdf/font/true_type_wrapper.rb', line 168 def scaling_factor @scaling_factor ||= 1000.0 / @wrapped_font[:head].units_per_em end |
#subset? ⇒ Boolean
Returns true
if the wrapped TrueType font will be subset.
183 184 185 |
# File 'lib/hexapdf/font/true_type_wrapper.rb', line 183 def subset? !@subsetter.nil? end |