prawn-svg 0.35.1 → 0.36.1

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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +3 -5
  3. data/README.md +4 -7
  4. data/lib/prawn/svg/attributes/opacity.rb +23 -8
  5. data/lib/prawn/svg/attributes/stroke.rb +7 -9
  6. data/lib/prawn/svg/attributes/transform.rb +1 -1
  7. data/lib/prawn/svg/calculators/pixels.rb +9 -22
  8. data/lib/prawn/svg/color.rb +58 -59
  9. data/lib/prawn/svg/css/font_parser.rb +46 -0
  10. data/lib/prawn/svg/document.rb +16 -9
  11. data/lib/prawn/svg/elements/base.rb +22 -30
  12. data/lib/prawn/svg/elements/gradient.rb +99 -74
  13. data/lib/prawn/svg/elements/line.rb +1 -1
  14. data/lib/prawn/svg/elements/marker.rb +2 -0
  15. data/lib/prawn/svg/elements/root.rb +1 -1
  16. data/lib/prawn/svg/elements/text_component.rb +3 -3
  17. data/lib/prawn/svg/funciri.rb +14 -0
  18. data/lib/prawn/svg/gradient_renderer.rb +313 -0
  19. data/lib/prawn/svg/length.rb +43 -0
  20. data/lib/prawn/svg/paint.rb +67 -0
  21. data/lib/prawn/svg/percentage.rb +24 -0
  22. data/lib/prawn/svg/properties.rb +208 -104
  23. data/lib/prawn/svg/renderer.rb +5 -0
  24. data/lib/prawn/svg/state.rb +5 -3
  25. data/lib/prawn/svg/transform_parser.rb +19 -13
  26. data/lib/prawn/svg/transform_utils.rb +37 -0
  27. data/lib/prawn/svg/version.rb +1 -1
  28. data/lib/prawn-svg.rb +7 -3
  29. data/prawn-svg.gemspec +4 -4
  30. data/spec/prawn/svg/attributes/opacity_spec.rb +27 -20
  31. data/spec/prawn/svg/attributes/transform_spec.rb +5 -2
  32. data/spec/prawn/svg/calculators/pixels_spec.rb +1 -2
  33. data/spec/prawn/svg/color_spec.rb +22 -52
  34. data/spec/prawn/svg/document_spec.rb +18 -4
  35. data/spec/prawn/svg/elements/base_spec.rb +9 -10
  36. data/spec/prawn/svg/elements/gradient_spec.rb +92 -36
  37. data/spec/prawn/svg/elements/marker_spec.rb +13 -15
  38. data/spec/prawn/svg/funciri_spec.rb +59 -0
  39. data/spec/prawn/svg/length_spec.rb +89 -0
  40. data/spec/prawn/svg/paint_spec.rb +96 -0
  41. data/spec/prawn/svg/pathable_spec.rb +3 -3
  42. data/spec/prawn/svg/pdfmatrix_spec.rb +60 -0
  43. data/spec/prawn/svg/percentage_spec.rb +60 -0
  44. data/spec/prawn/svg/properties_spec.rb +124 -107
  45. data/spec/prawn/svg/transform_parser_spec.rb +13 -13
  46. data/spec/sample_svg/gradient_stress_test.svg +115 -0
  47. metadata +17 -5
  48. data/lib/prawn/svg/extensions/additional_gradient_transforms.rb +0 -23
@@ -6,7 +6,7 @@ RSpec.describe Prawn::SVG::TransformParser do
6
6
  include Prawn::SVG::TransformParser
7
7
 
8
8
  State = Struct.new(:viewport_sizing)
9
- Properties = Struct.new(:numerical_font_size)
9
+ Properties = Struct.new(:numeric_font_size)
10
10
  Document = Struct.new(:sizing)
11
11
 
12
12
  def document
@@ -30,27 +30,27 @@ RSpec.describe Prawn::SVG::TransformParser do
30
30
 
31
31
  context 'with no transform' do
