prawn 1.1.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 +1 -0
- data/GPLv2 +20 -21
- data/Gemfile +3 -9
- data/Rakefile +9 -40
- data/lib/prawn/document/bounding_box.rb +54 -40
- data/lib/prawn/document/column_box.rb +8 -10
- data/lib/prawn/document/internals.rb +39 -146
- data/lib/prawn/document/span.rb +23 -17
- data/lib/prawn/document.rb +217 -182
- data/lib/prawn/encoding.rb +69 -101
- data/lib/prawn/errors.rb +47 -43
- data/lib/prawn/font.rb +124 -104
- data/lib/prawn/font_metric_cache.rb +23 -21
- data/lib/prawn/fonts/afm.rb +292 -0
- data/lib/prawn/{font → fonts}/dfont.rb +5 -12
- data/lib/prawn/fonts/otf.rb +11 -0
- data/lib/prawn/fonts/ttc.rb +36 -0
- data/lib/prawn/{font → fonts}/ttf.rb +140 -88
- data/lib/prawn/graphics/blend_mode.rb +65 -0
- data/lib/prawn/graphics/cap_style.rb +5 -5
- data/lib/prawn/graphics/color.rb +46 -44
- data/lib/prawn/graphics/dash.rb +27 -11
- data/lib/prawn/graphics/join_style.rb +11 -6
- data/lib/prawn/graphics/patterns.rb +220 -78
- data/lib/prawn/graphics/transformation.rb +20 -12
- data/lib/prawn/graphics/transparency.rb +20 -18
- data/lib/prawn/graphics.rb +153 -115
- data/lib/prawn/grid.rb +93 -50
- data/lib/prawn/image_handler.rb +4 -4
- data/lib/prawn/images/image.rb +3 -2
- data/lib/prawn/images/jpg.rb +31 -24
- data/lib/prawn/images/png.rb +101 -68
- data/lib/prawn/images.rb +64 -56
- data/lib/prawn/measurement_extensions.rb +10 -9
- data/lib/prawn/measurements.rb +20 -23
- data/lib/prawn/outline.rb +96 -75
- data/lib/prawn/repeater.rb +16 -16
- data/lib/prawn/security/arcfour.rb +2 -2
- data/lib/prawn/security.rb +100 -85
- data/lib/prawn/soft_mask.rb +37 -38
- data/lib/prawn/stamp.rb +28 -13
- data/lib/prawn/text/box.rb +24 -29
- data/lib/prawn/text/formatted/arranger.rb +108 -63
- data/lib/prawn/text/formatted/box.rb +187 -124
- data/lib/prawn/text/formatted/fragment.rb +24 -20
- data/lib/prawn/text/formatted/line_wrap.rb +133 -73
- data/lib/prawn/text/formatted/parser.rb +147 -127
- data/lib/prawn/text/formatted/wrap.rb +48 -35
- data/lib/prawn/text/formatted.rb +5 -5
- data/lib/prawn/text.rb +103 -68
- data/lib/prawn/transformation_stack.rb +44 -0
- data/lib/prawn/utilities.rb +10 -22
- data/lib/prawn/version.rb +5 -0
- data/lib/prawn/view.rb +101 -0
- data/lib/prawn.rb +39 -54
- data/manual/basic_concepts/adding_pages.rb +6 -7
- data/manual/basic_concepts/basic_concepts.rb +34 -25
- data/manual/basic_concepts/creation.rb +10 -11
- data/manual/basic_concepts/cursor.rb +4 -5
- data/manual/basic_concepts/measurement.rb +8 -9
- data/manual/basic_concepts/origin.rb +5 -6
- data/manual/basic_concepts/other_cursor_helpers.rb +11 -12
- data/manual/basic_concepts/view.rb +48 -0
- data/manual/bounding_box/bounding_box.rb +30 -28
- data/manual/bounding_box/bounds.rb +12 -13
- data/manual/bounding_box/canvas.rb +7 -8
- data/manual/bounding_box/creation.rb +6 -7
- data/manual/bounding_box/indentation.rb +14 -15
- data/manual/bounding_box/nesting.rb +25 -18
- data/manual/bounding_box/russian_boxes.rb +18 -18
- data/manual/bounding_box/stretchy.rb +12 -14
- data/manual/contents.rb +28 -22
- data/manual/cover.rb +33 -32
- data/manual/document_and_page_options/background.rb +15 -13
- data/manual/document_and_page_options/document_and_page_options.rb +24 -22
- data/manual/document_and_page_options/metadata.rb +20 -18
- data/manual/document_and_page_options/page_margins.rb +18 -20
- data/manual/document_and_page_options/page_size.rb +13 -13
- data/manual/document_and_page_options/print_scaling.rb +18 -15
- data/manual/example_helper.rb +5 -4
- data/manual/graphics/blend_mode.rb +52 -0
- data/manual/graphics/circle_and_ellipse.rb +4 -5
- data/manual/graphics/color.rb +7 -9
- data/manual/graphics/common_lines.rb +7 -8
- data/manual/graphics/fill_and_stroke.rb +5 -6
- data/manual/graphics/fill_rules.rb +12 -11
- data/manual/graphics/gradients.rb +27 -21
- data/manual/graphics/graphics.rb +46 -40
- data/manual/graphics/helper.rb +19 -9
- data/manual/graphics/line_width.rb +8 -7
- data/manual/graphics/lines_and_curves.rb +8 -9
- data/manual/graphics/polygon.rb +6 -8
- data/manual/graphics/rectangle.rb +4 -5
- data/manual/graphics/rotate.rb +6 -9
- data/manual/graphics/scale.rb +14 -13
- data/manual/graphics/soft_masks.rb +4 -6
- data/manual/graphics/stroke_cap.rb +7 -8
- data/manual/graphics/stroke_dash.rb +15 -16
- data/manual/graphics/stroke_join.rb +6 -7
- data/manual/graphics/translate.rb +10 -10
- data/manual/graphics/transparency.rb +7 -9
- data/manual/how_to_read_this_manual.rb +8 -9
- data/manual/images/absolute_position.rb +6 -7
- data/manual/images/fit.rb +7 -8
- data/manual/images/horizontal.rb +10 -11
- data/manual/images/images.rb +28 -27
- data/manual/images/plain_image.rb +5 -6
- data/manual/images/scale.rb +9 -10
- data/manual/images/vertical.rb +16 -14
- data/manual/images/width_and_height.rb +10 -11
- data/manual/layout/boxes.rb +10 -11
- data/manual/layout/content.rb +9 -10
- data/manual/layout/layout.rb +17 -18
- data/manual/layout/simple_grid.rb +6 -7
- data/manual/outline/add_subsection_to.rb +20 -21
- data/manual/outline/insert_section_after.rb +15 -16
- data/manual/outline/outline.rb +22 -21
- data/manual/outline/sections_and_pages.rb +17 -18
- data/manual/repeatable_content/alternate_page_numbering.rb +36 -0
- data/manual/repeatable_content/page_numbering.rb +17 -16
- data/manual/repeatable_content/repeatable_content.rb +27 -23
- data/manual/repeatable_content/repeater.rb +15 -16
- data/manual/repeatable_content/stamp.rb +14 -15
- data/manual/security/encryption.rb +8 -11
- data/manual/security/permissions.rb +20 -15
- data/manual/security/security.rb +18 -18
- data/manual/table.rb +16 -0
- data/manual/text/alignment.rb +16 -17
- data/manual/text/color.rb +12 -12
- data/manual/text/column_box.rb +9 -11
- data/manual/text/fallback_fonts.rb +25 -21
- data/manual/text/font.rb +11 -12
- data/manual/text/font_size.rb +13 -14
- data/manual/text/font_style.rb +10 -8
- data/manual/text/formatted_callbacks.rb +33 -23
- data/manual/text/formatted_text.rb +36 -25
- data/manual/text/free_flowing_text.rb +22 -23
- data/manual/text/inline.rb +18 -19
- data/manual/text/kerning_and_character_spacing.rb +14 -15
- data/manual/text/leading.rb +7 -8
- data/manual/text/line_wrapping.rb +37 -18
- data/manual/text/paragraph_indentation.rb +15 -10
- data/manual/text/positioned_text.rb +16 -17
- data/manual/text/registering_families.rb +27 -24
- data/manual/text/rendering_and_color.rb +9 -10
- data/manual/text/right_to_left_text.rb +30 -19
- data/manual/text/rotation.rb +33 -24
- data/manual/text/single_usage.rb +8 -9
- data/manual/text/text.rb +56 -54
- data/manual/text/text_box_excess.rb +20 -17
- data/manual/text/text_box_extensions.rb +18 -15
- data/manual/text/text_box_overflow.rb +24 -17
- data/manual/text/utf8.rb +12 -13
- data/manual/text/win_ansi_charset.rb +28 -25
- data/prawn.gemspec +45 -50
- data/spec/extensions/encoding_helpers.rb +3 -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 +19 -25
- data.tar.gz.sig +0 -0
- metadata +113 -276
- metadata.gz.sig +0 -0
- data/data/encodings/win_ansi.txt +0 -29
- data/data/images/16bit.alpha +0 -0
- data/data/images/16bit.color +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/dice.alpha +0 -0
- data/data/images/dice.color +0 -0
- data/data/images/dice.png +0 -0
- data/data/images/dice_interlaced.png +0 -0
- data/data/images/fractal.jpg +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/license.md +0 -8
- data/data/images/page_white_text.alpha +0 -0
- data/data/images/page_white_text.color +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/prawn/document/graphics_state.rb +0 -73
- data/lib/prawn/font/afm.rb +0 -247
- data/lib/prawn/table/cell/image.rb +0 -69
- data/lib/prawn/table/cell/in_table.rb +0 -33
- data/lib/prawn/table/cell/span_dummy.rb +0 -93
- data/lib/prawn/table/cell/subtable.rb +0 -66
- data/lib/prawn/table/cell/text.rb +0 -154
- data/lib/prawn/table/cell.rb +0 -772
- data/lib/prawn/table/cells.rb +0 -255
- data/lib/prawn/table/column_width_calculator.rb +0 -182
- data/lib/prawn/table.rb +0 -644
- 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/spec/acceptance/png.rb +0 -25
- data/spec/annotations_spec.rb +0 -74
- data/spec/bounding_box_spec.rb +0 -510
- data/spec/cell_spec.rb +0 -629
- data/spec/column_box_spec.rb +0 -65
- data/spec/destinations_spec.rb +0 -15
- data/spec/document_spec.rb +0 -730
- data/spec/extensions/mocha.rb +0 -46
- data/spec/font_metric_cache_spec.rb +0 -52
- data/spec/font_spec.rb +0 -449
- data/spec/formatted_text_arranger_spec.rb +0 -421
- data/spec/formatted_text_box_spec.rb +0 -639
- data/spec/formatted_text_fragment_spec.rb +0 -298
- data/spec/graphics_spec.rb +0 -669
- data/spec/grid_spec.rb +0 -96
- data/spec/image_handler_spec.rb +0 -54
- data/spec/images_spec.rb +0 -153
- data/spec/inline_formatted_text_parser_spec.rb +0 -564
- data/spec/jpg_spec.rb +0 -25
- data/spec/line_wrap_spec.rb +0 -344
- data/spec/measurement_units_spec.rb +0 -25
- data/spec/outline_spec.rb +0 -430
- data/spec/png_spec.rb +0 -237
- data/spec/reference_spec.rb +0 -25
- data/spec/repeater_spec.rb +0 -160
- data/spec/security_spec.rb +0 -158
- data/spec/soft_mask_spec.rb +0 -79
- data/spec/span_spec.rb +0 -44
- data/spec/stamp_spec.rb +0 -160
- data/spec/stroke_styles_spec.rb +0 -211
- data/spec/table/span_dummy_spec.rb +0 -17
- data/spec/table_spec.rb +0 -1527
- data/spec/text_at_spec.rb +0 -115
- data/spec/text_box_spec.rb +0 -1034
- data/spec/text_rendering_mode_spec.rb +0 -45
- data/spec/text_spacing_spec.rb +0 -93
- data/spec/text_spec.rb +0 -437
- data/spec/text_with_inline_formatting_spec.rb +0 -35
- data/spec/transparency_spec.rb +0 -91
data/lib/prawn/graphics/dash.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# dash.rb : Implements stroke dashing
|
4
4
|
#
|
@@ -28,8 +28,9 @@ module Prawn
|
|
28
28
|
# 3 on, 2 off, 3 on, 2 off, ...
|
29
29
|
#
|
30
30
|
# * If the parameter +length+ is an array, it specifies the
|
31
|
-
# lengths of alternating dashes and gaps. The
|
32
|
-
#
|
31
|
+
# lengths of alternating dashes and gaps. The numbers must be
|
32
|
+
# non-negative and not all zero. The :space option is ignored
|
33
|
+
# in this case.
|
33
34
|
#
|
34
35
|
# Examples:
|
35
36
|
#
|
@@ -37,6 +38,8 @@ module Prawn
|
|
37
38
|
# 2 on, 1 off, 2 on, 1 off, ...
|
38
39
|
# length = [3, 1, 2, 3]
|
39
40
|
# 3 on, 1 off, 2 on, 3 off, 3 on, 1 off, ...
|
41
|
+
# length = [3, 0, 1]
|
42
|
+
# 3 on, 0 off, 1 on, 3 off, 0 on, 1 off, ...
|
40
43
|
#
|
41
44
|
# Options may contain the keys :space and :phase
|
42
45
|
#
|
@@ -52,17 +55,31 @@ module Prawn
|
|
52
55
|
# Integers or Floats may be used for length and the option values.
|
53
56
|
# Dash units are in PDF points (1/72 inch).
|
54
57
|
#
|
55
|
-
def dash(length=nil, options={})
|
58
|
+
def dash(length = nil, options = {})
|
56
59
|
return current_dash_state if length.nil?
|
57
60
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
+
length = Array(length)
|
62
|
+
|
63
|
+
if length.all?(&:zero?)
|
64
|
+
raise ArgumentError,
|
65
|
+
'Zero length dashes are invalid. Call #undash to disable dashes.'
|
66
|
+
elsif length.any?(&:negative?)
|
67
|
+
raise ArgumentError,
|
68
|
+
'Negative numbers are not allowed for dash lengths.'
|
69
|
+
end
|
70
|
+
|
71
|
+
length = length.first if length.length == 1
|
72
|
+
|
73
|
+
self.current_dash_state = {
|
74
|
+
dash: length,
|
75
|
+
space: length.is_a?(Array) ? nil : options[:space] || length,
|
76
|
+
phase: options[:phase] || 0
|
77
|
+
}
|
61
78
|
|
62
79
|
write_stroke_dash
|
63
80
|
end
|
64
81
|
|
65
|
-
|
82
|
+
alias dash= dash
|
66
83
|
|
67
84
|
# Stops dashing, restoring solid stroked lines and curves
|
68
85
|
#
|
@@ -80,11 +97,11 @@ module Prawn
|
|
80
97
|
private
|
81
98
|
|
82
99
|
def write_stroke_dash
|
83
|
-
add_content dash_setting
|
100
|
+
renderer.add_content dash_setting
|
84
101
|
end
|
85
102
|
|
86
103
|
def undashed_setting
|
87
|
-
{ :
|
104
|
+
{ dash: nil, space: nil, phase: 0 }
|
88
105
|
end
|
89
106
|
|
90
107
|
def current_dash_state=(dash_options)
|
@@ -98,7 +115,6 @@ module Prawn
|
|
98
115
|
def dash_setting
|
99
116
|
graphic_state.dash_setting
|
100
117
|
end
|
101
|
-
|
102
118
|
end
|
103
119
|
end
|
104
120
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# join_style.rb : Implements stroke join styling
|
4
4
|
#
|
@@ -9,7 +9,7 @@
|
|
9
9
|
module Prawn
|
10
10
|
module Graphics
|
11
11
|
module JoinStyle
|
12
|
-
JOIN_STYLES = { :
|
12
|
+
JOIN_STYLES = { miter: 0, round: 1, bevel: 2 }.freeze
|
13
13
|
|
14
14
|
# @group Stable API
|
15
15
|
|
@@ -20,15 +20,21 @@ module Prawn
|
|
20
20
|
# NOTE: if this method is never called, :miter will be used for join style
|
21
21
|
# throughout the document
|
22
22
|
#
|
23
|
-
def join_style(style=nil)
|
23
|
+
def join_style(style = nil)
|
24
24
|
return current_join_style || :miter if style.nil?
|
25
25
|
|
26
26
|
self.current_join_style = style
|
27
27
|
|
28
|
+
unless JOIN_STYLES.key?(current_join_style)
|
29
|
+
raise Prawn::Errors::InvalidJoinStyle,
|
30
|
+
"#{style} is not a recognized join style. Valid styles are " +
|
31
|
+
JOIN_STYLES.keys.join(', ')
|
32
|
+
end
|
33
|
+
|
28
34
|
write_stroke_join_style
|
29
35
|
end
|
30
36
|
|
31
|
-
|
37
|
+
alias join_style= join_style
|
32
38
|
|
33
39
|
private
|
34
40
|
|
@@ -40,9 +46,8 @@ module Prawn
|
|
40
46
|
graphic_state.join_style = style
|
41
47
|
end
|
42
48
|
|
43
|
-
|
44
49
|
def write_stroke_join_style
|
45
|
-
add_content "#{JOIN_STYLES[current_join_style]} j"
|
50
|
+
renderer.add_content "#{JOIN_STYLES[current_join_style]} j"
|
46
51
|
end
|
47
52
|
end
|
48
53
|
end
|
@@ -1,4 +1,6 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'digest/sha1'
|
2
4
|
|
3
5
|
# patterns.rb : Implements axial & radial gradients
|
4
6
|
#
|
@@ -10,116 +12,256 @@
|
|
10
12
|
module Prawn
|
11
13
|
module Graphics
|
12
14
|
module Patterns
|
15
|
+
GradientStop = Struct.new(:position, :color)
|
16
|
+
Gradient = Struct.new(
|
17
|
+
:type, :apply_transformations, :stops, :from, :to, :r1, :r2
|
18
|
+
)
|
19
|
+
|
13
20
|
# @group Stable API
|
14
21
|
|
15
|
-
# Sets the fill gradient
|
16
|
-
# old arguments:
|
17
|
-
#
|
18
|
-
#
|
19
|
-
|
20
|
-
|
22
|
+
# Sets the fill gradient.
|
23
|
+
# old arguments:
|
24
|
+
# from, to, color1, color2
|
25
|
+
# or
|
26
|
+
# from, r1, to, r2, color1, color2
|
27
|
+
# new arguments:
|
28
|
+
# from: [x, y]
|
29
|
+
# to: [x, y]
|
30
|
+
# r1: radius
|
31
|
+
# r2: radius
|
32
|
+
# stops: [color, color, ...] or
|
33
|
+
# { position => color, position => color, ... }
|
34
|
+
# apply_transformations: true
|
35
|
+
#
|
36
|
+
# Examples:
|
37
|
+
#
|
38
|
+
# # draws a horizontal axial gradient that starts at red on the left
|
39
|
+
# # and ends at blue on the right
|
40
|
+
# fill_gradient from: [0, 0], to: [100, 0], stops: ['red', 'blue']
|
41
|
+
#
|
42
|
+
# # draws a horizontal radial gradient that starts at red, is green
|
43
|
+
# # 80% of the way through, and finishes blue
|
44
|
+
# fill_gradient from: [0, 0], r1: 0, to: [100, 0], r2: 180,
|
45
|
+
# stops: { 0 => 'red', 0.8 => 'green', 1 => 'blue' }
|
46
|
+
#
|
47
|
+
# <tt>from</tt> and <tt>to</tt> specify the axis of where the gradient
|
48
|
+
# should be painted.
|
49
|
+
#
|
50
|
+
# <tt>r1</tt> and <tt>r2</tt>, if specified, make a radial gradient with
|
51
|
+
# the starting circle of radius <tt>r1</tt> centered at <tt>from</tt>
|
52
|
+
# and ending at a circle of radius <tt>r2</tt> centered at <tt>to</tt>.
|
53
|
+
# If <tt>r1</tt> is not specified, a axial gradient will be drawn.
|
54
|
+
#
|
55
|
+
# <tt>stops</tt> is an array or hash of stops. Each stop is either just a
|
56
|
+
# string indicating the color, in which case the stops will be evenly
|
57
|
+
# distributed across the gradient, or a hash where the key is
|
58
|
+
# a position between 0 and 1 indicating what distance through the
|
59
|
+
# gradient the color should change, and the value is a color string.
|
60
|
+
#
|
61
|
+
# Option <tt>apply_transformations</tt>, if set true, will transform the
|
62
|
+
# gradient's co-ordinate space so it matches the current co-ordinate
|
63
|
+
# space of the document. This option will be the default from Prawn v3,
|
64
|
+
# and is default true if you use the new arguments format.
|
65
|
+
# The default for the old arguments format, false, will mean if you
|
66
|
+
# (for example) scale your document by 2 and put a gradient inside, you
|
67
|
+
# will have to manually multiply your co-ordinates by 2 so the gradient
|
68
|
+
# is correctly positioned.
|
69
|
+
def fill_gradient(*args, **kwargs)
|
70
|
+
set_gradient(:fill, *args, **kwargs)
|
21
71
|
end
|
22
72
|
|
23
|
-
# Sets the stroke gradient
|
24
|
-
#
|
25
|
-
|
26
|
-
|
27
|
-
def stroke_gradient(*args)
|
28
|
-
set_gradient(:stroke, *args)
|
73
|
+
# Sets the stroke gradient.
|
74
|
+
# See fill_gradient for a description of the arguments to this method.
|
75
|
+
def stroke_gradient(*args, **kwargs)
|
76
|
+
set_gradient(:stroke, *args, **kwargs)
|
29
77
|
end
|
30
78
|
|
31
79
|
private
|
32
80
|
|
33
|
-
def set_gradient(type, *grad)
|
81
|
+
def set_gradient(type, *grad, **kwargs)
|
82
|
+
gradient = parse_gradient_arguments(*grad, **kwargs)
|
83
|
+
|
34
84
|
patterns = page.resources[:Pattern] ||= {}
|
35
85
|
|
36
|
-
registry_key = gradient_registry_key
|
86
|
+
registry_key = gradient_registry_key gradient
|
37
87
|
|
38
|
-
|
39
|
-
shading =
|
40
|
-
|
41
|
-
|
42
|
-
shading = gradient(*grad)
|
88
|
+
unless patterns.key? "SP#{registry_key}"
|
89
|
+
shading = gradient_registry[registry_key]
|
90
|
+
unless shading
|
91
|
+
shading = create_gradient_pattern(gradient)
|
43
92
|
gradient_registry[registry_key] = shading
|
44
93
|
end
|
45
94
|
|
46
95
|
patterns["SP#{registry_key}"] = shading
|
47
96
|
end
|
48
97
|
|
49
|
-
operator =
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
98
|
+
operator =
|
99
|
+
case type
|
100
|
+
when :fill
|
101
|
+
'scn'
|
102
|
+
when :stroke
|
103
|
+
'SCN'
|
104
|
+
else
|
105
|
+
raise ArgumentError, "unknown type '#{type}'"
|
106
|
+
end
|
107
|
+
|
108
|
+
set_color_space type, :Pattern
|
109
|
+
renderer.add_content "/SP#{registry_key} #{operator}"
|
110
|
+
end
|
111
|
+
|
112
|
+
# rubocop: disable Metrics/ParameterLists
|
113
|
+
def parse_gradient_arguments(
|
114
|
+
*arguments, from: nil, to: nil, r1: nil, r2: nil, stops: nil,
|
115
|
+
apply_transformations: nil
|
116
|
+
)
|
117
|
+
|
118
|
+
case arguments.length
|
119
|
+
when 0
|
120
|
+
apply_transformations = true if apply_transformations.nil?
|
121
|
+
when 4
|
122
|
+
from, to, *stops = arguments
|
123
|
+
when 6
|
124
|
+
from, r1, to, r2, *stops = arguments
|
54
125
|
else
|
55
|
-
raise ArgumentError, "
|
126
|
+
raise ArgumentError, "Unknown type of gradient: #{arguments.inspect}"
|
56
127
|
end
|
57
128
|
|
58
|
-
|
59
|
-
|
129
|
+
if stops.length < 2
|
130
|
+
raise ArgumentError, 'At least two stops must be specified'
|
131
|
+
end
|
132
|
+
|
133
|
+
stops =
|
134
|
+
stops.map.with_index do |stop, index|
|
135
|
+
case stop
|
136
|
+
when Array, Hash
|
137
|
+
position, color = stop
|
138
|
+
else
|
139
|
+
position = index / (stops.length.to_f - 1)
|
140
|
+
color = stop
|
141
|
+
end
|
142
|
+
|
143
|
+
unless (0..1).cover?(position)
|
144
|
+
raise ArgumentError, 'position must be between 0 and 1'
|
145
|
+
end
|
146
|
+
|
147
|
+
GradientStop.new(position, normalize_color(color))
|
148
|
+
end
|
149
|
+
|
150
|
+
if stops.first.position != 0
|
151
|
+
raise ArgumentError, 'The first stop must have a position of 0'
|
152
|
+
end
|
153
|
+
if stops.last.position != 1
|
154
|
+
raise ArgumentError, 'The last stop must have a position of 1'
|
155
|
+
end
|
156
|
+
|
157
|
+
if stops.map { |stop| color_type(stop.color) }.uniq.length > 1
|
158
|
+
raise ArgumentError, 'All colors must be of the same color space'
|
159
|
+
end
|
160
|
+
|
161
|
+
Gradient.new(
|
162
|
+
r1 ? :radial : :axial,
|
163
|
+
apply_transformations,
|
164
|
+
stops,
|
165
|
+
from,
|
166
|
+
to,
|
167
|
+
r1,
|
168
|
+
r2
|
169
|
+
)
|
60
170
|
end
|
171
|
+
# rubocop: enable Metrics/ParameterLists
|
61
172
|
|
62
173
|
def gradient_registry_key(gradient)
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
gradient[3],
|
75
|
-
gradient[4], gradient[5]
|
76
|
-
]
|
77
|
-
end.hash
|
174
|
+
_x1, _y1, x2, y2, transformation = gradient_coordinates(gradient)
|
175
|
+
|
176
|
+
key = [
|
177
|
+
gradient.type.to_s,
|
178
|
+
transformation,
|
179
|
+
x2, y2,
|
180
|
+
gradient.r1 || -1, gradient.r2 || -1,
|
181
|
+
gradient.stops.length,
|
182
|
+
gradient.stops.map { |s| [s.position, s.color] }
|
183
|
+
].flatten
|
184
|
+
Digest::SHA1.hexdigest(key.join(','))
|
78
185
|
end
|
79
186
|
|
80
187
|
def gradient_registry
|
81
188
|
@gradient_registry ||= {}
|
82
189
|
end
|
83
190
|
|
84
|
-
def gradient
|
85
|
-
if
|
86
|
-
|
191
|
+
def create_gradient_pattern(gradient)
|
192
|
+
if gradient.apply_transformations.nil? &&
|
193
|
+
current_transformation_matrix_with_translation(0, 0) !=
|
194
|
+
[1, 0, 0, 1, 0, 0]
|
195
|
+
warn 'Gradients in Prawn 2.x and lower are not correctly positioned '\
|
196
|
+
'when a transformation has been made to the document. ' \
|
197
|
+
"Pass 'apply_transformations: true' to correctly transform the " \
|
198
|
+
'gradient, or see ' \
|
199
|
+
'https://github.com/prawnpdf/prawn/wiki/Gradient-Transformations ' \
|
200
|
+
'for more information.'
|
87
201
|
end
|
88
202
|
|
89
|
-
|
90
|
-
|
203
|
+
shader_stops =
|
204
|
+
gradient.stops.each_cons(2).map do |first, second|
|
205
|
+
ref!(
|
206
|
+
FunctionType: 2,
|
207
|
+
Domain: [0.0, 1.0],
|
208
|
+
C0: first.color,
|
209
|
+
C1: second.color,
|
210
|
+
N: 1.0
|
211
|
+
)
|
212
|
+
end
|
91
213
|
|
92
|
-
|
93
|
-
|
94
|
-
|
214
|
+
# If there's only two stops, we can use the single shader.
|
215
|
+
# Otherwise we stitch the multiple shaders together.
|
216
|
+
shader =
|
217
|
+
if shader_stops.length == 1
|
218
|
+
shader_stops.first
|
219
|
+
else
|
220
|
+
ref!(
|
221
|
+
FunctionType: 3, # stitching function
|
222
|
+
Domain: [0.0, 1.0],
|
223
|
+
Functions: shader_stops,
|
224
|
+
Bounds: gradient.stops[1..-2].map(&:position),
|
225
|
+
Encode: [0.0, 1.0] * shader_stops.length
|
226
|
+
)
|
227
|
+
end
|
228
|
+
|
229
|
+
x1, y1, x2, y2, transformation = gradient_coordinates(gradient)
|
230
|
+
|
231
|
+
coords =
|
232
|
+
if gradient.type == :axial
|
233
|
+
[0, 0, x2 - x1, y2 - y1]
|
234
|
+
else
|
235
|
+
[0, 0, gradient.r1, x2 - x1, y2 - y1, gradient.r2]
|
236
|
+
end
|
237
|
+
|
238
|
+
shading = ref!(
|
239
|
+
ShadingType: gradient.type == :axial ? 2 : 3,
|
240
|
+
ColorSpace: color_space(gradient.stops.first.color),
|
241
|
+
Coords: coords,
|
242
|
+
Function: shader,
|
243
|
+
Extend: [true, true]
|
244
|
+
)
|
245
|
+
|
246
|
+
ref!(
|
247
|
+
PatternType: 2, # shading pattern
|
248
|
+
Shading: shading,
|
249
|
+
Matrix: transformation
|
250
|
+
)
|
251
|
+
end
|
252
|
+
|
253
|
+
def gradient_coordinates(gradient)
|
254
|
+
x1, y1 = map_to_absolute(gradient.from)
|
255
|
+
x2, y2 = map_to_absolute(gradient.to)
|
256
|
+
|
257
|
+
transformation =
|
258
|
+
if gradient.apply_transformations
|
259
|
+
current_transformation_matrix_with_translation(x1, y1)
|
260
|
+
else
|
261
|
+
[1, 0, 0, 1, x1, y1]
|
262
|
+
end
|
95
263
|
|
96
|
-
|
97
|
-
process_color color2
|
98
|
-
|
99
|
-
shader = ref!({
|
100
|
-
:FunctionType => 2,
|
101
|
-
:Domain => [0.0, 1.0],
|
102
|
-
:C0 => color1,
|
103
|
-
:C1 => color2,
|
104
|
-
:N => 1.0,
|
105
|
-
})
|
106
|
-
|
107
|
-
shading = ref!({
|
108
|
-
:ShadingType => args.length == 4 ? 2 : 3, # axial : radial shading
|
109
|
-
:ColorSpace => color_space(color1),
|
110
|
-
:Coords => args.length == 4 ?
|
111
|
-
[0, 0, args[1].first - args[0].first, args[1].last - args[0].last] :
|
112
|
-
[0, 0, args[1], args[2].first - args[0].first, args[2].last - args[0].last, args[3]],
|
113
|
-
:Function => shader,
|
114
|
-
:Extend => [true, true],
|
115
|
-
})
|
116
|
-
|
117
|
-
ref!({
|
118
|
-
:PatternType => 2, # shading pattern
|
119
|
-
:Shading => shading,
|
120
|
-
:Matrix => [1, 0,
|
121
|
-
0, 1] + map_to_absolute(args[0]),
|
122
|
-
})
|
264
|
+
[x1, y1, x2, y2, transformation]
|
123
265
|
end
|
124
266
|
end
|
125
267
|
end
|
@@ -1,5 +1,5 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
3
|
# transformation.rb: Implements rotate, translate, skew, scale and a generic
|
4
4
|
# transformation_matrix
|
5
5
|
#
|
@@ -40,7 +40,7 @@ module Prawn
|
|
40
40
|
# pdf.stroke_rectangle([x, y], width, height)
|
41
41
|
# end
|
42
42
|
#
|
43
|
-
def rotate(angle, options={}, &block)
|
43
|
+
def rotate(angle, options = {}, &block)
|
44
44
|
Prawn.verify_options(:origin, options)
|
45
45
|
rad = degree_to_rad(angle)
|
46
46
|
cos = Math.cos(rad)
|
@@ -48,7 +48,8 @@ module Prawn
|
|
48
48
|
if options[:origin].nil?
|
49
49
|
transformation_matrix(cos, sin, -sin, cos, 0, 0, &block)
|
50
50
|
else
|
51
|
-
raise Prawn::Errors::BlockRequired unless
|
51
|
+
raise Prawn::Errors::BlockRequired unless block
|
52
|
+
|
52
53
|
x = options[:origin][0] + bounds.absolute_left
|
53
54
|
y = options[:origin][1] + bounds.absolute_bottom
|
54
55
|
x_prime = x * cos - y * sin
|
@@ -59,8 +60,8 @@ module Prawn
|
|
59
60
|
end
|
60
61
|
end
|
61
62
|
|
62
|
-
# Translate the user space. If a block is not provided, then you must
|
63
|
-
# and restore the graphics state yourself.
|
63
|
+
# Translate the user space. If a block is not provided, then you must
|
64
|
+
# save and restore the graphics state yourself.
|
64
65
|
#
|
65
66
|
# Example without a block: move the text up and over 10
|
66
67
|
#
|
@@ -112,12 +113,13 @@ module Prawn
|
|
112
113
|
# pdf.stroke_rectangle([x, y], width, height)
|
113
114
|
# end
|
114
115
|
#
|
115
|
-
def scale(factor, options={}, &block)
|
116
|
+
def scale(factor, options = {}, &block)
|
116
117
|
Prawn.verify_options(:origin, options)
|
117
118
|
if options[:origin].nil?
|
118
119
|
transformation_matrix(factor, 0, 0, factor, 0, 0, &block)
|
119
120
|
else
|
120
|
-
raise Prawn::Errors::BlockRequired unless
|
121
|
+
raise Prawn::Errors::BlockRequired unless block
|
122
|
+
|
121
123
|
x = options[:origin][0] + bounds.absolute_left
|
122
124
|
y = options[:origin][1] + bounds.absolute_bottom
|
123
125
|
x_prime = factor * x
|
@@ -142,16 +144,22 @@ module Prawn
|
|
142
144
|
# Transform the user space (see notes for rotate regarding graphics state)
|
143
145
|
# Generally, one would use the rotate, scale, translate, and skew
|
144
146
|
# convenience methods instead of calling transformation_matrix directly
|
145
|
-
def transformation_matrix(
|
146
|
-
|
147
|
+
def transformation_matrix(*matrix)
|
148
|
+
if matrix.length != 6
|
149
|
+
raise ArgumentError,
|
150
|
+
'Transformation matrix must have exacty 6 elements'
|
151
|
+
end
|
147
152
|
save_graphics_state if block_given?
|
148
|
-
|
153
|
+
|
154
|
+
add_to_transformation_stack(*matrix)
|
155
|
+
|
156
|
+
values = PDF::Core.real_params(matrix)
|
157
|
+
renderer.add_content "#{values} cm"
|
149
158
|
if block_given?
|
150
159
|
yield
|
151
160
|
restore_graphics_state
|
152
161
|
end
|
153
162
|
end
|
154
|
-
|
155
163
|
end
|
156
164
|
end
|
157
165
|
end
|
@@ -1,5 +1,5 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
3
|
# transparency.rb : Implements transparency
|
4
4
|
#
|
5
5
|
# Copyright October 2009, Daniel Nelson. All Rights Reserved.
|
@@ -9,7 +9,6 @@
|
|
9
9
|
|
10
10
|
module Prawn
|
11
11
|
module Graphics
|
12
|
-
|
13
12
|
# The Prawn::Transparency module is used to place transparent
|
14
13
|
# content on the page. It has the capacity for separate
|
15
14
|
# transparency values for stroked content and all other content.
|
@@ -29,7 +28,6 @@ module Prawn
|
|
29
28
|
# end
|
30
29
|
#
|
31
30
|
module Transparency
|
32
|
-
|
33
31
|
# @group Stable API
|
34
32
|
|
35
33
|
# Sets the <tt>opacity</tt> and <tt>stroke_opacity</tt> for all
|
@@ -53,14 +51,16 @@ module Prawn
|
|
53
51
|
# pdf.fill_and_stroke_circle([x, y], 25)
|
54
52
|
# end
|
55
53
|
#
|
56
|
-
def transparent(opacity, stroke_opacity=opacity
|
57
|
-
min_version(1.4)
|
54
|
+
def transparent(opacity, stroke_opacity = opacity)
|
55
|
+
renderer.min_version(1.4)
|
58
56
|
|
59
|
-
opacity
|
57
|
+
opacity = [[opacity, 0.0].max, 1.0].min
|
60
58
|
stroke_opacity = [[stroke_opacity, 0.0].max, 1.0].min
|
61
59
|
|
62
60
|
save_graphics_state
|
63
|
-
add_content
|
61
|
+
renderer.add_content(
|
62
|
+
"/#{opacity_dictionary_name(opacity, stroke_opacity)} gs"
|
63
|
+
)
|
64
64
|
yield
|
65
65
|
restore_graphics_state
|
66
66
|
end
|
@@ -79,23 +79,25 @@ module Prawn
|
|
79
79
|
key = "#{opacity}_#{stroke_opacity}"
|
80
80
|
|
81
81
|
if opacity_dictionary_registry[key]
|
82
|
-
dictionary =
|
83
|
-
dictionary_name =
|
82
|
+
dictionary = opacity_dictionary_registry[key][:obj]
|
83
|
+
dictionary_name = opacity_dictionary_registry[key][:name]
|
84
84
|
else
|
85
|
-
dictionary = ref!(
|
86
|
-
|
87
|
-
|
88
|
-
|
85
|
+
dictionary = ref!(
|
86
|
+
Type: :ExtGState,
|
87
|
+
CA: stroke_opacity,
|
88
|
+
ca: opacity
|
89
|
+
)
|
89
90
|
|
90
91
|
dictionary_name = "Tr#{next_opacity_dictionary_id}"
|
91
|
-
opacity_dictionary_registry[key] = {
|
92
|
-
|
92
|
+
opacity_dictionary_registry[key] = {
|
93
|
+
name: dictionary_name,
|
94
|
+
obj: dictionary
|
95
|
+
}
|
93
96
|
end
|
94
97
|
|
95
|
-
page.ext_gstates
|
98
|
+
page.ext_gstates[dictionary_name] = dictionary
|
96
99
|
dictionary_name
|
97
100
|
end
|
98
|
-
|
99
101
|
end
|
100
102
|
end
|
101
103
|
end
|