prawn-svg 0.15.0.0 → 0.16.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.
@@ -1,12 +1,6 @@
1
- require 'open-uri'
2
- require 'base64'
3
-
4
1
  class Prawn::Svg::Parser::Image
5
2
  Error = Class.new(StandardError)
6
3
 
7
- DATAURL_REGEXP = /(data:image\/(png|jpg);base64(;[a-z0-9]+)*,)/
8
- URL_REGEXP = /^https?:\/\/|#{DATAURL_REGEXP}/
9
-
10
4
  class FakeIO
11
5
  def initialize(data)
12
6
  @data = data
@@ -30,12 +24,12 @@ class Prawn::Svg::Parser::Image
30
24
  raise Error, "image tag must have an xlink:href"
31
25
  end
32
26
 
33
- if !url.match(URL_REGEXP)
27
+ if !@document.url_loader.valid?(url)
34
28
  raise Error, "image tag xlink:href attribute must use http, https or data scheme"
35
29
  end
36
30
 
37
31
  image = begin
38
- retrieve_data_from_url(url)
32
+ @document.url_loader.load(url)
39
33
  rescue => e
40
34
  raise Error, "Error retrieving URL #{url}: #{e.message}"
41
35
  end
@@ -48,50 +42,18 @@ class Prawn::Svg::Parser::Image
48
42
  return if width.zero? || height.zero?
49
43
  raise Error, "width and height must be 0 or higher" if width < 0 || height < 0
50
44
 
51
- par = (attrs['preserveAspectRatio'] || "xMidYMid meet").strip.split(/\s+/)
52
- par.shift if par.first == "defer"
53
- align, meet_or_slice = par
54
- slice = meet_or_slice == "slice"
45
+ aspect = Prawn::Svg::Calculators::AspectRatio.new(attrs['preserveAspectRatio'], [width, height], image_dimensions(image))
55
46
 
56
- if slice
47
+ if aspect.slice?
57
48
  element.add_call "save"
58
49
  element.add_call "rectangle", [x, y], width, height
59
50
  element.add_call "clip"
60
51
  end
61
52
 
62
- options = {}
63
- case align
64
- when /\Ax(Min|Mid|Max)Y(Min|Mid|Max)\z/
65
- ratio = image_ratio(image)
66
-
67
- options[:fit] = [width, height] unless slice
68
-
69
- if (width/height > ratio) == slice
70
- options[:width] = width if slice
71
- y -= case $2
72
- when "Min" then 0
73
- when "Mid" then (height - width/ratio)/2
74
- when "Max" then height - width/ratio
75
- end
76
- else
77
- options[:height] = height if slice
78
- x += case $1
79
- when "Min" then 0
80
- when "Mid" then (width - height*ratio)/2
81
- when "Max" then width - height*ratio
82
- end
83
- end
84
- when 'none'
85
- options[:width] = width
86
- options[:height] = height
87
- else
88
- raise Error, "unknown preserveAspectRatio align keyword; ignoring image"
89
- end
90
-
91
- options[:at] = [x, y]
53
+ options = {:width => aspect.width, :height => aspect.height, :at => [x + aspect.x, y - aspect.y]}
92
54
 
93
55
  element.add_call "image", FakeIO.new(image), options
94
- element.add_call "restore" if slice
56
+ element.add_call "restore" if aspect.slice?
95
57
  rescue Error => e
96
58
  @document.warnings << e.message
97
59
  end
@@ -108,24 +70,7 @@ class Prawn::Svg::Parser::Image
108
70
  end
109
71
 
110
72
  image = handler.new(data)
111
- [image.width, image.height]
112
- end
113
-
114
- def image_ratio(data)
115
- w, h = image_dimensions(data)
116
- w.to_f / h.to_f
117
- end
118
-
119
- def retrieve_data_from_url(url)
120
- @url_cache[url] || begin
121
- if m = url.match(DATAURL_REGEXP)
122
- data = Base64.decode64(url[m[0].length .. -1])
123
- else
124
- data = open(url).read
125
- end
126
- @url_cache[url] = data if @document.cache_images
127
- data
128
- end
73
+ [image.width.to_f, image.height.to_f]
129
74
  end
130
75
 
131
76
  %w(x y distance).each do |method|