32
32
  let(:transform) { '' }
33
- it { is_expected.to eq [1, 0, 0, 1, 0, 0] }
33
+ it { is_expected.to eq Matrix[[1, 0, 0], [0, 1, 0], [0, 0, 1]] }
34
34
  end
35
35
 
36
36
  context 'with translate' do
37
37
  let(:transform) { 'translate(10 20)' }
38
- it { is_expected.to eq [1, 0, 0, 1, 10, -20] }
38
+ it { is_expected.to eq Matrix[[1, 0, 10.0], [0, 1, -20.0], [0, 0, 1.0]] }
39
39
  end
40
40
 
41
41
  context 'with single argument translate' do
42
42
  let(:transform) { 'translate(10)' }
43
- it { is_expected.to eq [1, 0, 0, 1, 10, 0] }
43
+ it { is_expected.to eq Matrix[[1, 0, 10.0], [0, 1, 0.0], [0, 0, 1.0]] }
44
44
  end
45
45
 
46
46
  context 'with translateX' do
47
47
  let(:transform) { 'translateX(10)' }
48
- it { is_expected.to eq [1, 0, 0, 1, 10, 0] }
48
+ it { is_expected.to eq Matrix[[1, 0, 10.0], [0, 1, 0.0], [0, 0, 1.0]] }
49
49
  end
50
50
 
51
51
  context 'with translateY' do
52
52
  let(:transform) { 'translateY(10)' }
53
- it { is_expected.to eq [1, 0, 0, 1, 0, -10] }
53
+ it { is_expected.to eq Matrix[[1, 0, 0.0], [0, 1, -10.0], [0, 0, 1.0]] }
54
54
  end
55
55
 
56
56
  let(:sin30) { Math.sin(30 * Math::PI / 180.0) }
@@ -59,36 +59,36 @@ RSpec.describe Prawn::SVG::TransformParser do
59
59
 
60
60
  context 'with single argument rotate' do
61
61
  let(:transform) { 'rotate(30)' }
62
- it { is_expected.to eq [cos30, -sin30, sin30, cos30, 0, 0] }
62
+ it { is_expected.to eq Matrix[[cos30, sin30, 0], [-sin30, cos30, 0], [0.0, 0.0, 1]] }
63
63
  end
64
64
 
65
65
  context 'with triple argument rotate' do
66
66
  let(:transform) { 'rotate(30 100 200)' }
67
- it { is_expected.to eq [cos30, -sin30, sin30, cos30, 113.39745962155611, 23.205080756887753] }
67
+ it { is_expected.to eq Matrix[[cos30, sin30, 113.39745962155611], [-sin30, cos30, 23.205080756887753], [0.0, 0.0, 1.0]] }
68
68
  end
69
69
 
70
70
  context 'with scale' do
71
71
  let(:transform) { 'scale(1.5)' }
72
- it { is_expected.to eq [1.5, 0, 0, 1.5, 0, 0] }
72
+ it { is_expected.to eq Matrix[[1.5, 0.0, 0], [0.0, 1.5, 0], [0.0, 0.0, 1]] }
73
73
  end
74
74
 
75
75
  context 'with skewX' do
76
76
  let(:transform) { 'skewX(30)' }
77
- it { is_expected.to eq [1, 0, -tan30, 1, 0, 0] }
77
+ it { is_expected.to eq Matrix[[1, -tan30, 0], [0, 1.0, 0], [0, 0.0, 1]] }
78
78
  end
79
79
 
80
80
  context 'with skewY' do
81
81
  let(:transform) { 'skewY(30)' }
82
- it { is_expected.to eq [1, -tan30, 0, 1, 0, 0] }
82
+ it { is_expected.to eq Matrix[[1.0, 0, 0], [-tan30, 1, 0], [0.0, 0, 1]] }
83
83
  end
84
84
 
85
85
  context 'with matrix' do
86
86
  let(:transform) { 'matrix(1 2 3 4 5 6)' }
