prawn-svg 0.29.1 → 0.32.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/test.yml +18 -0
- data/LICENSE +1 -1
- data/README.md +10 -9
- data/lib/prawn/svg/attributes/opacity.rb +4 -4
- data/lib/prawn/svg/attributes/transform.rb +2 -44
- data/lib/prawn/svg/elements/base.rb +11 -5
- data/lib/prawn/svg/elements/call_duplicator.rb +1 -1
- data/lib/prawn/svg/elements/gradient.rb +83 -25
- data/lib/prawn/svg/elements/image.rb +2 -2
- data/lib/prawn/svg/elements/path.rb +42 -29
- data/lib/prawn/svg/elements/root.rb +4 -1
- data/lib/prawn/svg/elements/text_component.rb +21 -5
- data/lib/prawn/svg/elements/use.rb +23 -7
- data/lib/prawn/svg/elements.rb +2 -0
- data/lib/prawn/svg/extensions/additional_gradient_transforms.rb +23 -0
- data/lib/prawn/svg/interface.rb +38 -8
- data/lib/prawn/svg/loaders/data.rb +1 -1
- data/lib/prawn/svg/loaders/file.rb +3 -1
- data/lib/prawn/svg/properties.rb +1 -0
- data/lib/prawn/svg/transform_parser.rb +72 -0
- data/lib/prawn/svg/version.rb +1 -1
- data/lib/prawn-svg.rb +4 -0
- data/prawn-svg.gemspec +3 -2
- data/spec/integration_spec.rb +24 -24
- data/spec/prawn/svg/attributes/opacity_spec.rb +85 -0
- data/spec/prawn/svg/attributes/transform_spec.rb +30 -35
- data/spec/prawn/svg/css/stylesheets_spec.rb +1 -19
- data/spec/prawn/svg/elements/base_spec.rb +16 -16
- data/spec/prawn/svg/elements/gradient_spec.rb +79 -4
- data/spec/prawn/svg/elements/line_spec.rb +12 -12
- data/spec/prawn/svg/elements/marker_spec.rb +27 -27
- data/spec/prawn/svg/elements/path_spec.rb +29 -17
- data/spec/prawn/svg/elements/polygon_spec.rb +9 -9
- data/spec/prawn/svg/elements/polyline_spec.rb +7 -7
- data/spec/prawn/svg/elements/text_spec.rb +65 -50
- data/spec/prawn/svg/loaders/data_spec.rb +8 -0
- data/spec/prawn/svg/pathable_spec.rb +4 -4
- data/spec/prawn/svg/transform_parser_spec.rb +94 -0
- data/spec/sample_svg/double_opacity.svg +6 -0
- data/spec/sample_svg/gradient_transform.svg +19 -0
- data/spec/sample_svg/links.svg +18 -0
- data/spec/sample_svg/radgrad01-bounding.svg +26 -0
- data/spec/sample_svg/radgrad01.svg +26 -0
- data/spec/sample_svg/svg_fill.svg +5 -0
- data/spec/sample_svg/text-decoration.svg +4 -0
- data/spec/sample_svg/transform.svg +20 -0
- data/spec/sample_svg/use_disordered.svg +17 -0
- data/spec/spec_helper.rb +2 -2
- metadata +48 -10
- data/.travis.yml +0 -8
@@ -9,7 +9,7 @@ describe Prawn::SVG::Elements::Gradient do
|
|
9
9
|
element.process
|
10
10
|
end
|
11
11
|
|
12
|
-
describe "object bounding box" do
|
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">
|
@@ -29,7 +29,8 @@ describe Prawn::SVG::Elements::Gradient do
|
|
29
29
|
expect(arguments).to eq(
|
30
30
|
from: [100.0, 100.0],
|
31
31
|
to: [120.0, 0.0],
|
32
|
-
stops: [[0, "ff0000"], [0.25, "ff0000"], [0.5, "ffffff"], [0.75, "0000ff"], [1, "0000ff"]]
|
32
|
+
stops: [[0, "ff0000"], [0.25, "ff0000"], [0.5, "ffffff"], [0.75, "0000ff"], [1, "0000ff"]],
|
33
|
+
apply_transformations: true,
|
33
34
|
)
|
34
35
|
end
|
35
36
|
|
@@ -39,7 +40,35 @@ describe Prawn::SVG::Elements::Gradient do
|
|
39
40
|
end
|
40
41
|
end
|
41
42
|
|
42
|
-
describe "
|
43
|
+
describe "object bounding box with radial gradient" do
|
44
|
+
let(:svg) do
|
45
|
+
<<-SVG
|
46
|
+
<radialGradient id="flag" cx="0" cy="0.2" fx="0.5" r="0.8">
|
47
|
+
<stop offset="25%" stop-color="red"/>
|
48
|
+
<stop offset="50%" stop-color="white"/>
|
49
|
+
<stop offset="75%" stop-color="blue"/>
|
50
|
+
</radialGradient>
|
51
|
+
SVG
|
52
|
+
end
|
53
|
+
|
54
|
+
it "is stored in the document gradients table" do
|
55
|
+
expect(document.gradients["flag"]).to eq element
|
56
|
+
end
|
57
|
+
|
58
|
+
it "returns correct gradient arguments for an element" do
|
59
|
+
arguments = element.gradient_arguments(double(bounding_box: [100, 100, 200, 0]))
|
60
|
+
expect(arguments).to eq(
|
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
|
+
)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "user space on use with linear gradient" do
|
43
72
|
let(:svg) do
|
44
73
|
<<-SVG
|
45
74
|
<linearGradient id="flag" gradientUnits="userSpaceOnUse" x1="100" y1="500" x2="200" y2="600">
|
@@ -54,7 +83,53 @@ describe Prawn::SVG::Elements::Gradient do
|
|
54
83
|
expect(arguments).to eq(
|
55
84
|
from: [100.0, 100.0],
|
56
85
|
to: [200.0, 0.0],
|
57
|
-
stops: [[0, "ff0000"], [1, "0000ff"]]
|
86
|
+
stops: [[0, "ff0000"], [1, "0000ff"]],
|
87
|
+
apply_transformations: true,
|
88
|
+
)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe "user space on use with radial gradient" do
|
93
|
+
let(:svg) do
|
94
|
+
<<-SVG
|
95
|
+
<radialGradient id="flag" gradientUnits="userSpaceOnUse" fx="100" fy="500" cx="200" cy="600" r="150">
|
96
|
+
<stop offset="0" stop-color="red"/>
|
97
|
+
<stop offset="1" stop-color="blue"/>
|
98
|
+
</radialGradient>
|
99
|
+
SVG
|
100
|
+
end
|
101
|
+
|
102
|
+
it "returns correct gradient arguments for an element" do
|
103
|
+
arguments = element.gradient_arguments(double)
|
104
|
+
expect(arguments).to eq(
|
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
|
+
)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
context "when gradientTransform is specified" do
|
116
|
+
let(:svg) do
|
117
|
+
<<-SVG
|
118
|
+
<linearGradient id="flag" gradientTransform="translateX(10) scale(2)" x1="0" y1="0" x2="10" y2="10">
|
119
|
+
<stop offset="0" stop-color="red"/>
|
120
|
+
<stop offset="1" stop-color="blue"/>
|
121
|
+
</linearGradient>
|
122
|
+
SVG
|
123
|
+
end
|
124
|
+
|
125
|
+
it "passes in the transform via the apply_transformations option" do
|
126
|
+
arguments = element.gradient_arguments(double(bounding_box: [0, 0, 10, 10]))
|
127
|
+
|
128
|
+
expect(arguments).to eq(
|
129
|
+
from: [0, 0],
|
130
|
+
to: [10, 10],
|
131
|
+
stops: [[0, "ff0000"], [1, "0000ff"]],
|
132
|
+
apply_transformations: [2, 0, 0, 2, 10, 0],
|
58
133
|
)
|
59
134
|
end
|
60
135
|
end
|
@@ -13,10 +13,10 @@ RSpec.describe Prawn::SVG::Elements::Line do
|
|
13
13
|
it "renders the line" do
|
14
14
|
subject.process
|
15
15
|
expect(subject.base_calls).to eq [
|
16
|
-
["stroke_color", ["000000"], []],
|
17
|
-
["stroke", [], [
|
18
|
-
["move_to", [[5.0, 590.0]], []],
|
19
|
-
["line_to", [[15.0, 580.0]], []]]
|
16
|
+
["stroke_color", ["000000"], {}, []],
|
17
|
+
["stroke", [], {}, [
|
18
|
+
["move_to", [[5.0, 590.0]], {}, []],
|
19
|
+
["line_to", [[15.0, 580.0]], {}, []]]
|
20
20
|
]
|
21
21
|
]
|
22
22
|
end
|
@@ -28,9 +28,9 @@ RSpec.describe Prawn::SVG::Elements::Line do
|
|
28
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
|
-
["end_path", [], [
|
32
|
-
["move_to", [[0, 600]], []],
|
33
|
-
["line_to", [[0, 600]], []]]
|
31
|
+
["end_path", [], {}, [
|
32
|
+
["move_to", [[0, 600]], {}, []],
|
33
|
+
["line_to", [[0, 600]], {}, []]]
|
34
34
|
]
|
35
35
|
]
|
36
36
|
end
|
@@ -43,11 +43,11 @@ RSpec.describe Prawn::SVG::Elements::Line do
|
|
43
43
|
subject.process
|
44
44
|
|
45
45
|
expect(subject.base_calls).to eq [
|
46
|
-
["fill_color", ["0000ff"], []],
|
47
|
-
["stroke_color", ["ff0000"], []],
|
48
|
-
["stroke", [], [
|
49
|
-
["move_to", [[0, 600]], []],
|
50
|
-
["line_to", [[15.0, 580.0]], []]]
|
46
|
+
["fill_color", ["0000ff"], {}, []],
|
47
|
+
["stroke_color", ["ff0000"], {}, []],
|
48
|
+
["stroke", [], {}, [
|
49
|
+
["move_to", [[0, 600]], {}, []],
|
50
|
+
["line_to", [[15.0, 580.0]], {}, []]]
|
51
51
|
]
|
52
52
|
]
|
53
53
|
end
|
@@ -54,41 +54,41 @@ RSpec.describe Prawn::SVG::Elements::Marker do
|
|
54
54
|
# in section 11.6.3.
|
55
55
|
|
56
56
|
expect(line_element.base_calls).to eq [
|
57
|
-
["stroke_color", ["000000"], []],
|
58
|
-
["line_width", [100.0], []],
|
59
|
-
["stroke", [], [
|
60
|
-
["move_to", [[0.0, 600.0]], []],
|
61
|
-
["line_to", [[10.0, 590.0]], []]
|
57
|
+
["stroke_color", ["000000"], {}, []],
|
58
|
+
["line_width", [100.0], {}, []],
|
59
|
+
["stroke", [], {}, [
|
60
|
+
["move_to", [[0.0, 600.0]], {}, []],
|
61
|
+
["line_to", [[10.0, 590.0]], {}, []]
|
62
62
|
]
|
63
63
|
],
|
64
|
-
["save", [], []],
|
65
|
-
["transformation_matrix", [1, 0, 0, 1, 10, -10], []],
|
66
|
-
["rotate", [-45, {origin: [0, 600.0]}
|
67
|
-
["transformation_matrix", [100.0, 0, 0, 100.0, 0, 0], []],
|
68
|
-
["transformation_matrix", [1, 0, 0, 1, -0.0, 1.5], []],
|
69
|
-
["rectangle", [[-0.5, 600.0], 4.0, 3.0], []],
|
70
|
-
["clip", [], []],
|
71
|
-
["transformation_matrix", [0.3, 0, 0, 0.3, 0, 0], []],
|
72
|
-
["transparent", [1.0, 1.0], [
|
73
|
-
["stroke_color", ["000000"], []],
|
74
|
-
["line_width", [100.0], []],
|
75
|
-
["cap_style", [:butt], []],
|
76
|
-
["undash", [], []],
|
77
|
-
["save", [], []],
|
78
|
-
["fill", [], [
|
79
|
-
["join_style", [:bevel], []],
|
80
|
-
["move_to", [[0.0, 600.0]], []],
|
81
|
-
["line_to", [[10.0, 595.0]], []],
|
82
|
-
["line_to", [[0.0, 590.0]], []],
|
83
|
-
["close_path", [], []]
|
64
|
+
["save", [], {}, []],
|
65
|
+
["transformation_matrix", [1, 0, 0, 1, 10, -10], {}, []],
|
66
|
+
["rotate", [-45], {origin: [0, 600.0]}, [
|
67
|
+
["transformation_matrix", [100.0, 0, 0, 100.0, 0, 0], {}, []],
|
68
|
+
["transformation_matrix", [1, 0, 0, 1, -0.0, 1.5], {}, []],
|
69
|
+
["rectangle", [[-0.5, 600.0], 4.0, 3.0], {}, []],
|
70
|
+
["clip", [], {}, []],
|
71
|
+
["transformation_matrix", [0.3, 0, 0, 0.3, 0, 0], {}, []],
|
72
|
+
["transparent", [1.0, 1.0], {}, [
|
73
|
+
["stroke_color", ["000000"], {}, []],
|
74
|
+
["line_width", [100.0], {}, []],
|
75
|
+
["cap_style", [:butt], {}, []],
|
76
|
+
["undash", [], {}, []],
|
77
|
+
["save", [], {}, []],
|
78
|
+
["fill", [], {}, [
|
79
|
+
["join_style", [:bevel], {}, []],
|
80
|
+
["move_to", [[0.0, 600.0]], {}, []],
|
81
|
+
["line_to", [[10.0, 595.0]], {}, []],
|
82
|
+
["line_to", [[0.0, 590.0]], {}, []],
|
83
|
+
["close_path", [], {}, []]
|
84
84
|
]
|
85
85
|
],
|
86
|
-
["restore", [], []],
|
86
|
+
["restore", [], {}, []],
|
87
87
|
]
|
88
88
|
]
|
89
89
|
]
|
90
90
|
],
|
91
|
-
["restore", [], []]
|
91
|
+
["restore", [], {}, []]
|
92
92
|
]
|
93
93
|
end
|
94
94
|
end
|
@@ -11,22 +11,22 @@ describe Prawn::SVG::Elements::Path do
|
|
11
11
|
|
12
12
|
describe "command parsing" do
|
13
13
|
context "with a valid path" do
|
14
|
-
let(:d) { "
|
14
|
+
let(:d) { "m12.34 -56.78 1 2M4 5 12-34 -.5.7+3 2.3e3 4e4 4e+4 L31,-2e-5L 6,7 Z ZZa50 50 0 100 100" }
|
15
15
|
|
16
16
|
it "correctly parses" do
|
17
17
|
calls = []
|
18
|
-
path.
|
18
|
+
allow(path).to receive(:parse_path_command) {|*args| calls << args}
|
19
19
|
path.parse
|
20
20
|
|
21
|
-
calls.
|
22
|
-
["
|
23
|
-
["
|
24
|
-
["
|
25
|
-
["
|
26
|
-
["
|
27
|
-
["
|
28
|
-
["
|
29
|
-
["
|
21
|
+
expect(calls).to eq [
|
22
|
+
["m", [[12.34, -56.78], [1, 2]]],
|
23
|
+
["M", [[4, 5], [12, -34], [-0.5, 0.7], [3, 2.3e3], [4e4, 4e4]]],
|
24
|
+
["L", [[31, -2e-5]]],
|
25
|
+
["L", [[6, 7]]],
|
26
|
+
["Z", []],
|
27
|
+
["Z", []],
|
28
|
+
["Z", []],
|
29
|
+
["a", [[50, 50, 0, 1, 0, 0, 100]]],
|
30
30
|
]
|
31
31
|
end
|
32
32
|
end
|
@@ -36,12 +36,12 @@ describe Prawn::SVG::Elements::Path do
|
|
36
36
|
|
37
37
|
it "treats subsequent points to m/M command as relative/absolute depending on command" do
|
38
38
|
[
|
39
|
-
["M", [1,2,3,4]],
|
40
|
-
["L", [3,4]],
|
41
|
-
["m", [5,6,7,8]],
|
42
|
-
["l", [7,8]]
|
39
|
+
["M", [[1,2],[3,4]]],
|
40
|
+
["L", [[3,4]]],
|
41
|
+
["m", [[5,6],[7,8]]],
|
42
|
+
["l", [[7,8]]]
|
43
43
|
].each do |args|
|
44
|
-
path.
|
44
|
+
expect(path).to receive(:parse_path_command).with(*args).and_call_original
|
45
45
|
end
|
46
46
|
|
47
47
|
path.parse
|
@@ -52,7 +52,7 @@ describe Prawn::SVG::Elements::Path do
|
|
52
52
|
let(:d) { "" }
|
53
53
|
|
54
54
|
it "correctly parses" do
|
55
|
-
path.
|
55
|
+
expect(path).not_to receive(:run_path_command)
|
56
56
|
path.parse
|
57
57
|
end
|
58
58
|
end
|
@@ -292,5 +292,17 @@ describe Prawn::SVG::Elements::Path do
|
|
292
292
|
]
|
293
293
|
end
|
294
294
|
end
|
295
|
+
|
296
|
+
context "with highly-compressed flags" do
|
297
|
+
let(:d) { "M100,100a50 50 0 100 100" }
|
298
|
+
|
299
|
+
it "correctly parses them" do
|
300
|
+
expect(subject).to eq [
|
301
|
+
Prawn::SVG::Elements::Path::Move.new([100.0, 100.0]),
|
302
|
+
Prawn::SVG::Elements::Path::Curve.new([50.0, 150.0], [72.57081148225681, 100.0], [50.0, 122.57081148225681]),
|
303
|
+
Prawn::SVG::Elements::Path::Curve.new([99.99999999999999, 200.0], [50.0, 177.42918851774317], [72.5708114822568, 200.0])
|
304
|
+
]
|
305
|
+
end
|
306
|
+
end
|
295
307
|
end
|
296
308
|
end
|
@@ -13,11 +13,11 @@ RSpec.describe Prawn::SVG::Elements::Polygon do
|
|
13
13
|
it "renders the polygon" do
|
14
14
|
subject.process
|
15
15
|
expect(subject.base_calls).to eq [
|
16
|
-
["fill", [], [
|
17
|
-
["move_to", [[10.0, 590.0]], []],
|
18
|
-
["line_to", [[20.0, 580.0]], []],
|
19
|
-
["line_to", [[30.0, 570.0]], []],
|
20
|
-
["close_path", [], []]]
|
16
|
+
["fill", [], {}, [
|
17
|
+
["move_to", [[10.0, 590.0]], {}, []],
|
18
|
+
["line_to", [[20.0, 580.0]], {}, []],
|
19
|
+
["line_to", [[30.0, 570.0]], {}, []],
|
20
|
+
["close_path", [], {}, []]]
|
21
21
|
]
|
22
22
|
]
|
23
23
|
end
|
@@ -29,10 +29,10 @@ RSpec.describe Prawn::SVG::Elements::Polygon do
|
|
29
29
|
it "ignores the last one" do
|
30
30
|
subject.process
|
31
31
|
expect(subject.base_calls).to eq [
|
32
|
-
["fill", [], [
|
33
|
-
["move_to", [[10.0, 590.0]], []],
|
34
|
-
["line_to", [[20.0, 580.0]], []],
|
35
|
-
["close_path", [], []]]
|
32
|
+
["fill", [], {}, [
|
33
|
+
["move_to", [[10.0, 590.0]], {}, []],
|
34
|
+
["line_to", [[20.0, 580.0]], {}, []],
|
35
|
+
["close_path", [], {}, []]]
|
36
36
|
]
|
37
37
|
]
|
38
38
|
end
|
@@ -13,10 +13,10 @@ RSpec.describe Prawn::SVG::Elements::Polyline do
|
|
13
13
|
it "renders the polyline" do
|
14
14
|
subject.process
|
15
15
|
expect(subject.base_calls).to eq [
|
16
|
-
["fill", [], [
|
17
|
-
["move_to", [[10.0, 590.0]], []],
|
18
|
-
["line_to", [[20.0, 580.0]], []],
|
19
|
-
["line_to", [[30.0, 570.0]], []]]
|
16
|
+
["fill", [], {}, [
|
17
|
+
["move_to", [[10.0, 590.0]], {}, []],
|
18
|
+
["line_to", [[20.0, 580.0]], {}, []],
|
19
|
+
["line_to", [[30.0, 570.0]], {}, []]]
|
20
20
|
]
|
21
21
|
]
|
22
22
|
end
|
@@ -28,9 +28,9 @@ RSpec.describe Prawn::SVG::Elements::Polyline do
|
|
28
28
|
it "ignores the last one" do
|
29
29
|
subject.process
|
30
30
|
expect(subject.base_calls).to eq [
|
31
|
-
["fill", [], [
|
32
|
-
["move_to", [[10.0, 590.0]], []],
|
33
|
-
["line_to", [[20.0, 580.0]], []]]
|
31
|
+
["fill", [], {}, [
|
32
|
+
["move_to", [[10.0, 590.0]], {}, []],
|
33
|
+
["line_to", [[20.0, 580.0]], {}, []]]
|
34
34
|
]
|
35
35
|
]
|
36
36
|
end
|
@@ -15,7 +15,7 @@ describe Prawn::SVG::Elements::Text do
|
|
15
15
|
it "converts newlines and tabs to spaces, and preserves spaces" do
|
16
16
|
element.process
|
17
17
|
|
18
|
-
expect(flatten_calls(element.calls)).to include ["draw_text", ["some text", {:size=>16, :style=>:normal, :text_anchor=>'start', :at=>[:relative, :relative], :offset=>[0,0]}]
|
18
|
+
expect(flatten_calls(element.calls)).to include ["draw_text", ["some text"], {:size=>16, :style=>:normal, :text_anchor=>'start', :at=>[:relative, :relative], :offset=>[0,0]}]
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
@@ -25,7 +25,7 @@ describe Prawn::SVG::Elements::Text do
|
|
25
25
|
it "strips space" do
|
26
26
|
element.process
|
27
27
|
|
28
|
-
expect(flatten_calls(element.calls)).to include ["draw_text", ["some text", {:size=>16, :style=>:normal, :text_anchor=>'start', :at=>[:relative, :relative], :offset=>[0,0]}]
|
28
|
+
expect(flatten_calls(element.calls)).to include ["draw_text", ["some text"], {:size=>16, :style=>:normal, :text_anchor=>'start', :at=>[:relative, :relative], :offset=>[0,0]}]
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
@@ -78,16 +78,31 @@ Even more
|
|
78
78
|
element.process
|
79
79
|
|
80
80
|
expect(element.base_calls).to eq [
|
81
|
-
["text_group", [], [
|
82
|
-
["font", ["Helvetica", {style: :normal}
|
83
|
-
["character_spacing", [5.0], [
|
84
|
-
["draw_text", ["spaced", default_style
|
81
|
+
["text_group", [], {}, [
|
82
|
+
["font", ["Helvetica"], {style: :normal}, []],
|
83
|
+
["character_spacing", [5.0], {}, [
|
84
|
+
["draw_text", ["spaced"], default_style, []]
|
85
85
|
]]
|
86
86
|
]]
|
87
87
|
]
|
88
88
|
end
|
89
89
|
end
|
90
90
|
|
91
|
+
describe "underline" do
|
92
|
+
let(:svg) { '<text text-decoration="underline">underlined</text>' }
|
93
|
+
|
94
|
+
it "marks the element to be underlined" do
|
95
|
+
element.process
|
96
|
+
|
97
|
+
expect(element.base_calls).to eq [
|
98
|
+
["text_group", [], {},[
|
99
|
+
["font", ["Helvetica"], {:style=>:normal}, []],
|
100
|
+
["draw_text", ["underlined"], default_style.merge(decoration: 'underline'), []]
|
101
|
+
]]
|
102
|
+
]
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
91
106
|
describe "fill/stroke modes" do
|
92
107
|
context "with a stroke and no fill" do
|
93
108
|
let(:svg) { '<text stroke="red" fill="none">stroked</text>' }
|
@@ -96,11 +111,11 @@ Even more
|
|
96
111
|
element.process
|
97
112
|
|
98
113
|
expect(element.base_calls).to eq [
|
99
|
-
["text_group", [], [
|
100
|
-
["stroke_color", ["ff0000"], []],
|
101
|
-
["font", ["Helvetica", {style: :normal}
|
102
|
-
["text_rendering_mode", [:stroke], [
|
103
|
-
["draw_text", ["stroked", default_style
|
114
|
+
["text_group", [], {}, [
|
115
|
+
["stroke_color", ["ff0000"], {}, []],
|
116
|
+
["font", ["Helvetica"], {style: :normal}, []],
|
117
|
+
["text_rendering_mode", [:stroke], {}, [
|
118
|
+
["draw_text", ["stroked"], default_style, []]
|
104
119
|
]]
|
105
120
|
]]
|
106
121
|
]
|
@@ -114,24 +129,24 @@ Even more
|
|
114
129
|
element.process
|
115
130
|
|
116
131
|
expect(element.base_calls).to eq [
|
117
|
-
["text_group", [], [
|
118
|
-
["stroke_color", ["ff0000"], []],
|
119
|
-
["font", ["Helvetica", {style: :normal}
|
120
|
-
["text_rendering_mode", [:stroke], [
|
121
|
-
["draw_text", ["stroked ", default_style
|
122
|
-
["save", [], []],
|
123
|
-
["fill_color", ["000000"], []],
|
124
|
-
["font", ["Helvetica", {style: :normal}
|
125
|
-
["text_rendering_mode", [:fill_stroke], [
|
126
|
-
["draw_text", ["both", default_style
|
132
|
+
["text_group", [], {}, [
|
133
|
+
["stroke_color", ["ff0000"], {}, []],
|
134
|
+
["font", ["Helvetica"], {style: :normal}, []],
|
135
|
+
["text_rendering_mode", [:stroke], {}, [
|
136
|
+
["draw_text", ["stroked "], default_style, []],
|
137
|
+
["save", [], {}, []],
|
138
|
+
["fill_color", ["000000"], {}, []],
|
139
|
+
["font", ["Helvetica"], {style: :normal}, []],
|
140
|
+
["text_rendering_mode", [:fill_stroke], {}, [
|
141
|
+
["draw_text", ["both"], default_style, []]
|
127
142
|
]],
|
128
|
-
["restore", [], []],
|
129
|
-
["save", [], []],
|
130
|
-
["font", ["Helvetica", {style: :normal}
|
131
|
-
["text_rendering_mode", [:invisible], [
|
132
|
-
["draw_text", ["neither", default_style
|
143
|
+
["restore", [], {}, []],
|
144
|
+
["save", [], {}, []],
|
145
|
+
["font", ["Helvetica"], {style: :normal}, []],
|
146
|
+
["text_rendering_mode", [:invisible], {}, [
|
147
|
+
["draw_text", ["neither"], default_style, []]
|
133
148
|
]],
|
134
|
-
["restore", [], []],
|
149
|
+
["restore", [], {}, []],
|
135
150
|
]]
|
136
151
|
]]
|
137
152
|
]
|
@@ -145,7 +160,7 @@ Even more
|
|
145
160
|
|
146
161
|
it "finds the font and uses it" do
|
147
162
|
element.process
|
148
|
-
expect(flatten_calls(element.base_calls)).to include ['font', ['Courier', {style: :normal}]
|
163
|
+
expect(flatten_calls(element.base_calls)).to include ['font', ['Courier'], {style: :normal}]
|
149
164
|
end
|
150
165
|
end
|
151
166
|
|
@@ -154,7 +169,7 @@ Even more
|
|
154
169
|
|
155
170
|
it "uses the fallback font" do
|
156
171
|
element.process
|
157
|
-
expect(flatten_calls(element.base_calls)).to include ['font', ['Times-Roman', {style: :normal}]
|
172
|
+
expect(flatten_calls(element.base_calls)).to include ['font', ['Times-Roman'], {style: :normal}]
|
158
173
|
end
|
159
174
|
|
160
175
|
context "when there is no fallback font" do
|
@@ -176,9 +191,9 @@ Even more
|
|
176
191
|
it "references the text" do
|
177
192
|
element.process
|
178
193
|
expect(flatten_calls(element.base_calls)[9..11]).to eq [
|
179
|
-
["fill_color", ["ff0000"]],
|
180
|
-
["font", ["Helvetica", {:style=>:normal}]
|
181
|
-
["draw_text", ["my reference text", {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[10.0, :relative], :offset=>[0,0]}]
|
194
|
+
["fill_color", ["ff0000"], {}],
|
195
|
+
["font", ["Helvetica"], {:style=>:normal}],
|
196
|
+
["draw_text", ["my reference text"], {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[10.0, :relative], :offset=>[0,0]}],
|
182
197
|
]
|
183
198
|
end
|
184
199
|
end
|
@@ -190,11 +205,11 @@ Even more
|
|
190
205
|
element.process
|
191
206
|
|
192
207
|
expect(flatten_calls(element.base_calls)).to eq [
|
193
|
-
["text_group", []],
|
194
|
-
["font", ["Helvetica", {:style=>:normal}]
|
195
|
-
["draw_text", ["H", {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[10.0, :relative], :offset=>[30.0, 2.0]}]
|
196
|
-
["draw_text", ["i", {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[20.0, :relative], :offset=>[50.0, 0]}]
|
197
|
-
["draw_text", [" there, this is a good test", {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[:relative, :relative], :offset=>[80.0, 0]}]
|
208
|
+
["text_group", [], {}],
|
209
|
+
["font", ["Helvetica"], {:style=>:normal}],
|
210
|
+
["draw_text", ["H"], {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[10.0, :relative], :offset=>[30.0, 2.0]}],
|
211
|
+
["draw_text", ["i"], {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[20.0, :relative], :offset=>[50.0, 0]}],
|
212
|
+
["draw_text", [" there, this is a good test"], {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[:relative, :relative], :offset=>[80.0, 0]}]
|
198
213
|
]
|
199
214
|
end
|
200
215
|
end
|
@@ -206,19 +221,19 @@ Even more
|
|
206
221
|
element.process
|
207
222
|
|
208
223
|
expect(flatten_calls(element.base_calls)).to eq [
|
209
|
-
["text_group", []],
|
210
|
-
["font", ["Helvetica", {:style=>:normal}]
|
211
|
-
["draw_text", ["H", {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[:relative, :relative], :offset=>[0, 0], :rotate=>-10.0}]
|
212
|
-
["draw_text", ["i", {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[:relative, :relative], :offset=>[0, 0], :rotate=>-20.0}]
|
213
|
-
["draw_text", [" ", {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[:relative, :relative], :offset=>[0, 0], :rotate=>-30.0}]
|
214
|
-
["save", []],
|
215
|
-
["font", ["Helvetica", {:style=>:normal}]
|
216
|
-
["draw_text", ["this", {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[:relative, :relative], :offset=>[0, 0]}]
|
217
|
-
["restore", []],
|
218
|
-
["draw_text", [" ", {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[:relative, :relative], :offset=>[0, 0], :rotate=>-80.0}]
|
219
|
-
["draw_text", ["o", {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[:relative, :relative], :offset=>[0, 0], :rotate=>-90.0}]
|
220
|
-
["draw_text", ["k", {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[:relative, :relative], :offset=>[0, 0], :rotate=>-100.0}]
|
221
|
-
["draw_text", ["!", {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[:relative, :relative], :offset=>[0, 0], :rotate=>-100.0}]
|
224
|
+
["text_group", [], {}],
|
225
|
+
["font", ["Helvetica"], {:style=>:normal}],
|
226
|
+
["draw_text", ["H"], {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[:relative, :relative], :offset=>[0, 0], :rotate=>-10.0}],
|
227
|
+
["draw_text", ["i"], {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[:relative, :relative], :offset=>[0, 0], :rotate=>-20.0}],
|
228
|
+
["draw_text", [" "], {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[:relative, :relative], :offset=>[0, 0], :rotate=>-30.0}],
|
229
|
+
["save", [], {}],
|
230
|
+
["font", ["Helvetica"], {:style=>:normal}],
|
231
|
+
["draw_text", ["this"], {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[:relative, :relative], :offset=>[0, 0]}],
|
232
|
+
["restore", [], {}],
|
233
|
+
["draw_text", [" "], {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[:relative, :relative], :offset=>[0, 0], :rotate=>-80.0}],
|
234
|
+
["draw_text", ["o"], {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[:relative, :relative], :offset=>[0, 0], :rotate=>-90.0}],
|
235
|
+
["draw_text", ["k"], {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[:relative, :relative], :offset=>[0, 0], :rotate=>-100.0}],
|
236
|
+
["draw_text", ["!"], {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[:relative, :relative], :offset=>[0, 0], :rotate=>-100.0}]
|
222
237
|
]
|
223
238
|
end
|
224
239
|
end
|
@@ -29,6 +29,14 @@ RSpec.describe Prawn::SVG::Loaders::Data do
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
+
context "with a data URL that's uppercase" do
|
33
|
+
let(:url) { "DATA:IMAGE/PNG;BASE64;METADATA;HERE,aGVsbG8=" }
|
34
|
+
|
35
|
+
it "loads the data" do
|
36
|
+
expect(subject).to eq "hello"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
32
40
|
context "with a URL that's not a data scheme" do
|
33
41
|
let(:url) { "http://some.host" }
|
34
42
|
|
@@ -40,10 +40,10 @@ RSpec.describe Prawn::SVG::Pathable do
|
|
40
40
|
subject.apply_commands
|
41
41
|
|
42
42
|
expect(subject.base_calls).to eq [
|
43
|
-
["move_to", [[10.0, 590.0]], []],
|
44
|
-
["line_to", [[20.0, 580.0]], []],
|
45
|
-
["curve_to", [[30.0, 570.0], {bounds: [[25.0, 580.0], [25.0, 575.0]]}
|
46
|
-
["close_path", [], []]
|
43
|
+
["move_to", [[10.0, 590.0]], {}, []],
|
44
|
+
["line_to", [[20.0, 580.0]], {}, []],
|
45
|
+
["curve_to", [[30.0, 570.0]], {bounds: [[25.0, 580.0], [25.0, 575.0]]}, []],
|
46
|
+
["close_path", [], {}, []]
|
47
47
|
]
|
48
48
|
end
|
49
49
|
end
|