prawn-svg 0.35.1 → 0.36.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.
Files changed (47) 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 +5 -1
  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/elements/base_spec.rb +9 -10
  35. data/spec/prawn/svg/elements/gradient_spec.rb +92 -36
  36. data/spec/prawn/svg/elements/marker_spec.rb +13 -15
  37. data/spec/prawn/svg/funciri_spec.rb +59 -0
  38. data/spec/prawn/svg/length_spec.rb +89 -0
  39. data/spec/prawn/svg/paint_spec.rb +96 -0
  40. data/spec/prawn/svg/pathable_spec.rb +3 -3
  41. data/spec/prawn/svg/pdfmatrix_spec.rb +60 -0
  42. data/spec/prawn/svg/percentage_spec.rb +60 -0
  43. data/spec/prawn/svg/properties_spec.rb +124 -107
  44. data/spec/prawn/svg/transform_parser_spec.rb +13 -13
  45. data/spec/sample_svg/gradient_stress_test.svg +115 -0
  46. metadata +17 -5
  47. data/lib/prawn/svg/extensions/additional_gradient_transforms.rb +0 -23
@@ -0,0 +1,96 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Prawn::SVG::Paint do
4
+ let(:red) { Prawn::SVG::Color::RGB.new('ff0000') }
5
+
6
+ describe '.parse' do
7
+ it 'parses a color' do
8
+ expect(described_class.parse('red')).to eq(described_class.new(red, nil))
9
+ end
10
+
11
+ it 'parses an rgb color with an icc color, ignoring the icc color' do
12
+ expect(described_class.parse('rgb(255, 0, 0) icc-color(1)')).to eq(described_class.new(red, nil))
13
+ end
14
+
15
+ it 'parses a URL' do
16
+ expect(described_class.parse('url(#foo)')).to eq(described_class.new(:none, '#foo'))
17
+ end
18
+
19
+ it 'parses a keyword' do
20
+ expect(described_class.parse('NONE')).to eq(described_class.new(:none, nil))
21
+ expect(described_class.parse('currentColor')).to eq(described_class.new(:currentcolor, nil))
22
+ end
23
+
24
+ it 'parses a URL with a fallback keyword' do
25
+ expect(described_class.parse('url(#foo) none')).to eq(described_class.new(:none, '#foo'))
26
+ end
27
+
28
+ it 'parses a URL with a fallback color' do
29
+ expect(described_class.parse('url(#foo) red')).to eq(described_class.new(red, '#foo'))
30
+ end
31
+
32
+ it 'parses a URL with a fallback color and an icc color, ignoring the icc color' do
33
+ expect(described_class.parse('url(#foo) red icc-color(1)')).to eq(described_class.new(red, '#foo'))
34
+ end
35
+
36
+ it 'returns nil if the value is unrecognised' do
37
+ expect(described_class.parse('foo')).to be_nil
38
+ end
39
+
40
+ it 'returns nil if the url has multiple arguments' do
41
+ expect(described_class.parse('url(#foo, bar)')).to be_nil
42
+ end
43
+ end
44
+
45
+ describe '#none?' do
46
+ it 'returns true if the color is none' do
47
+ expect(described_class.new(:none, nil).none?).to be(true)
48
+ end
49
+
50
+ it 'returns true if the color is none and the URL is unresolved' do
51
+ paint = described_class.new(:none, '#foo')
52
+ paint.instance_variable_set(:@unresolved_url, true)
53
+ expect(paint.none?).to be(true)
54
+ end
55
+
56
+ it 'returns false if the color is not none' do
57
+ expect(described_class.new(Prawn::SVG::Color::RGB.new('ff0000'), nil).none?).to be(false)
58
+ end
59
+ end
60
+
61
+ describe '#resolve' do
62
+ it 'returns the current color if the color is currentcolor' do
63
+ current_color = double
64
+ paint = described_class.new(:currentcolor, nil)
65
+ expect(paint.resolve(nil, current_color, :rgb)).to eq current_color
66
+ end
67
+
68
+ it 'returns the nil if the color is none' do
69
+ current_color = double
70
+ paint = described_class.new(:none, nil)
71
+ expect(paint.resolve(nil, current_color, :rgb)).to be nil
72
+ end
73
+
74
+ it 'returns the gradient if the URL is resolvable' do
75
+ gradient = double
76
+ paint = described_class.new(:none, '#foo')
77
+ expect(paint.resolve({ 'foo' => gradient }, nil, :rgb)).to eq(gradient)
78
+ end
79
+
80
+ it 'falls back to the color if the URL is unresolvable' do
81
+ paint = described_class.new(red, '#foo')
82
+ expect(paint.resolve(nil, nil, :rgb)).to eq red
83
+ expect(paint.resolve({}, nil, :rgb)).to eq red
84
+ end
85
+
86
+ it 'returns the color if the color is not currentcolor or none' do
87
+ paint = described_class.new(red, nil)
88
+ expect(paint.resolve(nil, nil, :rgb)).to eq red
89
+ end
90
+
91
+ it 'converts the color to CMYK if the color mode is CMYK' do
92
+ paint = described_class.new(red, nil)
93
+ expect(paint.resolve(nil, nil, :cmyk)).to eq Prawn::SVG::Color::CMYK.new([0, 100, 100, 0])
94
+ end
95
+ end
96
+ end
@@ -57,7 +57,7 @@ RSpec.describe Prawn::SVG::Pathable do
57
57
 