@@ -0,0 +1,34 @@
1
+ require 'open-uri'
2
+ require 'base64'
3
+
4
+ class Prawn::Svg::UrlLoader
5
+ attr_accessor :enable_cache, :enable_web
6
+ attr_reader :url_cache
7
+
8
+ DATAURL_REGEXP = /(data:image\/(png|jpg);base64(;[a-z0-9]+)*,)/
9
+ URL_REGEXP = /^https?:\/\/|#{DATAURL_REGEXP}/
10
+
11
+ def initialize(opts = {})
12
+ @url_cache = {}
13
+ @enable_cache = opts.fetch(:enable_cache, false)
14
+ @enable_web = opts.fetch(:enable_web, true)
15
+ end
16
+
17
+ def valid?(url)
18
+ !!url.match(URL_REGEXP)
19
+ end
20
+
21
+ def load(url)
22
+ @url_cache[url] || begin
23
+ if m = url.match(DATAURL_REGEXP)
24
+ data = Base64.decode64(url[m[0].length .. -1])
25
+ elsif enable_web
26
+ data = open(url).read
27
+ else
28
+ raise "No handler available to retrieve URL #{url}"
29
+ end
30
+ @url_cache[url] = data if enable_cache
31
+ data
32
+ end
33
+ end
34
+ end
@@ -1,5 +1,5 @@
1
1
  module Prawn
2
2
  module Svg
3
- VERSION = '0.15.0.0'
3
+ VERSION = '0.16.0'
4
4
  end
5
5
  end
