prawn-core 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 (186) hide show
  1. data/COPYING +340 -0
  2. data/LICENSE +56 -0
  3. data/README +121 -0
  4. data/Rakefile +74 -0
  5. data/data/encodings/win_ansi.txt +29 -0
  6. data/data/fonts/Action Man.dfont +0 -0
  7. data/data/fonts/Activa.ttf +0 -0
  8. data/data/fonts/Chalkboard.ttf +0 -0
  9. data/data/fonts/Courier-Bold.afm +342 -0
  10. data/data/fonts/Courier-BoldOblique.afm +342 -0
  11. data/data/fonts/Courier-Oblique.afm +342 -0
  12. data/data/fonts/Courier.afm +342 -0
  13. data/data/fonts/DejaVuSans.ttf +0 -0
  14. data/data/fonts/Dustismo_Roman.ttf +0 -0
  15. data/data/fonts/Helvetica-Bold.afm +2827 -0
  16. data/data/fonts/Helvetica-BoldOblique.afm +2827 -0
  17. data/data/fonts/Helvetica-Oblique.afm +3051 -0
  18. data/data/fonts/Helvetica.afm +3051 -0
  19. data/data/fonts/MustRead.html +19 -0
  20. data/data/fonts/Symbol.afm +213 -0
  21. data/data/fonts/Times-Bold.afm +2588 -0
  22. data/data/fonts/Times-BoldItalic.afm +2384 -0
  23. data/data/fonts/Times-Italic.afm +2667 -0
  24. data/data/fonts/Times-Roman.afm +2419 -0
  25. data/data/fonts/ZapfDingbats.afm +225 -0
  26. data/data/fonts/comicsans.ttf +0 -0
  27. data/data/fonts/gkai00mp.ttf +0 -0
  28. data/data/images/16bit.alpha +0 -0
  29. data/data/images/16bit.dat +0 -0
  30. data/data/images/16bit.png +0 -0
  31. data/data/images/arrow.png +0 -0
  32. data/data/images/arrow2.png +0 -0
  33. data/data/images/barcode_issue.png +0 -0
  34. data/data/images/dice.alpha +0 -0
  35. data/data/images/dice.dat +0 -0
  36. data/data/images/dice.png +0 -0
  37. data/data/images/dice_interlaced.png +0 -0
  38. data/data/images/fractal.jpg +0 -0
  39. data/data/images/letterhead.jpg +0 -0
  40. data/data/images/page_white_text.alpha +0 -0
  41. data/data/images/page_white_text.dat +0 -0
  42. data/data/images/page_white_text.png +0 -0
  43. data/data/images/pigs.jpg +0 -0
  44. data/data/images/rails.dat +0 -0
  45. data/data/images/rails.png +0 -0
  46. data/data/images/ruport.png +0 -0
  47. data/data/images/ruport_data.dat +0 -0
  48. data/data/images/ruport_transparent.png +0 -0
  49. data/data/images/ruport_type0.png +0 -0
  50. data/data/images/stef.jpg +0 -0
  51. data/data/images/tru256.bmp +0 -0
  52. data/data/images/web-links.dat +1 -0
  53. data/data/images/web-links.png +0 -0
  54. data/data/shift_jis_text.txt +1 -0
  55. data/examples/bounding_box/bounding_boxes.rb +44 -0
  56. data/examples/bounding_box/russian_boxes.rb +37 -0
  57. data/examples/column_box/column_box_example.rb +44 -0
  58. data/examples/general/background.rb +20 -0
  59. data/examples/general/canvas.rb +16 -0
  60. data/examples/general/measurement_units.rb +52 -0
  61. data/examples/general/metadata-info.rb +17 -0
  62. data/examples/general/multi_page_layout.rb +17 -0
  63. data/examples/general/page_geometry.rb +32 -0
  64. data/examples/graphics/basic_images.rb +24 -0
  65. data/examples/graphics/cmyk.rb +13 -0
  66. data/examples/graphics/curves.rb +12 -0
  67. data/examples/graphics/hexagon.rb +14 -0
  68. data/examples/graphics/image_fit.rb +16 -0
  69. data/examples/graphics/image_flow.rb +38 -0
  70. data/examples/graphics/image_position.rb +18 -0
  71. data/examples/graphics/line.rb +33 -0
  72. data/examples/graphics/png_types.rb +23 -0
  73. data/examples/graphics/polygons.rb +17 -0
  74. data/examples/graphics/remote_images.rb +12 -0
  75. data/examples/graphics/ruport_style_helpers.rb +20 -0
  76. data/examples/graphics/stroke_bounds.rb +21 -0
  77. data/examples/m17n/chinese_text_wrapping.rb +20 -0
  78. data/examples/m17n/euro.rb +16 -0
  79. data/examples/m17n/sjis.rb +29 -0
  80. data/examples/m17n/utf8.rb +14 -0
  81. data/examples/m17n/win_ansi_charset.rb +55 -0
  82. data/examples/text/alignment.rb +19 -0
  83. data/examples/text/dfont.rb +49 -0
  84. data/examples/text/family_based_styling.rb +25 -0
  85. data/examples/text/font_calculations.rb +92 -0
  86. data/examples/text/font_size.rb +34 -0
  87. data/examples/text/kerning.rb +31 -0
  88. data/examples/text/simple_text.rb +18 -0
  89. data/examples/text/simple_text_ttf.rb +18 -0
  90. data/examples/text/span.rb +30 -0
  91. data/examples/text/text_box.rb +26 -0
  92. data/examples/text/text_flow.rb +68 -0
  93. data/lib/prawn/compatibility.rb +38 -0
  94. data/lib/prawn/core.rb +79 -0
  95. data/lib/prawn/document.rb +399 -0
  96. data/lib/prawn/document/annotations.rb +63 -0
  97. data/lib/prawn/document/bounding_box.rb +377 -0
  98. data/lib/prawn/document/column_box.rb +89 -0
  99. data/lib/prawn/document/destinations.rb +81 -0
  100. data/lib/prawn/document/internals.rb +133 -0
  101. data/lib/prawn/document/page_geometry.rb +149 -0
  102. data/lib/prawn/document/span.rb +55 -0
  103. data/lib/prawn/document/text.rb +186 -0
  104. data/lib/prawn/document/text/box.rb +83 -0
  105. data/lib/prawn/document/text/wrapping.rb +59 -0
  106. data/lib/prawn/encoding.rb +121 -0
  107. data/lib/prawn/errors.rb +49 -0
  108. data/lib/prawn/font.rb +292 -0
  109. data/lib/prawn/font/afm.rb +202 -0
  110. data/lib/prawn/font/dfont.rb +31 -0
  111. data/lib/prawn/font/ttf.rb +327 -0
  112. data/lib/prawn/graphics.rb +257 -0
  113. data/lib/prawn/graphics/color.rb +141 -0
  114. data/lib/prawn/images.rb +339 -0
  115. data/lib/prawn/images/jpg.rb +45 -0
  116. data/lib/prawn/images/png.rb +217 -0
  117. data/lib/prawn/literal_string.rb +14 -0
  118. data/lib/prawn/measurement_extensions.rb +46 -0
  119. data/lib/prawn/measurements.rb +71 -0
  120. data/lib/prawn/name_tree.rb +165 -0
  121. data/lib/prawn/pdf_object.rb +77 -0
  122. data/lib/prawn/reference.rb +59 -0
  123. data/spec/annotations_spec.rb +90 -0
  124. data/spec/bounding_box_spec.rb +141 -0
  125. data/spec/destinations_spec.rb +15 -0
  126. data/spec/document_spec.rb +178 -0
  127. data/spec/font_spec.rb +274 -0
  128. data/spec/graphics_spec.rb +209 -0
  129. data/spec/images_spec.rb +79 -0
  130. data/spec/jpg_spec.rb +25 -0
  131. data/spec/measurement_units_spec.rb +23 -0
  132. data/spec/name_tree_spec.rb +103 -0
  133. data/spec/pdf_object_spec.rb +117 -0
  134. data/spec/png_spec.rb +236 -0
  135. data/spec/reference_spec.rb +42 -0
  136. data/spec/span_spec.rb +45 -0
  137. data/spec/spec_helper.rb +23 -0
  138. data/spec/text_box_spec.rb +83 -0
  139. data/spec/text_spec.rb +178 -0
  140. data/vendor/pdf-inspector/README +18 -0
  141. data/vendor/pdf-inspector/lib/pdf/inspector.rb +25 -0
  142. data/vendor/pdf-inspector/lib/pdf/inspector/graphics.rb +80 -0
  143. data/vendor/pdf-inspector/lib/pdf/inspector/page.rb +16 -0
  144. data/vendor/pdf-inspector/lib/pdf/inspector/text.rb +31 -0
  145. data/vendor/pdf-inspector/lib/pdf/inspector/xobject.rb +19 -0
  146. data/vendor/ttfunk/data/fonts/DejaVuSans.ttf +0 -0
  147. data/vendor/ttfunk/data/fonts/comicsans.ttf +0 -0
  148. data/vendor/ttfunk/example.rb +45 -0
  149. data/vendor/ttfunk/lib/ttfunk.rb +102 -0
  150. data/vendor/ttfunk/lib/ttfunk/directory.rb +17 -0
  151. data/vendor/ttfunk/lib/ttfunk/encoding/mac_roman.rb +88 -0
  152. data/vendor/ttfunk/lib/ttfunk/encoding/windows_1252.rb +69 -0
  153. data/vendor/ttfunk/lib/ttfunk/reader.rb +44 -0
  154. data/vendor/ttfunk/lib/ttfunk/resource_file.rb +78 -0
  155. data/vendor/ttfunk/lib/ttfunk/subset.rb +18 -0
  156. data/vendor/ttfunk/lib/ttfunk/subset/base.rb +141 -0
  157. data/vendor/ttfunk/lib/ttfunk/subset/mac_roman.rb +46 -0
  158. data/vendor/ttfunk/lib/ttfunk/subset/unicode.rb +48 -0
  159. data/vendor/ttfunk/lib/ttfunk/subset/unicode_8bit.rb +63 -0
  160. data/vendor/ttfunk/lib/ttfunk/subset/windows_1252.rb +51 -0
  161. data/vendor/ttfunk/lib/ttfunk/subset_collection.rb +72 -0
  162. data/vendor/ttfunk/lib/ttfunk/table.rb +46 -0
  163. data/vendor/ttfunk/lib/ttfunk/table/cmap.rb +34 -0
  164. data/vendor/ttfunk/lib/ttfunk/table/cmap/format00.rb +54 -0
  165. data/vendor/ttfunk/lib/ttfunk/table/cmap/format04.rb +126 -0
  166. data/vendor/ttfunk/lib/ttfunk/table/cmap/subtable.rb +79 -0
  167. data/vendor/ttfunk/lib/ttfunk/table/glyf.rb +64 -0
  168. data/vendor/ttfunk/lib/ttfunk/table/glyf/compound.rb +81 -0
  169. data/vendor/ttfunk/lib/ttfunk/table/glyf/simple.rb +37 -0
  170. data/vendor/ttfunk/lib/ttfunk/table/head.rb +44 -0
  171. data/vendor/ttfunk/lib/ttfunk/table/hhea.rb +41 -0
  172. data/vendor/ttfunk/lib/ttfunk/table/hmtx.rb +47 -0
  173. data/vendor/ttfunk/lib/ttfunk/table/kern.rb +79 -0
  174. data/vendor/ttfunk/lib/ttfunk/table/kern/format0.rb +62 -0
  175. data/vendor/ttfunk/lib/ttfunk/table/loca.rb +43 -0
  176. data/vendor/ttfunk/lib/ttfunk/table/maxp.rb +40 -0
  177. data/vendor/ttfunk/lib/ttfunk/table/name.rb +119 -0
  178. data/vendor/ttfunk/lib/ttfunk/table/os2.rb +78 -0
  179. data/vendor/ttfunk/lib/ttfunk/table/post.rb +91 -0
  180. data/vendor/ttfunk/lib/ttfunk/table/post/format10.rb +43 -0
  181. data/vendor/ttfunk/lib/ttfunk/table/post/format20.rb +35 -0
  182. data/vendor/ttfunk/lib/ttfunk/table/post/format25.rb +23 -0
  183. data/vendor/ttfunk/lib/ttfunk/table/post/format30.rb +17 -0
  184. data/vendor/ttfunk/lib/ttfunk/table/post/format40.rb +17 -0
  185. data/vendor/ttfunk/lib/ttfunk/table/simple.rb +14 -0
  186. metadata +245 -0