58
58
  context 'with marker-start attribute specified' do
59
59
  before do
60
- subject.properties.marker_start = 'url(#triangle)'
60
+ subject.properties.marker_start = Prawn::SVG::FuncIRI.new('#triangle')
61
61
  end
62
62
 
63
63
  it 'calls apply_marker on the marker' do
@@ -68,7 +68,7 @@ RSpec.describe Prawn::SVG::Pathable do
68
68
 
69
69
  context 'with marker-mid attribute specified' do
70
70
  before do
71
- subject.properties.marker_mid = 'url(#triangle)'
71
+ subject.properties.marker_mid = Prawn::SVG::FuncIRI.new('#triangle')
72
72
  end
73
73
 
74
74
  it 'calls apply_marker on the marker' do
@@ -80,7 +80,7 @@ RSpec.describe Prawn::SVG::Pathable do
80
80
 
81
81
  context 'with marker-end attribute specified' do
82
82
  before do
83
- subject.properties.marker_end = 'url(#triangle)'
83
+ subject.properties.marker_end = Prawn::SVG::FuncIRI.new('#triangle')
84
84
  end
85
85
 
86
86
  it 'calls apply_marker on the marker' do
@@ -0,0 +1,60 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Prawn::SVG::PDFMatrix do
4
+ subject do
5
+ obj = Object.new
6
+ obj.extend(Prawn::SVG::PDFMatrix)
7
+ obj
8
+ end
9
+
10
+ describe '#load_matrix' do
11
+ it 'converts a PDF-style matrix into a Ruby Matrix' do
12
+ expect(subject.load_matrix([1.0, 0.0, 0.0, 1.0, 5.0, 7.0])).to eq(Matrix[
13
+ [1.0, 0.0, 5.0],
14
+ [0.0, 1.0, 7.0],
15
+ [0.0, 0.0, 1.0]
16
+ ])
17
+ end
18
+
19
+ it 'returns the same Ruby Matrix if it has the correct dimensions' do
20
+ matrix = Matrix[[1.0, 0.0, 5.0], [0.0, 1.0, 7.0], [0.0, 0.0, 1.0]]
21
+ expect(subject.load_matrix(matrix)).to eq(matrix)
22
+ end
23
+
24
+ it 'raises an error for unexpected Ruby matrices' do
25
+ matrix = Matrix.identity(4)
26
+ expect { subject.load_matrix(matrix) }.to raise_error(ArgumentError)
27
+ end
28
+
29
+ it 'raises an error for unexpected PDF-style matrices' do
30
+ matrix = [1.0, 2.0, 3.0, 4.0]
31
+ expect { subject.load_matrix(matrix) }.to raise_error(ArgumentError)
32
+ end
33
+ end
34
+
35
+ describe '#matrix_for_pdf' do
36
+ it 'converts a Ruby Matrix into the correct format for PDF' do
37
+ matrix = Matrix[[1.0, 0.0, 5.0], [0.0, 1.0, 7.0], [0.0, 0.0, 1.0]]
38
+ expect(subject.matrix_for_pdf(matrix)).to eq([1.0, 0.0, 0.0, 1.0, 5.0, 7.0])
39
+ end
40
+ end
41
+
42
+ describe '#rotation_matrix' do
43
+ let(:angle) { 45 * Math::PI / 180.0 }
44
+ let(:inv_root_2) { 0.707 }
45
+
46
+ context 'in PDF space' do
47
+ it 'returns the expected matrix' do
48
+ matrix = Matrix[[inv_root_2, inv_root_2, 0], [-inv_root_2, inv_root_2, 0], [0, 0, 1]]
49
+ expect(subject.rotation_matrix(angle).round(3)).to eq(matrix)
50
+ end
51
+ end
52
+
53
+ context 'in SVG space' do
54
+ it 'returns the expected matrix' do
55
+ matrix = Matrix[[inv_root_2, -inv_root_2, 0], [inv_root_2, inv_root_2, 0], [0, 0, 1]]
56
+ expect(subject.rotation_matrix(angle, space: :svg).round(3)).to eq(matrix)
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,60 @@
1
+ require 'spec_helper'
2
+
3
+ describe Prawn::SVG::Percentage do
4
+ describe '.parse' do
5
+ it 'parses a percentage' do
6
+ expect(described_class.parse('1.23%')).to eq(described_class.new(1.23))
7
+ end
8
+
9
+ it 'parses a percentage with a positive sign' do
10
+ expect(described_class.parse('+1.23%')).to eq(described_class.new(1.23))
11
+ end
12
+
13
+ it 'parses a percentage with a negative sign' do
14
+ expect(described_class.parse('-1.23%')).to eq(described_class.new(-1.23))
15
+ end
16
+
17
+ it 'parses a percentage with no decimal points' do
18
+ expect(described_class.parse('1%')).to eq(described_class.new(1))
19
+ end
20
+
21
+ it 'does not parse a percentage with no number' do
22
+ expect(described_class.parse('%')).to be nil
23
+ end
24
+
25
+ it 'does not parse a percentage with a trailing dot' do
26
+ expect(described_class.parse('1.%')).to be nil
27
+ end
28
+
29
+ it 'requires that the percentage sign is specified' do
30
+ expect(described_class.parse('1.23')).to be nil
31
+ end
32
+
33
+ context 'when positive_only is true' do
34
+ it 'does not allow negative numbers' do
35
+ expect(described_class.parse('-1.23%', positive_only: true)).to be nil
36
+ end
37
+
38
+ it 'does allow zero' do
39
+ expect(described_class.parse('0%', positive_only: true)).to eq(described_class.new(0))
40
+ end
41
+
42
+ it 'does allow positive numbers' do
43
+ expect(described_class.parse('1.23%', positive_only: true)).to eq(described_class.new(1.23))
44
+ end
45
+ end
46
+ end
47
+
48
+ describe '#to_factor' do
49
+ it 'converts a percentage to a factor' do
50
+ expect(described_class.new(2.5).to_factor).to eq(0.025)
51
+ end
52
+ end
53
+
54
+ describe '#to_pixels' do
55
+ it 'converts a percentage to pixels' do
56
+ expect(described_class.new(2.5).to_pixels(100, nil)).to eq(2.5)
57
+ expect(described_class.new(2.5).to_pixels(200, nil)).to eq(5)
58
+ end
59
+ end
60
+ end
@@ -14,13 +14,13 @@ RSpec.describe Prawn::SVG::Properties do
14
14
  it 'sets a property' do
