prawn-svg 0.34.1 → 0.35.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/lint.yml +19 -0
- data/.github/workflows/test.yml +14 -27
- data/.gitignore +0 -1
- data/.rubocop.yml +86 -0
- data/.rubocop_todo.yml +51 -0
- data/Gemfile +4 -3
- data/Gemfile.lock +81 -0
- data/README.md +1 -1
- data/Rakefile +1 -1
- data/lib/prawn/svg/attributes/clip_path.rb +3 -3
- data/lib/prawn/svg/attributes/opacity.rb +3 -3
- data/lib/prawn/svg/attributes/stroke.rb +9 -9
- data/lib/prawn/svg/attributes/transform.rb +2 -2
- data/lib/prawn/svg/attributes.rb +1 -1
- data/lib/prawn/svg/calculators/arc_to_bezier_curve.rb +17 -15
- data/lib/prawn/svg/calculators/aspect_ratio.rb +16 -14
- data/lib/prawn/svg/calculators/document_sizing.rb +9 -10
- data/lib/prawn/svg/calculators/pixels.rb +8 -5
- data/lib/prawn/svg/color.rb +209 -212
- data/lib/prawn/svg/css/font_family_parser.rb +2 -2
- data/lib/prawn/svg/css/selector_parser.rb +39 -35
- data/lib/prawn/svg/css/stylesheets.rb +31 -24
- data/lib/prawn/svg/css/values_parser.rb +68 -0
- data/lib/prawn/svg/document.rb +6 -5
- data/lib/prawn/svg/elements/base.rb +39 -34
- data/lib/prawn/svg/elements/circle.rb +4 -4
- data/lib/prawn/svg/elements/clip_path.rb +0 -1
- data/lib/prawn/svg/elements/depth_first_base.rb +6 -6
- data/lib/prawn/svg/elements/ellipse.rb +3 -4
- data/lib/prawn/svg/elements/gradient.rb +49 -51
- data/lib/prawn/svg/elements/image.rb +5 -5
- data/lib/prawn/svg/elements/marker.rb +6 -7
- data/lib/prawn/svg/elements/path.rb +46 -47
- data/lib/prawn/svg/elements/polygon.rb +1 -1
- data/lib/prawn/svg/elements/polyline.rb +2 -2
- data/lib/prawn/svg/elements/rect.rb +3 -3
- data/lib/prawn/svg/elements/text.rb +1 -1
- data/lib/prawn/svg/elements/text_component.rb +22 -22
- data/lib/prawn/svg/elements/use.rb +4 -8
- data/lib/prawn/svg/elements/viewport.rb +5 -4
- data/lib/prawn/svg/elements.rb +30 -29
- data/lib/prawn/svg/extension.rb +2 -1
- data/lib/prawn/svg/font.rb +7 -7
- data/lib/prawn/svg/font_registry.rb +13 -13
- data/lib/prawn/svg/gradients.rb +3 -2
- data/lib/prawn/svg/interface.rb +4 -3
- data/lib/prawn/svg/loaders/data.rb +2 -2
- data/lib/prawn/svg/loaders/file.rb +12 -14
- data/lib/prawn/svg/loaders/web.rb +4 -8
- data/lib/prawn/svg/pathable.rb +41 -37
- data/lib/prawn/svg/properties.rb +34 -33
- data/lib/prawn/svg/renderer.rb +7 -7
- data/lib/prawn/svg/state.rb +1 -1
- data/lib/prawn/svg/transform_parser.rb +5 -5
- data/lib/prawn/svg/ttf.rb +21 -17
- data/lib/prawn/svg/url_loader.rb +1 -1
- data/lib/prawn/svg/version.rb +1 -1
- data/lib/prawn-svg.rb +1 -0
- data/prawn-svg.gemspec +4 -6
- data/spec/integration_spec.rb +77 -70
- data/spec/prawn/svg/attributes/opacity_spec.rb +11 -15
- data/spec/prawn/svg/attributes/transform_spec.rb +6 -6
- data/spec/prawn/svg/calculators/aspect_ratio_spec.rb +50 -50
- data/spec/prawn/svg/calculators/document_sizing_spec.rb +35 -35
- data/spec/prawn/svg/calculators/pixels_spec.rb +31 -30
- data/spec/prawn/svg/color_spec.rb +31 -31
- data/spec/prawn/svg/css/font_family_parser_spec.rb +12 -12
- data/spec/prawn/svg/css/selector_parser_spec.rb +21 -21
- data/spec/prawn/svg/css/stylesheets_spec.rb +51 -43
- data/spec/prawn/svg/css/values_parser_spec.rb +16 -0
- data/spec/prawn/svg/document_spec.rb +15 -14
- data/spec/prawn/svg/elements/base_spec.rb +39 -34
- data/spec/prawn/svg/elements/gradient_spec.rb +39 -39
- data/spec/prawn/svg/elements/line_spec.rb +22 -22
- data/spec/prawn/svg/elements/marker_spec.rb +44 -47
- data/spec/prawn/svg/elements/path_spec.rb +134 -110
- data/spec/prawn/svg/elements/polygon_spec.rb +18 -18
- data/spec/prawn/svg/elements/polyline_spec.rb +16 -16
- data/spec/prawn/svg/elements/text_spec.rb +149 -127
- data/spec/prawn/svg/font_registry_spec.rb +34 -34
- data/spec/prawn/svg/font_spec.rb +4 -4
- data/spec/prawn/svg/interface_spec.rb +47 -39
- data/spec/prawn/svg/loaders/data_spec.rb +21 -21
- data/spec/prawn/svg/loaders/file_spec.rb +43 -40
- data/spec/prawn/svg/loaders/web_spec.rb +15 -15
- data/spec/prawn/svg/pathable_spec.rb +21 -21
- data/spec/prawn/svg/properties_spec.rb +51 -51
- data/spec/prawn/svg/transform_parser_spec.rb +12 -12
- data/spec/prawn/svg/ttf_spec.rb +5 -5
- data/spec/prawn/svg/url_loader_spec.rb +25 -23
- data/spec/spec_helper.rb +4 -4
- metadata +12 -143
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
RSpec.describe Prawn::SVG::CSS::Stylesheets do
|
4
|
-
describe
|
4
|
+
describe 'typical usage' do
|
5
5
|
let(:svg) { <<-SVG }
|
6
6
|
<svg>
|
7
7
|
<style>
|
@@ -57,65 +57,73 @@ RSpec.describe Prawn::SVG::CSS::Stylesheets do
|
|
57
57
|
</svg>
|
58
58
|
SVG
|
59
59
|
|
60
|
-
it
|
60
|
+
it 'associates styles with elements' do
|
61
61
|
result = Prawn::SVG::CSS::Stylesheets.new(CssParser::Parser.new, REXML::Document.new(svg)).load
|
62
|
-
width_and_styles = result.map { |k, v| [k.attributes[
|
62
|
+
width_and_styles = result.map { |k, v| [k.attributes['width'].to_i, v] }.sort_by(&:first)
|
63
63
|
|
64
64
|
expected = [
|
65
|
-
[
|
66
|
-
[
|
67
|
-
[
|
68
|
-
|
65
|
+
[0, [['overflow', 'hidden', false]]],
|
66
|
+
[1, [['fill', '#ff0000', false]]],
|
67
|
+
[2,
|
68
|
+
[['fill', '#ff0000', false], ['fill', '#330000', false], ['fill', '#440000', false],
|
69
|
+
['fill', '#220000', false]]],
|
70
|
+
[3, [['fill', '#ff0000', false], ['fill', '#00ff00', false]]],
|
71
|
+
[4,
|
72
|
+
[['fill', '#ff0000', false], ['fill', '#330000', false], ['fill', '#440000', false],
|
73
|
+
['fill', '#00ff00', false]]]
|
69
74
|
]
|
70
75
|
|
71
|
-
expected << [5,
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
[
|
77
|
-
[
|
78
|
-
[
|
79
|
-
[
|
80
|
-
[
|
81
|
-
[
|
82
|
-
[
|
83
|
-
[
|
84
|
-
[
|
85
|
-
|
76
|
+
expected << [5,
|
77
|
+
[['fill', '#ff0000', false], ['fill', '#330000', false], ['fill', '#330000', false], ['fill', '#440000', false],
|
78
|
+
['fill', '#00ff00', false]]]
|
79
|
+
|
80
|
+
expected.push(
|
81
|
+
[6, [['fill', '#ff0000', false], ['fill', '#441234', false], ['fill', '#0000ff', false]]],
|
82
|
+
[7, [['fill', '#550000', false]]],
|
83
|
+
[8, [['fill', '#660000', false]]],
|
84
|
+
[9, [['fill', '#770000', false]]],
|
85
|
+
[10, [['fill', '#880000', false]]],
|
86
|
+
[11, [['fill', '#990000', false]]],
|
87
|
+
[12, [['fill', '#aa0000', false]]],
|
88
|
+
[13, [['fill', '#bb0000', false]]],
|
89
|
+
[14, [['fill', '#cc0000', false]]],
|
90
|
+
[15, [['fill', '#dd0000', false]]],
|
91
|
+
[16, [['fill', '#ee0000', false]]]
|
92
|
+
)
|
86
93
|
|
87
94
|
expect(width_and_styles).to eq(expected)
|
88
95
|
end
|
89
96
|
end
|
90
97
|
|
91
|
-
describe
|
98
|
+
describe 'style tag parsing' do
|
92
99
|
let(:svg) do
|
93
|
-
|
94
|
-
<svg>
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
z</style>
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
</svg>
|
100
|
+
<<~SVG
|
101
|
+
<svg>
|
102
|
+
<some-tag>
|
103
|
+
<style>a
|
104
|
+
before>
|
105
|
+
x <![CDATA[ y
|
106
|
+
inside <>>
|
107
|
+
k ]]> j
|
108
|
+
after
|
109
|
+
z</style>
|
110
|
+
</some-tag>
|
111
|
+
|
112
|
+
<other-tag>
|
113
|
+
<more-tag>
|
114
|
+
<style>hello</style>
|
115
|
+
</more-tag>
|
116
|
+
</other-tag>
|
117
|
+
</svg>
|
111
118
|
SVG
|
112
119
|
end
|
113
120
|
|
114
|
-
it
|
121
|
+
it 'scans the document for style tags and adds the style information to the css parser' do
|
115
122
|
css_parser = instance_double(CssParser::Parser)
|
116
123
|
|
124
|
+
expect(css_parser).to receive(:add_block!).with('svg, symbol, image, marker, pattern, foreignObject { overflow: hidden }')
|
117
125
|
expect(css_parser).to receive(:add_block!).with("a\n before>\n x y\n inside <>>\n k j\n after\nz")
|
118
|
-
expect(css_parser).to receive(:add_block!).with(
|
126
|
+
expect(css_parser).to receive(:add_block!).with('hello')
|
119
127
|
allow(css_parser).to receive(:each_rule_set)
|
120
128
|
|
121
129
|
Prawn::SVG::CSS::Stylesheets.new(css_parser, REXML::Document.new(svg)).load
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Prawn::SVG::CSS::ValuesParser do
|
4
|
+
it 'parses specified values' do
|
5
|
+
values = 'hello world url("#myid") no-quote(very good) escaping(")\\")ok") rgb( 1,4, 5 )'
|
6
|
+
|
7
|
+
expect(described_class.parse(values)).to eq [
|
8
|
+
'hello',
|
9
|
+
'world',
|
10
|
+
['url', ['#myid']],
|
11
|
+
['no-quote', ['very good']],
|
12
|
+
['escaping', [')")ok']],
|
13
|
+
['rgb', %w[1 4 5]]
|
14
|
+
]
|
15
|
+
end
|
16
|
+
end
|
@@ -1,15 +1,15 @@
|
|
1
|
-
require File.dirname(__FILE__)
|
1
|
+
require "#{File.dirname(__FILE__)}/../../spec_helper"
|
2
2
|
|
3
3
|
describe Prawn::SVG::Document do
|
4
4
|
let(:bounds) { [100, 100] }
|
5
5
|
let(:options) { {} }
|
6
6
|
|
7
|
-
describe
|
8
|
-
context
|
9
|
-
let(:svg) {
|
10
|
-
let(:options) { {color_mode: :cmyk} }
|
7
|
+
describe '#initialize' do
|
8
|
+
context 'with a well-formed document' do
|
9
|
+
let(:svg) { '<svg></svg>' }
|
10
|
+
let(:options) { { color_mode: :cmyk } }
|
11
11
|
|
12
|
-
it
|
12
|
+
it 'parses the XML and yields itself to its block' do
|
13
13
|
yielded = nil
|
14
14
|
|
15
15
|
document = Prawn::SVG::Document.new(svg, bounds, options) do |doc|
|
@@ -22,23 +22,24 @@ describe Prawn::SVG::Document do
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
context
|
25
|
+
context 'when unparsable XML is provided' do
|
26
26
|
let(:svg) { "this isn't SVG data" }
|
27
27
|
|
28
|
-
it
|
29
|
-
expect
|
28
|
+
it 'raises an exception' do
|
29
|
+
expect do
|
30
30
|
Prawn::SVG::Document.new(svg, bounds, options)
|
31
|
-
|
31
|
+
end.to raise_error Prawn::SVG::Document::InvalidSVGData, 'The data supplied is not a valid SVG document.'
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
-
context
|
36
|
-
let(:svg) {
|
35
|
+
context 'when the user passes in a filename instead of SVG data' do
|
36
|
+
let(:svg) { 'some_file.svg' }
|
37
37
|
|
38
38
|
it "raises an exception letting them know what they've done" do
|
39
|
-
expect
|
39
|
+
expect do
|
40
40
|
Prawn::SVG::Document.new(svg, bounds, options)
|
41
|
-
|
41
|
+
end.to raise_error Prawn::SVG::Document::InvalidSVGData,
|
42
|
+
"The data supplied is not a valid SVG document. It looks like you've supplied a filename instead; use IO.read(filename) to get the data before you pass it to prawn-svg."
|
42
43
|
end
|
43
44
|
end
|
44
45
|
end
|
@@ -1,104 +1,107 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Prawn::SVG::Elements::Base do
|
4
|
-
let(:svg) {
|
5
|
-
let(:document)
|
4
|
+
let(:svg) { '<svg></svg>' }
|
5
|
+
let(:document) do
|
6
|
+
Prawn::SVG::Document.new(svg, [800, 600], {},
|
7
|
+
font_registry: Prawn::SVG::FontRegistry.new('Helvetica' => { normal: nil }))
|
8
|
+
end
|
6
9
|
let(:parent_calls) { [] }
|
7
10
|
let(:element) { Prawn::SVG::Elements::Base.new(document, document.root, parent_calls, fake_state) }
|
8
11
|
|
9
|
-
describe
|
12
|
+
describe '#initialize' do
|
10
13
|
let(:svg) { '<something id="hello"/>' }
|
11
14
|
|
12
|
-
it
|
15
|
+
it 'adds itself to the elements_by_id hash if an id attribute is supplied' do
|
13
16
|
element
|
14
|
-
expect(document.elements_by_id[
|
17
|
+
expect(document.elements_by_id['hello']).to eq element
|
15
18
|
end
|
16
19
|
end
|
17
20
|
|
18
|
-
describe
|
19
|
-
it
|
21
|
+
describe '#process' do
|
22
|
+
it 'calls #parse and #apply so subclasses can parse the element' do
|
20
23
|
expect(element).to receive(:parse).ordered
|
21
24
|
expect(element).to receive(:apply).ordered
|
22
25
|
element.process
|
23
26
|
end
|
24
27
|
|
25
|
-
describe
|
28
|
+
describe 'applying calls from the standard attributes' do
|
26
29
|
let(:svg) do
|
27
30
|
<<-SVG
|
28
31
|
<something transform="scale(2)" fill-opacity="0.5" fill="red" stroke="blue" stroke-width="5"/>
|
29
32
|
SVG
|
30
33
|
end
|
31
34
|
|
32
|
-
it
|
35
|
+
it 'appends the relevant calls' do
|
33
36
|
element.process
|
34
37
|
expect(element.base_calls).to eq [
|
35
|
-
[
|
36
|
-
[
|
37
|
-
[
|
38
|
-
[
|
39
|
-
[
|
40
|
-
[
|
38
|
+
['transformation_matrix', [2, 0, 0, 2, 0, 0], {}, [
|
39
|
+
['transparent', [0.5, 1], {}, [
|
40
|
+
['fill_color', ['ff0000'], {}, []],
|
41
|
+
['stroke_color', ['0000ff'], {}, []],
|
42
|
+
['line_width', [5.0], {}, []],
|
43
|
+
['fill_and_stroke', [], {}, []]
|
41
44
|
]]
|
42
45
|
]]
|
43
46
|
]
|
44
47
|
end
|
45
48
|
end
|
46
49
|
|
47
|
-
describe
|
50
|
+
describe 'fills and strokes' do
|
48
51
|
before { element.process }
|
49
52
|
subject { element.base_calls.last }
|
50
53
|
|
51
|
-
context
|
54
|
+
context 'with neither fill nor stroke' do
|
52
55
|
let(:svg) { '<rect style="fill: none;"></rect>' }
|
53
56
|
it { is_expected.to eq ['end_path', [], {}, []] }
|
54
57
|
end
|
55
58
|
|
56
|
-
context
|
59
|
+
context 'with a fill only' do
|
57
60
|
let(:svg) { '<rect style="fill: black;"></rect>' }
|
58
61
|
it { is_expected.to eq ['fill', [], {}, []] }
|
59
62
|
end
|
60
63
|
|
61
|
-
context
|
64
|
+
context 'with a stroke only' do
|
62
65
|
let(:svg) { '<rect style="fill: none; stroke: black;"></rect>' }
|
63
66
|
it { is_expected.to eq ['stroke', [], {}, []] }
|
64
67
|
end
|
65
68
|
|
66
|
-
context
|
69
|
+
context 'with fill and stroke' do
|
67
70
|
let(:svg) { '<rect style="fill: black; stroke: black;"></rect>' }
|
68
71
|
it { is_expected.to eq ['fill_and_stroke', [], {}, []] }
|
69
72
|
end
|
70
73
|
|
71
|
-
context
|
74
|
+
context 'with fill with evenodd fill rule' do
|
72
75
|
let(:svg) { '<rect style="fill: black; fill-rule: evenodd;"></rect>' }
|
73
|
-
it { is_expected.to eq ['fill', [], {fill_rule: :even_odd}, []] }
|
76
|
+
it { is_expected.to eq ['fill', [], { fill_rule: :even_odd }, []] }
|
74
77
|
end
|
75
78
|
end
|
76
79
|
|
77
|
-
it
|
80
|
+
it 'appends calls to the parent element' do
|
78
81
|
expect(element).to receive(:apply) do
|
79
|
-
element.send :add_call,
|
82
|
+
element.send :add_call, 'test', 'argument', kw: 'argument'
|
80
83
|
end
|
81
84
|
|
82
85
|
element.process
|
83
|
-
expect(element.parent_calls).to eq [[
|
86
|
+
expect(element.parent_calls).to eq [['fill', [], {}, [['test', ['argument'], { kw: 'argument' }, []]]]]
|
84
87
|
end
|
85
88
|
|
86
|
-
it
|
89
|
+
it 'quietly absorbs a SkipElementQuietly exception' do
|
87
90
|
expect(element).to receive(:parse).and_raise(Prawn::SVG::Elements::Base::SkipElementQuietly)
|
88
91
|
expect(element).to_not receive(:apply)
|
89
92
|
element.process
|
90
93
|
expect(document.warnings).to be_empty
|
91
94
|
end
|
92
95
|
|
93
|
-
it
|
94
|
-
expect(element).to receive(:parse).and_raise(Prawn::SVG::Elements::Base::SkipElementError,
|
96
|
+
it 'absorbs a SkipElementError exception, logging a warning' do
|
97
|
+
expect(element).to receive(:parse).and_raise(Prawn::SVG::Elements::Base::SkipElementError, 'hello')
|
95
98
|
expect(element).to_not receive(:apply)
|
96
99
|
element.process
|
97
|
-
expect(document.warnings).to eq [
|
100
|
+
expect(document.warnings).to eq ['hello']
|
98
101
|
end
|
99
102
|
end
|
100
103
|
|
101
|
-
describe
|
104
|
+
describe '#apply_colors' do
|
102
105
|
before do
|
103
106
|
element.send(:extract_attributes_and_properties)
|
104
107
|
end
|
@@ -141,8 +144,10 @@ describe Prawn::SVG::Elements::Base do
|
|
141
144
|
subject
|
142
145
|
end
|
143
146
|
|
144
|
-
context
|
145
|
-
let(:svg)
|
147
|
+
context 'with a color attribute defined on a parent element' do
|
148
|
+
let(:svg) do
|
149
|
+
'<svg style="color: green;"><g style="color: red;"><rect width="10" height="10" style="fill: currentColor;"></rect></g></svg>'
|
150
|
+
end
|
146
151
|
let(:element) { Prawn::SVG::Elements::Root.new(document, document.root, parent_calls) }
|
147
152
|
let(:flattened_calls) { flatten_calls(element.base_calls) }
|
148
153
|
|
@@ -162,7 +167,7 @@ describe Prawn::SVG::Elements::Base do
|
|
162
167
|
end
|
163
168
|
end
|
164
169
|
|
165
|
-
describe
|
170
|
+
describe 'stylesheets' do
|
166
171
|
let(:svg) { <<-SVG }
|
167
172
|
<svg>
|
168
173
|
<style>
|
@@ -177,7 +182,7 @@ describe Prawn::SVG::Elements::Base do
|
|
177
182
|
</svg>
|
178
183
|
SVG
|
179
184
|
|
180
|
-
it
|
185
|
+
it 'applies stylesheet styling but style attributes take precedence' do
|
181
186
|
document = Prawn::SVG::Document.new(svg, [100, 100], {})
|
182
187
|
calls = []
|
183
188
|
element = Prawn::SVG::Elements::Root.new(document, document.root, calls)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Prawn::SVG::Elements::Gradient do
|
4
|
-
let(:document) { Prawn::SVG::Document.new(svg, [800, 600], {width: 800, height: 600}) }
|
4
|
+
let(:document) { Prawn::SVG::Document.new(svg, [800, 600], { width: 800, height: 600 }) }
|
5
5
|
let(:element) { Prawn::SVG::Elements::Gradient.new(document, document.root, [], fake_state) }
|
6
6
|
|
7
7
|
before do
|
@@ -9,7 +9,7 @@ describe Prawn::SVG::Elements::Gradient do
|
|
9
9
|
element.process
|
10
10
|
end
|
11
11
|
|
12
|
-
describe
|
12
|
+
describe 'object bounding box with linear gradient' do
|
13
13
|
let(:svg) do
|
14
14
|
<<-SVG
|
15
15
|
<linearGradient id="flag" x1="0" x2="0.2" y1="0" y2="1">
|
@@ -20,17 +20,17 @@ describe Prawn::SVG::Elements::Gradient do
|
|
20
20
|
SVG
|
21
21
|
end
|
22
22
|
|
23
|
-
it
|
24
|
-
expect(document.gradients[
|
23
|
+
it 'is stored in the document gradients table' do
|
24
|
+
expect(document.gradients['flag']).to eq element
|
25
25
|
end
|
26
26
|
|
27
|
-
it
|
27
|
+
it 'returns correct gradient arguments for an element' do
|
28
28
|
arguments = element.gradient_arguments(double(bounding_box: [100, 100, 200, 0]))
|
29
29
|
expect(arguments).to eq(
|
30
|
-
from:
|
31
|
-
to:
|
32
|
-
stops:
|
33
|
-
apply_transformations: true
|
30
|
+
from: [100.0, 100.0],
|
31
|
+
to: [120.0, 0.0],
|
32
|
+
stops: [[0, 'ff0000'], [0.25, 'ff0000'], [0.5, 'ffffff'], [0.75, '0000ff'], [1, '0000ff']],
|
33
|
+
apply_transformations: true
|
34
34
|
)
|
35
35
|
end
|
36
36
|
|
@@ -40,7 +40,7 @@ describe Prawn::SVG::Elements::Gradient do
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
describe
|
43
|
+
describe 'object bounding box with radial gradient' do
|
44
44
|
let(:svg) do
|
45
45
|
<<-SVG
|
46
46
|
<radialGradient id="flag" cx="0" cy="0.2" fx="0.5" r="0.8">
|
@@ -51,24 +51,24 @@ describe Prawn::SVG::Elements::Gradient do
|
|
51
51
|
SVG
|
52
52
|
end
|
53
53
|
|
54
|
-
it
|
55
|
-
expect(document.gradients[
|
54
|
+
it 'is stored in the document gradients table' do
|
55
|
+
expect(document.gradients['flag']).to eq element
|
56
56
|
end
|
57
57
|
|
58
|
-
it
|
58
|
+
it 'returns correct gradient arguments for an element' do
|
59
59
|
arguments = element.gradient_arguments(double(bounding_box: [100, 100, 200, 0]))
|
60
60
|
expect(arguments).to eq(
|
61
|
-
from:
|
62
|
-
to:
|
63
|
-
r1:
|
64
|
-
r2:
|
65
|
-
stops:
|
66
|
-
apply_transformations: true
|
61
|
+
from: [150, 80],
|
62
|
+
to: [100, 80],
|
63
|
+
r1: 0,
|
64
|
+
r2: Math.sqrt(((0.8 * 100)**2) + ((0.8 * 100)**2)),
|
65
|
+
stops: [[0, 'ff0000'], [0.25, 'ff0000'], [0.5, 'ffffff'], [0.75, '0000ff'], [1, '0000ff']],
|
66
|
+
apply_transformations: true
|
67
67
|
)
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
|
-
describe
|
71
|
+
describe 'user space on use with linear gradient' do
|
72
72
|
let(:svg) do
|
73
73
|
<<-SVG
|
74
74
|
<linearGradient id="flag" gradientUnits="userSpaceOnUse" x1="100" y1="500" x2="200" y2="600">
|
@@ -78,18 +78,18 @@ describe Prawn::SVG::Elements::Gradient do
|
|
78
78
|
SVG
|
79
79
|
end
|
80
80
|
|
81
|
-
it
|
81
|
+
it 'returns correct gradient arguments for an element' do
|
82
82
|
arguments = element.gradient_arguments(double)
|
83
83
|
expect(arguments).to eq(
|
84
|
-
from:
|
85
|
-
to:
|
86
|
-
stops:
|
87
|
-
apply_transformations: true
|
84
|
+
from: [100.0, 100.0],
|
85
|
+
to: [200.0, 0.0],
|
86
|
+
stops: [[0, 'ff0000'], [1, '0000ff']],
|
87
|
+
apply_transformations: true
|
88
88
|
)
|
89
89
|
end
|
90
90
|
end
|
91
91
|
|
92
|
-
describe
|
92
|
+
describe 'user space on use with radial gradient' do
|
93
93
|
let(:svg) do
|
94
94
|
<<-SVG
|
95
95
|
<radialGradient id="flag" gradientUnits="userSpaceOnUse" fx="100" fy="500" cx="200" cy="600" r="150">
|
@@ -99,20 +99,20 @@ describe Prawn::SVG::Elements::Gradient do
|
|
99
99
|
SVG
|
100
100
|
end
|
101
101
|
|
102
|
-
it
|
102
|
+
it 'returns correct gradient arguments for an element' do
|
103
103
|
arguments = element.gradient_arguments(double)
|
104
104
|
expect(arguments).to eq(
|
105
|
-
from:
|
106
|
-
to:
|
107
|
-
r1:
|
108
|
-
r2:
|
109
|
-
stops:
|
110
|
-
apply_transformations: true
|
105
|
+
from: [100.0, 100.0],
|
106
|
+
to: [200.0, 0.0],
|
107
|
+
r1: 0,
|
108
|
+
r2: 150,
|
109
|
+
stops: [[0, 'ff0000'], [1, '0000ff']],
|
110
|
+
apply_transformations: true
|
111
111
|
)
|
112
112
|
end
|
113
113
|
end
|
114
114
|
|
115
|
-
context
|
115
|
+
context 'when gradientTransform is specified' do
|
116
116
|
let(:svg) do
|
117
117
|
<<-SVG
|
118
118
|
<linearGradient id="flag" gradientTransform="translateX(10) scale(2)" x1="0" y1="0" x2="10" y2="10">
|
@@ -122,14 +122,14 @@ describe Prawn::SVG::Elements::Gradient do
|
|
122
122
|
SVG
|
123
123
|
end
|
124
124
|
|
125
|
-
it
|
125
|
+
it 'passes in the transform via the apply_transformations option' do
|
126
126
|
arguments = element.gradient_arguments(double(bounding_box: [0, 0, 10, 10]))
|
127
127
|
|
128
128
|
expect(arguments).to eq(
|
129
|
-
from:
|
130
|
-
to:
|
131
|
-
stops:
|
132
|
-
apply_transformations: [2, 0, 0, 2, 10, 0]
|
129
|
+
from: [0, 0],
|
130
|
+
to: [10, 10],
|
131
|
+
stops: [[0, 'ff0000'], [1, '0000ff']],
|
132
|
+
apply_transformations: [2, 0, 0, 2, 10, 0]
|
133
133
|
)
|
134
134
|
end
|
135
135
|
end
|
@@ -1,54 +1,54 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
RSpec.describe Prawn::SVG::Elements::Line do
|
4
|
-
let(:document) { Prawn::SVG::Document.new(svg, [800, 600], {width: 800, height: 600}) }
|
4
|
+
let(:document) { Prawn::SVG::Document.new(svg, [800, 600], { width: 800, height: 600 }) }
|
5
5
|
|
6
6
|
subject do
|
7
7
|
Prawn::SVG::Elements::Line.new(document, document.root, [], fake_state)
|
8
8
|
end
|
9
9
|
|
10
|
-
context
|
10
|
+
context 'with attributes specified' do
|
11
11
|
let(:svg) { '<line x1="5" y1="10" x2="15" y2="20" stroke="black" />' }
|
12
12
|
|
13
|
-
it
|
13
|
+
it 'renders the line' do
|
14
14
|
subject.process
|
15
15
|
expect(subject.base_calls).to eq [
|
16
|
-
[
|
17
|
-
[
|
18
|
-
[
|
19
|
-
[
|
20
|
-
]
|
16
|
+
['stroke_color', ['000000'], {}, []],
|
17
|
+
['stroke', [], {}, [
|
18
|
+
['move_to', [[5.0, 590.0]], {}, []],
|
19
|
+
['line_to', [[15.0, 580.0]], {}, []]
|
20
|
+
]]
|
21
21
|
]
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
context
|
25
|
+
context 'with no attributes nor stroke specified' do
|
26
26
|
let(:svg) { '<line />' }
|
27
27
|
|
28
|
-
it
|
28
|
+
it 'outlines a path from 0,0 to 0,0' do
|
29
29
|
subject.process
|
30
30
|
expect(subject.base_calls).to eq [
|
31
|
-
[
|
32
|
-
[
|
33
|
-
[
|
34
|
-
]
|
31
|
+
['end_path', [], {}, [
|
32
|
+
['move_to', [[0, 600]], {}, []],
|
33
|
+
['line_to', [[0, 600]], {}, []]
|
34
|
+
]]
|
35
35
|
]
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
-
context
|
39
|
+
context 'with a fill specified' do
|
40
40
|
let(:svg) { '<line x1="0" y1="0" x2="15" y2="20" style="stroke: red; fill: blue;" />' }
|
41
41
|
|
42
|
-
it
|
42
|
+
it 'ignores the fill' do
|
43
43
|
subject.process
|
44
44
|
|
45
45
|
expect(subject.base_calls).to eq [
|
46
|
-
[
|
47
|
-
[
|
48
|
-
[
|
49
|
-
[
|
50
|
-
[
|
51
|
-
]
|
46
|
+
['fill_color', ['0000ff'], {}, []],
|
47
|
+
['stroke_color', ['ff0000'], {}, []],
|
48
|
+
['stroke', [], {}, [
|
49
|
+
['move_to', [[0, 600]], {}, []],
|
50
|
+
['line_to', [[15.0, 580.0]], {}, []]
|
51
|
+
]]
|
52
52
|
]
|
53
53
|
end
|
54
54
|
end
|