prawn 0.4.1 → 0.5.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. data/lib/prawn.rb +2 -72
  2. metadata +33 -224
  3. data/COPYING +0 -340
  4. data/LICENSE +0 -56
  5. data/README +0 -40
  6. data/Rakefile +0 -79
  7. data/data/encodings/win_ansi.txt +0 -29
  8. data/data/fonts/Action Man.dfont +0 -0
  9. data/data/fonts/Activa.ttf +0 -0
  10. data/data/fonts/Chalkboard.ttf +0 -0
  11. data/data/fonts/Courier-Bold.afm +0 -342
  12. data/data/fonts/Courier-BoldOblique.afm +0 -342
  13. data/data/fonts/Courier-Oblique.afm +0 -342
  14. data/data/fonts/Courier.afm +0 -342
  15. data/data/fonts/DejaVuSans.ttf +0 -0
  16. data/data/fonts/Dustismo_Roman.ttf +0 -0
  17. data/data/fonts/Helvetica-Bold.afm +0 -2827
  18. data/data/fonts/Helvetica-BoldOblique.afm +0 -2827
  19. data/data/fonts/Helvetica-Oblique.afm +0 -3051
  20. data/data/fonts/Helvetica.afm +0 -3051
  21. data/data/fonts/MustRead.html +0 -19
  22. data/data/fonts/Symbol.afm +0 -213
  23. data/data/fonts/Times-Bold.afm +0 -2588
  24. data/data/fonts/Times-BoldItalic.afm +0 -2384
  25. data/data/fonts/Times-Italic.afm +0 -2667
  26. data/data/fonts/Times-Roman.afm +0 -2419
  27. data/data/fonts/ZapfDingbats.afm +0 -225
  28. data/data/fonts/comicsans.ttf +0 -0
  29. data/data/fonts/gkai00mp.ttf +0 -0
  30. data/data/images/arrow.png +0 -0
  31. data/data/images/arrow2.png +0 -0
  32. data/data/images/barcode_issue.png +0 -0
  33. data/data/images/dice.alpha +0 -0
  34. data/data/images/dice.dat +0 -0
  35. data/data/images/dice.png +0 -0
  36. data/data/images/fractal.jpg +0 -0
  37. data/data/images/letterhead.jpg +0 -0
  38. data/data/images/page_white_text.alpha +0 -0
  39. data/data/images/page_white_text.dat +0 -0
  40. data/data/images/page_white_text.png +0 -0
  41. data/data/images/pigs.jpg +0 -0
  42. data/data/images/rails.dat +0 -0
  43. data/data/images/rails.png +0 -0
  44. data/data/images/ruport.png +0 -0
  45. data/data/images/ruport_data.dat +0 -0
  46. data/data/images/ruport_transparent.png +0 -0
  47. data/data/images/ruport_type0.png +0 -0
  48. data/data/images/stef.jpg +0 -0
  49. data/data/images/web-links.dat +0 -1
  50. data/data/images/web-links.png +0 -0
  51. data/data/shift_jis_text.txt +0 -1
  52. data/examples/bounding_box/bounding_boxes.rb +0 -44
  53. data/examples/bounding_box/lazy_bounding_boxes.rb +0 -28
  54. data/examples/bounding_box/padded_box.rb +0 -24
  55. data/examples/bounding_box/russian_boxes.rb +0 -37
  56. data/examples/general/background.rb +0 -20
  57. data/examples/general/canvas.rb +0 -16
  58. data/examples/general/measurement_units.rb +0 -52
  59. data/examples/general/multi_page_layout.rb +0 -17
  60. data/examples/general/page_geometry.rb +0 -32
  61. data/examples/graphics/basic_images.rb +0 -27
  62. data/examples/graphics/cmyk.rb +0 -13
  63. data/examples/graphics/curves.rb +0 -12
  64. data/examples/graphics/hexagon.rb +0 -14
  65. data/examples/graphics/image_fit.rb +0 -16
  66. data/examples/graphics/image_flow.rb +0 -38
  67. data/examples/graphics/image_position.rb +0 -18
  68. data/examples/graphics/line.rb +0 -33
  69. data/examples/graphics/png_types.rb +0 -23
  70. data/examples/graphics/polygons.rb +0 -17
  71. data/examples/graphics/remote_images.rb +0 -12
  72. data/examples/graphics/ruport_style_helpers.rb +0 -20
  73. data/examples/graphics/stroke_bounds.rb +0 -23
  74. data/examples/m17n/chinese_text_wrapping.rb +0 -20
  75. data/examples/m17n/euro.rb +0 -16
  76. data/examples/m17n/sjis.rb +0 -29
  77. data/examples/m17n/utf8.rb +0 -14
  78. data/examples/m17n/win_ansi_charset.rb +0 -55
  79. data/examples/text/alignment.rb +0 -19
  80. data/examples/text/dfont.rb +0 -49
  81. data/examples/text/family_based_styling.rb +0 -25
  82. data/examples/text/flowing_text_with_header_and_footer.rb +0 -37
  83. data/examples/text/font_calculations.rb +0 -92
  84. data/examples/text/font_size.rb +0 -34
  85. data/examples/text/kerning.rb +0 -31
  86. data/examples/text/simple_text.rb +0 -18
  87. data/examples/text/simple_text_ttf.rb +0 -18
  88. data/examples/text/span.rb +0 -30
  89. data/examples/text/text_box.rb +0 -26
  90. data/examples/text/text_flow.rb +0 -68
  91. data/lib/prawn/compatibility.rb +0 -38
  92. data/lib/prawn/document.rb +0 -309
  93. data/lib/prawn/document/annotations.rb +0 -63
  94. data/lib/prawn/document/bounding_box.rb +0 -368
  95. data/lib/prawn/document/destinations.rb +0 -81
  96. data/lib/prawn/document/internals.rb +0 -126
  97. data/lib/prawn/document/page_geometry.rb +0 -79
  98. data/lib/prawn/document/span.rb +0 -55
  99. data/lib/prawn/document/text.rb +0 -185
  100. data/lib/prawn/document/text/box.rb +0 -76
  101. data/lib/prawn/document/text/wrapping.rb +0 -59
  102. data/lib/prawn/encoding.rb +0 -121
  103. data/lib/prawn/errors.rb +0 -40
  104. data/lib/prawn/font.rb +0 -277
  105. data/lib/prawn/font/afm.rb +0 -202
  106. data/lib/prawn/font/dfont.rb +0 -31
  107. data/lib/prawn/font/ttf.rb +0 -326
  108. data/lib/prawn/graphics.rb +0 -257
  109. data/lib/prawn/graphics/color.rb +0 -140
  110. data/lib/prawn/images.rb +0 -339
  111. data/lib/prawn/images/jpg.rb +0 -45
  112. data/lib/prawn/images/png.rb +0 -199
  113. data/lib/prawn/literal_string.rb +0 -14
  114. data/lib/prawn/measurement_extensions.rb +0 -46
  115. data/lib/prawn/measurements.rb +0 -71
  116. data/lib/prawn/name_tree.rb +0 -165
  117. data/lib/prawn/pdf_object.rb +0 -73
  118. data/lib/prawn/reference.rb +0 -59
  119. data/spec/annotations_spec.rb +0 -90
  120. data/spec/bounding_box_spec.rb +0 -141
  121. data/spec/destinations_spec.rb +0 -15
  122. data/spec/document_spec.rb +0 -193
  123. data/spec/font_spec.rb +0 -234
  124. data/spec/graphics_spec.rb +0 -209
  125. data/spec/images_spec.rb +0 -68
  126. data/spec/jpg_spec.rb +0 -25
  127. data/spec/measurement_units_spec.rb +0 -23
  128. data/spec/name_tree_spec.rb +0 -103
  129. data/spec/pdf_object_spec.rb +0 -112
  130. data/spec/png_spec.rb +0 -196
  131. data/spec/reference_spec.rb +0 -42
  132. data/spec/spec_helper.rb +0 -23
  133. data/spec/text_spec.rb +0 -178
  134. data/vendor/pdf-inspector/README +0 -18
  135. data/vendor/pdf-inspector/lib/pdf/inspector.rb +0 -25
  136. data/vendor/pdf-inspector/lib/pdf/inspector/graphics.rb +0 -80
  137. data/vendor/pdf-inspector/lib/pdf/inspector/page.rb +0 -16
  138. data/vendor/pdf-inspector/lib/pdf/inspector/text.rb +0 -31
  139. data/vendor/pdf-inspector/lib/pdf/inspector/xobject.rb +0 -19
  140. data/vendor/ttfunk/data/fonts/DejaVuSans.ttf +0 -0
  141. data/vendor/ttfunk/data/fonts/comicsans.ttf +0 -0
  142. data/vendor/ttfunk/example.rb +0 -45
  143. data/vendor/ttfunk/lib/ttfunk.rb +0 -102
  144. data/vendor/ttfunk/lib/ttfunk/directory.rb +0 -17
  145. data/vendor/ttfunk/lib/ttfunk/encoding/mac_roman.rb +0 -88
  146. data/vendor/ttfunk/lib/ttfunk/encoding/windows_1252.rb +0 -69
  147. data/vendor/ttfunk/lib/ttfunk/reader.rb +0 -44
  148. data/vendor/ttfunk/lib/ttfunk/resource_file.rb +0 -78
  149. data/vendor/ttfunk/lib/ttfunk/subset.rb +0 -18
  150. data/vendor/ttfunk/lib/ttfunk/subset/base.rb +0 -141
  151. data/vendor/ttfunk/lib/ttfunk/subset/mac_roman.rb +0 -46
  152. data/vendor/ttfunk/lib/ttfunk/subset/unicode.rb +0 -48
  153. data/vendor/ttfunk/lib/ttfunk/subset/unicode_8bit.rb +0 -63
  154. data/vendor/ttfunk/lib/ttfunk/subset/windows_1252.rb +0 -51
  155. data/vendor/ttfunk/lib/ttfunk/subset_collection.rb +0 -72
  156. data/vendor/ttfunk/lib/ttfunk/table.rb +0 -46
  157. data/vendor/ttfunk/lib/ttfunk/table/cmap.rb +0 -34
  158. data/vendor/ttfunk/lib/ttfunk/table/cmap/format00.rb +0 -54
  159. data/vendor/ttfunk/lib/ttfunk/table/cmap/format04.rb +0 -126
  160. data/vendor/ttfunk/lib/ttfunk/table/cmap/subtable.rb +0 -79
  161. data/vendor/ttfunk/lib/ttfunk/table/glyf.rb +0 -64
  162. data/vendor/ttfunk/lib/ttfunk/table/glyf/compound.rb +0 -81
  163. data/vendor/ttfunk/lib/ttfunk/table/glyf/simple.rb +0 -37
  164. data/vendor/ttfunk/lib/ttfunk/table/head.rb +0 -44
  165. data/vendor/ttfunk/lib/ttfunk/table/hhea.rb +0 -41
  166. data/vendor/ttfunk/lib/ttfunk/table/hmtx.rb +0 -47
  167. data/vendor/ttfunk/lib/ttfunk/table/kern.rb +0 -79
  168. data/vendor/ttfunk/lib/ttfunk/table/kern/format0.rb +0 -62
  169. data/vendor/ttfunk/lib/ttfunk/table/loca.rb +0 -43
  170. data/vendor/ttfunk/lib/ttfunk/table/maxp.rb +0 -40
  171. data/vendor/ttfunk/lib/ttfunk/table/name.rb +0 -119
  172. data/vendor/ttfunk/lib/ttfunk/table/os2.rb +0 -78
  173. data/vendor/ttfunk/lib/ttfunk/table/post.rb +0 -91
  174. data/vendor/ttfunk/lib/ttfunk/table/post/format10.rb +0 -43
  175. data/vendor/ttfunk/lib/ttfunk/table/post/format20.rb +0 -35
  176. data/vendor/ttfunk/lib/ttfunk/table/post/format25.rb +0 -23
  177. data/vendor/ttfunk/lib/ttfunk/table/post/format30.rb +0 -17
  178. data/vendor/ttfunk/lib/ttfunk/table/post/format40.rb +0 -17
  179. data/vendor/ttfunk/lib/ttfunk/table/simple.rb +0 -14