15
15
  result = subject.set('color', 'red')
16
16
  expect(result).to be
17
- expect(subject.color).to eq 'red'
17
+ expect(subject.color).to eq Prawn::SVG::Color::RGB.new('ff0000')
18
18
  end
19
19
 
20
20
  it 'handles property names that are not lower case' do
21
21
  result = subject.set('COLor', 'red')
22
22
  expect(result).to be
23
- expect(subject.color).to eq 'red'
23
+ expect(subject.color).to eq Prawn::SVG::Color::RGB.new('ff0000')
24
24
  end
25
25
 
26
26
  it 'right-cases and strips keywords' do
@@ -28,22 +28,99 @@ RSpec.describe Prawn::SVG::Properties do
28
28
  expect(subject.stroke_linecap).to eq 'round'
29
29
  end
30
30
 
31
- it "doesn't right-case values that aren't recognised as keywords" do
32
- subject.set('color', 'Red')
33
- expect(subject.color).to eq 'Red'
31
+ it 'ignores invalid values, retaining any previously set value' do
32
+ subject.set('display', 'invalid')
33
+ expect(subject.display).to be nil
34
+ subject.set('display', 'none')
35
+ expect(subject.display).to eq 'none'
36
+ subject.set('display', 'invalid')
37
+ expect(subject.display).to eq 'none'
34
38
  end
