prawn 2.4.0 → 2.5.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 +0 -0
- data/lib/prawn/document/bounding_box.rb +213 -141
- data/lib/prawn/document/column_box.rb +61 -26
- data/lib/prawn/document/internals.rb +25 -16
- data/lib/prawn/document/span.rb +20 -18
- data/lib/prawn/document.rb +257 -171
- data/lib/prawn/encoding.rb +2 -5
- data/lib/prawn/errors.rb +23 -34
- data/lib/prawn/font.rb +248 -135
- data/lib/prawn/font_metric_cache.rb +11 -10
- data/lib/prawn/fonts/afm.rb +85 -45
- data/lib/prawn/fonts/dfont.rb +7 -1
- data/lib/prawn/fonts/otf.rb +4 -1
- data/lib/prawn/fonts/to_unicode_cmap.rb +151 -0
- data/lib/prawn/fonts/ttc.rb +7 -2
- data/lib/prawn/fonts/ttf.rb +305 -93
- data/lib/prawn/fonts.rb +14 -0
- data/lib/prawn/graphics/blend_mode.rb +25 -28
- data/lib/prawn/graphics/cap_style.rb +9 -12
- data/lib/prawn/graphics/color.rb +57 -34
- data/lib/prawn/graphics/dash.rb +45 -42
- data/lib/prawn/graphics/join_style.rb +17 -11
- data/lib/prawn/graphics/patterns.rb +190 -69
- data/lib/prawn/graphics/transformation.rb +48 -41
- data/lib/prawn/graphics/transparency.rb +16 -40
- data/lib/prawn/graphics.rb +363 -253
- data/lib/prawn/grid.rb +184 -57
- data/lib/prawn/image_handler.rb +27 -10
- data/lib/prawn/images/image.rb +8 -10
- data/lib/prawn/images/jpg.rb +42 -19
- data/lib/prawn/images/png.rb +92 -41
- data/lib/prawn/images.rb +44 -57
- data/lib/prawn/measurement_extensions.rb +39 -8
- data/lib/prawn/measurements.rb +60 -5
- data/lib/prawn/outline.rb +114 -108
- data/lib/prawn/repeater.rb +51 -35
- data/lib/prawn/security/arcfour.rb +4 -4
- data/lib/prawn/security.rb +75 -70
- data/lib/prawn/soft_mask.rb +42 -30
- data/lib/prawn/stamp.rb +38 -42
- data/lib/prawn/text/box.rb +146 -96
- data/lib/prawn/text/formatted/arranger.rb +87 -26
- data/lib/prawn/text/formatted/box.rb +221 -150
- data/lib/prawn/text/formatted/fragment.rb +130 -14
- data/lib/prawn/text/formatted/line_wrap.rb +33 -24
- data/lib/prawn/text/formatted/parser.rb +112 -72
- data/lib/prawn/text/formatted/wrap.rb +12 -17
- data/lib/prawn/text/formatted.rb +75 -0
- data/lib/prawn/text.rb +441 -196
- data/lib/prawn/transformation_stack.rb +29 -10
- data/lib/prawn/utilities.rb +13 -13
- data/lib/prawn/version.rb +2 -1
- data/lib/prawn/view.rb +68 -53
- data/lib/prawn.rb +23 -18
- data.tar.gz.sig +0 -0
- metadata +54 -177
- metadata.gz.sig +0 -0
- data/.yardopts +0 -10
- data/Gemfile +0 -5
- data/Rakefile +0 -25
- data/manual/absolute_position.pdf +0 -0
- data/manual/basic_concepts/adding_pages.rb +0 -26
- data/manual/basic_concepts/basic_concepts.rb +0 -43
- data/manual/basic_concepts/creation.rb +0 -38
- data/manual/basic_concepts/cursor.rb +0 -32
- data/manual/basic_concepts/measurement.rb +0 -24
- data/manual/basic_concepts/origin.rb +0 -37
- data/manual/basic_concepts/other_cursor_helpers.rb +0 -39
- data/manual/basic_concepts/view.rb +0 -48
- data/manual/bounding_box/bounding_box.rb +0 -41
- data/manual/bounding_box/bounds.rb +0 -48
- data/manual/bounding_box/canvas.rb +0 -23
- data/manual/bounding_box/creation.rb +0 -22
- data/manual/bounding_box/indentation.rb +0 -45
- data/manual/bounding_box/nesting.rb +0 -52
- data/manual/bounding_box/russian_boxes.rb +0 -40
- data/manual/bounding_box/stretchy.rb +0 -29
- data/manual/contents.rb +0 -35
- data/manual/cover.rb +0 -43
- data/manual/document_and_page_options/background.rb +0 -29
- data/manual/document_and_page_options/document_and_page_options.rb +0 -34
- data/manual/document_and_page_options/metadata.rb +0 -25
- data/manual/document_and_page_options/page_margins.rb +0 -36
- data/manual/document_and_page_options/page_size.rb +0 -34
- data/manual/document_and_page_options/print_scaling.rb +0 -23
- data/manual/example_helper.rb +0 -8
- data/manual/graphics/blend_mode.rb +0 -52
- data/manual/graphics/circle_and_ellipse.rb +0 -21
- data/manual/graphics/color.rb +0 -22
- data/manual/graphics/common_lines.rb +0 -29
- data/manual/graphics/fill_and_stroke.rb +0 -41
- data/manual/graphics/fill_rules.rb +0 -38
- data/manual/graphics/gradients.rb +0 -43
- data/manual/graphics/graphics.rb +0 -64
- data/manual/graphics/helper.rb +0 -34
- data/manual/graphics/line_width.rb +0 -36
- data/manual/graphics/lines_and_curves.rb +0 -40
- data/manual/graphics/polygon.rb +0 -27
- data/manual/graphics/rectangle.rb +0 -20
- data/manual/graphics/rotate.rb +0 -25
- data/manual/graphics/scale.rb +0 -42
- data/manual/graphics/soft_masks.rb +0 -44
- data/manual/graphics/stroke_cap.rb +0 -30
- data/manual/graphics/stroke_dash.rb +0 -47
- data/manual/graphics/stroke_join.rb +0 -29
- data/manual/graphics/translate.rb +0 -29
- data/manual/graphics/transparency.rb +0 -33
- data/manual/how_to_read_this_manual.rb +0 -39
- data/manual/images/absolute_position.rb +0 -22
- data/manual/images/fit.rb +0 -20
- data/manual/images/horizontal.rb +0 -24
- data/manual/images/images.rb +0 -41
- data/manual/images/plain_image.rb +0 -17
- data/manual/images/scale.rb +0 -21
- data/manual/images/vertical.rb +0 -30
- data/manual/images/width_and_height.rb +0 -24
- data/manual/layout/boxes.rb +0 -26
- data/manual/layout/content.rb +0 -24
- data/manual/layout/layout.rb +0 -27
- data/manual/layout/simple_grid.rb +0 -22
- data/manual/outline/add_subsection_to.rb +0 -60
- data/manual/outline/insert_section_after.rb +0 -46
- data/manual/outline/outline.rb +0 -33
- data/manual/outline/sections_and_pages.rb +0 -66
- data/manual/repeatable_content/alternate_page_numbering.rb +0 -36
- data/manual/repeatable_content/page_numbering.rb +0 -55
- data/manual/repeatable_content/repeatable_content.rb +0 -35
- data/manual/repeatable_content/repeater.rb +0 -54
- data/manual/repeatable_content/stamp.rb +0 -40
- data/manual/security/encryption.rb +0 -28
- data/manual/security/permissions.rb +0 -43
- data/manual/security/security.rb +0 -28
- data/manual/table.rb +0 -16
- data/manual/text/alignment.rb +0 -43
- data/manual/text/color.rb +0 -24
- data/manual/text/column_box.rb +0 -30
- data/manual/text/fallback_fonts.rb +0 -41
- data/manual/text/font.rb +0 -40
- data/manual/text/font_size.rb +0 -44
- data/manual/text/font_style.rb +0 -25
- data/manual/text/formatted_callbacks.rb +0 -70
- data/manual/text/formatted_text.rb +0 -61
- data/manual/text/free_flowing_text.rb +0 -50
- data/manual/text/inline.rb +0 -40
- data/manual/text/kerning_and_character_spacing.rb +0 -38
- data/manual/text/leading.rb +0 -24
- data/manual/text/line_wrapping.rb +0 -60
- data/manual/text/paragraph_indentation.rb +0 -31
- data/manual/text/positioned_text.rb +0 -37
- data/manual/text/registering_families.rb +0 -51
- data/manual/text/rendering_and_color.rb +0 -36
- data/manual/text/right_to_left_text.rb +0 -54
- data/manual/text/rotation.rb +0 -52
- data/manual/text/single_usage.rb +0 -36
- data/manual/text/text.rb +0 -75
- data/manual/text/text_box_excess.rb +0 -35
- data/manual/text/text_box_extensions.rb +0 -48
- data/manual/text/text_box_overflow.rb +0 -51
- data/manual/text/utf8.rb +0 -27
- data/manual/text/win_ansi_charset.rb +0 -62
- data/prawn.gemspec +0 -51
- data/spec/data/curves.pdf +0 -66
- data/spec/extensions/encoding_helpers.rb +0 -11
- data/spec/prawn/document/bounding_box_spec.rb +0 -550
- data/spec/prawn/document/column_box_spec.rb +0 -75
- data/spec/prawn/document/security_spec.rb +0 -176
- data/spec/prawn/document_annotations_spec.rb +0 -76
- data/spec/prawn/document_destinations_spec.rb +0 -15
- data/spec/prawn/document_grid_spec.rb +0 -99
- data/spec/prawn/document_reference_spec.rb +0 -27
- data/spec/prawn/document_span_spec.rb +0 -44
- data/spec/prawn/document_spec.rb +0 -805
- data/spec/prawn/font_metric_cache_spec.rb +0 -54
- data/spec/prawn/font_spec.rb +0 -544
- data/spec/prawn/graphics/blend_mode_spec.rb +0 -63
- data/spec/prawn/graphics/transparency_spec.rb +0 -81
- data/spec/prawn/graphics_spec.rb +0 -872
- data/spec/prawn/graphics_stroke_styles_spec.rb +0 -229
- data/spec/prawn/image_handler_spec.rb +0 -53
- data/spec/prawn/images/jpg_spec.rb +0 -20
- data/spec/prawn/images/png_spec.rb +0 -283
- data/spec/prawn/images_spec.rb +0 -229
- data/spec/prawn/measurements_extensions_spec.rb +0 -24
- data/spec/prawn/outline_spec.rb +0 -512
- data/spec/prawn/repeater_spec.rb +0 -166
- data/spec/prawn/soft_mask_spec.rb +0 -74
- data/spec/prawn/stamp_spec.rb +0 -173
- data/spec/prawn/text/box_spec.rb +0 -1110
- data/spec/prawn/text/formatted/arranger_spec.rb +0 -466
- data/spec/prawn/text/formatted/box_spec.rb +0 -849
- data/spec/prawn/text/formatted/fragment_spec.rb +0 -343
- data/spec/prawn/text/formatted/line_wrap_spec.rb +0 -495
- data/spec/prawn/text/formatted/parser_spec.rb +0 -697
- data/spec/prawn/text_draw_text_spec.rb +0 -150
- data/spec/prawn/text_rendering_mode_spec.rb +0 -48
- data/spec/prawn/text_spacing_spec.rb +0 -95
- data/spec/prawn/text_spec.rb +0 -603
- data/spec/prawn/text_with_inline_formatting_spec.rb +0 -35
- data/spec/prawn/transformation_stack_spec.rb +0 -66
- data/spec/prawn/view_spec.rb +0 -63
- data/spec/prawn_manual_spec.rb +0 -35
- data/spec/spec_helper.rb +0 -48
@@ -1,849 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
describe Prawn::Text::Formatted::Box do
|
6
|
-
let(:pdf) { create_pdf }
|
7
|
-
|
8
|
-
describe 'wrapping' do
|
9
|
-
it 'does not wrap between two fragments' do
|
10
|
-
texts = [
|
11
|
-
{ text: 'Hello ' },
|
12
|
-
{ text: 'World' },
|
13
|
-
{ text: '2', styles: [:superscript] }
|
14
|
-
]
|
15
|
-
text_box = described_class.new(
|
16
|
-
texts,
|
17
|
-
document: pdf,
|
18
|
-
width: pdf.width_of('Hello World')
|
19
|
-
)
|
20
|
-
text_box.render
|
21
|
-
expect(text_box.text).to eq("Hello\nWorld2")
|
22
|
-
end
|
23
|
-
|
24
|
-
it 'does not raise an Encoding::CompatibilityError when keeping a TTF and '\
|
25
|
-
'an AFM font together' do
|
26
|
-
file = "#{Prawn::DATADIR}/fonts/gkai00mp.ttf"
|
27
|
-
|
28
|
-
pdf.font_families['Kai'] = {
|
29
|
-
normal: { file: file, font: 'Kai' }
|
30
|
-
}
|
31
|
-
|
32
|
-
texts = [
|
33
|
-
{ text: 'Hello ' },
|
34
|
-
{ text: '再见', font: 'Kai' },
|
35
|
-
{ text: 'World' }
|
36
|
-
]
|
37
|
-
text_box = described_class.new(
|
38
|
-
texts,
|
39
|
-
document: pdf,
|
40
|
-
width: pdf.width_of('Hello World')
|
41
|
-
)
|
42
|
-
|
43
|
-
text_box.render
|
44
|
-
end
|
45
|
-
|
46
|
-
it 'wraps between two fragments when the preceding fragment ends with '\
|
47
|
-
'a white space' do
|
48
|
-
texts = [
|
49
|
-
{ text: 'Hello ' },
|
50
|
-
{ text: 'World ' },
|
51
|
-
{ text: '2', styles: [:superscript] }
|
52
|
-
]
|
53
|
-
text_box = described_class.new(
|
54
|
-
texts,
|
55
|
-
document: pdf,
|
56
|
-
width: pdf.width_of('Hello World')
|
57
|
-
)
|
58
|
-
text_box.render
|
59
|
-
expect(text_box.text).to eq("Hello World\n2")
|
60
|
-
|
61
|
-
texts = [
|
62
|
-
{ text: 'Hello ' },
|
63
|
-
{ text: "World\n" },
|
64
|
-
{ text: '2', styles: [:superscript] }
|
65
|
-
]
|
66
|
-
text_box = described_class.new(
|
67
|
-
texts,
|
68
|
-
document: pdf,
|
69
|
-
width: pdf.width_of('Hello World')
|
70
|
-
)
|
71
|
-
text_box.render
|
72
|
-
expect(text_box.text).to eq("Hello World\n2")
|
73
|
-
end
|
74
|
-
|
75
|
-
it 'wraps between two fragments when the final fragment begins with '\
|
76
|
-
'a white space' do
|
77
|
-
texts = [
|
78
|
-
{ text: 'Hello ' },
|
79
|
-
{ text: 'World' },
|
80
|
-
{ text: ' 2', styles: [:superscript] }
|
81
|
-
]
|
82
|
-
text_box = described_class.new(
|
83
|
-
texts,
|
84
|
-
document: pdf,
|
85
|
-
width: pdf.width_of('Hello World')
|
86
|
-
)
|
87
|
-
text_box.render
|
88
|
-
expect(text_box.text).to eq("Hello World\n2")
|
89
|
-
|
90
|
-
texts = [
|
91
|
-
{ text: 'Hello ' },
|
92
|
-
{ text: 'World' },
|
93
|
-
{ text: "\n2", styles: [:superscript] }
|
94
|
-
]
|
95
|
-
text_box = described_class.new(
|
96
|
-
texts,
|
97
|
-
document: pdf,
|
98
|
-
width: pdf.width_of('Hello World')
|
99
|
-
)
|
100
|
-
text_box.render
|
101
|
-
expect(text_box.text).to eq("Hello World\n2")
|
102
|
-
end
|
103
|
-
|
104
|
-
it 'properlies handle empty slices using default encoding' do
|
105
|
-
texts = [{
|
106
|
-
text: 'Noua Delineatio Geographica generalis | Apostolicarum ' \
|
107
|
-
'peregrinationum | S FRANCISCI XAUERII | Indiarum & Iaponiæ Apostoli',
|
108
|
-
font: 'Courier',
|
109
|
-
size: 10
|
110
|
-
}]
|
111
|
-
text_box = described_class.new(
|
112
|
-
texts,
|
113
|
-
document: pdf,
|
114
|
-
width: pdf.width_of('Noua Delineatio Geographica gen')
|
115
|
-
)
|
116
|
-
expect do
|
117
|
-
text_box.render
|
118
|
-
end.to_not raise_error
|
119
|
-
expect(text_box.text).to eq(
|
120
|
-
"Noua Delineatio Geographica\ngeneralis | Apostolicarum\n" \
|
121
|
-
"peregrinationum | S FRANCISCI\nXAUERII | Indiarum & Iaponi\346\n" \
|
122
|
-
'Apostoli'
|
123
|
-
)
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
describe 'Text::Formatted::Box with :fallback_fonts option that includes' \
|
128
|
-
'a Chinese font and set of Chinese glyphs not in the current font' do
|
129
|
-
it 'changes the font to the Chinese font for the Chinese glyphs' do
|
130
|
-
file = "#{Prawn::DATADIR}/fonts/gkai00mp.ttf"
|
131
|
-
pdf.font_families['Kai'] = {
|
132
|
-
normal: { file: file, font: 'Kai' }
|
133
|
-
}
|
134
|
-
formatted_text = [
|
135
|
-
{ text: 'hello你好' },
|
136
|
-
{ text: '再见goodbye' }
|
137
|
-
]
|
138
|
-
pdf.formatted_text_box(formatted_text, fallback_fonts: ['Kai'])
|
139
|
-
|
140
|
-
text = PDF::Inspector::Text.analyze(pdf.render)
|
141
|
-
|
142
|
-
fonts_used = text.font_settings.map { |e| e[:name] }
|
143
|
-
expect(fonts_used.length).to eq(4)
|
144
|
-
expect(fonts_used[0]).to eq(:Helvetica)
|
145
|
-
expect(fonts_used[1].to_s).to match(/GBZenKai-Medium/)
|
146
|
-
expect(fonts_used[2].to_s).to match(/GBZenKai-Medium/)
|
147
|
-
expect(fonts_used[3]).to eq(:Helvetica)
|
148
|
-
|
149
|
-
expect(text.strings[0]).to eq('hello')
|
150
|
-
expect(text.strings[1]).to eq('你好')
|
151
|
-
expect(text.strings[2]).to eq('再见')
|
152
|
-
expect(text.strings[3]).to eq('goodbye')
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
describe 'Text::Formatted::Box with :fallback_fonts option that includes' \
|
157
|
-
'an AFM font and Win-Ansi glyph not in the current Chinese font' do
|
158
|
-
it 'changes the font to the AFM font for the Win-Ansi glyph' do
|
159
|
-
file = "#{Prawn::DATADIR}/fonts/gkai00mp.ttf"
|
160
|
-
pdf.font_families['Kai'] = {
|
161
|
-
normal: { file: file, font: 'Kai' }
|
162
|
-
}
|
163
|
-
pdf.font('Kai')
|
164
|
-
formatted_text = [
|
165
|
-
{ text: 'hello你好' },
|
166
|
-
{ text: '再见€' }
|
167
|
-
]
|
168
|
-
pdf.formatted_text_box(formatted_text, fallback_fonts: ['Helvetica'])
|
169
|
-
|
170
|
-
text = PDF::Inspector::Text.analyze(pdf.render)
|
171
|
-
|
172
|
-
fonts_used = text.font_settings.map { |e| e[:name] }
|
173
|
-
expect(fonts_used.length).to eq(4)
|
174
|
-
expect(fonts_used[0].to_s).to match(/GBZenKai-Medium/)
|
175
|
-
expect(fonts_used[1].to_s).to match(/GBZenKai-Medium/)
|
176
|
-
expect(fonts_used[2].to_s).to match(/GBZenKai-Medium/)
|
177
|
-
expect(fonts_used[3]).to eq(:Helvetica)
|
178
|
-
|
179
|
-
expect(text.strings[0]).to eq('hello')
|
180
|
-
expect(text.strings[1]).to eq('你好')
|
181
|
-
expect(text.strings[2]).to eq('再见')
|
182
|
-
expect(text.strings[3]).to eq('€')
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
|
-
describe 'Text::Formatted::Box with :fallback_fonts option and fragment ' \
|
187
|
-
'level font' do
|
188
|
-
it 'uses the fragment level font except for glyphs not in that font' do
|
189
|
-
file = "#{Prawn::DATADIR}/fonts/gkai00mp.ttf"
|
190
|
-
pdf.font_families['Kai'] = {
|
191
|
-
normal: { file: file, font: 'Kai' }
|
192
|
-
}
|
193
|
-
|
194
|
-
file = "#{Prawn::DATADIR}/fonts/DejaVuSans.ttf"
|
195
|
-
pdf.font_families['DejaVu Sans'] = {
|
196
|
-
normal: { file: file }
|
197
|
-
}
|
198
|
-
|
199
|
-
formatted_text = [
|
200
|
-
{ text: 'hello你好' },
|
201
|
-
{ text: '再见goodbye', font: 'Times-Roman' }
|
202
|
-
]
|
203
|
-
pdf.formatted_text_box(formatted_text, fallback_fonts: ['Kai'])
|
204
|
-
|
205
|
-
text = PDF::Inspector::Text.analyze(pdf.render)
|
206
|
-
|
207
|
-
fonts_used = text.font_settings.map { |e| e[:name] }
|
208
|
-
expect(fonts_used.length).to eq(4)
|
209
|
-
expect(fonts_used[0]).to eq(:Helvetica)
|
210
|
-
expect(fonts_used[1].to_s).to match(/GBZenKai-Medium/)
|
211
|
-
expect(fonts_used[2].to_s).to match(/GBZenKai-Medium/)
|
212
|
-
expect(fonts_used[3]).to eq(:"Times-Roman")
|
213
|
-
|
214
|
-
expect(text.strings[0]).to eq('hello')
|
215
|
-
expect(text.strings[1]).to eq('你好')
|
216
|
-
expect(text.strings[2]).to eq('再见')
|
217
|
-
expect(text.strings[3]).to eq('goodbye')
|
218
|
-
end
|
219
|
-
end
|
220
|
-
|
221
|
-
describe 'Text::Formatted::Box' do
|
222
|
-
let(:formatted_text) { [{ text: 'hello你好' }] }
|
223
|
-
|
224
|
-
before do
|
225
|
-
file = "#{Prawn::DATADIR}/fonts/gkai00mp.ttf"
|
226
|
-
pdf.font_families['Kai'] = {
|
227
|
-
normal: { file: file, font: 'Kai' }
|
228
|
-
}
|
229
|
-
|
230
|
-
file = "#{Prawn::DATADIR}/fonts/DejaVuSans.ttf"
|
231
|
-
pdf.font_families['DejaVu Sans'] = {
|
232
|
-
normal: { file: file }
|
233
|
-
}
|
234
|
-
|
235
|
-
pdf.fallback_fonts(['Kai'])
|
236
|
-
pdf.fallback_fonts = ['Kai']
|
237
|
-
end
|
238
|
-
|
239
|
-
it '#fallback_fonts should return the document-wide fallback fonts' do
|
240
|
-
expect(pdf.fallback_fonts).to eq(['Kai'])
|
241
|
-
end
|
242
|
-
|
243
|
-
it 'is able to set text fallback_fonts document-wide' do
|
244
|
-
pdf.formatted_text_box(formatted_text)
|
245
|
-
|
246
|
-
text = PDF::Inspector::Text.analyze(pdf.render)
|
247
|
-
|
248
|
-
fonts_used = text.font_settings.map { |e| e[:name] }
|
249
|
-
expect(fonts_used.length).to eq(2)
|
250
|
-
expect(fonts_used[0]).to eq(:Helvetica)
|
251
|
-
expect(fonts_used[1].to_s).to match(/GBZenKai-Medium/)
|
252
|
-
end
|
253
|
-
|
254
|
-
it 'is able to override document-wide fallback_fonts' do
|
255
|
-
pdf.fallback_fonts = ['DejaVu Sans']
|
256
|
-
pdf.formatted_text_box(formatted_text, fallback_fonts: ['Kai'])
|
257
|
-
|
258
|
-
text = PDF::Inspector::Text.analyze(pdf.render)
|
259
|
-
|
260
|
-
fonts_used = text.font_settings.map { |e| e[:name] }
|
261
|
-
expect(fonts_used.length).to eq(2)
|
262
|
-
expect(fonts_used[0]).to eq(:Helvetica)
|
263
|
-
expect(fonts_used[1]).to match(/Kai/)
|
264
|
-
end
|
265
|
-
|
266
|
-
it 'omits the fallback fonts overhead when passing an empty array ' \
|
267
|
-
'as the :fallback_fonts' do
|
268
|
-
pdf.font('Kai')
|
269
|
-
|
270
|
-
box = described_class.new(
|
271
|
-
formatted_text,
|
272
|
-
document: pdf,
|
273
|
-
fallback_fonts: []
|
274
|
-
)
|
275
|
-
|
276
|
-
allow(box).to receive(:process_fallback_fonts)
|
277
|
-
box.render
|
278
|
-
expect(box).to_not have_received(:process_fallback_fonts)
|
279
|
-
end
|
280
|
-
|
281
|
-
it 'is able to clear document-wide fallback_fonts' do
|
282
|
-
pdf.fallback_fonts([])
|
283
|
-
box = described_class.new(formatted_text, document: pdf)
|
284
|
-
|
285
|
-
pdf.font('Kai')
|
286
|
-
|
287
|
-
allow(box).to receive(:process_fallback_fonts)
|
288
|
-
box.render
|
289
|
-
expect(box).to_not have_received(:process_fallback_fonts)
|
290
|
-
end
|
291
|
-
end
|
292
|
-
|
293
|
-
describe 'Text::Formatted::Box with :fallback_fonts option ' \
|
294
|
-
'with glyphs not in the primary or the fallback fonts' do
|
295
|
-
it 'raises an exception' do
|
296
|
-
formatted_text = [{ text: 'hello world. 世界你好。' }]
|
297
|
-
|
298
|
-
expect do
|
299
|
-
pdf.formatted_text_box(formatted_text, fallback_fonts: ['Courier'])
|
300
|
-
end.to raise_error(Prawn::Errors::IncompatibleStringEncoding)
|
301
|
-
end
|
302
|
-
end
|
303
|
-
|
304
|
-
describe 'Text::Formatted::Box#extensions' do
|
305
|
-
let(:formatted_wrap_override) do
|
306
|
-
Module.new do
|
307
|
-
# rubocop: disable RSpec/InstanceVariable
|
308
|
-
def wrap(_array)
|
309
|
-
initialize_wrap([{ text: 'all your base are belong to us' }])
|
310
|
-
@line_wrap.wrap_line(
|
311
|
-
document: @document,
|
312
|
-
kerning: @kerning,
|
313
|
-
width: 10_000,
|
314
|
-
arranger: @arranger
|
315
|
-
)
|
316
|
-
fragment = @arranger.retrieve_fragment
|
317
|
-
format_and_draw_fragment(fragment, 0, @line_wrap.width, 0)
|
318
|
-
|
319
|
-
[]
|
320
|
-
end
|
321
|
-
# rubocop: enable RSpec/InstanceVariable
|
322
|
-
end
|
323
|
-
end
|
324
|
-
|
325
|
-
it 'is able to override default line wrapping' do
|
326
|
-
described_class.extensions << formatted_wrap_override
|
327
|
-
pdf.formatted_text_box([{ text: 'hello world' }], {})
|
328
|
-
described_class.extensions.delete(formatted_wrap_override)
|
329
|
-
text = PDF::Inspector::Text.analyze(pdf.render)
|
330
|
-
expect(text.strings[0]).to eq('all your base are belong to us')
|
331
|
-
end
|
332
|
-
|
333
|
-
it 'overrides Text::Formatted::Box line wrapping does not affect ' \
|
334
|
-
'Text::Box wrapping' do
|
335
|
-
described_class.extensions << formatted_wrap_override
|
336
|
-
pdf.text_box('hello world', {})
|
337
|
-
described_class.extensions.delete(formatted_wrap_override)
|
338
|
-
text = PDF::Inspector::Text.analyze(pdf.render)
|
339
|
-
expect(text.strings[0]).to eq('hello world')
|
340
|
-
end
|
341
|
-
|
342
|
-
it "overring Text::Box line wrapping doesn't override Text::Box wrapping" do
|
343
|
-
Prawn::Text::Box.extensions << formatted_wrap_override
|
344
|
-
pdf.text_box('hello world', {})
|
345
|
-
Prawn::Text::Box.extensions.delete(formatted_wrap_override)
|
346
|
-
text = PDF::Inspector::Text.analyze(pdf.render)
|
347
|
-
expect(text.strings[0]).to eq('all your base are belong to us')
|
348
|
-
end
|
349
|
-
end
|
350
|
-
|
351
|
-
describe 'Text::Formatted::Box#render' do
|
352
|
-
let(:fragment_callback_class) do
|
353
|
-
Class.new do
|
354
|
-
def initialize(_string, _number, _options); end
|
355
|
-
|
356
|
-
def render_behind(fragment); end
|
357
|
-
|
358
|
-
def render_in_front(fragment); end
|
359
|
-
end
|
360
|
-
end
|
361
|
-
|
362
|
-
it 'handles newlines' do
|
363
|
-
array = [{ text: "hello\nworld" }]
|
364
|
-
options = { document: pdf }
|
365
|
-
text_box = described_class.new(array, options)
|
366
|
-
text_box.render
|
367
|
-
expect(text_box.text).to eq("hello\nworld")
|
368
|
-
end
|
369
|
-
|
370
|
-
it 'omits spaces from the beginning of the line' do
|
371
|
-
array = [{ text: " hello\n world" }]
|
372
|
-
options = { document: pdf }
|
373
|
-
text_box = described_class.new(array, options)
|
374
|
-
text_box.render
|
375
|
-
expect(text_box.text).to eq("hello\nworld")
|
376
|
-
end
|
377
|
-
|
378
|
-
it 'is okay printing a line of whitespace' do
|
379
|
-
array = [{ text: "hello\n \nworld" }]
|
380
|
-
options = { document: pdf }
|
381
|
-
text_box = described_class.new(array, options)
|
382
|
-
text_box.render
|
383
|
-
expect(text_box.text).to eq("hello\n\nworld")
|
384
|
-
|
385
|
-
array = [
|
386
|
-
{ text: "hello#{' ' * 500}" },
|
387
|
-
{ text: ' ' * 500 },
|
388
|
-
{ text: "#{' ' * 500}\n" },
|
389
|
-
{ text: 'world' }
|
390
|
-
]
|
391
|
-
options = { document: pdf }
|
392
|
-
text_box = described_class.new(array, options)
|
393
|
-
text_box.render
|
394
|
-
expect(text_box.text).to eq("hello\n\nworld")
|
395
|
-
end
|
396
|
-
|
397
|
-
it 'enables fragment level direction setting' do
|
398
|
-
number_of_hellos = 18
|
399
|
-
array = [
|
400
|
-
{ text: 'hello ' * number_of_hellos },
|
401
|
-
{ text: 'world', direction: :ltr },
|
402
|
-
{ text: ', how are you?' }
|
403
|
-
]
|
404
|
-
options = { document: pdf, direction: :rtl }
|
405
|
-
text_box = described_class.new(array, options)
|
406
|
-
text_box.render
|
407
|
-
text = PDF::Inspector::Text.analyze(pdf.render)
|
408
|
-
expect(text.strings[0]).to eq('era woh ,')
|
409
|
-
expect(text.strings[1]).to eq('world')
|
410
|
-
expect(text.strings[2]).to eq(' olleh' * number_of_hellos)
|
411
|
-
expect(text.strings[3]).to eq('?uoy')
|
412
|
-
end
|
413
|
-
|
414
|
-
it 'is able to perform fragment callbacks' do
|
415
|
-
callback_object =
|
416
|
-
fragment_callback_class.new('something', 7, document: pdf)
|
417
|
-
allow(callback_object).to receive(:render_behind)
|
418
|
-
allow(callback_object).to receive(:render_in_front)
|
419
|
-
array = [
|
420
|
-
{ text: 'hello world ' },
|
421
|
-
{ text: 'callback now', callback: callback_object }
|
422
|
-
]
|
423
|
-
text_box = described_class.new(array, document: pdf)
|
424
|
-
text_box.render
|
425
|
-
|
426
|
-
expect(callback_object).to have_received(:render_behind).with(
|
427
|
-
kind_of(Prawn::Text::Formatted::Fragment)
|
428
|
-
)
|
429
|
-
expect(callback_object).to have_received(:render_in_front).with(
|
430
|
-
kind_of(Prawn::Text::Formatted::Fragment)
|
431
|
-
)
|
432
|
-
end
|
433
|
-
|
434
|
-
it 'is able to perform fragment callbacks on multiple objects' do
|
435
|
-
callback_object =
|
436
|
-
fragment_callback_class.new('something', 7, document: pdf)
|
437
|
-
allow(callback_object).to receive(:render_behind)
|
438
|
-
allow(callback_object).to receive(:render_in_front)
|
439
|
-
|
440
|
-
callback_object2 = fragment_callback_class.new(
|
441
|
-
'something else', 14, document: pdf
|
442
|
-
)
|
443
|
-
allow(callback_object2).to receive(:render_behind)
|
444
|
-
allow(callback_object2).to receive(:render_in_front)
|
445
|
-
|
446
|
-
array = [
|
447
|
-
{ text: 'hello world ' },
|
448
|
-
{ text: 'callback now', callback: [callback_object, callback_object2] }
|
449
|
-
]
|
450
|
-
text_box = described_class.new(array, document: pdf)
|
451
|
-
text_box.render
|
452
|
-
|
453
|
-
expect(callback_object).to have_received(:render_behind).with(
|
454
|
-
kind_of(Prawn::Text::Formatted::Fragment)
|
455
|
-
)
|
456
|
-
expect(callback_object).to have_received(:render_in_front).with(
|
457
|
-
kind_of(Prawn::Text::Formatted::Fragment)
|
458
|
-
)
|
459
|
-
expect(callback_object2).to have_received(:render_behind).with(
|
460
|
-
kind_of(Prawn::Text::Formatted::Fragment)
|
461
|
-
)
|
462
|
-
expect(callback_object2).to have_received(:render_in_front).with(
|
463
|
-
kind_of(Prawn::Text::Formatted::Fragment)
|
464
|
-
)
|
465
|
-
end
|
466
|
-
|
467
|
-
it 'fragment callbacks is able to define only the callback they need' do
|
468
|
-
behind = (
|
469
|
-
Class.new do
|
470
|
-
def initialize(_string, _number, _options); end
|
471
|
-
|
472
|
-
def render_behind(fragment); end
|
473
|
-
end
|
474
|
-
).new(
|
475
|
-
'something',
|
476
|
-
7,
|
477
|
-
document: pdf
|
478
|
-
)
|
479
|
-
in_front = (
|
480
|
-
Class.new do
|
481
|
-
def initialize(_string, _number, _options); end
|
482
|
-
|
483
|
-
def render_in_front(fragment); end
|
484
|
-
end
|
485
|
-
).new(
|
486
|
-
'something',
|
487
|
-
7,
|
488
|
-
document: pdf
|
489
|
-
)
|
490
|
-
array = [
|
491
|
-
{ text: 'hello world ' },
|
492
|
-
{ text: 'callback now', callback: [behind, in_front] }
|
493
|
-
]
|
494
|
-
text_box = described_class.new(array, document: pdf)
|
495
|
-
|
496
|
-
text_box.render # trigger callbacks
|
497
|
-
end
|
498
|
-
|
499
|
-
it 'is able to set the font' do
|
500
|
-
array = [
|
501
|
-
{ text: 'this contains ' },
|
502
|
-
{
|
503
|
-
text: 'Times-Bold',
|
504
|
-
styles: [:bold],
|
505
|
-
font: 'Times-Roman'
|
506
|
-
},
|
507
|
-
{ text: ' text' }
|
508
|
-
]
|
509
|
-
text_box = described_class.new(array, document: pdf)
|
510
|
-
text_box.render
|
511
|
-
contents = PDF::Inspector::Text.analyze(pdf.render)
|
512
|
-
fonts = contents.font_settings.map { |e| e[:name] }
|
513
|
-
expect(fonts).to eq(%i[Helvetica Times-Bold Helvetica])
|
514
|
-
expect(contents.strings[0]).to eq('this contains ')
|
515
|
-
expect(contents.strings[1]).to eq('Times-Bold')
|
516
|
-
expect(contents.strings[2]).to eq(' text')
|
517
|
-
end
|
518
|
-
|
519
|
-
it 'is able to set bold' do
|
520
|
-
array = [
|
521
|
-
{ text: 'this contains ' },
|
522
|
-
{ text: 'bold', styles: [:bold] },
|
523
|
-
{ text: ' text' }
|
524
|
-
]
|
525
|
-
text_box = described_class.new(array, document: pdf)
|
526
|
-
text_box.render
|
527
|
-
contents = PDF::Inspector::Text.analyze(pdf.render)
|
528
|
-
fonts = contents.font_settings.map { |e| e[:name] }
|
529
|
-
expect(fonts).to eq(%i[Helvetica Helvetica-Bold Helvetica])
|
530
|
-
expect(contents.strings[0]).to eq('this contains ')
|
531
|
-
expect(contents.strings[1]).to eq('bold')
|
532
|
-
expect(contents.strings[2]).to eq(' text')
|
533
|
-
end
|
534
|
-
|
535
|
-
it 'is able to set italics' do
|
536
|
-
array = [
|
537
|
-
{ text: 'this contains ' },
|
538
|
-
{ text: 'italic', styles: [:italic] },
|
539
|
-
{ text: ' text' }
|
540
|
-
]
|
541
|
-
text_box = described_class.new(array, document: pdf)
|
542
|
-
text_box.render
|
543
|
-
contents = PDF::Inspector::Text.analyze(pdf.render)
|
544
|
-
fonts = contents.font_settings.map { |e| e[:name] }
|
545
|
-
expect(fonts).to eq(%i[Helvetica Helvetica-Oblique Helvetica])
|
546
|
-
end
|
547
|
-
|
548
|
-
it 'is able to set subscript' do
|
549
|
-
array = [
|
550
|
-
{ text: 'this contains ' },
|
551
|
-
{ text: 'subscript', size: 18, styles: [:subscript] },
|
552
|
-
{ text: ' text' }
|
553
|
-
]
|
554
|
-
text_box = described_class.new(array, document: pdf)
|
555
|
-
text_box.render
|
556
|
-
contents = PDF::Inspector::Text.analyze(pdf.render)
|
557
|
-
expect(contents.font_settings[0][:size]).to eq(12)
|
558
|
-
expect(contents.font_settings[1][:size])
|
559
|
-
.to be_within(0.0001).of(18 * 0.583)
|
560
|
-
end
|
561
|
-
|
562
|
-
it 'is able to set superscript' do
|
563
|
-
array = [
|
564
|
-
{ text: 'this contains ' },
|
565
|
-
{ text: 'superscript', size: 18, styles: [:superscript] },
|
566
|
-
{ text: ' text' }
|
567
|
-
]
|
568
|
-
text_box = described_class.new(array, document: pdf)
|
569
|
-
text_box.render
|
570
|
-
contents = PDF::Inspector::Text.analyze(pdf.render)
|
571
|
-
expect(contents.font_settings[0][:size]).to eq(12)
|
572
|
-
expect(contents.font_settings[1][:size])
|
573
|
-
.to be_within(0.0001).of(18 * 0.583)
|
574
|
-
end
|
575
|
-
|
576
|
-
it 'is able to set compound bold and italic text' do
|
577
|
-
array = [
|
578
|
-
{ text: 'this contains ' },
|
579
|
-
{ text: 'bold italic', styles: %i[bold italic] },
|
580
|
-
{ text: ' text' }
|
581
|
-
]
|
582
|
-
text_box = described_class.new(array, document: pdf)
|
583
|
-
text_box.render
|
584
|
-
contents = PDF::Inspector::Text.analyze(pdf.render)
|
585
|
-
fonts = contents.font_settings.map { |e| e[:name] }
|
586
|
-
expect(fonts).to eq(%i[Helvetica Helvetica-BoldOblique Helvetica])
|
587
|
-
end
|
588
|
-
|
589
|
-
it 'is able to underline' do
|
590
|
-
array = [
|
591
|
-
{ text: 'this contains ' },
|
592
|
-
{ text: 'underlined', styles: [:underline] },
|
593
|
-
{ text: ' text' }
|
594
|
-
]
|
595
|
-
text_box = described_class.new(array, document: pdf)
|
596
|
-
text_box.render
|
597
|
-
line_drawing = PDF::Inspector::Graphics::Line.analyze(pdf.render)
|
598
|
-
expect(line_drawing.points.length).to eq(2)
|
599
|
-
end
|
600
|
-
|
601
|
-
it 'is able to strikethrough' do
|
602
|
-
array = [
|
603
|
-
{ text: 'this contains ' },
|
604
|
-
{ text: 'struckthrough', styles: [:strikethrough] },
|
605
|
-
{ text: ' text' }
|
606
|
-
]
|
607
|
-
text_box = described_class.new(array, document: pdf)
|
608
|
-
text_box.render
|
609
|
-
line_drawing = PDF::Inspector::Graphics::Line.analyze(pdf.render)
|
610
|
-
expect(line_drawing.points.length).to eq(2)
|
611
|
-
end
|
612
|
-
|
613
|
-
it 'is able to add URL links' do
|
614
|
-
allow(pdf).to receive(:link_annotation)
|
615
|
-
array = [
|
616
|
-
{ text: 'click ' },
|
617
|
-
{ text: 'here', link: 'http://example.com' },
|
618
|
-
{ text: ' to visit' }
|
619
|
-
]
|
620
|
-
text_box = described_class.new(array, document: pdf)
|
621
|
-
text_box.render
|
622
|
-
|
623
|
-
expect(pdf).to have_received(:link_annotation).with(
|
624
|
-
kind_of(Array),
|
625
|
-
Border: [0, 0, 0],
|
626
|
-
A: {
|
627
|
-
Type: :Action,
|
628
|
-
S: :URI,
|
629
|
-
URI: 'http://example.com'
|
630
|
-
}
|
631
|
-
)
|
632
|
-
end
|
633
|
-
|
634
|
-
it 'is able to add destination links' do
|
635
|
-
allow(pdf).to receive(:link_annotation)
|
636
|
-
array = [
|
637
|
-
{ text: 'Go to the ' },
|
638
|
-
{ text: 'Table of Contents', anchor: 'ToC' }
|
639
|
-
]
|
640
|
-
text_box = described_class.new(array, document: pdf)
|
641
|
-
text_box.render
|
642
|
-
|
643
|
-
expect(pdf).to have_received(:link_annotation).with(
|
644
|
-
kind_of(Array),
|
645
|
-
Border: [0, 0, 0],
|
646
|
-
Dest: 'ToC'
|
647
|
-
)
|
648
|
-
end
|
649
|
-
|
650
|
-
it 'is able to add local actions' do
|
651
|
-
allow(pdf).to receive(:link_annotation)
|
652
|
-
array = [
|
653
|
-
{ text: 'click ' },
|
654
|
-
{ text: 'here', local: '../example.pdf' },
|
655
|
-
{ text: ' to open a local file' }
|
656
|
-
]
|
657
|
-
text_box = described_class.new(array, document: pdf)
|
658
|
-
text_box.render
|
659
|
-
|
660
|
-
expect(pdf).to have_received(:link_annotation).with(
|
661
|
-
kind_of(Array),
|
662
|
-
Border: [0, 0, 0],
|
663
|
-
A: {
|
664
|
-
Type: :Action,
|
665
|
-
S: :Launch,
|
666
|
-
F: '../example.pdf',
|
667
|
-
NewWindow: true
|
668
|
-
}
|
669
|
-
)
|
670
|
-
end
|
671
|
-
|
672
|
-
it 'is able to set font size' do
|
673
|
-
array = [
|
674
|
-
{ text: 'this contains ' },
|
675
|
-
{ text: 'sized', size: 24 },
|
676
|
-
{ text: ' text' }
|
677
|
-
]
|
678
|
-
text_box = described_class.new(array, document: pdf)
|
679
|
-
text_box.render
|
680
|
-
contents = PDF::Inspector::Text.analyze(pdf.render)
|
681
|
-
expect(contents.font_settings[0][:size]).to eq(12)
|
682
|
-
expect(contents.font_settings[1][:size]).to eq(24)
|
683
|
-
end
|
684
|
-
|
685
|
-
it 'sets the baseline based on the tallest fragment on a given line' do
|
686
|
-
array = [
|
687
|
-
{ text: 'this contains ' },
|
688
|
-
{ text: 'sized', size: 24 },
|
689
|
-
{ text: ' text' }
|
690
|
-
]
|
691
|
-
text_box = described_class.new(array, document: pdf)
|
692
|
-
text_box.render
|
693
|
-
pdf.font_size(24) do
|
694
|
-
expect(text_box.height).to be_within(0.001)
|
695
|
-
.of(pdf.font.ascender + pdf.font.descender)
|
696
|
-
end
|
697
|
-
end
|
698
|
-
|
699
|
-
it 'is able to set color via an rgb hex string' do
|
700
|
-
array = [{
|
701
|
-
text: 'rgb',
|
702
|
-
color: 'ff0000'
|
703
|
-
}]
|
704
|
-
text_box = described_class.new(array, document: pdf)
|
705
|
-
text_box.render
|
706
|
-
colors = PDF::Inspector::Graphics::Color.analyze(pdf.render)
|
707
|
-
expect(colors.fill_color_count).to eq(2)
|
708
|
-
expect(colors.stroke_color_count).to eq(2)
|
709
|
-
end
|
710
|
-
|
711
|
-
it 'is able to set color using a cmyk array' do
|
712
|
-
array = [{
|
713
|
-
text: 'cmyk',
|
714
|
-
color: [100, 0, 0, 0]
|
715
|
-
}]
|
716
|
-
text_box = described_class.new(array, document: pdf)
|
717
|
-
text_box.render
|
718
|
-
colors = PDF::Inspector::Graphics::Color.analyze(pdf.render)
|
719
|
-
expect(colors.fill_color_count).to eq(2)
|
720
|
-
expect(colors.stroke_color_count).to eq(2)
|
721
|
-
end
|
722
|
-
end
|
723
|
-
|
724
|
-
describe 'Text::Formatted::Box#render(:dry_run => true)' do
|
725
|
-
it 'does not change the graphics state of the document' do
|
726
|
-
state_before = PDF::Inspector::Graphics::Color.analyze(pdf.render)
|
727
|
-
fill_color_count = state_before.fill_color_count
|
728
|
-
stroke_color_count = state_before.stroke_color_count
|
729
|
-
stroke_color_space_count = state_before.stroke_color_space_count
|
730
|
-
|
731
|
-
array = [{
|
732
|
-
text: 'Foo',
|
733
|
-
color: [0, 0, 0, 100]
|
734
|
-
}]
|
735
|
-
options = { document: pdf }
|
736
|
-
text_box = described_class.new(array, options)
|
737
|
-
text_box.render(dry_run: true)
|
738
|
-
|
739
|
-
state_after = PDF::Inspector::Graphics::Color.analyze(pdf.render)
|
740
|
-
expect(state_after.fill_color_count).to eq(fill_color_count)
|
741
|
-
expect(state_after.stroke_color_count).to eq(stroke_color_count)
|
742
|
-
expect(state_after.stroke_color_space_count)
|
743
|
-
.to eq(stroke_color_space_count)
|
744
|
-
end
|
745
|
-
end
|
746
|
-
|
747
|
-
describe 'Text::Formatted::Box#render with fragment level '\
|
748
|
-
':character_spacing option' do
|
749
|
-
it 'draws the character spacing to the document' do
|
750
|
-
array = [{
|
751
|
-
text: 'hello world',
|
752
|
-
character_spacing: 7
|
753
|
-
}]
|
754
|
-
options = { document: pdf }
|
755
|
-
text_box = described_class.new(array, options)
|
756
|
-
text_box.render
|
757
|
-
contents = PDF::Inspector::Text.analyze(pdf.render)
|
758
|
-
expect(contents.character_spacing[0]).to eq(7)
|
759
|
-
end
|
760
|
-
|
761
|
-
it 'lays out text properly' do
|
762
|
-
array = [{
|
763
|
-
text: 'hello world',
|
764
|
-
font: 'Courier',
|
765
|
-
character_spacing: 10
|
766
|
-
}]
|
767
|
-
options = {
|
768
|
-
document: pdf,
|
769
|
-
width: 100,
|
770
|
-
overflow: :expand
|
771
|
-
}
|
772
|
-
text_box = described_class.new(array, options)
|
773
|
-
text_box.render
|
774
|
-
expect(text_box.text).to eq("hello\nworld")
|
775
|
-
end
|
776
|
-
end
|
777
|
-
|
778
|
-
describe 'Text::Formatted::Box#render with :align => :justify' do
|
779
|
-
it 'does not justify the last line of a paragraph' do
|
780
|
-
array = [
|
781
|
-
{ text: 'hello world ' },
|
782
|
-
{ text: "\n" },
|
783
|
-
{ text: 'goodbye' }
|
784
|
-
]
|
785
|
-
options = { document: pdf, align: :justify }
|
786
|
-
text_box = described_class.new(array, options)
|
787
|
-
text_box.render
|
788
|
-
contents = PDF::Inspector::Text.analyze(pdf.render)
|
789
|
-
expect(contents.word_spacing).to be_empty
|
790
|
-
end
|
791
|
-
|
792
|
-
it 'raise an exception when align value is not a symbol' do
|
793
|
-
array = [
|
794
|
-
{ text: 'hello world ' },
|
795
|
-
{ text: "\n" },
|
796
|
-
{ text: 'goodbye' }
|
797
|
-
]
|
798
|
-
options = { document: pdf, align: 'justify' }
|
799
|
-
text_box = described_class.new(array, options)
|
800
|
-
expect { text_box.render }.to raise_error(
|
801
|
-
ArgumentError,
|
802
|
-
'align must be one of :left, :right, :center or :justify symbols'
|
803
|
-
)
|
804
|
-
end
|
805
|
-
end
|
806
|
-
|
807
|
-
describe 'Text::Formatted::Box#render with :valign => :center' do
|
808
|
-
it 'has a bottom gap equal to baseline and bottom of box' do
|
809
|
-
box_height = 100
|
810
|
-
y = 450
|
811
|
-
array = [{ text: 'Vertical Align' }]
|
812
|
-
options = {
|
813
|
-
document: pdf,
|
814
|
-
valign: :center,
|
815
|
-
at: [0, y],
|
816
|
-
width: 100,
|
817
|
-
height: box_height,
|
818
|
-
size: 16
|
819
|
-
}
|
820
|
-
text_box = described_class.new(array, options)
|
821
|
-
text_box.render
|
822
|
-
line_padding = (box_height - text_box.height + text_box.descender) * 0.5
|
823
|
-
baseline = y - line_padding
|
824
|
-
|
825
|
-
expect(text_box.at[1]).to be_within(0.01).of(baseline)
|
826
|
-
end
|
827
|
-
end
|
828
|
-
|
829
|
-
describe 'Text::Formatted::Box#render with :valign => :bottom' do
|
830
|
-
it 'does not render a gap between the text and bottom of box' do
|
831
|
-
box_height = 100
|
832
|
-
y = 450
|
833
|
-
array = [{ text: 'Vertical Align' }]
|
834
|
-
options = {
|
835
|
-
document: pdf,
|
836
|
-
valign: :bottom,
|
837
|
-
at: [0, y],
|
838
|
-
width: 100,
|
839
|
-
height: box_height,
|
840
|
-
size: 16
|
841
|
-
}
|
842
|
-
text_box = described_class.new(array, options)
|
843
|
-
text_box.render
|
844
|
-
top_padding = y - (box_height - text_box.height)
|
845
|
-
|
846
|
-
expect(text_box.at[1]).to be_within(0.01).of(top_padding)
|
847
|
-
end
|
848
|
-
end
|
849
|
-
end
|