Class: HexaPDF::Font::Type1Wrapper

Inherits:
Object
  • Object
show all
Defined in:
lib/hexapdf/font/type1_wrapper.rb

Overview

This class wraps a generic Type1 font object and provides the methods needed for working with the font in a PDF context.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(document, font, custom_encoding: false) ⇒ Type1Wrapper

Creates a new object wrapping the Type1 font for the PDF document.

The optional argument custom_encoding can be set to true so that a custom encoding instead of the WinAnsiEncoding is used.



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/hexapdf/font/type1_wrapper.rb', line 111

def initialize(document, font, custom_encoding: false)
  @document = document
  @wrapped_font = font

  @dict = build_font_dict
  @document.register_listener(:complete_objects, &method(:complete_font_dict))
  if @wrapped_font.metrics.character_set == 'Special' || custom_encoding
    @encoding = Encoding::Base.new
    @encoding.code_to_name[32] = :space
    @max_code = 32 # 32 = space
  else
    @encoding = Encoding.for_name(:WinAnsiEncoding)
    @max_code = 255 # Encoding is not modified
  end

  @zapf_dingbats_opt = {zapf_dingbats: (@wrapped_font.font_name == 'ZapfDingbats')}
  @name_to_glyph = {}
  @codepoint_to_glyph = {}
  @encoded_glyphs = {}
end

Instance Attribute Details

#dictObject (readonly)

The PDF font dictionary representing the wrapped font.



105
106
107
# File 'lib/hexapdf/font/type1_wrapper.rb', line 105

def dict
  @dict
end

#wrapped_fontObject (readonly)

Returns the wrapped Type1 font object.



102
103
104
# File 'lib/hexapdf/font/type1_wrapper.rb', line 102

def wrapped_font
  @wrapped_font
end

Instance Method Details

#decode_utf8(str) ⇒ Object

Returns an array of glyph objects representing the characters in the UTF-8 encoded string.



156
157
158
159
160
161
162
163
164
165
# File 'lib/hexapdf/font/type1_wrapper.rb', line 156

def decode_utf8(str)
  str.codepoints.map! do |c|
    @codepoint_to_glyph[c] ||=
      begin
        name = Encoding::GlyphList.unicode_to_name(+'' << c, @zapf_dingbats_opt)
        name = +"u" << c.to_s(16).rjust(6, '0') if name == :'.notdef'
        glyph(name)
      end
  end
end

#encode(glyph) ⇒ Object

Encodes the glyph and returns the code string.



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/hexapdf/font/type1_wrapper.rb', line 168

def encode(glyph)
  @encoded_glyphs[glyph.name] ||=
    begin
      if glyph.name == @wrapped_font.missing_glyph_id
        raise HexaPDF::Error, "Glyph for #{glyph.str.inspect} missing"
      end
      code = @encoding.code_to_name.key(glyph.name)
      if code
        code.chr.freeze
      elsif @max_code < 255
        @max_code += 1
        @encoding.code_to_name[@max_code] = glyph.name
        @max_code.chr.freeze
      else
        raise HexaPDF::Error, "Type1 encoding has no codepoint for #{glyph.name}"
      end
    end
end

#font_typeObject

Returns the type of the font, i.e. :Type1.



133
134
135
# File 'lib/hexapdf/font/type1_wrapper.rb', line 133

def font_type
  :Type1
end

#glyph(name) ⇒ Object

Returns a Glyph object for the given glyph name.



143
144
145
146
147
148
149
150
151
152
153
# File 'lib/hexapdf/font/type1_wrapper.rb', line 143

def glyph(name)
  @name_to_glyph[name] ||=
    begin
      str = Encoding::GlyphList.name_to_unicode(name, @zapf_dingbats_opt)
      if @wrapped_font.metrics.character_metrics.key?(name)
        Glyph.new(@wrapped_font, name, str)
      else
        @document.config['font.on_missing_glyph'].call(str, font_type, @wrapped_font)
      end
    end
end

#scaling_factorObject

Returns 1 since all Type1 fonts use 1000 units for the em-square.



138
139
140
# File 'lib/hexapdf/font/type1_wrapper.rb', line 138

def scaling_factor
  1
end