prawn-svg 0.15.0.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 +20 -12
- data/lib/prawn/svg/calculators/aspect_ratio.rb +58 -0
- data/lib/prawn/svg/calculators/document_sizing.rb +75 -0
- data/lib/prawn/svg/calculators/pixels.rb +21 -0
- data/lib/prawn/svg/document.rb +16 -43
- data/lib/prawn/svg/element.rb +71 -18
- data/lib/prawn/svg/extension.rb +3 -3
- data/lib/prawn/svg/interface.rb +80 -19
- data/lib/prawn/svg/parser/image.rb +9 -62
- data/lib/prawn/svg/parser/path.rb +19 -1
- data/lib/prawn/svg/parser/text.rb +2 -0
- data/lib/prawn/svg/parser.rb +53 -18
- data/lib/prawn/svg/url_loader.rb +34 -0
- data/lib/prawn/svg/version.rb +1 -1
- data/lib/prawn-svg.rb +4 -0
- data/prawn-svg.gemspec +7 -4
- data/spec/integration_spec.rb +83 -0
- 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 +21 -17
- data/spec/prawn/svg/element_spec.rb +1 -1
- data/spec/prawn/svg/interface_spec.rb +59 -0
- data/spec/prawn/svg/parser/path_spec.rb +89 -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/cap_styles.svg +13 -0
- data/spec/sample_svg/display_none.svg +13 -0
- data/spec/sample_svg/gistfile1.svg +36 -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/path.svg +5 -0
- data/spec/sample_svg/pie_piece.svg +7 -0
- data/spec/sample_svg/viewbox.svg +4 -0
- data/spec/sample_svg/viewport.svg +23 -0
- data/spec/spec_helper.rb +7 -0
- metadata +81 -25
- data/spec/lib/path_spec.rb +0 -54
- data/spec/lib/svg_spec.rb +0 -47
- /data/spec/{lib → prawn/svg}/parser_spec.rb +0 -0
@@ -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
|
@@ -1,27 +1,31 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
2
|
|
3
3
|
describe Prawn::Svg::Document do
|
4
|
-
before
|
5
|
-
|
4
|
+
before do
|
5
|
+
sizing = instance_double(Prawn::Svg::Calculators::DocumentSizing, viewport_width: 600, viewport_height: 400, viewport_diagonal: 500, :requested_width= => nil, :requested_height= => nil)
|
6
|
+
expect(sizing).to receive(:calculate)
|
7
|
+
expect(Prawn::Svg::Calculators::DocumentSizing).to receive(:new).and_return(sizing)
|
6
8
|
end
|
7
9
|
|
10
|
+
let(:document) { Prawn::Svg::Document.new("<svg></svg>", [100, 100], {}) }
|
11
|
+
|
8
12
|
describe :points do
|
9
13
|
it "converts a variety of measurement units to points" do
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
14
|
+
document.send(:points, 32).should == 32.0
|
15
|
+
document.send(:points, 32.0).should == 32.0
|
16
|
+
document.send(:points, "32").should == 32.0
|
17
|
+
document.send(:points, "32unknown").should == 32.0
|
18
|
+
document.send(:points, "32pt").should == 32.0
|
19
|
+
document.send(:points, "32in").should == 32.0 * 72
|
20
|
+
document.send(:points, "32ft").should == 32.0 * 72 * 12
|
21
|
+
document.send(:points, "32pc").should == 32.0 * 15
|
22
|
+
document.send(:points, "32mm").should be_within(0.0001).of(32 * 72 * 0.0393700787)
|
23
|
+
document.send(:points, "32cm").should be_within(0.0001).of(32 * 72 * 0.393700787)
|
24
|
+
document.send(:points, "32m").should be_within(0.0001).of(32 * 72 * 39.3700787)
|
25
|
+
|
26
|
+
document.send(:points, "50%").should == 250
|
27
|
+
document.send(:points, "50%", :x).should == 300
|
28
|
+
document.send(:points, "50%", :y).should == 200
|
25
29
|
end
|
26
30
|
end
|
27
31
|
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, [], {})
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Prawn::Svg::Interface do
|
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
|
17
|
+
|
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
|
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)
|
28
|
+
|
29
|
+
expect(interface.position).to eq [1, 2]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "when only a position is supplied" do
|
34
|
+
let(:interface) { Prawn::Svg::Interface.new(svg, prawn, position: position) }
|
35
|
+
|
36
|
+
subject { interface.position }
|
37
|
+
|
38
|
+
context "(:left)" do
|
39
|
+
let(:position) { :left }
|
40
|
+
it { is_expected.to eq [0, 600] }
|
41
|
+
end
|
42
|
+
|
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
|
52
|
+
|
53
|
+
context "a number" do
|
54
|
+
let(:position) { 25.5 }
|
55
|
+
it { is_expected.to eq [25.5, 600] }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Prawn::Svg::Parser::Path do
|
4
|
+
let(:path) { Prawn::Svg::Parser::Path.new }
|
5
|
+
|
6
|
+
describe "command parsing" do
|
7
|
+
it "correctly parses a valid path" do
|
8
|
+
calls = []
|
9
|
+
path.stub(:run_path_command) {|*args| calls << args}
|
10
|
+
path.parse("A12.34 -56.78 89B4 5 12-34 -.5.7+3 2.3e3 4e4 4e+4 c31,-2e-5C 6,7 T QX 0 Z")
|
11
|
+
|
12
|
+
calls.should == [
|
13
|
+
["A", [12.34, -56.78, 89]],
|
14
|
+
["B", [4, 5, 12, -34, -0.5, 0.7, 3, 2.3e3, 4e4, 4e4]],
|
15
|
+
["c", [31, -2e-5]],
|
16
|
+
["C", [6, 7]],
|
17
|
+
["T", []],
|
18
|
+
["Q", []],
|
19
|
+
["X", [0]],
|
20
|
+
["Z", []]
|
21
|
+
]
|
22
|
+
end
|
23
|
+
|
24
|
+
it "treats subsequent points to m/M command as relative/absolute depending on command" do
|
25
|
+
[
|
26
|
+
["M", [1,2,3,4]],
|
27
|
+
["L", [3,4]],
|
28
|
+
["m", [5,6,7,8]],
|
29
|
+
["l", [7,8]]
|
30
|
+
].each do |args|
|
31
|
+
path.should_receive(:run_path_command).with(*args).and_call_original
|
32
|
+
end
|
33
|
+
|
34
|
+
path.parse("M 1,2 3,4 m 5,6 7,8")
|
35
|
+
end
|
36
|
+
|
37
|
+
it "correctly parses an empty path" do
|
38
|
+
path.should_not_receive(:run_path_command)
|
39
|
+
path.parse("").should == []
|
40
|
+
path.parse(" ").should == []
|
41
|
+
end
|
42
|
+
|
43
|
+
it "raises on invalid characters in the path" do
|
44
|
+
lambda {path.parse("M 10 % 20")}.should raise_error(Prawn::Svg::Parser::Path::InvalidError)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "raises on numerical data before a command letter" do
|
48
|
+
lambda {path.parse("10 P")}.should raise_error(Prawn::Svg::Parser::Path::InvalidError)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "when given an A path" do
|
53
|
+
it "uses bezier curves to approximate an arc path" do
|
54
|
+
result = path.parse("M 100 200 A 10 10 0 0 1 200 200")
|
55
|
+
|
56
|
+
expect(result).to eq [
|
57
|
+
["move_to", [100.0, 200.0]],
|
58
|
+
["curve_to", [150.0, 150.0, 100.0, 172.57081148225683, 122.57081148225683, 150.0]],
|
59
|
+
["curve_to", [200.0, 200.0, 177.42918851774317, 150.0, 200.0, 172.57081148225683]]
|
60
|
+
]
|
61
|
+
end
|
62
|
+
|
63
|
+
it "ignores a path that has an identical start and end point" do
|
64
|
+
result = path.parse("M 100 200 A 30 30 0 0 1 100 200")
|
65
|
+
|
66
|
+
expect(result).to eq [
|
67
|
+
["move_to", [100.0, 200.0]]
|
68
|
+
]
|
69
|
+
end
|
70
|
+
|
71
|
+
it "substitutes a line_to when rx is 0" do
|
72
|
+
result = path.parse("M 100 200 A 0 10 0 0 1 200 200")
|
73
|
+
|
74
|
+
expect(result).to eq [
|
75
|
+
["move_to", [100.0, 200.0]],
|
76
|
+
["line_to", [200.0, 200.0]]
|
77
|
+
]
|
78
|
+
end
|
79
|
+
|
80
|
+
it "substitutes a line_to when ry is 0" do
|
81
|
+
result = path.parse("M 100 200 A 10 0 0 0 1 200 200")
|
82
|
+
|
83
|
+
expect(result).to eq [
|
84
|
+
["move_to", [100.0, 200.0]],
|
85
|
+
["line_to", [200.0, 200.0]]
|
86
|
+
]
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -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,13 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="1100" height="210">
|
2
|
+
<rect x="100" y="100" width="900" height="100" fill="none" stroke="blue" stroke-width="2" />
|
3
|
+
|
4
|
+
<g stroke="green" stroke-width="10">
|
5
|
+
<line x1="120" y1="110" x2="120" y2="190" />
|
6
|
+
<line x1="140" y1="110" x2="140" y2="190" stroke-linecap="butt" />
|
7
|
+
<line x1="160" y1="110" x2="160" y2="190" stroke-linecap="round" />
|
8
|
+
<line x1="180" y1="110" x2="180" y2="190" stroke-linecap="square" />
|
9
|
+
<line x1="200" y1="110" x2="200" y2="190" />
|
10
|
+
<line x1="220" y1="110" x2="220" y2="190" stroke-linecap="invalid" />
|
11
|
+
</g>
|
12
|
+
</svg>
|
13
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
2
|
+
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" width="800" height="600">
|
3
|
+
<g id="layer1" style="display:none">
|
4
|
+
<rect x="350" y="200" width="20" height="20" fill="green" />
|
5
|
+
<text x="361.80859" y="200" id="text2986" xml:space="preserve" style="font-size:24px;font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Helvetica">
|
6
|
+
<tspan x="361.80859" y="200" id="tspan2988">Hidden</tspan>
|
7
|
+
</text>
|
8
|
+
</g>
|
9
|
+
<g id="layer2">
|
10
|
+
<text x="365.24805" y="300" id="text2990" xml:space="preserve" style="font-size:24px;font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Helvetica">
|
11
|
+
<tspan x="365.24805" y="300" id="tspan2992">Visible</tspan></text>
|
12
|
+
</g>
|
13
|
+
</svg>
|
@@ -0,0 +1,36 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
2
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="205pt" style="width:362px;height:205px;" version="1.1" viewBox="0 0 362 205" width="362pt">
|
3
|
+
<g>
|
4
|
+
<line style="stroke: blue; stroke-width: 1.0; stroke-dasharray: 20,40;" x1="146" x2="146" y1="35.4883" y2="204.041"/>
|
5
|
+
<line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="204" x2="204" y1="35.4883" y2="204.041"/>
|
6
|
+
<rect fill="#FEFECE" height="30.4883" style="stroke: #A80036; stroke-width: 1.5;" width="47" x="121" y="0"/>
|
7
|
+
<text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="33" x="128" y="20.5352">Alice</text>
|
8
|
+
<rect fill="#FEFECE" height="30.4883" style="stroke: #A80036; stroke-width: 1.5;" width="40" x="182" y="0"/>
|
9
|
+
<text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="26" x="189" y="20.5352">Bob</text>
|
10
|
+
<polygon fill="#A80036" points="192,67.4883,202,71.4883,192,75.4883,196,71.4883" style="stroke: #A80036; stroke-width: 1.0;"/>
|
11
|
+
<line style="stroke: #A80036; stroke-width: 1.0;" x1="146.5" x2="198" y1="71.4883" y2="71.4883"/>
|
12
|
+
<text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="31" x="153.5" y="67.0566">hello</text>
|
13
|
+
<polygon fill="#FBFB77" points="5,50.4883,5,75.4883,138,75.4883,138,60.4883,128,50.4883,5,50.4883" style="stroke: #A80036; stroke-width: 1.0;"/>
|
14
|
+
<line style="stroke: #A80036; stroke-width: 1.0;" x1="128" x2="128" y1="50.4883" y2="60.4883"/>
|
15
|
+
<line style="stroke: #A80036; stroke-width: 1.0;" x1="138" x2="128" y1="60.4883" y2="60.4883"/>
|
16
|
+
<text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="112" x="11" y="68.0566">this is a first note</text>
|
17
|
+
<polygon fill="#A80036" points="157.5,106.7988,147.5,110.7988,157.5,114.7988,153.5,110.7988" style="stroke: #A80036; stroke-width: 1.0;"/>
|
18
|
+
<line style="stroke: #A80036; stroke-width: 1.0;" x1="151.5" x2="203" y1="110.7988" y2="110.7988"/>
|
19
|
+
<text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="16" x="163.5" y="106.3672">ok</text>
|
20
|
+
<polygon fill="#FBFB77" points="209,89.7988,209,114.7988,353,114.7988,353,99.7988,343,89.7988,209,89.7988" style="stroke: #A80036; stroke-width: 1.0;"/>
|
21
|
+
<line style="stroke: #A80036; stroke-width: 1.0;" x1="343" x2="343" y1="89.7988" y2="99.7988"/>
|
22
|
+
<line style="stroke: #A80036; stroke-width: 1.0;" x1="353" x2="343" y1="99.7988" y2="99.7988"/>
|
23
|
+
<text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="123" x="215" y="107.3672">this is another note</text>
|
24
|
+
<line style="stroke: #A80036; stroke-width: 1.0;" x1="204" x2="246" y1="159.2305" y2="159.2305"/>
|
25
|
+
<line style="stroke: #A80036; stroke-width: 1.0;" x1="246" x2="246" y1="159.2305" y2="172.2305"/>
|
26
|
+
<line style="stroke: #A80036; stroke-width: 1.0;" x1="205" x2="246" y1="172.2305" y2="172.2305"/>
|
27
|
+
<polygon fill="#A80036" points="215,168.2305,205,172.2305,215,176.2305,211,172.2305" style="stroke: #A80036; stroke-width: 1.0;"/>
|
28
|
+
<text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="84" x="211" y="154.4883">I am thinking</text>
|
29
|
+
<polygon fill="#FBFB77" points="52,129.1094,52,184.1094,195,184.1094,195,139.1094,185,129.1094,52,129.1094" style="stroke: #A80036; stroke-width: 1.0;"/>
|
30
|
+
<line style="stroke: #A80036; stroke-width: 1.0;" x1="185" x2="185" y1="129.1094" y2="139.1094"/>
|
31
|
+
<line style="stroke: #A80036; stroke-width: 1.0;" x1="195" x2="185" y1="139.1094" y2="139.1094"/>
|
32
|
+
<text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="39" x="58" y="146.6777">a note</text>
|
33
|
+
<text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="122" x="58" y="161.9883">can also be defined</text>
|
34
|
+
<text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="98" x="58" y="177.2988">on several lines</text>
|
35
|
+
</g>
|
36
|
+
</svg>
|
@@ -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>
|