prawn 0.14.0 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +2 -1
  3. data/Rakefile +12 -0
  4. data/lib/prawn.rb +9 -21
  5. data/lib/prawn/document.rb +95 -68
  6. data/lib/prawn/document/bounding_box.rb +22 -4
  7. data/lib/prawn/document/column_box.rb +2 -0
  8. data/lib/prawn/document/graphics_state.rb +1 -1
  9. data/lib/prawn/document/internals.rb +2 -2
  10. data/lib/prawn/document/snapshot.rb +2 -1
  11. data/lib/prawn/document/span.rb +2 -0
  12. data/lib/prawn/encoding.rb +1 -1
  13. data/lib/prawn/font.rb +89 -75
  14. data/lib/prawn/font/afm.rb +3 -0
  15. data/lib/prawn/font/dfont.rb +1 -0
  16. data/lib/prawn/font/ttf.rb +2 -0
  17. data/lib/prawn/font_metric_cache.rb +3 -1
  18. data/lib/prawn/graphics.rb +2 -14
  19. data/lib/prawn/graphics/cap_style.rb +1 -0
  20. data/lib/prawn/graphics/color.rb +1 -0
  21. data/lib/prawn/graphics/dash.rb +3 -2
  22. data/lib/prawn/graphics/join_style.rb +2 -0
  23. data/lib/prawn/graphics/patterns.rb +1 -0
  24. data/lib/prawn/graphics/transformation.rb +1 -0
  25. data/lib/prawn/graphics/transparency.rb +2 -0
  26. data/lib/prawn/image_handler.rb +2 -0
  27. data/lib/prawn/images.rb +5 -0
  28. data/lib/prawn/images/image.rb +1 -0
  29. data/lib/prawn/images/jpg.rb +3 -0
  30. data/lib/prawn/images/png.rb +2 -0
  31. data/lib/prawn/layout.rb +8 -13
  32. data/lib/prawn/layout/grid.rb +15 -3
  33. data/lib/prawn/measurement_extensions.rb +4 -0
  34. data/lib/prawn/measurements.rb +2 -0
  35. data/lib/prawn/outline.rb +3 -1
  36. data/lib/prawn/repeater.rb +3 -1
  37. data/lib/prawn/security.rb +15 -7
  38. data/lib/prawn/security/arcfour.rb +52 -0
  39. data/lib/prawn/soft_mask.rb +3 -1
  40. data/lib/prawn/stamp.rb +2 -0
  41. data/lib/prawn/table.rb +2 -0
  42. data/lib/prawn/table/cell.rb +4 -1
  43. data/lib/prawn/table/cell/image.rb +1 -2
  44. data/lib/prawn/table/cell/in_table.rb +2 -0
  45. data/lib/prawn/table/cell/span_dummy.rb +1 -0
  46. data/lib/prawn/table/cells.rb +7 -2
  47. data/lib/prawn/table/column_width_calculator.rb +8 -2
  48. data/lib/prawn/text.rb +4 -2
  49. data/lib/prawn/text/box.rb +3 -0
  50. data/lib/prawn/text/formatted/arranger.rb +2 -0
  51. data/lib/prawn/text/formatted/box.rb +55 -50
  52. data/lib/prawn/text/formatted/fragment.rb +2 -0
  53. data/lib/prawn/text/formatted/line_wrap.rb +1 -0
  54. data/lib/prawn/text/formatted/parser.rb +2 -0
  55. data/lib/prawn/text/formatted/wrap.rb +2 -0
  56. data/lib/prawn/utilities.rb +5 -3
  57. data/manual/graphics/common_lines.rb +2 -0
  58. data/manual/text/group.rb +2 -0
  59. data/manual/text/text.rb +1 -1
  60. data/prawn.gemspec +4 -3
  61. data/spec/grid_spec.rb +11 -0
  62. data/spec/object_store_spec.rb +1 -96
  63. data/spec/reference_spec.rb +0 -57
  64. data/spec/spec_helper.rb +7 -0
  65. data/spec/table_spec.rb +26 -0
  66. metadata +172 -185
  67. data/lib/pdf/core.rb +0 -35
  68. data/lib/pdf/core/annotations.rb +0 -60
  69. data/lib/pdf/core/byte_string.rb +0 -9
  70. data/lib/pdf/core/destinations.rb +0 -90
  71. data/lib/pdf/core/document_state.rb +0 -79
  72. data/lib/pdf/core/filter_list.rb +0 -51
  73. data/lib/pdf/core/filters.rb +0 -36
  74. data/lib/pdf/core/graphics_state.rb +0 -89
  75. data/lib/pdf/core/literal_string.rb +0 -16
  76. data/lib/pdf/core/name_tree.rb +0 -177
  77. data/lib/pdf/core/object_store.rb +0 -311
  78. data/lib/pdf/core/outline.rb +0 -315
  79. data/lib/pdf/core/page.rb +0 -212
  80. data/lib/pdf/core/page_geometry.rb +0 -126
  81. data/lib/pdf/core/pdf_object.rb +0 -99
  82. data/lib/pdf/core/reference.rb +0 -103
  83. data/lib/pdf/core/stream.rb +0 -98
  84. data/lib/pdf/core/text.rb +0 -275
  85. data/lib/prawn/templates.rb +0 -75
  86. data/spec/filters_spec.rb +0 -34
  87. data/spec/name_tree_spec.rb +0 -112
  88. data/spec/pdf_object_spec.rb +0 -172
  89. data/spec/stream_spec.rb +0 -58
  90. data/spec/template_spec_obsolete.rb +0 -352
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d83c112e79d7d99ade30524585cf7d7cb7d4de52
4
- data.tar.gz: a0143b1b1ebf8db3776daafe04dbceeedb62db6b
3
+ metadata.gz: 97e70822529ce4c7edb736c4c57f2c6a015ddb02
4
+ data.tar.gz: 685b8386302414f80c7ac7a7c714987e0a8d2ff9
5
5
  SHA512:
6
- metadata.gz: 6f9ac40edd92c31df1f2a63e73684f983069edcb8f1dd15ffb26f9bcc85256ac4adc0f476aa6ef5b4fa2248318515c56a39dc68e5f2352711e30dd4863aa4989
7
- data.tar.gz: 7ecbae3e281cae29a8a7234fc32c0148eaae4d27dabc35cecba01073d28319c5480c50dcc1cce2f1bdb5b1c99b4a11e80168d62b8c7c94faa8a1a1f7995f0043
6
+ metadata.gz: dad2cab43e9fdda28fa1a4c364507fd7ecff16d2120a65b3c8ab9a07130d8c6fd73a6a9ae44a98be6faad680b20e894e9d6d1d8b88a870b824f08b9a5a28e527
7
+ data.tar.gz: 3c61667b13c7ed6aa815728ec777e8d12b04f7219184682d8b2b37d9fe046c942529c957f35597c3ccfe2a48131c701834d209a5cd77a454be9395e695450be3
data/.yardopts CHANGED
@@ -1,7 +1,8 @@
1
1
  --charset UTF-8
2
2
  --main README.md
3
3
  --title 'Prawn Documentation'
4
- lib/**/*.rb
4
+ --no-private
5
+ lib/prawn/**/*.rb
5
6
  -
6
7
  CONTRIBUTING.md
7
8
  COPYING
data/Rakefile CHANGED
@@ -40,3 +40,15 @@ Gem::PackageTask.new(spec) do |pkg|
40
40
  pkg.need_zip = true
41
41
  pkg.need_tar = true
42
42
  end
43
+
44
+ desc "Run a console with Prawn loaded"
45
+ task :console do
46
+ require 'irb'
47
+ require 'irb/completion'
48
+ require_relative 'lib/prawn'
49
+ Prawn.debug = true
50
+
51
+ ARGV.clear
52
+ IRB.start
53
+ end
54
+
@@ -1,26 +1,13 @@
1
1
  # Welcome to Prawn, the best PDF Generation library ever.
2
2
  # This documentation covers user level functionality.
3
3
  #
4
- # Those looking to contribute code or write extensions should look
5
- # into the lib/prawn/core/* source tree.
6
- #
7
- %w[ttfunk/lib].each do |dep|
8
- $LOAD_PATH.unshift(File.dirname(__FILE__) + "/../../vendor/#{dep}")
9
- end
10
-
11
- begin
12
- require 'ttfunk'
13
- rescue LoadError
14
- puts "Failed to load ttfunk. If you are running Prawn from git:"
15
- puts " git submodule init"
16
- puts " git submodule update"
17
- exit
18
- end
19
-
20
4
  require "set"
21
5
 
6
+ require 'ttfunk'
7
+ require "pdf/core"
8
+
22
9
  module Prawn
23
- VERSION = "0.14.0"
10
+ VERSION = "0.15.0"
24
11
 
25
12
  extend self
26
13
 
@@ -33,6 +20,8 @@ module Prawn
33
20
  #
34
21
  BASEDIR = File.expand_path(File.join(dir, '..'))
