prawn-svg 0.24.0 → 0.25.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +13 -9
  3. data/lib/prawn/svg/attributes.rb +1 -1
  4. data/lib/prawn/svg/attributes/space.rb +10 -0
  5. data/lib/prawn/svg/attributes/stroke.rb +2 -2
  6. data/lib/prawn/svg/attributes/transform.rb +2 -2
  7. data/lib/prawn/svg/calculators/document_sizing.rb +4 -5
  8. data/lib/prawn/svg/calculators/pixels.rb +27 -3
  9. data/lib/prawn/svg/document.rb +0 -18
  10. data/lib/prawn/svg/elements.rb +2 -2
  11. data/lib/prawn/svg/elements/base.rb +14 -2
  12. data/lib/prawn/svg/elements/circle.rb +1 -1
  13. data/lib/prawn/svg/elements/depth_first_base.rb +52 -0
  14. data/lib/prawn/svg/elements/ellipse.rb +2 -2
  15. data/lib/prawn/svg/elements/image.rb +2 -2
  16. data/lib/prawn/svg/elements/line.rb +4 -4
  17. data/lib/prawn/svg/elements/marker.rb +2 -2
  18. data/lib/prawn/svg/elements/rect.rb +3 -3
  19. data/lib/prawn/svg/elements/root.rb +5 -1
  20. data/lib/prawn/svg/elements/text.rb +47 -85
  21. data/lib/prawn/svg/elements/text_component.rb +186 -0
  22. data/lib/prawn/svg/elements/use.rb +1 -1
  23. data/lib/prawn/svg/elements/viewport.rb +28 -0
  24. data/lib/prawn/svg/interface.rb +20 -12
  25. data/lib/prawn/svg/pathable.rb +18 -2
  26. data/lib/prawn/svg/state.rb +3 -2
  27. data/lib/prawn/svg/version.rb +1 -1
  28. data/spec/prawn/svg/attributes/transform_spec.rb +2 -2
  29. data/spec/prawn/svg/calculators/pixels_spec.rb +72 -0
  30. data/spec/prawn/svg/document_spec.rb +0 -28
  31. data/spec/prawn/svg/elements/base_spec.rb +1 -1
  32. data/spec/prawn/svg/elements/gradient_spec.rb +1 -1
  33. data/spec/prawn/svg/elements/line_spec.rb +1 -1
  34. data/spec/prawn/svg/elements/marker_spec.rb +4 -0
  35. data/spec/prawn/svg/elements/text_spec.rb +104 -15
  36. data/spec/sample_svg/markers_degenerate_cp.svg +19 -0
  37. data/spec/sample_svg/offset_viewport.svg +8 -0
  38. data/spec/sample_svg/subviewports.svg +173 -0
  39. data/spec/sample_svg/subviewports2.svg +16 -0
  40. data/spec/sample_svg/tref01.svg +21 -0
  41. data/spec/sample_svg/tspan05.svg +40 -0
  42. data/spec/sample_svg/tspan91.svg +34 -0
  43. data/spec/spec_helper.rb +6 -0
  44. metadata +22 -2
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe Prawn::SVG::Elements::Gradient do
4
4
  let(:document) { Prawn::SVG::Document.new(svg, [800, 600], {width: 800, height: 600}) }
5
- let(:element) { Prawn::SVG::Elements::Gradient.new(document, document.root, [], Prawn::SVG::State.new) }
5
+ let(:element) { Prawn::SVG::Elements::Gradient.new(document, document.root, [], fake_state) }
6
6
 
7
7
  before do
8
8
  allow(element).to receive(:assert_compatible_prawn_version)
@@ -4,7 +4,7 @@ RSpec.describe Prawn::SVG::Elements::Line do
4
4
  let(:document) { Prawn::SVG::Document.new(svg, [800, 600], {width: 800, height: 600}) }
5
5
 
6
6
  subject do
7
- Prawn::SVG::Elements::Line.new(document, document.root, [], Prawn::SVG::State.new)
7
+ Prawn::SVG::Elements::Line.new(document, document.root, [], fake_state)
8
8
  end
9
9
 
10
10
  context "with attributes specified" do
@@ -28,6 +28,10 @@ RSpec.describe Prawn::SVG::Elements::Marker do
28
28
  Prawn::SVG::Elements::Marker.new(document, document.root.elements[1], [], state)
29
29
  end
30
30
 