87
- it { is_expected.to eq [1, -2, -3, 4, 5, -6] }
87
+ it { is_expected.to eq Matrix[[1.0, -3.0, 5.0], [-2.0, 4.0, -6.0], [0.0, 0.0, 1.0]] }
88
88
  end
89
89
 
90
90
  context 'with multiple' do
91
91
  let(:transform) { 'scale(2) translate(7) scale(3)' }
92
- it { is_expected.to eq [6, 0, 0, 6, 14, 0] }
92
+ it { is_expected.to eq Matrix[[6.0, 0.0, 14.0], [0.0, 6.0, 0.0], [0.0, 0.0, 1.0]] }
93
93
  end
94
94
  end
@@ -0,0 +1,115 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg id="Laag_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 260 173.33">
3
+ <defs>
4
+ <linearGradient id="linear-base">
5
+ <stop offset="0" stop-color="white"/>
6
+ <stop offset="0.01" stop-color="red"/>
7
+ <stop offset="0.49" stop-color="orange"/>
8
+ <stop offset=".5" stop-color="white"/>
9
+ <stop offset=".51" stop-color="aqua"/>
10
+ <stop offset="0.99" stop-color="blue"/>
11
+ <stop offset="1" stop-color="white"/>
12
+ </linearGradient>
13
+
14
+ <linearGradient id="transparent-linear-base">
15
+ <stop offset="0" stop-opacity="0" stop-color="white"/>
16
+ <stop offset="0.01" stop-opacity="0.01" stop-color="red"/>
17
+ <stop offset="0.49" stop-opacity="0.49" stop-color="orange"/>
18
+ <stop offset=".5" stop-opacity=".5" stop-color="white"/>
19
+ <stop offset=".51" stop-opacity=".51" stop-color="aqua"/>
20
+ <stop offset="0.99" stop-opacity="0.99" stop-color="blue"/>
21
+ <stop offset="1" stop-opacity="1" stop-color="white"/>
22
+ </linearGradient>
23
+
24
+ <linearGradient id="linear-1" href="#linear-base" gradientTransform="translate(0.2 0)" x1="0" y1="0" x2="1" y2="0" />
25
+ <linearGradient id="linear-2" href="#linear-base" x1="120" y1="20" x2="120" y2="0" gradientUnits="userSpaceOnUse" />
26
+ <linearGradient id="linear-3" href="#linear-base" gradientTransform="scale(0.5)" spreadMethod="repeat" />
27
+ <linearGradient id="linear-4" href="#linear-base" gradientTransform="scale(0.5)" spreadMethod="reflect" />
28
+ <linearGradient id="linear-5" href="#linear-base" gradientTransform="rotate(10)" />
29
+ <linearGradient id="linear-6" href="#linear-base" x1="0" y1="200" x2="1" y2="200" gradientTransform="translate(29023.21 20) rotate(-90) scale(20 -167.5)" gradientUnits="userSpaceOnUse" />
30
+ <linearGradient id="linear-7" href="#linear-base" gradientTransform="skewX(10)" />
31
+ <linearGradient id="linear-8" href="#linear-base" gradientTransform="skewY(10) rotate(90)" />
32
+ <linearGradient id="linear-9" href="#linear-base" x1="0" y1="0" x2="20" y2="0" gradientUnits="userSpaceOnUse" spreadMethod="reflect" />
33
+ <linearGradient id="linear-10" href="#linear-base" x1="210" y1="0" x2="230" y2="0" gradientUnits="userSpaceOnUse" spreadMethod="reflect" />
34
+
35
+ <linearGradient id="transparent-linear-1" href="#transparent-linear-base" gradientTransform="translate(0.2 0)" x1="0" y1="0" x2="1" y2="0" />
36
+ <linearGradient id="transparent-linear-2" href="#transparent-linear-base" x1="120" y1="50" x2="120" y2="30" gradientUnits="userSpaceOnUse" />
37
+ <linearGradient id="transparent-linear-3" href="#transparent-linear-base" gradientTransform="scale(0.5)" spreadMethod="repeat" />
38
+ <linearGradient id="transparent-linear-4" href="#transparent-linear-base" gradientTransform="scale(0.5)" spreadMethod="reflect" />
39
+ <linearGradient id="transparent-linear-5" href="#transparent-linear-base" gradientTransform="rotate(10)" />
40
+ <linearGradient id="transparent-linear-6" href="#transparent-linear-base" x1="0" y1="200" x2="1" y2="200" gradientTransform="translate(29023.21 50) rotate(-90) scale(20 -167.5)" gradientUnits="userSpaceOnUse" />
41
+ <linearGradient id="transparent-linear-7" href="#transparent-linear-base" gradientTransform="skewX(10)" />
42
+ <linearGradient id="transparent-linear-8" href="#transparent-linear-base" gradientTransform="skewY(10) rotate(90)" />
43
+
44
+ <radialGradient id="radial-base">
45
+ <stop offset="25%" stop-color="red"/>
46
+ <stop offset="49%" stop-color="orange"/>
47
+ <stop offset="50%" stop-color="white"/>
48
+ <stop offset="51%" stop-color="aqua"/>
49
+ <stop offset="75%" stop-color="blue"/>
50
+ </radialGradient>
51
+
52
+ <radialGradient id="transparent-radial-base">
53
+ <stop offset="25%" stop-opacity="0.01" stop-color="red"/>
54
+ <stop offset="49%" stop-opacity="0.49" stop-color="orange"/>
55
+ <stop offset="50%" stop-opacity=".5" stop-color="white"/>
56
+ <stop offset="51%" stop-opacity=".51" stop-color="aqua"/>
57
+ <stop offset="75%" stop-opacity="0.99" stop-color="blue"/>
58
+ </radialGradient>
59
+
60
+ <radialGradient id="radial-1" href="#radial-base" cx="0.2" fx="0.6" r="50%" gradientTransform="scale(1 0.5)" spreadMethod="repeat" />
61
+ <radialGradient id="radial-2" href="#radial-base" cx="0.2" fx="0.6" spreadMethod="reflect" />
62
+ <radialGradient id="radial-3" href="#radial-base" gradientUnits="userSpaceOnUse" cx="130" cy="70" r="5" />
63
+
64
+ <radialGradient id="transparent-radial-1" href="#transparent-radial-base" cx="0.2" fx="0.6" r="50%" gradientTransform="scale(1 0.5)" spreadMethod="repeat" />
65
+ <radialGradient id="transparent-radial-2" href="#transparent-radial-base" cx="0.2" fx="0.6" spreadMethod="reflect" />
66
+ </defs>
67
+
68
+ <rect fill="#0f1941" width="260" height="173.33"/>
69
+
70
+ <g>
71
+ <rect fill="url(#linear-base)" width="20" height="20" />
72
+ <rect fill="url(#linear-1)" x="30" y="0" width="20" height="20" />
73
+ <rect fill="url(#linear-2)" x="60" y="0" width="20" height="20"/>
74
+ <rect fill="url(#linear-3)" x="90" y="0" width="20" height="20"/>
75
+ <rect fill="url(#linear-4)" x="120" y="0" width="20" height="20"/>
76
+ <rect fill="url(#linear-5)" x="150" y="0" width="20" height="20"/>
77
+ <rect fill="url(#linear-6)" x="180" y="0" width="20" height="20"/>
78
+ <rect fill="url(#linear-7)" x="210" y="0" width="20" height="20"/>
79
+ <rect fill="url(#linear-8)" x="240" y="0" width="20" height="20"/>
80
+ <rect fill="url(#linear-9)" x="210" y="60" width="20" height="20"/>
81
+ <rect fill="url(#linear-10)" x="180" y="60" width="20" height="20"/>
82
+ </g>
83
+
84
+ <g>
85
+ <rect fill="url(#transparent-linear-base)" y="30" width="20" height="20" />
86
+ <rect fill="url(#transparent-linear-1)" x="30" y="30" width="20" height="20" />
87
+ <rect fill="url(#transparent-linear-2)" x="60" y="30" width="20" height="20"/>
88
+ <rect fill="url(#transparent-linear-3)" x="90" y="30" width="20" height="20"/>
89
+ <rect fill="url(#transparent-linear-4)" x="120" y="30" width="20" height="20"/>
90
+ <rect fill="url(#transparent-linear-5)" x="150" y="30" width="20" height="20"/>
91
+ <rect fill="url(#transparent-linear-6)" x="180" y="30" width="20" height="20"/>
92
+ <rect fill="url(#transparent-linear-7)" x="210" y="30" width="20" height="20"/>
93
+ <rect fill="url(#transparent-linear-8)" x="240" y="30" width="20" height="20"/>
94
+
95
+ <rect fill="url(#transparent-linear-7)" x="120" y="30" width="20" height="20" transform="rotate(45)" />
96
+ </g>
97
+
98
+ <g>
99
+ <rect fill="url(#radial-base)" x="0" y="60" width="20" height="20" />
100
+ <rect fill="url(#radial-base)" x="30" y="60" width="10" height="20" />
101
+ <rect fill="url(#radial-base)" x="60" y="60" width="20" height="10" />
102
+ <rect fill="url(#radial-1)" x="90" y="60" width="20" height="20" />
103
+ <rect fill="url(#radial-2)" x="120" y="60" width="20" height="20" />
104
+
105
+ <rect fill="url(#radial-3)" x="120" y="60" width="20" height="20" transform="rotate(45)" />
106
+ </g>
107
+
108
+ <g>
109
+ <rect fill="url(#transparent-radial-base)" x="0" y="90" width="20" height="20" />
110
+ <rect fill="url(#transparent-radial-base)" x="30" y="90" width="10" height="20" />
111
+ <rect fill="url(#transparent-radial-base)" x="60" y="90" width="20" height="10" />
112
+ <rect fill="url(#transparent-radial-1)" x="90" y="90" width="10" height="20" />
113
+ <rect fill="url(#transparent-radial-2)" x="120" y="90" width="20" height="10" />
114
+ </g>
115
+ </svg>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prawn-svg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.35.1
4
+ version: 0.36.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mog Nesbitt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-07-17 00:00:00.000000000 Z
11
+ date: 2025-01-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: css_parser
@@ -64,7 +64,7 @@ dependencies:
64
64
  requirements:
