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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +18 -0
  3. data/LICENSE +1 -1
  4. data/README.md +10 -9
  5. data/lib/prawn/svg/attributes/opacity.rb +4 -4
  6. data/lib/prawn/svg/attributes/transform.rb +2 -44
  7. data/lib/prawn/svg/elements/base.rb +11 -5
  8. data/lib/prawn/svg/elements/call_duplicator.rb +1 -1
  9. data/lib/prawn/svg/elements/gradient.rb +83 -25
  10. data/lib/prawn/svg/elements/image.rb +2 -2
  11. data/lib/prawn/svg/elements/path.rb +42 -29
  12. data/lib/prawn/svg/elements/root.rb +4 -1
  13. data/lib/prawn/svg/elements/text_component.rb +21 -5
  14. data/lib/prawn/svg/elements/use.rb +23 -7
  15. data/lib/prawn/svg/elements.rb +2 -0
  16. data/lib/prawn/svg/extensions/additional_gradient_transforms.rb +23 -0
  17. data/lib/prawn/svg/interface.rb +38 -8
  18. data/lib/prawn/svg/loaders/data.rb +1 -1
  19. data/lib/prawn/svg/loaders/file.rb +3 -1
  20. data/lib/prawn/svg/properties.rb +1 -0
  21. data/lib/prawn/svg/transform_parser.rb +72 -0
  22. data/lib/prawn/svg/version.rb +1 -1
  23. data/lib/prawn-svg.rb +4 -0
  24. data/prawn-svg.gemspec +3 -2
  25. data/spec/integration_spec.rb +24 -24
  26. data/spec/prawn/svg/attributes/opacity_spec.rb +85 -0
  27. data/spec/prawn/svg/attributes/transform_spec.rb +30 -35
  28. data/spec/prawn/svg/css/stylesheets_spec.rb +1 -19
  29. data/spec/prawn/svg/elements/base_spec.rb +16 -16
  30. data/spec/prawn/svg/elements/gradient_spec.rb +79 -4
  31. data/spec/prawn/svg/elements/line_spec.rb +12 -12
  32. data/spec/prawn/svg/elements/marker_spec.rb +27 -27
  33. data/spec/prawn/svg/elements/path_spec.rb +29 -17
  34. data/spec/prawn/svg/elements/polygon_spec.rb +9 -9
  35. data/spec/prawn/svg/elements/polyline_spec.rb +7 -7
  36. data/spec/prawn/svg/elements/text_spec.rb +65 -50
  37. data/spec/prawn/svg/loaders/data_spec.rb +8 -0
  38. data/spec/prawn/svg/pathable_spec.rb +4 -4
  39. data/spec/prawn/svg/transform_parser_spec.rb +94 -0
  40. data/spec/sample_svg/double_opacity.svg +6 -0
  41. data/spec/sample_svg/gradient_transform.svg +19 -0
  42. data/spec/sample_svg/links.svg +18 -0
  43. data/spec/sample_svg/radgrad01-bounding.svg +26 -0
  44. data/spec/sample_svg/radgrad01.svg +26 -0
  45. data/spec/sample_svg/svg_fill.svg +5 -0
  46. data/spec/sample_svg/text-decoration.svg +4 -0
  47. data/spec/sample_svg/transform.svg +20 -0
  48. data/spec/sample_svg/use_disordered.svg +17 -0
  49. data/spec/spec_helper.rb +2 -2
  50. metadata +48 -10
  51. 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 "user space on use" do
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) { "A12.34 -56.78 89B4 5 12-34 -.5.7+3 2.3e3 4e4 4e+4 c31,-2e-5C 6,7 T QX 0 Z" }
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.stub(:parse_path_command) {|*args| calls << args}
18
+ allow(path).to receive(:parse_path_command) {|*args| calls << args}
19
19
  path.parse
20
20
 
21
- calls.should == [
22
- ["A", [12.34, -56.78, 89]],
23
- ["B", [4, 5, 12, -34, -0.5, 0.7, 3, 2.3e3, 4e4, 4e4]],
24
- ["c", [31, -2e-5]],
25
- ["C", [6, 7]],
26
- ["T", []],
27
- ["Q", []],
28
- ["X", [0]],
29
- ["Z", []]
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.should_receive(:parse_path_command).with(*args).and_call_original
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.should_not_receive(:run_path_command)
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