Class: Prawn::Font::TTF
- Inherits:
-
Prawn::Font
- Object
- Prawn::Font
- Prawn::Font::TTF
- Defined in:
- lib/prawn/font/ttf.rb
Direct Known Subclasses
Instance Attribute Summary collapse
-
#subsets ⇒ Object
readonly
Returns the value of attribute subsets.
-
#ttf ⇒ Object
readonly
Returns the value of attribute ttf.
Attributes inherited from Prawn::Font
Instance Method Summary collapse
- #basename ⇒ Object
-
#bbox ⇒ Object
The font bbox, as an array of integers.
- #cap_height ⇒ Object
-
#character_count(str) ⇒ Object
Returns the number of characters in
str
(a UTF-8-encoded string). -
#compute_width_of(string, options = {}) ⇒ Object
NOTE:
string
must be UTF8-encoded. -
#encode_text(text, options = {}) ⇒ Object
Perform any changes to the string that need to happen before it is rendered to the canvas.
- #family_class ⇒ Object
- #glyph_present?(char) ⇒ Boolean
-
#has_kerning_data? ⇒ Boolean
Returns true if the font has kerning data, false otherwise.
-
#initialize(document, name, options = {}) ⇒ TTF
constructor
A new instance of TTF.
- #italic_angle ⇒ Object
- #normalize_encoding(text) ⇒ Object
- #pdf_flags ⇒ Object
- #script? ⇒ Boolean
- #serif? ⇒ Boolean
-
#stemV ⇒ Object
not sure how to compute this for true-type fonts…
- #unicode? ⇒ Boolean
- #x_height ⇒ Object
Methods inherited from Prawn::Font
#add_to_current_page, #ascender, #descender, #height, #height_at, #identifier_for, #inspect, #line_gap, load, #normalize_encoding!
Constructor Details
#initialize(document, name, options = {}) ⇒ TTF
Returns a new instance of TTF.
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/prawn/font/ttf.rb', line 22 def initialize(document, name, ={}) super @ttf = read_ttf_file @subsets = TTFunk::SubsetCollection.new(@ttf) @attributes = {} @bounding_boxes = {} @char_widths = {} @has_kerning_data = @ttf.kerning.exists? && @ttf.kerning.tables.any? @ascender = Integer(@ttf.ascent * scale_factor) @descender = Integer(@ttf.descent * scale_factor) @line_gap = Integer(@ttf.line_gap * scale_factor) end |
Instance Attribute Details
#subsets ⇒ Object (readonly)
Returns the value of attribute subsets.
16 17 18 |
# File 'lib/prawn/font/ttf.rb', line 16 def subsets @subsets end |
#ttf ⇒ Object (readonly)
Returns the value of attribute ttf.
16 17 18 |
# File 'lib/prawn/font/ttf.rb', line 16 def ttf @ttf end |
Instance Method Details
#basename ⇒ Object
106 107 108 |
# File 'lib/prawn/font/ttf.rb', line 106 def basename @basename ||= @ttf.name.postscript_name end |
#bbox ⇒ Object
The font bbox, as an array of integers
58 59 60 |
# File 'lib/prawn/font/ttf.rb', line 58 def bbox @bbox ||= @ttf.bbox.map { |i| Integer(i * scale_factor) } end |
#cap_height ⇒ Object
126 127 128 129 130 131 |
# File 'lib/prawn/font/ttf.rb', line 126 def cap_height @cap_height ||= begin height = @ttf.os2.exists? && @ttf.os2.cap_height || 0 height == 0 ? ascender : height end end |
#character_count(str) ⇒ Object
Returns the number of characters in str
(a UTF-8-encoded string).
195 196 197 198 199 200 201 |
# File 'lib/prawn/font/ttf.rb', line 195 def character_count(str) if str.respond_to?(:encode) str.length else str.unpack("U*").length end end |
#compute_width_of(string, options = {}) ⇒ Object
NOTE: string
must be UTF8-encoded.
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/prawn/font/ttf.rb', line 39 def compute_width_of(string, ={}) #:nodoc: scale = ([:size] || size) / 1000.0 if [:kerning] kern(string).inject(0) do |s,r| if r.is_a?(Numeric) s - r else r.inject(s) { |s2, u| s2 + character_width_by_code(u) } end end * scale else string.unpack("U*").inject(0) do |s,r| s + character_width_by_code(r) end * scale end end |
#encode_text(text, options = {}) ⇒ Object
Perform any changes to the string that need to happen before it is rendered to the canvas. Returns an array of subset “chunks”, where the even-numbered indices are the font subset number, and the following entry element is either a string or an array (for kerned text).
The text
parameter must be UTF8-encoded.
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/prawn/font/ttf.rb', line 75 def encode_text(text,={}) text = text.chomp if [:kerning] last_subset = nil kern(text).inject([]) do |result, element| if element.is_a?(Numeric) result.last[1] = [result.last[1]] unless result.last[1].is_a?(Array) result.last[1] << element result else encoded = @subsets.encode(element) if encoded.first[0] == last_subset result.last[1] << encoded.first[1] encoded.shift end if encoded.any? last_subset = encoded.last[0] result + encoded else result end end end else @subsets.encode(text.unpack("U*")) end end |
#family_class ⇒ Object
139 140 141 |
# File 'lib/prawn/font/ttf.rb', line 139 def family_class @family_class ||= (@ttf.os2.exists? && @ttf.os2.family_class || 0) >> 8 end |
#glyph_present?(char) ⇒ Boolean
188 189 190 191 |
# File 'lib/prawn/font/ttf.rb', line 188 def glyph_present?(char) code = char.unpack("U*").first cmap[code] > 0 end |
#has_kerning_data? ⇒ Boolean
Returns true if the font has kerning data, false otherwise
63 64 65 |
# File 'lib/prawn/font/ttf.rb', line 63 def has_kerning_data? @has_kerning_data end |
#italic_angle ⇒ Object
115 116 117 118 119 120 121 122 123 124 |
# File 'lib/prawn/font/ttf.rb', line 115 def italic_angle @italic_angle ||= if @ttf.postscript.exists? raw = @ttf.postscript.italic_angle hi, low = raw >> 16, raw & 0xFF hi = -((hi ^ 0xFFFF) + 1) if hi & 0x8000 != 0 "#{hi}.#{low}".to_f else 0 end end |
#normalize_encoding(text) ⇒ Object
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/prawn/font/ttf.rb', line 162 def normalize_encoding(text) if text.respond_to?(:encode) # if we're running under a M17n aware VM, ensure the string provided is # UTF-8 (by converting it if necessary) begin text.encode("UTF-8") rescue raise Prawn::Errors::IncompatibleStringEncoding, "Encoding " + "#{text.encoding} can not be transparently converted to UTF-8. " + "Please ensure the encoding of the string you are attempting " + "to use is set correctly" end else # on a non M17N aware VM, use unpack as a hackish way to verify the # string is valid utf-8. I thought it was better than loading iconv # though. begin text.unpack("U*") return text.dup rescue raise Prawn::Errors::IncompatibleStringEncoding, "The string you " + "are attempting to render is not encoded in valid UTF-8." end end end |
#pdf_flags ⇒ Object
151 152 153 154 155 156 157 158 159 160 |
# File 'lib/prawn/font/ttf.rb', line 151 def pdf_flags @flags ||= begin flags = 0 flags |= 0x0001 if @ttf.postscript.fixed_pitch? flags |= 0x0002 if serif? flags |= 0x0008 if script? flags |= 0x0040 if italic_angle != 0 flags |= 0x0004 # assume the font contains at least some non-latin characters end end |
#script? ⇒ Boolean
147 148 149 |
# File 'lib/prawn/font/ttf.rb', line 147 def script? @script ||= family_class == 10 end |
#serif? ⇒ Boolean
143 144 145 |
# File 'lib/prawn/font/ttf.rb', line 143 def serif? @serif ||= [1,2,3,4,5,7].include?(family_class) end |
#stemV ⇒ Object
not sure how to compute this for true-type fonts…
111 112 113 |
# File 'lib/prawn/font/ttf.rb', line 111 def stemV 0 end |
#unicode? ⇒ Boolean
18 19 20 |
# File 'lib/prawn/font/ttf.rb', line 18 def unicode? true end |
#x_height ⇒ Object
133 134 135 136 137 |
# File 'lib/prawn/font/ttf.rb', line 133 def x_height # FIXME: seems like if os2 table doesn't exist, we could # just find the height of the lower-case 'x' glyph? @ttf.os2.exists? && @ttf.os2.x_height || 0 end |