@@ -0,0 +1,95 @@
1
+ require File.dirname(__FILE__) + '/../../../spec_helper'
2
+
3
+ describe Prawn::Svg::Calculators::AspectRatio do
4
+ def test(*args)
5
+ aspect = Prawn::Svg::Calculators::AspectRatio.new(*args)
6
+ [[aspect.width, aspect.height], [aspect.x, aspect.y]]
7
+ end
8
+
9
+ it "handles none" do
10
+ expect(test "none", [50,80], [100,100]).to eq [[50, 80], [0, 0]]
11
+ expect(test "none", [100,100], [50,80]).to eq [[100, 100], [0, 0]]
12
+ end
13
+
14
+ context "using meet" do
15
+ context "with smaller containers than objects" do
16
+ let(:coords) { [[50,80], [100,100]] }
17
+
18
+ it "correctly calculates the result" do
19
+ expect(test "xMidYMid meet", *coords).to eq [[50, 50], [0, 15]]
20
+ expect(test "xMinYMin meet", *coords).to eq [[50, 50], [0, 0]]
21
+ expect(test "xMaxYMax meet", *coords).to eq [[50, 50], [0, 30]]
22
+ end
23
+ end
24
+
25
+ context "with bigger containers than objects" do
26
+ let(:coords) { [[100,80], [50,50]] }
27
+
28
+ it "correctly calculates the result" do
29
+ expect(test "xMidYMid meet", *coords).to eq [[80, 80], [10, 0]]
30
+ expect(test "xMinYMin meet", *coords).to eq [[80, 80], [0, 0]]
31
+ expect(test "xMaxYMax meet", *coords).to eq [[80, 80], [20, 0]]
32
+ end
33
+ end
34
+
35
+ context "with bigger square containers" do
36
+ let(:coords) { [[100,100], [50,80]] }
37
+
38
+ it "correctly calculates the result" do
39
+ expect(test "xMidYMid meet", *coords).to eq [[62.5, 100], [18.75, 0]]
40
+ expect(test "xMinYMin meet", *coords).to eq [[62.5, 100], [0, 0]]
41
+ expect(test "xMaxYMax meet", *coords).to eq [[62.5, 100], [37.5, 0]]
42
+ end
43
+ end
44
+
45
+ context "with oddly shaped containers" do
46
+ let(:coords) { [[100,20], [50,50]] }
47
+
48
+ it "correctly calculates the result" do
49
+ expect(test "xMidYMid meet", *coords).to eq [[20, 20], [40, 0]]
50
+ expect(test "xMinYMin meet", *coords).to eq [[20, 20], [0, 0]]
51
+ expect(test "xMaxYMax meet", *coords).to eq [[20, 20], [80, 0]]
52
+ end
53
+ end
54
+ end
55
+
56
+ context "using slice" do
57
+ context "with smaller containers than objects" do
58
+ let(:coords) { [[50,80], [100,100]] }
59
+
60
+ it "correctly calculates the result" do
61
+ expect(test "xMidYMid slice", *coords).to eq [[80, 80], [-15, 0]]
62
+ expect(test "xMinYMin slice", *coords).to eq [[80, 80], [0, 0]]
63
+ expect(test "xMaxYMax slice", *coords).to eq [[80, 80], [-30, 0]]
64
+ end
65
+ end
66
+
67
+ context "with bigger containers than objects" do
68
+ let(:coords) { [[100,80], [50,50]] }
69
+
70
+ it "correctly calculates the result" do
71
+ expect(test "xMidYMid slice", *coords).to eq [[100, 100], [0, -10]]
72
+ expect(test "xMinYMin slice", *coords).to eq [[100, 100], [0, 0]]
73
+ expect(test "xMaxYMax slice", *coords).to eq [[100, 100], [0, -20]]
74
+ end
75
+ end
76
+
77
+ context "with oddly shaped containers" do
78
+ let(:coords) { [[100,20], [50,50]] }
79
+
80
+ it "correctly calculates the result" do
81
+ expect(test "xMidYMid slice", *coords).to eq [[100, 100], [0, -40]]
82
+ expect(test "xMinYMin slice", *coords).to eq [[100, 100], [0, 0]]
83
+ expect(test "xMaxYMax slice", *coords).to eq [[100, 100], [0, -80]]
84
+ end
85
+ end
86
+ end
87
+
88
+ it "defaults to 'xMidYMid meet' if nothing is supplied" do
89
+ expect(test "", [50,80], [100,100]).to eq test "xMidYMid meet", [50,80], [100,100]
90
+ end
91
+
92
+ it "defaults to 'xMidYMid meet' if something invalid is supplied" do
93
+ expect(test "completely invalid", [50,80], [100,100]).to eq test "xMidYMid meet", [50,80], [100,100]
94
+ end
95
+ end
@@ -0,0 +1,73 @@
1
+ require File.dirname(__FILE__) + '/../../../spec_helper'
2
+
3
+ describe Prawn::Svg::Calculators::DocumentSizing do
4
+ let(:attributes) do
5
+ {"width" => "150", "height" => "200", "viewBox" => "0 -30 300 800", "preserveAspectRatio" => "xMaxYMid meet"}
6
+ end
7
+
8
+ let(:bounds) { [1200, 800] }
9
+
10
+ let(:sizing) { Prawn::Svg::Calculators::DocumentSizing.new(bounds, attributes) }
11
+
12
+ describe "#initialize" do
13
+ it "takes bounds and a set of attributes and calls set_from_attributes" do
14
+ expect(sizing.instance_variable_get :@bounds).to eq bounds
15
+ expect(sizing.instance_variable_get :@document_width).to eq "150"
16
+ end
17
+ end
18
+
19
+ describe "#set_from_attributes" do
20
+ let(:sizing) { Prawn::Svg::Calculators::DocumentSizing.new(bounds) }
21
+
22
+ it "sets ivars from the passed-in attributes hash" do
23
+ sizing.set_from_attributes(attributes)
24
+ expect(sizing.instance_variable_get :@document_width).to eq "150"
25
+ expect(sizing.instance_variable_get :@document_height).to eq "200"
26
+ expect(sizing.instance_variable_get :@view_box).to eq "0 -30 300 800"
27
+ expect(sizing.instance_variable_get :@preserve_aspect_ratio).to eq "xMaxYMid meet"
28
+ end
29
+ end
30
+
31
+ describe "#calculate" do
32
+ it "calculates the document sizing measurements for a given set of inputs" do
33
+ sizing.calculate
34
+ expect(sizing.x_offset).to eq -75
35
+ expect(sizing.y_offset).to eq -30
36
+ expect(sizing.x_scale).to eq 0.25
37
+ expect(sizing.y_scale).to eq 0.25
38
+ expect(sizing.viewport_width).to eq 300
39
+ expect(sizing.viewport_height).to eq 800
40
+ expect(sizing.output_width).to eq 150
41
+ expect(sizing.output_height).to eq 200
42
+ end
43
+
44
+ it "scales again based on requested width" do
45
+ sizing.requested_width = 75
46
+ sizing.calculate
47
+ expect(sizing.x_scale).to eq 0.125
48
+ expect(sizing.y_scale).to eq 0.125
49
+ expect(sizing.viewport_width).to eq 300
50
+ expect(sizing.viewport_height).to eq 800
51
+ expect(sizing.output_width).to eq 75
52
+ expect(sizing.output_height).to eq 100
53
+ end
54
+
55
+ it "scales again based on requested height" do
56
+ sizing.requested_height = 100
57
+ sizing.calculate
58
+ expect(sizing.x_scale).to eq 0.125
59
+ expect(sizing.y_scale).to eq 0.125
60
+ expect(sizing.viewport_width).to eq 300
61
+ expect(sizing.viewport_height).to eq 800
62
+ expect(sizing.output_width).to eq 75
63
+ expect(sizing.output_height).to eq 100
64
+ end
65
+
66
+ it "correctly handles % values being passed in" do
67
+ sizing.document_width = sizing.document_height = "50%"
68
+ sizing.calculate
69
+ expect(sizing.output_width).to eq 600
70
+ expect(sizing.output_height).to eq 400
71
+ end
72
+ end
73
+ end
@@ -14,13 +14,15 @@ describe Prawn::Svg::Document do
14
14
  @document.send(:points, "32pt").should == 32.0
15
15
  @document.send(:points, "32in").should == 32.0 * 72
16
16
  @document.send(:points, "32ft").should == 32.0 * 72 * 12
17
+ @document.send(:points, "32pc").should == 32.0 * 15
17
18
  @document.send(:points, "32mm").should be_within(0.0001).of(32 * 72 * 0.0393700787)
