prawn 0.14.0 → 0.15.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardopts +2 -1
- data/Rakefile +12 -0
- data/lib/prawn.rb +9 -21
- data/lib/prawn/document.rb +95 -68
- data/lib/prawn/document/bounding_box.rb +22 -4
- data/lib/prawn/document/column_box.rb +2 -0
- data/lib/prawn/document/graphics_state.rb +1 -1
- data/lib/prawn/document/internals.rb +2 -2
- data/lib/prawn/document/snapshot.rb +2 -1
- data/lib/prawn/document/span.rb +2 -0
- data/lib/prawn/encoding.rb +1 -1
- data/lib/prawn/font.rb +89 -75
- data/lib/prawn/font/afm.rb +3 -0
- data/lib/prawn/font/dfont.rb +1 -0
- data/lib/prawn/font/ttf.rb +2 -0
- data/lib/prawn/font_metric_cache.rb +3 -1
- data/lib/prawn/graphics.rb +2 -14
- data/lib/prawn/graphics/cap_style.rb +1 -0
- data/lib/prawn/graphics/color.rb +1 -0
- data/lib/prawn/graphics/dash.rb +3 -2
- data/lib/prawn/graphics/join_style.rb +2 -0
- data/lib/prawn/graphics/patterns.rb +1 -0
- data/lib/prawn/graphics/transformation.rb +1 -0
- data/lib/prawn/graphics/transparency.rb +2 -0
- data/lib/prawn/image_handler.rb +2 -0
- data/lib/prawn/images.rb +5 -0
- data/lib/prawn/images/image.rb +1 -0
- data/lib/prawn/images/jpg.rb +3 -0
- data/lib/prawn/images/png.rb +2 -0
- data/lib/prawn/layout.rb +8 -13
- data/lib/prawn/layout/grid.rb +15 -3
- data/lib/prawn/measurement_extensions.rb +4 -0
- data/lib/prawn/measurements.rb +2 -0
- data/lib/prawn/outline.rb +3 -1
- data/lib/prawn/repeater.rb +3 -1
- data/lib/prawn/security.rb +15 -7
- data/lib/prawn/security/arcfour.rb +52 -0
- data/lib/prawn/soft_mask.rb +3 -1
- data/lib/prawn/stamp.rb +2 -0
- data/lib/prawn/table.rb +2 -0
- data/lib/prawn/table/cell.rb +4 -1
- data/lib/prawn/table/cell/image.rb +1 -2
- data/lib/prawn/table/cell/in_table.rb +2 -0
- data/lib/prawn/table/cell/span_dummy.rb +1 -0
- data/lib/prawn/table/cells.rb +7 -2
- data/lib/prawn/table/column_width_calculator.rb +8 -2
- data/lib/prawn/text.rb +4 -2
- data/lib/prawn/text/box.rb +3 -0
- data/lib/prawn/text/formatted/arranger.rb +2 -0
- data/lib/prawn/text/formatted/box.rb +55 -50
- data/lib/prawn/text/formatted/fragment.rb +2 -0
- data/lib/prawn/text/formatted/line_wrap.rb +1 -0
- data/lib/prawn/text/formatted/parser.rb +2 -0
- data/lib/prawn/text/formatted/wrap.rb +2 -0
- data/lib/prawn/utilities.rb +5 -3
- data/manual/graphics/common_lines.rb +2 -0
- data/manual/text/group.rb +2 -0
- data/manual/text/text.rb +1 -1
- data/prawn.gemspec +4 -3
- data/spec/grid_spec.rb +11 -0
- data/spec/object_store_spec.rb +1 -96
- data/spec/reference_spec.rb +0 -57
- data/spec/spec_helper.rb +7 -0
- data/spec/table_spec.rb +26 -0
- metadata +172 -185
- data/lib/pdf/core.rb +0 -35
- data/lib/pdf/core/annotations.rb +0 -60
- data/lib/pdf/core/byte_string.rb +0 -9
- data/lib/pdf/core/destinations.rb +0 -90
- data/lib/pdf/core/document_state.rb +0 -79
- data/lib/pdf/core/filter_list.rb +0 -51
- data/lib/pdf/core/filters.rb +0 -36
- data/lib/pdf/core/graphics_state.rb +0 -89
- data/lib/pdf/core/literal_string.rb +0 -16
- data/lib/pdf/core/name_tree.rb +0 -177
- data/lib/pdf/core/object_store.rb +0 -311
- data/lib/pdf/core/outline.rb +0 -315
- data/lib/pdf/core/page.rb +0 -212
- data/lib/pdf/core/page_geometry.rb +0 -126
- data/lib/pdf/core/pdf_object.rb +0 -99
- data/lib/pdf/core/reference.rb +0 -103
- data/lib/pdf/core/stream.rb +0 -98
- data/lib/pdf/core/text.rb +0 -275
- data/lib/prawn/templates.rb +0 -75
- data/spec/filters_spec.rb +0 -34
- data/spec/name_tree_spec.rb +0 -112
- data/spec/pdf_object_spec.rb +0 -172
- data/spec/stream_spec.rb +0 -58
- data/spec/template_spec_obsolete.rb +0 -352
data/lib/prawn/images/image.rb
CHANGED
data/lib/prawn/images/jpg.rb
CHANGED
@@ -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
|
|
data/lib/prawn/images/png.rb
CHANGED
@@ -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
|
data/lib/prawn/layout.rb
CHANGED
@@ -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
|
-
|
7
|
+
# This error is raised when table data is malformed
|
8
|
+
#
|
9
|
+
InvalidTableData = Class.new(StandardError)
|
7
10
|
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
data/lib/prawn/layout/grid.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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
|
data/lib/prawn/measurements.rb
CHANGED
data/lib/prawn/outline.rb
CHANGED
@@ -5,12 +5,14 @@
|
|
5
5
|
# Author Jonathan Greenberg
|
6
6
|
|
7
7
|
require 'forwardable'
|
8
|
-
|
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
|
data/lib/prawn/repeater.rb
CHANGED
@@ -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.
|
data/lib/prawn/security.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
data/lib/prawn/soft_mask.rb
CHANGED
@@ -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
|
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
|
|
data/lib/prawn/stamp.rb
CHANGED
data/lib/prawn/table.rb
CHANGED
data/lib/prawn/table/cell.rb
CHANGED
@@ -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
|
-
|
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
|
data/lib/prawn/table/cells.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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
|