prawn 2.1.0 → 2.2.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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +2 -0
- data.tar.gz.sig +0 -0
- data/Gemfile +1 -9
- data/Rakefile +12 -22
- data/lib/prawn.rb +29 -48
- data/lib/prawn/document.rb +148 -123
- data/lib/prawn/document/bounding_box.rb +33 -26
- data/lib/prawn/document/column_box.rb +5 -7
- data/lib/prawn/document/internals.rb +6 -6
- data/lib/prawn/document/span.rb +20 -17
- data/lib/prawn/encoding.rb +65 -67
- data/lib/prawn/errors.rb +10 -7
- data/lib/prawn/font.rb +78 -62
- data/lib/prawn/font/afm.rb +93 -66
- data/lib/prawn/font/dfont.rb +2 -10
- data/lib/prawn/font/ttc.rb +34 -0
- data/lib/prawn/font/ttf.rb +73 -65
- data/lib/prawn/font_metric_cache.rb +9 -8
- data/lib/prawn/graphics.rb +110 -70
- data/lib/prawn/graphics/blend_mode.rb +7 -8
- data/lib/prawn/graphics/cap_style.rb +2 -4
- data/lib/prawn/graphics/color.rb +23 -26
- data/lib/prawn/graphics/dash.rb +22 -12
- data/lib/prawn/graphics/join_style.rb +8 -4
- data/lib/prawn/graphics/patterns.rb +185 -96
- data/lib/prawn/graphics/transformation.rb +11 -9
- data/lib/prawn/graphics/transparency.rb +15 -13
- data/lib/prawn/grid.rb +20 -20
- data/lib/prawn/image_handler.rb +4 -6
- data/lib/prawn/images.rb +22 -15
- data/lib/prawn/images/image.rb +0 -1
- data/lib/prawn/images/jpg.rb +26 -22
- data/lib/prawn/images/png.rb +60 -57
- data/lib/prawn/measurement_extensions.rb +8 -9
- data/lib/prawn/measurements.rb +14 -15
- data/lib/prawn/outline.rb +96 -78
- data/lib/prawn/repeater.rb +12 -10
- data/lib/prawn/security.rb +66 -48
- data/lib/prawn/security/arcfour.rb +1 -3
- data/lib/prawn/soft_mask.rb +23 -25
- data/lib/prawn/stamp.rb +16 -12
- data/lib/prawn/text.rb +59 -45
- data/lib/prawn/text/box.rb +9 -8
- data/lib/prawn/text/formatted.rb +4 -6
- data/lib/prawn/text/formatted/arranger.rb +51 -30
- data/lib/prawn/text/formatted/box.rb +112 -88
- data/lib/prawn/text/formatted/fragment.rb +10 -15
- data/lib/prawn/text/formatted/line_wrap.rb +118 -61
- data/lib/prawn/text/formatted/parser.rb +134 -110
- data/lib/prawn/text/formatted/wrap.rb +42 -32
- data/lib/prawn/transformation_stack.rb +3 -4
- data/lib/prawn/utilities.rb +6 -21
- data/lib/prawn/version.rb +1 -3
- data/lib/prawn/view.rb +4 -2
- data/manual/basic_concepts/adding_pages.rb +4 -7
- data/manual/basic_concepts/basic_concepts.rb +29 -22
- data/manual/basic_concepts/creation.rb +8 -11
- data/manual/basic_concepts/cursor.rb +2 -5
- data/manual/basic_concepts/measurement.rb +3 -6
- data/manual/basic_concepts/origin.rb +3 -6
- data/manual/basic_concepts/other_cursor_helpers.rb +9 -12
- data/manual/basic_concepts/view.rb +20 -16
- data/manual/bounding_box/bounding_box.rb +27 -24
- data/manual/bounding_box/bounds.rb +9 -12
- data/manual/bounding_box/canvas.rb +2 -5
- data/manual/bounding_box/creation.rb +4 -7
- data/manual/bounding_box/indentation.rb +12 -15
- data/manual/bounding_box/nesting.rb +22 -17
- data/manual/bounding_box/russian_boxes.rb +8 -9
- data/manual/bounding_box/stretchy.rb +10 -13
- data/manual/contents.rb +26 -22
- data/manual/cover.rb +22 -20
- data/manual/document_and_page_options/background.rb +9 -13
- data/manual/document_and_page_options/document_and_page_options.rb +23 -20
- data/manual/document_and_page_options/metadata.rb +16 -16
- data/manual/document_and_page_options/page_margins.rb +16 -20
- data/manual/document_and_page_options/page_size.rb +11 -12
- data/manual/document_and_page_options/print_scaling.rb +15 -15
- data/manual/example_helper.rb +2 -4
- data/manual/graphics/blend_mode.rb +10 -9
- data/manual/graphics/circle_and_ellipse.rb +2 -5
- data/manual/graphics/color.rb +5 -9
- data/manual/graphics/common_lines.rb +5 -8
- data/manual/graphics/fill_and_stroke.rb +2 -5
- data/manual/graphics/fill_rules.rb +7 -10
- data/manual/graphics/gradients.rb +25 -21
- data/manual/graphics/graphics.rb +49 -43
- data/manual/graphics/helper.rb +10 -9
- data/manual/graphics/line_width.rb +5 -7
- data/manual/graphics/lines_and_curves.rb +5 -8
- data/manual/graphics/polygon.rb +4 -8
- data/manual/graphics/rectangle.rb +2 -5
- data/manual/graphics/rotate.rb +4 -7
- data/manual/graphics/scale.rb +12 -15
- data/manual/graphics/soft_masks.rb +1 -4
- data/manual/graphics/stroke_cap.rb +3 -6
- data/manual/graphics/stroke_dash.rb +9 -12
- data/manual/graphics/stroke_join.rb +2 -5
- data/manual/graphics/translate.rb +7 -10
- data/manual/graphics/transparency.rb +5 -8
- data/manual/how_to_read_this_manual.rb +4 -6
- data/manual/images/absolute_position.rb +4 -7
- data/manual/images/fit.rb +5 -8
- data/manual/images/horizontal.rb +6 -9
- data/manual/images/images.rb +25 -23
- data/manual/images/plain_image.rb +3 -6
- data/manual/images/scale.rb +7 -10
- data/manual/images/vertical.rb +10 -13
- data/manual/images/width_and_height.rb +8 -11
- data/manual/layout/boxes.rb +3 -6
- data/manual/layout/content.rb +5 -8
- data/manual/layout/layout.rb +16 -16
- data/manual/layout/simple_grid.rb +4 -7
- data/manual/outline/add_subsection_to.rb +18 -21
- data/manual/outline/insert_section_after.rb +13 -16
- data/manual/outline/outline.rb +19 -17
- data/manual/outline/sections_and_pages.rb +15 -18
- data/manual/repeatable_content/alternate_page_numbering.rb +19 -17
- data/manual/repeatable_content/page_numbering.rb +15 -16
- data/manual/repeatable_content/repeatable_content.rb +23 -19
- data/manual/repeatable_content/repeater.rb +12 -15
- data/manual/repeatable_content/stamp.rb +12 -15
- data/manual/security/encryption.rb +7 -10
- data/manual/security/permissions.rb +17 -14
- data/manual/security/security.rb +17 -16
- data/manual/table.rb +2 -4
- data/manual/text/alignment.rb +14 -17
- data/manual/text/color.rb +10 -11
- data/manual/text/column_box.rb +5 -8
- data/manual/text/fallback_fonts.rb +23 -21
- data/manual/text/font.rb +9 -12
- data/manual/text/font_size.rb +11 -14
- data/manual/text/font_style.rb +4 -7
- data/manual/text/formatted_callbacks.rb +23 -21
- data/manual/text/formatted_text.rb +31 -25
- data/manual/text/free_flowing_text.rb +18 -21
- data/manual/text/inline.rb +16 -19
- data/manual/text/kerning_and_character_spacing.rb +12 -15
- data/manual/text/leading.rb +5 -8
- data/manual/text/line_wrapping.rb +33 -17
- data/manual/text/paragraph_indentation.rb +11 -14
- data/manual/text/positioned_text.rb +13 -16
- data/manual/text/registering_families.rb +16 -19
- data/manual/text/rendering_and_color.rb +7 -10
- data/manual/text/right_to_left_text.rb +24 -19
- data/manual/text/rotation.rb +26 -23
- data/manual/text/single_usage.rb +6 -9
- data/manual/text/text.rb +56 -52
- data/manual/text/text_box_excess.rb +18 -17
- data/manual/text/text_box_extensions.rb +16 -15
- data/manual/text/text_box_overflow.rb +15 -18
- data/manual/text/utf8.rb +9 -12
- data/manual/text/win_ansi_charset.rb +18 -19
- data/prawn.gemspec +37 -27
- data/spec/extensions/encoding_helpers.rb +0 -2
- data/spec/manual_spec.rb +33 -0
- data/spec/prawn/document/bounding_box_spec.rb +546 -0
- data/spec/prawn/document/column_box_spec.rb +73 -0
- data/spec/prawn/document/security_spec.rb +173 -0
- data/spec/prawn/document_annotations_spec.rb +74 -0
- data/spec/prawn/document_destinations_spec.rb +13 -0
- data/spec/prawn/document_grid_spec.rb +96 -0
- data/spec/prawn/document_reference_spec.rb +25 -0
- data/spec/prawn/document_span_spec.rb +34 -0
- data/spec/prawn/document_spec.rb +751 -0
- data/spec/prawn/font_metric_cache_spec.rb +52 -0
- data/spec/prawn/font_spec.rb +513 -0
- data/spec/prawn/graphics/blend_mode_spec.rb +61 -0
- data/spec/prawn/graphics/transparency_spec.rb +79 -0
- data/spec/prawn/graphics_spec.rb +817 -0
- data/spec/prawn/graphics_stroke_styles_spec.rb +227 -0
- data/spec/{image_handler_spec.rb → prawn/image_handler_spec.rb} +13 -15
- data/spec/prawn/images/jpg_spec.rb +18 -0
- data/spec/prawn/images/png_spec.rb +281 -0
- data/spec/prawn/images_spec.rb +170 -0
- data/spec/prawn/measurements_extensions_spec.rb +22 -0
- data/spec/prawn/outline_spec.rb +408 -0
- data/spec/prawn/repeater_spec.rb +163 -0
- data/spec/prawn/soft_mask_spec.rb +72 -0
- data/spec/prawn/stamp_spec.rb +168 -0
- data/spec/prawn/text/box_spec.rb +1113 -0
- data/spec/prawn/text/formatted/arranger_spec.rb +464 -0
- data/spec/prawn/text/formatted/box_spec.rb +825 -0
- data/spec/prawn/text/formatted/fragment_spec.rb +341 -0
- data/spec/prawn/text/formatted/line_wrap_spec.rb +491 -0
- data/spec/prawn/text/formatted/parser_spec.rb +667 -0
- data/spec/prawn/text_draw_text_spec.rb +147 -0
- data/spec/prawn/text_rendering_mode_spec.rb +42 -0
- data/spec/prawn/text_spacing_spec.rb +93 -0
- data/spec/prawn/text_spec.rb +601 -0
- data/spec/prawn/text_with_inline_formatting_spec.rb +33 -0
- data/spec/{transformation_stack_spec.rb → prawn/transformation_stack_spec.rb} +21 -20
- data/spec/prawn/view_spec.rb +45 -0
- data/spec/spec_helper.rb +16 -16
- metadata +96 -151
- metadata.gz.sig +1 -0
- data/data/images/16bit.alpha +0 -0
- data/data/images/16bit.color +0 -0
- data/data/images/16bit.png +0 -0
- data/data/images/arrow.png +0 -0
- data/data/images/arrow2.png +0 -0
- data/data/images/blend_modes_bottom_layer.jpg +0 -0
- data/data/images/blend_modes_top_layer.jpg +0 -0
- data/data/images/dice.alpha +0 -0
- data/data/images/dice.color +0 -0
- data/data/images/dice.png +0 -0
- data/data/images/dice_interlaced.png +0 -0
- data/data/images/fractal.jpg +0 -0
- data/data/images/indexed_color.dat +0 -0
- data/data/images/indexed_color.png +0 -0
- data/data/images/indexed_transparency.png +0 -0
- data/data/images/indexed_transparency_alpha.dat +0 -0
- data/data/images/indexed_transparency_color.dat +0 -0
- data/data/images/letterhead.jpg +0 -0
- data/data/images/license.md +0 -8
- data/data/images/page_white_text.alpha +0 -0
- data/data/images/page_white_text.color +0 -0
- data/data/images/page_white_text.png +0 -0
- data/data/images/pigs.jpg +0 -0
- data/data/images/prawn.png +0 -0
- data/data/images/ruport.png +0 -0
- data/data/images/ruport_data.dat +0 -0
- data/data/images/ruport_transparent.png +0 -0
- data/data/images/ruport_type0.png +0 -0
- data/data/images/stef.jpg +0 -0
- data/data/images/tru256.bmp +0 -0
- data/data/images/web-links.dat +0 -1
- data/data/images/web-links.png +0 -0
- data/data/pdfs/complex_template.pdf +0 -0
- data/data/pdfs/contains_ttf_font.pdf +0 -0
- data/data/pdfs/encrypted.pdf +0 -0
- data/data/pdfs/form.pdf +1 -819
- data/data/pdfs/hexagon.pdf +0 -61
- data/data/pdfs/indirect_reference.pdf +0 -86
- data/data/pdfs/multipage_template.pdf +0 -127
- data/data/pdfs/nested_pages.pdf +0 -118
- data/data/pdfs/page_without_mediabox.pdf +0 -193
- data/data/pdfs/resources_as_indirect_object.pdf +0 -83
- data/data/pdfs/two_hexagons.pdf +0 -90
- data/data/pdfs/version_1_6.pdf +0 -61
- data/data/shift_jis_text.txt +0 -1
- data/spec/acceptance/png_spec.rb +0 -35
- data/spec/annotations_spec.rb +0 -67
- data/spec/blend_mode_spec.rb +0 -71
- data/spec/bounding_box_spec.rb +0 -501
- data/spec/column_box_spec.rb +0 -59
- data/spec/destinations_spec.rb +0 -13
- data/spec/document_spec.rb +0 -738
- data/spec/font_metric_cache_spec.rb +0 -52
- data/spec/font_spec.rb +0 -475
- data/spec/formatted_text_arranger_spec.rb +0 -452
- data/spec/formatted_text_box_spec.rb +0 -716
- data/spec/formatted_text_fragment_spec.rb +0 -299
- data/spec/graphics_spec.rb +0 -705
- data/spec/grid_spec.rb +0 -95
- data/spec/images_spec.rb +0 -167
- data/spec/inline_formatted_text_parser_spec.rb +0 -568
- data/spec/jpg_spec.rb +0 -23
- data/spec/line_wrap_spec.rb +0 -366
- data/spec/measurement_units_spec.rb +0 -22
- data/spec/outline_spec.rb +0 -409
- data/spec/png_spec.rb +0 -257
- data/spec/reference_spec.rb +0 -25
- data/spec/repeater_spec.rb +0 -154
- data/spec/security_spec.rb +0 -151
- data/spec/soft_mask_spec.rb +0 -78
- data/spec/span_spec.rb +0 -43
- data/spec/stamp_spec.rb +0 -179
- data/spec/stroke_styles_spec.rb +0 -208
- data/spec/text_at_spec.rb +0 -142
- data/spec/text_box_spec.rb +0 -1042
- data/spec/text_rendering_mode_spec.rb +0 -45
- data/spec/text_spacing_spec.rb +0 -93
- data/spec/text_spec.rb +0 -543
- data/spec/text_with_inline_formatting_spec.rb +0 -35
- data/spec/transparency_spec.rb +0 -91
- data/spec/view_spec.rb +0 -42
data/spec/manual_spec.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'digest/sha2'
|
3
|
+
|
4
|
+
# rubocop: disable Metrics/LineLength
|
5
|
+
MANUAL_HASH =
|
6
|
+
case RUBY_ENGINE
|
7
|
+
when 'ruby'
|
8
|
+
'b55f154c9093c60f38051c75920c8157c775b946b0c77ffafc0a8a634ad5401e8ceafd0b96942839f82bacd726a690af3fdd1fd9e185616f67c6c0edfcfd0460'
|
9
|
+
when 'jruby'
|
10
|
+
'd2eb71ea3ddc35acb185de671a6fa48862ebad5727ce372e3a742f45d31447765c4004fbe5fbfdc1f5a32903ac87182c75e6abe021ab003c8af6e6cc33e0d01e'
|
11
|
+
end
|
12
|
+
# rubocop: enable Metrics/LineLength
|
13
|
+
|
14
|
+
RSpec.describe Prawn do
|
15
|
+
describe 'manual' do
|
16
|
+
# JRuby's zlib is a bit quirky. It sometimes produces different output to
|
17
|
+
# libzlib (used by MRI). It's still a proper deflate stream and can be
|
18
|
+
# decompressed just fine but for whatever reason compressin produses
|
19
|
+
# different output.
|
20
|
+
#
|
21
|
+
# See: https://github.com/jruby/jruby/issues/4244
|
22
|
+
it 'contains no unexpected changes' do
|
23
|
+
ENV['CI'] ||= 'true'
|
24
|
+
|
25
|
+
require File.expand_path(File.join(__dir__, %w[.. manual contents]))
|
26
|
+
s = prawn_manual_document.render
|
27
|
+
|
28
|
+
hash = Digest::SHA512.hexdigest(s)
|
29
|
+
|
30
|
+
expect(hash).to eq MANUAL_HASH
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,546 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Prawn::Document::BoundingBox do
|
4
|
+
let(:pdf) { create_pdf }
|
5
|
+
let(:x) { 100 }
|
6
|
+
let(:y) { 125 }
|
7
|
+
let(:width) { 50 }
|
8
|
+
let(:height) { 75 }
|
9
|
+
let(:box) do
|
10
|
+
described_class.new(
|
11
|
+
nil,
|
12
|
+
nil,
|
13
|
+
[x, y],
|
14
|
+
width: width,
|
15
|
+
height: height
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'has an anchor at (x, y - height)' do
|
20
|
+
expect(box.anchor).to eq([x, y - height])
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'has a left boundary of 0' do
|
24
|
+
expect(box.left).to eq(0)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'has a right boundary equal to the width' do
|
28
|
+
expect(box.right).to eq(width)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'has a top boundary of height' do
|
32
|
+
expect(box.top).to eq(height)
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'has a bottom boundary of 0' do
|
36
|
+
expect(box.bottom).to eq(0)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'has a top-left of [0,height]' do
|
40
|
+
expect(box.top_left).to eq([0, height])
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'has a top-right of [width,height]' do
|
44
|
+
expect(box.top_right).to eq([width, height])
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'has a bottom-left of [0,0]' do
|
48
|
+
expect(box.bottom_left).to eq([0, 0])
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'has a bottom-right of [width,0]' do
|
52
|
+
expect(box.bottom_right).to eq([width, 0])
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'has an absolute left boundary of x' do
|
56
|
+
expect(box.absolute_left).to eq(x)
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'has an absolute right boundary of x + width' do
|
60
|
+
expect(box.absolute_right).to eq(x + width)
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'has an absolute top boundary of y' do
|
64
|
+
expect(box.absolute_top).to eq(y)
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'has an absolute bottom boundary of y - height' do
|
68
|
+
expect(box.absolute_bottom).to eq(y - height)
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'has an absolute bottom-left of [x,y-height]' do
|
72
|
+
expect(box.absolute_bottom_left).to eq([x, y - height])
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'has an absolute bottom-right of [x+width,y-height]' do
|
76
|
+
expect(box.absolute_bottom_right).to eq([x + width, y - height])
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'has an absolute top-left of [x,y]' do
|
80
|
+
expect(box.absolute_top_left).to eq([x, y])
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'has an absolute top-right of [x+width,y]' do
|
84
|
+
expect(box.absolute_top_right).to eq([x + width, y])
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'requires width to be set' do
|
88
|
+
expect do
|
89
|
+
described_class.new(nil, nil, [100, 100])
|
90
|
+
end.to raise_error(ArgumentError)
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'raise_errors an ArgumentError if a block is not passed' do
|
94
|
+
pdf = Prawn::Document.new
|
95
|
+
expect do
|
96
|
+
pdf.bounding_box([0, 0], width: 200)
|
97
|
+
end.to raise_error(ArgumentError)
|
98
|
+
end
|
99
|
+
|
100
|
+
describe 'drawing' do
|
101
|
+
it 'does not stomp on the arguments to bounding_box' do
|
102
|
+
pdf = Prawn::Document.new
|
103
|
+
x = [100, 500]
|
104
|
+
pdf.bounding_box x, width: 100 do
|
105
|
+
pdf.text 'bork-bork-bork'
|
106
|
+
end
|
107
|
+
expect(x).to eq([100, 500])
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'restores Document#bounds to the correct margin box on exit' do
|
111
|
+
pdf = Prawn::Document.new(margin: 200)
|
112
|
+
|
113
|
+
# add a multi-page bounding box
|
114
|
+
pdf.bounding_box([100, pdf.bounds.top], width: 400) do
|
115
|
+
pdf.text "The rain in spain falls mainly in the plains.\n" * 30
|
116
|
+
end
|
117
|
+
|
118
|
+
pdf.start_new_page(margin: 0)
|
119
|
+
|
120
|
+
x_min, y_min, x_max, y_max = pdf.page.dimensions
|
121
|
+
|
122
|
+
expect(pdf.bounds.absolute_top_left).to eq([x_min, y_max])
|
123
|
+
expect(pdf.bounds.absolute_bottom_right).to eq([x_max, y_min])
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'restores the parent bounding box when calls are nested' do
|
127
|
+
pdf.bounding_box [100, 500], width: 300, height: 300 do
|
128
|
+
expect(pdf.bounds.absolute_top)
|
129
|
+
.to eq(500 + pdf.margin_box.absolute_bottom)
|
130
|
+
expect(pdf.bounds.absolute_left)
|
131
|
+
.to eq(100 + pdf.margin_box.absolute_left)
|
132
|
+
|
133
|
+
parent_box = pdf.bounds
|
134
|
+
|
135
|
+
pdf.bounding_box [50, 200], width: 100, height: 100 do
|
136
|
+
expect(pdf.bounds.absolute_top)
|
137
|
+
.to eq(200 + parent_box.absolute_bottom)
|
138
|
+
expect(pdf.bounds.absolute_left).to eq(50 + parent_box.absolute_left)
|
139
|
+
end
|
140
|
+
|
141
|
+
expect(pdf.bounds.absolute_top)
|
142
|
+
.to eq(500 + pdf.margin_box.absolute_bottom)
|
143
|
+
expect(pdf.bounds.absolute_left)
|
144
|
+
.to eq(100 + pdf.margin_box.absolute_left)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'calculates a height if none is specified' do
|
149
|
+
pdf.bounding_box([100, 500], width: 100) do
|
150
|
+
pdf.text 'The rain in Spain falls mainly on the plains.'
|
151
|
+
end
|
152
|
+
|
153
|
+
expect(pdf.y).to be_within(0.001).of(458.384)
|
154
|
+
end
|
155
|
+
|
156
|
+
it 'keeps track of the max height the box was stretched to' do
|
157
|
+
box = pdf.bounding_box(pdf.bounds.top_left, width: 100) do
|
158
|
+
pdf.move_down 100
|
159
|
+
pdf.move_up 15
|
160
|
+
end
|
161
|
+
|
162
|
+
expect(box.height).to eq(100)
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'advances the y-position by bbox.height by default' do
|
166
|
+
orig_y = pdf.y
|
167
|
+
pdf.bounding_box [0, pdf.cursor], width: pdf.bounds.width, height: 30 do
|
168
|
+
pdf.text 'hello'
|
169
|
+
end
|
170
|
+
expect(pdf.y).to be_within(0.001).of(orig_y - 30)
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'does not advance y-position if passed :hold_position => true' do
|
174
|
+
orig_y = pdf.y
|
175
|
+
pdf.bounding_box(
|
176
|
+
[0, pdf.cursor],
|
177
|
+
width: pdf.bounds.width,
|
178
|
+
hold_position: true
|
179
|
+
) do
|
180
|
+
pdf.text 'hello'
|
181
|
+
end
|
182
|
+
# y only advances by height of one line ("hello")
|
183
|
+
expect(pdf.y).to be_within(0.001).of(orig_y - pdf.height_of('hello'))
|
184
|
+
end
|
185
|
+
|
186
|
+
it 'should not advance y-position of a stretchy bbox if it would stretch ' \
|
187
|
+
'the bbox further' do
|
188
|
+
bottom = pdf.y = pdf.margin_box.absolute_bottom
|
189
|
+
pdf.bounding_box [0, pdf.margin_box.top], width: pdf.bounds.width do
|
190
|
+
pdf.y = bottom
|
191
|
+
pdf.text 'hello' # starts a new page
|
192
|
+
end
|
193
|
+
expect(pdf.page_count).to eq(2)
|
194
|
+
|
195
|
+
# Restoring the position (to the absolute bottom) would stretch the bbox
|
196
|
+
# to the bottom of the page, which we don't want. This should be
|
197
|
+
# equivalent to a bbox with :hold_position => true, where we only advance
|
198
|
+
# by the amount that was actually drawn.
|
199
|
+
expect(pdf.y).to be_within(0.001).of(
|
200
|
+
pdf.margin_box.absolute_top - pdf.height_of('hello')
|
201
|
+
)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
describe 'Indentation' do
|
206
|
+
it 'temporarilies shift the x coordinate and width' do
|
207
|
+
pdf.bounding_box([100, 100], width: 200) do
|
208
|
+
pdf.indent(20) do
|
209
|
+
expect(pdf.bounds.absolute_left).to eq(120)
|
210
|
+
expect(pdf.bounds.width).to eq(180)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
it 'restores the x coordinate and width after block exits' do
|
216
|
+
pdf.bounding_box([100, 100], width: 200) do
|
217
|
+
pdf.indent(20) do
|
218
|
+
# no-op
|
219
|
+
end
|
220
|
+
expect(pdf.bounds.absolute_left).to eq(100)
|
221
|
+
expect(pdf.bounds.width).to eq(200)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
it 'restores the x coordinate and width on error' do
|
226
|
+
pdf.bounding_box([100, 100], width: 200) do
|
227
|
+
begin
|
228
|
+
pdf.indent(20) { raise }
|
229
|
+
rescue
|
230
|
+
expect(pdf.bounds.absolute_left).to eq(100)
|
231
|
+
expect(pdf.bounds.width).to eq(200)
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
it 'maintains left indentation across a page break' do
|
237
|
+
original_left = pdf.bounds.absolute_left
|
238
|
+
|
239
|
+
pdf.indent(20) do
|
240
|
+
expect(pdf.bounds.absolute_left).to eq(original_left + 20)
|
241
|
+
pdf.start_new_page
|
242
|
+
expect(pdf.bounds.absolute_left).to eq(original_left + 20)
|
243
|
+
end
|
244
|
+
|
245
|
+
expect(pdf.bounds.absolute_left).to eq(original_left)
|
246
|
+
end
|
247
|
+
|
248
|
+
it 'maintains right indentation across a page break' do
|
249
|
+
original_width = pdf.bounds.width
|
250
|
+
|
251
|
+
pdf.indent(0, 20) do
|
252
|
+
expect(pdf.bounds.width).to eq(original_width - 20)
|
253
|
+
pdf.start_new_page
|
254
|
+
expect(pdf.bounds.width).to eq(original_width - 20)
|
255
|
+
end
|
256
|
+
|
257
|
+
expect(pdf.bounds.width).to eq(original_width)
|
258
|
+
end
|
259
|
+
|
260
|
+
it 'optionally allows adjustment of the right bound as well' do
|
261
|
+
pdf.bounding_box([100, 100], width: 200) do
|
262
|
+
pdf.indent(20, 30) do
|
263
|
+
expect(pdf.bounds.absolute_left).to eq(120)
|
264
|
+
expect(pdf.bounds.width).to eq(150)
|
265
|
+
end
|
266
|
+
expect(pdf.bounds.absolute_left).to eq(100)
|
267
|
+
expect(pdf.bounds.width).to eq(200)
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
describe 'in a ColumnBox' do
|
272
|
+
it 'subtracts the given indentation from the available width' do
|
273
|
+
pdf.column_box(
|
274
|
+
[0, pdf.cursor],
|
275
|
+
width: pdf.bounds.width,
|
276
|
+
height: 200,
|
277
|
+
columns: 2,
|
278
|
+
spacer: 20
|
279
|
+
) do
|
280
|
+
width = pdf.bounds.width
|
281
|
+
pdf.indent(20) do
|
282
|
+
expect(pdf.bounds.width).to be_within(0.01).of(width - 20)
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
it 'subtracts right padding from the available width' do
|
288
|
+
pdf.column_box(
|
289
|
+
[0, pdf.cursor],
|
290
|
+
width: pdf.bounds.width,
|
291
|
+
height: 200,
|
292
|
+
columns: 2,
|
293
|
+
spacer: 20
|
294
|
+
) do
|
295
|
+
width = pdf.bounds.width
|
296
|
+
pdf.indent(20, 30) do
|
297
|
+
expect(pdf.bounds.width).to be_within(0.01).of(width - 50)
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
it 'maintains the same left indentation across column breaks' do
|
303
|
+
pdf.column_box(
|
304
|
+
[0, pdf.cursor],
|
305
|
+
width: pdf.bounds.width,
|
306
|
+
columns: 3,
|
307
|
+
spacer: 15
|
308
|
+
) do
|
309
|
+
3.times do |_column|
|
310
|
+
x = pdf.bounds.left_side
|
311
|
+
pdf.indent(20) do
|
312
|
+
expect(pdf.bounds.left_side).to eq(x + 20)
|
313
|
+
end
|
314
|
+
pdf.bounds.move_past_bottom
|
315
|
+
end
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
it 'does not change the right margin if only left indentation is '\
|
320
|
+
'requested' do
|
321
|
+
pdf.column_box(
|
322
|
+
[0, pdf.cursor],
|
323
|
+
width: pdf.bounds.width,
|
324
|
+
columns: 3,
|
325
|
+
spacer: 15
|
326
|
+
) do
|
327
|
+
3.times do |_column|
|
328
|
+
x = pdf.bounds.right_side
|
329
|
+
pdf.indent(20) do
|
330
|
+
expect(pdf.bounds.right_side).to eq(x)
|
331
|
+
end
|
332
|
+
pdf.bounds.move_past_bottom
|
333
|
+
end
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
it 'maintains the same right indentation across columns' do
|
338
|
+
pdf.column_box(
|
339
|
+
[0, pdf.cursor],
|
340
|
+
width: pdf.bounds.width,
|
341
|
+
columns: 3,
|
342
|
+
spacer: 15
|
343
|
+
) do
|
344
|
+
3.times do |_column|
|
345
|
+
x = pdf.bounds.right_side
|
346
|
+
pdf.indent(20, 10) do
|
347
|
+
expect(pdf.bounds.right_side).to eq(x - 10)
|
348
|
+
end
|
349
|
+
pdf.bounds.move_past_bottom
|
350
|
+
end
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
it 'keeps the right indentation after nesting indents' do
|
355
|
+
pdf.column_box(
|
356
|
+
[0, pdf.cursor],
|
357
|
+
width: pdf.bounds.width,
|
358
|
+
columns: 3,
|
359
|
+
spacer: 15
|
360
|
+
) do
|
361
|
+
3.times do |_column|
|
362
|
+
# I am giving a right indent of 10...
|
363
|
+
pdf.indent(20, 10) do
|
364
|
+
x = pdf.bounds.right_side
|
365
|
+
# ...and no right indent here...
|
366
|
+
pdf.indent(20) do
|
367
|
+
# right indent is inherited from the parent!
|
368
|
+
expect(pdf.bounds.right_side).to eq(x)
|
369
|
+
end
|
370
|
+
end
|
371
|
+
pdf.bounds.move_past_bottom
|
372
|
+
end
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
it 'reverts the right indentation if negative indent is given in '\
|
377
|
+
'nested indent' do
|
378
|
+
pdf.column_box(
|
379
|
+
[0, pdf.cursor],
|
380
|
+
width: pdf.bounds.width,
|
381
|
+
columns: 3,
|
382
|
+
spacer: 15
|
383
|
+
) do
|
384
|
+
3.times do |_column|
|
385
|
+
x = pdf.bounds.right_side
|
386
|
+
pdf.indent(20, 10) do
|
387
|
+
# requesting a negative right-indent of equivalent size...
|
388
|
+
pdf.indent(20, -10) do
|
389
|
+
# ...resets the right margin to that of the column!
|
390
|
+
expect(pdf.bounds.right_side).to eq(x)
|
391
|
+
end
|
392
|
+
end
|
393
|
+
pdf.bounds.move_past_bottom
|
394
|
+
end
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
398
|
+
it 'reduces the available column width by the sum of ' \
|
399
|
+
'all nested indents' do
|
400
|
+
pdf.column_box(
|
401
|
+
[0, pdf.cursor],
|
402
|
+
width: pdf.bounds.width,
|
403
|
+
columns: 3,
|
404
|
+
spacer: 15
|
405
|
+
) do
|
406
|
+
3.times do |_column|
|
407
|
+
w = pdf.bounds.width
|
408
|
+
pdf.indent(20, 10) do
|
409
|
+
pdf.indent(20, 10) do
|
410
|
+
expect(pdf.bounds.width).to eq(w - 60)
|
411
|
+
end
|
412
|
+
end
|
413
|
+
pdf.bounds.move_past_bottom
|
414
|
+
end
|
415
|
+
end
|
416
|
+
end
|
417
|
+
end
|
418
|
+
end
|
419
|
+
|
420
|
+
describe 'A canvas' do
|
421
|
+
it 'uses whatever the last set y position is' do
|
422
|
+
pdf.canvas do
|
423
|
+
pdf.bounding_box([100, 500], width: 200) { pdf.move_down 50 }
|
424
|
+
end
|
425
|
+
expect(pdf.y).to eq(450)
|
426
|
+
end
|
427
|
+
|
428
|
+
it 'restores the original ypos after execution', issue: 523 do
|
429
|
+
doc = Prawn::Document.new(skip_page_creation: true)
|
430
|
+
doc.start_new_page
|
431
|
+
|
432
|
+
original_ypos = doc.y
|
433
|
+
|
434
|
+
doc.canvas {}
|
435
|
+
|
436
|
+
expect(doc.y).to eq(original_ypos)
|
437
|
+
end
|
438
|
+
end
|
439
|
+
|
440
|
+
describe 'Deep-copying' do
|
441
|
+
it 'creates a new object that does not copy @document' do
|
442
|
+
Prawn::Document.new do |pdf|
|
443
|
+
orig = pdf.bounds
|
444
|
+
copy = orig.deep_copy
|
445
|
+
|
446
|
+
expect(copy).to_not eq(pdf.bounds)
|
447
|
+
expect(copy.document).to be_nil
|
448
|
+
end
|
449
|
+
end
|
450
|
+
|
451
|
+
it 'deep-copies parent bounds' do
|
452
|
+
Prawn::Document.new do |pdf|
|
453
|
+
outside = pdf.bounds
|
454
|
+
pdf.bounding_box [100, 100], width: 100 do
|
455
|
+
copy = pdf.bounds.deep_copy
|
456
|
+
|
457
|
+
# the parent bounds should have the same parameters
|
458
|
+
expect(copy.parent.width).to eq(outside.width)
|
459
|
+
expect(copy.parent.height).to eq(outside.height)
|
460
|
+
|
461
|
+
# but should not be the same object
|
462
|
+
expect(copy.parent).to_not eq(outside)
|
463
|
+
end
|
464
|
+
end
|
465
|
+
end
|
466
|
+
end
|
467
|
+
|
468
|
+
describe 'Prawn::Document#reference_bounds' do
|
469
|
+
it 'returns self for non-stretchy bounds' do
|
470
|
+
pdf.bounding_box([0, pdf.cursor], width: 100, height: 100) do
|
471
|
+
expect(pdf.reference_bounds).to eq(pdf.bounds)
|
472
|
+
end
|
473
|
+
end
|
474
|
+
|
475
|
+
it 'returns the parent bounds if in a stretchy box' do
|
476
|
+
pdf.bounding_box([0, pdf.cursor], width: 100, height: 100) do
|
477
|
+
correct_bounds = pdf.bounds
|
478
|
+
pdf.bounding_box([0, pdf.cursor], width: 100) do
|
479
|
+
expect(pdf.reference_bounds).to eq(correct_bounds)
|
480
|
+
end
|
481
|
+
end
|
482
|
+
end
|
483
|
+
|
484
|
+
it 'finds the non-stretchy box through 2 levels' do
|
485
|
+
pdf.bounding_box([0, pdf.cursor], width: 100, height: 100) do
|
486
|
+
correct_bounds = pdf.bounds
|
487
|
+
pdf.bounding_box([0, pdf.cursor], width: 100) do
|
488
|
+
pdf.bounding_box([0, pdf.cursor], width: 100) do
|
489
|
+
expect(pdf.reference_bounds).to eq(correct_bounds)
|
490
|
+
end
|
491
|
+
end
|
492
|
+
end
|
493
|
+
end
|
494
|
+
|
495
|
+
it "returns the margin box if there's no explicit bbox" do
|
496
|
+
expect(pdf.reference_bounds).to eq(pdf.margin_box)
|
497
|
+
|
498
|
+
pdf.bounding_box([0, pdf.cursor], width: 100) do
|
499
|
+
expect(pdf.reference_bounds).to eq(pdf.margin_box)
|
500
|
+
end
|
501
|
+
end
|
502
|
+
|
503
|
+
it "returns the canvas box if we're in a canvas" do
|
504
|
+
pdf.canvas do
|
505
|
+
canvas_box = pdf.bounds
|
506
|
+
|
507
|
+
expect(pdf.reference_bounds).to eq(canvas_box)
|
508
|
+
|
509
|
+
pdf.bounding_box([0, pdf.cursor], width: 100) do
|
510
|
+
expect(pdf.reference_bounds).to eq(canvas_box)
|
511
|
+
end
|
512
|
+
end
|
513
|
+
end
|
514
|
+
end
|
515
|
+
|
516
|
+
describe '#move_past_bottom' do
|
517
|
+
it 'ordinarilies start a new page' do
|
518
|
+
pdf.bounds.move_past_bottom
|
519
|
+
pdf.text 'Foo'
|
520
|
+
|
521
|
+
pages = PDF::Inspector::Page.analyze(pdf.render).pages
|
522
|
+
expect(pages.size).to eq(2)
|
523
|
+
expect(pages[0][:strings]).to eq([])
|
524
|
+
expect(pages[1][:strings]).to eq(['Foo'])
|
525
|
+
end
|
526
|
+
|
527
|
+
it 'moves to the top of the next page if it exists already' do
|
528
|
+
# save away the y-position at the top of a page
|
529
|
+
top_y = pdf.y
|
530
|
+
|
531
|
+
# create a blank page but go to the page before it
|
532
|
+
pdf.start_new_page
|
533
|
+
pdf.go_to_page 1
|
534
|
+
pdf.text 'Foo'
|
535
|
+
|
536
|
+
pdf.bounds.move_past_bottom
|
537
|
+
expect(pdf.y).to be_within(0.001).of(top_y)
|
538
|
+
pdf.text 'Bar'
|
539
|
+
|
540
|
+
pages = PDF::Inspector::Page.analyze(pdf.render).pages
|
541
|
+
expect(pages.size).to eq(2)
|
542
|
+
expect(pages[0][:strings]).to eq(['Foo'])
|
543
|
+
expect(pages[1][:strings]).to eq(['Bar'])
|
544
|
+
end
|
545
|
+
end
|
546
|
+
end
|