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.
- checksums.yaml +4 -4
- data/Gemfile.lock +3 -5
- data/README.md +4 -7
- data/lib/prawn/svg/attributes/opacity.rb +23 -8
- data/lib/prawn/svg/attributes/stroke.rb +7 -9
- data/lib/prawn/svg/attributes/transform.rb +1 -1
- data/lib/prawn/svg/calculators/pixels.rb +9 -22
- data/lib/prawn/svg/color.rb +58 -59
- data/lib/prawn/svg/css/font_parser.rb +46 -0
- data/lib/prawn/svg/document.rb +5 -1
- data/lib/prawn/svg/elements/base.rb +22 -30
- data/lib/prawn/svg/elements/gradient.rb +99 -74
- data/lib/prawn/svg/elements/line.rb +1 -1
- data/lib/prawn/svg/elements/marker.rb +2 -0
- data/lib/prawn/svg/elements/root.rb +1 -1
- data/lib/prawn/svg/elements/text_component.rb +3 -3
- data/lib/prawn/svg/funciri.rb +14 -0
- data/lib/prawn/svg/gradient_renderer.rb +313 -0
- data/lib/prawn/svg/length.rb +43 -0
- data/lib/prawn/svg/paint.rb +67 -0
- data/lib/prawn/svg/percentage.rb +24 -0
- data/lib/prawn/svg/properties.rb +208 -104
- data/lib/prawn/svg/renderer.rb +5 -0
- data/lib/prawn/svg/state.rb +5 -3
- data/lib/prawn/svg/transform_parser.rb +19 -13
- data/lib/prawn/svg/transform_utils.rb +37 -0
- data/lib/prawn/svg/version.rb +1 -1
- data/lib/prawn-svg.rb +7 -3
- data/prawn-svg.gemspec +4 -4
- data/spec/prawn/svg/attributes/opacity_spec.rb +27 -20
- data/spec/prawn/svg/attributes/transform_spec.rb +5 -2
- data/spec/prawn/svg/calculators/pixels_spec.rb +1 -2
- data/spec/prawn/svg/color_spec.rb +22 -52
- data/spec/prawn/svg/elements/base_spec.rb +9 -10
- data/spec/prawn/svg/elements/gradient_spec.rb +92 -36
- data/spec/prawn/svg/elements/marker_spec.rb +13 -15
- data/spec/prawn/svg/funciri_spec.rb +59 -0
- data/spec/prawn/svg/length_spec.rb +89 -0
- data/spec/prawn/svg/paint_spec.rb +96 -0
- data/spec/prawn/svg/pathable_spec.rb +3 -3
- data/spec/prawn/svg/pdfmatrix_spec.rb +60 -0
- data/spec/prawn/svg/percentage_spec.rb +60 -0
- data/spec/prawn/svg/properties_spec.rb +124 -107
- data/spec/prawn/svg/transform_parser_spec.rb +13 -13
- data/spec/sample_svg/gradient_stress_test.svg +115 -0
- metadata +17 -5
- 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 = '
|
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 = '
|
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 = '
|
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 '
|
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 '
|
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
|
32
|
-
subject.set('
|
33
|
-
expect(subject.
|
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
|
-
|
37
|
-
|
38
|
-
|
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 '
|
46
|
-
expect(subject.fill).to eq '
|
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 '
|
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 '
|
154
|
+
expect(subject.color).to eq Prawn::SVG::Color::RGB.new('ff0000')
|
78
155
|
end
|
156
|
+
end
|
79
157
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
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
|
-
|
162
|
-
|
163
|
-
|
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
|
-
|
170
|
-
|
171
|
-
|
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
|
-
|
174
|
-
|
175
|
-
end
|
176
|
-
end
|
192
|
+
b = Prawn::SVG::Properties.new
|
193
|
+
b.set('font-size', '1.2em')
|
177
194
|
|
178
|
-
|
179
|
-
|
195
|
+
properties = Prawn::SVG::Properties.new
|
196
|
+
properties.compute_properties(a)
|
197
|
+
properties.compute_properties(b)
|
180
198
|
|
181
|
-
|
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(:
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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, -
|
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,
|
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
|