35
22
  DATADIR = File.expand_path(File.join(dir, '..', 'data'))
23
+
24
+ FLOAT_PRECISION = 1.0e-9
36
25
 
37
26
  # Whe set to true, Prawn will verify hash options to ensure only valid keys
38
27
  # are used. Off by default.
@@ -43,9 +32,9 @@ module Prawn
43
32
  # Detected unknown option(s): [:tomato]
44
33
  # Accepted options are: [:page_size, :page_layout, :left_margin, ...]
45
34
  #
46
- attr_accessor :debug
35
+ attr_accessor :debug # @private
47
36
 
48
- def verify_options(accepted, actual) #:nodoc:
37
+ def verify_options(accepted, actual) # @private
49
38
  return unless debug || $DEBUG
50
39
  unless (act=Set[*actual.keys]).subset?(acc=Set[*accepted])
51
40
  raise Prawn::Errors::UnknownOption,
@@ -55,7 +44,7 @@ module Prawn
55
44
  yield if block_given?
56
45
  end
57
46
 
58
- module Configurable #:nodoc:
47
+ module Configurable # @private
59
48
  def configuration(*args)
60
49
  @config ||= Marshal.load(Marshal.dump(default_configuration))
61
50
  if Hash === args[0]
@@ -75,7 +64,6 @@ end
75
64
 
76
65
  require_relative "prawn/errors"
77
66
 
78
- require_relative "pdf/core"
79
67
 
80
68
  require_relative "prawn/utilities"
81
69
  require_relative "prawn/text"
@@ -7,6 +7,7 @@
7
7
  # This is free software. Please see the LICENSE and COPYING files for details.
8
8
 
9
9
  require "stringio"
10
+
10
11
  require_relative "document/bounding_box"
11
12
  require_relative "document/column_box"
12
13
  require_relative "document/internals"
@@ -62,6 +63,8 @@ module Prawn
62
63
  include Prawn::Stamp
63
64
  include Prawn::SoftMask
64
65
 
66
+ # @group Extension API
67
+
65
68
  # NOTE: We probably need to rethink the options validation system, but this
66
69
  # constant temporarily allows for extensions to modify the list.
67
70
 
@@ -90,14 +93,28 @@ module Prawn
90
93
  # party!
91
94
  # end
92
95
  #
96
+ #
93
97
  def self.extensions
94
98
  @extensions ||= []
95
99
  end
96
100
 
97
- def self.inherited(base) #:nodoc:
101
+ # @private
102
+ def self.inherited(base)
98
103
  extensions.each { |e| base.extensions << e }
99
104
  end
100
105
 
106
+ # @group Stable Attributes
107
+
108
+ attr_accessor :margin_box
109
+ attr_reader :margins, :y
110
+ attr_accessor :page_number
111
+
112
+ # @group Extension Attributes
113
+
114
+ attr_accessor :text_formatter
115
+
116
+ # @group Stable API
117
+
101
118
  # Creates and renders a PDF document.
102
119
  #
103
120
  # When using the implicit block form, Prawn will evaluate the block
@@ -215,27 +232,7 @@ module Prawn
215
232
  end
216
233
  end
217
234
 
218
- attr_accessor :margin_box
219
- attr_reader :margins, :y
220
- attr_writer :font_size
221
- attr_accessor :page_number
222
- attr_accessor :text_formatter
223
-
224
- def state
225
- @internal_state
226
- end
227
-
228
- def page
229
- state.page
230
- end
231
-
232
- def initialize_first_page(options)
233
- if options[:skip_page_creation]
234
- start_new_page(options.merge(:orphan => true))
235
- else
236
- start_new_page(options)
237
- end
238
- end
235
+ # @group Stable API
239
236
 
240
237
  # Creates and advances to a new page in the document.
241
238
  #
@@ -356,6 +353,9 @@ module Prawn
356
353
  # Pass an open file descriptor to render to file.
357
354
  #
358
355
  def render(output = StringIO.new)
356
+ if output.instance_of?(StringIO)
357
+ output.set_encoding(::Encoding::ASCII_8BIT)
358
+ end
359
359
  finalize_all_page_contents
360
360
 
361
361
  render_header(output)
@@ -412,6 +412,7 @@ module Prawn
412
412
 
413
413
  # Returns the innermost non-stretchy bounding box.
414
414
  #
415
+ # @private
415
416
  def reference_bounds
416
417
  @bounding_box.reference_bounds
417
418
  end
@@ -497,47 +498,6 @@ module Prawn
497
498
  bounds.indent(left, right, &block)
