prawn 0.12.0 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (282) hide show
  1. checksums.yaml +7 -0
  2. data/COPYING +2 -2
  3. data/Gemfile +18 -0
  4. data/LICENSE +1 -1
  5. data/README.md +17 -4
  6. data/Rakefile +18 -22
  7. data/data/images/indexed_color.dat +0 -0
  8. data/data/images/indexed_color.png +0 -0
  9. data/data/pdfs/nested_pages.pdf +13 -13
  10. data/lib/pdf/core.rb +35 -0
  11. data/lib/{prawn → pdf}/core/annotations.rb +6 -7
  12. data/lib/{prawn → pdf}/core/byte_string.rb +1 -1
  13. data/lib/{prawn → pdf}/core/destinations.rb +23 -23
  14. data/lib/{prawn → pdf}/core/document_state.rb +8 -8
  15. data/lib/pdf/core/filter_list.rb +51 -0
  16. data/lib/pdf/core/filters.rb +36 -0
  17. data/lib/pdf/core/graphics_state.rb +68 -0
  18. data/lib/{prawn → pdf}/core/literal_string.rb +1 -1
  19. data/lib/{prawn → pdf}/core/name_tree.rb +14 -2
  20. data/lib/{prawn → pdf}/core/object_store.rb +80 -24
  21. data/lib/pdf/core/outline.rb +315 -0
  22. data/lib/{prawn → pdf}/core/page.rb +23 -26
  23. data/lib/{prawn/document → pdf/core}/page_geometry.rb +11 -21
  24. data/lib/{prawn → pdf}/core/pdf_object.rb +48 -32
  25. data/lib/{prawn → pdf}/core/reference.rb +35 -44
  26. data/lib/pdf/core/stream.rb +98 -0
  27. data/lib/{prawn → pdf}/core/text.rb +24 -17
  28. data/lib/prawn.rb +95 -17
  29. data/lib/prawn/compatibility.rb +66 -26
  30. data/lib/prawn/document.rb +48 -30
  31. data/lib/prawn/document/bounding_box.rb +3 -3
  32. data/lib/prawn/document/column_box.rb +46 -8
  33. data/lib/prawn/document/graphics_state.rb +10 -73
  34. data/lib/prawn/document/internals.rb +24 -23
  35. data/lib/prawn/document/snapshot.rb +6 -7
  36. data/lib/prawn/document/span.rb +10 -10
  37. data/lib/prawn/encoding.rb +7 -7
  38. data/lib/prawn/errors.rb +18 -29
  39. data/lib/prawn/font.rb +64 -28
  40. data/lib/prawn/font/afm.rb +32 -74
  41. data/lib/prawn/font/dfont.rb +2 -2
  42. data/lib/prawn/font/ttf.rb +28 -57
  43. data/lib/prawn/font_metric_cache.rb +45 -0
  44. data/lib/prawn/graphics.rb +307 -41
  45. data/lib/prawn/graphics/cap_style.rb +3 -3
  46. data/lib/prawn/graphics/color.rb +12 -5
  47. data/lib/prawn/graphics/dash.rb +52 -31
  48. data/lib/prawn/graphics/join_style.rb +7 -7
  49. data/lib/prawn/graphics/patterns.rb +137 -0
  50. data/lib/prawn/graphics/transformation.rb +9 -9
  51. data/lib/prawn/graphics/transparency.rb +1 -1
  52. data/lib/prawn/image_handler.rb +30 -0
  53. data/lib/prawn/images.rb +86 -105
  54. data/lib/prawn/images/image.rb +48 -0
  55. data/lib/prawn/images/jpg.rb +14 -10
  56. data/lib/prawn/images/png.rb +50 -37
  57. data/lib/prawn/layout.rb +2 -2
  58. data/lib/prawn/layout/grid.rb +51 -51
  59. data/lib/prawn/measurement_extensions.rb +5 -5
  60. data/lib/prawn/measurements.rb +25 -21
  61. data/lib/prawn/outline.rb +4 -308
  62. data/lib/prawn/repeater.rb +8 -8
  63. data/lib/prawn/security.rb +50 -36
  64. data/lib/prawn/soft_mask.rb +94 -0
  65. data/lib/prawn/stamp.rb +3 -3
  66. data/lib/prawn/table.rb +292 -118
  67. data/lib/prawn/table/cell.rb +272 -45
  68. data/lib/prawn/table/cell/image.rb +70 -0
  69. data/lib/prawn/table/cell/in_table.rb +2 -2
  70. data/lib/prawn/table/cell/span_dummy.rb +92 -0
  71. data/lib/prawn/table/cell/subtable.rb +2 -2
  72. data/lib/prawn/table/cell/text.rb +42 -24
  73. data/lib/prawn/table/cells.rb +137 -48
  74. data/lib/prawn/text.rb +35 -23
  75. data/lib/prawn/text/box.rb +18 -5
  76. data/lib/prawn/text/formatted.rb +5 -4
  77. data/lib/prawn/text/formatted/arranger.rb +292 -0
  78. data/lib/prawn/text/formatted/box.rb +52 -13
  79. data/lib/prawn/text/formatted/fragment.rb +37 -22
  80. data/lib/prawn/text/formatted/line_wrap.rb +286 -0
  81. data/lib/prawn/text/formatted/parser.rb +14 -6
  82. data/lib/prawn/text/formatted/wrap.rb +151 -0
  83. data/lib/prawn/utilities.rb +44 -0
  84. data/manual/basic_concepts/adding_pages.rb +27 -0
  85. data/manual/basic_concepts/basic_concepts.rb +34 -0
  86. data/manual/basic_concepts/creation.rb +39 -0
  87. data/manual/basic_concepts/cursor.rb +33 -0
  88. data/manual/basic_concepts/measurement.rb +25 -0
  89. data/manual/basic_concepts/origin.rb +38 -0
  90. data/manual/basic_concepts/other_cursor_helpers.rb +40 -0
  91. data/manual/bounding_box/bounding_box.rb +39 -0
  92. data/manual/bounding_box/bounds.rb +49 -0
  93. data/manual/bounding_box/canvas.rb +24 -0
  94. data/manual/bounding_box/creation.rb +23 -0
  95. data/manual/bounding_box/indentation.rb +46 -0
  96. data/manual/bounding_box/nesting.rb +45 -0
  97. data/manual/bounding_box/russian_boxes.rb +40 -0
  98. data/manual/bounding_box/stretchy.rb +31 -0
  99. data/manual/document_and_page_options/background.rb +27 -0
  100. data/manual/document_and_page_options/document_and_page_options.rb +31 -0
  101. data/manual/document_and_page_options/metadata.rb +23 -0
  102. data/manual/document_and_page_options/page_margins.rb +38 -0
  103. data/manual/document_and_page_options/page_size.rb +34 -0
  104. data/manual/example_file.rb +116 -0
  105. data/manual/example_helper.rb +411 -0
  106. data/manual/example_package.rb +53 -0
  107. data/manual/example_section.rb +46 -0
  108. data/manual/graphics/circle_and_ellipse.rb +22 -0
  109. data/manual/graphics/color.rb +24 -0
  110. data/manual/graphics/common_lines.rb +28 -0
  111. data/manual/graphics/fill_and_stroke.rb +42 -0
  112. data/manual/graphics/fill_rules.rb +37 -0
  113. data/manual/graphics/gradients.rb +37 -0
  114. data/manual/graphics/graphics.rb +58 -0
  115. data/manual/graphics/helper.rb +24 -0
  116. data/manual/graphics/line_width.rb +35 -0
  117. data/manual/graphics/lines_and_curves.rb +41 -0
  118. data/manual/graphics/polygon.rb +29 -0
  119. data/manual/graphics/rectangle.rb +21 -0
  120. data/manual/graphics/rotate.rb +28 -0
  121. data/manual/graphics/scale.rb +41 -0
  122. data/manual/graphics/soft_masks.rb +46 -0
  123. data/manual/graphics/stroke_cap.rb +31 -0
  124. data/manual/graphics/stroke_dash.rb +48 -0
  125. data/manual/graphics/stroke_join.rb +30 -0
  126. data/manual/graphics/translate.rb +29 -0
  127. data/manual/graphics/transparency.rb +35 -0
  128. data/manual/images/absolute_position.rb +23 -0
  129. data/manual/images/fit.rb +21 -0
  130. data/manual/images/horizontal.rb +25 -0
  131. data/manual/images/images.rb +40 -0
  132. data/manual/images/plain_image.rb +18 -0
  133. data/manual/images/scale.rb +22 -0
  134. data/manual/images/vertical.rb +28 -0
  135. data/manual/images/width_and_height.rb +25 -0
  136. data/manual/layout/boxes.rb +27 -0
  137. data/manual/layout/content.rb +25 -0
  138. data/manual/layout/layout.rb +28 -0
  139. data/manual/layout/simple_grid.rb +23 -0
  140. data/manual/manual/cover.rb +35 -0
  141. data/manual/manual/foreword.rb +85 -0
  142. data/manual/manual/how_to_read_this_manual.rb +41 -0
  143. data/manual/manual/manual.rb +35 -0
  144. data/manual/outline/add_subsection_to.rb +61 -0
  145. data/manual/outline/insert_section_after.rb +47 -0
  146. data/manual/outline/outline.rb +32 -0
  147. data/manual/outline/sections_and_pages.rb +67 -0
  148. data/manual/repeatable_content/page_numbering.rb +54 -0
  149. data/manual/repeatable_content/repeatable_content.rb +31 -0
  150. data/manual/repeatable_content/repeater.rb +55 -0
  151. data/manual/repeatable_content/stamp.rb +41 -0
  152. data/manual/security/encryption.rb +31 -0
  153. data/manual/security/permissions.rb +38 -0
  154. data/manual/security/security.rb +28 -0
  155. data/manual/syntax_highlight.rb +52 -0
  156. data/manual/table/basic_block.rb +53 -0
  157. data/manual/table/before_rendering_page.rb +26 -0
  158. data/manual/table/cell_border_lines.rb +24 -0
  159. data/manual/table/cell_borders_and_bg.rb +31 -0
  160. data/manual/table/cell_dimensions.rb +30 -0
  161. data/manual/table/cell_text.rb +38 -0
  162. data/manual/table/column_widths.rb +30 -0
  163. data/manual/table/content_and_subtables.rb +39 -0
  164. data/manual/table/creation.rb +27 -0
  165. data/manual/table/filtering.rb +36 -0
  166. data/manual/table/flow_and_header.rb +17 -0
  167. data/manual/table/image_cells.rb +33 -0
  168. data/manual/table/position.rb +29 -0
  169. data/manual/table/row_colors.rb +20 -0
  170. data/manual/table/span.rb +30 -0
  171. data/manual/table/style.rb +22 -0
  172. data/manual/table/table.rb +52 -0
  173. data/manual/table/width.rb +27 -0
  174. data/manual/templates/full_template.rb +25 -0
  175. data/manual/templates/page_template.rb +48 -0
  176. data/manual/templates/templates.rb +27 -0
  177. data/manual/text/alignment.rb +44 -0
  178. data/manual/text/color.rb +24 -0
  179. data/manual/text/column_box.rb +32 -0
  180. data/manual/text/fallback_fonts.rb +37 -0
  181. data/manual/text/font.rb +41 -0
  182. data/manual/text/font_size.rb +45 -0
  183. data/manual/text/font_style.rb +23 -0
  184. data/manual/text/formatted_callbacks.rb +60 -0
  185. data/manual/text/formatted_text.rb +54 -0
  186. data/manual/text/free_flowing_text.rb +51 -0
  187. data/manual/text/group.rb +29 -0
  188. data/manual/text/inline.rb +43 -0
  189. data/manual/text/kerning_and_character_spacing.rb +39 -0
  190. data/manual/text/leading.rb +25 -0
  191. data/manual/text/line_wrapping.rb +41 -0
  192. data/manual/text/paragraph_indentation.rb +26 -0
  193. data/manual/text/positioned_text.rb +38 -0
  194. data/manual/text/registering_families.rb +48 -0
  195. data/manual/text/rendering_and_color.rb +37 -0
  196. data/manual/text/right_to_left_text.rb +43 -0
  197. data/manual/text/rotation.rb +43 -0
  198. data/manual/text/single_usage.rb +37 -0
  199. data/manual/text/text.rb +75 -0
  200. data/manual/text/text_box_excess.rb +32 -0
  201. data/manual/text/text_box_extensions.rb +45 -0
  202. data/manual/text/text_box_overflow.rb +44 -0
  203. data/manual/text/utf8.rb +28 -0
  204. data/{examples/m17n → manual/text}/win_ansi_charset.rb +14 -10
  205. data/prawn.gemspec +18 -12
  206. data/spec/acceptance/png.rb +23 -0
  207. data/spec/annotations_spec.rb +16 -32
  208. data/spec/bounding_box_spec.rb +128 -15
  209. data/spec/cell_spec.rb +169 -38
  210. data/spec/column_box_spec.rb +33 -0
  211. data/spec/destinations_spec.rb +5 -5
  212. data/spec/document_spec.rb +150 -104
  213. data/spec/extensions/encoding_helpers.rb +10 -0
  214. data/spec/extensions/mocha.rb +1 -0
  215. data/spec/filters_spec.rb +34 -0
  216. data/spec/font_metric_cache_spec.rb +52 -0
  217. data/spec/font_spec.rb +183 -97
  218. data/spec/formatted_text_arranger_spec.rb +43 -43
  219. data/spec/formatted_text_box_spec.rb +30 -20
  220. data/spec/formatted_text_fragment_spec.rb +8 -8
  221. data/spec/graphics_spec.rb +158 -69
  222. data/spec/grid_spec.rb +15 -15
  223. data/spec/image_handler_spec.rb +42 -0
  224. data/spec/images_spec.rb +49 -24
  225. data/spec/inline_formatted_text_parser_spec.rb +73 -19
  226. data/spec/jpg_spec.rb +4 -4
  227. data/spec/line_wrap_spec.rb +26 -26
  228. data/spec/measurement_units_spec.rb +6 -6
  229. data/spec/name_tree_spec.rb +21 -21
  230. data/spec/object_store_spec.rb +39 -39
  231. data/spec/outline_spec.rb +93 -53
  232. data/spec/pdf_object_spec.rb +88 -86
  233. data/spec/png_spec.rb +31 -28
  234. data/spec/reference_spec.rb +32 -32
  235. data/spec/repeater_spec.rb +25 -11
  236. data/spec/security_spec.rb +44 -12
  237. data/spec/snapshot_spec.rb +8 -9
  238. data/spec/soft_mask_spec.rb +117 -0
  239. data/spec/span_spec.rb +10 -15
  240. data/spec/spec_helper.rb +25 -8
  241. data/spec/stamp_spec.rb +29 -30
  242. data/spec/stream_spec.rb +58 -0
  243. data/spec/stroke_styles_spec.rb +36 -18
  244. data/spec/table/span_dummy_spec.rb +17 -0
  245. data/spec/table_spec.rb +697 -105
  246. data/spec/template_spec.rb +108 -54
  247. data/spec/text_at_spec.rb +18 -17
  248. data/spec/text_box_spec.rb +111 -62
  249. data/spec/text_rendering_mode_spec.rb +5 -5
  250. data/spec/text_spacing_spec.rb +4 -4
  251. data/spec/text_spec.rb +57 -49
  252. data/spec/transparency_spec.rb +5 -5
  253. metadata +421 -213
  254. data/data/fonts/Action Man.dfont +0 -0
  255. data/data/fonts/Activa.ttf +0 -0
  256. data/data/fonts/Chalkboard.ttf +0 -0
  257. data/data/fonts/DejaVuSans.ttf +0 -0
  258. data/data/fonts/Dustismo_Roman.ttf +0 -0
  259. data/data/fonts/comicsans.ttf +0 -0
  260. data/data/fonts/gkai00mp.ttf +0 -0
  261. data/data/images/rails.dat +0 -0
  262. data/data/images/rails.png +0 -0
  263. data/examples/bounding_box/russian_boxes.rb +0 -37
  264. data/examples/example_helper.rb +0 -11
  265. data/examples/general/context_sensitive_headers.rb +0 -38
  266. data/examples/graphics/cmyk.rb +0 -13
  267. data/examples/graphics/gradient.rb +0 -23
  268. data/examples/graphics/png_types.rb +0 -23
  269. data/examples/graphics/remote_images.rb +0 -13
  270. data/examples/m17n/full_win_ansi_character_list.rb +0 -20
  271. data/examples/m17n/sjis.rb +0 -29
  272. data/examples/table/bill.rb +0 -54
  273. data/examples/table/header.rb +0 -15
  274. data/examples/text/font_calculations.rb +0 -92
  275. data/examples/text/hyphenation.rb +0 -45
  276. data/examples/text/indent_paragraphs.rb +0 -24
  277. data/lib/prawn/core.rb +0 -85
  278. data/lib/prawn/core/text/formatted/arranger.rb +0 -294
  279. data/lib/prawn/core/text/formatted/line_wrap.rb +0 -273
  280. data/lib/prawn/core/text/formatted/wrap.rb +0 -153
  281. data/lib/prawn/graphics/gradient.rb +0 -84
  282. data/lib/prawn/security/arcfour.rb +0 -51
