alphasights-prawn 0.10.0

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 (244) hide show
  1. data/COPYING +340 -0
  2. data/HACKING +50 -0
  3. data/LICENSE +56 -0
  4. data/README +141 -0
  5. data/Rakefile +52 -0
  6. data/data/encodings/win_ansi.txt +29 -0
  7. data/data/fonts/Action Man.dfont +0 -0
  8. data/data/fonts/Activa.ttf +0 -0
  9. data/data/fonts/Chalkboard.ttf +0 -0
  10. data/data/fonts/Courier-Bold.afm +342 -0
  11. data/data/fonts/Courier-BoldOblique.afm +342 -0
  12. data/data/fonts/Courier-Oblique.afm +342 -0
  13. data/data/fonts/Courier.afm +342 -0
  14. data/data/fonts/DejaVuSans.ttf +0 -0
  15. data/data/fonts/Dustismo_Roman.ttf +0 -0
  16. data/data/fonts/Helvetica-Bold.afm +2827 -0
  17. data/data/fonts/Helvetica-BoldOblique.afm +2827 -0
  18. data/data/fonts/Helvetica-Oblique.afm +3051 -0
  19. data/data/fonts/Helvetica.afm +3051 -0
  20. data/data/fonts/MustRead.html +19 -0
  21. data/data/fonts/Symbol.afm +213 -0
  22. data/data/fonts/Times-Bold.afm +2588 -0
  23. data/data/fonts/Times-BoldItalic.afm +2384 -0
  24. data/data/fonts/Times-Italic.afm +2667 -0
  25. data/data/fonts/Times-Roman.afm +2419 -0
  26. data/data/fonts/ZapfDingbats.afm +225 -0
  27. data/data/fonts/comicsans.ttf +0 -0
  28. data/data/fonts/gkai00mp.ttf +0 -0
  29. data/data/images/16bit.alpha +0 -0
  30. data/data/images/16bit.dat +0 -0
  31. data/data/images/16bit.png +0 -0
  32. data/data/images/arrow.png +0 -0
  33. data/data/images/arrow2.png +0 -0
  34. data/data/images/barcode_issue.png +0 -0
  35. data/data/images/dice.alpha +0 -0
  36. data/data/images/dice.dat +0 -0
  37. data/data/images/dice.png +0 -0
  38. data/data/images/dice_interlaced.png +0 -0
  39. data/data/images/fractal.jpg +0 -0
  40. data/data/images/letterhead.jpg +0 -0
  41. data/data/images/page_white_text.alpha +0 -0
  42. data/data/images/page_white_text.dat +0 -0
  43. data/data/images/page_white_text.png +0 -0
  44. data/data/images/pigs.jpg +0 -0
  45. data/data/images/rails.dat +0 -0
  46. data/data/images/rails.png +0 -0
  47. data/data/images/ruport.png +0 -0
  48. data/data/images/ruport_data.dat +0 -0
  49. data/data/images/ruport_transparent.png +0 -0
  50. data/data/images/ruport_type0.png +0 -0
  51. data/data/images/stef.jpg +0 -0
  52. data/data/images/tru256.bmp +0 -0
  53. data/data/images/web-links.dat +1 -0
  54. data/data/images/web-links.png +0 -0
  55. data/data/pdfs/complex_template.pdf +0 -0
  56. data/data/pdfs/contains_ttf_font.pdf +0 -0
  57. data/data/pdfs/encrypted.pdf +0 -0
  58. data/data/pdfs/hexagon.pdf +61 -0
  59. data/data/pdfs/indirect_reference.pdf +86 -0
  60. data/data/pdfs/nested_pages.pdf +118 -0
  61. data/data/pdfs/resources_as_indirect_object.pdf +83 -0
  62. data/data/pdfs/two_hexagons.pdf +90 -0
  63. data/data/pdfs/version_1_6.pdf +61 -0
  64. data/data/shift_jis_text.txt +1 -0
  65. data/examples/bounding_box/bounding_boxes.rb +43 -0
  66. data/examples/bounding_box/indentation.rb +34 -0
  67. data/examples/bounding_box/russian_boxes.rb +36 -0
  68. data/examples/bounding_box/stretched_nesting.rb +67 -0
  69. data/examples/builder/simple.rb +28 -0
  70. data/examples/example_helper.rb +4 -0
  71. data/examples/general/background.rb +23 -0
  72. data/examples/general/canvas.rb +15 -0
  73. data/examples/general/context_sensitive_headers.rb +37 -0
  74. data/examples/general/float.rb +11 -0
  75. data/examples/general/margin.rb +36 -0
  76. data/examples/general/measurement_units.rb +51 -0
  77. data/examples/general/metadata-info.rb +16 -0
  78. data/examples/general/multi_page_layout.rb +18 -0
  79. data/examples/general/outlines.rb +50 -0
  80. data/examples/general/page_geometry.rb +31 -0
  81. data/examples/general/page_numbering.rb +15 -0
  82. data/examples/general/repeaters.rb +47 -0
  83. data/examples/general/stamp.rb +41 -0
  84. data/examples/general/templates.rb +13 -0
  85. data/examples/graphics/basic_images.rb +23 -0
  86. data/examples/graphics/chunkable.rb +38 -0
  87. data/examples/graphics/cmyk.rb +12 -0
  88. data/examples/graphics/curves.rb +11 -0
  89. data/examples/graphics/hexagon.rb +13 -0
  90. data/examples/graphics/image_fit.rb +15 -0
  91. data/examples/graphics/image_flow.rb +37 -0
  92. data/examples/graphics/image_position.rb +17 -0
  93. data/examples/graphics/line.rb +32 -0
  94. data/examples/graphics/png_types.rb +22 -0
  95. data/examples/graphics/polygons.rb +16 -0
  96. data/examples/graphics/remote_images.rb +12 -0
  97. data/examples/graphics/rounded_polygons.rb +19 -0
  98. data/examples/graphics/rounded_rectangle.rb +20 -0
  99. data/examples/graphics/ruport_style_helpers.rb +19 -0
  100. data/examples/graphics/stroke_bounds.rb +20 -0
  101. data/examples/graphics/stroke_cap_and_join.rb +45 -0
  102. data/examples/graphics/stroke_dash.rb +42 -0
  103. data/examples/graphics/transformations.rb +52 -0
  104. data/examples/graphics/transparency.rb +26 -0
  105. data/examples/m17n/chinese_text_wrapping.rb +17 -0
  106. data/examples/m17n/euro.rb +15 -0
  107. data/examples/m17n/sjis.rb +28 -0
  108. data/examples/m17n/utf8.rb +13 -0
  109. data/examples/m17n/win_ansi_charset.rb +54 -0
  110. data/examples/security/hello_foo.rb +8 -0
  111. data/examples/table/bill.rb +53 -0
  112. data/examples/table/cell.rb +12 -0
  113. data/examples/table/checkerboard.rb +22 -0
  114. data/examples/table/header.rb +14 -0
  115. data/examples/table/inline_format_table.rb +12 -0
  116. data/examples/table/multi_page_table.rb +9 -0
  117. data/examples/table/simple_table.rb +24 -0
  118. data/examples/table/subtable.rb +12 -0
  119. data/examples/table/widths.rb +20 -0
  120. data/examples/text/alignment.rb +18 -0
  121. data/examples/text/character_spacing.rb +12 -0
  122. data/examples/text/dfont.rb +48 -0
  123. data/examples/text/family_based_styling.rb +24 -0
  124. data/examples/text/font_calculations.rb +91 -0
  125. data/examples/text/font_size.rb +33 -0
  126. data/examples/text/hyphenation.rb +45 -0
  127. data/examples/text/indent_paragraphs.rb +22 -0
  128. data/examples/text/inline_format.rb +103 -0
  129. data/examples/text/kerning.rb +30 -0
  130. data/examples/text/rotated.rb +98 -0
  131. data/examples/text/shaped_text_box.rb +31 -0
  132. data/examples/text/simple_text.rb +17 -0
  133. data/examples/text/simple_text_ttf.rb +17 -0
  134. data/examples/text/text_box.rb +88 -0
  135. data/examples/text/text_box_returning_excess.rb +51 -0
  136. data/examples/text/text_flow.rb +67 -0
  137. data/lib/prawn.rb +27 -0
  138. data/lib/prawn/canvas.rb +119 -0
  139. data/lib/prawn/chunkable.rb +37 -0
  140. data/lib/prawn/compatibility.rb +51 -0
  141. data/lib/prawn/core.rb +85 -0
  142. data/lib/prawn/core/annotations.rb +61 -0
  143. data/lib/prawn/core/byte_string.rb +9 -0
  144. data/lib/prawn/core/chunk.rb +36 -0
  145. data/lib/prawn/core/destinations.rb +90 -0
  146. data/lib/prawn/core/document_state.rb +78 -0
  147. data/lib/prawn/core/literal_string.rb +16 -0
  148. data/lib/prawn/core/name_tree.rb +165 -0
  149. data/lib/prawn/core/object_store.rb +236 -0
  150. data/lib/prawn/core/page.rb +179 -0
  151. data/lib/prawn/core/pdf_object.rb +108 -0
  152. data/lib/prawn/core/reference.rb +112 -0
  153. data/lib/prawn/core/text.rb +140 -0
  154. data/lib/prawn/core/text/formatted/arranger.rb +266 -0
  155. data/lib/prawn/core/text/formatted/line_wrap.rb +127 -0
  156. data/lib/prawn/core/text/formatted/wrap.rb +112 -0
  157. data/lib/prawn/core/text/line_wrap.rb +209 -0
  158. data/lib/prawn/core/text/wrap.rb +80 -0
  159. data/lib/prawn/document.rb +573 -0
  160. data/lib/prawn/document/bounding_box.rb +425 -0
  161. data/lib/prawn/document/graphics_state.rb +48 -0
  162. data/lib/prawn/document/internals.rb +170 -0
  163. data/lib/prawn/document/page_geometry.rb +136 -0
  164. data/lib/prawn/document/snapshot.rb +87 -0
  165. data/lib/prawn/document_builder.rb +51 -0
  166. data/lib/prawn/document_builder/command.rb +38 -0
  167. data/lib/prawn/document_builder/constructs.rb +2 -0
  168. data/lib/prawn/document_builder/constructs/flowing_text_construct.rb +18 -0
  169. data/lib/prawn/document_builder/constructs/path_construct.rb +9 -0
  170. data/lib/prawn/document_builder/layout.rb +25 -0
  171. data/lib/prawn/document_builder/modifications.rb +2 -0
  172. data/lib/prawn/document_builder/modifications/layout_modification.rb +9 -0
  173. data/lib/prawn/document_builder/modifications/path_modification.rb +9 -0
  174. data/lib/prawn/encoding.rb +121 -0
  175. data/lib/prawn/errors.rb +94 -0
  176. data/lib/prawn/font.rb +341 -0
  177. data/lib/prawn/font/afm.rb +225 -0
  178. data/lib/prawn/font/dfont.rb +42 -0
  179. data/lib/prawn/font/ttf.rb +350 -0
  180. data/lib/prawn/graphics.rb +325 -0
  181. data/lib/prawn/graphics/cap_style.rb +38 -0
  182. data/lib/prawn/graphics/color.rb +205 -0
  183. data/lib/prawn/graphics/dash.rb +71 -0
  184. data/lib/prawn/graphics/join_style.rb +38 -0
  185. data/lib/prawn/graphics/transformation.rb +156 -0
  186. data/lib/prawn/graphics/transparency.rb +99 -0
  187. data/lib/prawn/images.rb +348 -0
  188. data/lib/prawn/images/jpg.rb +46 -0
  189. data/lib/prawn/images/png.rb +226 -0
  190. data/lib/prawn/measurement_extensions.rb +46 -0
  191. data/lib/prawn/measurements.rb +71 -0
  192. data/lib/prawn/outline.rb +278 -0
  193. data/lib/prawn/repeater.rb +129 -0
  194. data/lib/prawn/security.rb +262 -0
  195. data/lib/prawn/security/arcfour.rb +51 -0
  196. data/lib/prawn/stamp.rb +126 -0
  197. data/lib/prawn/table.rb +421 -0
  198. data/lib/prawn/table/accessors.rb +180 -0
  199. data/lib/prawn/table/cell.rb +350 -0
  200. data/lib/prawn/table/cell/in_table.rb +27 -0
  201. data/lib/prawn/table/cell/subtable.rb +65 -0
  202. data/lib/prawn/table/cell/text.rb +125 -0
  203. data/lib/prawn/text.rb +449 -0
  204. data/lib/prawn/text/box.rb +392 -0
  205. data/lib/prawn/text/formatted.rb +4 -0
  206. data/lib/prawn/text/formatted/box.rb +228 -0
  207. data/lib/prawn/text/formatted/fragment.rb +181 -0
  208. data/lib/prawn/text/formatted/parser.rb +213 -0
  209. data/spec/annotations_spec.rb +90 -0
  210. data/spec/bounding_box_spec.rb +190 -0
  211. data/spec/cell_spec.rb +348 -0
  212. data/spec/destinations_spec.rb +15 -0
  213. data/spec/document_spec.rb +473 -0
  214. data/spec/font_spec.rb +324 -0
  215. data/spec/formatted_text_arranger_spec.rb +426 -0
  216. data/spec/formatted_text_box_spec.rb +756 -0
  217. data/spec/formatted_text_fragment_spec.rb +211 -0
  218. data/spec/graphics_spec.rb +446 -0
  219. data/spec/images_spec.rb +96 -0
  220. data/spec/inline_formatted_text_parser_spec.rb +502 -0
  221. data/spec/jpg_spec.rb +25 -0
  222. data/spec/line_wrap_spec.rb +341 -0
  223. data/spec/measurement_units_spec.rb +23 -0
  224. data/spec/name_tree_spec.rb +112 -0
  225. data/spec/object_store_spec.rb +160 -0
  226. data/spec/outline_spec.rb +269 -0
  227. data/spec/pdf_object_spec.rb +170 -0
  228. data/spec/png_spec.rb +237 -0
  229. data/spec/reference_spec.rb +82 -0
  230. data/spec/repeater_spec.rb +96 -0
  231. data/spec/security_spec.rb +120 -0
  232. data/spec/snapshot_spec.rb +138 -0
  233. data/spec/spec_helper.rb +26 -0
  234. data/spec/stamp_spec.rb +108 -0
  235. data/spec/stroke_styles_spec.rb +163 -0
  236. data/spec/table_spec.rb +598 -0
  237. data/spec/template_spec.rb +158 -0
  238. data/spec/text_at_spec.rb +119 -0
  239. data/spec/text_box_spec.rb +742 -0
  240. data/spec/text_spacing_spec.rb +75 -0
  241. data/spec/text_spec.rb +333 -0
  242. data/spec/text_with_inline_formatting_spec.rb +193 -0
  243. data/spec/transparency_spec.rb +89 -0
  244. metadata +331 -0