18
19
  @document.send(:points, "32cm").should be_within(0.0001).of(32 * 72 * 0.393700787)
19
20
  @document.send(:points, "32m").should be_within(0.0001).of(32 * 72 * 39.3700787)
20
21
 
21
- @document.send :instance_variable_set, "@actual_width", 600
22
- @document.send :instance_variable_set, "@actual_height", 400
22
+ @document.sizing.send :instance_variable_set, "@viewport_width", 600
23
+ @document.sizing.send :instance_variable_set, "@viewport_height", 400
23
24
  @document.send(:points, "50%").should == 300
25
+ @document.send(:points, "50%", :x).should == 300
24
26
  @document.send(:points, "50%", :y).should == 200
25
27
  end
26
28
  end
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/../../spec_helper'
2
2
 
3
3
  describe Prawn::Svg::Element do
4
4
  before :each do
5
- e = double(:attributes => {})
5
+ e = double(:attributes => {}, :name => "path")
6
6
 
7
7
  @document = Struct.new(:fallback_font_name, :css_parser, :warnings).new("Courier", nil, [])
8
8
  @element = Prawn::Svg::Element.new(@document, e, [], {})
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Prawn::Svg::Interface do
4
- root = "#{File.dirname(__FILE__)}/../.."
4
+ root = "#{File.dirname(__FILE__)}/../../.."
5
5
 
6
6
  describe "sample file rendering" do
7
7
  files = Dir["#{root}/spec/sample_svg/*.svg"]
@@ -14,7 +14,12 @@ describe Prawn::Svg::Interface do
14
14
  it "renders the #{File.basename file} sample file without warnings or crashing" do
15
15
  warnings = nil
16
16
  Prawn::Document.generate("#{root}/spec/sample_output/#{File.basename file}.pdf") do |prawn|
17
- r = prawn.svg IO.read(file), :at => [0, prawn.bounds.top], :width => prawn.bounds.width, :cache_images => true
17
+ r = prawn.svg IO.read(file), :at => [0, prawn.bounds.top], :width => prawn.bounds.width do |doc|
18
+ doc.url_loader.enable_web = false
19
+ doc.url_loader.url_cache["https://raw.githubusercontent.com/mogest/prawn-svg/master/spec/sample_images/mushroom-wide.jpg"] = IO.read("#{root}/spec/sample_images/mushroom-wide.jpg")
20
+ doc.url_loader.url_cache["https://raw.githubusercontent.com/mogest/prawn-svg/master/spec/sample_images/mushroom-long.jpg"] = IO.read("#{root}/spec/sample_images/mushroom-long.jpg")
21
+ end
22
+
18
23
  warnings = r[:warnings].reject {|w| w =~ /Verdana/ && w =~ /is not a known font/ }
19
24
  end
20
25
  warnings.should == []
File without changes
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ describe Prawn::Svg::UrlLoader do
4
+ let(:loader) { Prawn::Svg::UrlLoader.new(:enable_cache => true, :enable_web => true) }
5
+
6
+ describe "#initialize" do
7
+ it "sets options" do
8
+ expect(loader.enable_cache).to be true
9
+ expect(loader.enable_web).to be true
10
+ end
11
+ end
12
+
13
+ describe "#valid?" do
14
+ it "knows what a valid URL looks like" do
15
+ expect(loader.valid?("http://valid.example/url")).to be true
16
+ expect(loader.valid?("not/a/valid/url")).to be false
17
+ end
18
+
19
+ it "doesn't accept schemes it doesn't like" do
20
+ expect(loader.valid?("mail://valid.example/url")).to be false
21
+ end
22
+ end
23
+
24
+ describe "#load" do
25
+ let(:url) { "http://hello/there" }
26
+
27
+ it "loads an HTTP URL and saves to the cache" do
28
+ o = double(:read => "hello!")
29
+ loader.should_receive(:open).with(url).and_return(o)
30
+
31
+ expect(loader.load(url)).to eq "hello!"
32
+ expect(loader.url_cache[url]).to eq "hello!"
33
+ end
34
+
35
+ it "loads an HTTP URL from the cache without calling open" do
36
+ loader.url_cache[url] = "hello"
37
+ loader.should_not_receive(:open)
38
+ expect(loader.load(url)).to eq "hello"
39
+ end
40
+
41
+ it "loads a data URL" do
42
+ loader.should_not_receive(:open)
43
+ expect(loader.load("data:image/png;base64,aGVsbG8=")).to eq "hello"
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,6 @@
1
+ <svg style="fill: none;">
2
+ <g class="x axis" transform="translate(0,227.9359)">
3
+ <path class="domain" d="M0,0V0H470V0" style="fill: none; stroke: none;"></path>
4
+ <path d="M 44.82625 0 L 44.82625 -3 L 94 -3 L 94 0" class="cantilever" style="stroke: black; fill: none;"></path>
5
+ </g>
6
+ </svg>
@@ -18,113 +18,113 @@
18
18
  <text y="25" font-size="12pt">wide image, aspect ratio meet</text>