@@ -2,9 +2,9 @@ require "prawn/table"
2
2
  require 'prawn/layout/grid'
3
3
 
4
4
  module Prawn
5
-
5
+
6
6
  module Errors
7
-
7
+
8
8
  # This error is raised when table data is malformed
9
9
  #
10
10
  InvalidTableData = Class.new(StandardError)
@@ -1,15 +1,15 @@
1
1
  module Prawn
2
2
  class Document
3
-
4
- # Defines the grid system for a particular document. Takes the number of
5
- # rows and columns and the width to use for the gutter as the
3
+
4
+ # Defines the grid system for a particular document. Takes the number of
5
+ # rows and columns and the width to use for the gutter as the
6
6
  # keys :rows, :columns, :gutter, :row_gutter, :column_gutter
7
7
  #
8
8
  def define_grid(options = {})
9
9
  @grid = Grid.new(self, options)
10
10
  end
11
-
12
- # A method that can either be used to access a particular grid on the page
11
+
12
+ # A method that can either be used to access a particular grid on the page
13
13
  # or work with the grid system directly.
14
14
  #
15
15
  # @pdf.grid # Get the Grid directly
@@ -22,7 +22,7 @@ module Prawn
22
22
  @grid
23
23
  else
24
24
  g1, g2 = args