35
39
 
36
- it "sets a 'keyword restricted' property to its default if the value doesn't match a keyword" do
37
- subject.set('stroke-linecap', 'invalid')
38
- expect(subject.stroke_linecap).to eq 'butt'
40
+ context 'when setting the font shorthand property' do
41
+ it 'sets font style, weight, size, and family' do
42
+ subject.set('font', 'italic bold 12px/30px "New Font", sans-serif')
43
+ expect(subject.font_style).to eq 'italic'
44
+ expect(subject.font_weight).to eq 'bold'
45
+ expect(subject.font_variant).to eq 'normal'
46
+ expect(subject.font_size).to eq Prawn::SVG::Length.parse('12px')
47
+ expect(subject.font_family).to eq '"New Font", sans-serif'
48
+ end
49
+
50
+ it 'sets font style, weight, variant, size, and family' do
51
+ subject.set('font', 'italic small-caps bold 12px/30px "New Font", sans-serif')
52
+ expect(subject.font_style).to eq 'italic'
53
+ expect(subject.font_weight).to eq 'bold'
54
+ expect(subject.font_variant).to eq 'small-caps'
55
+ expect(subject.font_size).to eq Prawn::SVG::Length.parse('12px')
56
+ expect(subject.font_family).to eq '"New Font", sans-serif'
57
+ end
58
+
59
+ it 'sets size and family, defaulting everything else to normal' do
60
+ subject.set('font-weight', 'bold')
61
+ subject.set('font-style', 'italic')
62
+ subject.set('font-variant', 'small-caps')
63
+
64
+ subject.set('font', '12px fontname')
65
+ expect(subject.font_style).to eq 'normal'
66
+ expect(subject.font_weight).to eq 'normal'
67
+ expect(subject.font_variant).to eq 'normal'
68
+ expect(subject.font_size).to eq Prawn::SVG::Length.parse('12px')
69
+ expect(subject.font_family).to eq 'fontname'
70
+ end
71
+
72
+ it 'suports the inherit keyword' do
73
+ subject.set('font', 'inherit')
74
+ expect(subject.font_style).to eq 'inherit'
75
+ expect(subject.font_weight).to eq 'inherit'
76
+ expect(subject.font_variant).to eq 'inherit'
77
+ expect(subject.font_size).to eq 'inherit'
78
+ expect(subject.font_family).to eq 'inherit'
79
+ end
80
+
81
+ it 'supports the standard font keyword, menu' do
82
+ subject.set('font', 'menu')
83
+ expect(subject.font_style).to eq 'normal'
84
+ expect(subject.font_weight).to eq 'normal'
85
+ expect(subject.font_variant).to eq 'normal'
86
+ expect(subject.font_size).to eq 'medium'
87
+ expect(subject.font_family).to eq 'sans-serif'
88
+ end
89
+
90
+ it 'does nothing if an unrecognised keyword is used' do
91
+ subject.set('font', 'invalid')
92
+ expect(subject.font_style).to be nil
93
+ expect(subject.font_weight).to be nil
94
+ expect(subject.font_variant).to be nil
95
+ expect(subject.font_size).to be nil
96
+ expect(subject.font_family).to be nil
97
+ end
98
+
99
+ it 'does nothing if the font size is not valid' do
100
+ subject.set('font', '23bad sans-serif')
101
+ expect(subject.font_style).to be nil
102
+ expect(subject.font_weight).to be nil
103
+ expect(subject.font_variant).to be nil
104
+ expect(subject.font_size).to be nil
105
+ expect(subject.font_family).to be nil
106
+ end
107
+
108
+ it 'does nothing if one of the font keywords is not recognised' do
109
+ subject.set('font', 'italic invalid bold 12px/30px "New Font", sans-serif')
110
+ expect(subject.font_style).to be nil
111
+ expect(subject.font_weight).to be nil
112
+ expect(subject.font_variant).to be nil
113
+ expect(subject.font_size).to be nil
114
+ expect(subject.font_family).to be nil
115
+ end
39
116
  end