65
65
  - - ">="
66
66
  - !ruby/object:Gem::Version
67
- version: 3.2.0
67
+ version: 3.3.9
68
68
  - - "<"
69
69
  - !ruby/object:Gem::Version
70
70
  version: '4'
@@ -74,7 +74,7 @@ dependencies:
74
74
  requirements:
75
75
  - - ">="
76
76
  - !ruby/object:Gem::Version
77
- version: 3.2.0
77
+ version: 3.3.9
78
78
  - - "<"
79
79
  - !ruby/object:Gem::Version
80
80
  version: '4'
@@ -110,6 +110,7 @@ files:
110
110
  - lib/prawn/svg/calculators/pixels.rb
111
111
  - lib/prawn/svg/color.rb
112
112
  - lib/prawn/svg/css/font_family_parser.rb
113
+ - lib/prawn/svg/css/font_parser.rb
113
114
  - lib/prawn/svg/css/selector_parser.rb
114
115
  - lib/prawn/svg/css/stylesheets.rb
115
116
  - lib/prawn/svg/css/values_parser.rb
@@ -137,19 +138,24 @@ files:
137
138
  - lib/prawn/svg/elements/use.rb
138
139
  - lib/prawn/svg/elements/viewport.rb
139
140
  - lib/prawn/svg/extension.rb
