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
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'pathname'
|
5
|
+
|
6
|
+
describe Prawn::FontMetricCache do
|
7
|
+
let(:document) { Prawn::Document.new }
|
8
|
+
let(:font_metric_cache) { described_class.new(document) }
|
9
|
+
|
10
|
+
it 'starts with an empty cache' do
|
11
|
+
expect(font_metric_cache.instance_variable_get(:@cache)).to be_empty
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'caches the width of the provided string' do
|
15
|
+
font_metric_cache.width_of('M', {})
|
16
|
+
|
17
|
+
expect(font_metric_cache.instance_variable_get(:@cache).size).to eq(1)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'onlies cache a single copy of the same string' do
|
21
|
+
font_metric_cache.width_of('M', {})
|
22
|
+
font_metric_cache.width_of('M', {})
|
23
|
+
|
24
|
+
expect(font_metric_cache.instance_variable_get(:@cache).size).to eq(1)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'caches different copies for different strings' do
|
28
|
+
font_metric_cache.width_of('M', {})
|
29
|
+
font_metric_cache.width_of('W', {})
|
30
|
+
|
31
|
+
expect(font_metric_cache.instance_variable_get(:@cache).entries.size)
|
32
|
+
.to eq 2
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'caches different copies of the same string with different font sizes' do
|
36
|
+
font_metric_cache.width_of('M', {})
|
37
|
+
|
38
|
+
document.font_size 24
|
39
|
+
font_metric_cache.width_of('M', {})
|
40
|
+
|
41
|
+
expect(font_metric_cache.instance_variable_get(:@cache).entries.size)
|
42
|
+
.to eq 2
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'caches different copies of the same string with different fonts' do
|
46
|
+
font_metric_cache.width_of('M', {})
|
47
|
+
|
48
|
+
document.font 'Courier'
|
49
|
+
font_metric_cache.width_of('M', {})
|
50
|
+
|
51
|
+
expect(font_metric_cache.instance_variable_get(:@cache).entries.size)
|
52
|
+
.to eq 2
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,544 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'pathname'
|
5
|
+
|
6
|
+
describe Prawn::Font do
|
7
|
+
let(:pdf) { create_pdf }
|
8
|
+
|
9
|
+
describe 'Font behavior' do
|
10
|
+
it 'defaults to Helvetica if no font is specified' do
|
11
|
+
pdf = Prawn::Document.new
|
12
|
+
expect(pdf.font.name).to eq('Helvetica')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe 'Font objects' do
|
17
|
+
it 'is equal' do
|
18
|
+
font1 = Prawn::Document.new.font
|
19
|
+
font2 = Prawn::Document.new.font
|
20
|
+
|
21
|
+
expect(font1).to eql(font2)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'alwayses be the same key' do
|
25
|
+
font1 = Prawn::Document.new.font
|
26
|
+
font2 = Prawn::Document.new.font
|
27
|
+
|
28
|
+
hash = {}
|
29
|
+
|
30
|
+
hash[font1] = 'Original'
|
31
|
+
hash[font2] = 'Overwritten'
|
32
|
+
|
33
|
+
expect(hash.size).to eq(1)
|
34
|
+
|
35
|
+
expect(hash[font1]).to eq('Overwritten')
|
36
|
+
expect(hash[font2]).to eq('Overwritten')
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '#width_of' do
|
41
|
+
it 'takes character spacing into account' do
|
42
|
+
original_width = pdf.width_of('hello world')
|
43
|
+
pdf.character_spacing(7) do
|
44
|
+
expect(pdf.width_of('hello world')).to eq(original_width + 10 * 7)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'excludes newlines' do
|
49
|
+
# Use a TTF font that has a non-zero width for \n
|
50
|
+
pdf.font("#{Prawn::DATADIR}/fonts/gkai00mp.ttf")
|
51
|
+
|
52
|
+
expect(pdf.width_of("\nhello world\n")).to eq(
|
53
|
+
pdf.width_of('hello world')
|
54
|
+
)
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'takes formatting into account' do
|
58
|
+
normal_hello = pdf.width_of('hello')
|
59
|
+
inline_bold_hello = pdf.width_of('<b>hello</b>', inline_format: true)
|
60
|
+
expect(inline_bold_hello).to be > normal_hello
|
61
|
+
|
62
|
+
pdf.font('Helvetica', style: :bold) do
|
63
|
+
expect(inline_bold_hello).to eq(pdf.width_of('hello'))
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'accepts :style as an argument' do
|
68
|
+
styled_bold_hello = pdf.width_of('hello', style: :bold)
|
69
|
+
pdf.font('Helvetica', style: :bold) do
|
70
|
+
expect(styled_bold_hello).to eq(pdf.width_of('hello'))
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'reports missing font with style' do
|
75
|
+
expect do
|
76
|
+
pdf.font('Nada', style: :bold) do
|
77
|
+
pdf.width_of('hello')
|
78
|
+
end
|
79
|
+
end.to raise_error(Prawn::Errors::UnknownFont, /Nada \(bold\)/)
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'calculates styled widths correctly using TTFs' do
|
83
|
+
pdf.font_families.update(
|
84
|
+
'DejaVu Sans' => {
|
85
|
+
normal: "#{Prawn::DATADIR}/fonts/DejaVuSans.ttf",
|
86
|
+
bold: "#{Prawn::DATADIR}/fonts/DejaVuSans-Bold.ttf"
|
87
|
+
}
|
88
|
+
)
|
89
|
+
styled_bold_hello = nil
|
90
|
+
bold_hello = nil
|
91
|
+
plain_hello = nil
|
92
|
+
|
93
|
+
pdf.font('DejaVu Sans') do
|
94
|
+
styled_bold_hello = pdf.width_of('hello', style: :bold)
|
95
|
+
end
|
96
|
+
pdf.font('DejaVu Sans', style: :bold) do
|
97
|
+
bold_hello = pdf.width_of('hello')
|
98
|
+
end
|
99
|
+
|
100
|
+
pdf.font('DejaVu Sans') do
|
101
|
+
plain_hello = pdf.width_of('hello')
|
102
|
+
end
|
103
|
+
|
104
|
+
expect(plain_hello).to_not eq(bold_hello)
|
105
|
+
|
106
|
+
expect(styled_bold_hello).to eq(bold_hello)
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'does not treat minus as if it were a hyphen', issue: 578 do
|
110
|
+
expect(pdf.width_of('-0.75')).to be < pdf.width_of('25.00')
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe '#font_size' do
|
115
|
+
it 'allows setting font size in DSL style' do
|
116
|
+
pdf.font_size 20
|
117
|
+
expect(pdf.font_size).to eq(20)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
describe 'font style support' do
|
122
|
+
it 'complains if there is no @current_page' do
|
123
|
+
pdf_without_page = Prawn::Document.new(skip_page_creation: true)
|
124
|
+
|
125
|
+
expect { pdf_without_page.font 'Helvetica' }
|
126
|
+
.to raise_error(Prawn::Errors::NotOnPage)
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'allows specifying font style by style name and font family' do
|
130
|
+
pdf.font 'Courier', style: :bold
|
131
|
+
pdf.text 'In Courier bold'
|
132
|
+
|
133
|
+
pdf.font 'Courier', style: :bold_italic
|
134
|
+
pdf.text 'In Courier bold-italic'
|
135
|
+
|
136
|
+
pdf.font 'Courier', style: :italic
|
137
|
+
pdf.text 'In Courier italic'
|
138
|
+
|
139
|
+
pdf.font 'Courier', style: :normal
|
140
|
+
pdf.text 'In Normal Courier'
|
141
|
+
|
142
|
+
pdf.font 'Helvetica'
|
143
|
+
pdf.text 'In Normal Helvetica'
|
144
|
+
|
145
|
+
text = PDF::Inspector::Text.analyze(pdf.render)
|
146
|
+
expect(text.font_settings.map { |e| e[:name] }).to eq(
|
147
|
+
%i[
|
148
|
+
Courier-Bold Courier-BoldOblique Courier-Oblique
|
149
|
+
Courier Helvetica
|
150
|
+
]
|
151
|
+
)
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'allows font familes to be defined in a single dfont' do
|
155
|
+
file = "#{Prawn::DATADIR}/fonts/Panic+Sans.dfont"
|
156
|
+
pdf.font_families['Panic Sans'] = {
|
157
|
+
normal: { file: file, font: 'PanicSans' },
|
158
|
+
italic: { file: file, font: 'PanicSans-Italic' },
|
159
|
+
bold: { file: file, font: 'PanicSans-Bold' },
|
160
|
+
bold_italic: { file: file, font: 'PanicSans-BoldItalic' }
|
161
|
+
}
|
162
|
+
|
163
|
+
pdf.font 'Panic Sans', style: :italic
|
164
|
+
pdf.text 'In PanicSans-Italic'
|
165
|
+
|
166
|
+
text = PDF::Inspector::Text.analyze(pdf.render)
|
167
|
+
name = text.font_settings.map { |e| e[:name] }.first.to_s
|
168
|
+
name = name.sub(/\w+\+/, 'subset+')
|
169
|
+
expect(name).to eq('subset+PanicSans-Italic')
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'allows font familes to be defined in a single ttc' do
|
173
|
+
file = "#{Prawn::DATADIR}/fonts/DejaVuSans.ttc"
|
174
|
+
pdf.font_families['DejaVu Sans'] = {
|
175
|
+
normal: { file: file, font: 0 },
|
176
|
+
bold: { file: file, font: 1 }
|
177
|
+
}
|
178
|
+
|
179
|
+
pdf.font 'DejaVu Sans', style: :bold
|
180
|
+
pdf.text 'In PanicSans-Bold'
|
181
|
+
|
182
|
+
text = PDF::Inspector::Text.analyze(pdf.render)
|
183
|
+
name = text.font_settings.map { |e| e[:name] }.first.to_s
|
184
|
+
name = name.sub(/\w+\+/, 'subset+')
|
185
|
+
expect(name).to eq('subset+DejaVuSans-Bold')
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'allows fonts to be indexed by name in a ttc file' do
|
189
|
+
file = "#{Prawn::DATADIR}/fonts/DejaVuSans.ttc"
|
190
|
+
pdf.font_families['DejaVu Sans'] = {
|
191
|
+
normal: { file: file, font: 'DejaVu Sans' },
|
192
|
+
bold: { file: file, font: 'DejaVu Sans Bold' }
|
193
|
+
}
|
194
|
+
|
195
|
+
pdf.font 'DejaVu Sans', style: :bold
|
196
|
+
pdf.text 'In PanicSans-Bold'
|
197
|
+
|
198
|
+
text = PDF::Inspector::Text.analyze(pdf.render)
|
199
|
+
name = text.font_settings.map { |e| e[:name] }.first.to_s
|
200
|
+
name = name.sub(/\w+\+/, 'subset+')
|
201
|
+
expect(name).to eq('subset+DejaVuSans-Bold')
|
202
|
+
end
|
203
|
+
|
204
|
+
it 'accepts Pathname objects for font files' do
|
205
|
+
file = Pathname.new("#{Prawn::DATADIR}/fonts/DejaVuSans.ttf")
|
206
|
+
pdf.font_families['DejaVu Sans'] = {
|
207
|
+
normal: file
|
208
|
+
}
|
209
|
+
|
210
|
+
pdf.font 'DejaVu Sans'
|
211
|
+
pdf.text 'In DejaVu Sans'
|
212
|
+
|
213
|
+
text = PDF::Inspector::Text.analyze(pdf.render)
|
214
|
+
name = text.font_settings.map { |e| e[:name] }.first.to_s
|
215
|
+
name = name.sub(/\w+\+/, 'subset+')
|
216
|
+
expect(name).to eq('subset+DejaVuSans')
|
217
|
+
end
|
218
|
+
|
219
|
+
it 'accepts IO objects for font files' do
|
220
|
+
File.open "#{Prawn::DATADIR}/fonts/DejaVuSans.ttf" do |io|
|
221
|
+
pdf.font_families['DejaVu Sans'] = {
|
222
|
+
normal: described_class.load(pdf, io)
|
223
|
+
}
|
224
|
+
|
225
|
+
pdf.font 'DejaVu Sans'
|
226
|
+
pdf.text 'In DejaVu Sans'
|
227
|
+
|
228
|
+
text = PDF::Inspector::Text.analyze(pdf.render)
|
229
|
+
name = text.font_settings.map { |e| e[:name] }.first.to_s
|
230
|
+
name = name.sub(/\w+\+/, 'subset+')
|
231
|
+
expect(name).to eq('subset+DejaVuSans')
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
describe 'Transactional font handling' do
|
237
|
+
it 'allows setting of size directly when font is created' do
|
238
|
+
pdf.font 'Courier', size: 16
|
239
|
+
expect(pdf.font_size).to eq(16)
|
240
|
+
end
|
241
|
+
|
242
|
+
it 'allows temporary setting of a new font using a transaction' do
|
243
|
+
pdf.font 'Helvetica', size: 12
|
244
|
+
|
245
|
+
pdf.font 'Courier', size: 16 do
|
246
|
+
expect(pdf.font.name).to eq('Courier')
|
247
|
+
expect(pdf.font_size).to eq(16)
|
248
|
+
end
|
249
|
+
|
250
|
+
expect(pdf.font.name).to eq('Helvetica')
|
251
|
+
expect(pdf.font_size).to eq(12)
|
252
|
+
end
|
253
|
+
|
254
|
+
it 'masks font size when using a transacation' do
|
255
|
+
pdf.font 'Courier', size: 16 do
|
256
|
+
expect(pdf.font_size).to eq(16)
|
257
|
+
end
|
258
|
+
|
259
|
+
pdf.font 'Times-Roman'
|
260
|
+
pdf.font 'Courier'
|
261
|
+
|
262
|
+
expect(pdf.font_size).to eq(12)
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
describe 'Document#page_fonts' do
|
267
|
+
it 'registers fonts properly by page' do
|
268
|
+
pdf.font 'Courier'
|
269
|
+
pdf.text('hello')
|
270
|
+
|
271
|
+
pdf.font 'Helvetica'
|
272
|
+
pdf.text('hello')
|
273
|
+
|
274
|
+
pdf.font 'Times-Roman'
|
275
|
+
pdf.text('hello')
|
276
|
+
|
277
|
+
%w[Courier Helvetica Times-Roman].each do |f|
|
278
|
+
page_should_include_font(f)
|
279
|
+
end
|
280
|
+
|
281
|
+
pdf.start_new_page
|
282
|
+
|
283
|
+
pdf.font 'Helvetica'
|
284
|
+
pdf.text('hello')
|
285
|
+
|
286
|
+
page_should_include_font('Helvetica')
|
287
|
+
page_should_not_include_font('Courier')
|
288
|
+
page_should_not_include_font('Times-Roman')
|
289
|
+
end
|
290
|
+
|
291
|
+
def page_includes_font?(font)
|
292
|
+
pdf.page.fonts.values.map { |e| e.data[:BaseFont] }.include?(font.to_sym)
|
293
|
+
end
|
294
|
+
|
295
|
+
def page_should_include_font(font)
|
296
|
+
expect(page_includes_font?(font)).to eq true
|
297
|
+
end
|
298
|
+
|
299
|
+
def page_should_not_include_font(font)
|
300
|
+
expect(page_includes_font?(font)).to eq false
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
describe 'AFM fonts' do
|
305
|
+
let(:times) { pdf.find_font 'Times-Roman' }
|
306
|
+
|
307
|
+
it 'calculates string width taking into account accented characters' do
|
308
|
+
input = win1252_string("\xE9") # é in win-1252
|
309
|
+
expect(times.compute_width_of(input, size: 12))
|
310
|
+
.to eq(times.compute_width_of('e', size: 12))
|
311
|
+
end
|
312
|
+
|
313
|
+
it 'calculates string width taking into account kerning pairs' do
|
314
|
+
expect(times.compute_width_of(win1252_string('To'), size: 12))
|
315
|
+
.to eq(13.332)
|
316
|
+
expect(times.compute_width_of(
|
317
|
+
win1252_string('To'),
|
318
|
+
size: 12,
|
319
|
+
kerning: true
|
320
|
+
)).to eq(12.372)
|
321
|
+
|
322
|
+
input = win1252_string("T\xF6") # Tö in win-1252
|
323
|
+
expect(times.compute_width_of(input, size: 12, kerning: true))
|
324
|
+
.to eq(12.372)
|
325
|
+
end
|
326
|
+
|
327
|
+
it 'encodes text without kerning by default' do
|
328
|
+
expect(times.encode_text(win1252_string('To'))).to eq([[0, 'To']])
|
329
|
+
input = win1252_string("T\xE9l\xE9") # Télé in win-1252
|
330
|
+
expect(times.encode_text(input)).to eq([[0, input]])
|
331
|
+
expect(times.encode_text(win1252_string('Technology')))
|
332
|
+
.to eq([[0, 'Technology']])
|
333
|
+
expect(times.encode_text(win1252_string('Technology...')))
|
334
|
+
.to eq([[0, 'Technology...']])
|
335
|
+
end
|
336
|
+
|
337
|
+
it 'encodes text with kerning if requested' do
|
338
|
+
expect(times.encode_text(win1252_string('To'), kerning: true))
|
339
|
+
.to eq([[0, ['T', 80, 'o']]])
|
340
|
+
input = win1252_string("T\xE9l\xE9") # Télé in win-1252
|
341
|
+
output = win1252_string("\xE9l\xE9") # élé in win-1252
|
342
|
+
expect(times.encode_text(input, kerning: true))
|
343
|
+
.to eq([[0, ['T', 70, output]]])
|
344
|
+
expect(times.encode_text(win1252_string('Technology'), kerning: true))
|
345
|
+
.to eq([[0, ['T', 70, 'echnology']]])
|
346
|
+
expect(times.encode_text(win1252_string('Technology...'), kerning: true))
|
347
|
+
.to eq([[0, ['T', 70, 'echnology', 65, '...']]])
|
348
|
+
end
|
349
|
+
|
350
|
+
describe 'when normalizing encoding' do
|
351
|
+
it 'does not modify the original string when normalize_encoding() '\
|
352
|
+
'is used' do
|
353
|
+
original = 'Foo'
|
354
|
+
normalized = times.normalize_encoding(original)
|
355
|
+
expect(original.equal?(normalized)).to eq false
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
it 'omits /Encoding for symbolic fonts' do
|
360
|
+
zapf = pdf.find_font 'ZapfDingbats'
|
361
|
+
font_dict = zapf.__send__(:register, nil)
|
362
|
+
expect(font_dict.data[:Encoding]).to be_nil
|
363
|
+
end
|
364
|
+
end
|
365
|
+
|
366
|
+
describe '#glyph_present' do
|
367
|
+
it 'returns true when present in an AFM font' do
|
368
|
+
font = pdf.find_font('Helvetica')
|
369
|
+
expect(font.glyph_present?('H')).to eq true
|
370
|
+
end
|
371
|
+
|
372
|
+
it 'returns false when absent in an AFM font' do
|
373
|
+
font = pdf.find_font('Helvetica')
|
374
|
+
expect(font.glyph_present?('再')).to eq false
|
375
|
+
end
|
376
|
+
|
377
|
+
it 'returns true when present in a TTF font' do
|
378
|
+
font = pdf.find_font("#{Prawn::DATADIR}/fonts/DejaVuSans.ttf")
|
379
|
+
expect(font.glyph_present?('H')).to eq true
|
380
|
+
end
|
381
|
+
|
382
|
+
it 'returns false when absent in a TTF font' do
|
383
|
+
font = pdf.find_font("#{Prawn::DATADIR}/fonts/DejaVuSans.ttf")
|
384
|
+
expect(font.glyph_present?('再')).to eq false
|
385
|
+
|
386
|
+
font = pdf.find_font("#{Prawn::DATADIR}/fonts/gkai00mp.ttf")
|
387
|
+
expect(font.glyph_present?('€')).to eq false
|
388
|
+
end
|
389
|
+
end
|
390
|
+
|
391
|
+
describe 'TTF fonts' do
|
392
|
+
let(:font) { pdf.find_font "#{Prawn::DATADIR}/fonts/DejaVuSans.ttf" }
|
393
|
+
|
394
|
+
it 'calculates string width taking into account accented characters' do
|
395
|
+
expect(font.compute_width_of('é', size: 12)).to eq(
|
396
|
+
font.compute_width_of('e', size: 12)
|
397
|
+
)
|
398
|
+
end
|
399
|
+
|
400
|
+
it 'calculates string width taking into account kerning pairs' do
|
401
|
+
expect(font.compute_width_of('To', size: 12)).to be_within(0.01).of(14.65)
|
402
|
+
expect(font.compute_width_of('To', size: 12, kerning: true))
|
403
|
+
.to be_within(0.01).of(12.61)
|
404
|
+
end
|
405
|
+
|
406
|
+
it 'encodes text without kerning by default' do
|
407
|
+
expect(font.encode_text('To')).to eq([[0, 'To']])
|
408
|
+
|
409
|
+
tele = "T\216l\216"
|
410
|
+
result = font.encode_text('Télé')
|
411
|
+
expect(result.length).to eq(1)
|
412
|
+
expect(result[0][0]).to eq(0)
|
413
|
+
expect(result[0][1].bytes.to_a).to eq(tele.bytes.to_a)
|
414
|
+
|
415
|
+
expect(font.encode_text('Technology')).to eq([[0, 'Technology']])
|
416
|
+
expect(font.encode_text('Technology...')).to eq([[0, 'Technology...']])
|
417
|
+
expect(font.encode_text('Teχnology...')).to eq([
|
418
|
+
[0, 'Te'],
|
419
|
+
[1, '!'], [0, 'nology...']
|
420
|
+
])
|
421
|
+
end
|
422
|
+
|
423
|
+
it 'encodes text with kerning if requested' do
|
424
|
+
expect(font.encode_text('To', kerning: true)).to eq([
|
425
|
+
[0, ['T', 169.921875, 'o']]
|
426
|
+
])
|
427
|
+
expect(font.encode_text('Technology', kerning: true)).to eq([
|
428
|
+
[0, ['T', 169.921875, 'echnology']]
|
429
|
+
])
|
430
|
+
expect(font.encode_text('Technology...', kerning: true)).to eq([
|
431
|
+
[0, ['T', 169.921875, 'echnology', 142.578125, '...']]
|
432
|
+
])
|
433
|
+
expect(font.encode_text('Teχnology...', kerning: true)).to eq([
|
434
|
+
[0, ['T', 169.921875, 'e']],
|
435
|
+
[1, '!'],
|
436
|
+
[0, ['nology', 142.578125, '...']]
|
437
|
+
])
|
438
|
+
end
|
439
|
+
|
440
|
+
it 'uses the ascender, descender, and cap height from the TTF verbatim' do
|
441
|
+
# These metrics are relative to the font's own bbox. They should not be
|
442
|
+
# scaled with font size.
|
443
|
+
ref = pdf.ref!({})
|
444
|
+
font.__send__(:embed, ref, 0)
|
445
|
+
|
446
|
+
# Pull out the embedded font descriptor
|
447
|
+
descriptor = ref.data[:FontDescriptor].data
|
448
|
+
expect(descriptor[:Ascent]).to eq(759)
|
449
|
+
expect(descriptor[:Descent]).to eq(-240)
|
450
|
+
expect(descriptor[:CapHeight]).to eq(759)
|
451
|
+
end
|
452
|
+
|
453
|
+
describe 'when normalizing encoding' do
|
454
|
+
it 'does not modify the original string with normalize_encoding()' do
|
455
|
+
original = 'Foo'
|
456
|
+
normalized = font.normalize_encoding(original)
|
457
|
+
expect(original.equal?(normalized)).to eq false
|
458
|
+
end
|
459
|
+
end
|
460
|
+
end
|
461
|
+
|
462
|
+
describe 'OTF fonts' do
|
463
|
+
let(:font) { pdf.find_font "#{Prawn::DATADIR}/fonts/Bodoni-Book.otf" }
|
464
|
+
|
465
|
+
it 'calculates string width taking into account accented characters' do
|
466
|
+
expect(font.compute_width_of('é', size: 12)).to eq(
|
467
|
+
font.compute_width_of('e', size: 12)
|
468
|
+
)
|
469
|
+
end
|
470
|
+
|
471
|
+
it 'uses the ascender, descender, and cap height from the OTF verbatim' do
|
472
|
+
# These metrics are relative to the font's own bbox. They should not be
|
473
|
+
# scaled with font size.
|
474
|
+
ref = pdf.ref!({})
|
475
|
+
font.__send__(:embed, ref, 0)
|
476
|
+
|
477
|
+
# Pull out the embedded font descriptor
|
478
|
+
descriptor = ref.data[:FontDescriptor].data
|
479
|
+
expect(descriptor[:Ascent]).to eq(1023)
|
480
|
+
expect(descriptor[:Descent]).to eq(-200)
|
481
|
+
expect(descriptor[:CapHeight]).to eq(3072)
|
482
|
+
end
|
483
|
+
|
484
|
+
describe 'when normalizing encoding' do
|
485
|
+
it 'does not modify the original string with normalize_encoding()' do
|
486
|
+
original = 'Foo'
|
487
|
+
normalized = font.normalize_encoding(original)
|
488
|
+
expect(original).to_not be_equal(normalized)
|
489
|
+
end
|
490
|
+
end
|
491
|
+
end
|
492
|
+
|
493
|
+
describe 'DFont fonts' do
|
494
|
+
let(:file) { "#{Prawn::DATADIR}/fonts/Panic+Sans.dfont" }
|
495
|
+
|
496
|
+
it 'lists all named fonts' do
|
497
|
+
list = Prawn::Fonts::DFont.named_fonts(file)
|
498
|
+
expect(list).to match_array(%w[
|
499
|
+
PanicSans PanicSans-Bold PanicSans-BoldItalic PanicSans-Italic
|
500
|
+
])
|
501
|
+
end
|
502
|
+
|
503
|
+
it 'counts the number of fonts in the file' do
|
504
|
+
expect(Prawn::Fonts::DFont.font_count(file)).to eq(4)
|
505
|
+
end
|
506
|
+
|
507
|
+
it 'defaults selected font to the first one if not specified' do
|
508
|
+
font = pdf.find_font(file)
|
509
|
+
expect(font.basename).to eq('PanicSans')
|
510
|
+
end
|
511
|
+
|
512
|
+
it 'allows font to be selected by index' do
|
513
|
+
font = pdf.find_font(file, font: 2)
|
514
|
+
expect(font.basename).to eq('PanicSans-Italic')
|
515
|
+
end
|
516
|
+
|
517
|
+
it 'allows font to be selected by name' do
|
518
|
+
font = pdf.find_font(file, font: 'PanicSans-BoldItalic')
|
519
|
+
expect(font.basename).to eq('PanicSans-BoldItalic')
|
520
|
+
end
|
521
|
+
|
522
|
+
it 'caches font object based on selected font' do
|
523
|
+
f1 = pdf.find_font(file, font: 'PanicSans')
|
524
|
+
f2 = pdf.find_font(file, font: 'PanicSans-Bold')
|
525
|
+
expect(f2.object_id).to_not eq(f1.object_id)
|
526
|
+
expect(pdf.find_font(file, font: 'PanicSans').object_id)
|
527
|
+
.to eq(f1.object_id)
|
528
|
+
expect(pdf.find_font(file, font: 'PanicSans-Bold').object_id)
|
529
|
+
.to eq(f2.object_id)
|
530
|
+
end
|
531
|
+
end
|
532
|
+
|
533
|
+
describe '#character_count(text)' do
|
534
|
+
it 'works on TTF fonts' do
|
535
|
+
pdf.font("#{Prawn::DATADIR}/fonts/gkai00mp.ttf")
|
536
|
+
expect(pdf.font.character_count('こんにちは世界')).to eq(7)
|
537
|
+
expect(pdf.font.character_count('Hello, world!')).to eq(13)
|
538
|
+
end
|
539
|
+
|
540
|
+
it 'works on AFM fonts' do
|
541
|
+
expect(pdf.font.character_count('Hello, world!')).to eq(13)
|
542
|
+
end
|
543
|
+
end
|
544
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Prawn::Graphics::BlendMode do
|
6
|
+
def make_blend_mode(blend_mode)
|
7
|
+
pdf.blend_mode(blend_mode) do
|
8
|
+
yield if block_given?
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:pdf) { create_pdf }
|
13
|
+
|
14
|
+
it 'the PDF version should be at least 1.4' do
|
15
|
+
make_blend_mode(:Multiply)
|
16
|
+
str = pdf.render
|
17
|
+
expect(str[0, 8]).to eq('%PDF-1.4')
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'a new extended graphics state should be created for ' \
|
21
|
+
'each unique blend mode setting' do
|
22
|
+
make_blend_mode(:Multiply) do
|
23
|
+
make_blend_mode(:Screen)
|
24
|
+
end
|
25
|
+
extgstates = PDF::Inspector::ExtGState.analyze(pdf.render).extgstates
|
26
|
+
expect(extgstates.length).to eq(2)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'a new extended graphics state should not be created for ' \
|
30
|
+
'each duplicate blend mode setting' do
|
31
|
+
make_blend_mode(:Multiply) do
|
32
|
+
make_blend_mode(:Multiply)
|
33
|
+
end
|
34
|
+
extgstates = PDF::Inspector::ExtGState.analyze(pdf.render).extgstates
|
35
|
+
expect(extgstates.length).to eq(1)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'setting the blend mode with only one parameter sets a single '\
|
39
|
+
'blend mode value' do
|
40
|
+
make_blend_mode(:Multiply)
|
41
|
+
extgstate = PDF::Inspector::ExtGState.analyze(pdf.render).extgstates.first
|
42
|
+
expect(extgstate[:blend_mode]).to eq(:Multiply)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'setting the blend mode with multiple parameters sets an array of '\
|
46
|
+
'blend modes' do
|
47
|
+
make_blend_mode(%i[Multiply Screen Overlay])
|
48
|
+
extgstate = PDF::Inspector::ExtGState.analyze(pdf.render).extgstates.first
|
49
|
+
expect(extgstate[:blend_mode]).to eq(%i[Multiply Screen Overlay])
|
50
|
+
end
|
51
|
+
|
52
|
+
describe 'with more than one page' do
|
53
|
+
it 'the extended graphic state resource should be added to both pages' do
|
54
|
+
make_blend_mode(:Multiply)
|
55
|
+
pdf.start_new_page
|
56
|
+
make_blend_mode(:Multiply)
|
57
|
+
extgstates = PDF::Inspector::ExtGState.analyze(pdf.render).extgstates
|
58
|
+
extgstate = extgstates[0]
|
59
|
+
expect(extgstates.length).to eq(2)
|
60
|
+
expect(extgstate[:blend_mode]).to eq(:Multiply)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|