40
117
  end
41
118
 
42
119
  describe '#load_hash' do
43
120
  it 'uses #set to load in a hash of properties' do
44
121
  subject.load_hash('stroke' => 'blue', 'fill' => 'green', 'stroke-linecap' => 'Round')
45
- expect(subject.stroke).to eq 'blue'
46
- expect(subject.fill).to eq 'green'
122
+ expect(subject.stroke).to eq Prawn::SVG::Paint.new(Prawn::SVG::Color::RGB.new('0000ff'))
123
+ expect(subject.fill).to eq Prawn::SVG::Paint.new(Prawn::SVG::Color::RGB.new('008000'))
47
124
  expect(subject.stroke_linecap).to eq 'round'
48
125
  end
49
126
  end
@@ -54,7 +131,7 @@ RSpec.describe Prawn::SVG::Properties do
54
131
  it 'auto-inherits inheritable properties when the property is not supplied' do
55
132
  subject.set('color', 'green')
56
133
  subject.compute_properties(other)
57
- expect(subject.color).to eq 'green'
134
+ expect(subject.color).to eq Prawn::SVG::Color::RGB.new('008000')
58
135
  end
59
136
 
60
137
  it "doesn't auto-inherit non-inheritable properties" do
@@ -74,112 +151,52 @@ RSpec.describe Prawn::SVG::Properties do
74
151
  subject.set('color', 'green')
75
152
  other.set('color', 'red')
76
153
  subject.compute_properties(other)
77
- expect(subject.color).to eq 'red'
154
+ expect(subject.color).to eq Prawn::SVG::Color::RGB.new('ff0000')
78
155
  end
156
+ end
79
157
 