19
19
 
20
20
  <rect y="50" width="100" height="100" fill="none" stroke="blue" stroke-width="2"/>
21
- <image y="50" width="100" height="100" preserveAspectRatio="xMidYMid" xlink:href="http://files.myopera.com/baby2u/albums/423302/smiley-cool.jpg"></image>
21
+ <image y="50" width="100" height="100" preserveAspectRatio="xMidYMid" xlink:href="https://raw.githubusercontent.com/mogest/prawn-svg/master/spec/sample_images/mushroom-wide.jpg"></image>
22
22
 
23
23
  <rect y="200" width="150" height="100" fill="none" stroke="blue" stroke-width="2"/>
24
- <image y="200" width="150" height="100" xlink:href="http://files.myopera.com/baby2u/albums/423302/smiley-cool.jpg"></image>
24
+ <image y="200" width="150" height="100" xlink:href="https://raw.githubusercontent.com/mogest/prawn-svg/master/spec/sample_images/mushroom-wide.jpg"></image>
25
25
 
26
26
  <rect y="350" width="100" height="150" fill="none" stroke="blue" stroke-width="2"/>
27
- <image y="350" width="100" height="150" xlink:href="http://files.myopera.com/baby2u/albums/423302/smiley-cool.jpg"></image>
27
+ <image y="350" width="100" height="150" xlink:href="https://raw.githubusercontent.com/mogest/prawn-svg/master/spec/sample_images/mushroom-wide.jpg"></image>
28
28
 
29
29
  <rect y="550" width="150" height="100" fill="none" stroke="blue" stroke-width="2"/>
30
- <image y="550" width="150" height="100" preserveAspectRatio="xMinYMin" xlink:href="http://files.myopera.com/baby2u/albums/423302/smiley-cool.jpg"></image>
30
+ <image y="550" width="150" height="100" preserveAspectRatio="xMinYMin" xlink:href="https://raw.githubusercontent.com/mogest/prawn-svg/master/spec/sample_images/mushroom-wide.jpg"></image>
31
31
 
32
32
  <rect y="700" width="100" height="150" fill="none" stroke="blue" stroke-width="2"/>
33
- <image y="700" width="100" height="150" preserveAspectRatio="xMinYMin" xlink:href="http://files.myopera.com/baby2u/albums/423302/smiley-cool.jpg"></image>
33
+ <image y="700" width="100" height="150" preserveAspectRatio="xMinYMin" xlink:href="https://raw.githubusercontent.com/mogest/prawn-svg/master/spec/sample_images/mushroom-wide.jpg"></image>
34
34
 
35
35
  <rect y="900" width="150" height="100" fill="none" stroke="blue" stroke-width="2"/>
36
- <image y="900" width="150" height="100" preserveAspectRatio="xMaxYMax" xlink:href="http://files.myopera.com/baby2u/albums/423302/smiley-cool.jpg"></image>
36
+ <image y="900" width="150" height="100" preserveAspectRatio="xMaxYMax" xlink:href="https://raw.githubusercontent.com/mogest/prawn-svg/master/spec/sample_images/mushroom-wide.jpg"></image>
37
37
 
38
38
  <rect y="1050" width="100" height="150" fill="none" stroke="blue" stroke-width="2"/>
39
- <image y="1050" width="100" height="150" preserveAspectRatio="xMaxYMax" xlink:href="http://files.myopera.com/baby2u/albums/423302/smiley-cool.jpg"></image>
39
+ <image y="1050" width="100" height="150" preserveAspectRatio="xMaxYMax" xlink:href="https://raw.githubusercontent.com/mogest/prawn-svg/master/spec/sample_images/mushroom-wide.jpg"></image>
40
40
  </g>
41
41
 
42
42
  <g transform="translate(250 0)">
43
43
  <text y="25" font-size="12pt">wide image, aspect ratio slice</text>
44
44
 
45
45
  <rect y="50" width="100" height="100" fill="none" stroke="blue" stroke-width="2"/>
46
- <image y="50" width="100" height="100" preserveAspectRatio="xMidYMid slice" xlink:href="http://files.myopera.com/baby2u/albums/423302/smiley-cool.jpg"></image>
46
+ <image y="50" width="100" height="100" preserveAspectRatio="xMidYMid slice" xlink:href="https://raw.githubusercontent.com/mogest/prawn-svg/master/spec/sample_images/mushroom-wide.jpg"></image>
47
47
 
48
48
  <rect y="200" width="150" height="100" fill="none" stroke="blue" stroke-width="2"/>
