prawn-svg 0.18.0 → 0.19.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.
- checksums.yaml +4 -4
- data/README.md +9 -9
- data/lib/prawn/svg/calculators/document_sizing.rb +1 -0
- data/lib/prawn/svg/interface.rb +51 -6
- data/lib/prawn/svg/version.rb +1 -1
- data/spec/integration_spec.rb +83 -0
- data/spec/prawn/svg/interface_spec.rb +42 -35
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dcccb8c6d35a2f33debf7f17d04dc1a8b3099398
|
4
|
+
data.tar.gz: 3ac53d2c35c41f1de03582e46175a9bf296a6cd0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ea4c6fb099669924881a72e4d983a5b890a4e74d38eb5bc7e1173223485acc35a69b0dabf95c41329bc1c254a6be53771d98f5e13fcf5d5c118c2fa1b2bd85ce
|
7
|
+
data.tar.gz: d3440e0c86365ad251beec2011f1f243dfc35e24ee82af3684c925e2e9c08d4b44e416e366cbd036343908241567cfd75878929bc5ce98fa9e4f81cdde963317
|
data/README.md
CHANGED
@@ -16,7 +16,9 @@ Prawn::Document.generate("svg.pdf") do
|
|
16
16
|
end
|
17
17
|
```
|
18
18
|
|
19
|
-
<tt>:at</tt>
|
19
|
+
Supply <tt>:at</tt> if you want to render it at a specific location on the page.
|
20
|
+
Use <tt>:position</tt> with a value of <tt>:left</tt>, <tt>:center</tt>, <tt>:right</tt> or a number to render it at the current cursor position, or use <tt>:vposition</tt> with a value
|
21
|
+
of <tt>:top</tt>, <tt>:center</tt>, <tt>:bottom</tt> or a number to specify its Y position too.
|
20
22
|
|
21
23
|
Either <tt>:width</tt>, <tt>:height</tt>, or neither may be specified; if neither is present,
|
22
24
|
the dimensions specified in the SVG will be used, or if the dimensions aren't specified, it'll
|
@@ -29,7 +31,7 @@ If this value is set to <tt>nil</tt>, prawn-svg will ignore a request for an unk
|
|
29
31
|
|
30
32
|
## Supported features
|
31
33
|
|
32
|
-
prawn-svg
|
34
|
+
prawn-svg supports most but not all of the full SVG 1.1 specification. It currently supports:
|
33
35
|
|
34
36
|
- <tt><line></tt>, <tt><polyline></tt>, <tt><polygon></tt>, <tt><circle></tt> and <tt><ellipse></tt>
|
35
37
|
|
@@ -39,21 +41,19 @@ prawn-svg does not support the full SVG specification. It currently supports:
|
|
39
41
|
implementation of elliptical arc is a bit rough at the moment.
|
40
42
|
|
41
43
|
- <tt><text></tt> and <tt><tspan></tt> with attributes
|
42
|
-
<tt>
|
44
|
+
<tt>text-anchor</tt>, <tt>font-size</tt>, <tt>font-family</tt>, <tt>font-weight</tt>, <tt>font-style</tt>, <tt>dx</tt>, <tt>dy</tt>
|
43
45
|
|
44
46
|
- <tt><svg></tt>, <tt><g></tt> and <tt><symbol></tt>
|
45
47
|
|
46
48
|
- <tt><use></tt>
|
47
49
|
|
48
|
-
- <tt><style></tt
|
50
|
+
- <tt><style></tt> plus <tt>id</tt>, <tt>class</tt> and <tt>style</tt> attributes (see CSS section below)
|
49
51
|
|
50
52
|
- <tt><image></tt> with <tt>http:</tt>, <tt>https:</tt> and <tt>data:image/*;base64</tt> schemes
|
51
53
|
|
52
54
|
- <tt><clipPath></tt>
|
53
55
|
|
54
|
-
- 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>, <tt>clip-path</tt>
|
55
|
-
|
56
|
-
- attribute <tt>stroke-linecap</tt>, but only when <tt>fill="none"</tt> due to a PDF limitation
|
56
|
+
- attributes/styles: <tt>fill</tt>, <tt>stroke</tt>, <tt>stroke-width</tt>, <tt>stroke-linecap</tt>, <tt>stroke-dasharray</tt>, <tt>opacity</tt>, <tt>fill-opacity</tt>, <tt>stroke-opacity</tt>, <tt>transform</tt>, <tt>clip-path</tt>, <tt>display</tt>
|
57
57
|
|
58
58
|
- the <tt>viewBox</tt> attribute on the <tt><svg></tt> tag
|
59
59
|
|
@@ -65,7 +65,7 @@ prawn-svg does not support the full SVG specification. It currently supports:
|
|
65
65
|
|
66
66
|
- measurements specified in <tt>pt</tt>, <tt>cm</tt>, <tt>dm</tt>, <tt>ft</tt>, <tt>in</tt>, <tt>m</tt>, <tt>mm</tt>, <tt>yd</tt>, <tt>pc</tt>, <tt>%</tt>
|
67
67
|
|
68
|
-
- fonts: generic CSS fonts, built
|
68
|
+
- fonts: generic CSS fonts, built-in PDF fonts, and any TTF fonts in your fonts path
|
69
69
|
|
70
70
|
## CSS
|
71
71
|
|
@@ -73,7 +73,7 @@ prawn-svg uses the css_parser gem to parse CSS <tt><style></tt> blocks. I
|
|
73
73
|
|
74
74
|
## Not supported
|
75
75
|
|
76
|
-
prawn-svg does not support external references, measurements in <tt>en</tt> or <tt>em</tt>, sub-viewports, gradients/patterns or markers.
|
76
|
+
prawn-svg does not support external <tt>url()</tt> references, measurements in <tt>en</tt> or <tt>em</tt>, sub-viewports, gradients/patterns or markers.
|
77
77
|
|
78
78
|
## Configuration
|
79
79
|
|
@@ -4,6 +4,7 @@ module Prawn::Svg::Calculators
|
|
4
4
|
attr_writer :view_box, :preserve_aspect_ratio
|
5
5
|
attr_writer :requested_width, :requested_height
|
6
6
|
|
7
|
+
attr_reader :bounds
|
7
8
|
attr_reader :x_offset, :y_offset, :x_scale, :y_scale
|
8
9
|
attr_reader :viewport_width, :viewport_height, :viewport_diagonal, :output_width, :output_height
|
9
10
|
|
data/lib/prawn/svg/interface.rb
CHANGED
@@ -5,6 +5,8 @@
|
|
5
5
|
module Prawn
|
6
6
|
module Svg
|
7
7
|
class Interface
|
8
|
+
VALID_OPTIONS = [:at, :position, :vposition, :width, :height, :cache_images, :fallback_font_name]
|
9
|
+
|
8
10
|
DEFAULT_FONT_PATHS = ["/Library/Fonts", "/System/Library/Fonts", "#{ENV["HOME"]}/Library/Fonts", "/usr/share/fonts/truetype"]
|
9
11
|
|
10
12
|
@font_path = []
|
@@ -19,18 +21,25 @@ module Prawn
|
|
19
21
|
#
|
20
22
|
# +data+ is the SVG data to convert. +prawn+ is your Prawn::Document object.
|
21
23
|
#
|
22
|
-
#
|
24
|
+
# Options:
|
25
|
+
# <tt>:at</tt>:: an array [x,y] specifying the location of the top-left corner of the SVG.
|
26
|
+
# <tt>:position</tt>:: one of (nil, :left, :center, :right) or an x-offset
|
27
|
+
# <tt>:vposition</tt>:: one of (nil, :top, :center, :bottom) or a y-offset
|
28
|
+
# <tt>:width</tt>:: the width that the SVG is to be rendered
|
29
|
+
# <tt>:height</tt>:: the height that the SVG is to be rendered
|
30
|
+
#
|
31
|
+
# If <tt>:at</tt> is provided, the SVG will be placed in the current page but
|
32
|
+
# the text position will not be changed.
|
23
33
|
#
|
24
|
-
#
|
25
|
-
# specified, only :width will be used.
|
34
|
+
# If both <tt>:width</tt> and <tt>:height</tt> are specified, only the width will be used.
|
26
35
|
#
|
27
36
|
def initialize(data, prawn, options, &block)
|
37
|
+
Prawn.verify_options VALID_OPTIONS, options
|
38
|
+
|
28
39
|
@data = data
|
29
40
|
@prawn = prawn
|
30
41
|
@options = options
|
31
42
|
|
32
|
-
@options[:at] or raise "options[:at] must be specified"
|
33
|
-
|
34
43
|
Prawn::Svg::Font.load_external_fonts(prawn.font_families)
|
35
44
|
|
36
45
|
@document = Document.new(data, [prawn.bounds.width, prawn.bounds.height], options, &block)
|
@@ -40,7 +49,7 @@ module Prawn
|
|
40
49
|
# Draws the SVG to the Prawn::Document object.
|
41
50
|
#
|
42
51
|
def draw
|
43
|
-
prawn.bounding_box(
|
52
|
+
prawn.bounding_box(position, :width => @document.sizing.output_width, :height => @document.sizing.output_height) do
|
44
53
|
prawn.save_graphics_state do
|
45
54
|
clip_rectangle 0, 0, @document.sizing.output_width, @document.sizing.output_height
|
46
55
|
proc_creator(prawn, Parser.new(@document).parse).call
|
@@ -48,8 +57,44 @@ module Prawn
|
|
48
57
|
end
|
49
58
|
end
|
50
59
|
|
60
|
+
def position
|
61
|
+
@options[:at] || [x_based_on_requested_alignment, y_based_on_requested_alignment]
|
62
|
+
end
|
51
63
|
|
52
64
|
private
|
65
|
+
|
66
|
+
def x_based_on_requested_alignment
|
67
|
+
case options[:position]
|
68
|
+
when :left, nil
|
69
|
+
0
|
70
|
+
when :center, :centre
|
71
|
+
(@document.sizing.bounds[0] - @document.sizing.output_width) / 2.0
|
72
|
+
when :right
|
73
|
+
@document.sizing.bounds[0] - @document.sizing.output_width
|
74
|
+
when Numeric
|
75
|
+
options[:position]
|
76
|
+
else
|
77
|
+
raise ArgumentError, "options[:position] must be one of nil, :left, :right, :center or a number"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def y_based_on_requested_alignment
|
82
|
+
case options[:vposition]
|
83
|
+
when nil
|
84
|
+
prawn.cursor
|
85
|
+
when :top
|
86
|
+
@document.sizing.bounds[1]
|
87
|
+
when :center, :centre
|
88
|
+
@document.sizing.bounds[1] - (@document.sizing.bounds[1] - @document.sizing.output_height) / 2.0
|
89
|
+
when :bottom
|
90
|
+
@document.sizing.output_height
|
91
|
+
when Numeric
|
92
|
+
@document.sizing.bounds[1] - options[:vposition]
|
93
|
+
else
|
94
|
+
raise ArgumentError, "options[:vposition] must be one of nil, :top, :right, :bottom or a number"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
53
98
|
def proc_creator(prawn, calls)
|
54
99
|
Proc.new {issue_prawn_command(prawn, calls)}
|
55
100
|
end
|
data/lib/prawn/svg/version.rb
CHANGED
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Prawn::Svg::Interface do
|
4
|
+
root = "#{File.dirname(__FILE__)}/.."
|
5
|
+
|
6
|
+
context "with option :position" do
|
7
|
+
let(:svg) { IO.read("#{root}/spec/sample_svg/cubic01a.svg") }
|
8
|
+
|
9
|
+
it "aligns the image as requested" do
|
10
|
+
Prawn::Document.generate("#{root}/spec/sample_output/_with_position.pdf") do |prawn|
|
11
|
+
width = prawn.bounds.width / 3
|
12
|
+
|
13
|
+
prawn.svg svg, :width => width, :position => :left
|
14
|
+
prawn.svg svg, :width => width, :position => :center
|
15
|
+
prawn.svg svg, :width => width, :position => :right
|
16
|
+
prawn.svg svg, :width => width, :position => 50
|
17
|
+
prawn.svg svg, :width => width
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context "with option :vposition" do
|
23
|
+
let(:svg) { IO.read("#{root}/spec/sample_svg/cubic01a.svg") }
|
24
|
+
|
25
|
+
it "aligns the image as requested" do
|
26
|
+
Prawn::Document.generate("#{root}/spec/sample_output/_with_vposition.pdf") do |prawn|
|
27
|
+
width = prawn.bounds.width / 3
|
28
|
+
|
29
|
+
prawn.svg svg, :width => width, :position => :left, :vposition => :bottom
|
30
|
+
prawn.svg svg, :width => width, :position => :center, :vposition => :center
|
31
|
+
prawn.svg svg, :width => width, :position => :right, :vposition => :top
|
32
|
+
prawn.svg svg, :width => width, :position => 50, :vposition => 50
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "sample file rendering" do
|
38
|
+
files = Dir["#{root}/spec/sample_svg/*.svg"]
|
39
|
+
|
40
|
+
it "has at least 10 SVG sample files to test" do
|
41
|
+
files.length.should >= 10
|
42
|
+
end
|
43
|
+
|
44
|
+
files.each do |file|
|
45
|
+
it "renders the #{File.basename file} sample file without warnings or crashing" do
|
46
|
+
warnings = nil
|
47
|
+
Prawn::Document.generate("#{root}/spec/sample_output/#{File.basename file}.pdf") do |prawn|
|
48
|
+
r = prawn.svg IO.read(file), :at => [0, prawn.bounds.top], :width => prawn.bounds.width do |doc|
|
49
|
+
doc.url_loader.enable_web = false
|
50
|
+
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")
|
51
|
+
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")
|
52
|
+
end
|
53
|
+
|
54
|
+
warnings = r[:warnings].reject {|w| w =~ /Verdana/ && w =~ /is not a known font/ }
|
55
|
+
end
|
56
|
+
warnings.should == []
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "multiple file rendering" do
|
62
|
+
it "renders multiple files on to the same PDF" do
|
63
|
+
Prawn::Document.generate("#{root}/spec/sample_output/_multiple.pdf") do |prawn|
|
64
|
+
width = prawn.bounds.width
|
65
|
+
|
66
|
+
y = prawn.bounds.top - 12
|
67
|
+
prawn.draw_text "This is multiple SVGs being output to the same PDF", :at => [0, y]
|
68
|
+
|
69
|
+
y -= 12
|
70
|
+
prawn.svg IO.read("#{root}/spec/sample_svg/arcs01.svg"), :at => [0, y], :width => width / 2
|
71
|
+
prawn.svg IO.read("#{root}/spec/sample_svg/circle01.svg"), :at => [width / 2, y], :width => width / 2
|
72
|
+
|
73
|
+
y -= 120
|
74
|
+
prawn.draw_text "Here are some more PDFs below", :at => [0, y]
|
75
|
+
|
76
|
+
y -= 12
|
77
|
+
prawn.svg IO.read("#{root}/spec/sample_svg/quad01.svg"), :at => [0, y], :width => width / 3
|
78
|
+
prawn.svg IO.read("#{root}/spec/sample_svg/rect01.svg"), :at => [width / 3, y], :width => width / 3
|
79
|
+
prawn.svg IO.read("#{root}/spec/sample_svg/rect02.svg"), :at => [width / 3 * 2, y], :width => width / 3
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -1,51 +1,58 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Prawn::Svg::Interface do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
let(:bounds) { double(width: 800, height: 600) }
|
5
|
+
let(:prawn) { instance_double(Prawn::Document, font_families: {}, bounds: bounds, cursor: 600) }
|
6
|
+
let(:svg) { '<svg width="250" height="100"></svg>' }
|
7
|
+
|
8
|
+
describe "#initialize" do
|
9
|
+
describe "invalid option detection" do
|
10
|
+
it "rejects invalid options when debug is on" do
|
11
|
+
allow(Prawn).to receive(:debug).and_return(true)
|
12
|
+
|
13
|
+
expect {
|
14
|
+
Prawn::Svg::Interface.new(svg, prawn, :invalid => "option")
|
15
|
+
}.to raise_error(Prawn::Errors::UnknownOption)
|
16
|
+
end
|
8
17
|
|
9
|
-
|
10
|
-
|
18
|
+
it "does nothing if an invalid option is given and debug is off" do
|
19
|
+
Prawn::Svg::Interface.new(svg, prawn, :invalid => "option")
|
20
|
+
end
|
11
21
|
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#position" do
|
25
|
+
context "when options[:at] supplied" do
|
26
|
+
it "returns options[:at]" do
|
27
|
+
interface = Prawn::Svg::Interface.new(svg, prawn, at: [1, 2], position: :left)
|
12
28
|
|
13
|
-
|
14
|
-
it "renders the #{File.basename file} sample file without warnings or crashing" do
|
15
|
-
warnings = nil
|
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 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
|
-
|
23
|
-
warnings = r[:warnings].reject {|w| w =~ /Verdana/ && w =~ /is not a known font/ }
|
24
|
-
end
|
25
|
-
warnings.should == []
|
29
|
+
expect(interface.position).to eq [1, 2]
|
26
30
|
end
|
27
31
|
end
|
28
|
-
end
|
29
32
|
|
30
|
-
|
31
|
-
|
32
|
-
Prawn::Document.generate("#{root}/spec/sample_output/multiple.pdf") do |prawn|
|
33
|
-
width = prawn.bounds.width
|
33
|
+
context "when only a position is supplied" do
|
34
|
+
let(:interface) { Prawn::Svg::Interface.new(svg, prawn, position: position) }
|
34
35
|
|
35
|
-
|
36
|
-
prawn.draw_text "This is multiple SVGs being output to the same PDF", :at => [0, y]
|
36
|
+
subject { interface.position }
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
|
38
|
+
context "(:left)" do
|
39
|
+
let(:position) { :left }
|
40
|
+
it { is_expected.to eq [0, 600] }
|
41
|
+
end
|
41
42
|
|
42
|
-
|
43
|
-
|
43
|
+
context "(:center)" do
|
44
|
+
let(:position) { :center }
|
45
|
+
it { is_expected.to eq [275, 600] }
|
46
|
+
end
|
47
|
+
|
48
|
+
context "(:right)" do
|
49
|
+
let(:position) { :right }
|
50
|
+
it { is_expected.to eq [550, 600] }
|
51
|
+
end
|
44
52
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
prawn.svg IO.read("#{root}/spec/sample_svg/rect02.svg"), :at => [width / 3 * 2, y], :width => width / 3
|
53
|
+
context "a number" do
|
54
|
+
let(:position) { 25.5 }
|
55
|
+
it { is_expected.to eq [25.5, 600] }
|
49
56
|
end
|
50
57
|
end
|
51
58
|
end
|
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.
|
4
|
+
version: 0.19.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Roger Nesbitt
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-06-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: prawn
|
@@ -103,6 +103,7 @@ files:
|
|
103
103
|
- lib/prawn/svg/url_loader.rb
|
104
104
|
- lib/prawn/svg/version.rb
|
105
105
|
- prawn-svg.gemspec
|
106
|
+
- spec/integration_spec.rb
|
106
107
|
- spec/prawn/svg/calculators/aspect_ratio_spec.rb
|
107
108
|
- spec/prawn/svg/calculators/document_sizing_spec.rb
|
108
109
|
- spec/prawn/svg/color_spec.rb
|
@@ -186,6 +187,7 @@ signing_key:
|
|
186
187
|
specification_version: 4
|
187
188
|
summary: SVG renderer for Prawn PDF library
|
188
189
|
test_files:
|
190
|
+
- spec/integration_spec.rb
|
189
191
|
- spec/prawn/svg/calculators/aspect_ratio_spec.rb
|
190
192
|
- spec/prawn/svg/calculators/document_sizing_spec.rb
|
191
193
|
- spec/prawn/svg/color_spec.rb
|