prawn-svg 0.29.1 → 0.32.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.
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