498
499
  end
499
500
 
500
-
501
- def mask(*fields) # :nodoc:
502
- # Stores the current state of the named attributes, executes the block, and
503
- # then restores the original values after the block has executed.
504
- # -- I will remove the nodoc if/when this feature is a little less hacky
505
- stored = {}
506
- fields.each { |f| stored[f] = send(f) }
507
- yield
508
- fields.each { |f| send("#{f}=", stored[f]) }
509
- end
510
-
511
- # Attempts to group the given block vertically within the current context.
512
- # First attempts to render it in the current position on the current page.
513
- # If that attempt overflows, it is tried anew after starting a new context
514
- # (page or column). Returns a logically true value if the content fits in
515
- # one page/column, false if a new page or column was needed.
516
- #
517
- # Raises CannotGroup if the provided content is too large to fit alone in
518
- # the current page or column.
519
- #
520
- def group(second_attempt=false)
521
- old_bounding_box = @bounding_box
522
- @bounding_box = SimpleDelegator.new(@bounding_box)
523
-
524
- def @bounding_box.move_past_bottom
525
- raise RollbackTransaction
526
- end
527
-
528
- success = transaction { yield }
529
-
530
- @bounding_box = old_bounding_box
531
-
532
- unless success
533
- raise Prawn::Errors::CannotGroup if second_attempt
534
- old_bounding_box.move_past_bottom
535
- group(second_attempt=true) { yield }
536
- end
537
-
538
- success
539
- end
540
-
541
501
  # Places a text box on specified pages for page numbering. This should be called
542
502
  # towards the end of document creation, after all your content is already in
543
503
  # place. In your template string, <page> refers to the current page, and
@@ -610,6 +570,46 @@ module Prawn
610
570
  end
611
571
  end
612
572
 
573
+ # Returns true if content streams will be compressed before rendering,
574
+ # false otherwise
575
+ #
576
+ def compression_enabled?
577
+ !!state.compress
578
+ end
579
+
580
+ # @group Experimental API
581
+
582
+ # Attempts to group the given block vertically within the current context.
583
+ # First attempts to render it in the current position on the current page.
584
+ # If that attempt overflows, it is tried anew after starting a new context
585
+ # (page or column). Returns a logically true value if the content fits in
586
+ # one page/column, false if a new page or column was needed.
587
+ #
588
+ # Raises CannotGroup if the provided content is too large to fit alone in
589
+ # the current page or column.
590
+ #
591
+ def group(second_attempt=false)
592
+ old_bounding_box = @bounding_box
593
+ @bounding_box = SimpleDelegator.new(@bounding_box)
594
+
595
+ # @private
596
+ def @bounding_box.move_past_bottom
597
+ raise RollbackTransaction
598
+ end
599
+
600
+ success = transaction { yield }
601
+
602
+ @bounding_box = old_bounding_box
603
+
604
+ unless success
605
+ raise Prawn::Errors::CannotGroup if second_attempt
606
+ old_bounding_box.move_past_bottom
607
+ group(second_attempt=true) { yield }
608
+ end
609
+
610
+ success
611
+ end
612
+
613
613
  # Provides a way to execute a block of code repeatedly based on a
614
614
  # page_filter.
615
615
  #
@@ -635,16 +635,43 @@ module Prawn
635
635
  end
636
636
  end
637
637
 
638
+ # @private
639
+
640
+ def mask(*fields)
641
+ # Stores the current state of the named attributes, executes the block, and
642
+ # then restores the original values after the block has executed.
643
+ # -- I will remove the nodoc if/when this feature is a little less hacky
644
+ stored = {}
645
+ fields.each { |f| stored[f] = send(f) }
646
+ yield
647
+ fields.each { |f| send("#{f}=", stored[f]) }
648
+ end
638
649
 
639
- # Returns true if content streams will be compressed before rendering,
640
- # false otherwise
641
- #
642
- def compression_enabled?
643
- !!state.compress
650
+ # @group Extension API
651
+
652
+ def initialize_first_page(options)
653
+ if options[:skip_page_creation]
654
+ start_new_page(options.merge(:orphan => true))
655
+ else
656
+ start_new_page(options)
657
+ end
658
+ end
659
+
660
+ ## Internals. Don't depend on them!
661
+
662
+ # @private
663
+ def state
664
+ @internal_state
665
+ end
666
+
667
+ # @private
668
+ def page
669
+ state.page
644
670
  end
645
671
 
646
672
  private
647
673
 