@@ -0,0 +1,51 @@
1
+ # coding: utf-8
2
+ #
3
+ # Why would we ever use Ruby 1.8.7 when we can backport with something
4
+ # as simple as this?
5
+ #
6
+ class String #:nodoc:
7
+ def first_line
8
+ self.each_line { |line| return line }
9
+ end
10
+ unless "".respond_to?(:lines)
11
+ alias_method :lines, :to_a
12
+ end
13
+ unless "".respond_to?(:each_char)
14
+ def each_char #:nodoc:
15
+ # copied from jcode
16
+ if block_given?
17
+ scan(/./m) { |x| yield x }
18
+ else
19
+ scan(/./m)
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ unless File.respond_to?(:binread)
26
+ def File.binread(file) #:nodoc:
27
+ File.open(file,"rb") { |f| f.read }
28
+ end
29
+ end
30
+
31
+ if RUBY_VERSION < "1.9"
32
+
33
+ def ruby_18 #:nodoc:
34
+ yield
35
+ end
36
+
37
+ def ruby_19 #:nodoc:
38
+ false
39
+ end
40
+
41
+ else
42
+
43
+ def ruby_18 #:nodoc:
44
+ false
45
+ end
46
+
47
+ def ruby_19 #:nodoc:
48
+ yield
49
+ end
50
+
51
+ end
@@ -0,0 +1,85 @@
1
+ # encoding: utf-8
2
+ # Prawn : A library for PDF generation in Ruby
3
+ #
4
+ # Copyright April 2008, Gregory Brown. All Rights Reserved.
5
+ #
6
+ # This is free software. Please see the LICENSE and COPYING files for details.
7
+
8
+ require "set"
9
+
10
+ %w[ttfunk/lib].each do |dep|
11
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + "/../../vendor/#{dep}")
12
+ end
13
+
14
+ begin
15
+ require 'ttfunk'
16
+ rescue LoadError
17
+ puts "Failed to load ttfunk. If you are running Prawn from git:"
18
+ puts " git submodule init"
19
+ puts " git submodule update"
20
+ exit
21
+ end
22
+
23
+ module Prawn
24
+ extend self
25
+
26
+ file = __FILE__
27
+ file = File.readlink(file) if File.symlink?(file)
28
+ dir = File.dirname(file)
29
+
30
+ # The base source directory for Prawn as installed on the system
31
+ #
32
+ BASEDIR = File.expand_path(File.join(dir, '..', '..'))
33
+
34
+ # Whe set to true, Prawn will verify hash options to ensure only valid keys
35
+ # are used. Off by default.
36
+ #
37
+ # Example:
38
+ # >> Prawn::Document.new(:tomato => "Juicy")
39
+ # Prawn::Errors::UnknownOption:
40
+ # Detected unknown option(s): [:tomato]
41
+ # Accepted options are: [:page_size, :page_layout, :left_margin, ...]
42
+ #
43
+ attr_accessor :debug
44
+
45
+ def verify_options(accepted, actual) #:nodoc:
46
+ return unless debug || $DEBUG
47
+ unless (act=Set[*actual.keys]).subset?(acc=Set[*accepted])
48
+ raise Prawn::Errors::UnknownOption,
49
+ "\nDetected unknown option(s): #{(act - acc).to_a.inspect}\n" <<
50
+ "Accepted options are: #{accepted.inspect}"
51
+ end
52
+ yield if block_given?
53
+ end
54
+
55
+ module Configurable #:nodoc:
56
+ def configuration(*args)
57
+ @config ||= Marshal.load(Marshal.dump(default_configuration))
58
+ if Hash === args[0]
59
+ @config.update(args[0])
60
+ elsif args.length > 1
61
+ @config.values_at(*args)
62
+ elsif args.length == 1
63
+ @config[args[0]]
64
+ else
65
+ @config
66
+ end
67
+ end
68
+
69
+ alias_method :C, :configuration
70
+ end
71
+ end
72
+
73
+ require "prawn/compatibility"
74
+ require "prawn/errors"
75
+ require "prawn/core/pdf_object"
76
+ require "prawn/core/reference"
77
+ require "prawn/core/page"
78
+ require "prawn/core/object_store"
79
+ require "prawn/core/document_state"
80
+ require "prawn/core/literal_string"
81
+ require "prawn/core/byte_string"
82
+ require "prawn/core/name_tree"
83
+ require "prawn/core/annotations"
84
+ require "prawn/core/destinations"
85
+ require "prawn/core/chunk"
@@ -0,0 +1,61 @@
1
+ # encoding: utf-8
2
+
3
+ # annotations.rb : Implements low-level annotation 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
+ module Prawn
10
+ module Core
11
+
12
+ # Provides very low-level support for annotations.
13
+ #
14
+ module Annotations #:nodoc:
15
+
16
+ # Adds a new annotation (section 8.4 in PDF spec) to the current page.
17
+ # +options+ must be a Hash describing the annotation.
18
+ #
19
+ def annotate(options)
20
+ state.page.dictionary.data[:Annots] ||= []
21
+ options = sanitize_annotation_hash(options)
22
+ state.page.dictionary.data[:Annots] << ref!(options)
23
+ return options
24
+ end
25
+
26
+ # A convenience method for creating Text annotations. +rect+ must be an array
27
+ # of four numbers, describing the bounds of the annotation. +contents+ should
28
+ # be a string, to be shown when the annotation is activated.
29
+ #
30
+ def text_annotation(rect, contents, options={})
31
+ options = options.merge(:Subtype => :Text, :Rect => rect, :Contents => contents)
32
+ annotate(options)
33
+ end
34
+
35
+ # A convenience method for creating Link annotations. +rect+ must be an array
36
+ # of four numbers, describing the bounds of the annotation. The +options+ hash
37
+ # should include either :Dest (describing the target destination, usually as a
38
+ # string that has been recorded in the document's Dests tree), or :A (describing
39
+ # an action to perform on clicking the link), or :PA (for describing a URL to
40
+ # link to).
41
+ #
42
+ def link_annotation(rect, options={})
43
+ options = options.merge(:Subtype => :Link, :Rect => rect)
44
+ annotate(options)
45
+ end
46
+
47
+ private
48
+
49
+ def sanitize_annotation_hash(options)
50
+ options = options.merge(:Type => :Annot)
51
+
52
+ if options[:Dest].is_a?(String)
53
+ options[:Dest] = Prawn::Core::LiteralString.new(options[:Dest])
54
+ end
55
+
56
+ options
57
+ end
58
+
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,9 @@
1
+ # encoding: utf-8
2
+ module Prawn
3
+ module Core
4
+ # This is used to differentiate strings that must be encoded as
5
+ # a byte string, such as binary data from encrypted strings.
6
+ class ByteString < String #:nodoc:
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,36 @@
1
+ module Prawn
2
+ module Core
3
+ class Chunk
4
+ def initialize(command, params={}, &action)
5
+ @command = command
6
+ @params = params
7
+ @action = action
8
+ end
9
+
10
+ attr_reader :command, :params, :action
11
+
12
+ def content
13
+ action.call(self)
14
+ end
15
+
16
+ def to_pdf
17
+ case results = content
18
+ when Array
19
+ results.map { |sub_chunk| sub_chunk.to_pdf }.join("\n")
20
+ when Prawn::Core::Chunk
21
+ results.to_pdf
22
+ else
23
+ results
24
+ end
25
+ end
26
+
27
+ def [](attr)
28
+ @params[attr]
29
+ end
30
+
31
+ def []=(attr, value)
32
+ @params[attr] = value
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,90 @@
1
+ # encoding: utf-8
2
+
3
+ # prawn/core/destinations.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
+ module Prawn
10
+ module Core
11
+ module Destinations #:nodoc:
12
+
13
+ # The maximum number of children to fit into a single node in the Dests tree.
14
+ NAME_TREE_CHILDREN_LIMIT = 20 #:nodoc:
15
+
16
+ # The Dests name tree in the Name dictionary (see Prawn::Document::Internal#names).
17
+ # This name tree is used to store named destinations (PDF spec 8.2.1).
18
+ # (For more on name trees, see section 3.8.4 in the PDF spec.)
19
+ #
20
+ def dests
21
+ names.data[:Dests] ||= ref!(Prawn::Core::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
+ #
28
+ def add_dest(name, reference)
29
+ reference = ref!(reference) unless reference.is_a?(Prawn::Core::Reference)
30
+ dests.data.add(name, reference)
31
+ end
32
+
33
+ # Return a Dest specification for a specific location (and optional zoom
34
+ # level).
35
+ #
36
+ def dest_xyz(left, top, zoom=nil, page=current_page)
37
+ [page, :XYZ, left, top, zoom]
38
+ end
39
+
40
+ # Return a Dest specification that will fit the given page into the
41
+ # viewport.
42
+ #
43
+ def dest_fit(page=current_page)
44
+ [page, :Fit]
45
+ end
46
+
47
+ # Return a Dest specification that will fit the given page horizontally
48
+ # into the viewport, aligned vertically at the given top coordinate.
49
+ #
50
+ def dest_fit_horizontally(top, page=current_page)
51
+ [page, :FitH, top]
52
+ end
53
+
54
+ # Return a Dest specification that will fit the given page vertically
55
+ # into the viewport, aligned horizontally at the given left coordinate.
56
+ #
57
+ def dest_fit_vertically(left, page=current_page)
58
+ [page, :FitV, left]
59
+ end
60
+
61
+ # Return a Dest specification that will fit the given rectangle into the
62
+ # viewport, for the given page.
63
+ #
64
+ def dest_fit_rect(left, bottom, right, top, page=current_page)
65
+ [page, :FitR, left, bottom, right, top]
66
+ end
67
+
68
+ # Return a Dest specfication that will fit the given page's bounding box
69
+ # into the viewport.
70
+ #
71
+ def dest_fit_bounds(page=current_page)
72
+ [page, :FitB]
73
+ end
74
+
75
+ # Same as #dest_fit_horizontally, but works on the page's bounding box
76
+ # instead of the entire page.
77
+ #
78
+ def dest_fit_bounds_horizontally(top, page=current_page)
79
+ [page, :FitBH, top]
80
+ end
81
+
82
+ # Same as #dest_fit_vertically, but works on the page's bounding box
83
+ # instead of the entire page.
84
+ #
85
+ def dest_fit_bounds_vertically(left, page=current_page)
86
+ [page, :FitBV, left]
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,78 @@
1
+ module Prawn
2
+ module Core
3
+ class DocumentState #:nodoc:
4
+ def initialize(options)
5
+ normalize_metadata(options)
6
+
7
+ if options[:template]
8
+ @store = Prawn::Core::ObjectStore.new(:template => options[:template])
9
+ else
10
+ @store = Prawn::Core::ObjectStore.new(:info => options[:info])
11
+ end
12
+
13
+ @version = 1.3
14
+ @pages = []
15
+ @page = nil
16
+ @trailer = {}
17
+ @compress = options.fetch(:compress, false)
18
+ @encrypt = options.fetch(:encrypt, false)
19
+ @encryption_key = options[:encryption_key]
20
+ @optimize_objects = options.fetch(:optimize_objects, false)
21
+ @skip_encoding = options.fetch(:skip_encoding, false)
22
+ @before_render_callbacks = []
23
+ @on_page_create_callback = nil
24
+ end
25
+
26
+ attr_accessor :store, :version, :pages, :page, :trailer, :compress,
27
+ :encrypt, :encryption_key, :optimize_objects, :skip_encoding,
28
+ :before_render_callbacks, :on_page_create_callback
29
+
30
+ def populate_pages_from_store(document)
31
+ return 0 if @store.page_count <= 0 || @pages.size > 0
32
+
33
+ count = (1..@store.page_count)
34
+ @pages = count.map do |index|
35
+ orig_dict_id = @store.object_id_for_page(index)
36
+ Prawn::Core::Page.new(document, :object_id => orig_dict_id)
37
+ end
38
+
39
+ end
40
+
41
+ def normalize_metadata(options)
42
+ options[:info] ||= {}
43
+ options[:info][:Creator] ||= "Prawn"
44
+ options[:info][:Producer] = "Prawn"
45
+
46
+ info = options[:info]
47
+ end
48
+
49
+ def insert_page(page, page_number)
50
+ pages.insert(page_number, page)
51
+ store.pages.data[:Kids].insert(page_number, page.dictionary)
52
+ store.pages.data[:Count] += 1
53
+ end
54
+
55
+ def on_page_create_action(doc)
56
+ on_page_create_callback[doc] if on_page_create_callback
57
+ end
58
+
59
+ def before_render_actions(doc)
60
+ before_render_callbacks.each{ |c| c.call(self) }
61
+ end
62
+
63
+ def page_count
64
+ pages.length
65
+ end
66
+
67
+ def render_body(output)
68
+ store.compact if optimize_objects
69
+ store.each do |ref|
70
+ ref.offset = output.size
71
+ output << (@encrypt ? ref.encrypted_object(@encryption_key) :
72
+ ref.object)
73
+ end
74
+ end
75
+
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,16 @@
1
+ # encoding: utf-8
2
+ module Prawn
3
+ module Core
4
+ # This is used to differentiate strings that must be encoded as
5
+ # a *literal* string, versus those that can be encoded in
6
+ # the PDF hexadecimal format.
7
+ #
8
+ # Some features of the PDF format appear to require that literal
9
+ # strings be used. One such feature is the /Dest key of a link
10
+ # annotation; if a hex encoded string is used there, the links
11
+ # do not work (as tested in Mac OS X Preview, and Adobe Acrobat
12
+ # Reader).
13
+ class LiteralString < String #:nodoc:
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,165 @@
1
+ # encoding: utf-8
2
+
3
+ # name_tree.rb : Implements NameTree 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
+ module Prawn
10
+ module Core
11
+ module NameTree #:nodoc:
12
+ class Node #:nodoc:
13
+ attr_reader :children
14
+ attr_reader :limit
15
+ attr_reader :document
16
+ attr_accessor :parent
17
+ attr_accessor :ref
18
+
19
+ def initialize(document, limit, parent=nil)
20
+ @document = document
21
+ @children = []
22
+ @limit = limit
23
+ @parent = parent
24
+ @ref = nil
25
+ end
26
+
27
+ def empty?
28
+ children.empty?
29
+ end
30
+
31
+ def size
32
+ leaf? ? children.size : children.inject(0) { |sum, child| sum + child.size }
33
+ end
34
+
35
+ def leaf?
36
+ children.empty? || children.first.is_a?(Value)
37
+ end
38
+
39
+ def add(name, value)
40
+ self << Value.new(name, value)
41
+ end
42
+
43
+ def to_hash
44
+ hash = {}
45
+
46
+ hash[:Limits] = [least, greatest] if parent
47
+ if leaf?
48
+ hash[:Names] = children if leaf?
49
+ else
50
+ hash[:Kids] = children.map { |child| child.ref }
51
+ end
52
+
53
+ return hash
54
+ end
55
+
56
+ def least
57
+ if leaf?
58
+ children.first.name
59
+ else
60
+ children.first.least
61
+ end
62
+ end
63
+
64
+ def greatest
65
+ if leaf?
66
+ children.last.name
67
+ else
68
+ children.last.greatest
69
+ end
70
+ end
71
+
72
+ def <<(value)
73
+ if children.empty?
74
+ children << value
75
+ elsif leaf?
76
+ children.insert(insertion_point(value), value)
77
+ split! if children.length > limit
78
+ else
79
+ fit = children.detect { |child| child >= value }
80
+ fit = children.last unless fit
81
+ fit << value
82
+ end
83
+
84
+ value
85
+ end
86
+
87
+ def >=(value)
88
+ children.empty? || children.last >= value
89
+ end
90
+
91
+ def split!
92
+ if parent
93
+ parent.split(self)
94
+ else
95
+ left, right = new_node(self), new_node(self)
96
+ split_children(self, left, right)
97
+ children.replace([left, right])
98
+ end
99
+ end
100
+
101
+ protected
102
+
103
+ def split(node)
104
+ new_child = new_node(self)
105
+ split_children(node, node, new_child)
106
+ index = children.index(node)
107
+ children.insert(index+1, new_child)
108
+ split! if children.length > limit
109
+ end
110
+
111
+ private
112
+
113
+ def new_node(parent=nil)
114
+ node = Node.new(document, limit, parent)
115
+ node.ref = document.ref!(node)
116
+ return node
117
+ end
118
+
119
+ def split_children(node, left, right)
120
+ half = (node.limit+1)/2
121
+
122
+ left_children, right_children = node.children[0...half], node.children[half..-1]
123
+
124
+ left.children.replace(left_children)
125
+ right.children.replace(right_children)
126
+
127
+ unless node.leaf?
128
+ left_children.each { |child| child.parent = left }
129
+ right_children.each { |child| child.parent = right }
130
+ end
131
+ end
132
+
133
+ def insertion_point(value)
134
+ children.each_with_index do |child, index|
135
+ return index if child >= value
136
+ end
137
+ return children.length
138
+ end
139
+ end
140
+
141
+ class Value #:nodoc:
142
+ include Comparable
143
+
144
+ attr_reader :name
145
+ attr_reader :value
146
+
147
+ def initialize(name, value)
148
+ @name, @value = Prawn::Core::LiteralString.new(name), value
149
+ end
150
+
151
+ def <=>(leaf)
152
+ name <=> leaf.name
153
+ end
154
+
155
+ def inspect
156
+ "#<Value: #{name.inspect} : #{value.inspect}>"
157
+ end
158
+
159
+ def to_s
160
+ "#{name} : #{value}"
161
+ end
162
+ end
163
+ end
164
+ end
165
+ end