prawn-svg 0.12.0.1 → 0.12.0.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.
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 &lt;&lt; "/my/font/directory"
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
@@ -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
- else
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)
@@ -1,5 +1,5 @@
1
1
  module Prawn
2
2
  module Svg
3
- VERSION = '0.12.0.1'
3
+ VERSION = '0.12.0.2'
4
4
  end
5
5
  end
data/lib/prawn-svg.rb CHANGED
@@ -7,5 +7,6 @@ require 'prawn/svg/element'
7
7
  require 'prawn/svg/parser'
8
8
  require 'prawn/svg/parser/path'
9
9
  require 'prawn/svg/parser/text'
10
+ require 'prawn/svg/parser/image'
10
11
 
11
12
  Prawn::Document.extensions << Prawn::Svg::Extension
@@ -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.1
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-10 00:00:00.000000000 Z
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