49
- <image y="200" width="150" height="100" preserveAspectRatio="xMidYMid slice" xlink:href="http://files.myopera.com/baby2u/albums/423302/smiley-cool.jpg"></image>
49
+ <image y="200" width="150" height="100" preserveAspectRatio="xMidYMid slice" xlink:href="https://raw.githubusercontent.com/mogest/prawn-svg/master/spec/sample_images/mushroom-wide.jpg"></image>
50
50
 
51
51
  <rect y="350" width="100" height="150" fill="none" stroke="blue" stroke-width="2"/>
52
- <image y="350" width="100" height="150" preserveAspectRatio="xMidYMid slice" xlink:href="http://files.myopera.com/baby2u/albums/423302/smiley-cool.jpg"></image>
52
+ <image y="350" width="100" height="150" preserveAspectRatio="xMidYMid slice" xlink:href="https://raw.githubusercontent.com/mogest/prawn-svg/master/spec/sample_images/mushroom-wide.jpg"></image>
53
53
 
54
54
  <rect y="550" width="150" height="100" fill="none" stroke="blue" stroke-width="2"/>
55
- <image y="550" width="150" height="100" preserveAspectRatio="xMinYMin slice" xlink:href="http://files.myopera.com/baby2u/albums/423302/smiley-cool.jpg"></image>
55
+ <image y="550" width="150" height="100" preserveAspectRatio="xMinYMin slice" xlink:href="https://raw.githubusercontent.com/mogest/prawn-svg/master/spec/sample_images/mushroom-wide.jpg"></image>
56
56
 
57
57
  <rect y="700" width="100" height="150" fill="none" stroke="blue" stroke-width="2"/>
58
- <image y="700" width="100" height="150" preserveAspectRatio="xMinYMin slice" xlink:href="http://files.myopera.com/baby2u/albums/423302/smiley-cool.jpg"></image>
58
+ <image y="700" width="100" height="150" preserveAspectRatio="xMinYMin slice" xlink:href="https://raw.githubusercontent.com/mogest/prawn-svg/master/spec/sample_images/mushroom-wide.jpg"></image>
59
59
 
60
60
  <rect y="900" width="150" height="100" fill="none" stroke="blue" stroke-width="2"/>
61
- <image y="900" width="150" height="100" preserveAspectRatio="xMaxYMax slice" xlink:href="http://files.myopera.com/baby2u/albums/423302/smiley-cool.jpg"></image>
61
+ <image y="900" width="150" height="100" preserveAspectRatio="xMaxYMax slice" xlink:href="https://raw.githubusercontent.com/mogest/prawn-svg/master/spec/sample_images/mushroom-wide.jpg"></image>
62
62
 
63
63
  <rect y="1050" width="100" height="150" fill="none" stroke="blue" stroke-width="2"/>
64
- <image y="1050" width="100" height="150" preserveAspectRatio="xMaxYMax slice" xlink:href="http://files.myopera.com/baby2u/albums/423302/smiley-cool.jpg"></image>
64
+ <image y="1050" width="100" height="150" preserveAspectRatio="xMaxYMax slice" xlink:href="https://raw.githubusercontent.com/mogest/prawn-svg/master/spec/sample_images/mushroom-wide.jpg"></image>
65
65
  </g>
66
66
 
67
67
  <g transform="translate(450 0)">
68
68
  <text y="25" font-size="12pt">long image, aspect ratio meet</text>
69
69
 
70
70
  <rect y="50" width="100" height="100" fill="none" stroke="blue" stroke-width="2"/>
71
- <image y="50" width="100" height="100" xlink:href="http://imalbum.aufeminin.com/album/D20090809/583007_KWWH1ZQ8FU5ATJXSR84C5MRBUWW33L_989174388_H143954_L.jpg"></image>
71
+ <image y="50" width="100" height="100" xlink:href="https://raw.githubusercontent.com/mogest/prawn-svg/master/spec/sample_images/mushroom-long.jpg"></image>
72
72
 
73
73
  <rect y="200" width="150" height="100" fill="none" stroke="blue" stroke-width="2"/>
74
- <image y="200" width="150" height="100" xlink:href="http://imalbum.aufeminin.com/album/D20090809/583007_KWWH1ZQ8FU5ATJXSR84C5MRBUWW33L_989174388_H143954_L.jpg"></image>
74
+ <image y="200" width="150" height="100" xlink:href="https://raw.githubusercontent.com/mogest/prawn-svg/master/spec/sample_images/mushroom-long.jpg"></image>
75
75
 
76
76
  <rect y="350" width="100" height="200" fill="none" stroke="blue" stroke-width="2"/>