@@ -1,121 +0,0 @@
1
- # encoding: utf-8
2
- #
3
- # Copyright September 2008, Gregory Brown, James Healy All Rights Reserved.
4
- #
5
- # This is free software. Please see the LICENSE and COPYING files for details.
6
- #
7
- module Prawn
8
- module Encoding
9
- # Map between unicode and WinAnsiEnoding
10
- #
11
- class WinAnsi #:nodoc:
12
- CHARACTERS = %w[
13
- .notdef .notdef .notdef .notdef
14
- .notdef .notdef .notdef .notdef
15
- .notdef .notdef .notdef .notdef
16
- .notdef .notdef .notdef .notdef
17
- .notdef .notdef .notdef .notdef
18
- .notdef .notdef .notdef .notdef
19
- .notdef .notdef .notdef .notdef
20
- .notdef .notdef .notdef .notdef
21
-
22
- space exclam quotedbl numbersign
23
- dollar percent ampersand quotesingle
24
- parenleft parenright asterisk plus
25
- comma hyphen period slash
26
- zero one two three
27
- four five six seven
28
- eight nine colon semicolon
29
- less equal greater question
30
-
31
- at A B C
32
- D E F G
33
- H I J K
34
- L M N O
35
- P Q R S
36
- T U V W
37
- X Y Z bracketleft
38
- backslash bracketright asciicircum underscore
39
-
40
- grave a b c
41
- d e f g
42
- h i j k
43
- l m n o
44
- p q r s
45
- t u v w
46
- x y z braceleft
47
- bar braceright asciitilde .notdef
48
-
49
- Euro .notdef quotesinglbase florin
50
- quotedblbase ellipsis dagger daggerdbl
51
- circumflex perthousand Scaron guilsinglleft
52
- OE .notdef Zcaron .notdef
53
- .notdef quoteleft quoteright quotedblleft
54
- quotedblright bullet endash emdash
55
- tilde trademark scaron guilsinglright
56
- oe .notdef zcaron ydieresis
57
-
58
- space exclamdown cent sterling
59
- currency yen brokenbar section
60
- dieresis copyright ordfeminine guillemotleft
61
- logicalnot hyphen registered macron
62
- degree plusminus twosuperior threesuperior
63
- acute mu paragraph periodcentered
64
- cedilla onesuperior ordmasculine guillemotright
65
- onequarter onehalf threequarters questiondown
66
-
67
- Agrave Aacute Acircumflex Atilde
68
- Adieresis Aring AE Ccedilla
69
- Egrave Eacute Ecircumflex Edieresis
70
- Igrave Iacute Icircumflex Idieresis
71
- Eth Ntilde Ograve Oacute
72
- Ocircumflex Otilde Odieresis multiply
73
- Oslash Ugrave Uacute Ucircumflex
74
- Udieresis Yacute Thorn germandbls
75
-
76
- agrave aacute acircumflex atilde
77
- adieresis aring ae ccedilla
78
- egrave eacute ecircumflex edieresis
79
- igrave iacute icircumflex idieresis
80
- eth ntilde ograve oacute
81
- ocircumflex otilde odieresis divide
82
- oslash ugrave uacute ucircumflex
83
- udieresis yacute thorn ydieresis
84
- ]
85
-
86
- def initialize
87
- @mapping_file = "#{Prawn::BASEDIR}/data/encodings/win_ansi.txt"
88
- load_mapping if self.class.mapping.empty?
89
- end
90
-
91
- # Converts a Unicode codepoint into a valid WinAnsi single byte character.
92
- #
93
- # If there is no WinAnsi equivlant for a character, a _ will be substituted.
94
- #
95
- def [](codepoint)
96
- # unicode codepoints < 255 map directly to the single byte value in WinAnsi
97
- return codepoint if codepoint <= 255
98
-
99
- # There are a handful of codepoints > 255 that have equivilants in WinAnsi.
100
- # Replace anything else with an underscore
101
- self.class.mapping[codepoint] || 95
102
- end
103
-
104
- def self.mapping
105
- @mapping ||= {}
106
- end
107
-
108
- private
109
-
110
- def load_mapping
111
- RUBY_VERSION >= "1.9" ? mode = "r:BINARY" : mode = "r"
112
- File.open(@mapping_file, mode) do |f|
113
- f.each do |l|
114
- m, single_byte, unicode = *l.match(/([0-9A-Za-z]+);([0-9A-F]{4})/)
115
- self.class.mapping["0x#{unicode}".hex] = "0x#{single_byte}".hex if single_byte
116
- end
117
- end
118
- end
119
- end
120
- end
121
- end
data/lib/prawn/errors.rb DELETED
@@ -1,40 +0,0 @@
1
- # encoding: utf-8
2
-
3
- # errors.rb : Implements custom error classes for Prawn
4
- #
5
- # Copyright April 2008, Gregory Brown. All Rights Reserved.
6
- #
7
- # This is free software. Please see the LICENSE and COPYING files for details.
8
-
9
- module Prawn
10
- module Errors
11
-
12
- # This error is raised when Prawn::PdfObject() encounters a Ruby object it
13
- # cannot convert to PDF
14
- #
15
- class FailedObjectConversion < StandardError; end
16
-
17
- # This error is raised when Document#page_layout is set to anything
18
- # other than :portrait or :landscape
19
- #
20
- class InvalidPageLayout < StandardError; end
21
-
22
- # This error is raised when Prawn cannot find a specified font
23
- #
24
- class UnknownFont < StandardError; end
25
-
26
- # This error is raised when Prawn is being used on a M17N aware VM,
27
- # and the user attempts to add text that isn't compatible with UTF-8
28
- # to their document
29
- #
30
- class IncompatibleStringEncoding < StandardError; end
31
-
32
- # This error is raised when Prawn encounters an unknown key in functions
33
- # that accept an options hash. This usually means there is a typo in your
34
- # code or that the option you are trying to use has a different name than
35
- # what you have specified.
36
- #
37
- class UnknownOption < StandardError; end
38
-
39
- end
40
- end
data/lib/prawn/font.rb DELETED
@@ -1,277 +0,0 @@
1
- # encoding: utf-8
2
- #
3
- # font.rb : The Prawn font class
4
- #
5
- # Copyright May 2008, Gregory Brown / James Healy. All Rights Reserved.
6
- #
7
- # This is free software. Please see the LICENSE and COPYING files for details.
8
- require "prawn/font/afm"
9
- require "prawn/font/ttf"
10
- require "prawn/font/dfont"
11
-
12
- module Prawn
13
-
14
- class Document
15
- # Without arguments, this returns the currently selected font. Otherwise,
16
- # it sets the current font.
17
- #
18
- # The single parameter must be a string. It can be one of the 14 built-in
19
- # fonts supported by PDF, or the location of a TTF file. The Font::AFM::BUILT_INS
20
- # array specifies the valid built in font values.
21
- #
22
- # pdf.font "Times-Roman"
23
- # pdf.font "Chalkboard.ttf"
24
- #
25
- # If a ttf font is specified, the glyphs necessary to render your document
26
- # will be embedded in the rendered PDF. This should be your preferred option
27
- # in most cases. It will increase the size of the resulting file, but also
28
- # make it more portable.
29
- #
30
- def font(name=nil, options={})
31
- return @font || font("Helvetica") if name.nil?
32
-
33
- new_font = find_font(name, options)
34
-
35
- if block_given?
36
- save_font do
37
- set_font(new_font, options[:size])
38
- yield
39
- end
40
- else
41
- set_font(new_font, options[:size])
42
- end
43
-
44
- @font
45
- end
46
-
47
- # When called with no argument, returns the current font size.
48
- # When called with a single argument but no block, sets the current font
49
- # size. When a block is used, the font size is applied transactionally and
50
- # is rolled back when the block exits. You may still change the font size
51
- # within a transactional block for individual text segments, or nested calls
52
- # to font_size.
53
- #
54
- # Prawn::Document.generate("font_size.pdf") do
55
- # font_size 16
56
- # text "At size 16"
57
- #
58
- # font_size(10) do
59
- # text "At size 10"
60
- # text "At size 6", :size => 6
61
- # text "At size 10"
62
- # end
63
- #
64
- # text "At size 16"
65
- # end
66
- #
67
- # When called without an argument, this method returns the current font
68
- # size.
69
- #
70
- def font_size(points=nil)
71
- return @font_size unless points
72
- size_before_yield = @font_size
73
- @font_size = points
74
- block_given? ? yield : return
75
- @font_size = size_before_yield
76
- end
77
-
78
- # Sets the font directly, given an actual Font object
79
- # and size.
80
- def set_font(font, size=nil) # :nodoc:
81
- @font = font
82
- @font_size = size if size
83
- end
84
-
85
- # Saves the current font, and then yields. When the block
86
- # finishes, the original font is restored.
87
- def save_font
88
- @font ||= find_font("Helvetica")
89
- original_font = @font
90
- original_size = @font_size
91
-
92
- yield
93
- ensure
94
- set_font(original_font, original_size) if original_font
95
- end
96
-
97
- # Looks up the given font using the given criteria. Once a font has been
98
- # found by that matches the criteria, it will be cached to subsequent lookups
99
- # for that font will return the same object.
100
- #--
101
- # Challenges involved: the name alone is not sufficient to uniquely identify
102
- # a font (think dfont suitcases that can hold multiple different fonts in a
103
- # single file). Thus, the :name key is included in the cache key.
104
- #
105
- # It is further complicated, however, since fonts in some formats (like the
106
- # dfont suitcases) can be identified either by numeric index, OR by their
107
- # name within the suitcase, and both should hash to the same font object
108
- # (to avoid the font being embedded multiple times). This is not yet implemented,
109
- # which means if someone selects a font both by name, and by index, the
110
- # font will be embedded twice. Since we do font subsetting, this double
111
- # embedding won't be catastrophic, just annoying.
112
- # ++
113
- #
114
- def find_font(name, options={}) #:nodoc:
115
- if font_families.key?(name)
116
- family, name = name, font_families[name][options[:style] || :normal]
117
-
118
- if name.is_a?(Hash)
119
- options = options.merge(name)
120
- name = options[:file]
121
- end
122
- end
123
-
124
- key = "#{name}:#{options[:font] || 0}"
125
- font_registry[key] ||= Font.load(self, name, options.merge(:family => family))
126
- end
127
-
128
- # Hash of Font objects keyed by names
129
- #
130
- def font_registry #:nodoc:
131
- @font_registry ||= {}
132
- end
133
-
134
- # Hash that maps font family names to their styled individual font names
135
- #
136
- # To add support for another font family, append to this hash, e.g:
137
- #
138
- # pdf.font_families.update(
139
- # "MyTrueTypeFamily" => { :bold => "foo-bold.ttf",
140
- # :italic => "foo-italic.ttf",
141
- # :bold_italic => "foo-bold-italic.ttf",
142
- # :normal => "foo.ttf" })
143
- #
144
- # This will then allow you to use the fonts like so:
145
- #
146
- # pdf.font("MyTrueTypeFamily", :style => :bold)
147
- # pdf.text "Some bold text"
148
- # pdf.font("MyTrueTypeFamily")
149
- # pdf.text "Some normal text"
150
- #
151
- # This assumes that you have appropriate TTF fonts for each style you
152
- # wish to support.
153
- #
154
- def font_families
155
- @font_families ||= Hash.new { |h,k| h[k] = {} }.merge!(
156
- { "Courier" => { :bold => "Courier-Bold",
157
- :italic => "Courier-Oblique",
158
- :bold_italic => "Courier-BoldOblique",
159
- :normal => "Courier" },
160
-
161
- "Times-Roman" => { :bold => "Times-Bold",
162
- :italic => "Times-Italic",
163
- :bold_italic => "Times-BoldItalic",
164
- :normal => "Times-Roman" },
165
-
166
- "Helvetica" => { :bold => "Helvetica-Bold",
167
- :italic => "Helvetica-Oblique",
168
- :bold_italic => "Helvetica-BoldOblique",
169
- :normal => "Helvetica" }
170
- })
171
- end
172
- end
173
-
174
- # Provides font information and helper functions.
175
- #
176
- class Font
177
-
178
- # The current font name
179
- attr_reader :name
180
-
181
- # The current font family
182
- attr_reader :family
183
-
184
- # The options hash used to initialize the font
185
- attr_reader :options
186
-
187
- def self.load(document,name,options={})
188
- case name
189
- when /\.ttf$/ then TTF.new(document, name, options)
190
- when /\.dfont$/ then DFont.new(document, name, options)
191
- when /\.afm$/ then AFM.new(document, name, options)
192
- else AFM.new(document, name, options)
193
- end
194
- end
195
-
196
- def initialize(document,name,options={}) #:nodoc:
197
- @document = document
198
- @name = name
199
- @options = options
200
-
201
- @family = options[:family]
202
-
203
- @document.proc_set :PDF, :Text
204
- @identifier = :"F#{@document.font_registry.size + 1}"
205
-
206
- @references = {}
207
- end
208
-
209
- def ascender
210
- @ascender / 1000.0 * size
211
- end
212
-
213
- def descender
214
- @descender / 1000.0 * size
215
- end
216
-
217
- def line_gap
218
- @line_gap / 1000.0 * size
219
- end
220
-
221
- def identifier_for(subset)
222
- "#{@identifier}.#{subset}"
223
- end
224
-
225
- def inspect
226
- "#{self.class.name}< #{name}: #{size} >"
227
- end
228
-
229
- # Returns the width of the given string using the given font. If :size is not
230
- # specified as one of the options, the string is measured using the current
231
- # font size. You can also pass :kerning as an option to indicate whether
232
- # kerning should be used when measuring the width (defaults to +false+).
233
- #
234
- # Note that the string _must_ be encoded properly for the font being used.
235
- # For AFM fonts, this is WinAnsi. For TTF, make sure the font is encoded as
236
- # UTF-8. You can use the #normalize_encoding method to make sure strings
237
- # are in an encoding appropriate for the font.
238
- def width_of(string, options={})
239
- raise NotImplementedError, "subclasses of Prawn::Font must implement #width_of"
240
- end
241
-
242
- # Normalizes the encoding of the string to an encoding supported by the font.
243
- # The string is expected to be UTF-8 going in, and will be reencoded in-place
244
- # (the argument will be modified directly). The return value is not defined.
245
- def normalize_encoding(string)
246
- raise NotImplementedError, "subclasses of Prawn::Font must implement #normalize_encoding"
247
- end
248
-
249
- def height_at(size)
250
- @normalized_height ||= (@ascender - @descender + @line_gap) / 1000.0
251
- @normalized_height * size
252
- end
253
-
254
- # Gets height of current font in PDF points at current font size
255
- #
256
- def height
257
- height_at(size)
258
- end
259
-
260
- # Registers the given subset of the current font with the current PDF
261
- # page. This is safe to call multiple times for a given font and subset,
262
- # as it will only add the font the first time it is called.
263
- #
264
- def add_to_current_page(subset)
265
- @references[subset] ||= register(subset)
266
- @document.page_fonts.merge!(identifier_for(subset) => @references[subset])
267
- end
268
-
269
- private
270
-
271
- def size
272
- @document.font_size
273
- end
274
-
275
- end
276
-
277
- end
@@ -1,202 +0,0 @@
1
- require 'prawn/encoding'
2
-
3
- module Prawn
4
- class Font
5
- class AFM < Font
6
- BUILT_INS = %w[ Courier Helvetica Times-Roman Symbol ZapfDingbats
7
- Courier-Bold Courier-Oblique Courier-BoldOblique
8
- Times-Bold Times-Italic Times-BoldItalic
9
- Helvetica-Bold Helvetica-Oblique Helvetica-BoldOblique ]
10
-
11
- def self.metrics_path
12
- if m = ENV['METRICS']
13
- @metrics_path ||= m.split(':')
14
- else
15
- @metrics_path ||= [
16
- ".", "/usr/lib/afm",
17
- "/usr/local/lib/afm",
18
- "/usr/openwin/lib/fonts/afm/",
19
- Prawn::BASEDIR+'/data/fonts/']
20
- end
21
- end
22
-
23
- attr_reader :attributes
24
-
25
- def initialize(document, name, options={})
26
- unless BUILT_INS.include?(name)
27
- raise Prawn::Errors::UnknownFont, "#{name} is not a known font."
28
- end
29
-
30
- super
31
-
32
- @attributes = {}
33
- @glyph_widths = {}
34
- @bounding_boxes = {}
35
- @kern_pairs = {}
36
-
37
- file_name = @name.dup
38
- file_name << ".afm" unless file_name =~ /\.afm$/
39
- file_name = file_name[0] == ?/ ? file_name : find_font(file_name)
40
-
41
- parse_afm(file_name)
42
-
43
- @ascender = @attributes["ascender"].to_i
44
- @descender = @attributes["descender"].to_i
45
- @line_gap = Float(bbox[3] - bbox[1]) - (@ascender - @descender)
46
- end
47
-
48
- def bbox
49
- @bbox ||= @attributes['fontbbox'].split(/\s+/).map { |e| Integer(e) }
50
- end
51
-
52
- # calculates the width of the supplied string.
53
- #
54
- # String *must* be encoded as WinAnsi
55
- #
56
- def width_of(string, options={})
57
- scale = (options[:size] || size) / 1000.0
58
-
59
- if options[:kerning]
60
- strings, numbers = kern(string).partition { |e| e.is_a?(String) }
61
- total_kerning_offset = numbers.inject(0.0) { |s,r| s + r }
62
- (unscaled_width_of(strings.join) - total_kerning_offset) * scale
63
- else
64
- unscaled_width_of(string) * scale
65
- end
66
- end
67
-
68
- def has_kerning_data?
69
- @kern_pairs.any?
70
- end
71
-
72
- # built-in fonts only work with winansi encoding, so translate the
73
- # string. Changes the encoding in-place, so the argument itself
74
- # is replaced with a string in WinAnsi encoding.
75
- def normalize_encoding(text)
76
- enc = Prawn::Encoding::WinAnsi.new
77
- text.replace text.unpack("U*").collect { |i| enc[i] }.pack("C*")
78
- end
79
-
80
- # Perform any changes to the string that need to happen
81
- # before it is rendered to the canvas. Returns an array of
82
- # subset "chunks", where each chunk is an array of two elements.
83
- # The first element is the font subset number, and the second
84
- # is either a string or an array (for kerned text).
85
- #
86
- # For Adobe fonts, there is only ever a single subset, so
87
- # the first element of the array is "0", and the second is
88
- # the string itself (or an array, if kerning is performed).
89
- #
90
- # The +text+ parameter must be in WinAnsi encoding (cp1252).
91
- def encode_text(text, options={})
92
- [[0, options[:kerning] ? kern(text) : text]]
93
- end
94
-
95
- private
96
-
97
- def register(subset)
98
- @document.ref(:Type => :Font,
99
- :Subtype => :Type1,
100
- :BaseFont => name.to_sym,
101
- :Encoding => :WinAnsiEncoding)
102
- end
103
-
104
- def find_font(file)
105
- self.class.metrics_path.find { |f| File.exist? "#{f}/#{file}" } + "/#{file}"
106
- rescue NoMethodError
107
- raise Prawn::Errors::UnknownFont,
108
- "Couldn't find the font: #{file} in any of:\n" +
109
- self.class.metrics_path.join("\n")
110
- end
111
-
112
- def parse_afm(file_name)
113
- section = []
114
-
115
- File.foreach(file_name) do |line|
116
- case line
117
- when /^Start(\w+)/
118
- section.push $1
119
- next
120
- when /^End(\w+)/
121
- section.pop
122
- next
123
- end
124
-
125
- case section
126
- when ["FontMetrics", "CharMetrics"]
127
- next unless line =~ /^CH?\s/
128
-
129
- name = line[/\bN\s+(\.?\w+)\s*;/, 1]
130
- @glyph_widths[name] = line[/\bWX\s+(\d+)\s*;/, 1].to_i
131
- @bounding_boxes[name] = line[/\bB\s+([^;]+);/, 1].to_s.rstrip
132
- when ["FontMetrics", "KernData", "KernPairs"]
133
- next unless line =~ /^KPX\s+(\.?\w+)\s+(\.?\w+)\s+(-?\d+)/
134
- @kern_pairs[[$1, $2]] = $3.to_i
135
- when ["FontMetrics", "KernData", "TrackKern"],
136
- ["FontMetrics", "Composites"]
137
- next
138
- else
139
- parse_generic_afm_attribute(line)
140
- end
141
- end
142
- end
143
-
144
- def parse_generic_afm_attribute(line)
145
- line =~ /(^\w+)\s+(.*)/
146
- key, value = $1.to_s.downcase, $2
147
-
148
- @attributes[key] = @attributes[key] ?
149
- Array(@attributes[key]) << value : value
150
- end
151
-
152
- # converts a string into an array with spacing offsets
153
- # bewteen characters that need to be kerned
154
- #
155
- # String *must* be encoded as WinAnsi
156
- #
157
- def kern(string)
158
- kerned = [[]]
159
- last_byte = nil
160
-
161
- kern_pairs = latin_kern_pairs_table
162
-
163
- string.unpack("C*").each do |byte|
164
- if k = last_byte && kern_pairs[[last_byte, byte]]
165
- kerned << -k << [byte]
166
- else
167
- kerned.last << byte
168
- end
169
- last_byte = byte
170
- end
171
-
172
- kerned.map { |e|
173
- e = (Array === e ? e.pack("C*") : e)
174
- e.respond_to?(:force_encoding) ? e.force_encoding("Windows-1252") : e
175
- }
176
- end
177
-
178
- def latin_kern_pairs_table
179
- @kern_pairs_table ||= @kern_pairs.inject({}) do |h,p|
180
- h[p[0].map { |n| Encoding::WinAnsi::CHARACTERS.index(n) }] = p[1]
181
- h
182
- end
183
- end
184
-
185
- def latin_glyphs_table
186
- @glyphs_table ||= (0..255).map do |i|
187
- @glyph_widths[Encoding::WinAnsi::CHARACTERS[i]].to_i
188
- end
189
- end
190
-
191
- private
192
-
193
- def unscaled_width_of(string)
194
- glyph_table = latin_glyphs_table
195
-
196
- string.unpack("C*").inject(0) do |s,r|
197
- s + glyph_table[r]
198
- end
199
- end
200
- end
201
- end
202
- end