prawn-svg 0.35.1 → 0.36.0

Sign up to get free protection for your applications and to get access to all the features.
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