77
- <image y="350" width="100" height="200" xlink:href="http://imalbum.aufeminin.com/album/D20090809/583007_KWWH1ZQ8FU5ATJXSR84C5MRBUWW33L_989174388_H143954_L.jpg"></image>
77
+ <image y="350" width="100" height="200" xlink:href="https://raw.githubusercontent.com/mogest/prawn-svg/master/spec/sample_images/mushroom-long.jpg"></image>
78
78
 
79
79
  <rect y="550" width="150" height="100" fill="none" stroke="blue" stroke-width="2"/>
80
- <image y="550" width="150" height="100" preserveAspectRatio="xMinYMin" xlink:href="http://imalbum.aufeminin.com/album/D20090809/583007_KWWH1ZQ8FU5ATJXSR84C5MRBUWW33L_989174388_H143954_L.jpg"></image>
80
+ <image y="550" width="150" height="100" preserveAspectRatio="xMinYMin" xlink:href="https://raw.githubusercontent.com/mogest/prawn-svg/master/spec/sample_images/mushroom-long.jpg"></image>
81
81
 
82
82
  <rect y="700" width="100" height="200" fill="none" stroke="blue" stroke-width="2"/>
83
- <image y="700" width="100" height="200" preserveAspectRatio="xMinYMin" xlink:href="http://imalbum.aufeminin.com/album/D20090809/583007_KWWH1ZQ8FU5ATJXSR84C5MRBUWW33L_989174388_H143954_L.jpg"></image>
83
+ <image y="700" width="100" height="200" preserveAspectRatio="xMinYMin" xlink:href="https://raw.githubusercontent.com/mogest/prawn-svg/master/spec/sample_images/mushroom-long.jpg"></image>
84
84
 
85
85
  <rect y="900" width="150" height="100" fill="none" stroke="blue" stroke-width="2"/>
86
- <image y="900" width="150" height="100" preserveAspectRatio="xMaxYMax" xlink:href="http://imalbum.aufeminin.com/album/D20090809/583007_KWWH1ZQ8FU5ATJXSR84C5MRBUWW33L_989174388_H143954_L.jpg"></image>
86
+ <image y="900" width="150" height="100" preserveAspectRatio="xMaxYMax" xlink:href="https://raw.githubusercontent.com/mogest/prawn-svg/master/spec/sample_images/mushroom-long.jpg"></image>
87
87
 
88
88
  <rect y="1050" width="100" height="200" fill="none" stroke="blue" stroke-width="2"/>
89
- <image y="1050" width="100" height="200" preserveAspectRatio="xMaxYMax" xlink:href="http://imalbum.aufeminin.com/album/D20090809/583007_KWWH1ZQ8FU5ATJXSR84C5MRBUWW33L_989174388_H143954_L.jpg"></image>
89
+ <image y="1050" width="100" height="200" preserveAspectRatio="xMaxYMax" xlink:href="https://raw.githubusercontent.com/mogest/prawn-svg/master/spec/sample_images/mushroom-long.jpg"></image>
90
90
  </g>
91
91
 
92
92
  <g transform="translate(650 0)">
93
93
  <text y="25" font-size="12pt">long image, aspect ratio slice</text>
94
94
 
95
95
  <rect y="50" width="100" height="100" fill="none" stroke="blue" stroke-width="2"/>
96
- <image y="50" width="100" height="100" preserveAspectRatio="xMidYMid slice" xlink:href="http://imalbum.aufeminin.com/album/D20090809/583007_KWWH1ZQ8FU5ATJXSR84C5MRBUWW33L_989174388_H143954_L.jpg"></image>
96
+ <image y="50" width="100" height="100" preserveAspectRatio="xMidYMid slice" xlink:href="https://raw.githubusercontent.com/mogest/prawn-svg/master/spec/sample_images/mushroom-long.jpg"></image>
97
97
 
98
98
  <rect y="200" width="150" height="100" fill="none" stroke="blue" stroke-width="2"/>
99
- <image y="200" width="150" height="100" preserveAspectRatio="xMidYMid slice" xlink:href="http://imalbum.aufeminin.com/album/D20090809/583007_KWWH1ZQ8FU5ATJXSR84C5MRBUWW33L_989174388_H143954_L.jpg"></image>
99
+ <image y="200" width="150" height="100" preserveAspectRatio="xMidYMid slice" xlink:href="https://raw.githubusercontent.com/mogest/prawn-svg/master/spec/sample_images/mushroom-long.jpg"></image>
100
100
 
101
101
  <rect y="350" width="100" height="200" fill="none" stroke="blue" stroke-width="2"/>
102
- <image y="350" width="100" height="200" preserveAspectRatio="xMidYMid slice" xlink:href="http://imalbum.aufeminin.com/album/D20090809/583007_KWWH1ZQ8FU5ATJXSR84C5MRBUWW33L_989174388_H143954_L.jpg"></image>
102
+ <image y="350" width="100" height="200" preserveAspectRatio="xMidYMid slice" xlink:href="https://raw.githubusercontent.com/mogest/prawn-svg/master/spec/sample_images/mushroom-long.jpg"></image>
103
103
 
