prawn-svg 0.15.0.0 → 0.16.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +10 -3
- data/lib/prawn-svg.rb +4 -0
- data/lib/prawn/svg/calculators/aspect_ratio.rb +58 -0
- data/lib/prawn/svg/calculators/document_sizing.rb +71 -0
- data/lib/prawn/svg/calculators/pixels.rb +21 -0
- data/lib/prawn/svg/document.rb +15 -44
- data/lib/prawn/svg/element.rb +19 -10
- data/lib/prawn/svg/extension.rb +3 -3
- data/lib/prawn/svg/interface.rb +14 -10
- data/lib/prawn/svg/parser.rb +13 -0
- data/lib/prawn/svg/parser/image.rb +7 -62
- data/lib/prawn/svg/url_loader.rb +34 -0
- data/lib/prawn/svg/version.rb +1 -1
- data/spec/prawn/svg/calculators/aspect_ratio_spec.rb +95 -0
- data/spec/prawn/svg/calculators/document_sizing_spec.rb +73 -0
- data/spec/prawn/svg/document_spec.rb +4 -2
- data/spec/prawn/svg/element_spec.rb +1 -1
- data/spec/{lib/svg_spec.rb → prawn/svg/interface_spec.rb} +7 -2
- data/spec/{lib → prawn/svg/parser}/path_spec.rb +0 -0
- data/spec/{lib → prawn/svg}/parser_spec.rb +0 -0
- data/spec/prawn/svg/url_loader_spec.rb +46 -0
- data/spec/sample_images/mushroom-long.jpg +0 -0
- data/spec/sample_images/mushroom-wide.jpg +0 -0
- data/spec/sample_svg/hidden_paths.svg +6 -0
- data/spec/sample_svg/image01.svg +31 -31
- data/spec/sample_svg/negminy.svg +25 -0
- data/spec/sample_svg/viewbox.svg +4 -0
- data/spec/sample_svg/viewport.svg +23 -0
- metadata +30 -8
@@ -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
|
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
|
-
|
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
|
-
|
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
|
data/lib/prawn/svg/version.rb
CHANGED
@@ -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, "@
|
22
|
-
@document.send :instance_variable_set, "@
|
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
|
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
|
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
|
Binary file
|
Binary file
|
@@ -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>
|
data/spec/sample_svg/image01.svg
CHANGED
@@ -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="
|
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="
|
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="
|
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="
|
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="
|
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="
|
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="
|
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="
|
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="
|
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="
|
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="
|
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="
|
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="
|
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="
|
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="
|
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="
|
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="
|
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="
|
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="
|
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="
|
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="
|
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="
|
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="
|
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="
|
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="
|
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="
|
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="
|
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="
|
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="
|
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="
|
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="
|
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>
|