@@ -0,0 +1,81 @@
1
+ # encoding: utf-8
2
+
3
+ # annotations.rb : Implements destination support for PDF
4
+ #
5
+ # Copyright November 2008, Jamis Buck. All Rights Reserved.
6
+ #
7
+ # This is free software. Please see the LICENSE and COPYING files for details.
8
+ #
9
+ require 'prawn/name_tree'
10
+
11
+ module Prawn
12
+ class Document
13
+ module Destinations
14
+ # The maximum number of children to fit into a single node in the Dests tree.
15
+ NAME_TREE_CHILDREN_LIMIT = 20 #:nodoc:
16
+
17
+ # The Dests name tree in the Name dictionary (see Prawn::Document::Internal#names).
18
+ # This name tree is used to store named destinations (PDF spec 8.2.1).
19
+ # (For more on name trees, see section 3.8.4 in the PDF spec.)
20
+ def dests
21
+ names.data[:Dests] ||= ref(Prawn::NameTree::Node.new(self, NAME_TREE_CHILDREN_LIMIT))
22
+ end
23
+
24
+ # Adds a new destination to the dests name tree (see #dests). The
25
+ # +reference+ parameter will be converted into a Prawn::Reference if
26
+ # it is not already one.
27
+ def add_dest(name, reference)
28
+ reference = ref(reference) unless reference.is_a?(Prawn::Reference)
29
+ dests.data.add(name, reference)
30
+ end
31
+
32
+ # Return a Dest specification for a specific location (and optional zoom
33
+ # level).
34
+ def dest_xyz(left, top, zoom=nil, page=@current_page)
35
+ [page, :XYZ, left, top, zoom]
36
+ end
37
+
38
+ # Return a Dest specification that will fit the given page into the
39
+ # viewport.
40
+ def dest_fit(page=@current_page)
41
+ [page, :Fit]
42
+ end
43
+
44
+ # Return a Dest specification that will fit the given page horizontally
45
+ # into the viewport, aligned vertically at the given top coordinate.
46
+ def dest_fit_horizontally(top, page=@current_page)
47
+ [page, :FitH, top]
48
+ end
49
+
50
+ # Return a Dest specification that will fit the given page vertically
51
+ # into the viewport, aligned horizontally at the given left coordinate.
52
+ def dest_fit_vertically(left, page=@current_page)
53
+ [page, :FitV, left]
54
+ end
55
+
56
+ # Return a Dest specification that will fit the given rectangle into the
57
+ # viewport, for the given page.
58
+ def dest_fit_rect(left, bottom, right, top, page=@current_page)
59
+ [page, :FitR, left, bottom, right, top]
60
+ end
61
+
62
+ # Return a Dest specfication that will fit the given page's bounding box
63
+ # into the viewport.
64
+ def dest_fit_bounds(page=@current_page)
65
+ [page, :FitB]
66
+ end
67
+
68
+ # Same as #dest_fit_horizontally, but works on the page's bounding box
69
+ # instead of the entire page.
70
+ def dest_fit_bounds_horizontally(top, page=@current_page)
71
+ [page, :FitBH, top]
72
+ end
73
+
74
+ # Same as #dest_fit_vertically, but works on the page's bounding box
75
+ # instead of the entire page.
76
+ def dest_fit_bounds_vertically(left, page=@current_page)
77
+ [page, :FitBV, left]
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,133 @@
1
+ # encoding: utf-8
2
+ #
3
+ # internals.rb : Implements document internals for Prawn
4
+ #
5
+ # Copyright August 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
+ class Document
11
+
12
+ # This module exposes a few low-level PDF features for those who want
13
+ # to extend Prawn's core functionality. If you are not comfortable with
14
+ # low level PDF functionality as defined by Adobe's specification, chances
15
+ # are you won't need anything you find here.
16
+ #
17
+ module Internals
18
+ # Creates a new Prawn::Reference and adds it to the Document's object
19
+ # list. The +data+ argument is anything that Prawn::PdfObject() can convert.
20
+ #
21
+ # If a block is given, it will be invoked just before the object is written
22
+ # out to the PDF document stream. This allows you to do deferred processing
23
+ # on some references (such as fonts, which you might know all the details
24
+ # about until the last page of the document is finished).
25
+ def ref(data, &block)
26
+ @objects.push(Prawn::Reference.new(@objects.size + 1, data, &block)).last
27
+ end
28
+
29
+ # Appends a raw string to the current page content.
30
+ #
31
+ # # Raw line drawing example:
32
+ # x1,y1,x2,y2 = 100,500,300,550
33
+ # pdf.add_content("%.3f %.3f m" % [ x1, y1 ]) # move
34
+ # pdf.add_content("%.3f %.3f l" % [ x2, y2 ]) # draw path
35
+ # pdf.add_content("S") # stroke
36
+ #
37
+ def add_content(str)
38
+ @page_content << str << "\n"
39
+ end
40
+
41
+ # Add a new type to the current pages ProcSet
42
+ #
43
+ def proc_set(*types)
44
+ @current_page.data[:ProcSet] ||= ref([])
45
+ @current_page.data[:ProcSet].data |= types
46
+ end
47
+
48
+ # The Resources dictionary for the current page
49
+ #
50
+ def page_resources
51
+ @current_page.data[:Resources] ||= {}
52
+ end
53
+
54
+ # The Font dictionary for the current page
55
+ #
56
+ def page_fonts
57
+ page_resources[:Font] ||= {}
58
+ end
59
+
60
+ # The XObject dictionary for the current page
61
+ def page_xobjects
62
+ page_resources[:XObject] ||= {}
63
+ end
64
+
65
+ # The Name dictionary (PDF spec 3.6.3) for this document. It is
66
+ # lazily initialized, so that documents that do not need a name
67
+ # dictionary do not incur the additional overhead.
68
+ def names
69
+ @root.data[:Names] ||= ref(:Type => :Names)
70
+ end
71
+
72
+ private
73
+
74
+ def finish_page_content
75
+ @header.draw if @header
76
+ @footer.draw if @footer
77
+ add_content "Q"
78
+ @page_content.compress_stream if compression_enabled?
79
+ @page_content.data[:Length] = @page_content.stream.size
80
+ end
81
+
82
+ # raise the PDF version of the file we're going to generate.
83
+ # A private method, designed for internal use when the user adds a feature
84
+ # to their document that requires a particular version.
85
+ def min_version(min)
86
+ @version = min if min > @version
87
+ end
88
+
89
+ # Write out the PDF Header, as per spec 3.4.1
90
+ def render_header(output)
91
+ # pdf version
92
+ output << "%PDF-#{@version}\n"
93
+
94
+ # 4 binary chars, as recommended by the spec
95
+ output << "\xFF\xFF\xFF\xFF\n"
96
+ end
97
+
98
+ # Write out the PDF Body, as per spec 3.4.2
99
+ def render_body(output)
100
+ @objects.each do |ref|
101
+ ref.offset = output.size
102
+ output << ref.object
103
+ end
104
+ end
105
+
106
+ # Write out the PDF Cross Reference Table, as per spec 3.4.3
107
+ def render_xref(output)
108
+ @xref_offset = output.size
109
+ output << "xref\n"
110
+ output << "0 #{@objects.size + 1}\n"
111
+ output << "0000000000 65535 f \n"
112
+ @objects.each do |ref|
113
+ output.printf("%010d", ref.offset)
114
+ output << " 00000 n \n"
115
+ end
116
+ end
117
+
118
+ # Write out the PDF Trailer, as per spec 3.4.4
119
+ def render_trailer(output)
120
+ trailer_hash = {:Size => @objects.size + 1,
121
+ :Root => @root,
122
+ :Info => @info}
123
+
124
+ output << "trailer\n"
125
+ output << Prawn::PdfObject(trailer_hash) << "\n"
126
+ output << "startxref\n"
127
+ output << @xref_offset << "\n"
128
+ output << "%%EOF" << "\n"
129
+ end
130
+
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,149 @@
1
+ # encoding: utf-8
2
+
3
+ # page_geometry.rb : Describes PDF page geometries
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
+ class Document
11
+
12
+ # Dimensions pulled from PDF::Writer, rubyforge.org/projects/ruby-pdf
13
+ #
14
+ # All of these dimensions are in PDF Points, see Prawn::Measurements for
15
+ # conversion utilities.
16
+ #
17
+ # Additionally, if the size you are after is not listed below, you can always
18
+ # specify your size by passing an array of width and height to Prawn::Document.new
19
+ # like:
20
+ #
21
+ # Prawn::Document.new(:page_size => [1000, 20000])
22
+ #
23
+ # The sizes below can be used by passing the appropriate string to :size:
24
+ #
25
+ # Prawn::Document.new(:page_size => '2A0')
26
+ #
27
+ # ===Inbuilt Sizes:
28
+ #
29
+ #
30
+ # 4A0:: => 4767.87 x 6740.79
31
+ # 2A0:: => 3370.39 x 4767.87
32
+ # A0:: => 2383.94 x 3370.39
33
+ # A1:: => 1683.78 x 2383.94
34
+ # A2:: => 1190.55 x 1683.78
35
+ # A3:: => 841.89 x 1190.55
36
+ # A4:: => 595.28 x 841.89
37
+ # A5:: => 419.53 x 595.28
38
+ # A6:: => 297.64 x 419.53
39
+ # A7:: => 209.76 x 297.64
40
+ # A8:: => 147.40 x 209.76
41
+ # A9:: => 104.88 x 147.40
42
+ # A10:: => 73.70 x 104.88
43
+ # B0:: => 2834.65 x 4008.19
44
+ # B1:: => 2004.09 x 2834.65
45
+ # B2:: => 1417.32 x 2004.09
46
+ # B3:: => 1000.63 x 1417.32
47
+ # B4:: => 708.66 x 1000.63
48
+ # B5:: => 498.90 x 708.66
49
+ # B6:: => 354.33 x 498.90
50
+ # B7:: => 249.45 x 354.33
51
+ # B8:: => 175.75 x 249.45
52
+ # B9:: => 124.72 x 175.75
53
+ # B10:: => 87.87 x 124.72
54
+ # C0:: => 2599.37 x 3676.54
55
+ # C1:: => 1836.85 x 2599.37
56
+ # C2:: => 1298.27 x 1836.85
57
+ # C3:: => 918.43 x 1298.27
58
+ # C4:: => 649.13 x 918.43
59
+ # C5:: => 459.21 x 649.13
60
+ # C6:: => 323.15 x 459.21
61
+ # C7:: => 229.61 x 323.15
62
+ # C8:: => 161.57 x 229.61
63
+ # C9:: => 113.39 x 161.57
64
+ # C10:: => 79.37 x 113.39
65
+ # RA0:: => 2437.80 x 3458.27
66
+ # RA1:: => 1729.13 x 2437.80
67
+ # RA2:: => 1218.90 x 1729.13
68
+ # RA3:: => 864.57 x 1218.90
69
+ # RA4:: => 609.45 x 864.57
70
+ # SRA0:: => 2551.18 x 3628.35
71
+ # SRA1:: => 1814.17 x 2551.18
72
+ # SRA2:: => 1275.59 x 1814.17
73
+ # SRA3:: => 907.09 x 1275.59
74
+ # SRA4:: => 637.80 x 907.09
75
+ # EXECUTIVE:: => 521.86 x 756.00
76
+ # FOLIO:: => 612.00 x 936.00
77
+ # LEGAL:: => 612.00 x 1008.00
78
+ # LETTER:: => 612.00 x 792.00
79
+ # TABLOID:: => 792.00 x 1224.00
80
+
81
+
82
+ module PageGeometry
83
+
84
+ SIZES = { "4A0" => [4767.87, 6740.79],
85
+ "2A0" => [3370.39, 4767.87],
86
+ "A0" => [2383.94, 3370.39],
87
+ "A1" => [1683.78, 2383.94],
88
+ "A2" => [1190.55, 1683.78],
89
+ "A3" => [841.89, 1190.55],
90
+ "A4" => [595.28, 841.89],
91
+ "A5" => [419.53, 595.28],
92
+ "A6" => [297.64, 419.53],
93
+ "A7" => [209.76, 297.64],
94
+ "A8" => [147.40, 209.76],
95
+ "A9" => [104.88, 147.40],
96
+ "A10" => [73.70, 104.88],
97
+ "B0" => [2834.65, 4008.19],
98
+ "B1" => [2004.09, 2834.65],
99
+ "B2" => [1417.32, 2004.09],
100
+ "B3" => [1000.63, 1417.32],
101
+ "B4" => [708.66, 1000.63],
102
+ "B5" => [498.90, 708.66],
103
+ "B6" => [354.33, 498.90],
104
+ "B7" => [249.45, 354.33],
105
+ "B8" => [175.75, 249.45],
106
+ "B9" => [124.72, 175.75],
107
+ "B10" => [87.87, 124.72],
108
+ "C0" => [2599.37, 3676.54],
109
+ "C1" => [1836.85, 2599.37],
110
+ "C2" => [1298.27, 1836.85],
111
+ "C3" => [918.43, 1298.27],
112
+ "C4" => [649.13, 918.43],
113
+ "C5" => [459.21, 649.13],
114
+ "C6" => [323.15, 459.21],
115
+ "C7" => [229.61, 323.15],
116
+ "C8" => [161.57, 229.61],
117
+ "C9" => [113.39, 161.57],
118
+ "C10" => [79.37, 113.39],
119
+ "RA0" => [2437.80, 3458.27],
120
+ "RA1" => [1729.13, 2437.80],
121
+ "RA2" => [1218.90, 1729.13],
122
+ "RA3" => [864.57, 1218.90],
123
+ "RA4" => [609.45, 864.57],
124
+ "SRA0" => [2551.18, 3628.35],
125
+ "SRA1" => [1814.17, 2551.18],
126
+ "SRA2" => [1275.59, 1814.17],
127
+ "SRA3" => [907.09, 1275.59],
128
+ "SRA4" => [637.80, 907.09],
129
+ "EXECUTIVE" => [521.86, 756.00],
130
+ "FOLIO" => [612.00, 936.00],
131
+ "LEGAL" => [612.00, 1008.00],
132
+ "LETTER" => [612.00, 792.00],
133
+ "TABLOID" => [792.00, 1224.00] }
134
+
135
+ def page_dimensions #:nodoc:
136
+ coords = SIZES[page_size] || page_size
137
+ [0,0] + case(page_layout)
138
+ when :portrait
139
+ coords
140
+ when :landscape
141
+ coords.reverse
142
+ else
143
+ raise Prawn::Errors::InvalidPageLayout,
144
+ "Layout must be either :portrait or :landscape"
145
+ end
146
+ end
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,55 @@
1
+ # encoding: utf-8
2
+
3
+ # span.rb : Implements text columns
4
+ #
5
+ # Copyright September 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
+ class Document
11
+ # A span is a special purpose bounding box that allows a column of
12
+ # elements to be positioned relative to the margin_box.
13
+ #
14
+ # Arguments:
15
+ # +width+:: The width of the column in PDF points
16
+ #
17
+ # Options:
18
+ # <tt>:position</tt>:: One of :left, :center, :right or an x offset
19
+ #
20
+ # This method is typically used for flowing a column of text from one
21
+ # page to the next.
22
+ #
23
+ # span(350, :position => :center) do
24
+ # text "Here's some centered text in a 350 point column. " * 100
25
+ # end
26
+ #
27
+ def span(width, options={})
28
+ Prawn.verify_options [:position], options
29
+ original_position = self.y
30
+
31
+ # FIXME: How many effing times do I want to write this same code?
32
+ left_boundary = case(options[:position] || :left)
33
+ when :left
34
+ margin_box.absolute_left
35
+ when :center
36
+ margin_box.absolute_left + margin_box.width / 2.0 - width /2.0
37
+ when :right
38
+ margin_box.absolute_right - width
39
+ when Numeric
40
+ margin_box.absolute_left + options[:position]
41
+ else
42
+ raise ArgumentError, "Invalid option for :position"
43
+ end
44
+
45
+ # we need to bust out of whatever nested bounding boxes we're in.
46
+ canvas do
47
+ bounding_box([left_boundary,
48
+ margin_box.absolute_top], :width => width) do
49
+ self.y = original_position
50
+ yield
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,186 @@
1
+ # encoding: utf-8
2
+
3
+ # text.rb : Implements PDF text primitives
4
+ #
5
+ # Copyright May 2008, Gregory Brown. All Rights Reserved.
6
+ #
7
+ # This is free software. Please see the LICENSE and COPYING files for details.
8
+ require "zlib"
9
+ require "prawn/document/text/box"
10
+ require "prawn/document/text/wrapping"
11
+
12
+ module Prawn
13
+ class Document
14
+ module Text
15
+ include Wrapping
16
+
17
+ # Draws text on the page. If a point is specified via the +:at+
18
+ # option the text will begin exactly at that point, and the string is
19
+ # assumed to be pre-formatted to properly fit the page.
20
+ #
21
+ # pdf.text "Hello World", :at => [100,100]
22
+ # pdf.text "Goodbye World", :at => [50,50], :size => 16
23
+ #
24
+ # When +:at+ is not specified, Prawn attempts to wrap the text to
25
+ # fit within your current bounding box (or margin_box if no bounding box
26
+ # is being used ). Text will flow onto the next page when it reaches
27
+ # the bottom of the bounding box. Text wrap in Prawn does not re-flow
28
+ # linebreaks, so if you want fully automated text wrapping, be sure to
29
+ # remove newlines before attempting to draw your string.
30
+ #
31
+ # pdf.text "Will be wrapped when it hits the edge of your bounding box"
32
+ # pdf.text "This will be centered", :align => :center
33
+ # pdf.text "This will be right aligned", :align => :right
34
+ #
35
+ # Wrapping is done by splitting words by spaces by default. If your text
36
+ # does not contain spaces, you can wrap based on characters instead:
37
+ #
38
+ # pdf.text "This will be wrapped by character", :wrap => :character
39
+ #
40
+ # If your font contains kerning pairs data that Prawn can parse, the
41
+ # text will be kerned by default. You can disable this feature by passing
42
+ # <tt>:kerning => false</tt>.
43
+ #
44
+ # === Text Positioning Details:
45
+ #
46
+ # When using the :at parameter, Prawn will position your text by its
47
+ # baseline, and flow along a single line.
48
+ #
49
+ # Otherwise, the text is positioned at font.ascender below the baseline,
50
+ # making it easy to use this method within bounding boxes and spans.
51
+ #
52
+ # == Rotation
53
+ #
54
+ # Text can be rotated before it is placed on the canvas by specifying the
55
+ # :rotate option. Rotation occurs counter-clockwise.
56
+ #
57
+ # == Encoding
58
+ #
59
+ # Note that strings passed to this function should be encoded as UTF-8.
60
+ # If you get unexpected characters appearing in your rendered document,
61
+ # check this.
62
+ #
63
+ # If the current font is a built-in one, although the string must be
64
+ # encoded as UTF-8, only characters that are available in WinAnsi
65
+ # are allowed.
66
+ #
67
+ # If an empty box is rendered to your PDF instead of the character you
68
+ # wanted it usually means the current font doesn't include that character.
69
+ #
70
+ def text(text,options={})
71
+ # we'll be messing with the strings encoding, don't change the users
72
+ # original string
73
+ text = text.to_s.dup
74
+
75
+ save_font do
76
+ options = text_options.merge(options)
77
+ process_text_options(options)
78
+
79
+ font.normalize_encoding!(text) unless @skip_encoding
80
+
81
+ if options[:at]
82
+ x,y = translate(options[:at])
83
+ font_size(options[:size]) { add_text_content(text,x,y,options) }
84
+ else
85
+ if options[:rotate]
86
+ raise ArgumentError, "Rotated text may only be used with :at"
87
+ end
88
+ wrapped_text(text,options)
89
+ end
90
+ end
91
+ end
92
+
93
+ # A hash of configuration options, to be used globally by text().
94
+ #
95
+ # pdf.text_options.update(:size => 16, :align => :right)
96
+ # pdf.text "Hello World" #=> Size 16 w. right alignment
97
+ #
98
+ def text_options
99
+ @text_options ||= {}
100
+ end
101
+
102
+ private
103
+
104
+ def process_text_options(options)
105
+ Prawn.verify_options [:style, :kerning, :size, :at, :wrap,
106
+ :spacing, :align, :rotate, :final_gap ], options
107
+
108
+ if options[:style]
109
+ raise "Bad font family" unless font.family
110
+ font(font.family,:style => options[:style])
111
+ end
112
+
113
+ unless options.key?(:kerning)
114
+ options[:kerning] = font.has_kerning_data?
115
+ end
116
+
117
+ options[:size] ||= font_size
118
+ end
119
+
120
+ def move_text_position(dy)
121
+ bottom = @bounding_box.stretchy? ? @margin_box.absolute_bottom :
122
+ @bounding_box.absolute_bottom
123
+
124
+ @bounding_box.move_past_bottom if (y - dy) < bottom
125
+
126
+ self.y -= dy
127
+ end
128
+
129
+ def wrapped_text(text,options)
130
+ options[:align] ||= :left
131
+
132
+ font_size(options[:size]) do
133
+ text = naive_wrap(text, bounds.width, font_size,
134
+ :kerning => options[:kerning], :mode => options[:wrap])
135
+
136
+ lines = text.lines.to_a
137
+ last_gap_before = options.fetch(:final_gap, true) ? lines.length : lines.length-1
138
+
139
+ lines.each_with_index do |e,i|
140
+ move_text_position(font.ascender)
141
+
142
+ line_width = width_of(e, :kerning => options[:kerning])
143
+ case(options[:align])
144
+ when :left
145
+ x = @bounding_box.left_side
146
+ when :center
147
+ x = @bounding_box.left_side +
148
+ (@bounding_box.width - line_width) / 2.0
149
+ when :right
150
+ x = @bounding_box.right_side - line_width
151
+ end
152
+
153
+ add_text_content(e,x,y,options)
154
+
155
+ if i < last_gap_before
156
+ move_text_position(font.line_gap - font.descender)
157
+ move_text_position(options[:spacing]) if options[:spacing]
158
+ end
159
+ end
160
+ end
161
+ end
162
+
163
+ def add_text_content(text, x, y, options)
164
+ chunks = font.encode_text(text,options)
165
+
166
+ add_content "\nBT"
167
+ if options[:rotate]
168
+ rad = options[:rotate].to_i * Math::PI / 180
169
+ arr = [ Math.cos(rad), Math.sin(rad), -Math.sin(rad), Math.cos(rad), x, y ]
170
+ add_content "%.3f %.3f %.3f %.3f %.3f %.3f Tm" % arr
171
+ else
172
+ add_content "#{x} #{y} Td"
173
+ end
174
+
175
+ chunks.each do |(subset, string)|
176
+ font.add_to_current_page(subset)
177
+ add_content "/#{font.identifier_for(subset)} #{font_size} Tf"
178
+
179
+ operation = options[:kerning] && string.is_a?(Array) ? "TJ" : "Tj"
180
+ add_content Prawn::PdfObject(string, true) << " " << operation
181
+ end
182
+ add_content "ET\n"
183
+ end
184
+ end
185
+ end
186
+ end