140
- - lib/prawn/svg/extensions/additional_gradient_transforms.rb
141
141
  - lib/prawn/svg/font.rb
142
142
  - lib/prawn/svg/font_registry.rb
143
+ - lib/prawn/svg/funciri.rb
144
+ - lib/prawn/svg/gradient_renderer.rb
143
145
  - lib/prawn/svg/gradients.rb
144
146
  - lib/prawn/svg/interface.rb
147
+ - lib/prawn/svg/length.rb
145
148
  - lib/prawn/svg/loaders/data.rb
146
149
  - lib/prawn/svg/loaders/file.rb
147
150
  - lib/prawn/svg/loaders/web.rb
151
+ - lib/prawn/svg/paint.rb
148
152
  - lib/prawn/svg/pathable.rb
153
+ - lib/prawn/svg/percentage.rb
149
154
  - lib/prawn/svg/properties.rb
150
155
  - lib/prawn/svg/renderer.rb
151
156
  - lib/prawn/svg/state.rb
152
157
  - lib/prawn/svg/transform_parser.rb
158
+ - lib/prawn/svg/transform_utils.rb
153
159
  - lib/prawn/svg/ttf.rb
154
160
  - lib/prawn/svg/url_loader.rb
155
161
  - lib/prawn/svg/version.rb
