prawn-svg 0.9.1.10 → 0.9.1.11
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/.rspec +2 -0
- data/Gemfile +14 -0
- data/Rakefile +26 -0
- data/lib/prawn/svg/element.rb +7 -2
- data/lib/prawn/svg/font.rb +7 -4
- data/lib/prawn/svg/parser.rb +12 -4
- data/lib/prawn/svg/version.rb +5 -0
- data/prawn-svg.gemspec +23 -0
- data/spec/lib/parser_spec.rb +58 -0
- data/spec/lib/path_spec.rb +38 -0
- data/spec/lib/svg_spec.rb +22 -0
- data/spec/prawn/svg/document_spec.rb +27 -0
- data/spec/prawn/svg/element_spec.rb +32 -0
- data/spec/prawn/svg/font_spec.rb +31 -0
- data/spec/prawn/svg/parser/text_spec.rb +4 -0
- data/spec/sample_output/directory +0 -0
- data/spec/sample_svg/arcs01.svg +21 -0
- data/spec/sample_svg/circle01.svg +12 -0
- data/spec/sample_svg/cubic01.svg +37 -0
- data/spec/sample_svg/cubic01a.svg +40 -0
- data/spec/sample_svg/cubic02.svg +86 -0
- data/spec/sample_svg/ellipse01.svg +17 -0
- data/spec/sample_svg/line01.svg +22 -0
- data/spec/sample_svg/maths.svg +34 -0
- data/spec/sample_svg/omnigraffle.svg +41 -0
- data/spec/sample_svg/opacity01.svg +42 -0
- data/spec/sample_svg/polygon01.svg +17 -0
- data/spec/sample_svg/polyline01.svg +18 -0
- data/spec/sample_svg/quad01.svg +28 -0
- data/spec/sample_svg/rect01.svg +12 -0
- data/spec/sample_svg/rect02.svg +16 -0
- data/spec/sample_svg/rotate_scale.svg +38 -0
- data/spec/sample_svg/scruffy_graph.svg +134 -0
- data/spec/sample_svg/triangle01.svg +12 -0
- data/spec/sample_svg/tspan01.svg +17 -0
- data/spec/sample_svg/tspan02.svg +22 -0
- data/spec/sample_svg/tspan03.svg +21 -0
- data/spec/sample_svg/use.svg +17 -0
- data/spec/spec_helper.rb +9 -0
- metadata +103 -15
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
# Declare your gem's dependencies in prawn-svg.gemspec.
|
4
|
+
# Bundler will treat runtime dependencies like base dependencies, and
|
5
|
+
# development dependencies will be added by default to the :development group.
|
6
|
+
gemspec
|
7
|
+
|
8
|
+
# Declare any dependencies that are still in development here instead of in
|
9
|
+
# your gemspec. These might include edge Rails or gems from your path or
|
10
|
+
# Git. Remember to move these dependencies to your gemspec before releasing
|
11
|
+
# your gem to rubygems.org.
|
12
|
+
|
13
|
+
# To use debugger
|
14
|
+
# gem 'ruby-debug19', :require => 'ruby-debug'
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
|
3
|
+
require 'bundler/gem_tasks'
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'rdoc/task'
|
7
|
+
rescue LoadError
|
8
|
+
require 'rdoc/rdoc'
|
9
|
+
require 'rake/rdoctask'
|
10
|
+
RDoc::Task = Rake::RDocTask
|
11
|
+
end
|
12
|
+
|
13
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
14
|
+
rdoc.rdoc_dir = 'rdoc'
|
15
|
+
rdoc.title = 'prawn-svg documentation'
|
16
|
+
rdoc.options << '--line-numbers'
|
17
|
+
rdoc.rdoc_files.include('README')
|
18
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'rspec/core/rake_task'
|
22
|
+
|
23
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
24
|
+
end
|
25
|
+
|
26
|
+
task :default => :spec
|
data/lib/prawn/svg/element.rb
CHANGED
@@ -56,8 +56,13 @@ class Prawn::Svg::Element
|
|
56
56
|
x, y = x.split(/\s+/) if y.nil?
|
57
57
|
add_call_and_enter name, @document.distance(x), -@document.distance(y)
|
58
58
|
|
59
|
-
when 'rotate'
|
60
|
-
|
59
|
+
when 'rotate'
|
60
|
+
rotation_arguments = arguments.first.split(/\s+/)
|
61
|
+
if (rotation_arguments.length == 3)
|
62
|
+
add_call_and_enter name, -rotation_arguments.first.to_f, :origin => [@document.x(rotation_arguments[1].to_f), @document.y(rotation_arguments[2].to_f)]
|
63
|
+
else
|
64
|
+
add_call_and_enter name, -arguments.first.to_f, :origin => [0, @document.y('0')]
|
65
|
+
end
|
61
66
|
|
62
67
|
when 'scale'
|
63
68
|
args = arguments.first.split(/\s+/)
|
data/lib/prawn/svg/font.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'iconv'
|
2
|
-
|
3
1
|
class Prawn::Svg::Font
|
4
2
|
BUILT_IN_FONTS = ["Courier", "Helvetica", "Times-Roman", "Symbol", "ZapfDingbats"]
|
5
3
|
|
@@ -59,7 +57,7 @@ class Prawn::Svg::Font
|
|
59
57
|
def self.font_information(filename)
|
60
58
|
File.open(filename, "r") do |f|
|
61
59
|
x = f.read(12)
|
62
|
-
table_count = x[4] * 256 + x[5]
|
60
|
+
table_count = x[4].ord * 256 + x[5].ord
|
63
61
|
tables = f.read(table_count * 16)
|
64
62
|
|
65
63
|
offset, length = table_count.times do |index|
|
@@ -86,7 +84,12 @@ class Prawn::Svg::Font
|
|
86
84
|
field = data[offset..offset+length-1]
|
87
85
|
names[name_id] = if platform_id == 0
|
88
86
|
begin
|
89
|
-
|
87
|
+
if field.respond_to?(:encode)
|
88
|
+
field.encode(Encoding::UTF16)
|
89
|
+
else
|
90
|
+
require "iconv"
|
91
|
+
Iconv.iconv('UTF-8', 'UTF-16', field)
|
92
|
+
end
|
90
93
|
rescue
|
91
94
|
field
|
92
95
|
end
|
data/lib/prawn/svg/parser.rb
CHANGED
@@ -59,6 +59,9 @@ class Prawn::Svg::Parser
|
|
59
59
|
"rect" => %w(width height),
|
60
60
|
"path" => %w(d)
|
61
61
|
}
|
62
|
+
|
63
|
+
USE_NEW_CIRCLE_CALL = Prawn::Document.new.respond_to?(:circle)
|
64
|
+
USE_NEW_ELLIPSE_CALL = Prawn::Document.new.respond_to?(:ellipse)
|
62
65
|
|
63
66
|
def parse_element(element)
|
64
67
|
attrs = element.attributes
|
@@ -106,11 +109,16 @@ class Prawn::Svg::Parser
|
|
106
109
|
element.add_call "polygon", *points
|
107
110
|
|
108
111
|
when 'circle'
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
+
if USE_NEW_CIRCLE_CALL
|
113
|
+
element.add_call "circle",
|
114
|
+
[x(attrs['cx'] || "0"), y(attrs['cy'] || "0")], distance(attrs['r'])
|
115
|
+
else
|
116
|
+
element.add_call "circle_at",
|
117
|
+
[x(attrs['cx'] || "0"), y(attrs['cy'] || "0")], :radius => distance(attrs['r'])
|
118
|
+
end
|
119
|
+
|
112
120
|
when 'ellipse'
|
113
|
-
element.add_call "ellipse_at",
|
121
|
+
element.add_call USE_NEW_ELLIPSE_CALL ? "ellipse" : "ellipse_at",
|
114
122
|
[x(attrs['cx'] || "0"), y(attrs['cy'] || "0")], distance(attrs['rx']), distance(attrs['ry'])
|
115
123
|
|
116
124
|
when 'rect'
|
data/prawn-svg.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/prawn/svg/version', __FILE__)
|
3
|
+
|
4
|
+
spec = Gem::Specification.new do |gem|
|
5
|
+
gem.name = 'prawn-svg'
|
6
|
+
gem.version = Prawn::Svg::VERSION
|
7
|
+
gem.summary = "SVG renderer for Prawn PDF library"
|
8
|
+
gem.description = "SVG renderer for Prawn PDF library"
|
9
|
+
gem.has_rdoc = false
|
10
|
+
gem.author = "Roger Nesbitt"
|
11
|
+
gem.email = "roger@seriousorange.com"
|
12
|
+
gem.homepage = "http://github.com/mogest/prawn-svg"
|
13
|
+
|
14
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
15
|
+
gem.files = `git ls-files`.split("\n")
|
16
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
gem.name = "prawn-svg"
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_dependency "prawn", ">= 0.8.4"
|
21
|
+
gem.add_development_dependency "rspec"
|
22
|
+
gem.add_development_dependency "rake"
|
23
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Prawn::Svg::Parser do
|
4
|
+
describe "document width and height" do
|
5
|
+
it "handles the width and height being set as a %" do
|
6
|
+
svg = <<-SVG
|
7
|
+
<svg width="50%" height="50%" version="1.1">
|
8
|
+
<line x1="10%" y1="10%" x2="90%" y2="90%" />
|
9
|
+
</svg>
|
10
|
+
SVG
|
11
|
+
|
12
|
+
document = Prawn::Svg::Document.new(svg, [2000, 2000], {})
|
13
|
+
Prawn::Svg::Parser.new(document).parse[-2][-1].should == [["line", [100.0, 900.0, 900.0, 100.0], []]]
|
14
|
+
end
|
15
|
+
|
16
|
+
it "handles the width and height being set in inches" do
|
17
|
+
svg = <<-SVG
|
18
|
+
<svg width="10in" height="10in" version="1.1">
|
19
|
+
<line x1="1in" y1="1in" x2="9in" y2="9in" />
|
20
|
+
</svg>
|
21
|
+
SVG
|
22
|
+
|
23
|
+
document = Prawn::Svg::Document.new(svg, [2000, 2000], {})
|
24
|
+
Prawn::Svg::Parser.new(document).parse[-2][-1].should == [["line", [72.0, 720.0 - 72.0, 720.0 - 72.0, 72.0], []]]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe :parse_element do
|
29
|
+
before(:each) do
|
30
|
+
@document = Prawn::Svg::Document.new("<svg></svg>", [100, 100], {})
|
31
|
+
@parser = Prawn::Svg::Parser.new(@document)
|
32
|
+
end
|
33
|
+
|
34
|
+
def mock_element(name, attributes = {})
|
35
|
+
e = mock
|
36
|
+
e.stub!(:name).and_return(name)
|
37
|
+
e.stub!(:attributes).and_return(attributes)
|
38
|
+
|
39
|
+
Prawn::Svg::Element.new(@document, e, [], {})
|
40
|
+
end
|
41
|
+
|
42
|
+
it "ignores tags it doesn't know about" do
|
43
|
+
calls = []
|
44
|
+
@parser.send :parse_element, mock_element("unknown")
|
45
|
+
calls.should == []
|
46
|
+
@document.warnings.length.should == 1
|
47
|
+
@document.warnings.first.should include("Unknown tag")
|
48
|
+
end
|
49
|
+
|
50
|
+
it "ignores tags that don't have all required attributes set" do
|
51
|
+
calls = []
|
52
|
+
@parser.send :parse_element, mock_element("ellipse", "rx" => "1")
|
53
|
+
calls.should == []
|
54
|
+
@document.warnings.length.should == 1
|
55
|
+
@document.warnings.first.should include("Must have attributes ry on tag ellipse")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Prawn::Svg::Parser::Path do
|
4
|
+
before :each do
|
5
|
+
@path = Prawn::Svg::Parser::Path.new
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "command parsing" do
|
9
|
+
it "correctly parses a valid path" do
|
10
|
+
calls = []
|
11
|
+
@path.stub!(:run_path_command) {|*args| calls << args}
|
12
|
+
@path.parse("A12.34 -56.78 89B4 5 C 6,7 T QX 0")
|
13
|
+
|
14
|
+
calls.should == [
|
15
|
+
["A", [12.34, -56.78, 89]],
|
16
|
+
["B", [4, 5]],
|
17
|
+
["C", [6, 7]],
|
18
|
+
["T", []],
|
19
|
+
["Q", []],
|
20
|
+
["X", [0]]
|
21
|
+
]
|
22
|
+
end
|
23
|
+
|
24
|
+
it "correctly parses an empty path" do
|
25
|
+
@path.should_not_receive(:run_path_command)
|
26
|
+
@path.parse("").should == []
|
27
|
+
@path.parse(" ").should == []
|
28
|
+
end
|
29
|
+
|
30
|
+
it "raises on invalid characters in the path" do
|
31
|
+
lambda {@path.parse("M 10 % 20")}.should raise_error(Prawn::Svg::Parser::Path::InvalidError)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "raises on numerical data before a command letter" do
|
35
|
+
lambda {@path.parse("10 P")}.should raise_error(Prawn::Svg::Parser::Path::InvalidError)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Prawn::Svg::Interface do
|
4
|
+
describe "sample file rendering" do
|
5
|
+
root = "#{File.dirname(__FILE__)}/../.."
|
6
|
+
files = Dir["#{root}/spec/sample_svg/*.svg"]
|
7
|
+
|
8
|
+
it "has at least 10 SVG sample files to test" do
|
9
|
+
files.length.should >= 10
|
10
|
+
end
|
11
|
+
|
12
|
+
files.each do |file|
|
13
|
+
it "renders the #{File.basename file} sample file without warnings or crashing" do
|
14
|
+
Prawn::Document.generate("#{root}/spec/sample_output/#{File.basename file}.pdf") do
|
15
|
+
r = svg IO.read(file), :at => [0, y], :width => 612 - 72
|
16
|
+
warnings = r[:warnings].reject {|w| w =~ /Verdana/ && w =~ /is not a known font/ }
|
17
|
+
warnings.should == []
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
|
3
|
+
describe Prawn::Svg::Document do
|
4
|
+
before(:each) do
|
5
|
+
@document = Prawn::Svg::Document.new("<svg></svg>", [100, 100], {})
|
6
|
+
end
|
7
|
+
|
8
|
+
describe :points do
|
9
|
+
it "converts a variety of measurement units to points" do
|
10
|
+
@document.send(:points, 32).should == 32.0
|
11
|
+
@document.send(:points, 32.0).should == 32.0
|
12
|
+
@document.send(:points, "32").should == 32.0
|
13
|
+
@document.send(:points, "32unknown").should == 32.0
|
14
|
+
@document.send(:points, "32pt").should == 32.0
|
15
|
+
@document.send(:points, "32in").should == 32.0 * 72
|
16
|
+
@document.send(:points, "32ft").should == 32.0 * 72 * 12
|
17
|
+
@document.send(:points, "32mm").should be_within(0.0001).of(32 * 72 * 0.0393700787)
|
18
|
+
@document.send(:points, "32cm").should be_within(0.0001).of(32 * 72 * 0.393700787)
|
19
|
+
@document.send(:points, "32m").should be_within(0.0001).of(32 * 72 * 39.3700787)
|
20
|
+
|
21
|
+
@document.send :instance_variable_set, "@actual_width", 600
|
22
|
+
@document.send :instance_variable_set, "@actual_height", 400
|
23
|
+
@document.send(:points, "50%").should == 300
|
24
|
+
@document.send(:points, "50%", :y).should == 200
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
|
3
|
+
describe Prawn::Svg::Element do
|
4
|
+
before :each do
|
5
|
+
e = mock
|
6
|
+
e.stub!(:attributes).and_return({})
|
7
|
+
@element = Prawn::Svg::Element.new(nil, e, [], {})
|
8
|
+
end
|
9
|
+
|
10
|
+
describe :color_to_hex do
|
11
|
+
it "converts #xxx to a hex value" do
|
12
|
+
@element.send(:color_to_hex, "#9ab").should == "99aabb"
|
13
|
+
end
|
14
|
+
|
15
|
+
it "converts #xxxxxx to a hex value" do
|
16
|
+
@element.send(:color_to_hex, "#9ab123").should == "9ab123"
|
17
|
+
end
|
18
|
+
|
19
|
+
it "converts an html colour name to a hex value" do
|
20
|
+
@element.send(:color_to_hex, "White").should == "ffffff"
|
21
|
+
end
|
22
|
+
|
23
|
+
it "converts an rgb string to a hex value" do
|
24
|
+
@element.send(:color_to_hex, "rgb(16, 32, 48)").should == "102030"
|
25
|
+
@element.send(:color_to_hex, "rgb(-5, 50%, 120%)").should == "007fff"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "scans the string and finds the first colour it can parse" do
|
29
|
+
@element.send(:color_to_hex, "function(#someurl, 0) nonexistent rgb( 3 ,4,5 ) white").should == "030405"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
|
3
|
+
describe Prawn::Svg::Font do
|
4
|
+
describe :map_font_family_to_pdf_font do
|
5
|
+
it "matches a built in font" do
|
6
|
+
Prawn::Svg::Font.map_font_family_to_pdf_font("blah, 'courier', nothing").should == 'Courier'
|
7
|
+
end
|
8
|
+
|
9
|
+
it "matches a default font" do
|
10
|
+
Prawn::Svg::Font.map_font_family_to_pdf_font("serif").should == 'Times-Roman'
|
11
|
+
Prawn::Svg::Font.map_font_family_to_pdf_font("blah, serif").should == 'Times-Roman'
|
12
|
+
Prawn::Svg::Font.map_font_family_to_pdf_font("blah, serif , test").should == 'Times-Roman'
|
13
|
+
end
|
14
|
+
|
15
|
+
if !Prawn::Svg::Font.installed_fonts.empty?
|
16
|
+
it "matches a font installed on the system" do
|
17
|
+
Prawn::Svg::Font.map_font_family_to_pdf_font("verdana, sans-serif").should == 'verdana'
|
18
|
+
Prawn::Svg::Font.map_font_family_to_pdf_font("VERDANA, sans-serif").should == 'verdana'
|
19
|
+
Prawn::Svg::Font.map_font_family_to_pdf_font("something, \"Times New Roman\", serif").should == "times new roman"
|
20
|
+
Prawn::Svg::Font.map_font_family_to_pdf_font("something, Times New Roman, serif").should == "times new roman"
|
21
|
+
end
|
22
|
+
else
|
23
|
+
it "not running font test because we couldn't find a font directory"
|
24
|
+
end
|
25
|
+
|
26
|
+
it "returns nil if it can't find any such font" do
|
27
|
+
Prawn::Svg::Font.map_font_family_to_pdf_font("blah, thing").should be_nil
|
28
|
+
Prawn::Svg::Font.map_font_family_to_pdf_font("").should be_nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
File without changes
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<?xml version="1.0" standalone="no"?>
|
2
|
+
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
3
|
+
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
4
|
+
<svg width="12cm" height="5.25cm" viewBox="0 0 1200 400"
|
5
|
+
xmlns="http://www.w3.org/2000/svg" version="1.1">
|
6
|
+
<title>Example arcs01 - arc commands in path data</title>
|
7
|
+
<desc>Picture of a pie chart with two pie wedges and
|
8
|
+
a picture of a line with arc blips</desc>
|
9
|
+
<rect x="1" y="1" width="1198" height="398"
|
10
|
+
fill="none" stroke="blue" stroke-width="1" />
|
11
|
+
<path d="M300,200 h-150 a150,150 0 1,0 150,-150 z"
|
12
|
+
fill="red" stroke="blue" stroke-width="5" />
|
13
|
+
<path d="M275,175 v-150 a150,150 0 0,0 -150,150 z"
|
14
|
+
fill="yellow" stroke="blue" stroke-width="5" />
|
15
|
+
<path d="M600,350 l 50,-25
|
16
|
+
a25,25 -30 0,1 50,-25 l 50,-25
|
17
|
+
a25,50 -30 0,1 50,-25 l 50,-25
|
18
|
+
a25,75 -30 0,1 50,-25 l 50,-25
|
19
|
+
a25,100 -30 0,1 50,-25 l 50,-25"
|
20
|
+
fill="none" stroke="red" stroke-width="5" />
|
21
|
+
</svg>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<?xml version="1.0" standalone="no"?>
|
2
|
+
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
3
|
+
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
4
|
+
<svg width="12cm" height="4cm" viewBox="0 0 1200 400"
|
5
|
+
xmlns="http://www.w3.org/2000/svg" version="1.1">
|
6
|
+
<desc>Example circle01 - circle filled with red and stroked with blue</desc>
|
7
|
+
<!-- Show outline of canvas using 'rect' element -->
|
8
|
+
<rect x="1" y="1" width="1198" height="398"
|
9
|
+
fill="none" stroke="blue" stroke-width="2"/>
|
10
|
+
<circle cx="600" cy="200" r="100"
|
11
|
+
fill="red" stroke="blue" stroke-width="10" />
|
12
|
+
</svg>
|
@@ -0,0 +1,37 @@
|
|
1
|
+
<?xml version="1.0" standalone="no"?>
|
2
|
+
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
3
|
+
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
4
|
+
<svg width="5cm" height="4cm" viewBox="0 0 500 400"
|
5
|
+
xmlns="http://www.w3.org/2000/svg" version="1.1">
|
6
|
+
<title>Example cubic01- cubic Bézier commands in path data</title>
|
7
|
+
<desc>Picture showing a simple example of path data
|
8
|
+
using both a "C" and an "S" command,
|
9
|
+
along with annotations showing the control points
|
10
|
+
and end points</desc>
|
11
|
+
<style type="text/css"><![CDATA[
|
12
|
+
.Border { fill:none; stroke:blue; stroke-width:1 }
|
13
|
+
.Connect { fill:none; stroke:#888888; stroke-width:2 }
|
14
|
+
.SamplePath { fill:none; stroke:red; stroke-width:5 }
|
15
|
+
.EndPoint { fill:none; stroke:#888888; stroke-width:2 }
|
16
|
+
.CtlPoint { fill:#888888; stroke:none }
|
17
|
+
.AutoCtlPoint { fill:none; stroke:blue; stroke-width:4 }
|
18
|
+
.Label { font-size:22; font-family:Verdana }
|
19
|
+
]]></style>
|
20
|
+
<rect class="Border" x="1" y="1" width="498" height="398" />
|
21
|
+
<polyline class="Connect" points="100,200 100,100" />
|
22
|
+
<polyline class="Connect" points="250,100 250,200" />
|
23
|
+
<polyline class="Connect" points="250,200 250,300" />
|
24
|
+
<polyline class="Connect" points="400,300 400,200" />
|
25
|
+
<path style=" fill:none; stroke:red; stroke-width:5" d="M100,200 C100,100 250,100 250,200
|
26
|
+
S400,300 400,200" />
|
27
|
+
<circle class="EndPoint" cx="100" cy="200" r="10" />
|
28
|
+
<circle class="EndPoint" cx="250" cy="200" r="10" />
|
29
|
+
<circle class="EndPoint" cx="400" cy="200" r="10" />
|
30
|
+
<circle class="CtlPoint" cx="100" cy="100" r="10" />
|
31
|
+
<circle class="CtlPoint" cx="250" cy="100" r="10" />
|
32
|
+
<circle class="CtlPoint" cx="400" cy="300" r="10" />
|
33
|
+
<circle class="AutoCtlPoint" cx="250" cy="300" r="9" />
|
34
|
+
<text class="Label" x="25" y="70">M100,200 C100,100 250,100 250,200</text>
|
35
|
+
<text class="Label" x="325" y="350"
|
36
|
+
style="text-anchor:middle">S400,300 400,200</text>
|
37
|
+
</svg>
|