prawn-svg 0.16.1 → 0.16.2
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/lib/prawn/svg/parser/path.rb +17 -1
- data/lib/prawn/svg/version.rb +1 -1
- data/prawn-svg.gemspec +1 -1
- data/spec/prawn/svg/parser/path_spec.rb +48 -13
- data/spec/sample_svg/display_none.svg +13 -0
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aa682df73b98546f5b1bb627b79cdc21151b0b2c
|
4
|
+
data.tar.gz: e1a1f7f04ca5d3c3954fbd9e4c3ddb36aaafd2f5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1e139a25230e0402cde88e8f5271f767d2bc3a0f2d34e52b0524de70b6a7e981ac53abbd3a4c2b5e7f868b75c825565b2fed697e2153dbf0f98da53524704407
|
7
|
+
data.tar.gz: 3c0864a2d2b56460c62014f06d9cb5d90911a6aed2a22c81966f1fdbf66ba7c11c631e0aa8e8c3f1d5357c2f81d76831646fa57e3237787e439b81d98bfe93c4
|
@@ -10,6 +10,7 @@ module Prawn
|
|
10
10
|
VALUES_REGEXP = /^#{INSIDE_REGEXP}/
|
11
11
|
COMMAND_REGEXP = /^#{OUTSIDE_SPACE_REGEXP}([A-Za-z])((?:#{INSIDE_REGEXP})*)#{OUTSIDE_SPACE_REGEXP}/
|
12
12
|
|
13
|
+
FLOAT_ERROR_DELTA = 1e-10
|
13
14
|
|
14
15
|
#
|
15
16
|
# Parses an SVG path and returns a Prawn-compatible call tree.
|
@@ -180,10 +181,21 @@ module Prawn
|
|
180
181
|
y2 += y1
|
181
182
|
end
|
182
183
|
|
184
|
+
# Normalise values as per F.6.2
|
183
185
|
rx = rx.abs
|
184
186
|
ry = ry.abs
|
185
187
|
phi = (phi % 360) * 2 * Math::PI / 360.0
|
186
188
|
|
189
|
+
# F.6.2: If the endpoints (x1, y1) and (x2, y2) are identical, then this is equivalent to omitting the elliptical arc segment entirely.
|
190
|
+
return if within_float_delta?(x1, x2) && within_float_delta?(y1, y2)
|
191
|
+
|
192
|
+
# F.6.2: If rx = 0 or ry = 0 then this arc is treated as a straight line segment (a "lineto") joining the endpoints.
|
193
|
+
if within_float_delta?(rx, 0) || within_float_delta?(ry, 0)
|
194
|
+
@last_point = [x2, y2]
|
195
|
+
@calls << ["line_to", @last_point]
|
196
|
+
return
|
197
|
+
end
|
198
|
+
|
187
199
|
# We need to get the center co-ordinates, as well as the angles from the X axis to the start and end
|
188
200
|
# points. To do this, we use the algorithm documented in the SVG specification section F.6.5.
|
189
201
|
|
@@ -204,7 +216,7 @@ module Prawn
|
|
204
216
|
r2x = rx * rx
|
205
217
|
r2y = ry * ry
|
206
218
|
square = (r2x * r2y - r2x * yp1 * yp1 - r2y * xp1 * xp1) / (r2x * yp1 * yp1 + r2y * xp1 * xp1)
|
207
|
-
square = 0 if square < 0 && square > -
|
219
|
+
square = 0 if square < 0 && square > -FLOAT_ERROR_DELTA # catch rounding errors
|
208
220
|
base = Math.sqrt(square)
|
209
221
|
base *= -1 if fa == fs
|
210
222
|
cpx = base * rx * yp1 / ry
|
@@ -254,6 +266,10 @@ module Prawn
|
|
254
266
|
@previous_quadratic_control_point = nil unless %w(Q T).include?(upcase_command)
|
255
267
|
end
|
256
268
|
|
269
|
+
def within_float_delta?(a, b)
|
270
|
+
(a - b).abs < FLOAT_ERROR_DELTA
|
271
|
+
end
|
272
|
+
|
257
273
|
def match_all(string, regexp) # regexp must start with ^
|
258
274
|
result = []
|
259
275
|
while string != ""
|
data/lib/prawn/svg/version.rb
CHANGED
data/prawn-svg.gemspec
CHANGED
@@ -18,7 +18,7 @@ spec = Gem::Specification.new do |gem|
|
|
18
18
|
gem.name = "prawn-svg"
|
19
19
|
gem.require_paths = ["lib"]
|
20
20
|
|
21
|
-
gem.add_runtime_dependency "prawn", ">= 0.8.4", "<
|
21
|
+
gem.add_runtime_dependency "prawn", ">= 0.8.4", "< 3"
|
22
22
|
gem.add_development_dependency "rspec", "~> 2.14"
|
23
23
|
gem.add_development_dependency "rake", "~> 10.1"
|
24
24
|
end
|
@@ -1,15 +1,13 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Prawn::Svg::Parser::Path do
|
4
|
-
|
5
|
-
@path = Prawn::Svg::Parser::Path.new
|
6
|
-
end
|
4
|
+
let(:path) { Prawn::Svg::Parser::Path.new }
|
7
5
|
|
8
6
|
describe "command parsing" do
|
9
7
|
it "correctly parses a valid path" do
|
10
8
|
calls = []
|
11
|
-
|
12
|
-
|
9
|
+
path.stub(:run_path_command) {|*args| calls << args}
|
10
|
+
path.parse("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")
|
13
11
|
|
14
12
|
calls.should == [
|
15
13
|
["A", [12.34, -56.78, 89]],
|
@@ -24,31 +22,68 @@ describe Prawn::Svg::Parser::Path do
|
|
24
22
|
end
|
25
23
|
|
26
24
|
it "treats subsequent points to m/M command as relative/absolute depending on command" do
|
27
|
-
|
28
25
|
[
|
29
26
|
["M", [1,2,3,4]],
|
30
27
|
["L", [3,4]],
|
31
28
|
["m", [5,6,7,8]],
|
32
29
|
["l", [7,8]]
|
33
30
|
].each do |args|
|
34
|
-
|
31
|
+
path.should_receive(:run_path_command).with(*args).and_call_original
|
35
32
|
end
|
36
33
|
|
37
|
-
|
34
|
+
path.parse("M 1,2 3,4 m 5,6 7,8")
|
38
35
|
end
|
39
36
|
|
40
37
|
it "correctly parses an empty path" do
|
41
|
-
|
42
|
-
|
43
|
-
|
38
|
+
path.should_not_receive(:run_path_command)
|
39
|
+
path.parse("").should == []
|
40
|
+
path.parse(" ").should == []
|
44
41
|
end
|
45
42
|
|
46
43
|
it "raises on invalid characters in the path" do
|
47
|
-
lambda {
|
44
|
+
lambda {path.parse("M 10 % 20")}.should raise_error(Prawn::Svg::Parser::Path::InvalidError)
|
48
45
|
end
|
49
46
|
|
50
47
|
it "raises on numerical data before a command letter" do
|
51
|
-
lambda {
|
48
|
+
lambda {path.parse("10 P")}.should raise_error(Prawn::Svg::Parser::Path::InvalidError)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "when given an A path" do
|
53
|
+
it "uses bezier curves to approximate an arc path" do
|
54
|
+
result = path.parse("M 100 200 A 10 10 0 0 1 200 200")
|
55
|
+
|
56
|
+
expect(result).to eq [
|
57
|
+
["move_to", [100.0, 200.0]],
|
58
|
+
["curve_to", [150.0, 150.0, 100.0, 172.57081148225683, 122.57081148225683, 150.0]],
|
59
|
+
["curve_to", [200.0, 200.0, 177.42918851774317, 150.0, 200.0, 172.57081148225683]]
|
60
|
+
]
|
61
|
+
end
|
62
|
+
|
63
|
+
it "ignores a path that has an identical start and end point" do
|
64
|
+
result = path.parse("M 100 200 A 30 30 0 0 1 100 200")
|
65
|
+
|
66
|
+
expect(result).to eq [
|
67
|
+
["move_to", [100.0, 200.0]]
|
68
|
+
]
|
69
|
+
end
|
70
|
+
|
71
|
+
it "substitutes a line_to when rx is 0" do
|
72
|
+
result = path.parse("M 100 200 A 0 10 0 0 1 200 200")
|
73
|
+
|
74
|
+
expect(result).to eq [
|
75
|
+
["move_to", [100.0, 200.0]],
|
76
|
+
["line_to", [200.0, 200.0]]
|
77
|
+
]
|
78
|
+
end
|
79
|
+
|
80
|
+
it "substitutes a line_to when ry is 0" do
|
81
|
+
result = path.parse("M 100 200 A 10 0 0 0 1 200 200")
|
82
|
+
|
83
|
+
expect(result).to eq [
|
84
|
+
["move_to", [100.0, 200.0]],
|
85
|
+
["line_to", [200.0, 200.0]]
|
86
|
+
]
|
52
87
|
end
|
53
88
|
end
|
54
89
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
2
|
+
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" width="800" height="600">
|
3
|
+
<g id="layer1" style="display:none">
|
4
|
+
<rect x="350" y="200" width="20" height="20" fill="green" />
|
5
|
+
<text x="361.80859" y="200" id="text2986" xml:space="preserve" style="font-size:24px;font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Helvetica">
|
6
|
+
<tspan x="361.80859" y="200" id="tspan2988">Hidden</tspan>
|
7
|
+
</text>
|
8
|
+
</g>
|
9
|
+
<g id="layer2">
|
10
|
+
<text x="365.24805" y="300" id="text2990" xml:space="preserve" style="font-size:24px;font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Helvetica">
|
11
|
+
<tspan x="365.24805" y="300" id="tspan2992">Visible</tspan></text>
|
12
|
+
</g>
|
13
|
+
</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.16.
|
4
|
+
version: 0.16.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Roger Nesbitt
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-03-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: prawn
|
@@ -19,7 +19,7 @@ dependencies:
|
|
19
19
|
version: 0.8.4
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: '
|
22
|
+
version: '3'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -29,7 +29,7 @@ dependencies:
|
|
29
29
|
version: 0.8.4
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: '
|
32
|
+
version: '3'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: rspec
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -110,6 +110,7 @@ files:
|
|
110
110
|
- spec/sample_svg/cubic01.svg
|
111
111
|
- spec/sample_svg/cubic01a.svg
|
112
112
|
- spec/sample_svg/cubic02.svg
|
113
|
+
- spec/sample_svg/display_none.svg
|
113
114
|
- spec/sample_svg/ellipse01.svg
|
114
115
|
- spec/sample_svg/google_charts.svg
|
115
116
|
- spec/sample_svg/hidden_paths.svg
|
@@ -189,6 +190,7 @@ test_files:
|
|
189
190
|
- spec/sample_svg/cubic01.svg
|
190
191
|
- spec/sample_svg/cubic01a.svg
|
191
192
|
- spec/sample_svg/cubic02.svg
|
193
|
+
- spec/sample_svg/display_none.svg
|
192
194
|
- spec/sample_svg/ellipse01.svg
|
193
195
|
- spec/sample_svg/google_charts.svg
|
194
196
|
- spec/sample_svg/hidden_paths.svg
|