@@ -177,11 +183,16 @@ files:
177
183
  - spec/prawn/svg/elements/text_spec.rb
178
184
  - spec/prawn/svg/font_registry_spec.rb
179
185
  - spec/prawn/svg/font_spec.rb
186
+ - spec/prawn/svg/funciri_spec.rb
180
187
  - spec/prawn/svg/interface_spec.rb
188
+ - spec/prawn/svg/length_spec.rb
181
189
  - spec/prawn/svg/loaders/data_spec.rb
182
190
  - spec/prawn/svg/loaders/file_spec.rb
183
191
  - spec/prawn/svg/loaders/web_spec.rb
192
+ - spec/prawn/svg/paint_spec.rb
184
193
  - spec/prawn/svg/pathable_spec.rb
194
+ - spec/prawn/svg/pdfmatrix_spec.rb
195
+ - spec/prawn/svg/percentage_spec.rb
185
196
  - spec/prawn/svg/properties_spec.rb
186
197
  - spec/prawn/svg/transform_parser_spec.rb
187
198
  - spec/prawn/svg/ttf_spec.rb
@@ -205,6 +216,7 @@ files:
205
216
  - spec/sample_svg/ellipse01.svg
206
217
  - spec/sample_svg/gistfile1.svg
207
218
  - spec/sample_svg/google_charts.svg
219
+ - spec/sample_svg/gradient_stress_test.svg
208
220
  - spec/sample_svg/gradient_transform.svg
209
221
  - spec/sample_svg/gradients-cmyk.svg
210
222
  - spec/sample_svg/gradients.svg
@@ -1,23 +0,0 @@
1
- module Prawn::SVG::Extensions
2
- module AdditionalGradientTransforms
3
- def gradient_coordinates(gradient)
4
- # As of Prawn 2.2.0, apply_transformations is used as purely a boolean.
5
- #
6
- # Here we're using it to optionally pass in a 6-tuple transformation matrix that gets applied to the
7
- # gradient. This should be added to Prawn properly, and then this monkey patch will not be necessary.
8
-
9
- if gradient.apply_transformations.is_a?(Array)
10
- x1, y1, x2, y2, transformation = super
11
- a, b, c, d, e, f = transformation
12
- na, nb, nc, nd, ne, nf = gradient.apply_transformations
13
-
14
- matrix = Matrix[[a, c, e], [b, d, f], [0, 0, 1]] * Matrix[[na, nc, ne], [nb, nd, nf], [0, 0, 1]]
15
- new_transformation = matrix.to_a[0..1].transpose.flatten
16
-
17
- [x1, y1, x2, y2, new_transformation]
18
- else
19
- super
20
- end
21
- end
22
- end
23
- end