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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 13276a5db1c1dd04e219c4e8082205e49dca13ad
4
- data.tar.gz: fc5446141d6e7d6ef9f0a393f64bc975d26e453e
3
+ metadata.gz: dcccb8c6d35a2f33debf7f17d04dc1a8b3099398
4
+ data.tar.gz: 3ac53d2c35c41f1de03582e46175a9bf296a6cd0
5
5
  SHA512:
6
- metadata.gz: 345b0a1c89e7bd4aad297bbcc398322ea7d72ca51a3ac13ea22fdfa62ed0c42ea60344940880f9c570e60f0d21b669e7b3f73ff3791aff16fef87c21c92181d6
7
- data.tar.gz: 23391e2209dde7f293c12f4f36af60fc421bea3e05a74b6acd5249bb81c249b0f9bcd8f3c66898f696febf7102ac6157ab836d7d98c20764e0074d2544d6a5f3
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> must be specified.
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 does not support the full SVG specification. It currently supports:
34
+ prawn-svg supports most but not all of the full SVG 1.1 specification. It currently supports:
33
35
 
34
36
  - <tt>&lt;line&gt;</tt>, <tt>&lt;polyline&gt;</tt>, <tt>&lt;polygon&gt;</tt>, <tt>&lt;circle&gt;</tt> and <tt>&lt;ellipse&gt;</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>&lt;text&gt;</tt> and <tt>&lt;tspan&gt;</tt> with attributes
42
- <tt>size</tt>, <tt>text-anchor</tt>, <tt>font-family</tt>, <tt>font-weight</tt>, <tt>dx</tt>, <tt>dy</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>&lt;svg&gt;</tt>, <tt>&lt;g&gt;</tt> and <tt>&lt;symbol&gt;</tt>
45
47
 
46
48
  - <tt>&lt;use&gt;</tt>
47
49
 
48
- - <tt>&lt;style&gt;</tt>, if css_parser gem is installed on the system (see CSS section below)
50
+ - <tt>&lt;style&gt;</tt> plus <tt>id</tt>, <tt>class</tt> and <tt>style</tt> attributes (see CSS section below)
49
51
 
50
52
  - <tt>&lt;image&gt;</tt> with <tt>http:</tt>, <tt>https:</tt> and <tt>data:image/*;base64</tt> schemes
51
53
 
52
54
  - <tt>&lt;clipPath&gt;</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>&lt;svg&gt;</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 in PDF fonts, and any TTF fonts in your fonts path
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>&lt;style&gt;</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
 
@@ -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
- # +options+ must contain the key :at, which takes a tuple of x and y co-ordinates.
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
- # +options+ can optionally contain the key :width or :height. If both are
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(@options[:at], :width => @document.sizing.output_width, :height => @document.sizing.output_height) do
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
@@ -1,5 +1,5 @@
1
1
  module Prawn
2
2
  module Svg
3
- VERSION = '0.18.0'
3
+ VERSION = '0.19.0'
4
4
  end
5
5
  end
@@ -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
- root = "#{File.dirname(__FILE__)}/../../.."
5
-
6
- describe "sample file rendering" do
7
- files = Dir["#{root}/spec/sample_svg/*.svg"]
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
- it "has at least 10 SVG sample files to test" do
10
- files.length.should >= 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
- files.each do |file|
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
- describe "multiple file rendering" do
31
- it "renders multiple files on to the same PDF" do
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
- y = prawn.bounds.top - 12
36
- prawn.draw_text "This is multiple SVGs being output to the same PDF", :at => [0, y]
36
+ subject { interface.position }
37
37
 
38
- y -= 12
39
- prawn.svg IO.read("#{root}/spec/sample_svg/arcs01.svg"), :at => [0, y], :width => width / 2
40
- prawn.svg IO.read("#{root}/spec/sample_svg/circle01.svg"), :at => [width / 2, y], :width => width / 2
38
+ context "(:left)" do
39
+ let(:position) { :left }
40
+ it { is_expected.to eq [0, 600] }
41
+ end
41
42
 
42
- y -= 120
43
- prawn.draw_text "Here are some more PDFs below", :at => [0, y]
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
- y -= 12
46
- prawn.svg IO.read("#{root}/spec/sample_svg/quad01.svg"), :at => [0, y], :width => width / 3
47
- prawn.svg IO.read("#{root}/spec/sample_svg/rect01.svg"), :at => [width / 3, y], :width => width / 3
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.18.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-05-02 00:00:00.000000000 Z
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