prawn-svg 0.12.0.1 → 0.12.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +3 -1
- data/lib/prawn/svg/parser/image.rb +101 -0
- data/lib/prawn/svg/parser/text.rb +1 -0
- data/lib/prawn/svg/parser.rb +9 -4
- data/lib/prawn/svg/version.rb +1 -1
- data/lib/prawn-svg.rb +1 -0
- data/spec/sample_svg/image01.svg +39 -0
- data/spec/sample_svg/tspan04.svg +16 -0
- metadata +7 -2
data/README.md
CHANGED
@@ -45,6 +45,8 @@ prawn-svg is in its infancy and does not support the full SVG specifications. I
|
|
45
45
|
- <tt>use</tt> tag
|
46
46
|
|
47
47
|
- <tt>style</tt> tag, if css_parser gem is installed on the system (see CSS section below)
|
48
|
+
|
49
|
+
- <tt>image</tt> tag, only with http/https schemes and preserveAspectRatio of 'xMidYMid' (default) or 'none'
|
48
50
|
|
49
51
|
- attributes/styles: <tt>fill</tt>, <tt>stroke</tt>, <tt>stroke-width</tt>, <tt>opacity</tt>, <tt>fill-opacity</tt>, <tt>stroke-opacity</tt>, <tt>transform</tt>
|
50
52
|
|
@@ -60,7 +62,7 @@ By default, prawn-svg has a fonts path of <tt>["/Library/Fonts", "/usr/share/fon
|
|
60
62
|
Mac OS X and Debian Linux users. You can add to the font path:
|
61
63
|
|
62
64
|
```ruby
|
63
|
-
Prawn::Svg.font_path
|
65
|
+
Prawn::Svg.font_path << "/my/font/directory"
|
64
66
|
```
|
65
67
|
|
66
68
|
CSS
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
|
3
|
+
class Prawn::Svg::Parser::Image
|
4
|
+
Error = Class.new(StandardError)
|
5
|
+
|
6
|
+
class FakeIO
|
7
|
+
def initialize(data)
|
8
|
+
@data = data
|
9
|
+
end
|
10
|
+
def read
|
11
|
+
@data
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(document)
|
16
|
+
@document = document
|
17
|
+
end
|
18
|
+
|
19
|
+
def parse(element)
|
20
|
+
attrs = element.attributes
|
21
|
+
url = attrs['xlink:href'] || attrs['href']
|
22
|
+
if url.nil?
|
23
|
+
raise Error, "image tag must have an xlink:href"
|
24
|
+
end
|
25
|
+
if url.match(%r{\Ahttps?://}).nil?
|
26
|
+
raise Error, "image tag xlink:href attribute must use http or https scheme"
|
27
|
+
end
|
28
|
+
|
29
|
+
image = begin
|
30
|
+
open(url).read
|
31
|
+
rescue => e
|
32
|
+
raise Error, "Error retrieving URL #{url}: #{e.message}"
|
33
|
+
end
|
34
|
+
|
35
|
+
x = x(attrs['x'] || 0)
|
36
|
+
y = y(attrs['y'] || 0)
|
37
|
+
width = distance(attrs['width'])
|
38
|
+
height = distance(attrs['height'])
|
39
|
+
options = {}
|
40
|
+
|
41
|
+
return if width.zero? || height.zero?
|
42
|
+
raise Error, "width and height must be 0 or higher" if width < 0 || height < 0
|
43
|
+
|
44
|
+
par = (attrs['preserveAspectRatio'] || "xMidYMid meet").strip.split(/\s+/)
|
45
|
+
par.unshift if par.first == "defer"
|
46
|
+
|
47
|
+
case par.first
|
48
|
+
when 'xMidYMid'
|
49
|
+
ratio = image_ratio(image)
|
50
|
+
if width < height
|
51
|
+
options[:width] = width
|
52
|
+
y -= height/2 - width/ratio/2
|
53
|
+
elsif width > height
|
54
|
+
options[:height] = height
|
55
|
+
x += width/2 - height*ratio/2
|
56
|
+
else
|
57
|
+
options[:fit] = [width, height]
|
58
|
+
if ratio >= 1
|
59
|
+
y -= height/2 - width/ratio/2
|
60
|
+
else
|
61
|
+
x += width/2 - height*ratio/2
|
62
|
+
end
|
63
|
+
end
|
64
|
+
when 'none'
|
65
|
+
options[:width] = width
|
66
|
+
options[:height] = height
|
67
|
+
else
|
68
|
+
raise Error, "image tag only support preserveAspectRatio with xMidYMid or none; ignoring"
|
69
|
+
end
|
70
|
+
|
71
|
+
options[:at] = [x, y]
|
72
|
+
|
73
|
+
element.add_call "image", FakeIO.new(image), options
|
74
|
+
rescue Error => e
|
75
|
+
@document.warnings << e.message
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
protected
|
80
|
+
def image_dimensions(data)
|
81
|
+
handler = if data[0, 3].unpack("C*") == [255, 216, 255]
|
82
|
+
Prawn::Images::JPG
|
83
|
+
elsif data[0, 8].unpack("C*") == [137, 80, 78, 71, 13, 10, 26, 10]
|
84
|
+
Prawn::Images::PNG
|
85
|
+
else
|
86
|
+
raise Error, "Unsupported image type supplied to image tag; Prawn only supports JPG and PNG"
|
87
|
+
end
|
88
|
+
|
89
|
+
image = handler.new(data)
|
90
|
+
[image.width, image.height]
|
91
|
+
end
|
92
|
+
|
93
|
+
def image_ratio(data)
|
94
|
+
w, h = image_dimensions(data)
|
95
|
+
w.to_f / h.to_f
|
96
|
+
end
|
97
|
+
|
98
|
+
%w(x y distance).each do |method|
|
99
|
+
define_method(method) {|*a| @document.send(method, *a)}
|
100
|
+
end
|
101
|
+
end
|
@@ -54,6 +54,7 @@ class Prawn::Svg::Parser::Text
|
|
54
54
|
|
55
55
|
elsif child.name == "tspan"
|
56
56
|
element.add_call 'save'
|
57
|
+
child.attributes['text-anchor'] ||= opts[:text_anchor] if opts[:text_anchor]
|
57
58
|
child_element = Prawn::Svg::Element.new(element.document, child, element.calls, element.state.dup)
|
58
59
|
internal_parse(child_element, x_positions, y_positions, relative)
|
59
60
|
child_element.append_calls_to_parent
|
data/lib/prawn/svg/parser.rb
CHANGED
@@ -56,7 +56,8 @@ class Prawn::Svg::Parser
|
|
56
56
|
"circle" => %w(r),
|
57
57
|
"ellipse" => %w(rx ry),
|
58
58
|
"rect" => %w(width height),
|
59
|
-
"path" => %w(d)
|
59
|
+
"path" => %w(d),
|
60
|
+
"image" => %w(width height)
|
60
61
|
}
|
61
62
|
|
62
63
|
USE_NEW_CIRCLE_CALL = Prawn::Document.new.respond_to?(:circle)
|
@@ -143,8 +144,12 @@ class Prawn::Svg::Parser
|
|
143
144
|
when 'font-face'
|
144
145
|
# not supported
|
145
146
|
do_not_append_calls = true
|
146
|
-
|
147
|
-
|
147
|
+
|
148
|
+
when 'image'
|
149
|
+
@svg_image ||= Image.new(@document)
|
150
|
+
@svg_image.parse(element)
|
151
|
+
|
152
|
+
else
|
148
153
|
@document.warnings << "Unknown tag '#{element.name}'; ignoring"
|
149
154
|
end
|
150
155
|
|
@@ -197,7 +202,7 @@ class Prawn::Svg::Parser
|
|
197
202
|
@document.warnings << "no xlink:href specified on use tag"
|
198
203
|
end
|
199
204
|
end
|
200
|
-
|
205
|
+
|
201
206
|
####################################################################################################################
|
202
207
|
|
203
208
|
def load_css_styles(element)
|
data/lib/prawn/svg/version.rb
CHANGED
data/lib/prawn-svg.rb
CHANGED
@@ -0,0 +1,39 @@
|
|
1
|
+
<?xml version="1.0" standalone="no"?>
|
2
|
+
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
3
|
+
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
4
|
+
<svg width="12cm" height="8cm" viewBox="0 0 1200 800"
|
5
|
+
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
|
6
|
+
<desc>Example rect01 - rectangle with sharp corners</desc>
|
7
|
+
<!-- Show outline of canvas using 'rect' element -->
|
8
|
+
<rect x="1" y="1" width="1198" height="798"
|
9
|
+
fill="none" stroke="blue" stroke-width="2"/>
|
10
|
+
|
11
|
+
<rect x="50" y="50" width="100" height="100" fill="none" stroke="blue" stroke-width="2"/>
|
12
|
+
<image x="50" y="50" width="100" height="100" preserveAspectRatio="xMidYMid" xlink:href="http://files.myopera.com/baby2u/albums/423302/smiley-cool.jpg"></image>
|
13
|
+
|
14
|
+
<rect x="50" y="200" width="150" height="100" fill="none" stroke="blue" stroke-width="2"/>
|
15
|
+
<image x="50" y="200" width="150" height="100" xlink:href="http://files.myopera.com/baby2u/albums/423302/smiley-cool.jpg"></image>
|
16
|
+
|
17
|
+
<rect x="50" y="350" width="100" height="150" fill="none" stroke="blue" stroke-width="2"/>
|
18
|
+
<image x="50" y="350" width="100" height="150" xlink:href="http://files.myopera.com/baby2u/albums/423302/smiley-cool.jpg"></image>
|
19
|
+
|
20
|
+
<rect x="250" y="50" width="100" height="100" fill="none" stroke="blue" stroke-width="2"/>
|
21
|
+
<image x="250" y="50" width="100" height="100" xlink:href="http://imalbum.aufeminin.com/album/D20090809/583007_KWWH1ZQ8FU5ATJXSR84C5MRBUWW33L_989174388_H143954_L.jpg"></image>
|
22
|
+
|
23
|
+
<rect x="250" y="200" width="150" height="100" fill="none" stroke="blue" stroke-width="2"/>
|
24
|
+
<image x="250" y="200" width="150" height="100" xlink:href="http://imalbum.aufeminin.com/album/D20090809/583007_KWWH1ZQ8FU5ATJXSR84C5MRBUWW33L_989174388_H143954_L.jpg"></image>
|
25
|
+
|
26
|
+
<rect x="250" y="350" width="100" height="200" fill="none" stroke="blue" stroke-width="2"/>
|
27
|
+
<image x="250" y="350" width="100" height="200" xlink:href="http://imalbum.aufeminin.com/album/D20090809/583007_KWWH1ZQ8FU5ATJXSR84C5MRBUWW33L_989174388_H143954_L.jpg"></image>
|
28
|
+
|
29
|
+
<rect x="450" y="50" width="100" height="100" fill="none" stroke="blue" stroke-width="2"/>
|
30
|
+
<image x="450" y="50" width="100" height="100" preserveAspectRatio="none" xlink:href="http://imalbum.aufeminin.com/album/D20090809/583007_KWWH1ZQ8FU5ATJXSR84C5MRBUWW33L_989174388_H143954_L.jpg"></image>
|
31
|
+
|
32
|
+
<rect x="450" y="200" width="150" height="100" fill="none" stroke="blue" stroke-width="2"/>
|
33
|
+
<image x="450" y="200" width="150" height="100" preserveAspectRatio="none" xlink:href="http://imalbum.aufeminin.com/album/D20090809/583007_KWWH1ZQ8FU5ATJXSR84C5MRBUWW33L_989174388_H143954_L.jpg"></image>
|
34
|
+
|
35
|
+
<rect x="450" y="350" width="100" height="200" fill="none" stroke="blue" stroke-width="2"/>
|
36
|
+
<image x="450" y="350" width="100" height="200" preserveAspectRatio="none" xlink:href="http://imalbum.aufeminin.com/album/D20090809/583007_KWWH1ZQ8FU5ATJXSR84C5MRBUWW33L_989174388_H143954_L.jpg"></image>
|
37
|
+
|
38
|
+
</svg>
|
39
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<?xml version="1.0" standalone="no"?>
|
2
|
+
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
3
|
+
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
4
|
+
<svg width="10cm" height="3cm" viewBox="0 0 1000 300"
|
5
|
+
xmlns="http://www.w3.org/2000/svg" version="1.1">
|
6
|
+
<desc>Example tspan04 - Use parent text-anchor attribute attributes</desc>
|
7
|
+
<g font-family="Verdana" font-size="45" >
|
8
|
+
<rect x="100" y="150" width="450" height="2" fill="none" stroke="blue" stroke-width="2"/>
|
9
|
+
<text x="100" y="150" width="500" fill="blue" text-anchor="middle">
|
10
|
+
<tspan font-weight="bold" fill="red" >You are a banana.</tspan>
|
11
|
+
</text>
|
12
|
+
</g>
|
13
|
+
<!-- Show outline of canvas using 'rect' element -->
|
14
|
+
<rect x="1" y="1" width="998" height="298"
|
15
|
+
fill="none" stroke="blue" stroke-width="2" />
|
16
|
+
</svg>
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prawn-svg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.12.0.
|
4
|
+
version: 0.12.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-10-
|
12
|
+
date: 2012-10-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: prawn
|
@@ -78,6 +78,7 @@ files:
|
|
78
78
|
- lib/prawn/svg/font.rb
|
79
79
|
- lib/prawn/svg/interface.rb
|
80
80
|
- lib/prawn/svg/parser.rb
|
81
|
+
- lib/prawn/svg/parser/image.rb
|
81
82
|
- lib/prawn/svg/parser/path.rb
|
82
83
|
- lib/prawn/svg/parser/text.rb
|
83
84
|
- lib/prawn/svg/version.rb
|
@@ -97,6 +98,7 @@ files:
|
|
97
98
|
- spec/sample_svg/cubic01a.svg
|
98
99
|
- spec/sample_svg/cubic02.svg
|
99
100
|
- spec/sample_svg/ellipse01.svg
|
101
|
+
- spec/sample_svg/image01.svg
|
100
102
|
- spec/sample_svg/line01.svg
|
101
103
|
- spec/sample_svg/maths.svg
|
102
104
|
- spec/sample_svg/matrix_transform.svg
|
@@ -113,6 +115,7 @@ files:
|
|
113
115
|
- spec/sample_svg/tspan01.svg
|
114
116
|
- spec/sample_svg/tspan02.svg
|
115
117
|
- spec/sample_svg/tspan03.svg
|
118
|
+
- spec/sample_svg/tspan04.svg
|
116
119
|
- spec/sample_svg/use.svg
|
117
120
|
- spec/spec_helper.rb
|
118
121
|
homepage: http://github.com/mogest/prawn-svg
|
@@ -155,6 +158,7 @@ test_files:
|
|
155
158
|
- spec/sample_svg/cubic01a.svg
|
156
159
|
- spec/sample_svg/cubic02.svg
|
157
160
|
- spec/sample_svg/ellipse01.svg
|
161
|
+
- spec/sample_svg/image01.svg
|
158
162
|
- spec/sample_svg/line01.svg
|
159
163
|
- spec/sample_svg/maths.svg
|
160
164
|
- spec/sample_svg/matrix_transform.svg
|
@@ -171,5 +175,6 @@ test_files:
|
|
171
175
|
- spec/sample_svg/tspan01.svg
|
172
176
|
- spec/sample_svg/tspan02.svg
|
173
177
|
- spec/sample_svg/tspan03.svg
|
178
|
+
- spec/sample_svg/tspan04.svg
|
174
179
|
- spec/sample_svg/use.svg
|
175
180
|
- spec/spec_helper.rb
|