prawn 0.14.0 → 0.15.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 (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
@@ -10,6 +10,7 @@ require 'digest/sha1'
10
10
  module Prawn
11
11
  module Images
12
12
  class Image
13
+ # @group Extension API
13
14
 
14
15
  def calc_image_dimensions(options)
15
16
  w = options[:width] || width
@@ -10,10 +10,13 @@ require 'stringio'
10
10
 
11
11
  module Prawn
12
12
  module Images
13
+
13
14
  # A convenience class that wraps the logic for extracting the parts
14
15
  # of a JPG image that we need to embed them in a PDF
15
16
  #
16
17
  class JPG < Image
18
+ # @group Extension API
19
+
17
20
  attr_reader :width, :height, :bits, :channels
18
21
  attr_accessor :scaled_width, :scaled_height
19
22
 
@@ -17,6 +17,8 @@ module Prawn
17
17
  # of a PNG image that we need to embed them in a PDF
18
18
  #
19
19
  class PNG < Image
20
+ # @group Extension API
21
+
20
22
  attr_reader :palette, :img_data, :transparency
21
23
  attr_reader :width, :height, :bits
22
24
  attr_reader :color_type, :compression_method, :filter_method
@@ -2,19 +2,14 @@ require_relative "table"
2
2
  require_relative "layout/grid"
3
3
 
4
4
  module Prawn
5
+ module Errors
5
6
 
6
- module Errors
7
+ # This error is raised when table data is malformed
8
+ #
9
+ InvalidTableData = Class.new(StandardError)
7
10
 
8
- # This error is raised when table data is malformed
9
- #
10
- InvalidTableData = Class.new(StandardError)
11
-
12
- # This error is raised when an empty or nil table is rendered
13
- #
14
- EmptyTable = Class.new(StandardError)
15
- end
16
-
17
- module Layout
18
-
19
- end
11
+ # This error is raised when an empty or nil table is rendered
12
+ #
13
+ EmptyTable = Class.new(StandardError)
14
+ end
20
15
  end
@@ -1,11 +1,18 @@
1
1
  module Prawn
2
2
  class Document
3
+ # @group Experimental API
3
4
 
4
5
  # Defines the grid system for a particular document. Takes the number of
5
6
  # rows and columns and the width to use for the gutter as the
6
7
  # keys :rows, :columns, :gutter, :row_gutter, :column_gutter
7
8
  #
9
+ # Note that a completely new grid object is built each time define_grid()
10
+ # is called. This means that all subsequent calls to grid() will use
11
+ # the newly defined Grid object -- grids are not nestable like
12
+ # bounding boxes are.
13
+
8
14
  def define_grid(options = {})
15
+ @boxes = nil
9
16
  @grid = Grid.new(self, options)
10
17
  end
11
18
 
@@ -33,6 +40,8 @@ module Prawn
33
40
 
34
41
  # A Grid represents the entire grid system of a Page and calculates
35
42
  # the column width and row height of the base box.
43
+ #
44
+ # @private
36
45
  class Grid
37
46
  attr_reader :pdf, :columns, :rows, :gutter, :row_gutter, :column_gutter
38
47
  def initialize(pdf, options = {}) # :nodoc:
@@ -86,7 +95,8 @@ module Prawn
86
95
  # A Grid object has methods that allow easy access to the coordinates of
87
96
  # its corners, which can be plugged into most existing prawnmethods.
88
97
  #
89
- class Box #:nodoc:
98
+ # @private
99
+ class GridBox
90
100
  attr_reader :pdf
91
101
 
92
102
  def initialize(pdf, i, j)
@@ -187,7 +197,9 @@ module Prawn
187
197
  end
188
198
 
189
199
  # A MultiBox is specified by 2 Boxes and spans the areas between.
190
- class MultiBox < Box #:nodoc:
200
+ #
201
+ # @private
202
+ class MultiBox < GridBox #:nodoc:
191
203
  def initialize(pdf, b1, b2)
192
204
  @pdf = pdf
193
205
  @bs = [b1, b2]
@@ -249,7 +261,7 @@ module Prawn
249
261
 
250
262
  private
251
263
  def single_box(i, j)
252
- Box.new(self, i, j)
264
+ GridBox.new(self, i, j)
253
265
  end
254
266
 
255
267
  def multi_box(b1, b2)
@@ -7,11 +7,15 @@
7
7
 
8
8
  require_relative 'measurements'
9
9
 
10
+ # @group Stable API
11
+
10
12
  class Numeric
11
13
  include Prawn::Measurements
12
14
  # prawns' basic unit is PostScript-Point
13
15
  # 72 points per inch
14
16
 
17
+ # @group Experimental API
18
+
15
19
  def mm
16
20
  return mm2pt(self)
17
21
  end
@@ -4,6 +4,8 @@
4
4
  # Copyright December 2008, Florian Witteler. All Rights Reserved.
5
5
  #
6
6
  module Prawn
7
+ # @group Stable API
8
+
7
9
  module Measurements
8
10
 
9
11
  # ============================================================================
@@ -5,12 +5,14 @@
5
5
  # Author Jonathan Greenberg
6
6
 
7
7
  require 'forwardable'
8
- require_relative "../pdf/core/outline"
8
+ require "pdf/core/outline"
9
9
 
10
10
  module Prawn
11
11
 
12
12
  class Document
13
13
 
14
+ # @group Experimental API
15
+
14
16
  # Lazily instantiates an Outline object for document. This is used as point of entry
15
17
  # to methods to build the outline tree.
16
18
  def outline
@@ -11,14 +11,16 @@
11
11
  module Prawn
12
12
 
13
13
  class Document
14
-
15
14
  # A list of all repeaters in the document.
16
15
  # See Document#repeat for details
17
16
  #
17
+ # @private
18
18
  def repeaters
19
19
  @repeaters ||= []
20
20
  end
21
21
 
22
+ # @group Experimental API
23
+
22
24
  # Provides a way to execute a block of code repeatedly based on a
23
25
  # page_filter. Since Stamp is used under the hood, this method is very space
24
26
  # efficient.
@@ -7,9 +7,10 @@
7
7
  # This is free software. Please see the LICENSE and COPYING files for details.
8
8
 
9
9
  require 'digest/md5'
10
- require 'rc4'
11
10
 
12
- require_relative '../pdf/core/byte_string'
11
+ require 'pdf/core/byte_string'
12
+
13
+ require 'prawn/security/arcfour'
13
14
 
14
15
  module Prawn
15
16
  class Document
@@ -19,6 +20,8 @@ module Prawn
19
20
  module Security
20
21
  include PDF::Core
21
22
 
23
+ # @group Experimental API
24
+
22
25
  # Encrypts the document, to protect confidential data or control
23
26
  # modifications to the document. The encryption algorithm used is
24
27
  # detailed in the PDF Reference 1.3, section 3.5 "Encryption", and it is
@@ -117,7 +120,7 @@ module Prawn
117
120
 
118
121
  # Compute the RC4 key from the extended key and perform the encryption
119
122
  rc4_key = Digest::MD5.digest(extended_key)[0, 10]
120
- RC4.new(rc4_key).encrypt(str)
123
+ Arcfour.new(rc4_key).encrypt(str)
121
124
  end
122
125
 
123
126
  private
@@ -187,13 +190,13 @@ module Prawn
187
190
  def owner_password_hash
188
191
  @owner_password_hash ||= begin
189
192
  key = Digest::MD5.digest(pad_password(@owner_password))[0, 5]
190
- RC4.new(key).encrypt(pad_password(@user_password))
193
+ Arcfour.new(key).encrypt(pad_password(@user_password))
191
194
  end
192
195
  end
193
196
 
194
197
  # The U (user) value in the encryption dictionary. Algorithm 3.4.
195
198
  def user_password_hash
196
- RC4.new(user_encryption_key).encrypt(PasswordPadding)
199
+ Arcfour.new(user_encryption_key).encrypt(PasswordPadding)
197
200
  end
198
201
 
199
202
  end
@@ -201,14 +204,17 @@ module Prawn
201
204
  end
202
205
  end
203
206
 
204
- module PDF #:nodoc:
207
+ # @private
208
+ module PDF
205
209
  module Core
206
210
  module_function
207
211
 
208
212
  # Like PdfObject, but returns an encrypted result if required.
209
213
  # For direct objects, requires the object identifier and generation number
210
214
  # from the indirect object referencing obj.
211
- def EncryptedPdfObject(obj, key, id, gen, in_content_stream=false)
215
+ #
216
+ # @private
217
+ def EncryptedPdfObject(obj, key, id, gen, in_content_stream=false)
212
218
  case obj
213
219
  when Array
214
220
  "[" << obj.map { |e|
@@ -248,6 +254,7 @@ module PDF #:nodoc:
248
254
  end
249
255
 
250
256
 
257
+ # @private
251
258
  class Stream
252
259
  def encrypted_object(key, id, gen)
253
260
  if filtered_stream
@@ -258,6 +265,7 @@ module PDF #:nodoc:
258
265
  end
259
266
  end
260
267
 
268
+ # @private
261
269
  class Reference
262
270
 
263
271
  # Returns the object definition for the object this references, keyed from
@@ -0,0 +1,52 @@
1
+ # Implementation of the "ARCFOUR" algorithm ("alleged RC4 (tm)"). Implemented
2
+ # as described at:
3
+ # http://www.mozilla.org/projects/security/pki/nss/draft-kaukonen-cipher-arcfour-03.txt
4
+ #
5
+ # "RC4" is a trademark of RSA Data Security, Inc.
6
+ #
7
+ # Copyright August 2009, Brad Ediger. All Rights Reserved.
8
+ #
9
+ # This is free software. Please see the LICENSE and COPYING files for details.
10
+
11
+ # @private
12
+ class Arcfour
13
+ def initialize(key)
14
+ # Convert string key to Array of integers
15
+ key = key.unpack('c*') if key.is_a?(String)
16
+
17
+ # 1. Allocate an 256 element array of 8 bit bytes to be used as an S-box
18
+ # 2. Initialize the S-box. Fill each entry first with it's index
19
+ @sbox = (0..255).to_a
20
+
21
+ # 3. Fill another array of the same size (256) with the key, repeating
22
+ # bytes as necessary.
23
+ s2 = []
24
+ while s2.length < 256
25
+ s2 += key
26
+ end
27
+ s2 = s2[0, 256]
28
+
29
+ # 4. Set j to zero and initialize the S-box
30
+ j = 0
31
+ (0..255).each do |i|
32
+ j = (j + @sbox[i] + s2[i]) % 256
33
+ @sbox[i], @sbox[j] = @sbox[j], @sbox[i]
34
+ end
35
+
36
+ @i = @j = 0
37
+ end
38
+
39
+ def encrypt(string)
40
+ string.unpack('c*').map{|byte| byte ^ key_byte}.pack('c*')
41
+ end
42
+
43
+ private
44
+
45
+ # Produces the next byte of key material in the stream (3.2 Stream Generation)
46
+ def key_byte
47
+ @i = (@i + 1) % 256
48
+ @j = (@j + @sbox[@i]) % 256
49
+ @sbox[@i], @sbox[@j] = @sbox[@j], @sbox[@i]
50
+ @sbox[(@sbox[@i] + @sbox[@j]) % 256]
51
+ end
52
+ end
@@ -10,7 +10,7 @@
10
10
  module Prawn
11
11
 
12
12
  # The Prawn::SoftMask module is used to create arbitrary transparency in
13
- # document. Using a soft mask allows creaing more visually rich documents.
13
+ # document. Using a soft mask allows creating more visually rich documents.
14
14
  #
15
15
  # You must group soft mask and graphics it's applied to under
16
16
  # save_graphics_state because soft mask is a part of graphic state in PDF.
@@ -26,6 +26,8 @@ module Prawn
26
26
  # end
27
27
  #
28
28
  module SoftMask
29
+ # @group Stable API
30
+
29
31
  def soft_mask(&block)
30
32
  min_version(1.4)
31
33
 
@@ -28,6 +28,8 @@ module Prawn
28
28
  #
29
29
  module Stamp
30
30
 
31
+ # @group Stable API
32
+
31
33
  # Renders the stamp named <tt>name</tt> to the page
32
34
  # raises <tt>Prawn::Errors::InvalidName</tt> if name.empty?
33
35
  # raises <tt>Prawn::Errors::UndefinedObjectName</tt> if no stamp
@@ -19,6 +19,8 @@ module Prawn
19
19
 
20
20
  class Document
21
21
 
22
+ # @group Experimental API
23
+
22
24
  # Set up and draw a table on this document. A block can be given, which will
23
25
  # be run after cell setup but before layout and drawing.
24
26
  #
@@ -10,6 +10,8 @@ require 'date'
10
10
  module Prawn
11
11
  class Document
12
12
 
13
+ # @group Experimental API
14
+
13
15
  # Instantiates and draws a cell on the document.
14
16
  #
15
17
  # cell(:content => "Hello world!", :at => [12, 34])
@@ -151,7 +153,8 @@ module Prawn
151
153
  # this span group. They know their own width / height, but do not draw
152
154
  # anything.
153
155
  #
154
- attr_reader :dummy_cells # :nodoc:
156
+ # @private
157
+ attr_reader :dummy_cells
155
158
 
156
159
  # Instantiates a Cell based on the given options. The particular class of
157
160
  # cell returned depends on the :content argument. See the Prawn::Table
@@ -9,8 +9,7 @@ module Prawn
9
9
  class Table
10
10
  class Cell
11
11
 
12
- # A Cell that contains another table.
13
- #
12
+ # @private
14
13
  class Image < Cell
15
14
 
16
15
  def initialize(pdf, point, options={})
@@ -4,6 +4,8 @@
4
4
 
5
5
  module Prawn
6
6
  class Table
7
+
8
+ # @private
7
9
  class Cell
8
10
 
9
11
  # This module extends Cell objects when they are used in a table (as
@@ -12,6 +12,7 @@ module Prawn
12
12
  # A Cell object used to represent all but the topmost cell in a span
13
13
  # group.
14
14
  #
15
+ # @private
15
16
  class SpanDummy < Cell
16
17
  def initialize(pdf, master_cell)
17
18
  super(pdf, [0, pdf.cursor])
@@ -8,7 +8,6 @@
8
8
 
9
9
  module Prawn
10
10
  class Table
11
-
12
11
  # Selects the given rows (0-based) for styling. Returns a Cells object --
13
12
  # see the documentation on Cells for things you can do with cells.
14
13
  #
@@ -38,6 +37,8 @@ module Prawn
38
37
  #
39
38
  class Cells < Array
40
39
 
40
+ # @group Experimental API
41
+
41
42
  # Limits selection to the given row or rows. +row_spec+ can be anything
42
43
  # that responds to the === operator selecting a set of 0-based row
43
44
  # numbers; most commonly a number or a range.
@@ -254,7 +255,11 @@ module Prawn
254
255
 
255
256
  #calculate future return value
256
257
  new_sum = cell.send(meth) * cell.colspan
257
- spanned_width_needs_fixing = (new_sum > old_sum)
258
+
259
+ #due to float rounding errors we need to ignore a small difference in the new
260
+ #and the old sum the same had to be done in
261
+ #the column_width_calculator#natural_width
262
+ spanned_width_needs_fixing = ((new_sum - old_sum) > Prawn::FLOAT_PRECISION)
258
263
 
259
264
  if spanned_width_needs_fixing
260
265
  #not entirely sure why we need this line, but with it the tests pass
@@ -1,6 +1,7 @@
1
1
  module Prawn
2
2
  class Table
3
- class ColumnWidthCalculator
3
+ # @private
4
+ class ColumnWidthCalculator
4
5
  def initialize(cells)
5
6
  @cells = cells
6
7
 
@@ -37,7 +38,12 @@ module Prawn
37
38
  .collect{|key, value| value}.inject(0, :+)
38
39
 
39
40
  #update the Hash only if the new with is at least equal to the old one
40
- if cell.width.to_f > current_width_of_spanned_cells
41
+ #due to arithmetic errors we need to ignore a small difference in the new and the old sum
42
+ #the same had to be done in the column_widht_calculator#natural_width
43
+ update_hash = ((cell.width.to_f - current_width_of_spanned_cells) >
44
+ Prawn::FLOAT_PRECISION)
45
+
46
+ if update_hash
41
47
  # Split the width of colspanned cells evenly by columns
42
48
  width_per_column = cell.width.to_f / cell.colspan
43
49
  # Update the Hash