80
- describe 'font size' do
81
- before do
82
- subject.font_size = '15'
83
- other.font_size = font_size
84
- end
85
-
86
- context 'when given a % as a font-size' do
87
- let(:font_size) { '120%' }
88
-
89
- it 'calculates the new font size' do
90
- subject.compute_properties(other)
91
- expect(subject.font_size).to eq '18.0'
92
- end
93
- end
94
-
95
- context "when given 'larger' as a font-size" do
96
- let(:font_size) { 'larger' }
97
-
98
- it 'calculates the new font size' do
99
- subject.compute_properties(other)
100
- expect(subject.font_size).to eq '19.0'
101
- end
102
- end
103
-
104
- context "when given 'smaller' as a font-size" do
105
- let(:font_size) { 'smaller' }
106
-
107
- it 'calculates the new font size' do
108
- subject.compute_properties(other)
109
- expect(subject.font_size).to eq '11.0'
110
- end
111
- end
112
-
113
- context "when given a value in 'em' as a font-size" do
114
- let(:font_size) { '2.5em' }
115
-
116
- it 'calculates the new font size' do
117
- subject.compute_properties(other)
118
- expect(subject.font_size).to eq '37.5'
119
- end
120
- end
121
-
122
- context "when given a value in 'rem' as a font-size" do
123
- let(:font_size) { '2.5rem' }
124
-
125
- it 'calculates the new font size' do
126
- subject.compute_properties(other)
127
- expect(subject.font_size).to eq '40.0'
128
- end
129
- end
130
-
131
- context "when given a value in 'px' as a font-size" do
132
- let(:font_size) { '19.5px' }
133
-
134
- it 'uses the font size specified' do
135
- subject.compute_properties(other)
136
- expect(subject.font_size).to eq '19.5'
137
- end
138
- end
139
-
140
- context "when given a value in 'pt' as a font-size" do
141
- let(:font_size) { '19.5pt' }
142
-
143
- it 'uses the font size specified' do
144
- subject.compute_properties(other)
145
- expect(subject.font_size).to eq '19.5'
146
- end
147
- end
148
-
149
- context 'when given a value without units as a font-size' do
150
- let(:font_size) { '19.5' }
151
-
152
- it 'uses the font size specified' do
153
- subject.compute_properties(other)
154
- expect(subject.font_size).to eq '19.5'
155
- end
156
- end
157
-
158
- context "when given the keyword 'inherit' as a font-size" do
159
- let(:font_size) { 'inherit' }
158
+ describe '#numeric_font_size' do
159
+ def calculate
160
+ properties = Prawn::SVG::Properties.new
161
+ properties.compute_properties(subject)
162
+ properties.numeric_font_size
163
+ end
160
164
 
161
- it 'uses the font size specified by the parent' do
162
- subject.compute_properties(other)
163
- expect(subject.font_size).to eq '15'
165
+ cases =
166
+ {
167
+ Prawn::SVG::Length.parse('18.5pt') => 18.5,
168
+ Prawn::SVG::Percentage.new(120) => 19.2,
169
+ 19.5 => 19.5,
170
+ 'larger' => 20,
171
+ 'smaller' => 12,
172
+ nil => 16,
173
+ 'inherit' => 16,
174
+ 'x-large' => 24
175
+ }
176
+
177
+ cases.each do |font_size, expected|
178
+ context "when the font size is #{font_size.inspect}" do
179
+ before { subject.font_size = font_size }
180
+
181
+ it 'returns the correct number' do
182
+ expect(calculate).to eq expected
164
183
  end
165
184
  end
166
185
  end
167
- end
168
186
 
169
- describe '#numerical_font_size' do
170
- context 'when the font size is a number' do
171
- before { subject.font_size = '16.5' }
187
+ context 'with a font-size of 1.2em, under a parent with a font size of x-large' do
188
+ it 'returns 24 * 1.2' do
189
+ a = Prawn::SVG::Properties.new
190
+ a.set('font-size', 'x-large')
172
191
 
173
- it 'returns the number as a float' do
174
- expect(subject.numerical_font_size).to eq 16.5
175
- end
176
- end
192
+ b = Prawn::SVG::Properties.new
193
+ b.set('font-size', '1.2em')
177
194
 
178
- context 'when the font size is one of the keyword size specifiers' do
179
- before { subject.font_size = 'x-large' }
195
+ properties = Prawn::SVG::Properties.new
196
+ properties.compute_properties(a)
197
+ properties.compute_properties(b)
180
198
 
181
- it 'returns the font size number corresponding with the keyword' do
182
- expect(subject.numerical_font_size).to eq 24
199
+ expect(properties.numeric_font_size.round(1)).to eq 28.8
183
200
  end
184
201
  end
185
202
  end
@@ -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