31
+ before do
32
+ state.viewport_sizing = document.sizing
33
+ end
34
+
31
35
  describe "#parse" do
32
36
  it "forces display none" do
33
37
  subject.parse
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
2
2
 
3
3
  describe Prawn::SVG::Elements::Text do
4
4
  let(:document) { Prawn::SVG::Document.new(svg, [800, 600], {}, font_registry: Prawn::SVG::FontRegistry.new("Helvetica" => {:normal => nil}, "Courier" => {normal: nil}, 'Times-Roman' => {normal: nil})) }
5
- let(:element) { Prawn::SVG::Elements::Text.new(document, document.root, [], Prawn::SVG::State.new) }
5
+ let(:element) { Prawn::SVG::Elements::Text.new(document, document.root, [], fake_state) }
6
6
 
7
7
  describe "xml:space preserve" do
8
8
  let(:svg) { %(<text#{attributes}>some\n\t text</text>) }
@@ -13,9 +13,7 @@ describe Prawn::SVG::Elements::Text do
13
13
  it "converts newlines and tabs to spaces, and preserves spaces" do
14
14
  element.process
15
15
 
16
- expect(element.calls).to eq [
17
- ["draw_text", ["some text", {:size=>16, :style=>:normal, :text_anchor=>'start', :at=>[0.0, 150.0]}], []]
18
- ]
16
+ expect(flatten_calls(element.calls)).to include ["draw_text", ["some text", {:size=>16, :style=>:normal, :text_anchor=>'start', :at=>[:relative, :relative], :offset=>[0,0]}]]
19
17
  end
20
18
  end
21
19
 
@@ -25,20 +23,49 @@ describe Prawn::SVG::Elements::Text do
25
23
  it "strips space" do
26
24
  element.process
27
25
 
28
- expect(element.calls).to eq [
29
- ["draw_text", ["some text", {:size=>16, :style=>:normal, :text_anchor=>'start', :at=>[0.0, 150.0]}], []]
30
- ]
26
+ expect(flatten_calls(element.calls)).to include ["draw_text", ["some text", {:size=>16, :style=>:normal, :text_anchor=>'start', :at=>[:relative, :relative], :offset=>[0,0]}]]
31
27
  end
32
28
  end
33
29
  end
34
30
 
31
+ describe "conventional whitespace handling" do
32
+ let(:svg) do
33
+ <<-SVG
34
+ <text>
35
+ <tspan>
36
+ </tspan>
37
+ Some text here
38
+ <tspan>More text</tspan>
39
+ Even more
40
+ <tspan></tspan>
41
+ <tspan>
42
+ leading goodness
43
+ </tspan>
44
+ ok
45
+ <tspan>
46
+ </tspan>
47
+ </text>
48
+ SVG
49
+ end
50
+
51
+ it "correctly apportions white space between the tags" do
52
+ element.process
53
+ calls = element.calls.flatten
54
+ expect(calls).to include "Some text here "
55
+ expect(calls).to include "More text"
56
+ expect(calls).to include "Even more"
57
+ expect(calls).to include " leading goodness "
58
+ expect(calls).to include "ok"
59
+ end
60
+ end
61
+
35
62
  describe "when text-anchor is specified" do
36
63
  let(:svg) { '<g text-anchor="middle" font-size="12"><text x="50" y="14">Text</text></g>' }
37
- let(:element) { Prawn::SVG::Elements::Container.new(document, document.root, [], Prawn::SVG::State.new) }
64
+ let(:element) { Prawn::SVG::Elements::Container.new(document, document.root, [], fake_state) }
38
65
 
39
66
  it "should inherit text-anchor from parent element" do
40
67
  element.process
41
- expect(element.calls.flatten).to include(:size => 12.0, :style => :normal, :text_anchor => "middle", :at => [50.0, 136.0])
68
+ expect(element.calls.flatten).to include(:size => 12.0, :style => :normal, :text_anchor => "middle", :at => [50.0, 136.0], :offset => [0,0])
42
69
  end
43
70
  end
44
71
 
@@ -49,11 +76,11 @@ describe Prawn::SVG::Elements::Text do
49
76
  element.process
50
77
 
51
78
  expect(element.base_calls).to eq [
52
- ["fill", [], [
53
- ["font", ["Helvetica", {style: :normal}], []],
54
- ["text_group", [], [
79
+ ["text_group", [], [
80
+ ["fill", [], [
81
+ ["font", ["Helvetica", {style: :normal}], []],
55
82
  ["character_spacing", [5.0], [
56
- ["draw_text", ["spaced", {:size=>16, :style=>:normal, :text_anchor=>'start', :at=>[0.0, 150.0]}], []]
83
+ ["draw_text", ["spaced", {:size=>16, :style=>:normal, :text_anchor=>'start', :at=>[:relative, :relative], :offset=>[0,0]}], []]
57
84
  ]]
58
85
  ]]
59
86
  ]]
@@ -67,7 +94,7 @@ describe Prawn::SVG::Elements::Text do
67
94
 
68
95
  it "finds the font and uses it" do
69
96
  element.process
70
- expect(element.base_calls[0][2][0]).to eq ['font', ['Courier', {style: :normal}], []]
97
+ expect(flatten_calls(element.base_calls)).to include ['font', ['Courier', {style: :normal}]]
71
98
  end
72
99
  end
73
100
 
@@ -76,7 +103,7 @@ describe Prawn::SVG::Elements::Text do
76
103
 
77
104
  it "uses the fallback font" do
78
105
  element.process
79
- expect(element.base_calls[0][2][0]).to eq ['font', ['Times-Roman', {style: :normal}], []]
106
+ expect(flatten_calls(element.base_calls)).to include ['font', ['Times-Roman', {style: :normal}]]
80
107
  end
81
108
 
82
109
  context "when there is no fallback font" do
@@ -90,4 +117,66 @@ describe Prawn::SVG::Elements::Text do
90
117
  end
91
118
  end
92
119
  end
120
+
121
+ describe "<tref>" do
122
+ let(:svg) { '<svg xmlns:xlink="http://www.w3.org/1999/xlink"><defs><text id="ref" fill="green">my reference text</text></defs><text x="10"><tref xlink:href="#ref" fill="red" /></text></svg>' }
123
+ let(:element) { Prawn::SVG::Elements::Root.new(document, document.root, [], fake_state) }
124
+
125
+ it "references the text" do
126
+ element.process
127
+ expect(flatten_calls(element.base_calls)[11..15]).to eq [
128
+ ["fill_color", ["ff0000"]],
129
+ ["fill", []],
130
+ ["font", ["Helvetica", {:style=>:normal}]],
131
+ ["character_spacing", [0]],
132
+ ["draw_text", ["my reference text", {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[10.0, :relative], :offset=>[0,0]}]],
133
+ ]
134
+ end
135
+ end
136
+
137
+ describe "dx and dy attributes" do
138
+ let(:svg) { '<text x="10 20" dx="30 50 80" dy="2">Hi there, this is a good test</text>' }
139
+
140
+ it "correctly calculates the positinos of the text" do
141
+ element.process
142
+
143
+ expect(flatten_calls(element.base_calls)).to eq [
144
+ ["text_group", []],
145
+ ["fill", []],
146
+ ["font", ["Helvetica", {:style=>:normal}]],
147
+ ["character_spacing", [0]],
148
+ ["draw_text", ["H", {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[10.0, :relative], :offset=>[30.0, 2.0]}]],
149
+ ["draw_text", ["i", {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[20.0, :relative], :offset=>[50.0, 0]}]],
150
+ ["draw_text", [" there, this is a good test", {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[:relative, :relative], :offset=>[80.0, 0]}]]
151
+ ]
152
+ end
153
+ end
154
+
155
+ describe "rotate attribute" do
156
+ let(:svg) { '<text rotate="10 20 30 40 50 60 70 80 90 100">Hi <tspan rotate="0">this</tspan> ok!</text>' }
157
+
158
+ it "correctly calculates the positinos of the text" do
159
+ element.process
160
+
161
+ expect(flatten_calls(element.base_calls)).to eq [
162
+ ["text_group", []],
163
+ ["fill", []],
164
+ ["font", ["Helvetica", {:style=>:normal}]],
165
+ ["character_spacing", [0]],
166
+ ["draw_text", ["H", {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[:relative, :relative], :offset=>[0, 0], :rotate=>-10.0}]],
167
+ ["draw_text", ["i", {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[:relative, :relative], :offset=>[0, 0], :rotate=>-20.0}]],
168
+ ["draw_text", [" ", {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[:relative, :relative], :offset=>[0, 0], :rotate=>-30.0}]],
169
+ ["save", []],
170
+ ["fill", []],
171
+ ["font", ["Helvetica", {:style=>:normal}]],
172
+ ["character_spacing", [0]],
173
+ ["draw_text", ["this", {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[:relative, :relative], :offset=>[0, 0]}]],
174
+ ["restore", []],
175
+ ["draw_text", [" ", {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[:relative, :relative], :offset=>[0, 0], :rotate=>-80.0}]],
176
+ ["draw_text", ["o", {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[:relative, :relative], :offset=>[0, 0], :rotate=>-90.0}]],
177
+ ["draw_text", ["k", {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[:relative, :relative], :offset=>[0, 0], :rotate=>-100.0}]],
178
+ ["draw_text", ["!", {:size=>16, :style=>:normal, :text_anchor=>"start", :at=>[:relative, :relative], :offset=>[0, 0], :rotate=>-100.0}]]
179
+ ]
180
+ end
181
+ end
93
182
  end
@@ -0,0 +1,19 @@
1
+ <svg width="240" height="240" version="1.1" xmlns="http://www.w3.org/2000/svg">
2
+ <defs>
3
+ <marker id="Triangle"
4
+ refX="0" refY="12" markerUnits="userSpaceOnUse"
5
+ markerWidth="24" markerHeight="24" orient="auto">
6
+ <path d="M 0 0 L 24 12 L 0 24 z" />
7
+ </marker>
8
+ </defs>
9
+
10
+ <!-- CP vectors are zero. Orientation should still work. -->
11
+
12
+ <path d="M 50,125 C 50,125, 100,25, 100,25" stroke-width="10" stroke="red"
13
+ marker-start="url(#Triangle)"
14
+ marker-end="url(#Triangle)" />
15
+
16
+ <path d="M 150,125 C 200,25, 200,25, 200,25" stroke-width="10" stroke="red"
17
+ marker-start="url(#Triangle)"
18
+ marker-end="url(#Triangle)" />
19
+ </svg>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
+ <svg width="1440px" height="750px" version="1.1"
4
+ viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
5
+ <rect x="0" y="0" width="100" height="100"
6
+ fill="yellow" stroke="blue" stroke-width="12" />
7
+ </svg>
8
+
@@ -0,0 +1,173 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
+
4
+ <svg width="450px" height="300px" version="1.1"
5
+ xmlns="http://www.w3.org/2000/svg">
6
+ <desc>Example PreserveAspectRatio - illustrates preserveAspectRatio attribute</desc>
7
+ <rect x="1" y="1" width="448" height="298"
8
+ fill="none" stroke="blue"/>
9
+ <g font-size="9">
10
+ <text x="10" y="30">SVG to fit</text>
11
+ <g transform="translate(20,40)">
12
+ <rect x='.5' y='.5' width='29' height='39' fill='black' stroke='red'/>
13
+ <g transform='translate(0, 5)'>
14
+ <circle cx='15' cy='15' r='10' fill='yellow'/>
15
+ <circle cx='12' cy='12' r='1.5' fill='black'/>
16
+ <circle cx='17' cy='12' r='1.5' fill='black'/>
17
+ <path d='M 10 19 A 8 8 0 0 0 20 19' stroke='black' stroke-width='2'/>
18
+ </g>
19
+ </g>
20
+ <text x="10" y="110">Viewport 1</text>
21
+ <g transform="translate(10,120)"><rect x='.5' y='.5' width='49' height='29' fill='none' stroke='blue'/></g>
22
+ <text x="10" y="180">Viewport 2</text>
23
+ <g transform="translate(20,190)"><rect x='.5' y='.5' width='29' height='59' fill='none' stroke='blue'/></g>
24
+
25
+ <g id="meet-group-1" transform="translate(100, 60)">
26
+ <text x="0" y="-30">--------------- meet ---------------</text>
27
+ <g><text y="-10">xMin*</text><rect x='.5' y='.5' width='49' height='29' fill='none' stroke='blue'/>
28
+ <svg preserveAspectRatio="xMinYMin meet" viewBox="0 0 30 40"
29
+ width="50" height="30">
30
+ <rect x='.5' y='.5' width='29' height='39' fill='black' stroke='red'/>
31
+ <g transform='translate(0, 5)'>
32
+ <circle cx='15' cy='15' r='10' fill='yellow'/>
33
+ <circle cx='12' cy='12' r='1.5' fill='black'/>
34
+ <circle cx='17' cy='12' r='1.5' fill='black'/>
35
+ <path d='M 10 19 A 8 8 0 0 0 20 19' stroke='black' stroke-width='2'/>
36
+ </g>
37
+ </svg></g>
38
+ <g transform="translate(70,0)"><text y="-10">xMid*</text><rect x='.5' y='.5' width='49' height='29' fill='none' stroke='blue'/>
39
+ <svg preserveAspectRatio="xMidYMid meet" viewBox="0 0 30 40"
40
+ width="50" height="30">
41
+ <rect x='.5' y='.5' width='29' height='39' fill='black' stroke='red'/>
42
+ <g transform='translate(0, 5)'>
43
+ <circle cx='15' cy='15' r='10' fill='yellow'/>
44
+ <circle cx='12' cy='12' r='1.5' fill='black'/>
45
+ <circle cx='17' cy='12' r='1.5' fill='black'/>
46
+ <path d='M 10 19 A 8 8 0 0 0 20 19' stroke='black' stroke-width='2'/>
47
+ </g>
48
+ </svg></g>
49
+ <g transform="translate(0,70)"><text y="-10">xMax*</text><rect x='.5' y='.5' width='49' height='29' fill='none' stroke='blue'/>
50
+ <svg preserveAspectRatio="xMaxYMax meet" viewBox="0 0 30 40"
51
+ width="50" height="30">
52
+ <rect x='.5' y='.5' width='29' height='39' fill='black' stroke='red'/>
53
+ <g transform='translate(0, 5)'>
54
+ <circle cx='15' cy='15' r='10' fill='yellow'/>
55
+ <circle cx='12' cy='12' r='1.5' fill='black'/>
56
+ <circle cx='17' cy='12' r='1.5' fill='black'/>
57
+ <path d='M 10 19 A 8 8 0 0 0 20 19' stroke='black' stroke-width='2'/>
58
+ </g>
59
+ </svg></g>
60
+ </g>
61
+
62
+ <g id="meet-group-2" transform="translate(250, 60)">
63
+ <text x="0" y="-30">---------- meet ----------</text>
64
+ <g><text y="-10">*YMin</text><rect x='.5' y='.5' width='29' height='59' fill='none' stroke='blue'/>
65
+ <svg preserveAspectRatio="xMinYMin meet" viewBox="0 0 30 40"
66
+ width="30" height="60">
67
+ <rect x='.5' y='.5' width='29' height='39' fill='black' stroke='red'/>
68
+ <g transform='translate(0, 5)'>
69
+ <circle cx='15' cy='15' r='10' fill='yellow'/>
70
+ <circle cx='12' cy='12' r='1.5' fill='black'/>
71
+ <circle cx='17' cy='12' r='1.5' fill='black'/>
72
+ <path d='M 10 19 A 8 8 0 0 0 20 19' stroke='black' stroke-width='2'/>
73
+ </g>
74
+ </svg></g>
75
+ <g transform="translate(50, 0)"><text y="-10">*YMid</text><rect x='.5' y='.5' width='29' height='59' fill='none' stroke='blue'/>
76
+ <svg preserveAspectRatio="xMidYMid meet" viewBox="0 0 30 40"
77
+ width="30" height="60">
78
+ <rect x='.5' y='.5' width='29' height='39' fill='black' stroke='red'/>
79
+ <g transform='translate(0, 5)'>
80
+ <circle cx='15' cy='15' r='10' fill='yellow'/>
81
+ <circle cx='12' cy='12' r='1.5' fill='black'/>
82
+ <circle cx='17' cy='12' r='1.5' fill='black'/>
83
+ <path d='M 10 19 A 8 8 0 0 0 20 19' stroke='black' stroke-width='2'/>
84
+ </g>
85
+ </svg></g>
86
+ <g transform="translate(100, 0)"><text y="-10">*YMax</text><rect x='.5' y='.5' width='29' height='59' fill='none' stroke='blue'/>
87
+ <svg preserveAspectRatio="xMaxYMax meet" viewBox="0 0 30 40"
88
+ width="30" height="60">
89
+ <rect x='.5' y='.5' width='29' height='39' fill='black' stroke='red'/>
90
+ <g transform='translate(0, 5)'>
91
+ <circle cx='15' cy='15' r='10' fill='yellow'/>
92
+ <circle cx='12' cy='12' r='1.5' fill='black'/>
93
+ <circle cx='17' cy='12' r='1.5' fill='black'/>
94
+ <path d='M 10 19 A 8 8 0 0 0 20 19' stroke='black' stroke-width='2'/>
95
+ </g>
96
+ </svg></g>
97
+ </g>
98
+
99
+ <g id="slice-group-1" transform="translate(100, 220)">
100
+ <text x="0" y="-30">---------- slice ----------</text>
101
+ <g><text y="-10">xMin*</text><rect x='.5' y='.5' width='29' height='59' fill='none' stroke='blue'/>
102
+ <svg preserveAspectRatio="xMinYMin slice" viewBox="0 0 30 40"
103
+ width="30" height="60">
104
+ <rect x='.5' y='.5' width='29' height='39' fill='black' stroke='red'/>
105
+ <g transform='translate(0, 5)'>
106
+ <circle cx='15' cy='15' r='10' fill='yellow'/>
107
+ <circle cx='12' cy='12' r='1.5' fill='black'/>
108
+ <circle cx='17' cy='12' r='1.5' fill='black'/>
109
+ <path d='M 10 19 A 8 8 0 0 0 20 19' stroke='black' stroke-width='2'/>
110
+ </g>
111
+ </svg></g>
112
+ <g transform="translate(50,0)"><text y="-10">xMid*</text><rect x='.5' y='.5' width='29' height='59' fill='none' stroke='blue'/>
113
+ <svg preserveAspectRatio="xMidYMid slice" viewBox="0 0 30 40"
114
+ width="30" height="60">
115
+ <rect x='.5' y='.5' width='29' height='39' fill='black' stroke='red'/>
116
+ <g transform='translate(0, 5)'>
117
+ <circle cx='15' cy='15' r='10' fill='yellow'/>
118
+ <circle cx='12' cy='12' r='1.5' fill='black'/>
119
+ <circle cx='17' cy='12' r='1.5' fill='black'/>
120
+ <path d='M 10 19 A 8 8 0 0 0 20 19' stroke='black' stroke-width='2'/>
121
+ </g>
122
+ </svg></g>
123
+ <g transform="translate(100,0)"><text y="-10">xMax*</text><rect x='.5' y='.5' width='29' height='59' fill='none' stroke='blue'/>
124
+ <svg preserveAspectRatio="xMaxYMax slice" viewBox="0 0 30 40"
125
+ width="30" height="60">
126
+ <rect x='.5' y='.5' width='29' height='39' fill='black' stroke='red'/>
127
+ <g transform='translate(0, 5)'>
128
+ <circle cx='15' cy='15' r='10' fill='yellow'/>
129
+ <circle cx='12' cy='12' r='1.5' fill='black'/>
130
+ <circle cx='17' cy='12' r='1.5' fill='black'/>
131
+ <path d='M 10 19 A 8 8 0 0 0 20 19' stroke='black' stroke-width='2'/>
132
+ </g>
133
+ </svg></g>
134
+ </g>
135
+
136
+ <g id="slice-group-2" transform="translate(250, 220)">
137
+ <text x="0" y="-30">--------------- slice ---------------</text>
138
+ <g><text y="-10">*YMin</text><rect x='.5' y='.5' width='49' height='29' fill='none' stroke='blue'/>
139
+ <svg preserveAspectRatio="xMinYMin slice" viewBox="0 0 30 40"
140
+ width="50" height="30">
141
+ <rect x='.5' y='.5' width='29' height='39' fill='black' stroke='red'/>
142
+ <g transform='translate(0, 5)'>
143
+ <circle cx='15' cy='15' r='10' fill='yellow'/>
144
+ <circle cx='12' cy='12' r='1.5' fill='black'/>
145
+ <circle cx='17' cy='12' r='1.5' fill='black'/>
146
+ <path d='M 10 19 A 8 8 0 0 0 20 19' stroke='black' stroke-width='2'/>
147
+ </g>
148
+ </svg></g>
149
+ <g transform="translate(70,0)"><text y="-10">*YMid</text><rect x='.5' y='.5' width='49' height='29' fill='none' stroke='blue'/>
150
+ <svg preserveAspectRatio="xMidYMid slice" viewBox="0 0 30 40"
151
+ width="50" height="30">
152
+ <rect x='.5' y='.5' width='29' height='39' fill='black' stroke='red'/>
153
+ <g transform='translate(0, 5)'>
154
+ <circle cx='15' cy='15' r='10' fill='yellow'/>
155
+ <circle cx='12' cy='12' r='1.5' fill='black'/>
156
+ <circle cx='17' cy='12' r='1.5' fill='black'/>
157
+ <path d='M 10 19 A 8 8 0 0 0 20 19' stroke='black' stroke-width='2'/>
158
+ </g>
159
+ </svg></g>
160
+ <g transform="translate(140,0)"><text y="-10">*YMax</text><rect x='.5' y='.5' width='49' height='29' fill='none' stroke='blue'/>
161
+ <svg preserveAspectRatio="xMaxYMax slice" viewBox="0 0 30 40"
162
+ width="50" height="30">
163
+ <rect x='.5' y='.5' width='29' height='39' fill='black' stroke='red'/>
164
+ <g transform='translate(0, 5)'>
165
+ <circle cx='15' cy='15' r='10' fill='yellow'/>
166
+ <circle cx='12' cy='12' r='1.5' fill='black'/>
167
+ <circle cx='17' cy='12' r='1.5' fill='black'/>
168
+ <path d='M 10 19 A 8 8 0 0 0 20 19' stroke='black' stroke-width='2'/>
169
+ </g>
170
+ </svg></g>
171
+ </g>
172
+ </g>
173
+ </svg>
@@ -0,0 +1,16 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
+
4
+ <svg width="450px" height="300px" version="1.1" xmlns="http://www.w3.org/2000/svg">
5
+ <g transform="translate(100, 100)">
6
+ <rect x='.5' y='.5' width='199' height='149' fill='none' stroke='blue' />
7
+ <svg width="200" height="150" viewBox="0 0 100 100">
8
+ <rect x=".5" y=".5" width="99" height="99" fill='none' stroke='green' />
9
+
10
+ <rect x="25.5" y="25.5" width="49" height="49" fill='none' stroke='blue' />
11
+ <svg x="25%" y="25%" width="50%" height="50%" viewBox="0 0 100 100">
12
+ <rect x="5" y="5" width="90" height="90" fill='green' />
13
+ </svg>
14
+ </svg>
15
+ </g>
16
+ </svg>
@@ -0,0 +1,21 @@
1
+ <?xml version="1.0" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
+ <svg width="10cm" height="3cm" viewBox="0 0 1000 300" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
4
+ <defs>
5
+ <text id="ReferencedText" fill="orange">
6
+ Referenced character data
7
+ </text>
8
+ </defs>
9
+ <desc>Example tref01 - inline vs reference text content</desc>
10
+
11
+ <text x="100" y="100" font-size="45" fill="blue" >
12
+ Inline character data
13
+ </text>
14
+ <text x="100" y="200" font-size="45" fill="red" >
15
+ <tref xlink:href="#ReferencedText" font-size="70" />
16
+ </text>
17
+
18
+ <!-- Show outline of canvas using 'rect' element -->
19
+ <rect x="1" y="1" width="998" height="298"
20
+ fill="none" stroke="blue" stroke-width="2" />
21
+ </svg>
@@ -0,0 +1,40 @@
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="100%" viewBox="0 0 500 120"
5
+ xmlns="http://www.w3.org/2000/svg" version="1.1">
6
+ <desc>
7
+ Example tspan05 - propagation of rotation values to nested tspan elements.
8
+ </desc>
9
+ <text id="parent" font-family="Arial, sans-serif" font-size="32" fill="red" x="40" y="40"
10
+ rotate="5,15,25,35,45,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,0,0,0,0,0,0,-30">
11
+ <tspan> </tspan>
12
+ Not
13
+
14
+ <tspan id="child1" rotate="-10,-20,-30,-40" fill="orange">
15
+ all characters
16
+
17
+ <tspan id="child2" rotate="0" fill="yellow">
18
+ in<tspan></tspan><tspan id="child3">the
19
+ </tspan>
20
+ </tspan>
21
+
22
+ <tspan id="child4" fill="orange" x="40" y="90">
23
+ text
24
+ </tspan>
25
+
26
+ have a
27
+ </tspan>
28
+
29
+ <tspan id="child5" rotate="-10" fill="blue">
30
+ specified
31
+ </tspan>
32
+
33
+ rotation
34
+ <tspan> </tspan>
35
+ </text>
36
+
37
+ <!-- Show outline of canvas using 'rect' element -->
38
+ <rect x="1" y="1" width="498" height="118" fill="none"
39
+ stroke="blue" stroke-width="2" />
40
+ </svg>