prawn-svg 0.29.1 → 0.30.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/LICENSE +1 -1
- data/README.md +6 -5
- data/lib/prawn-svg.rb +4 -0
- data/lib/prawn/svg/attributes/opacity.rb +4 -4
- data/lib/prawn/svg/attributes/transform.rb +2 -44
- data/lib/prawn/svg/elements.rb +1 -0
- data/lib/prawn/svg/elements/base.rb +2 -0
- data/lib/prawn/svg/elements/gradient.rb +6 -5
- data/lib/prawn/svg/elements/path.rb +1 -0
- data/lib/prawn/svg/elements/text_component.rb +15 -1
- data/lib/prawn/svg/extensions/additional_gradient_transforms.rb +23 -0
- data/lib/prawn/svg/interface.rb +13 -0
- data/lib/prawn/svg/loaders/data.rb +1 -1
- data/lib/prawn/svg/loaders/file.rb +3 -1
- data/lib/prawn/svg/transform_parser.rb +72 -0
- data/lib/prawn/svg/version.rb +1 -1
- data/spec/prawn/svg/attributes/opacity_spec.rb +85 -0
- data/spec/prawn/svg/attributes/transform_spec.rb +30 -35
- data/spec/prawn/svg/elements/base_spec.rb +2 -2
- data/spec/prawn/svg/elements/gradient_spec.rb +26 -2
- data/spec/prawn/svg/loaders/data_spec.rb +8 -0
- 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/transform.svg +20 -0
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 34f48795bbd6ee32d7c18228b833137dc52cb5b02f0446de0e3908d0827e7234
|
4
|
+
data.tar.gz: 4f654b0c484f81ba80660940d2823c836c0aaba0156cb9e803c722170fdec993
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4bf2b53a65607c75da3907433b40e1f4aaee67a70268f562a3f6c554087ab7a66924874befc1da5a6954b86b71f0e32ab6bff5108f64f3582b677500dc0a2f8b
|
7
|
+
data.tar.gz: 25d862c9b5b6e25a3dc22ac581c2e04c025ff76b3f842033578f2565d8641f2a951d03e0a88c272e52f584c87fb27a2af90593ae6aea8d69c80ec4ec06d0b36a
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -60,7 +60,7 @@ prawn-svg supports most but not all of the full SVG 1.1 specification. It curre
|
|
60
60
|
- <tt><path></tt> supports all commands defined in SVG 1.1, although the
|
61
61
|
implementation of elliptical arc is a bit rough at the moment.
|
62
62
|
|
63
|
-
- `<text>`, `<tspan>` and `<tref>` with attributes `x`, `y`, `dx`, `dy`, `rotate`, and with extra properties
|
63
|
+
- `<text>`, `<tspan>` and `<tref>` with attributes `x`, `y`, `dx`, `dy`, `rotate`, 'textLength', 'lengthAdjust', and with extra properties
|
64
64
|
`text-anchor`, `font-size`, `font-family`, `font-weight`, `font-style`, `letter-spacing`
|
65
65
|
|
66
66
|
- <tt><svg></tt>, <tt><g></tt> and <tt><symbol></tt>
|
@@ -76,7 +76,7 @@ prawn-svg supports most but not all of the full SVG 1.1 specification. It curre
|
|
76
76
|
|
77
77
|
- `<marker>`
|
78
78
|
|
79
|
-
- `<linearGradient>` is implemented
|
79
|
+
- `<linearGradient>` is implemented on Prawn 2.2.0+ with attributes `gradientUnits` and `gradientTransform` (spreadMethod and stop-opacity are unimplemented.)
|
80
80
|
|
81
81
|
- `<switch>` and `<foreignObject>`, although prawn-svg cannot handle any data that is not SVG so `<foreignObject>`
|
82
82
|
tags are always ignored.
|
@@ -91,7 +91,7 @@ prawn-svg supports most but not all of the full SVG 1.1 specification. It curre
|
|
91
91
|
|
92
92
|
- the <tt>preserveAspectRatio</tt> attribute on <tt><svg></tt>, <tt><image></tt> and `<marker>` elements
|
93
93
|
|
94
|
-
- transform methods:
|
94
|
+
- transform methods: `translate`, `translateX`, `translateY`, `rotate`, `scale`, `skewX`, `skewY`, `matrix`
|
95
95
|
|
96
96
|
- colors: HTML standard names, <tt>#xxx</tt>, <tt>#xxxxxx</tt>, <tt>rgb(1, 2, 3)</tt>, <tt>rgb(1%, 2%, 3%)</tt>
|
97
97
|
|
@@ -135,5 +135,6 @@ Mac OS X and Debian Linux users. You can add to the font path:
|
|
135
135
|
|
136
136
|
In your Gemfile, put `gem 'prawn-svg'` before `gem 'prawn-rails'` so that prawn-rails can see the prawn-svg extension.
|
137
137
|
|
138
|
-
|
139
|
-
|
138
|
+
## Licence
|
139
|
+
|
140
|
+
MIT licence. Copyright Roger Nesbitt.
|
data/lib/prawn-svg.rb
CHANGED
@@ -10,6 +10,7 @@ require 'prawn/svg/calculators/arc_to_bezier_curve'
|
|
10
10
|
require 'prawn/svg/calculators/aspect_ratio'
|
11
11
|
require 'prawn/svg/calculators/document_sizing'
|
12
12
|
require 'prawn/svg/calculators/pixels'
|
13
|
+
require 'prawn/svg/transform_parser'
|
13
14
|
require 'prawn/svg/url_loader'
|
14
15
|
require 'prawn/svg/loaders/data'
|
15
16
|
require 'prawn/svg/loaders/file'
|
@@ -29,6 +30,9 @@ require 'prawn/svg/font'
|
|
29
30
|
require 'prawn/svg/document'
|
30
31
|
require 'prawn/svg/state'
|
31
32
|
|
33
|
+
require 'prawn/svg/extensions/additional_gradient_transforms'
|
34
|
+
Prawn::Document.prepend Prawn::SVG::Extensions::AdditionalGradientTransforms
|
35
|
+
|
32
36
|
module Prawn
|
33
37
|
Svg = SVG # backwards compatibility
|
34
38
|
end
|
@@ -1,13 +1,13 @@
|
|
1
1
|
module Prawn::SVG::Attributes::Opacity
|
2
2
|
def parse_opacity_attributes_and_call
|
3
3
|
# We can't do nested opacities quite like the SVG requires, but this is close enough.
|
4
|
-
|
4
|
+
opacity = clamp(properties.opacity.to_f, 0, 1) if properties.opacity
|
5
5
|
fill_opacity = clamp(properties.fill_opacity.to_f, 0, 1) if properties.fill_opacity
|
6
6
|
stroke_opacity = clamp(properties.stroke_opacity.to_f, 0, 1) if properties.stroke_opacity
|
7
7
|
|
8
|
-
if fill_opacity || stroke_opacity
|
9
|
-
state.fill_opacity *= fill_opacity || 1
|
10
|
-
state.stroke_opacity *= stroke_opacity || 1
|
8
|
+
if opacity || fill_opacity || stroke_opacity
|
9
|
+
state.fill_opacity *= [opacity || 1, fill_opacity || 1].min
|
10
|
+
state.stroke_opacity *= [opacity || 1, stroke_opacity || 1].min
|
11
11
|
|
12
12
|
add_call_and_enter 'transparent', state.fill_opacity, state.stroke_opacity
|
13
13
|
end
|
@@ -2,49 +2,7 @@ module Prawn::SVG::Attributes::Transform
|
|
2
2
|
def parse_transform_attribute_and_call
|
3
3
|
return unless transform = attributes['transform']
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
when 'translate'
|
8
|
-
x, y = arguments
|
9
|
-
add_call_and_enter name, x_pixels(x.to_f), -y_pixels(y.to_f)
|
10
|
-
|
11
|
-
when 'rotate'
|
12
|
-
r, x, y = arguments.collect {|a| a.to_f}
|
13
|
-
case arguments.length
|
14
|
-
when 1
|
15
|
-
add_call_and_enter name, -r, :origin => [0, y('0')]
|
16
|
-
when 3
|
17
|
-
add_call_and_enter name, -r, :origin => [x(x), y(y)]
|
18
|
-
else
|
19
|
-
warnings << "transform 'rotate' must have either one or three arguments"
|
20
|
-
end
|
21
|
-
|
22
|
-
when 'scale'
|
23
|
-
x_scale = arguments[0].to_f
|
24
|
-
y_scale = (arguments[1] || x_scale).to_f
|
25
|
-
add_call_and_enter "transformation_matrix", x_scale, 0, 0, y_scale, 0, 0
|
26
|
-
|
27
|
-
when 'matrix'
|
28
|
-
if arguments.length != 6
|
29
|
-
warnings << "transform 'matrix' must have six arguments"
|
30
|
-
else
|
31
|
-
a, b, c, d, e, f = arguments.collect {|argument| argument.to_f}
|
32
|
-
add_call_and_enter "transformation_matrix", a, -b, -c, d, x_pixels(e), -y_pixels(f)
|
33
|
-
end
|
34
|
-
|
35
|
-
else
|
36
|
-
warnings << "Unknown transformation '#{name}'; ignoring"
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
private
|
42
|
-
|
43
|
-
def parse_css_method_calls(string)
|
44
|
-
string.scan(/\s*(\w+)\(([^)]+)\)\s*/).collect do |call|
|
45
|
-
name, argument_string = call
|
46
|
-
arguments = argument_string.strip.split(/\s*[,\s]\s*/)
|
47
|
-
[name, arguments]
|
48
|
-
end
|
5
|
+
matrix = parse_transform_attribute(transform)
|
6
|
+
add_call_and_enter "transformation_matrix", *matrix unless matrix == [1, 0, 0, 1, 0, 0]
|
49
7
|
end
|
50
8
|
end
|
data/lib/prawn/svg/elements.rb
CHANGED
@@ -13,6 +13,7 @@ module Prawn::SVG::Elements
|
|
13
13
|
g: Prawn::SVG::Elements::Container,
|
14
14
|
symbol: Prawn::SVG::Elements::Container,
|
15
15
|
defs: Prawn::SVG::Elements::Container,
|
16
|
+
a: Prawn::SVG::Elements::Container,
|
16
17
|
clipPath: Prawn::SVG::Elements::ClipPath,
|
17
18
|
switch: Prawn::SVG::Elements::Container,
|
18
19
|
svg: Prawn::SVG::Elements::Viewport,
|
@@ -11,6 +11,8 @@ class Prawn::SVG::Elements::Base
|
|
11
11
|
include Prawn::SVG::Attributes::Stroke
|
12
12
|
include Prawn::SVG::Attributes::Space
|
13
13
|
|
14
|
+
include Prawn::SVG::TransformParser
|
15
|
+
|
14
16
|
PAINT_TYPES = %w(fill stroke)
|
15
17
|
COMMA_WSP_REGEXP = Prawn::SVG::Elements::COMMA_WSP_REGEXP
|
16
18
|
SVG_NAMESPACE = "http://www.w3.org/2000/svg"
|
@@ -32,7 +32,11 @@ class Prawn::SVG::Elements::Gradient < Prawn::SVG::Elements::Base
|
|
32
32
|
to = [@x2, @y2]
|
33
33
|
end
|
34
34
|
|
35
|
-
|
35
|
+
# Passing in a transformation matrix to the apply_transformations option is supported
|
36
|
+
# by a monkey patch installed by prawn-svg. Prawn only sees this as a truthy variable.
|
37
|
+
#
|
38
|
+
# See Prawn::SVG::Extensions::AdditionalGradientTransforms for details.
|
39
|
+
{from: from, to: to, stops: @stops, apply_transformations: @transform_matrix || true}
|
36
40
|
end
|
37
41
|
|
38
42
|
private
|
@@ -51,10 +55,7 @@ class Prawn::SVG::Elements::Gradient < Prawn::SVG::Elements::Base
|
|
51
55
|
@units = attributes["gradientUnits"] == 'userSpaceOnUse' ? :user_space : :bounding_box
|
52
56
|
|
53
57
|
if transform = attributes["gradientTransform"]
|
54
|
-
|
55
|
-
if matrix != [1, 0, 0, 1, 0, 0]
|
56
|
-
raise SkipElementError, "prawn-svg does not yet support gradients with a non-identity gradientTransform attribute"
|
57
|
-
end
|
58
|
+
@transform_matrix = parse_transform_attribute(transform)
|
58
59
|
end
|
59
60
|
|
60
61
|
if (spread_method = attributes['spreadMethod']) && spread_method != "pad"
|
@@ -2,7 +2,7 @@ class Prawn::SVG::Elements::TextComponent < Prawn::SVG::Elements::DepthFirstBase
|
|
2
2
|
attr_reader :commands
|
3
3
|
|
4
4
|
Printable = Struct.new(:element, :text, :leading_space?, :trailing_space?)
|
5
|
-
TextState = Struct.new(:parent, :x, :y, :dx, :dy, :rotation, :spacing, :mode)
|
5
|
+
TextState = Struct.new(:parent, :x, :y, :dx, :dy, :rotation, :spacing, :mode, :text_length, :length_adjust)
|
6
6
|
|
7
7
|
def parse
|
8
8
|
if state.inside_clip_path
|
@@ -14,6 +14,8 @@ class Prawn::SVG::Elements::TextComponent < Prawn::SVG::Elements::DepthFirstBase
|
|
14
14
|
state.text.dx = (attributes['dx'] || "").split(COMMA_WSP_REGEXP).collect { |n| x_pixels(n) }
|
15
15
|
state.text.dy = (attributes['dy'] || "").split(COMMA_WSP_REGEXP).collect { |n| y_pixels(n) }
|
16
16
|
state.text.rotation = (attributes['rotate'] || "").split(COMMA_WSP_REGEXP).collect(&:to_f)
|
17
|
+
state.text.text_length = normalize_length(attributes['textLength'])
|
18
|
+
state.text.length_adjust = attributes['lengthAdjust']
|
17
19
|
state.text.spacing = calculate_character_spacing
|
18
20
|
state.text.mode = calculate_text_rendering_mode
|
19
21
|
|
@@ -133,6 +135,14 @@ class Prawn::SVG::Elements::TextComponent < Prawn::SVG::Elements::DepthFirstBase
|
|
133
135
|
opts.delete(:rotate)
|
134
136
|
end
|
135
137
|
|
138
|
+
if state.text.text_length
|
139
|
+
if state.text.length_adjust == 'spacingAndGlyphs'
|
140
|
+
opts[:stretch_to_width] = state.text.text_length
|
141
|
+
else
|
142
|
+
opts[:pad_to_width] = state.text.text_length
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
136
146
|
if remaining
|
137
147
|
add_call 'draw_text', text[0..0], opts.dup
|
138
148
|
text = text[1..-1]
|
@@ -222,4 +232,8 @@ class Prawn::SVG::Elements::TextComponent < Prawn::SVG::Elements::DepthFirstBase
|
|
222
232
|
# overridden, we don't want to call fill/stroke as draw_text does this for us
|
223
233
|
def apply_drawing_call
|
224
234
|
end
|
235
|
+
|
236
|
+
def normalize_length(length)
|
237
|
+
x_pixels(length) if length && length.match(/\d/)
|
238
|
+
end
|
225
239
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Prawn::SVG::Extensions
|
2
|
+
module AdditionalGradientTransforms
|
3
|
+
def gradient_coordinates(gradient)
|
4
|
+
# As of Prawn 2.2.0, apply_transformations is used as purely a boolean.
|
5
|
+
#
|
6
|
+
# Here we're using it to optionally pass in a 6-tuple transformation matrix that gets applied to the
|
7
|
+
# gradient. This should be added to Prawn properly, and then this monkey patch will not be necessary.
|
8
|
+
|
9
|
+
if gradient.apply_transformations.is_a?(Array)
|
10
|
+
x1, y1, x2, y2, transformation = super
|
11
|
+
a, b, c, d, e, f = transformation
|
12
|
+
na, nb, nc, nd, ne, nf = gradient.apply_transformations
|
13
|
+
|
14
|
+
matrix = Matrix[[a, c, e], [b, d, f], [0, 0, 1]] * Matrix[[na, nc, ne], [nb, nd, nf], [0, 0, 1]]
|
15
|
+
new_transformation = matrix.to_a[0..1].transpose.flatten
|
16
|
+
|
17
|
+
[x1, y1, x2, y2, new_transformation]
|
18
|
+
else
|
19
|
+
super
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/prawn/svg/interface.rb
CHANGED
@@ -148,6 +148,19 @@ module Prawn
|
|
148
148
|
|
149
149
|
width = prawn.width_of(text, options.merge(kerning: true))
|
150
150
|
|
151
|
+
if stretch_to_width = options.delete(:stretch_to_width)
|
152
|
+
factor = stretch_to_width.to_f * 100 / width.to_f
|
153
|
+
prawn.add_content "#{factor} Tz"
|
154
|
+
width = stretch_to_width.to_f
|
155
|
+
end
|
156
|
+
|
157
|
+
if pad_to_width = options.delete(:pad_to_width)
|
158
|
+
padding_required = pad_to_width.to_f - width.to_f
|
159
|
+
padding_per_character = padding_required / text.length.to_f
|
160
|
+
prawn.add_content "#{padding_per_character} Tc"
|
161
|
+
width = pad_to_width.to_f
|
162
|
+
end
|
163
|
+
|
151
164
|
case options.delete(:text_anchor)
|
152
165
|
when 'middle'
|
153
166
|
at[0] -= width / 2
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'addressable/uri'
|
2
|
+
|
1
3
|
#
|
2
4
|
# Load a file from disk.
|
3
5
|
#
|
@@ -56,7 +58,7 @@ module Prawn::SVG::Loaders
|
|
56
58
|
private
|
57
59
|
|
58
60
|
def load_file(path)
|
59
|
-
path = URI.
|
61
|
+
path = Addressable::URI.unencode(path)
|
60
62
|
path = build_absolute_and_expand_path(path)
|
61
63
|
assert_valid_path!(path)
|
62
64
|
assert_file_exists!(path)
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Prawn::SVG::TransformParser
|
2
|
+
def parse_transform_attribute(transform)
|
3
|
+
matrix = Matrix.identity(3)
|
4
|
+
|
5
|
+
parse_css_method_calls(transform).each do |name, arguments|
|
6
|
+
case name
|
7
|
+
when 'translate'
|
8
|
+
x, y = arguments
|
9
|
+
matrix *= Matrix[[1, 0, x_pixels(x.to_f)], [0, 1, -y_pixels(y.to_f)], [0, 0, 1]]
|
10
|
+
|
11
|
+
when 'translateX'
|
12
|
+
x = arguments.first
|
13
|
+
matrix *= Matrix[[1, 0, x_pixels(x.to_f)], [0, 1, 0], [0, 0, 1]]
|
14
|
+
|
15
|
+
when 'translateY'
|
16
|
+
y = arguments.first
|
17
|
+
matrix *= Matrix[[1, 0, 0], [0, 1, -y_pixels(y.to_f)], [0, 0, 1]]
|
18
|
+
|
19
|
+
when 'rotate'
|
20
|
+
angle, x, y = arguments.collect { |a| a.to_f }
|
21
|
+
angle = angle * Math::PI / 180.0
|
22
|
+
|
23
|
+
case arguments.length
|
24
|
+
when 1
|
25
|
+
matrix *= Matrix[[Math.cos(angle), Math.sin(angle), 0], [-Math.sin(angle), Math.cos(angle), 0], [0, 0, 1]]
|
26
|
+
when 3
|
27
|
+
matrix *= Matrix[[1, 0, x_pixels(x.to_f)], [0, 1, -y_pixels(y.to_f)], [0, 0, 1]]
|
28
|
+
matrix *= Matrix[[Math.cos(angle), Math.sin(angle), 0], [-Math.sin(angle), Math.cos(angle), 0], [0, 0, 1]]
|
29
|
+
matrix *= Matrix[[1, 0, -x_pixels(x.to_f)], [0, 1, y_pixels(y.to_f)], [0, 0, 1]]
|
30
|
+
else
|
31
|
+
warnings << "transform 'rotate' must have either one or three arguments"
|
32
|
+
end
|
33
|
+
|
34
|
+
when 'scale'
|
35
|
+
x_scale = arguments[0].to_f
|
36
|
+
y_scale = (arguments[1] || x_scale).to_f
|
37
|
+
matrix *= Matrix[[x_scale, 0, 0], [0, y_scale, 0], [0, 0, 1]]
|
38
|
+
|
39
|
+
when 'skewX'
|
40
|
+
angle = arguments[0].to_f * Math::PI / 180.0
|
41
|
+
matrix *= Matrix[[1, -Math.tan(angle), 0], [0, 1, 0], [0, 0, 1]]
|
42
|
+
|
43
|
+
when 'skewY'
|
44
|
+
angle = arguments[0].to_f * Math::PI / 180.0
|
45
|
+
matrix *= Matrix[[1, 0, 0], [-Math.tan(angle), 1, 0], [0, 0, 1]]
|
46
|
+
|
47
|
+
when 'matrix'
|
48
|
+
if arguments.length != 6
|
49
|
+
warnings << "transform 'matrix' must have six arguments"
|
50
|
+
else
|
51
|
+
a, b, c, d, e, f = arguments.collect { |argument| argument.to_f }
|
52
|
+
matrix *= Matrix[[a, -c, e], [-b, d, -f], [0, 0, 1]]
|
53
|
+
end
|
54
|
+
|
55
|
+
else
|
56
|
+
warnings << "Unknown/unsupported transformation '#{name}'; ignoring"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
matrix.to_a[0..1].transpose.flatten
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def parse_css_method_calls(string)
|
66
|
+
string.scan(/\s*(\w+)\(([^)]+)\)\s*/).collect do |call|
|
67
|
+
name, argument_string = call
|
68
|
+
arguments = argument_string.strip.split(/\s*[,\s]\s*/)
|
69
|
+
[name, arguments]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/lib/prawn/svg/version.rb
CHANGED
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Prawn::SVG::Attributes::Opacity do
|
4
|
+
class OpacityTestElement
|
5
|
+
include Prawn::SVG::Attributes::Opacity
|
6
|
+
|
7
|
+
attr_accessor :properties, :state
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@properties = ::Prawn::SVG::Properties.new
|
11
|
+
@state = ::Prawn::SVG::State.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def clamp(value, min_value, max_value)
|
15
|
+
[[value, min_value].max, max_value].min
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
let(:element) { OpacityTestElement.new }
|
20
|
+
|
21
|
+
describe "#parse_opacity_attributes_and_call" do
|
22
|
+
subject { element.parse_opacity_attributes_and_call }
|
23
|
+
|
24
|
+
context "with no opacity specified" do
|
25
|
+
it "does nothing" do
|
26
|
+
expect(element).not_to receive(:add_call_and_enter)
|
27
|
+
subject
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "with opacity" do
|
32
|
+
it "sets fill and stroke opacity" do
|
33
|
+
element.properties.opacity = '0.4'
|
34
|
+
|
35
|
+
expect(element).to receive(:add_call_and_enter).with('transparent', 0.4, 0.4)
|
36
|
+
subject
|
37
|
+
|
38
|
+
expect(element.state.fill_opacity).to eq 0.4
|
39
|
+
expect(element.state.stroke_opacity).to eq 0.4
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "with just fill opacity" do
|
44
|
+
it "sets fill opacity and sets stroke opacity to 1" do
|
45
|
+
element.properties.fill_opacity = '0.4'
|
46
|
+
|
47
|
+
expect(element).to receive(:add_call_and_enter).with('transparent', 0.4, 1)
|
48
|
+
subject
|
49
|
+
|
50
|
+
expect(element.state.fill_opacity).to eq 0.4
|
51
|
+
expect(element.state.stroke_opacity).to eq 1
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context "with an existing fill/stroke opacity" do
|
56
|
+
it "multiplies the new opacity by the old" do
|
57
|
+
element.state.fill_opacity = 0.5
|
58
|
+
element.state.stroke_opacity = 0.8
|
59
|
+
|
60
|
+
element.properties.fill_opacity = '0.4'
|
61
|
+
element.properties.stroke_opacity = '0.5'
|
62
|
+
|
63
|
+
expect(element).to receive(:add_call_and_enter).with('transparent', 0.2, 0.4)
|
64
|
+
subject
|
65
|
+
|
66
|
+
expect(element.state.fill_opacity).to eq 0.2
|
67
|
+
expect(element.state.stroke_opacity).to eq 0.4
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context "with stroke, fill, and opacity all specified" do
|
72
|
+
it "choses the lower of them" do
|
73
|
+
element.properties.fill_opacity = '0.4'
|
74
|
+
element.properties.stroke_opacity = '0.6'
|
75
|
+
element.properties.opacity = '0.5'
|
76
|
+
|
77
|
+
expect(element).to receive(:add_call_and_enter).with('transparent', 0.4, 0.5)
|
78
|
+
subject
|
79
|
+
|
80
|
+
expect(element.state.fill_opacity).to eq 0.4
|
81
|
+
expect(element.state.stroke_opacity).to eq 0.5
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -14,43 +14,38 @@ describe Prawn::SVG::Attributes::Transform do
|
|
14
14
|
|
15
15
|
let(:element) { TransformTestElement.new }
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
17
|
+
subject { element.send :parse_transform_attribute_and_call }
|
18
|
+
|
19
|
+
context "when a non-identity matrix is requested" do
|
20
|
+
let(:transform) { 'translate(-5.5)' }
|
21
|
+
|
22
|
+
it "passes the transform and executes the returned matrix" do
|
23
|
+
expect(element).to receive(:parse_transform_attribute).with(transform).and_return([1, 2, 3, 4, 5, 6])
|
24
|
+
expect(element).to receive(:add_call_and_enter).with('transformation_matrix', 1, 2, 3, 4, 5, 6)
|
25
|
+
|
26
|
+
element.attributes['transform'] = transform
|
27
|
+
subject
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "when an identity matrix is requested" do
|
32
|
+
let(:transform) { 'translate(0)' }
|
33
|
+
|
34
|
+
it "does not execute any commands" do
|
35
|
+
expect(element).to receive(:parse_transform_attribute).with(transform).and_return([1, 0, 0, 1, 0, 0])
|
36
|
+
expect(element).not_to receive(:add_call_and_enter)
|
37
|
+
|
38
|
+
element.attributes['transform'] = transform
|
39
|
+
subject
|
29
40
|
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "when transform is blank" do
|
44
|
+
it "does nothing" do
|
45
|
+
expect(element).not_to receive(:parse_transform_attribute)
|
46
|
+
expect(element).not_to receive(:add_call_and_enter)
|
30
47
|
|
31
|
-
|
32
|
-
it "handles a single angle argument" do
|
33
|
-
expect(element).to receive(:add_call_and_enter).with('rotate', -5.5, :origin => [0, 0])
|
34
|
-
expect(element).to receive(:y).with('0').and_return(0)
|
35
|
-
|
36
|
-
element.attributes['transform'] = 'rotate(5.5)'
|
37
|
-
subject
|
38
|
-
end
|
39
|
-
|
40
|
-
it "handles three arguments" do
|
41
|
-
expect(element).to receive(:add_call_and_enter).with('rotate', -5.5, :origin => [1.0, 2.0])
|
42
|
-
expect(element).to receive(:x).with(1.0).and_return(1.0)
|
43
|
-
expect(element).to receive(:y).with(2.0).and_return(2.0)
|
44
|
-
|
45
|
-
element.attributes['transform'] = 'rotate(5.5 1 2)'
|
46
|
-
subject
|
47
|
-
end
|
48
|
-
|
49
|
-
it "does nothing and warns if two arguments" do
|
50
|
-
expect(element).to receive(:warnings).and_return([])
|
51
|
-
element.attributes['transform'] = 'rotate(5.5 1)'
|
52
|
-
subject
|
53
|
-
end
|
48
|
+
subject
|
54
49
|
end
|
55
50
|
end
|
56
51
|
end
|
@@ -25,14 +25,14 @@ describe Prawn::SVG::Elements::Base do
|
|
25
25
|
describe "applying calls from the standard attributes" do
|
26
26
|
let(:svg) do
|
27
27
|
<<-SVG
|
28
|
-
<something transform="
|
28
|
+
<something transform="scale(2)" fill-opacity="0.5" fill="red" stroke="blue" stroke-width="5"/>
|
29
29
|
SVG
|
30
30
|
end
|
31
31
|
|
32
32
|
it "appends the relevant calls" do
|
33
33
|
element.process
|
34
34
|
expect(element.base_calls).to eq [
|
35
|
-
["
|
35
|
+
["transformation_matrix", [2, 0, 0, 2, 0, 0], [
|
36
36
|
["transparent", [0.5, 1], [
|
37
37
|
["fill_color", ["ff0000"], []],
|
38
38
|
["stroke_color", ["0000ff"], []],
|
@@ -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
|
|
@@ -54,7 +55,30 @@ describe Prawn::SVG::Elements::Gradient do
|
|
54
55
|
expect(arguments).to eq(
|
55
56
|
from: [100.0, 100.0],
|
56
57
|
to: [200.0, 0.0],
|
57
|
-
stops: [[0, "ff0000"], [1, "0000ff"]]
|
58
|
+
stops: [[0, "ff0000"], [1, "0000ff"]],
|
59
|
+
apply_transformations: true,
|
60
|
+
)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context "when gradientTransform is specified" do
|
65
|
+
let(:svg) do
|
66
|
+
<<-SVG
|
67
|
+
<linearGradient id="flag" gradientTransform="translateX(10) scale(2)" x1="0" y1="0" x2="10" y2="10">
|
68
|
+
<stop offset="0" stop-color="red"/>
|
69
|
+
<stop offset="1" stop-color="blue"/>
|
70
|
+
</linearGradient>
|
71
|
+
SVG
|
72
|
+
end
|
73
|
+
|
74
|
+
it "passes in the transform via the apply_transformations option" do
|
75
|
+
arguments = element.gradient_arguments(double(bounding_box: [0, 0, 10, 10]))
|
76
|
+
|
77
|
+
expect(arguments).to eq(
|
78
|
+
from: [0, 0],
|
79
|
+
to: [10, 10],
|
80
|
+
stops: [[0, "ff0000"], [1, "0000ff"]],
|
81
|
+
apply_transformations: [2, 0, 0, 2, 10, 0],
|
58
82
|
)
|
59
83
|
end
|
60
84
|
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
|
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Prawn::SVG::TransformParser do
|
4
|
+
class Test
|
5
|
+
include Prawn::SVG::Calculators::Pixels
|
6
|
+
include Prawn::SVG::TransformParser
|
7
|
+
|
8
|
+
State = Struct.new(:viewport_sizing)
|
9
|
+
Properties = Struct.new(:numerical_font_size)
|
10
|
+
Document = Struct.new(:sizing)
|
11
|
+
|
12
|
+
def document
|
13
|
+
Document.new(_sizing)
|
14
|
+
end
|
15
|
+
|
16
|
+
def state
|
17
|
+
State.new(_sizing)
|
18
|
+
end
|
19
|
+
|
20
|
+
def computed_properties
|
21
|
+
Properties.new(14)
|
22
|
+
end
|
23
|
+
|
24
|
+
def _sizing
|
25
|
+
Prawn::SVG::Calculators::DocumentSizing.new([1000, 800])
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
subject { Test.new.parse_transform_attribute(transform) }
|
30
|
+
|
31
|
+
context "with no transform" do
|
32
|
+
let(:transform) { '' }
|
33
|
+
it { is_expected.to eq [1, 0, 0, 1, 0, 0] }
|
34
|
+
end
|
35
|
+
|
36
|
+
context "with translate" do
|
37
|
+
let(:transform) { 'translate(10 20)' }
|
38
|
+
it { is_expected.to eq [1, 0, 0, 1, 10, -20] }
|
39
|
+
end
|
40
|
+
|
41
|
+
context "with single argument translate" do
|
42
|
+
let(:transform) { 'translate(10)' }
|
43
|
+
it { is_expected.to eq [1, 0, 0, 1, 10, 0] }
|
44
|
+
end
|
45
|
+
|
46
|
+
context "with translateX" do
|
47
|
+
let(:transform) { 'translateX(10)' }
|
48
|
+
it { is_expected.to eq [1, 0, 0, 1, 10, 0] }
|
49
|
+
end
|
50
|
+
|
51
|
+
context "with translateY" do
|
52
|
+
let(:transform) { 'translateY(10)' }
|
53
|
+
it { is_expected.to eq [1, 0, 0, 1, 0, -10] }
|
54
|
+
end
|
55
|
+
|
56
|
+
let(:sin30) { Math.sin(30 * Math::PI / 180.0) }
|
57
|
+
let(:cos30) { Math.cos(30 * Math::PI / 180.0) }
|
58
|
+
let(:tan30) { Math.tan(30 * Math::PI / 180.0) }
|
59
|
+
|
60
|
+
context "with single argument rotate" do
|
61
|
+
let(:transform) { 'rotate(30)' }
|
62
|
+
it { is_expected.to eq [cos30, -sin30, sin30, cos30, 0, 0] }
|
63
|
+
end
|
64
|
+
|
65
|
+
context "with triple argument rotate" do
|
66
|
+
let(:transform) { 'rotate(30 100 200)' }
|
67
|
+
it { is_expected.to eq [cos30, -sin30, sin30, cos30, 113.39745962155611, 23.205080756887753] }
|
68
|
+
end
|
69
|
+
|
70
|
+
context "with scale" do
|
71
|
+
let(:transform) { 'scale(1.5)' }
|
72
|
+
it { is_expected.to eq [1.5, 0, 0, 1.5, 0, 0] }
|
73
|
+
end
|
74
|
+
|
75
|
+
context "with skewX" do
|
76
|
+
let(:transform) { 'skewX(30)' }
|
77
|
+
it { is_expected.to eq [1, 0, -tan30, 1, 0, 0] }
|
78
|
+
end
|
79
|
+
|
80
|
+
context "with skewY" do
|
81
|
+
let(:transform) { 'skewY(30)' }
|
82
|
+
it { is_expected.to eq [1, -tan30, 0, 1, 0, 0] }
|
83
|
+
end
|
84
|
+
|
85
|
+
context "with matrix" do
|
86
|
+
let(:transform) { 'matrix(1 2 3 4 5 6)' }
|
87
|
+
it { is_expected.to eq [1, -2, -3, 4, 5, -6] }
|
88
|
+
end
|
89
|
+
|
90
|
+
context "with multiple" do
|
91
|
+
let(:transform) { 'scale(2) translate(7) scale(3)' }
|
92
|
+
it { is_expected.to eq [6, 0, 0, 6, 14, 0] }
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,6 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="206.404" height="167.984" viewBox="0 0 54.611 44.446">
|
2
|
+
<g transform="translate(-27.725 -80.097)" stroke="#000" stroke-width=".5">
|
3
|
+
<ellipse cx="48.451" cy="103.356" rx="20.476" ry="19.462" fill="#52e0ff"/>
|
4
|
+
<ellipse cx="66.77" cy="102.32" rx="15.316" ry="21.973" fill="#ff6c52" style="opacity:.75; fill-opacity:1"/>
|
5
|
+
</g>
|
6
|
+
</svg>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<svg viewBox="0 0 420 200" xmlns="http://www.w3.org/2000/svg">
|
2
|
+
<linearGradient id="gradient1" gradientUnits="userSpaceOnUse"
|
3
|
+
x1="0" y1="0" x2="200" y2="200">
|
4
|
+
<stop offset="0%" stop-color="darkblue" />
|
5
|
+
<stop offset="50%" stop-color="skyblue" />
|
6
|
+
<stop offset="100%" stop-color="darkblue" />
|
7
|
+
</linearGradient>
|
8
|
+
<linearGradient id="gradient2" gradientUnits="userSpaceOnUse"
|
9
|
+
x1="0" y1="0" x2="200" y2="200"
|
10
|
+
xgradientTransform="skewX(45) translate(-100, 0)"
|
11
|
+
gradientTransform="matrix(0.5, 0, 0, 1, 0, 100)">
|
12
|
+
<stop offset="0%" stop-color="darkblue" />
|
13
|
+
<stop offset="50%" stop-color="skyblue" />
|
14
|
+
<stop offset="100%" stop-color="darkblue" />
|
15
|
+
</linearGradient>
|
16
|
+
|
17
|
+
<rect x="0" y="0" width="200" height="200" fill="url(#gradient1)" />
|
18
|
+
<rect x="0" y="0" width="200" height="200" fill="url(#gradient2)" transform="translate(220, 0)" />
|
19
|
+
</svg>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<?xml version="1.0" standalone="no"?>
|
2
|
+
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
3
|
+
<svg width="1200" height="400" viewBox="0 0 600 200" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
|
4
|
+
<text fill="#000000" font-family="sans-serif" font-size="13" textLength="78" x="14" y="20">You can use</text>
|
5
|
+
<a target="_top" xlink:actuate="onRequest" xlink:href="http://plantuml.com/start" xlink:show="new" xlink:title="http://plantuml.com/start" xlink:type="simple">
|
6
|
+
<text fill="#0000FF" font-family="sans-serif" font-size="13" text-decoration="underline" textLength="87" x="96" y="20">links in notes</text>
|
7
|
+
<line style="stroke: #0000FF; stroke-width: 1.0;" x1="96" x2="183" y1="20" y2="20"/>
|
8
|
+
</a>
|
9
|
+
|
10
|
+
<g transform="translate(0 20)">
|
11
|
+
<text fill="#000000" font-family="sans-serif" font-size="13" textLength="78" lengthAdjust="spacingAndGlyphs" x="14" y="20">You can use</text>
|
12
|
+
<a target="_top" xlink:actuate="onRequest" xlink:href="http://plantuml.com/start" xlink:show="new" xlink:title="http://plantuml.com/start" xlink:type="simple">
|
13
|
+
<text fill="#0000FF" font-family="sans-serif" font-size="13" text-decoration="underline" textLength="87" lengthAdjust="spacingAndGlyphs" x="96" y="20">links in notes</text>
|
14
|
+
<line style="stroke: #0000FF; stroke-width: 1.0;" x1="96" x2="183" y1="20" y2="20"/>
|
15
|
+
</a>
|
16
|
+
</g>
|
17
|
+
</svg>
|
18
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<svg height="975" version="1.1" width="1275" xmlns="http://www.w3.org/2000/svg">
|
2
|
+
<rect x="0" y="0" width="200" height="100" fill="blue"/>
|
3
|
+
<rect x="0" y="0" width="200" height="100" fill="lightblue" transform="rotate(30 200 100) translate(200)"/>
|
4
|
+
<rect x="0" y="0" width="200" height="100" fill="lightblue" transform="rotate(-5) translate(400)"/>
|
5
|
+
|
6
|
+
<g transform="translate(0 200)">
|
7
|
+
<rect x="0" y="0" width="200" height="100" fill="green"/>
|
8
|
+
<rect x="0" y="0" width="200" height="100" fill="lightgreen" transform="skewX(35) translate(200)"/>
|
9
|
+
</g>
|
10
|
+
|
11
|
+
<g transform="translate(0 320)">
|
12
|
+
<rect x="0" y="0" width="200" height="100" fill="red"/>
|
13
|
+
<rect x="0" y="0" width="200" height="100" fill="pink" transform="skewY(5) translate(200)"/>
|
14
|
+
</g>
|
15
|
+
|
16
|
+
<g transform="translate(0 470)">
|
17
|
+
<rect x="0" y="0" width="200" height="100" fill="black"/>
|
18
|
+
<rect x="0" y="0" width="200" height="100" fill="grey" transform="translate(200) scale(1.5)"/>
|
19
|
+
</g>
|
20
|
+
</svg>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prawn-svg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.30.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Roger Nesbitt
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-11-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: prawn
|
@@ -126,6 +126,7 @@ files:
|
|
126
126
|
- lib/prawn/svg/elements/use.rb
|
127
127
|
- lib/prawn/svg/elements/viewport.rb
|
128
128
|
- lib/prawn/svg/extension.rb
|
129
|
+
- lib/prawn/svg/extensions/additional_gradient_transforms.rb
|
129
130
|
- lib/prawn/svg/font.rb
|
130
131
|
- lib/prawn/svg/font_registry.rb
|
131
132
|
- lib/prawn/svg/interface.rb
|
@@ -135,11 +136,13 @@ files:
|
|
135
136
|
- lib/prawn/svg/pathable.rb
|
136
137
|
- lib/prawn/svg/properties.rb
|
137
138
|
- lib/prawn/svg/state.rb
|
139
|
+
- lib/prawn/svg/transform_parser.rb
|
138
140
|
- lib/prawn/svg/ttf.rb
|
139
141
|
- lib/prawn/svg/url_loader.rb
|
140
142
|
- lib/prawn/svg/version.rb
|
141
143
|
- prawn-svg.gemspec
|
142
144
|
- spec/integration_spec.rb
|
145
|
+
- spec/prawn/svg/attributes/opacity_spec.rb
|
143
146
|
- spec/prawn/svg/attributes/transform_spec.rb
|
144
147
|
- spec/prawn/svg/calculators/aspect_ratio_spec.rb
|
145
148
|
- spec/prawn/svg/calculators/document_sizing_spec.rb
|
@@ -165,6 +168,7 @@ files:
|
|
165
168
|
- spec/prawn/svg/loaders/web_spec.rb
|
166
169
|
- spec/prawn/svg/pathable_spec.rb
|
167
170
|
- spec/prawn/svg/properties_spec.rb
|
171
|
+
- spec/prawn/svg/transform_parser_spec.rb
|
168
172
|
- spec/prawn/svg/ttf_spec.rb
|
169
173
|
- spec/prawn/svg/url_loader_spec.rb
|
170
174
|
- spec/sample_images/mushroom-long.jpg
|
@@ -180,9 +184,11 @@ files:
|
|
180
184
|
- spec/sample_svg/cubic01a.svg
|
181
185
|
- spec/sample_svg/cubic02.svg
|
182
186
|
- spec/sample_svg/display_none.svg
|
187
|
+
- spec/sample_svg/double_opacity.svg
|
183
188
|
- spec/sample_svg/ellipse01.svg
|
184
189
|
- spec/sample_svg/gistfile1.svg
|
185
190
|
- spec/sample_svg/google_charts.svg
|
191
|
+
- spec/sample_svg/gradient_transform.svg
|
186
192
|
- spec/sample_svg/gradients.svg
|
187
193
|
- spec/sample_svg/hidden_paths.svg
|
188
194
|
- spec/sample_svg/highcharts.svg
|
@@ -190,6 +196,7 @@ files:
|
|
190
196
|
- spec/sample_svg/image02_base64.svg
|
191
197
|
- spec/sample_svg/image03.svg
|
192
198
|
- spec/sample_svg/line01.svg
|
199
|
+
- spec/sample_svg/links.svg
|
193
200
|
- spec/sample_svg/marker.svg
|
194
201
|
- spec/sample_svg/markers_degenerate_cp.svg
|
195
202
|
- spec/sample_svg/maths.svg
|
@@ -216,6 +223,7 @@ files:
|
|
216
223
|
- spec/sample_svg/subviewports2.svg
|
217
224
|
- spec/sample_svg/text_entities.svg
|
218
225
|
- spec/sample_svg/text_stroke.svg
|
226
|
+
- spec/sample_svg/transform.svg
|
219
227
|
- spec/sample_svg/tref01.svg
|
220
228
|
- spec/sample_svg/triangle01.svg
|
221
229
|
- spec/sample_svg/tspan01.svg
|
@@ -256,6 +264,7 @@ specification_version: 4
|
|
256
264
|
summary: SVG renderer for Prawn PDF library
|
257
265
|
test_files:
|
258
266
|
- spec/integration_spec.rb
|
267
|
+
- spec/prawn/svg/attributes/opacity_spec.rb
|
259
268
|
- spec/prawn/svg/attributes/transform_spec.rb
|
260
269
|
- spec/prawn/svg/calculators/aspect_ratio_spec.rb
|
261
270
|
- spec/prawn/svg/calculators/document_sizing_spec.rb
|
@@ -281,6 +290,7 @@ test_files:
|
|
281
290
|
- spec/prawn/svg/loaders/web_spec.rb
|
282
291
|
- spec/prawn/svg/pathable_spec.rb
|
283
292
|
- spec/prawn/svg/properties_spec.rb
|
293
|
+
- spec/prawn/svg/transform_parser_spec.rb
|
284
294
|
- spec/prawn/svg/ttf_spec.rb
|
285
295
|
- spec/prawn/svg/url_loader_spec.rb
|
286
296
|
- spec/sample_images/mushroom-long.jpg
|
@@ -296,9 +306,11 @@ test_files:
|
|
296
306
|
- spec/sample_svg/cubic01a.svg
|
297
307
|
- spec/sample_svg/cubic02.svg
|
298
308
|
- spec/sample_svg/display_none.svg
|
309
|
+
- spec/sample_svg/double_opacity.svg
|
299
310
|
- spec/sample_svg/ellipse01.svg
|
300
311
|
- spec/sample_svg/gistfile1.svg
|
301
312
|
- spec/sample_svg/google_charts.svg
|
313
|
+
- spec/sample_svg/gradient_transform.svg
|
302
314
|
- spec/sample_svg/gradients.svg
|
303
315
|
- spec/sample_svg/hidden_paths.svg
|
304
316
|
- spec/sample_svg/highcharts.svg
|
@@ -306,6 +318,7 @@ test_files:
|
|
306
318
|
- spec/sample_svg/image02_base64.svg
|
307
319
|
- spec/sample_svg/image03.svg
|
308
320
|
- spec/sample_svg/line01.svg
|
321
|
+
- spec/sample_svg/links.svg
|
309
322
|
- spec/sample_svg/marker.svg
|
310
323
|
- spec/sample_svg/markers_degenerate_cp.svg
|
311
324
|
- spec/sample_svg/maths.svg
|
@@ -332,6 +345,7 @@ test_files:
|
|
332
345
|
- spec/sample_svg/subviewports2.svg
|
333
346
|
- spec/sample_svg/text_entities.svg
|
334
347
|
- spec/sample_svg/text_stroke.svg
|
348
|
+
- spec/sample_svg/transform.svg
|
335
349
|
- spec/sample_svg/tref01.svg
|
336
350
|
- spec/sample_svg/triangle01.svg
|
337
351
|
- spec/sample_svg/tspan01.svg
|