prawn 0.13.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 +5 -5
- checksums.yaml.gz.sig +0 -0
- data/.yardopts +10 -0
- data/GPLv2 +20 -21
- data/Gemfile +3 -16
- data/Rakefile +17 -39
- data/lib/prawn/document/bounding_box.rb +85 -42
- data/lib/prawn/document/column_box.rb +21 -11
- data/lib/prawn/document/internals.rb +40 -147
- data/lib/prawn/document/span.rb +25 -17
- data/lib/prawn/document.rb +286 -245
- data/lib/prawn/encoding.rb +68 -101
- data/lib/prawn/errors.rb +47 -43
- data/lib/prawn/font.rb +204 -155
- data/lib/prawn/font_metric_cache.rb +25 -21
- data/lib/prawn/fonts/afm.rb +292 -0
- data/lib/prawn/{font → fonts}/dfont.rb +7 -13
- data/lib/prawn/fonts/otf.rb +11 -0
- data/lib/prawn/fonts/ttc.rb +36 -0
- data/lib/prawn/{font → fonts}/ttf.rb +142 -80
- data/lib/prawn/graphics/blend_mode.rb +65 -0
- data/lib/prawn/graphics/cap_style.rb +6 -5
- data/lib/prawn/graphics/color.rb +47 -44
- data/lib/prawn/graphics/dash.rb +30 -13
- data/lib/prawn/graphics/join_style.rb +13 -6
- data/lib/prawn/graphics/patterns.rb +221 -90
- data/lib/prawn/graphics/transformation.rb +21 -12
- data/lib/prawn/graphics/transparency.rb +21 -17
- data/lib/prawn/graphics.rb +155 -128
- data/lib/prawn/{layout/grid.rb → grid.rb} +110 -47
- data/lib/prawn/image_handler.rb +16 -2
- data/lib/prawn/images/image.rb +4 -2
- data/lib/prawn/images/jpg.rb +39 -30
- data/lib/prawn/images/png.rb +132 -169
- data/lib/prawn/images.rb +70 -62
- data/lib/prawn/measurement_extensions.rb +15 -10
- data/lib/prawn/measurements.rb +22 -23
- data/lib/prawn/outline.rb +301 -13
- data/lib/prawn/repeater.rb +19 -17
- data/lib/prawn/security/arcfour.rb +54 -0
- data/lib/prawn/security.rb +108 -86
- data/lib/prawn/soft_mask.rb +40 -41
- data/lib/prawn/stamp.rb +29 -12
- data/lib/prawn/text/box.rb +27 -29
- data/lib/prawn/text/formatted/arranger.rb +110 -67
- data/lib/prawn/text/formatted/box.rb +233 -165
- data/lib/prawn/text/formatted/fragment.rb +27 -27
- data/lib/prawn/text/formatted/line_wrap.rb +137 -97
- data/lib/prawn/text/formatted/parser.rb +149 -127
- data/lib/prawn/text/formatted/wrap.rb +57 -37
- data/lib/prawn/text/formatted.rb +6 -4
- data/lib/prawn/text.rb +105 -73
- data/lib/prawn/transformation_stack.rb +44 -0
- data/lib/prawn/utilities.rb +11 -21
- data/lib/prawn/version.rb +5 -0
- data/lib/prawn/view.rb +101 -0
- data/lib/prawn.rb +42 -68
- data/{data/images/fractal.jpg → manual/absolute_position.pdf} +0 -0
- data/manual/basic_concepts/adding_pages.rb +9 -10
- data/manual/basic_concepts/basic_concepts.rb +33 -24
- data/manual/basic_concepts/creation.rb +10 -11
- data/manual/basic_concepts/cursor.rb +9 -10
- data/manual/basic_concepts/measurement.rb +10 -11
- data/manual/basic_concepts/origin.rb +8 -9
- data/manual/basic_concepts/other_cursor_helpers.rb +17 -18
- data/manual/basic_concepts/view.rb +48 -0
- data/manual/bounding_box/bounding_box.rb +31 -29
- data/manual/bounding_box/bounds.rb +17 -18
- data/manual/bounding_box/canvas.rb +8 -9
- data/manual/bounding_box/creation.rb +8 -9
- data/manual/bounding_box/indentation.rb +22 -23
- data/manual/bounding_box/nesting.rb +32 -25
- data/manual/bounding_box/russian_boxes.rb +19 -19
- data/manual/bounding_box/stretchy.rb +18 -20
- data/manual/contents.rb +35 -0
- data/manual/cover.rb +43 -0
- data/manual/document_and_page_options/background.rb +16 -14
- data/manual/document_and_page_options/document_and_page_options.rb +26 -23
- data/manual/document_and_page_options/metadata.rb +21 -19
- data/manual/document_and_page_options/page_margins.rb +20 -22
- data/manual/document_and_page_options/page_size.rb +15 -15
- data/manual/document_and_page_options/print_scaling.rb +23 -0
- data/manual/example_helper.rb +5 -408
- data/manual/graphics/blend_mode.rb +52 -0
- data/manual/graphics/circle_and_ellipse.rb +8 -9
- data/manual/graphics/color.rb +11 -13
- data/manual/graphics/common_lines.rb +13 -12
- data/manual/graphics/fill_and_stroke.rb +10 -11
- data/manual/graphics/fill_rules.rb +13 -12
- data/manual/graphics/gradients.rb +28 -22
- data/manual/graphics/graphics.rb +52 -46
- data/manual/graphics/helper.rb +20 -10
- data/manual/graphics/line_width.rb +13 -12
- data/manual/graphics/lines_and_curves.rb +13 -14
- data/manual/graphics/polygon.rb +10 -12
- data/manual/graphics/rectangle.rb +7 -8
- data/manual/graphics/rotate.rb +9 -12
- data/manual/graphics/scale.rb +19 -18
- data/manual/graphics/soft_masks.rb +5 -7
- data/manual/graphics/stroke_cap.rb +10 -11
- data/manual/graphics/stroke_dash.rb +16 -17
- data/manual/graphics/stroke_join.rb +10 -11
- data/manual/graphics/translate.rb +13 -13
- data/manual/graphics/transparency.rb +11 -13
- data/manual/{manual/how_to_read_this_manual.rb → how_to_read_this_manual.rb} +23 -25
- data/manual/images/absolute_position.rb +9 -10
- data/manual/images/fit.rb +9 -10
- data/manual/images/horizontal.rb +13 -14
- data/manual/images/images.rb +31 -30
- data/manual/images/plain_image.rb +6 -7
- data/manual/images/scale.rb +12 -13
- data/manual/images/vertical.rb +19 -17
- data/manual/images/width_and_height.rb +13 -14
- data/manual/layout/boxes.rb +14 -15
- data/manual/layout/content.rb +12 -13
- data/manual/layout/layout.rb +19 -20
- data/manual/layout/simple_grid.rb +8 -9
- data/manual/outline/add_subsection_to.rb +26 -27
- data/manual/outline/insert_section_after.rb +19 -20
- data/manual/outline/outline.rb +23 -22
- data/manual/outline/sections_and_pages.rb +24 -25
- data/manual/repeatable_content/alternate_page_numbering.rb +36 -0
- data/manual/repeatable_content/page_numbering.rb +20 -19
- data/manual/repeatable_content/repeatable_content.rb +26 -22
- data/manual/repeatable_content/repeater.rb +18 -19
- data/manual/repeatable_content/stamp.rb +18 -19
- data/manual/security/encryption.rb +8 -11
- data/manual/security/permissions.rb +20 -15
- data/manual/security/security.rb +20 -20
- data/manual/table.rb +16 -0
- data/manual/text/alignment.rb +17 -18
- data/manual/text/color.rb +13 -13
- data/manual/text/column_box.rb +10 -12
- data/manual/text/fallback_fonts.rb +29 -25
- data/manual/text/font.rb +17 -18
- data/manual/text/font_size.rb +21 -22
- data/manual/text/font_style.rb +12 -10
- data/manual/text/formatted_callbacks.rb +36 -26
- data/manual/text/formatted_text.rb +41 -34
- data/manual/text/free_flowing_text.rb +28 -29
- data/manual/text/inline.rb +23 -26
- data/manual/text/kerning_and_character_spacing.rb +20 -21
- data/manual/text/leading.rb +10 -11
- data/manual/text/line_wrapping.rb +40 -21
- data/manual/text/paragraph_indentation.rb +17 -12
- data/manual/text/positioned_text.rb +19 -20
- data/manual/text/registering_families.rb +33 -30
- data/manual/text/rendering_and_color.rb +11 -12
- data/manual/text/right_to_left_text.rb +31 -20
- data/manual/text/rotation.rb +36 -27
- data/manual/text/single_usage.rb +13 -14
- data/manual/text/text.rb +62 -62
- data/manual/text/text_box_excess.rb +22 -19
- data/manual/text/text_box_extensions.rb +21 -18
- data/manual/text/text_box_overflow.rb +28 -21
- data/manual/text/utf8.rb +16 -17
- data/manual/text/win_ansi_charset.rb +29 -26
- data/prawn.gemspec +45 -43
- data/spec/extensions/encoding_helpers.rb +4 -3
- data/spec/prawn/document/bounding_box_spec.rb +550 -0
- data/spec/prawn/document/column_box_spec.rb +75 -0
- data/spec/prawn/document/security_spec.rb +176 -0
- data/spec/prawn/document_annotations_spec.rb +76 -0
- data/spec/prawn/document_destinations_spec.rb +15 -0
- data/spec/prawn/document_grid_spec.rb +99 -0
- data/spec/prawn/document_reference_spec.rb +27 -0
- data/spec/prawn/document_span_spec.rb +44 -0
- data/spec/prawn/document_spec.rb +805 -0
- data/spec/prawn/font_metric_cache_spec.rb +54 -0
- data/spec/prawn/font_spec.rb +544 -0
- data/spec/prawn/graphics/blend_mode_spec.rb +63 -0
- data/spec/prawn/graphics/transparency_spec.rb +81 -0
- data/spec/prawn/graphics_spec.rb +872 -0
- data/spec/prawn/graphics_stroke_styles_spec.rb +229 -0
- data/spec/prawn/image_handler_spec.rb +53 -0
- data/spec/prawn/images/jpg_spec.rb +20 -0
- data/spec/prawn/images/png_spec.rb +283 -0
- data/spec/prawn/images_spec.rb +229 -0
- data/spec/prawn/measurements_extensions_spec.rb +24 -0
- data/spec/prawn/outline_spec.rb +512 -0
- data/spec/prawn/repeater_spec.rb +166 -0
- data/spec/prawn/soft_mask_spec.rb +74 -0
- data/spec/prawn/stamp_spec.rb +173 -0
- data/spec/prawn/text/box_spec.rb +1110 -0
- data/spec/prawn/text/formatted/arranger_spec.rb +466 -0
- data/spec/prawn/text/formatted/box_spec.rb +849 -0
- data/spec/prawn/text/formatted/fragment_spec.rb +343 -0
- data/spec/prawn/text/formatted/line_wrap_spec.rb +495 -0
- data/spec/prawn/text/formatted/parser_spec.rb +697 -0
- data/spec/prawn/text_draw_text_spec.rb +150 -0
- data/spec/prawn/text_rendering_mode_spec.rb +48 -0
- data/spec/prawn/text_spacing_spec.rb +95 -0
- data/spec/prawn/text_spec.rb +603 -0
- data/spec/prawn/text_with_inline_formatting_spec.rb +35 -0
- data/spec/prawn/transformation_stack_spec.rb +66 -0
- data/spec/prawn/view_spec.rb +63 -0
- data/spec/prawn_manual_spec.rb +35 -0
- data/spec/spec_helper.rb +22 -21
- data.tar.gz.sig +0 -0
- metadata +168 -307
- metadata.gz.sig +0 -0
- data/README.md +0 -109
- data/data/encodings/win_ansi.txt +0 -29
- data/data/images/16bit.alpha +0 -0
- data/data/images/16bit.dat +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/barcode_issue.png +0 -0
- data/data/images/dice.alpha +0 -0
- data/data/images/dice.dat +0 -0
- data/data/images/dice.png +0 -0
- data/data/images/dice_interlaced.png +0 -0
- data/data/images/indexed_color.dat +0 -0
- data/data/images/indexed_color.png +0 -0
- data/data/images/letterhead.jpg +0 -0
- data/data/images/page_white_text.alpha +0 -0
- data/data/images/page_white_text.dat +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/lib/pdf/core/annotations.rb +0 -60
- data/lib/pdf/core/byte_string.rb +0 -9
- data/lib/pdf/core/destinations.rb +0 -90
- data/lib/pdf/core/document_state.rb +0 -78
- data/lib/pdf/core/filter_list.rb +0 -51
- data/lib/pdf/core/filters.rb +0 -36
- data/lib/pdf/core/graphics_state.rb +0 -68
- data/lib/pdf/core/literal_string.rb +0 -16
- data/lib/pdf/core/name_tree.rb +0 -177
- data/lib/pdf/core/object_store.rb +0 -320
- data/lib/pdf/core/outline.rb +0 -315
- data/lib/pdf/core/page.rb +0 -212
- data/lib/pdf/core/page_geometry.rb +0 -126
- data/lib/pdf/core/pdf_object.rb +0 -124
- data/lib/pdf/core/reference.rb +0 -103
- data/lib/pdf/core/stream.rb +0 -98
- data/lib/pdf/core/text.rb +0 -275
- data/lib/pdf/core.rb +0 -35
- data/lib/prawn/compatibility.rb +0 -91
- data/lib/prawn/document/graphics_state.rb +0 -73
- data/lib/prawn/document/snapshot.rb +0 -89
- data/lib/prawn/font/afm.rb +0 -203
- data/lib/prawn/layout.rb +0 -20
- data/lib/prawn/table/cell/image.rb +0 -70
- data/lib/prawn/table/cell/in_table.rb +0 -27
- data/lib/prawn/table/cell/span_dummy.rb +0 -92
- data/lib/prawn/table/cell/subtable.rb +0 -65
- data/lib/prawn/table/cell/text.rb +0 -153
- data/lib/prawn/table/cell.rb +0 -770
- data/lib/prawn/table/cells.rb +0 -295
- data/lib/prawn/table.rb +0 -643
- data/manual/example_file.rb +0 -116
- data/manual/example_package.rb +0 -53
- data/manual/example_section.rb +0 -46
- data/manual/manual/cover.rb +0 -35
- data/manual/manual/foreword.rb +0 -85
- data/manual/manual/manual.rb +0 -35
- data/manual/syntax_highlight.rb +0 -52
- data/manual/table/basic_block.rb +0 -53
- data/manual/table/before_rendering_page.rb +0 -26
- data/manual/table/cell_border_lines.rb +0 -24
- data/manual/table/cell_borders_and_bg.rb +0 -31
- data/manual/table/cell_dimensions.rb +0 -30
- data/manual/table/cell_text.rb +0 -38
- data/manual/table/column_widths.rb +0 -30
- data/manual/table/content_and_subtables.rb +0 -39
- data/manual/table/creation.rb +0 -27
- data/manual/table/filtering.rb +0 -36
- data/manual/table/flow_and_header.rb +0 -17
- data/manual/table/image_cells.rb +0 -33
- data/manual/table/position.rb +0 -29
- data/manual/table/row_colors.rb +0 -20
- data/manual/table/span.rb +0 -30
- data/manual/table/style.rb +0 -22
- data/manual/table/table.rb +0 -52
- data/manual/table/width.rb +0 -27
- data/manual/templates/full_template.rb +0 -25
- data/manual/templates/page_template.rb +0 -48
- data/manual/templates/templates.rb +0 -27
- data/manual/text/group.rb +0 -29
- data/spec/acceptance/png.rb +0 -23
- data/spec/annotations_spec.rb +0 -74
- data/spec/bounding_box_spec.rb +0 -493
- data/spec/cell_spec.rb +0 -628
- data/spec/column_box_spec.rb +0 -33
- data/spec/destinations_spec.rb +0 -15
- data/spec/document_spec.rb +0 -761
- data/spec/extensions/mocha.rb +0 -44
- data/spec/filters_spec.rb +0 -34
- data/spec/font_metric_cache_spec.rb +0 -52
- data/spec/font_spec.rb +0 -464
- data/spec/formatted_text_arranger_spec.rb +0 -421
- data/spec/formatted_text_box_spec.rb +0 -650
- data/spec/formatted_text_fragment_spec.rb +0 -298
- data/spec/graphics_spec.rb +0 -651
- data/spec/grid_spec.rb +0 -85
- data/spec/image_handler_spec.rb +0 -42
- data/spec/images_spec.rb +0 -157
- data/spec/inline_formatted_text_parser_spec.rb +0 -564
- data/spec/jpg_spec.rb +0 -25
- data/spec/line_wrap_spec.rb +0 -333
- data/spec/measurement_units_spec.rb +0 -23
- data/spec/name_tree_spec.rb +0 -112
- data/spec/object_store_spec.rb +0 -170
- data/spec/outline_spec.rb +0 -448
- data/spec/pdf_object_spec.rb +0 -172
- data/spec/png_spec.rb +0 -240
- data/spec/reference_spec.rb +0 -82
- data/spec/repeater_spec.rb +0 -158
- data/spec/security_spec.rb +0 -158
- data/spec/snapshot_spec.rb +0 -186
- data/spec/soft_mask_spec.rb +0 -117
- data/spec/span_spec.rb +0 -44
- data/spec/stamp_spec.rb +0 -158
- data/spec/stream_spec.rb +0 -58
- data/spec/stroke_styles_spec.rb +0 -211
- data/spec/table/span_dummy_spec.rb +0 -17
- data/spec/table_spec.rb +0 -1355
- data/spec/template_spec.rb +0 -351
- data/spec/text_at_spec.rb +0 -130
- data/spec/text_box_spec.rb +0 -1030
- data/spec/text_rendering_mode_spec.rb +0 -45
- data/spec/text_spacing_spec.rb +0 -93
- data/spec/text_spec.rb +0 -425
- data/spec/text_with_inline_formatting_spec.rb +0 -35
- data/spec/transparency_spec.rb +0 -89
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# text/formatted/fragment.rb : Implements information about a formatted fragment
|
4
4
|
#
|
@@ -9,12 +9,11 @@
|
|
9
9
|
module Prawn
|
10
10
|
module Text
|
11
11
|
module Formatted
|
12
|
-
|
13
12
|
# Prawn::Text::Formatted::Fragment is a state store for a formatted text
|
14
13
|
# fragment. It does not render anything.
|
15
14
|
#
|
15
|
+
# @private
|
16
16
|
class Fragment
|
17
|
-
|
18
17
|
attr_reader :format_state, :text
|
19
18
|
attr_writer :width
|
20
19
|
attr_accessor :line_height, :descender, :ascender
|
@@ -25,14 +24,14 @@ module Prawn
|
|
25
24
|
@document = document
|
26
25
|
@word_spacing = 0
|
27
26
|
|
28
|
-
# keep the original value of "text", so we can reinitialize @text if
|
29
|
-
#
|
27
|
+
# keep the original value of "text", so we can reinitialize @text if
|
28
|
+
# formatting parameters like text direction are changed
|
30
29
|
@original_text = text
|
31
30
|
@text = process_text(@original_text)
|
32
31
|
end
|
33
32
|
|
34
33
|
def width
|
35
|
-
if @word_spacing
|
34
|
+
if @word_spacing.zero? then @width
|
36
35
|
else @width + @word_spacing * space_count
|
37
36
|
end
|
38
37
|
end
|
@@ -129,7 +128,7 @@ module Prawn
|
|
129
128
|
end
|
130
129
|
|
131
130
|
def space_count
|
132
|
-
@text.count(
|
131
|
+
@text.count(' ')
|
133
132
|
end
|
134
133
|
|
135
134
|
def callback_objects
|
@@ -207,16 +206,19 @@ module Prawn
|
|
207
206
|
|
208
207
|
def process_text(text)
|
209
208
|
string = strip_zero_width_spaces(text)
|
209
|
+
|
210
210
|
if exclude_trailing_white_space?
|
211
|
-
string =
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
if ruby_18 { true }
|
216
|
-
string.scan(/./mu).reverse.join
|
217
|
-
else
|
218
|
-
string.reverse
|
211
|
+
string = string.rstrip
|
212
|
+
|
213
|
+
if soft_hyphens_need_processing?(string)
|
214
|
+
string = process_soft_hyphens(string[0..-2]) + string[-1..-1]
|
219
215
|
end
|
216
|
+
elsif soft_hyphens_need_processing?(string)
|
217
|
+
string = process_soft_hyphens(string)
|
218
|
+
end
|
219
|
+
|
220
|
+
if direction == :rtl
|
221
|
+
string.reverse
|
220
222
|
else
|
221
223
|
string
|
222
224
|
end
|
@@ -226,31 +228,29 @@ module Prawn
|
|
226
228
|
@format_state[:exclude_trailing_white_space]
|
227
229
|
end
|
228
230
|
|
231
|
+
def soft_hyphens_need_processing?(string)
|
232
|
+
!string.empty? && normalized_soft_hyphen
|
233
|
+
end
|
234
|
+
|
229
235
|
def normalized_soft_hyphen
|
230
236
|
@format_state[:normalized_soft_hyphen]
|
231
237
|
end
|
232
238
|
|
233
239
|
def process_soft_hyphens(string)
|
234
|
-
if string.
|
235
|
-
|
236
|
-
if string.encoding != normalized_soft_hyphen.encoding
|
237
|
-
string.force_encoding(normalized_soft_hyphen.encoding)
|
238
|
-
end
|
239
|
-
}
|
240
|
-
string[0..-2].gsub(normalized_soft_hyphen, "") + string[-1..-1]
|
241
|
-
else
|
242
|
-
string
|
240
|
+
if string.encoding != normalized_soft_hyphen.encoding
|
241
|
+
string.force_encoding(normalized_soft_hyphen.encoding)
|
243
242
|
end
|
243
|
+
|
244
|
+
string.gsub(normalized_soft_hyphen, '')
|
244
245
|
end
|
245
246
|
|
246
247
|
def strip_zero_width_spaces(string)
|
247
|
-
if
|
248
|
-
string.gsub(Prawn::Text::ZWSP,
|
248
|
+
if string.encoding == ::Encoding::UTF_8
|
249
|
+
string.gsub(Prawn::Text::ZWSP, '')
|
249
250
|
else
|
250
251
|
string
|
251
252
|
end
|
252
253
|
end
|
253
|
-
|
254
254
|
end
|
255
255
|
end
|
256
256
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# core/text/formatted/line_wrap.rb : Implements individual line wrapping of
|
4
4
|
# formatted text
|
@@ -11,9 +11,8 @@
|
|
11
11
|
module Prawn
|
12
12
|
module Text
|
13
13
|
module Formatted #:nodoc:
|
14
|
-
|
14
|
+
# @private
|
15
15
|
class LineWrap #:nodoc:
|
16
|
-
|
17
16
|
# The width of the last wrapped line
|
18
17
|
#
|
19
18
|
def width
|
@@ -25,7 +24,11 @@ module Prawn
|
|
25
24
|
|
26
25
|
# Whether this line is the last line in the paragraph
|
27
26
|
def paragraph_finished?
|
28
|
-
@newline_encountered ||
|
27
|
+
@newline_encountered || next_string_newline? || @arranger.finished?
|
28
|
+
end
|
29
|
+
|
30
|
+
def tokenize(fragment)
|
31
|
+
fragment.scan(scan_pattern(fragment.encoding))
|
29
32
|
end
|
30
33
|
|
31
34
|
# Work in conjunction with the PDF::Formatted::Arranger
|
@@ -35,8 +38,10 @@ module Prawn
|
|
35
38
|
def wrap_line(options)
|
36
39
|
initialize_line(options)
|
37
40
|
|
41
|
+
# rubocop: disable Lint/AssignmentInCondition
|
38
42
|
while fragment = @arranger.next_string
|
39
|
-
|
43
|
+
# rubocop: enable Lint/AssignmentInCondition
|
44
|
+
@fragment_output = +''
|
40
45
|
|
41
46
|
fragment.lstrip! if first_fragment_on_this_line?(fragment)
|
42
47
|
next if empty_line?(fragment)
|
@@ -58,47 +63,56 @@ module Prawn
|
|
58
63
|
end
|
59
64
|
|
60
65
|
def empty_line?(fragment)
|
61
|
-
empty = line_empty? && fragment.empty? &&
|
62
|
-
|
66
|
+
empty = line_empty? && fragment.empty? && next_string_newline?
|
67
|
+
if empty
|
68
|
+
@arranger.update_last_string('', '', soft_hyphen(fragment.encoding))
|
69
|
+
end
|
63
70
|
empty
|
64
71
|
end
|
65
72
|
|
66
|
-
def
|
73
|
+
def next_string_newline?
|
67
74
|
@arranger.preview_next_string == "\n"
|
68
75
|
end
|
69
76
|
|
70
77
|
def apply_font_settings_and_add_fragment_to_line(fragment)
|
71
78
|
result = nil
|
72
79
|
@arranger.apply_font_settings do
|
73
|
-
# if font has changed from Unicode to non-Unicode, or vice versa, the characters used for soft hyphens
|
74
|
-
# and zero-width spaces will be different
|
75
|
-
set_soft_hyphen_and_zero_width_space
|
76
80
|
result = add_fragment_to_line(fragment)
|
77
81
|
end
|
78
82
|
result
|
79
83
|
end
|
80
84
|
|
81
|
-
# returns true
|
85
|
+
# returns true if all text was printed without running into the end of
|
82
86
|
# the line
|
83
87
|
#
|
84
88
|
def add_fragment_to_line(fragment)
|
85
|
-
|
89
|
+
case fragment
|
90
|
+
when ''
|
86
91
|
true
|
87
|
-
|
92
|
+
when "\n"
|
88
93
|
@newline_encountered = true
|
89
94
|
false
|
90
95
|
else
|
91
|
-
fragment
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
96
|
+
tokenize(fragment).each do |segment|
|
97
|
+
segment_width =
|
98
|
+
if segment == zero_width_space(segment.encoding)
|
99
|
+
0
|
100
|
+
else
|
101
|
+
@document.width_of(segment, kerning: @kerning)
|
102
|
+
end
|
97
103
|
|
98
104
|
if @accumulated_width + segment_width <= @width
|
99
105
|
@accumulated_width += segment_width
|
106
|
+
shy = soft_hyphen(segment.encoding)
|
107
|
+
if segment[-1] == shy
|
108
|
+
sh_width = @document.width_of(shy, kerning: @kerning)
|
109
|
+
@accumulated_width -= sh_width
|
110
|
+
end
|
100
111
|
@fragment_output += segment
|
101
112
|
else
|
113
|
+
if @accumulated_width.zero? && @line_contains_more_than_one_word
|
114
|
+
@line_contains_more_than_one_word = false
|
115
|
+
end
|
102
116
|
end_of_the_line_reached(segment)
|
103
117
|
fragment_finished(fragment)
|
104
118
|
return false
|
@@ -112,46 +126,83 @@ module Prawn
|
|
112
126
|
|
113
127
|
# The pattern used to determine chunks of text to place on a given line
|
114
128
|
#
|
115
|
-
def scan_pattern
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
129
|
+
def scan_pattern(encoding = ::Encoding::UTF_8)
|
130
|
+
ebc = break_chars(encoding)
|
131
|
+
eshy = soft_hyphen(encoding)
|
132
|
+
ehy = hyphen(encoding)
|
133
|
+
ews = whitespace(encoding)
|
134
|
+
|
135
|
+
patterns = [
|
136
|
+
"[^#{ebc}]+#{eshy}",
|
137
|
+
"[^#{ebc}]+#{ehy}+",
|
138
|
+
"[^#{ebc}]+",
|
139
|
+
"[#{ews}]+",
|
140
|
+
"#{ehy}+[^#{ebc}]*",
|
141
|
+
eshy.to_s
|
142
|
+
]
|
143
|
+
|
144
|
+
pattern = patterns
|
145
|
+
.map { |p| p.encode(encoding) }
|
146
|
+
.join('|')
|
147
|
+
|
148
|
+
Regexp.new(pattern)
|
123
149
|
end
|
124
150
|
|
125
151
|
# The pattern used to determine whether any word breaks exist on a
|
126
152
|
# current line, which in turn determines whether character level
|
127
153
|
# word breaking is needed
|
128
154
|
#
|
129
|
-
def word_division_scan_pattern
|
130
|
-
|
155
|
+
def word_division_scan_pattern(encoding = ::Encoding::UTF_8)
|
156
|
+
common_whitespaces =
|
157
|
+
["\t", "\n", "\v", "\r", ' '].map do |c|
|
158
|
+
c.encode(encoding)
|
159
|
+
end
|
160
|
+
|
161
|
+
Regexp.union(
|
162
|
+
common_whitespaces +
|
163
|
+
[
|
164
|
+
zero_width_space(encoding),
|
165
|
+
soft_hyphen(encoding),
|
166
|
+
hyphen(encoding)
|
167
|
+
].compact
|
168
|
+
)
|
131
169
|
end
|
132
170
|
|
133
|
-
def
|
134
|
-
|
171
|
+
def soft_hyphen(encoding = ::Encoding::UTF_8)
|
172
|
+
Prawn::Text::SHY.encode(encoding)
|
173
|
+
rescue ::Encoding::InvalidByteSequenceError,
|
174
|
+
::Encoding::UndefinedConversionError
|
175
|
+
nil
|
135
176
|
end
|
136
177
|
|
137
|
-
def
|
138
|
-
|
178
|
+
def break_chars(encoding = ::Encoding::UTF_8)
|
179
|
+
[
|
180
|
+
whitespace(encoding),
|
181
|
+
soft_hyphen(encoding),
|
182
|
+
hyphen(encoding)
|
183
|
+
].join('')
|
139
184
|
end
|
140
185
|
|
141
|
-
def
|
142
|
-
|
186
|
+
def zero_width_space(encoding = ::Encoding::UTF_8)
|
187
|
+
Prawn::Text::ZWSP.encode(encoding)
|
188
|
+
rescue ::Encoding::InvalidByteSequenceError,
|
189
|
+
::Encoding::UndefinedConversionError
|
190
|
+
nil
|
143
191
|
end
|
144
192
|
|
145
|
-
def
|
146
|
-
|
193
|
+
def whitespace(encoding = ::Encoding::UTF_8)
|
194
|
+
"\s\t#{zero_width_space(encoding)}".encode(encoding)
|
147
195
|
end
|
148
196
|
|
149
|
-
def
|
150
|
-
|
197
|
+
def hyphen(_encoding = ::Encoding::UTF_8)
|
198
|
+
'-'
|
199
|
+
rescue ::Encoding::InvalidByteSequenceError,
|
200
|
+
::Encoding::UndefinedConversionError
|
201
|
+
nil
|
151
202
|
end
|
152
203
|
|
153
204
|
def line_empty?
|
154
|
-
@line_empty && @accumulated_width
|
205
|
+
@line_empty && @accumulated_width.zero?
|
155
206
|
end
|
156
207
|
|
157
208
|
def initialize_line(options)
|
@@ -159,6 +210,8 @@ module Prawn
|
|
159
210
|
@kerning = options[:kerning]
|
160
211
|
@width = options[:width]
|
161
212
|
|
213
|
+
@disable_wrap_by_char = options[:disable_wrap_by_char]
|
214
|
+
|
162
215
|
@accumulated_width = 0
|
163
216
|
@line_empty = true
|
164
217
|
@line_contains_more_than_one_word = false
|
@@ -170,52 +223,57 @@ module Prawn
|
|
170
223
|
@line_full = false
|
171
224
|
end
|
172
225
|
|
173
|
-
def set_soft_hyphen_and_zero_width_space
|
174
|
-
# this is done once per fragment, after the font settings for the fragment are applied --
|
175
|
-
# it could actually be skipped if the font hasn't changed
|
176
|
-
font = @document.font
|
177
|
-
@soft_hyphen = font.normalize_encoding(Prawn::Text::SHY)
|
178
|
-
@zero_width_space = font.unicode? ? Prawn::Text::ZWSP : ""
|
179
|
-
end
|
180
|
-
|
181
226
|
def fragment_finished(fragment)
|
182
227
|
if fragment == "\n"
|
183
228
|
@newline_encountered = true
|
184
229
|
@line_empty = false
|
185
230
|
else
|
186
|
-
update_output_based_on_last_fragment(
|
231
|
+
update_output_based_on_last_fragment(
|
232
|
+
fragment,
|
233
|
+
soft_hyphen(fragment.encoding)
|
234
|
+
)
|
187
235
|
update_line_status_based_on_last_output
|
188
|
-
|
236
|
+
pull_preceding_fragment_to_join_this_one?(fragment)
|
189
237
|
end
|
190
238
|
remember_this_fragment_for_backward_looking_ops
|
191
239
|
end
|
192
240
|
|
193
|
-
def update_output_based_on_last_fragment(
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
241
|
+
def update_output_based_on_last_fragment(
|
242
|
+
fragment, normalized_soft_hyphen = nil
|
243
|
+
)
|
244
|
+
remaining_text =
|
245
|
+
fragment.slice(@fragment_output.length..fragment.length)
|
246
|
+
if line_finished? && line_empty? && @fragment_output.empty? &&
|
247
|
+
!fragment.strip.empty?
|
248
|
+
raise Prawn::Errors::CannotFit
|
249
|
+
end
|
250
|
+
|
251
|
+
@arranger.update_last_string(
|
252
|
+
@fragment_output,
|
253
|
+
remaining_text,
|
254
|
+
normalized_soft_hyphen
|
255
|
+
)
|
198
256
|
end
|
199
257
|
|
200
|
-
def
|
201
|
-
if @fragment_output.empty? &&
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
update_output_based_on_last_fragment(@previous_fragment)
|
208
|
-
end
|
258
|
+
def pull_preceding_fragment_to_join_this_one?(current_fragment)
|
259
|
+
if @fragment_output.empty? && !current_fragment.empty? &&
|
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)
|
209
265
|
end
|
210
266
|
end
|
211
267
|
|
212
268
|
def remember_this_fragment_for_backward_looking_ops
|
213
269
|
@previous_fragment = @fragment_output.dup
|
214
270
|
pf = @previous_fragment
|
215
|
-
@previous_fragment_ended_with_breakable =
|
216
|
-
|
271
|
+
@previous_fragment_ended_with_breakable =
|
272
|
+
pf =~ /[#{break_chars(pf.encoding)}]$/
|
273
|
+
last_word = pf.slice(/[^#{break_chars(pf.encoding)}]*$/)
|
217
274
|
last_word_length = last_word.nil? ? 0 : last_word.length
|
218
|
-
@previous_fragment_output_without_last_word =
|
275
|
+
@previous_fragment_output_without_last_word =
|
276
|
+
pf.slice(0, pf.length - last_word_length)
|
219
277
|
end
|
220
278
|
|
221
279
|
def previous_fragment_ended_with_breakable?
|
@@ -223,7 +281,7 @@ module Prawn
|
|
223
281
|
end
|
224
282
|
|
225
283
|
def fragment_begins_with_breakable?(fragment)
|
226
|
-
fragment =~ /^[#{break_chars}]/
|
284
|
+
fragment =~ /^[#{break_chars(fragment.encoding)}]/
|
227
285
|
end
|
228
286
|
|
229
287
|
def line_finished?
|
@@ -231,34 +289,28 @@ module Prawn
|
|
231
289
|
end
|
232
290
|
|
233
291
|
def update_line_status_based_on_last_output
|
234
|
-
|
292
|
+
if @fragment_output&.match?(word_division_scan_pattern(@fragment_output.encoding))
|
293
|
+
@line_contains_more_than_one_word = true
|
294
|
+
end
|
235
295
|
end
|
236
296
|
|
237
297
|
def end_of_the_line_reached(segment)
|
238
298
|
update_line_status_based_on_last_output
|
239
|
-
|
299
|
+
unless @disable_wrap_by_char || @line_contains_more_than_one_word
|
300
|
+
wrap_by_char(segment)
|
301
|
+
end
|
240
302
|
@line_full = true
|
241
303
|
end
|
242
304
|
|
243
305
|
def wrap_by_char(segment)
|
244
|
-
|
245
|
-
|
246
|
-
# under Ruby 1.9, it is implemented simply by aliasing #each_char
|
247
|
-
font = @document.font
|
248
|
-
if font.unicode?
|
249
|
-
segment.unicode_characters do |char|
|
250
|
-
break unless append_char(char,font)
|
251
|
-
end
|
252
|
-
else
|
253
|
-
segment.each_char do |char|
|
254
|
-
break unless append_char(char,font)
|
255
|
-
end
|
306
|
+
segment.each_char do |char|
|
307
|
+
break unless append_char(char)
|
256
308
|
end
|
257
309
|
end
|
258
310
|
|
259
|
-
def append_char(char
|
311
|
+
def append_char(char)
|
260
312
|
# kerning doesn't make sense in the context of a single character
|
261
|
-
char_width =
|
313
|
+
char_width = @document.width_of(char)
|
262
314
|
|
263
315
|
if @accumulated_width + char_width <= @width
|
264
316
|
@accumulated_width += char_width
|
@@ -268,18 +320,6 @@ module Prawn
|
|
268
320
|
false
|
269
321
|
end
|
270
322
|
end
|
271
|
-
|
272
|
-
def new_regexp(pattern)
|
273
|
-
regexp = ruby_19 {
|
274
|
-
Regexp.new(pattern)
|
275
|
-
}
|
276
|
-
regexp = regexp || ruby_18 {
|
277
|
-
lang = @document.font.unicode? ? 'U' : 'N'
|
278
|
-
Regexp.new(pattern, 0, lang)
|
279
|
-
}
|
280
|
-
regexp
|
281
|
-
end
|
282
|
-
|
283
323
|
end
|
284
324
|
end
|
285
325
|
end
|