674
+
648
675
  # setting override_settings to true ensures that a new graphic state does not end up using
649
676
  # previous settings.
650
677
  def use_graphic_settings(override_settings = false)
@@ -8,6 +8,7 @@
8
8
 
9
9
  module Prawn
10
10
  class Document
11
+ # @group Stable API
11
12
 
12
13
  # :call-seq:
13
14
  # bounding_box(point, options={}, &block)
@@ -219,7 +220,7 @@ module Prawn
219
220
  #
220
221
  class BoundingBox
221
222
 
222
- def initialize(document, parent, point, options={}) #:nodoc:
223
+ def initialize(document, parent, point, options={}) # @private
223
224
  unless options[:width]
224
225
  raise ArgumentError, "BoundingBox needs the :width option to be set"
225
226
  end
@@ -233,15 +234,22 @@ module Prawn
233
234
  @stretched_height = nil
234
235
  end
235
236
 
237
+ # @private
238
+
236
239
  attr_reader :document, :parent
240
+
241
+ # @private
237
242
  # The current indentation of the left side of the bounding box.
238
243
  attr_reader :total_left_padding
244
+
245
+ # @private
239
246
  # The current indentation of the right side of the bounding box.
240
247
  attr_reader :total_right_padding
241
248
 
242
249
  # The translated origin (x,y-height) which describes the location
243
250
  # of the bottom left corner of the bounding box
244
251
  #
252
+ # @private
245
253
  def anchor
246
254
  [@x, @y - height]
247
255
  end
@@ -272,6 +280,7 @@ module Prawn
272
280
  # text "indented on both sides"
273
281
  # end
274
282
  #
283
+ # @private
275
284
  def indent(left_padding, right_padding = 0, &block)
276
285
  add_left_padding(left_padding)
277
286
  add_right_padding(right_padding)
@@ -282,6 +291,7 @@ module Prawn
282
291
  end
283
292
 
284
293
  # Increase the left padding of the bounding box.
294
+ # @private
285
295
  def add_left_padding(left_padding)
286
296
  @total_left_padding += left_padding
287
297
  @x += left_padding
@@ -289,6 +299,7 @@ module Prawn
289
299
  end
290
300
 
291
301
  # Decrease the left padding of the bounding box.
302
+ # @private
292
303
  def subtract_left_padding(left_padding)
293
304
  @total_left_padding -= left_padding
294
305
  @x -= left_padding
@@ -296,12 +307,14 @@ module Prawn
296
307
  end
297
308
 
298
309
  # Increase the right padding of the bounding box.
310
+ # @private
299
311
  def add_right_padding(right_padding)
300
312
  @total_right_padding += right_padding
301
313
  @width -= right_padding
302
314
  end
303
315
 
304
316
  # Decrease the right padding of the bounding box.
317
+ # @private
305
318
  def subtract_right_padding(right_padding)
306
319
  @total_right_padding -= right_padding
307
320
  @width += right_padding
@@ -452,15 +465,19 @@ module Prawn
452
465
  end
453
466
 
454
467
  # an alias for absolute_left
468
+ # @private
455
469
  def left_side
456
470
  absolute_left
457
471
  end
458
472
 
459
473
  # an alias for absolute_right
474
+ # @private
460
475
  def right_side
461
476
  absolute_right
462
477
  end
463
478
 
479
+ # @group Extension API
480
+
464
481
  # Moves to the top of the next page of the document, starting a new page
465
482
  # if necessary.
466
483
  #
@@ -472,9 +489,6 @@ module Prawn
472
489
  end
473
490
  end
474
491
 
475
-
476
- alias_method :update_height, :height
477
-
478
492
  # Returns +false+ when the box has a defined height, +true+ when the height
479
493
  # is being calculated on the fly based on the current vertical position.
480
494
  #
@@ -493,9 +507,12 @@ module Prawn
493
507
  end
494
508
  end
495
509
 
510
+ alias_method :update_height, :height
511
+
496
512
  # Returns a deep copy of these bounds (including all parent bounds but
497
513
  # not copying the reference to the Document).
498
514
  #
515
+ # @private
499
516
  def deep_copy
500
517
  copy = dup
501
518
  # Deep-copy the parent bounds
@@ -510,6 +527,7 @@ module Prawn
510
527
  # context of the given +document+. Does *not* set the bounds of the
511
528
  # document to the resulting BoundingBox, only returns it.
512
529
  #
530
+ # @private
513
531
  def self.restore_deep_copy(bounds, document)
514
532
  bounds.instance_variable_set("@document", document)
515
533
  bounds