prawn 2.3.0 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|