25
- if(g1.class == Array && g2.class == Array &&
25
+ if(g1.class == Array && g2.class == Array &&
26
26
  g1.length == 2 && g2.length == 2)
27
27
  multi_box(single_box(*g1), single_box(*g2))
28
28
  else
@@ -30,15 +30,15 @@ module Prawn
30
30
  end
31
31
  end
32
32
  end
33
-
34
- # A Grid represents the entire grid system of a Page and calculates
33
+
34
+ # A Grid represents the entire grid system of a Page and calculates
35
35
  # the column width and row height of the base box.
36
36
  class Grid
37
37
  attr_reader :pdf, :columns, :rows, :gutter, :row_gutter, :column_gutter
38
38
  def initialize(pdf, options = {}) # :nodoc:
39
39
  valid_options = [:columns, :rows, :gutter, :row_gutter, :column_gutter]
40
40
  Prawn.verify_options valid_options, options
41
-
41
+
42
42
  @pdf = pdf
43
43
  @columns = options[:columns]
44
44
  @rows = options[:rows]
@@ -49,7 +49,7 @@ module Prawn
49
49
  def column_width
50
50
  @column_width ||= subdivide(pdf.bounds.width, columns, column_gutter)
51
51
  end
52
-
52
+
53
53
  # Calculates the base height of boxes.
54
54
  def row_height
55
55
  @row_height ||= subdivide(pdf.bounds.height, rows, row_gutter)
@@ -65,11 +65,11 @@ module Prawn
65
65
  end
66
66
 
67
67
  private
68
-
68
+
69
69
  def subdivide(total, num, gutter)
70
70
  (total.to_f - (gutter * (num - 1).to_f)) / num.to_f
71
71
  end
72
-
72
+
73
73
  def set_gutter(options)
74
74
  if options.has_key?(:gutter)
75
75
  @gutter = options[:gutter].to_f
@@ -81,92 +81,92 @@ module Prawn
81
81
  end
82
82
  end
83
83
  end
84
-
85
- # A Box is a class that represents a bounded area of a page.
86
- # A Grid object has methods that allow easy access to the coordinates of
84
+
85
+ # A Box is a class that represents a bounded area of a page.
86
+ # A Grid object has methods that allow easy access to the coordinates of
87
87
  # its corners, which can be plugged into most existing prawnmethods.
88
88
  #
89
89
  class Box #:nodoc:
90
90
  attr_reader :pdf
91
-
91
+
92
92
  def initialize(pdf, i, j)
93
93
  @pdf = pdf
94
94
  @i = i
95
95
  @j = j
96
96
  end
97
-
98
- # Mostly diagnostic method that outputs the name of a box as
97
+
98
+ # Mostly diagnostic method that outputs the name of a box as
99
99
  # col_num, row_num
100
100
  #
101
101
  def name
102
102
  "#{@i.to_s},#{@j.to_s}"
103
103
  end
104
-
104
+
105
105
  # :nodoc
106
106
  def total_height
107
107
  pdf.bounds.height.to_f
108
108
  end
109
-
109
+
110
110
  # Width of a box
111
111
  def width
112
112
  grid.column_width.to_f
113
113
  end
114
-
114
+
115
115
  # Height of a box
116
116
  def height
117
117
  grid.row_height.to_f
118
118
  end
119
-
119
+
120
120
  # Width of the gutter
121
121
  def gutter
122
122
  grid.gutter.to_f
123
123
  end
124
-
124
+
125
125
  # x-coordinate of left side
126
126
  def left
127
127
  @left ||= (width + grid.column_gutter) * @j.to_f
128
128
  end
129
-
130
- # x-coordinate of right side
129
+
130
+ # x-coordinate of right side
131
131
  def right
132
132
  @right ||= left + width
133
133
  end
134
-
134
+
135
135
  # y-coordinate of the top
136
136
  def top
137
137
  @top ||= total_height - ((height + grid.row_gutter) * @i.to_f)
138
138
  end
139
-
139
+
140
140
  # y-coordinate of the bottom
141
141
  def bottom
142
142
  @bottom ||= top - height
143
143
  end
144
-
144
+
145
145
  # x,y coordinates of top left corner
146
146
  def top_left
147
147
  [left, top]
148
148
  end
149
-
150
- # x,y coordinates of top right corner
149
+
150
+ # x,y coordinates of top right corner
151
151
  def top_right
152
152
  [right, top]
153
153
  end
154
-
154
+
155
155
  # x,y coordinates of bottom left corner
156
156
  def bottom_left
157
157
  [left, bottom]
158
158
  end
159
-
159
+
160
160
  # x,y coordinates of bottom right corner
161
161
  def bottom_right
162
162
  [right, bottom]
163
163
  end
164
-
164
+
165
165
  # Creates a standard bounding box based on the grid box.
166
166
  def bounding_box(&blk)
167
167
  pdf.bounding_box(top_left, :width => width, :height => height, &blk)
168
168
  end
169
-
169
+
170
170
  # Diagnostic method
171
171
  def show(grid_color = "CCCCCC")
172
172
  self.bounding_box do
@@ -175,28 +175,28 @@ module Prawn
175
175
  pdf.stroke_color = grid_color
176
176
  pdf.text self.name
177
177
  pdf.stroke_bounds
178
-
178
+
179
179
  pdf.stroke_color = original_stroke_color
180
180
  end
181
181
  end
182
-
182
+
183
183
  private
184
184
  def grid
185
185
  pdf.grid
186
186
  end
187
187
  end
188
-
188
+
189
189
  # A MultiBox is specified by 2 Boxes and spans the areas between.
190
190
  class MultiBox < Box #:nodoc:
191
191
  def initialize(pdf, b1, b2)
192
192
  @pdf = pdf
193
193
  @bs = [b1, b2]
194
194
  end
195
-
195
+
196
196
  def name
197
197
  @bs.map {|b| b.name}.join(":")
198
198
  end
199
-
199
+
200
200
  def total_height
201
201
  @bs[0].total_height
202
202
  end
@@ -204,54 +204,54 @@ module Prawn
204
204
  def width
205
205
  right_box.right - left_box.left
206
206
  end
207
-
207
+
208
208
  def height
209
209
  top_box.top - bottom_box.bottom
210
210
  end
211
-
211
+
212
212
  def gutter
213
213
  @bs[0].gutter
214
214
  end
215
-
215
+
216
216
  def left
217
217
  left_box.left
218
218
  end
219
-
219
+
220
220
  def right
221
221
  right_box.right
222
222
  end
223
-
223
+
224
224
  def top
225
225
  top_box.top
226
226
  end
227
-
227
+
228
228
  def bottom
229
229
  bottom_box.bottom
230
230
  end
231
-
231
+
232
232
  private
233
233
  def left_box
234
234
  @left_box ||= @bs.min {|a,b| a.left <=> b.left}
235
235
  end
236
-
236
+
237
237
  def right_box
238
238
  @right_box ||= @bs.max {|a,b| a.right <=> b.right}
239
239
  end
240
-
240
+
241
241
  def top_box
242
242
  @top_box ||= @bs.max {|a,b| a.top <=> b.top}
243
243
  end
244
-
244
+
245
245
  def bottom_box
246
246
  @bottom_box ||= @bs.min {|a,b| a.bottom <=> b.bottom}
247
247
  end
248
248
  end
249
-
249
+
250
250
  private
251
251
  def single_box(i, j)
252
252
  Box.new(self, i, j)
253
253
  end
254
-
254
+
255
255
  def multi_box(b1, b2)
256
256
  MultiBox.new(self, b1, b2)
257
257
  end
@@ -8,8 +8,8 @@
8
8
  require 'prawn/measurements'
9
9
 
10
10
  class Numeric
11
- include Prawn::Measurements
12
- # prawns' basic unit is PostScript-Point
11
+ include Prawn::Measurements
12
+ # prawns' basic unit is PostScript-Point
13
13
  # 72 points per inch
14
14
 
15
15
  def mm
@@ -39,8 +39,8 @@ class Numeric
39
39
  def ft
40
40
  return ft2pt(self)
41
41
  end
42
-
42
+
43
43
  def pt
44
- return self
44
+ return pt2pt(self)
45
45
  end
46
- end
46
+ end
@@ -3,69 +3,73 @@
3
3
  #
4
4
  # Copyright December 2008, Florian Witteler. All Rights Reserved.
5
5
  #
6
- module Prawn
6
+ module Prawn
7
7
  module Measurements
8
-
8
+
9
9
  # ============================================================================
10
10
  #metric conversions
11
11
  def cm2mm(cm)
12
12
  return cm*10
13
13
  end
14
-
14
+
15
15
  def dm2mm(dm)
16
- return dm*100
16
+ return dm*100
17
17
  end
18
-
18
+
19
19
  def m2mm(m)
20
20
  return m*1000
21
21
  end
22
-
22
+
23
23
  # ============================================================================
24
- # imperial conversions
24
+ # imperial conversions
25
25
  # from http://en.wikipedia.org/wiki/Imperial_units
26
-
26
+
27
27
  def ft2in(ft)
28
28
  return ft * 12
29
- end
29
+ end
30
30
 
31
31
  def yd2in(yd)
32
32
  return yd*36
33
33
  end
34
34
 
35
-
35
+
36
36
  # ============================================================================
37
37
  # PostscriptPoint-converisons
38
-
38
+
39
+ def pt2pt(pt)
40
+ return pt
41
+ end
42
+
39
43
  def in2pt(inch)
40
- return inch * 72
44
+ return inch * 72
41
45
  end
42
-
46
+
43
47
  def ft2pt(ft)
44
48
  return in2pt(ft2in(ft))
45
49
  end
46
-
50
+
47
51
  def yd2pt(yd)
48
52
  return in2pt(yd2in(yd))
49
53
  end
50
-
54
+
51
55
  def mm2pt(mm)
52
56
  return mm*(72 / 25.4)
53
57
  end
54
-
58
+
55
59
  def cm2pt(cm)
56
60
  return mm2pt(cm2mm(cm))
57
61
  end
58
-
62
+
59
63
  def dm2pt(dm)
60
64
  return mm2pt(dm2mm(dm))
61
65
  end
62
-
66
+
63
67
  def m2pt(m)
64
68
  return mm2pt(m2mm(m))
65
69
  end
66
-
67
- def pt2mm(pt)
70
+
71
+ def pt2mm(pt)
68
72
  return pt * 1 / mm2pt(1)# (25.4 / 72)
69
73
  end
70
74
  end
71
- end
75
+ end
@@ -5,322 +5,18 @@
5
5
  # Author Jonathan Greenberg
6
6
 
7
7
  require 'forwardable'
8
+ require_relative "../pdf/core/outline"
8
9
 
9
10
  module Prawn
10
-
11
+
11
12
  class Document
12
13
 
13
14
  # Lazily instantiates an Outline object for document. This is used as point of entry
14
15
  # to methods to build the outline tree.
15
16
  def outline
16
- @outline ||= Outline.new(self)
17
- end
18
-
19
- end
20
-
21
- # The Outline class organizes the outline tree items for the document.
22
- # Note that the prev and parent instance variables are adjusted while navigating
23
- # through the nested blocks. These variables along with the presence or absense
24
- # of blocks are the primary means by which the relations for the various
25
- # OutlineItems and the OutlineRoot are set. Unfortunately, the best way to
26
- # understand how this works is to follow the method calls through a real example.
27
- #
28
- # Some ideas for the organization of this class were gleaned from name_tree. In
29
- # particular the way in which the OutlineItems are finally rendered into document
30
- # objects in PdfObject through a hash.
31
- #
32
- class Outline
33
-
34
- extend Forwardable
35
- def_delegator :@document, :page_number
36
-
37
- attr_accessor :parent
38
- attr_accessor :prev
39
- attr_accessor :document
40
- attr_accessor :items
41
-
42
- def initialize(document)
43
- @document = document
44
- @parent = root
45
- @prev = nil
46
- @items = {}
47
- end
48
-
49
- # Defines/Updates an outline for the document.
50
- # The outline is an optional nested index that appears on the side of a PDF
51
- # document usually with direct links to pages. The outline DSL is defined by nested
52
- # blocks involving two methods: section and page; see the documentation on those methods
53
- # for their arguments and options. Note that one can also use outline#update
54
- # to add more sections to the end of the outline tree using the same syntax and scope.
55
- #
56
- # The syntax is best illustrated with an example:
57
- #
58
- # Prawn::Document.generate(outlined_document.pdf) do
59
- # text "Page 1. This is the first Chapter. "
60
- # start_new_page
61
- # text "Page 2. More in the first Chapter. "
62
- # start_new_page
63
- # outline.define do
64
- # section 'Chapter 1', :destination => 1, :closed => true do
65
- # page :destination => 1, :title => 'Page 1'
66
- # page :destination => 2, :title => 'Page 2'
67
- # end
68
- # end
69
- # start_new_page do
70
- # outline.update do
71
- # section 'Chapter 2', :destination => 2, do
72
- # page :destination => 3, :title => 'Page 3'
73
- # end
74
- # end
75
- # end
76
- #
77
- def define(&block)
78
- instance_eval(&block) if block
79
- end
80
-
81
- alias :update :define
82
-
83
- # Inserts an outline section to the outline tree (see outline#define).
84
- # Although you will probably choose to exclusively use outline#define so
85
- # that your outline tree is contained and easy to manage, this method
86
- # gives you the option to insert sections to the outline tree at any point
87
- # during document generation. This method allows you to add a child subsection
88
- # to any other item at any level in the outline tree.
89
- # Currently the only way to locate the place of entry is with the title for the
90
- # item. If your title names are not unique consider using define_outline.
91
- # The method takes the following arguments:
92
- # title: a string that must match an outline title to add the subsection to
93
- # position: either :first or :last(the default) where the subsection will be placed relative
94
- # to other child elements. If you need to position your subsection in between
95
- # other elements then consider using #insert_section_after
96
- # block: uses the same DSL syntax as outline#define, for example:
97
- #
98
- # Consider using this method inside of outline.update if you want to have the outline object
99
- # to be scoped as self (see #insert_section_after example).
100
- #
101
- # go_to_page 2
102
- # start_new_page
103
- # text "Inserted Page"
104
- # outline.add_subsection_to :title => 'Page 2', :first do
105
- # outline.page :destination => page_number, :title => "Inserted Page"
106
- # end
107
- #
108
- def add_subsection_to(title, position = :last, &block)
109
- @parent = items[title]
110
- raise Prawn::Errors::UnknownOutlineTitle,
111
- "\n No outline item with title: '#{title}' exists in the outline tree" unless @parent
112
- @prev = position == :first ? nil : @parent.data.last
113
- nxt = position == :first ? @parent.data.first : nil
114
- insert_section(nxt, &block)
115
- end
116
-
117
- # Inserts an outline section to the outline tree (see outline#define).
118
- # Although you will probably choose to exclusively use outline#define so
119
- # that your outline tree is contained and easy to manage, this method
120
- # gives you the option to insert sections to the outline tree at any point
121
- # during document generation. Unlike outline.add_section, this method allows
122
- # you to enter a section after any other item at any level in the outline tree.
123
- # Currently the only way to locate the place of entry is with the title for the
124
- # item. If your title names are not unique consider using define_outline.
125
- # The method takes the following arguments:
126
- # title: the title of other section or page to insert new section after
127
- # block: uses the same DSL syntax as outline#define, for example:
128
- #
129
- # go_to_page 2
130
- # start_new_page
131
- # text "Inserted Page"
132
- # update_outline do
133
- # insert_section_after :title => 'Page 2' do
134
- # page :destination => page_number, :title => "Inserted Page"
135
- # end
136
- # end
137
- #
138
- def insert_section_after(title, &block)
139
- @prev = items[title]
140
- raise Prawn::Errors::UnknownOutlineTitle,
141
- "\n No outline item with title: '#{title}' exists in the outline tree" unless @prev
142
- @parent = @prev.data.parent
143
- nxt = @prev.data.next
144
- insert_section(nxt, &block)
145
- end
146
-
147
- # See outline#define above for documentation on how this is used in that context
148
- #
149
- # Adds an outine section to the outline tree.
150
- # Although you will probably choose to exclusively use outline#define so
151
- # that your outline tree is contained and easy to manage, this method
152
- # gives you the option to add sections to the outline tree at any point
153
- # during document generation. When not being called from within another #section block
154
- # the section will be added at the top level after the other root elements of the outline.
155
- # For more flexible placement try using outline#insert_section_after and/or
156
- # outline#add_subsection_to
157
- # Takes the following arguments:
158
- # title: the outline text that appears for the section.
159
- # options: destination - optional integer defining the page number for a destination link.
160
- # - currently only :FIT destination supported with link to top of page.
161
- # closed - whether the section should show its nested outline elements.
162
- # - defaults to false.
163
- # block: more nested subsections and/or page blocks
164
- #
165
- # example usage:
166
- #
167
- # outline.section 'Added Section', :destination => 3 do
168
- # outline.page :destionation => 3, :title => 'Page 3'
169
- # end
170
- def section(title, options = {}, &block)
171
- add_outline_item(title, options, &block)
172
- end
173
-
174
- # See Outline#define above for more documentation on how it is used in that context
175
- #
176
- # Adds a page to the outline.
177
- # Although you will probably choose to exclusively use outline#define so
178
- # that your outline tree is contained and easy to manage, this method also
179
- # gives you the option to add pages to the root of outline tree at any point
180
- # during document generation. Note that the page will be added at the
181
- # top level after the other root outline elements. For more flexible placement try
182
- # using outline#insert_section_after and/or outline#add_subsection_to.
183
- #
184
- # Takes the following arguments:
185
- # options:
186
- # title - REQUIRED. The outline text that appears for the page.
187
- # destination - integer defining the page number for the destination link.
188
- # currently only :FIT destination supported with link to top of page.
189
- # closed - whether the section should show its nested outline elements.
190
- # - defaults to false.
191
- # example usage:
192
- #
193
- # outline.page :title => "Very Last Page"
194
- # Note: this method is almost identical to section except that it does not accept a block
195
- # thereby defining the outline item as a leaf on the outline tree structure.
196
- def page(options = {})
197
- if options[:title]
198
- title = options[:title]
199
- else
200
- raise Prawn::Errors::RequiredOption,
201
- "\nTitle is a required option for page"
202
- end
203
- add_outline_item(title, options)
17
+ @outline ||= PDF::Core::Outline.new(self)
204
18
  end
205
-
206
- private
207
-
208
- # The Outline dictionary (12.3.3) for this document. It is
209
- # lazily initialized, so that documents that do not have an outline
210
- # do not incur the additional overhead.
211
- def root
212
- document.state.store.root.data[:Outlines] ||= document.ref!(OutlineRoot.new)
213
- end
214
-
215
- def add_outline_item(title, options, &block)
216
- outline_item = create_outline_item(title, options)
217
- set_relations(outline_item)
218
- increase_count
219
- set_variables_for_block(outline_item, block)
220
- block.call if block
221
- reset_parent(outline_item)
222
- end
223
-
224
- def create_outline_item(title, options)
225
- outline_item = OutlineItem.new(title, parent, options)
226
-
227
- if options[:destination]
228
- page_index = options[:destination] - 1
229
- outline_item.dest = [document.state.pages[page_index].dictionary, :Fit]
230
- end
231
19
 
232
- outline_item.prev = prev if @prev
233
- items[title] = document.ref!(outline_item)
234
- end
235
-
236
- def set_relations(outline_item)
237
- prev.data.next = outline_item if prev
238
- parent.data.first = outline_item unless prev
239
- parent.data.last = outline_item
240
- end
241
-
242
- def increase_count
243
- counting_parent = parent
244
- while counting_parent
245
- counting_parent.data.count += 1
246
- if counting_parent == root
247
- counting_parent = nil
248
- else
249
- counting_parent = counting_parent.data.parent
250
- end
251
- end
252
- end
253
-
254
- def set_variables_for_block(outline_item, block)
255
- self.prev = block ? nil : outline_item
256
- self.parent = outline_item if block
257
- end
258
-
259
- def reset_parent(outline_item)
260
- if parent == outline_item
261
- self.prev = outline_item
262
- self.parent = outline_item.data.parent
263
- end
264
- end
265
-
266
- def insert_section(nxt, &block)
267
- last = @parent.data.last
268
- if block
269
- block.call
270
- end
271
- adjust_relations(nxt, last)
272
- reset_root_positioning
273
- end
274
-
275
- def adjust_relations(nxt, last)
276
- if nxt
277
- nxt.data.prev = @prev
278
- @prev.data.next = nxt
279
- @parent.data.last = last
280
- end
281
- end
282
-
283
- def reset_root_positioning
284
- @parent = root
285
- @prev = root.data.last
286
- end
287
-
288
- end
289
-
290
- class OutlineRoot #:nodoc:
291
- attr_accessor :count, :first, :last
292
-
293
- def initialize
294
- @count = 0
295
- end
296
-
297
- def to_hash
298
- {:Type => :Outlines, :Count => count, :First => first, :Last => last}
299
- end
300
20
  end
301
-
302
- class OutlineItem #:nodoc:
303
- attr_accessor :count, :first, :last, :next, :prev, :parent, :title, :dest, :closed
304
-
305
- def initialize(title, parent, options)
306
- @closed = options[:closed]
307
- @title = title
308
- @parent = parent
309
- @count = 0
310
- end
311
-
312
- def to_hash
313
- hash = { :Title => title,
314
- :Parent => parent,
315
- :Count => closed ? -count : count }
316
- [{:First => first}, {:Last => last}, {:Next => @next},
317
- {:Prev => prev}, {:Dest => dest}].each do |h|
318
- unless h.values.first.nil?
319
- hash.merge!(h)
320
- end
321
- end
322
- hash
323
- end
324
- end
21
+
325
22
  end
326
-