prawn-svg 0.24.0 → 0.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +13 -9
- data/lib/prawn/svg/attributes.rb +1 -1
- data/lib/prawn/svg/attributes/space.rb +10 -0
- data/lib/prawn/svg/attributes/stroke.rb +2 -2
- data/lib/prawn/svg/attributes/transform.rb +2 -2
- data/lib/prawn/svg/calculators/document_sizing.rb +4 -5
- data/lib/prawn/svg/calculators/pixels.rb +27 -3
- data/lib/prawn/svg/document.rb +0 -18
- data/lib/prawn/svg/elements.rb +2 -2
- data/lib/prawn/svg/elements/base.rb +14 -2
- data/lib/prawn/svg/elements/circle.rb +1 -1
- data/lib/prawn/svg/elements/depth_first_base.rb +52 -0
- data/lib/prawn/svg/elements/ellipse.rb +2 -2
- data/lib/prawn/svg/elements/image.rb +2 -2
- data/lib/prawn/svg/elements/line.rb +4 -4
- data/lib/prawn/svg/elements/marker.rb +2 -2
- data/lib/prawn/svg/elements/rect.rb +3 -3
- data/lib/prawn/svg/elements/root.rb +5 -1
- data/lib/prawn/svg/elements/text.rb +47 -85
- data/lib/prawn/svg/elements/text_component.rb +186 -0
- data/lib/prawn/svg/elements/use.rb +1 -1
- data/lib/prawn/svg/elements/viewport.rb +28 -0
- data/lib/prawn/svg/interface.rb +20 -12
- data/lib/prawn/svg/pathable.rb +18 -2
- data/lib/prawn/svg/state.rb +3 -2
- data/lib/prawn/svg/version.rb +1 -1
- data/spec/prawn/svg/attributes/transform_spec.rb +2 -2
- data/spec/prawn/svg/calculators/pixels_spec.rb +72 -0
- data/spec/prawn/svg/document_spec.rb +0 -28
- data/spec/prawn/svg/elements/base_spec.rb +1 -1
- data/spec/prawn/svg/elements/gradient_spec.rb +1 -1
- data/spec/prawn/svg/elements/line_spec.rb +1 -1
- data/spec/prawn/svg/elements/marker_spec.rb +4 -0
- data/spec/prawn/svg/elements/text_spec.rb +104 -15
- data/spec/sample_svg/markers_degenerate_cp.svg +19 -0
- data/spec/sample_svg/offset_viewport.svg +8 -0
- data/spec/sample_svg/subviewports.svg +173 -0
- data/spec/sample_svg/subviewports2.svg +16 -0
- data/spec/sample_svg/tref01.svg +21 -0
- data/spec/sample_svg/tspan05.svg +40 -0
- data/spec/sample_svg/tspan91.svg +34 -0
- data/spec/spec_helper.rb +6 -0
- metadata +22 -2
@@ -0,0 +1,186 @@
|
|
1
|
+
class Prawn::SVG::Elements::TextComponent < Prawn::SVG::Elements::DepthFirstBase
|
2
|
+
attr_reader :commands
|
3
|
+
|
4
|
+
Printable = Struct.new(:element, :text, :leading_space?, :trailing_space?)
|
5
|
+
PositionsList = Struct.new(:x, :y, :dx, :dy, :rotation, :parent)
|
6
|
+
|
7
|
+
def parse
|
8
|
+
state.text.x = attributes['x'].split(COMMA_WSP_REGEXP).collect {|n| x(n)} if attributes['x']
|
9
|
+
state.text.y = attributes['y'].split(COMMA_WSP_REGEXP).collect {|n| y(n)} if attributes['y']
|
10
|
+
state.text.dx = attributes['dx'].split(COMMA_WSP_REGEXP).collect {|n| x_pixels(n)} if attributes['dx']
|
11
|
+
state.text.dy = attributes['dy'].split(COMMA_WSP_REGEXP).collect {|n| y_pixels(n)} if attributes['dy']
|
12
|
+
state.text.rotation = attributes['rotate'].split(COMMA_WSP_REGEXP).collect(&:to_f) if attributes['rotate']
|
13
|
+
|
14
|
+
@commands = []
|
15
|
+
|
16
|
+
text_children.each do |child|
|
17
|
+
if child.node_type == :text
|
18
|
+
append_text(child)
|
19
|
+
else
|
20
|
+
case child.name
|
21
|
+
when 'tspan', 'tref'
|
22
|
+
append_child(child)
|
23
|
+
else
|
24
|
+
warnings << "Unknown tag '#{child.name}' inside text tag; ignoring"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def apply
|
31
|
+
raise SkipElementQuietly if computed_properties.display == "none"
|
32
|
+
|
33
|
+
font = select_font
|
34
|
+
apply_font(font) if font
|
35
|
+
|
36
|
+
# text_anchor isn't a Prawn option; we have to do some math to support it
|
37
|
+
# and so we handle this in Prawn::SVG::Interface#rewrite_call_arguments
|
38
|
+
opts = {
|
39
|
+
size: computed_properties.numerical_font_size,
|
40
|
+
style: font && font.subfamily,
|
41
|
+
text_anchor: computed_properties.text_anchor
|
42
|
+
}
|
43
|
+
|
44
|
+
spacing = computed_properties.letter_spacing
|
45
|
+
spacing = spacing == 'normal' ? 0 : pixels(spacing)
|
46
|
+
|
47
|
+
add_call_and_enter 'character_spacing', spacing
|
48
|
+
|
49
|
+
@commands.each do |command|
|
50
|
+
case command
|
51
|
+
when Printable
|
52
|
+
apply_text(command.text, opts)
|
53
|
+
when self.class
|
54
|
+
add_call 'save'
|
55
|
+
command.apply_step(calls)
|
56
|
+
add_call 'restore'
|
57
|
+
else
|
58
|
+
raise
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# It's possible there was no text to render. In that case, add a 'noop' so
|
63
|
+
# character_spacing doesn't blow up when it finds it doesn't have a block to execute.
|
64
|
+
add_call 'noop' if calls.empty?
|
65
|
+
end
|
66
|
+
|
67
|
+
protected
|
68
|
+
|
69
|
+
def append_text(child)
|
70
|
+
if state.preserve_space
|
71
|
+
text = child.value.tr("\n\t", ' ')
|
72
|
+
else
|
73
|
+
text = child.value.tr("\n", '').tr("\t", ' ')
|
74
|
+
leading = text[0] == ' '
|
75
|
+
trailing = text[-1] == ' '
|
76
|
+
text = text.strip.gsub(/ {2,}/, ' ')
|
77
|
+
end
|
78
|
+
|
79
|
+
@commands << Printable.new(self, text, leading, trailing)
|
80
|
+
end
|
81
|
+
|
82
|
+
def append_child(child)
|
83
|
+
new_state = state.dup
|
84
|
+
new_state.text = PositionsList.new([], [], [], [], [], state.text)
|
85
|
+
|
86
|
+
element = self.class.new(document, child, calls, new_state)
|
87
|
+
@commands << element
|
88
|
+
element.parse_step
|
89
|
+
end
|
90
|
+
|
91
|
+
def apply_text(text, opts)
|
92
|
+
while text != ""
|
93
|
+
x = y = dx = dy = rotate = nil
|
94
|
+
remaining = rotation_remaining = false
|
95
|
+
|
96
|
+
list = state.text
|
97
|
+
while list
|
98
|
+
shifted = list.x.shift
|
99
|
+
x ||= shifted
|
100
|
+
shifted = list.y.shift
|
101
|
+
y ||= shifted
|
102
|
+
shifted = list.dx.shift
|
103
|
+
dx ||= shifted
|
104
|
+
shifted = list.dy.shift
|
105
|
+
dy ||= shifted
|
106
|
+
|
107
|
+
shifted = list.rotation.length > 1 ? list.rotation.shift : list.rotation.first
|
108
|
+
if shifted && rotate.nil?
|
109
|
+
rotate = shifted
|
110
|
+
remaining ||= list.rotation != [0]
|
111
|
+
end
|
112
|
+
|
113
|
+
remaining ||= list.x.any? || list.y.any? || list.dx.any? || list.dy.any? || (rotate && rotate != 0)
|
114
|
+
rotation_remaining ||= list.rotation.length > 1
|
115
|
+
list = list.parent
|
116
|
+
end
|
117
|
+
|
118
|
+
opts[:at] = [x || :relative, y || :relative]
|
119
|
+
opts[:offset] = [dx || 0, dy || 0]
|
120
|
+
|
121
|
+
if rotate && rotate != 0
|
122
|
+
opts[:rotate] = -rotate
|
123
|
+
else
|
124
|
+
opts.delete(:rotate)
|
125
|
+
end
|
126
|
+
|
127
|
+
if remaining
|
128
|
+
add_call 'draw_text', text[0..0], opts.dup
|
129
|
+
text = text[1..-1]
|
130
|
+
else
|
131
|
+
add_call 'draw_text', text, opts.dup
|
132
|
+
|
133
|
+
# we can get to this path with rotations still pending
|
134
|
+
# solve this by shifting them out by the number of
|
135
|
+
# characters we've just drawn
|
136
|
+
shift = text.length - 1
|
137
|
+
if rotation_remaining && shift > 0
|
138
|
+
list = state.text
|
139
|
+
while list
|
140
|
+
count = [shift, list.rotation.length - 1].min
|
141
|
+
list.rotation.shift(count) if count > 0
|
142
|
+
list = list.parent
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
break
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def text_children
|
152
|
+
if name == 'tref'
|
153
|
+
reference = find_referenced_element
|
154
|
+
reference ? reference.source.children : []
|
155
|
+
else
|
156
|
+
source.children
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def find_referenced_element
|
161
|
+
href = attributes['xlink:href']
|
162
|
+
|
163
|
+
if href && href[0..0] == '#'
|
164
|
+
element = document.elements_by_id[href[1..-1]]
|
165
|
+
element if element.name == 'text'
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def select_font
|
170
|
+
font_families = [computed_properties.font_family, document.fallback_font_name]
|
171
|
+
font_style = :italic if computed_properties.font_style == 'italic'
|
172
|
+
font_weight = Prawn::SVG::Font.weight_for_css_font_weight(computed_properties.font_weight)
|
173
|
+
|
174
|
+
font_families.compact.each do |name|
|
175
|
+
font = document.font_registry.load(name, font_weight, font_style)
|
176
|
+
return font if font
|
177
|
+
end
|
178
|
+
|
179
|
+
warnings << "Font family '#{computed_properties.font_family}' style '#{computed_properties.font_style}' is not a known font, and the fallback font could not be found."
|
180
|
+
nil
|
181
|
+
end
|
182
|
+
|
183
|
+
def apply_font(font)
|
184
|
+
add_call 'font', font.name, style: font.subfamily
|
185
|
+
end
|
186
|
+
end
|
@@ -21,7 +21,7 @@ class Prawn::SVG::Elements::Use < Prawn::SVG::Elements::Base
|
|
21
21
|
|
22
22
|
def apply
|
23
23
|
if @x || @y
|
24
|
-
add_call_and_enter "translate",
|
24
|
+
add_call_and_enter "translate", x_pixels(@x || 0), -y_pixels(@y || 0)
|
25
25
|
end
|
26
26
|
|
27
27
|
add_calls_from_element @definition_element
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class Prawn::SVG::Elements::Viewport < Prawn::SVG::Elements::Base
|
2
|
+
def parse
|
3
|
+
parent_dimensions = [state.viewport_sizing.viewport_width, state.viewport_sizing.viewport_height]
|
4
|
+
|
5
|
+
@sizing = Prawn::SVG::Calculators::DocumentSizing.new(parent_dimensions, attributes)
|
6
|
+
@sizing.calculate
|
7
|
+
|
8
|
+
@x = x_pixels(attributes['x'] || 0)
|
9
|
+
@y = y_pixels(attributes['y'] || 0)
|
10
|
+
|
11
|
+
state.viewport_sizing = @sizing
|
12
|
+
end
|
13
|
+
|
14
|
+
def apply
|
15
|
+
if @x != 0 || @y != 0
|
16
|
+
add_call 'transformation_matrix', 1, 0, 0, 1, @x, -@y
|
17
|
+
end
|
18
|
+
|
19
|
+
add_call 'rectangle', [0, y(0)], @sizing.output_width, @sizing.output_height
|
20
|
+
add_call 'clip'
|
21
|
+
add_call 'transformation_matrix', @sizing.x_scale, 0, 0, @sizing.y_scale, 0, 0
|
22
|
+
add_call 'transformation_matrix', 1, 0, 0, 1, -@sizing.x_offset, @sizing.y_offset
|
23
|
+
end
|
24
|
+
|
25
|
+
def container?
|
26
|
+
true
|
27
|
+
end
|
28
|
+
end
|
data/lib/prawn/svg/interface.rb
CHANGED
@@ -118,28 +118,36 @@ module Prawn
|
|
118
118
|
end
|
119
119
|
|
120
120
|
def rewrite_call_arguments(prawn, call, arguments)
|
121
|
-
if call == 'relative_draw_text'
|
122
|
-
call.replace "draw_text"
|
123
|
-
arguments.last[:at][0] = @relative_text_position if @relative_text_position
|
124
|
-
end
|
125
|
-
|
126
121
|
case call
|
127
122
|
when 'text_group'
|
128
|
-
@
|
123
|
+
@cursor = [0, document.sizing.output_height]
|
129
124
|
yield
|
130
125
|
|
131
126
|
when 'draw_text'
|
132
127
|
text, options = arguments
|
133
128
|
|
134
|
-
|
129
|
+
at = options.fetch(:at)
|
130
|
+
|
131
|
+
at[0] = @cursor[0] if at[0] == :relative
|
132
|
+
at[1] = @cursor[1] if at[1] == :relative
|
135
133
|
|
136
|
-
if
|
137
|
-
|
138
|
-
|
134
|
+
if offset = options.delete(:offset)
|
135
|
+
at[0] += offset[0]
|
136
|
+
at[1] -= offset[1]
|
139
137
|
end
|
140
138
|
|
141
|
-
|
142
|
-
|
139
|
+
width = prawn.width_of(text, options.merge(kerning: true))
|
140
|
+
|
141
|
+
case options.delete(:text_anchor)
|
142
|
+
when 'middle'
|
143
|
+
at[0] -= width / 2
|
144
|
+
@cursor = [at[0] + width / 2, at[1]]
|
145
|
+
when 'end'
|
146
|
+
at[0] -= width
|
147
|
+
@cursor = at.dup
|
148
|
+
else
|
149
|
+
@cursor = [at[0] + width, at[1]]
|
150
|
+
end
|
143
151
|
|
144
152
|
when 'transformation_matrix'
|
145
153
|
left = prawn.bounds.absolute_left
|
data/lib/prawn/svg/pathable.rb
CHANGED
@@ -60,8 +60,12 @@ module Prawn::SVG::Pathable
|
|
60
60
|
angle = Math.atan2(command.destination[1] - last_point[1], command.destination[0] - last_point[0]) * 180.0 / Math::PI
|
61
61
|
[angle, angle]
|
62
62
|
when Curve
|
63
|
-
|
64
|
-
|
63
|
+
point = select_non_equal_point(last_point, command.point1, command.point2, command.destination)
|
64
|
+
start = Math.atan2(point[1] - last_point[1], point[0] - last_point[0]) * 180.0 / Math::PI
|
65
|
+
|
66
|
+
point = select_non_equal_point(command.destination, command.point2, command.point1, last_point)
|
67
|
+
stop = Math.atan2(command.destination[1] - point[1], command.destination[0] - point[0]) * 180.0 / Math::PI
|
68
|
+
|
65
69
|
[start, stop]
|
66
70
|
else
|
67
71
|
raise NotImplementedError, "Unknown path command type"
|
@@ -127,4 +131,16 @@ module Prawn::SVG::Pathable
|
|
127
131
|
def translate(point)
|
128
132
|
[point[0].to_f, document.sizing.output_height - point[1].to_f]
|
129
133
|
end
|
134
|
+
|
135
|
+
private
|
136
|
+
|
137
|
+
def select_non_equal_point(base, point_a, point_b, point_c)
|
138
|
+
if point_a != base
|
139
|
+
point_a
|
140
|
+
elsif point_b != base
|
141
|
+
point_b
|
142
|
+
else
|
143
|
+
point_c
|
144
|
+
end
|
145
|
+
end
|
130
146
|
end
|
data/lib/prawn/svg/state.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
class Prawn::SVG::State
|
2
2
|
attr_accessor :disable_drawing,
|
3
|
-
:
|
3
|
+
:text, :preserve_space,
|
4
4
|
:fill_opacity, :stroke_opacity, :stroke_width,
|
5
|
-
:computed_properties
|
5
|
+
:computed_properties,
|
6
|
+
:viewport_sizing
|
6
7
|
|
7
8
|
def initialize
|
8
9
|
@stroke_width = 1
|
data/lib/prawn/svg/version.rb
CHANGED
@@ -20,8 +20,8 @@ describe Prawn::SVG::Attributes::Transform do
|
|
20
20
|
describe "translate" do
|
21
21
|
it "handles a missing y argument" do
|
22
22
|
expect(element).to receive(:add_call_and_enter).with('translate', -5.5, 0)
|
23
|
-
expect(element).to receive(:
|
24
|
-
expect(element).to receive(:
|
23
|
+
expect(element).to receive(:x_pixels).with(-5.5).and_return(-5.5)
|
24
|
+
expect(element).to receive(:y_pixels).with(0.0).and_return(0.0)
|
25
25
|
|
26
26
|
element.attributes['transform'] = 'translate(-5.5)'
|
27
27
|
subject
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Prawn::SVG::Calculators::Pixels do
|
4
|
+
class TestPixelsCalculator
|
5
|
+
include Prawn::SVG::Calculators::Pixels
|
6
|
+
|
7
|
+
[:x, :y, :pixels, :x_pixels, :y_pixels].each { |method| public method }
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:viewport_sizing) do
|
11
|
+
instance_double(Prawn::SVG::Calculators::DocumentSizing, viewport_width: 600, viewport_height: 400, viewport_diagonal: 500, :requested_width= => nil, :requested_height= => nil)
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:document_sizing) do
|
15
|
+
instance_double(Prawn::SVG::Calculators::DocumentSizing, output_height: 800)
|
16
|
+
end
|
17
|
+
|
18
|
+
let(:state) { instance_double(Prawn::SVG::State, viewport_sizing: viewport_sizing) }
|
19
|
+
let(:document) { instance_double(Prawn::SVG::Document, sizing: document_sizing) }
|
20
|
+
|
21
|
+
subject { TestPixelsCalculator.new }
|
22
|
+
|
23
|
+
before do
|
24
|
+
allow(subject).to receive(:state).and_return(state)
|
25
|
+
allow(subject).to receive(:document).and_return(document)
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#pixels" do
|
29
|
+
it "converts a variety of measurement units to points" do
|
30
|
+
expect(subject.pixels(32)).to eq 32.0
|
31
|
+
expect(subject.pixels(32.0)).to eq 32.0
|
32
|
+
expect(subject.pixels("32")).to eq 32.0
|
33
|
+
expect(subject.pixels("32unknown")).to eq 32.0
|
34
|
+
expect(subject.pixels("32pt")).to eq 32.0
|
35
|
+
expect(subject.pixels("32in")).to eq 32.0 * 72
|
36
|
+
expect(subject.pixels("32ft")).to eq 32.0 * 72 * 12
|
37
|
+
expect(subject.pixels("32pc")).to eq 32.0 * 15
|
38
|
+
expect(subject.pixels("32mm")).to be_within(0.0001).of(32 * 72 * 0.0393700787)
|
39
|
+
expect(subject.pixels("32cm")).to be_within(0.0001).of(32 * 72 * 0.393700787)
|
40
|
+
expect(subject.pixels("32m")).to be_within(0.0001).of(32 * 72 * 39.3700787)
|
41
|
+
expect(subject.pixels("50%")).to eq 250
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "#x_pixels" do
|
46
|
+
it "uses the viewport width for percentages" do
|
47
|
+
expect(subject.x_pixels("50")).to eq 50
|
48
|
+
expect(subject.x_pixels("50%")).to eq 300
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "#y_pixels" do
|
53
|
+
it "uses the viewport height for percentages" do
|
54
|
+
expect(subject.y_pixels("50")).to eq 50
|
55
|
+
expect(subject.y_pixels("50%")).to eq 200
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "#x" do
|
60
|
+
it "performs the same as #x_pixels" do
|
61
|
+
expect(subject.x("50")).to eq 50
|
62
|
+
expect(subject.x("50%")).to eq 300
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "#y" do
|
67
|
+
it "performs the same as #y_pixels but subtracts the pixels from the page height" do
|
68
|
+
expect(subject.y("50")).to eq 800 - 50
|
69
|
+
expect(subject.y("50%")).to eq 800 - 200
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -25,32 +25,4 @@ describe Prawn::SVG::Document do
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
28
|
-
|
29
|
-
describe "#points" do
|
30
|
-
before do
|
31
|
-
sizing = instance_double(Prawn::SVG::Calculators::DocumentSizing, viewport_width: 600, viewport_height: 400, viewport_diagonal: 500, :requested_width= => nil, :requested_height= => nil)
|
32
|
-
expect(sizing).to receive(:calculate)
|
33
|
-
expect(Prawn::SVG::Calculators::DocumentSizing).to receive(:new).and_return(sizing)
|
34
|
-
end
|
35
|
-
|
36
|
-
let(:document) { Prawn::SVG::Document.new("<svg></svg>", [100, 100], {}) }
|
37
|
-
|
38
|
-
it "converts a variety of measurement units to points" do
|
39
|
-
document.send(:points, 32).should == 32.0
|
40
|
-
document.send(:points, 32.0).should == 32.0
|
41
|
-
document.send(:points, "32").should == 32.0
|
42
|
-
document.send(:points, "32unknown").should == 32.0
|
43
|
-
document.send(:points, "32pt").should == 32.0
|
44
|
-
document.send(:points, "32in").should == 32.0 * 72
|
45
|
-
document.send(:points, "32ft").should == 32.0 * 72 * 12
|
46
|
-
document.send(:points, "32pc").should == 32.0 * 15
|
47
|
-
document.send(:points, "32mm").should be_within(0.0001).of(32 * 72 * 0.0393700787)
|
48
|
-
document.send(:points, "32cm").should be_within(0.0001).of(32 * 72 * 0.393700787)
|
49
|
-
document.send(:points, "32m").should be_within(0.0001).of(32 * 72 * 39.3700787)
|
50
|
-
|
51
|
-
document.send(:points, "50%").should == 250
|
52
|
-
document.send(:points, "50%", :x).should == 300
|
53
|
-
document.send(:points, "50%", :y).should == 200
|
54
|
-
end
|
55
|
-
end
|
56
28
|
end
|
@@ -4,7 +4,7 @@ describe Prawn::SVG::Elements::Base do
|
|
4
4
|
let(:svg) { "<svg></svg>" }
|
5
5
|
let(:document) { Prawn::SVG::Document.new(svg, [800, 600], {}, font_registry: Prawn::SVG::FontRegistry.new("Helvetica" => {:normal => nil})) }
|
6
6
|
let(:parent_calls) { [] }
|
7
|
-
let(:element) { Prawn::SVG::Elements::Base.new(document, document.root, parent_calls,
|
7
|
+
let(:element) { Prawn::SVG::Elements::Base.new(document, document.root, parent_calls, fake_state) }
|
8
8
|
|
9
9
|
describe "#initialize" do
|
10
10
|
let(:svg) { '<something id="hello"/>' }
|