prawn 2.3.0 → 2.4.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.tar.gz.sig +0 -0
- data/Rakefile +2 -31
- data/lib/prawn.rb +1 -0
- data/lib/prawn/document.rb +20 -15
- data/lib/prawn/document/bounding_box.rb +10 -2
- data/lib/prawn/document/span.rb +2 -1
- data/lib/prawn/font.rb +6 -4
- data/lib/prawn/font_metric_cache.rb +7 -6
- data/lib/prawn/fonts/afm.rb +18 -16
- data/lib/prawn/fonts/ttf.rb +55 -29
- data/lib/prawn/graphics.rb +11 -11
- data/lib/prawn/graphics/color.rb +18 -16
- data/lib/prawn/graphics/join_style.rb +1 -1
- data/lib/prawn/graphics/patterns.rb +57 -49
- data/lib/prawn/graphics/transformation.rb +3 -3
- data/lib/prawn/grid.rb +36 -1
- data/lib/prawn/images.rb +29 -27
- data/lib/prawn/images/jpg.rb +4 -1
- data/lib/prawn/images/png.rb +2 -1
- data/lib/prawn/outline.rb +6 -5
- data/lib/prawn/repeater.rb +1 -1
- data/lib/prawn/security.rb +39 -36
- data/lib/prawn/text.rb +18 -18
- data/lib/prawn/text/box.rb +10 -9
- data/lib/prawn/text/formatted/arranger.rb +38 -19
- data/lib/prawn/text/formatted/box.rb +20 -15
- data/lib/prawn/text/formatted/line_wrap.rb +18 -16
- data/lib/prawn/text/formatted/parser.rb +28 -26
- data/lib/prawn/text/formatted/wrap.rb +15 -11
- data/lib/prawn/version.rb +1 -1
- data/lib/prawn/view.rb +2 -2
- data/manual/basic_concepts/measurement.rb +1 -1
- data/manual/bounding_box/canvas.rb +3 -3
- data/manual/bounding_box/nesting.rb +1 -1
- data/manual/document_and_page_options/background.rb +6 -2
- data/manual/document_and_page_options/document_and_page_options.rb +3 -3
- data/manual/document_and_page_options/print_scaling.rb +2 -1
- data/manual/graphics/common_lines.rb +1 -1
- data/manual/graphics/fill_and_stroke.rb +1 -1
- data/manual/graphics/fill_rules.rb +4 -3
- data/manual/graphics/helper.rb +11 -4
- data/manual/graphics/lines_and_curves.rb +1 -1
- data/manual/graphics/stroke_dash.rb +5 -5
- data/manual/graphics/translate.rb +2 -1
- data/manual/images/horizontal.rb +2 -2
- data/manual/images/scale.rb +3 -3
- data/manual/images/vertical.rb +6 -3
- data/manual/images/width_and_height.rb +3 -3
- data/manual/layout/content.rb +2 -2
- data/manual/outline/outline.rb +1 -1
- data/manual/security/permissions.rb +4 -2
- data/manual/security/security.rb +1 -1
- data/manual/text/alignment.rb +2 -2
- data/manual/text/column_box.rb +2 -2
- data/manual/text/font_style.rb +5 -2
- data/manual/text/formatted_callbacks.rb +17 -12
- data/manual/text/formatted_text.rb +7 -4
- data/manual/text/free_flowing_text.rb +3 -3
- data/manual/text/kerning_and_character_spacing.rb +4 -4
- data/manual/text/paragraph_indentation.rb +4 -5
- data/manual/text/rendering_and_color.rb +1 -1
- data/manual/text/right_to_left_text.rb +6 -6
- data/manual/text/rotation.rb +8 -3
- data/manual/text/text_box_extensions.rb +1 -1
- data/manual/text/text_box_overflow.rb +11 -9
- data/manual/text/win_ansi_charset.rb +9 -9
- data/prawn.gemspec +4 -10
- data/spec/prawn/document/bounding_box_spec.rb +82 -78
- data/spec/prawn/document/security_spec.rb +1 -1
- data/spec/prawn/document_span_spec.rb +14 -6
- data/spec/prawn/document_spec.rb +29 -26
- data/spec/prawn/font_spec.rb +16 -14
- data/spec/prawn/graphics_spec.rb +79 -44
- data/spec/prawn/images_spec.rb +13 -8
- data/spec/prawn/outline_spec.rb +127 -27
- data/spec/prawn/repeater_spec.rb +9 -8
- data/spec/prawn/soft_mask_spec.rb +1 -1
- data/spec/prawn/stamp_spec.rb +3 -2
- data/spec/prawn/text/box_spec.rb +57 -59
- data/spec/prawn/text/formatted/arranger_spec.rb +10 -10
- data/spec/prawn/text/formatted/box_spec.rb +8 -5
- data/spec/prawn/text/formatted/line_wrap_spec.rb +2 -1
- data/spec/prawn/text_draw_text_spec.rb +9 -8
- data/spec/prawn/text_spacing_spec.rb +2 -2
- data/spec/prawn/text_spec.rb +9 -9
- data/spec/prawn/text_with_inline_formatting_spec.rb +1 -1
- data/spec/prawn_manual_spec.rb +4 -4
- metadata +14 -98
- metadata.gz.sig +0 -0
data/lib/prawn/outline.rb
CHANGED
@@ -264,11 +264,12 @@ module Prawn
|
|
264
264
|
counting_parent = parent
|
265
265
|
while counting_parent
|
266
266
|
counting_parent.data.count += 1
|
267
|
-
counting_parent =
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
267
|
+
counting_parent =
|
268
|
+
if counting_parent == root
|
269
|
+
nil
|
270
|
+
else
|
271
|
+
counting_parent.data.parent
|
272
|
+
end
|
272
273
|
end
|
273
274
|
end
|
274
275
|
|
data/lib/prawn/repeater.rb
CHANGED
@@ -115,7 +115,7 @@ module Prawn
|
|
115
115
|
@document.stamp(@stamp_name) if match?(page_number)
|
116
116
|
elsif @block && match?(page_number)
|
117
117
|
@document.save_graphics_state(@graphic_state) do
|
118
|
-
@document.
|
118
|
+
@document.__send__(:freeze_stamp_graphics)
|
119
119
|
@block.call
|
120
120
|
end
|
121
121
|
end
|
data/lib/prawn/security.rb
CHANGED
@@ -124,8 +124,8 @@ module Prawn
|
|
124
124
|
def encryption_dictionary
|
125
125
|
{
|
126
126
|
Filter: :Standard, # default PDF security handler
|
127
|
-
V: 1,
|
128
|
-
R: 2,
|
127
|
+
V: 1, # "Algorithm 3.1", PDF reference 1.3
|
128
|
+
R: 2, # Revision 2 of the algorithm
|
129
129
|
O: PDF::Core::ByteString.new(owner_password_hash),
|
130
130
|
U: PDF::Core::ByteString.new(user_password_hash),
|
131
131
|
P: permissions_value
|
@@ -181,21 +181,23 @@ module Prawn
|
|
181
181
|
end
|
182
182
|
|
183
183
|
def user_encryption_key
|
184
|
-
@user_encryption_key ||=
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
184
|
+
@user_encryption_key ||=
|
185
|
+
begin
|
186
|
+
md5 = Digest::MD5.new
|
187
|
+
md5 << pad_password(@user_password)
|
188
|
+
md5 << owner_password_hash
|
189
|
+
md5 << [permissions_value].pack('V')
|
190
|
+
md5.digest[0, 5]
|
191
|
+
end
|
191
192
|
end
|
192
193
|
|
193
194
|
# The O (owner) value in the encryption dictionary. Algorithm 3.3.
|
194
195
|
def owner_password_hash
|
195
|
-
@owner_password_hash ||=
|
196
|
-
|
197
|
-
|
198
|
-
|
196
|
+
@owner_password_hash ||=
|
197
|
+
begin
|
198
|
+
key = Digest::MD5.digest(pad_password(@owner_password))[0, 5]
|
199
|
+
Arcfour.new(key).encrypt(pad_password(@user_password))
|
200
|
+
end
|
199
201
|
end
|
200
202
|
|
201
203
|
# The U (user) value in the encryption dictionary. Algorithm 3.4.
|
@@ -219,19 +221,22 @@ module PDF
|
|
219
221
|
def encrypted_pdf_object(obj, key, id, gen, in_content_stream = false)
|
220
222
|
case obj
|
221
223
|
when Array
|
222
|
-
|
224
|
+
array_content = obj.map do |e|
|
223
225
|
encrypted_pdf_object(e, key, id, gen, in_content_stream)
|
224
|
-
end.join(' ')
|
226
|
+
end.join(' ')
|
227
|
+
"[#{array_content}]"
|
225
228
|
when LiteralString
|
226
|
-
obj =
|
227
|
-
|
228
|
-
|
229
|
+
obj =
|
230
|
+
ByteString.new(
|
231
|
+
Prawn::Document::Security.encrypt_string(obj, key, id, gen)
|
232
|
+
).gsub(/[\\\n()]/) { |m| "\\#{m}" }
|
229
233
|
"(#{obj})"
|
230
234
|
when Time
|
231
|
-
obj = obj.strftime('D:%Y%m%d%H%M%S%z').chop.chop
|
232
|
-
obj =
|
233
|
-
|
234
|
-
|
235
|
+
obj = "#{obj.strftime('D:%Y%m%d%H%M%S%z').chop.chop}'00'"
|
236
|
+
obj =
|
237
|
+
ByteString.new(
|
238
|
+
Prawn::Document::Security.encrypt_string(obj, key, id, gen)
|
239
|
+
).gsub(/[\\\n()]/) { |m| "\\#{m}" }
|
235
240
|
"(#{obj})"
|
236
241
|
when String
|
237
242
|
pdf_object(
|
@@ -241,19 +246,16 @@ module PDF
|
|
241
246
|
in_content_stream
|
242
247
|
)
|
243
248
|
when ::Hash
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
end.join('') +
|
253
|
-
'>>'
|
249
|
+
hash_content = obj.map do |k, v|
|
250
|
+
unless k.is_a?(String) || k.is_a?(Symbol)
|
251
|
+
raise PDF::Core::Errors::FailedObjectConversion,
|
252
|
+
'A PDF Dictionary must be keyed by names'
|
253
|
+
end
|
254
|
+
"#{pdf_object(k.to_sym, in_content_stream)} #{encrypted_pdf_object(v, key, id, gen, in_content_stream)}\n"
|
255
|
+
end.join('')
|
256
|
+
"<< #{hash_content}>>"
|
254
257
|
when NameTree::Value
|
255
|
-
pdf_object(obj.name)
|
256
|
-
encrypted_pdf_object(obj.value, key, id, gen, in_content_stream)
|
258
|
+
"#{pdf_object(obj.name)} #{encrypted_pdf_object(obj.value, key, id, gen, in_content_stream)}"
|
257
259
|
when PDF::Core::OutlineRoot, PDF::Core::OutlineItem
|
258
260
|
encrypted_pdf_object(obj.to_hash, key, id, gen, in_content_stream)
|
259
261
|
else # delegate back to pdf_object
|
@@ -265,10 +267,11 @@ module PDF
|
|
265
267
|
class Stream
|
266
268
|
def encrypted_object(key, id, gen)
|
267
269
|
if filtered_stream
|
268
|
-
"stream\n
|
270
|
+
"stream\n#{
|
269
271
|
Prawn::Document::Security.encrypt_string(
|
270
272
|
filtered_stream, key, id, gen
|
271
|
-
)
|
273
|
+
)
|
274
|
+
}\nendstream\n"
|
272
275
|
else
|
273
276
|
''
|
274
277
|
end
|
data/lib/prawn/text.rb
CHANGED
@@ -192,21 +192,19 @@ module Prawn
|
|
192
192
|
|
193
193
|
color = options.delete(:color)
|
194
194
|
if color
|
195
|
-
array =
|
196
|
-
|
197
|
-
|
195
|
+
array =
|
196
|
+
array.map do |fragment|
|
197
|
+
fragment[:color] ? fragment : fragment.merge(color: color)
|
198
|
+
end
|
198
199
|
end
|
199
200
|
|
200
201
|
if @indent_paragraphs
|
201
202
|
text_formatter.array_paragraphs(array).each do |paragraph|
|
202
203
|
remaining_text = draw_indented_formatted_line(paragraph, options)
|
203
204
|
|
204
|
-
if @no_text_printed
|
205
|
-
|
206
|
-
|
207
|
-
@bounding_box.move_past_bottom
|
208
|
-
remaining_text = draw_indented_formatted_line(paragraph, options)
|
209
|
-
end
|
205
|
+
if @no_text_printed && !@all_text_printed
|
206
|
+
@bounding_box.move_past_bottom
|
207
|
+
remaining_text = draw_indented_formatted_line(paragraph, options)
|
210
208
|
end
|
211
209
|
|
212
210
|
unless @all_text_printed
|
@@ -337,8 +335,8 @@ module Prawn
|
|
337
335
|
#
|
338
336
|
def height_of_formatted(array, options = {})
|
339
337
|
if options[:indent_paragraphs]
|
340
|
-
raise NotImplementedError,
|
341
|
-
'with height_of'
|
338
|
+
raise NotImplementedError,
|
339
|
+
':indent_paragraphs option not available with height_of'
|
342
340
|
end
|
343
341
|
process_final_gap_option(options)
|
344
342
|
box = Text::Formatted::Box.new(
|
@@ -364,11 +362,12 @@ module Prawn
|
|
364
362
|
end
|
365
363
|
|
366
364
|
def draw_indented_formatted_line(string, options)
|
367
|
-
gap =
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
365
|
+
gap =
|
366
|
+
if options.fetch(:direction, text_direction) == :ltr
|
367
|
+
[@indent_paragraphs, 0]
|
368
|
+
else
|
369
|
+
[0, @indent_paragraphs]
|
370
|
+
end
|
372
371
|
|
373
372
|
indent(*gap) do
|
374
373
|
fill_formatted_text_box(string, options.dup.merge(single_line: true))
|
@@ -421,8 +420,9 @@ module Prawn
|
|
421
420
|
|
422
421
|
def inspect_options_for_text(options)
|
423
422
|
if options[:at]
|
424
|
-
raise ArgumentError,
|
425
|
-
|
423
|
+
raise ArgumentError,
|
424
|
+
':at is no longer a valid option with text.' \
|
425
|
+
'use draw_text or text_box instead'
|
426
426
|
end
|
427
427
|
process_final_gap_option(options)
|
428
428
|
process_indent_paragraphs_option(options)
|
data/lib/prawn/text/box.rb
CHANGED
@@ -107,14 +107,15 @@ module Prawn
|
|
107
107
|
options = options.dup
|
108
108
|
options[:document] = self
|
109
109
|
|
110
|
-
box =
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
110
|
+
box =
|
111
|
+
if options[:inline_format]
|
112
|
+
p = options.delete(:inline_format)
|
113
|
+
p = [] unless p.is_a?(Array)
|
114
|
+
array = text_formatter.format(string, *p)
|
115
|
+
Text::Formatted::Box.new(array, options)
|
116
|
+
else
|
117
|
+
Text::Box.new(string, options)
|
118
|
+
end
|
118
119
|
|
119
120
|
box.render
|
120
121
|
end
|
@@ -134,7 +135,7 @@ module Prawn
|
|
134
135
|
|
135
136
|
def render(flags = {})
|
136
137
|
leftover = super(flags)
|
137
|
-
leftover.
|
138
|
+
leftover.map { |hash| hash[:text] }.join
|
138
139
|
end
|
139
140
|
end
|
140
141
|
end
|
@@ -13,6 +13,25 @@ module Prawn
|
|
13
13
|
# @private
|
14
14
|
|
15
15
|
class Arranger #:nodoc:
|
16
|
+
class NotFinalized < StandardError
|
17
|
+
DEFAULT_MESSAGE = 'Lines must be finalized'
|
18
|
+
MESSAGE_WITH_METHOD = 'Lines must be finalized before calling #%<method>s'
|
19
|
+
|
20
|
+
def initialize(message = DEFAULT_MESSAGE, method: nil)
|
21
|
+
if method && message == DEFAULT_MESSAGE
|
22
|
+
super format(MESSAGE_WITH_METHOD, method: method)
|
23
|
+
else
|
24
|
+
super message
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class BadFontFamily < StandardError
|
30
|
+
def initialize(message = 'Bad font family')
|
31
|
+
super
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
16
35
|
attr_reader :max_line_height
|
17
36
|
attr_reader :max_descender
|
18
37
|
attr_reader :max_ascender
|
@@ -33,30 +52,30 @@ module Prawn
|
|
33
52
|
|
34
53
|
def space_count
|
35
54
|
unless finalized
|
36
|
-
raise '
|
55
|
+
raise NotFinalized.new(method: 'space_count')
|
37
56
|
end
|
38
57
|
|
39
|
-
@fragments.
|
58
|
+
@fragments.reduce(0) do |sum, fragment|
|
40
59
|
sum + fragment.space_count
|
41
60
|
end
|
42
61
|
end
|
43
62
|
|
44
63
|
def line_width
|
45
64
|
unless finalized
|
46
|
-
raise
|
65
|
+
raise raise NotFinalized.new(method: 'line_width')
|
47
66
|
end
|
48
67
|
|
49
|
-
@fragments.
|
68
|
+
@fragments.reduce(0) do |sum, fragment|
|
50
69
|
sum + fragment.width
|
51
70
|
end
|
52
71
|
end
|
53
72
|
|
54
73
|
def line
|
55
74
|
unless finalized
|
56
|
-
raise '
|
75
|
+
raise NotFinalized.new(method: 'line')
|
57
76
|
end
|
58
77
|
|
59
|
-
@fragments.
|
78
|
+
@fragments.map do |fragment|
|
60
79
|
fragment.text.dup.encode(::Encoding::UTF_8)
|
61
80
|
rescue ::Encoding::InvalidByteSequenceError,
|
62
81
|
::Encoding::UndefinedConversionError
|
@@ -110,7 +129,7 @@ module Prawn
|
|
110
129
|
|
111
130
|
def next_string
|
112
131
|
if finalized
|
113
|
-
raise '
|
132
|
+
raise NotFinalized.new(method: 'next_string')
|
114
133
|
end
|
115
134
|
|
116
135
|
next_unconsumed_hash = @unconsumed.shift
|
@@ -163,7 +182,7 @@ module Prawn
|
|
163
182
|
|
164
183
|
@document.character_spacing(character_spacing) do
|
165
184
|
if font || font_style != :normal
|
166
|
-
raise
|
185
|
+
raise BadFontFamily unless @document.font.family
|
167
186
|
|
168
187
|
@document.font(
|
169
188
|
font || @document.font.family, style: font_style
|
@@ -197,7 +216,7 @@ module Prawn
|
|
197
216
|
|
198
217
|
def retrieve_fragment
|
199
218
|
unless finalized
|
200
|
-
raise 'Lines must be finalized before fragments can be retrieved'
|
219
|
+
raise NotFinalized, 'Lines must be finalized before fragments can be retrieved'
|
201
220
|
end
|
202
221
|
|
203
222
|
@fragments.shift
|
@@ -215,9 +234,8 @@ module Prawn
|
|
215
234
|
end
|
216
235
|
|
217
236
|
def font_style(styles)
|
218
|
-
|
219
|
-
|
220
|
-
elsif styles.include?(:bold) && styles.include?(:italic)
|
237
|
+
styles = Array(styles)
|
238
|
+
if styles.include?(:bold) && styles.include?(:italic)
|
221
239
|
:bold_italic
|
222
240
|
elsif styles.include?(:bold)
|
223
241
|
:bold
|
@@ -240,19 +258,20 @@ module Prawn
|
|
240
258
|
end
|
241
259
|
end
|
242
260
|
|
243
|
-
def apply_font_size(size, styles)
|
261
|
+
def apply_font_size(size, styles, &block)
|
244
262
|
if subscript?(styles) || superscript?(styles)
|
245
263
|
relative_size = 0.583
|
246
|
-
size =
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
264
|
+
size =
|
265
|
+
if size.nil?
|
266
|
+
@document.font_size * relative_size
|
267
|
+
else
|
268
|
+
size * relative_size
|
269
|
+
end
|
251
270
|
end
|
252
271
|
if size.nil?
|
253
272
|
yield
|
254
273
|
else
|
255
|
-
@document.font_size(size)
|
274
|
+
@document.font_size(size, &block)
|
256
275
|
end
|
257
276
|
end
|
258
277
|
|
@@ -222,11 +222,12 @@ module Prawn
|
|
222
222
|
shrink_to_fit(text) if @overflow == :shrink_to_fit
|
223
223
|
process_vertical_alignment(text)
|
224
224
|
@inked = true unless flags[:dry_run]
|
225
|
-
unprinted_text =
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
225
|
+
unprinted_text =
|
226
|
+
if @rotate != 0 && @inked
|
227
|
+
render_rotated(text)
|
228
|
+
else
|
229
|
+
wrap(text)
|
230
|
+
end
|
230
231
|
@inked = false
|
231
232
|
end
|
232
233
|
end
|
@@ -265,11 +266,12 @@ module Prawn
|
|
265
266
|
when :right
|
266
267
|
x = @at[0] + @width - line_width
|
267
268
|
when :justify
|
268
|
-
x =
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
269
|
+
x =
|
270
|
+
if @direction == :ltr
|
271
|
+
@at[0]
|
272
|
+
else
|
273
|
+
@at[0] + @width - line_width
|
274
|
+
end
|
273
275
|
else
|
274
276
|
raise ArgumentError,
|
275
277
|
'align must be one of :left, :right, :center or :justify symbols'
|
@@ -290,13 +292,15 @@ module Prawn
|
|
290
292
|
@document.word_spacing(word_spacing) do
|
291
293
|
if @draw_text_callback
|
292
294
|
@draw_text_callback.call(
|
293
|
-
fragment.text,
|
294
|
-
|
295
|
+
fragment.text,
|
296
|
+
at: [x, y],
|
297
|
+
kerning: @kerning
|
295
298
|
)
|
296
299
|
else
|
297
300
|
@document.draw_text!(
|
298
|
-
fragment.text,
|
299
|
-
|
301
|
+
fragment.text,
|
302
|
+
at: [x, y],
|
303
|
+
kerning: @kerning
|
300
304
|
)
|
301
305
|
end
|
302
306
|
end
|
@@ -340,6 +344,7 @@ module Prawn
|
|
340
344
|
|
341
345
|
# @private
|
342
346
|
def self.inherited(base)
|
347
|
+
super
|
343
348
|
extensions.each { |e| base.extensions << e }
|
344
349
|
end
|
345
350
|
|
@@ -371,7 +376,7 @@ module Prawn
|
|
371
376
|
end
|
372
377
|
|
373
378
|
def original_text
|
374
|
-
@original_array.
|
379
|
+
@original_array.map(&:dup)
|
375
380
|
end
|
376
381
|
|
377
382
|
def original_text=(formatted_text)
|
@@ -86,18 +86,20 @@ module Prawn
|
|
86
86
|
# the line
|
87
87
|
#
|
88
88
|
def add_fragment_to_line(fragment)
|
89
|
-
|
89
|
+
case fragment
|
90
|
+
when ''
|
90
91
|
true
|
91
|
-
|
92
|
+
when "\n"
|
92
93
|
@newline_encountered = true
|
93
94
|
false
|
94
95
|
else
|
95
96
|
tokenize(fragment).each do |segment|
|
96
|
-
segment_width =
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
97
|
+
segment_width =
|
98
|
+
if segment == zero_width_space(segment.encoding)
|
99
|
+
0
|
100
|
+
else
|
101
|
+
@document.width_of(segment, kerning: @kerning)
|
102
|
+
end
|
101
103
|
|
102
104
|
if @accumulated_width + segment_width <= @width
|
103
105
|
@accumulated_width += segment_width
|
@@ -151,9 +153,10 @@ module Prawn
|
|
151
153
|
# word breaking is needed
|
152
154
|
#
|
153
155
|
def word_division_scan_pattern(encoding = ::Encoding::UTF_8)
|
154
|
-
common_whitespaces =
|
155
|
-
c
|
156
|
-
|
156
|
+
common_whitespaces =
|
157
|
+
["\t", "\n", "\v", "\r", ' '].map do |c|
|
158
|
+
c.encode(encoding)
|
159
|
+
end
|
157
160
|
|
158
161
|
Regexp.union(
|
159
162
|
common_whitespaces +
|
@@ -254,12 +257,11 @@ module Prawn
|
|
254
257
|
|
255
258
|
def pull_preceding_fragment_to_join_this_one?(current_fragment)
|
256
259
|
if @fragment_output.empty? && !current_fragment.empty? &&
|
257
|
-
@line_contains_more_than_one_word
|
258
|
-
|
259
|
-
fragment_begins_with_breakable?(current_fragment)
|
260
|
-
|
261
|
-
|
262
|
-
end
|
260
|
+
@line_contains_more_than_one_word &&
|
261
|
+
!(previous_fragment_ended_with_breakable? ||
|
262
|
+
fragment_begins_with_breakable?(current_fragment))
|
263
|
+
@fragment_output = @previous_fragment_output_without_last_word
|
264
|
+
update_output_based_on_last_fragment(@previous_fragment)
|
263
265
|
end
|
264
266
|
end
|
265
267
|
|