104
104
  <rect y="550" width="150" height="100" fill="none" stroke="blue" stroke-width="2"/>
105
- <image y="550" width="150" height="100" preserveAspectRatio="xMinYMin slice" xlink:href="http://imalbum.aufeminin.com/album/D20090809/583007_KWWH1ZQ8FU5ATJXSR84C5MRBUWW33L_989174388_H143954_L.jpg"></image>
105
+ <image y="550" width="150" height="100" preserveAspectRatio="xMinYMin slice" xlink:href="https://raw.githubusercontent.com/mogest/prawn-svg/master/spec/sample_images/mushroom-long.jpg"></image>
106
106
 
107
107
  <rect y="700" width="100" height="200" fill="none" stroke="blue" stroke-width="2"/>
108
- <image y="700" width="100" height="200" preserveAspectRatio="xMinYMin slice" xlink:href="http://imalbum.aufeminin.com/album/D20090809/583007_KWWH1ZQ8FU5ATJXSR84C5MRBUWW33L_989174388_H143954_L.jpg"></image>
108
+ <image y="700" width="100" height="200" preserveAspectRatio="xMinYMin slice" xlink:href="https://raw.githubusercontent.com/mogest/prawn-svg/master/spec/sample_images/mushroom-long.jpg"></image>
109
109
 
110
110
  <rect y="900" width="150" height="100" fill="none" stroke="blue" stroke-width="2"/>
111
- <image y="900" width="150" height="100" preserveAspectRatio="xMaxYMax slice" xlink:href="http://imalbum.aufeminin.com/album/D20090809/583007_KWWH1ZQ8FU5ATJXSR84C5MRBUWW33L_989174388_H143954_L.jpg"></image>
111
+ <image y="900" width="150" height="100" preserveAspectRatio="xMaxYMax slice" xlink:href="https://raw.githubusercontent.com/mogest/prawn-svg/master/spec/sample_images/mushroom-long.jpg"></image>
112
112
 
113
113
  <rect y="1050" width="100" height="200" fill="none" stroke="blue" stroke-width="2"/>
114
- <image y="1050" width="100" height="200" preserveAspectRatio="xMaxYMax slice" xlink:href="http://imalbum.aufeminin.com/album/D20090809/583007_KWWH1ZQ8FU5ATJXSR84C5MRBUWW33L_989174388_H143954_L.jpg"></image>
114
+ <image y="1050" width="100" height="200" preserveAspectRatio="xMaxYMax slice" xlink:href="https://raw.githubusercontent.com/mogest/prawn-svg/master/spec/sample_images/mushroom-long.jpg"></image>
115
115
  </g>
116
116
 
117
117
  <g transform="translate(850 0)">
118
118
  <text y="25" font-size="12pt">aspect ratio preservation disabled</text>
119
119
 
120
120
  <rect y="50" width="100" height="100" fill="none" stroke="blue" stroke-width="2"/>
121
- <image y="50" width="100" height="100" preserveAspectRatio="none" xlink:href="http://imalbum.aufeminin.com/album/D20090809/583007_KWWH1ZQ8FU5ATJXSR84C5MRBUWW33L_989174388_H143954_L.jpg"></image>
121
+ <image y="50" width="100" height="100" preserveAspectRatio="none" xlink:href="https://raw.githubusercontent.com/mogest/prawn-svg/master/spec/sample_images/mushroom-long.jpg"></image>
122
122
 
123
123
  <rect y="200" width="150" height="100" fill="none" stroke="blue" stroke-width="2"/>
124
- <image y="200" width="150" height="100" preserveAspectRatio="none" xlink:href="http://imalbum.aufeminin.com/album/D20090809/583007_KWWH1ZQ8FU5ATJXSR84C5MRBUWW33L_989174388_H143954_L.jpg"></image>
124
+ <image y="200" width="150" height="100" preserveAspectRatio="none" xlink:href="https://raw.githubusercontent.com/mogest/prawn-svg/master/spec/sample_images/mushroom-long.jpg"></image>
125
125
 
126
126
  <rect y="350" width="100" height="200" fill="none" stroke="blue" stroke-width="2"/>
127
- <image y="350" width="100" height="200" preserveAspectRatio="none" xlink:href="http://imalbum.aufeminin.com/album/D20090809/583007_KWWH1ZQ8FU5ATJXSR84C5MRBUWW33L_989174388_H143954_L.jpg"></image>
127
+ <image y="350" width="100" height="200" preserveAspectRatio="none" xlink:href="https://raw.githubusercontent.com/mogest/prawn-svg/master/spec/sample_images/mushroom-long.jpg"></image>
128
128
  </g>
129
129
 
130
130
  </svg>