prawn-svg 0.34.1 → 0.35.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/lint.yml +19 -0
- data/.github/workflows/test.yml +14 -27
- data/.gitignore +0 -1
- data/.rubocop.yml +86 -0
- data/.rubocop_todo.yml +51 -0
- data/Gemfile +4 -3
- data/Gemfile.lock +81 -0
- data/README.md +1 -1
- data/Rakefile +1 -1
- data/lib/prawn/svg/attributes/clip_path.rb +3 -3
- data/lib/prawn/svg/attributes/opacity.rb +3 -3
- data/lib/prawn/svg/attributes/stroke.rb +9 -9
- data/lib/prawn/svg/attributes/transform.rb +2 -2
- data/lib/prawn/svg/attributes.rb +1 -1
- data/lib/prawn/svg/calculators/arc_to_bezier_curve.rb +17 -15
- data/lib/prawn/svg/calculators/aspect_ratio.rb +16 -14
- data/lib/prawn/svg/calculators/document_sizing.rb +9 -10
- data/lib/prawn/svg/calculators/pixels.rb +8 -5
- data/lib/prawn/svg/color.rb +209 -212
- data/lib/prawn/svg/css/font_family_parser.rb +2 -2
- data/lib/prawn/svg/css/selector_parser.rb +39 -35
- data/lib/prawn/svg/css/stylesheets.rb +31 -24
- data/lib/prawn/svg/css/values_parser.rb +68 -0
- data/lib/prawn/svg/document.rb +6 -5
- data/lib/prawn/svg/elements/base.rb +39 -34
- data/lib/prawn/svg/elements/circle.rb +4 -4
- data/lib/prawn/svg/elements/clip_path.rb +0 -1
- data/lib/prawn/svg/elements/depth_first_base.rb +6 -6
- data/lib/prawn/svg/elements/ellipse.rb +3 -4
- data/lib/prawn/svg/elements/gradient.rb +49 -51
- data/lib/prawn/svg/elements/image.rb +5 -5
- data/lib/prawn/svg/elements/marker.rb +6 -7
- data/lib/prawn/svg/elements/path.rb +46 -47
- data/lib/prawn/svg/elements/polygon.rb +1 -1
- data/lib/prawn/svg/elements/polyline.rb +2 -2
- data/lib/prawn/svg/elements/rect.rb +3 -3
- data/lib/prawn/svg/elements/text.rb +1 -1
- data/lib/prawn/svg/elements/text_component.rb +22 -22
- data/lib/prawn/svg/elements/use.rb +4 -8
- data/lib/prawn/svg/elements/viewport.rb +5 -4
- data/lib/prawn/svg/elements.rb +30 -29
- data/lib/prawn/svg/extension.rb +2 -1
- data/lib/prawn/svg/font.rb +7 -7
- data/lib/prawn/svg/font_registry.rb +13 -13
- data/lib/prawn/svg/gradients.rb +3 -2
- data/lib/prawn/svg/interface.rb +4 -3
- data/lib/prawn/svg/loaders/data.rb +2 -2
- data/lib/prawn/svg/loaders/file.rb +12 -14
- data/lib/prawn/svg/loaders/web.rb +4 -8
- data/lib/prawn/svg/pathable.rb +41 -37
- data/lib/prawn/svg/properties.rb +34 -33
- data/lib/prawn/svg/renderer.rb +7 -7
- data/lib/prawn/svg/state.rb +1 -1
- data/lib/prawn/svg/transform_parser.rb +5 -5
- data/lib/prawn/svg/ttf.rb +21 -17
- data/lib/prawn/svg/url_loader.rb +1 -1
- data/lib/prawn/svg/version.rb +1 -1
- data/lib/prawn-svg.rb +1 -0
- data/prawn-svg.gemspec +4 -6
- data/spec/integration_spec.rb +77 -70
- data/spec/prawn/svg/attributes/opacity_spec.rb +11 -15
- data/spec/prawn/svg/attributes/transform_spec.rb +6 -6
- data/spec/prawn/svg/calculators/aspect_ratio_spec.rb +50 -50
- data/spec/prawn/svg/calculators/document_sizing_spec.rb +35 -35
- data/spec/prawn/svg/calculators/pixels_spec.rb +31 -30
- data/spec/prawn/svg/color_spec.rb +31 -31
- data/spec/prawn/svg/css/font_family_parser_spec.rb +12 -12
- data/spec/prawn/svg/css/selector_parser_spec.rb +21 -21
- data/spec/prawn/svg/css/stylesheets_spec.rb +51 -43
- data/spec/prawn/svg/css/values_parser_spec.rb +16 -0
- data/spec/prawn/svg/document_spec.rb +15 -14
- data/spec/prawn/svg/elements/base_spec.rb +39 -34
- data/spec/prawn/svg/elements/gradient_spec.rb +39 -39
- data/spec/prawn/svg/elements/line_spec.rb +22 -22
- data/spec/prawn/svg/elements/marker_spec.rb +44 -47
- data/spec/prawn/svg/elements/path_spec.rb +134 -110
- data/spec/prawn/svg/elements/polygon_spec.rb +18 -18
- data/spec/prawn/svg/elements/polyline_spec.rb +16 -16
- data/spec/prawn/svg/elements/text_spec.rb +149 -127
- data/spec/prawn/svg/font_registry_spec.rb +34 -34
- data/spec/prawn/svg/font_spec.rb +4 -4
- data/spec/prawn/svg/interface_spec.rb +47 -39
- data/spec/prawn/svg/loaders/data_spec.rb +21 -21
- data/spec/prawn/svg/loaders/file_spec.rb +43 -40
- data/spec/prawn/svg/loaders/web_spec.rb +15 -15
- data/spec/prawn/svg/pathable_spec.rb +21 -21
- data/spec/prawn/svg/properties_spec.rb +51 -51
- data/spec/prawn/svg/transform_parser_spec.rb +12 -12
- data/spec/prawn/svg/ttf_spec.rb +5 -5
- data/spec/prawn/svg/url_loader_spec.rb +25 -23
- data/spec/spec_helper.rb +4 -4
- metadata +12 -143
@@ -1,45 +1,45 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
RSpec.describe Prawn::SVG::Elements::Polyline do
|
4
|
-
let(:document) { Prawn::SVG::Document.new(svg, [800, 600], {width: 800, height: 600}) }
|
4
|
+
let(:document) { Prawn::SVG::Document.new(svg, [800, 600], { width: 800, height: 600 }) }
|
5
5
|
|
6
6
|
subject do
|
7
7
|
Prawn::SVG::Elements::Polyline.new(document, document.root, [], Prawn::SVG::State.new)
|
8
8
|
end
|
9
9
|
|
10
|
-
context
|
10
|
+
context 'with a valid points attribute' do
|
11
11
|
let(:svg) { '<polyline points="10 10 20,20 30,30" />' }
|
12
12
|
|
13
|
-
it
|
13
|
+
it 'renders the polyline' do
|
14
14
|
subject.process
|
15
15
|
expect(subject.base_calls).to eq [
|
16
|
-
[
|
17
|
-
[
|
18
|
-
[
|
19
|
-
[
|
20
|
-
]
|
16
|
+
['fill', [], {}, [
|
17
|
+
['move_to', [[10.0, 590.0]], {}, []],
|
18
|
+
['line_to', [[20.0, 580.0]], {}, []],
|
19
|
+
['line_to', [[30.0, 570.0]], {}, []]
|
20
|
+
]]
|
21
21
|
]
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
context
|
25
|
+
context 'with a polyline that has an odd number of arguments' do
|
26
26
|
let(:svg) { '<polyline points="10 10 20,20 30" />' }
|
27
27
|
|
28
|
-
it
|
28
|
+
it 'ignores the last one' do
|
29
29
|
subject.process
|
30
30
|
expect(subject.base_calls).to eq [
|
31
|
-
[
|
32
|
-
[
|
33
|
-
[
|
34
|
-
]
|
31
|
+
['fill', [], {}, [
|
32
|
+
['move_to', [[10.0, 590.0]], {}, []],
|
33
|
+
['line_to', [[20.0, 580.0]], {}, []]
|
34
|
+
]]
|
35
35
|
]
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
-
context
|
39
|
+
context 'with a polyline that has no arguments' do
|
40
40
|
let(:svg) { '<polyline points="" />' }
|
41
41
|
|
42
|
-
it
|
42
|
+
it 'renders nothing' do
|
43
43
|
subject.process
|
44
44
|
expect(subject.base_calls).to eq []
|
45
45
|
end
|
@@ -1,152 +1,162 @@
|
|
1
|
-
require File.dirname(__FILE__)
|
1
|
+
require "#{File.dirname(__FILE__)}/../../../spec_helper"
|
2
2
|
|
3
3
|
describe Prawn::SVG::Elements::Text do
|
4
|
-
let(:document)
|
5
|
-
|
4
|
+
let(:document) do
|
5
|
+
Prawn::SVG::Document.new(svg, [800, 600], {},
|
6
|
+
font_registry: Prawn::SVG::FontRegistry.new('Helvetica' => { normal: nil }, 'Courier' => { normal: nil }, 'Times-Roman' => { normal: nil }))
|
7
|
+
end
|
8
|
+
let(:element) { Prawn::SVG::Elements::Text.new(document, document.root, [], fake_state) }
|
6
9
|
|
7
|
-
let(:default_style)
|
10
|
+
let(:default_style) do
|
11
|
+
{ size: 16, style: :normal, text_anchor: 'start', at: [:relative, :relative], offset: [0, 0] }
|
12
|
+
end
|
8
13
|
|
9
|
-
describe
|
14
|
+
describe 'xml:space preserve' do
|
10
15
|
let(:svg) { %(<text#{attributes}>some\n\t text</text>) }
|
11
16
|
|
12
|
-
context
|
17
|
+
context 'when xml:space is preserve' do
|
13
18
|
let(:attributes) { ' xml:space="preserve"' }
|
14
19
|
|
15
|
-
it
|
20
|
+
it 'converts newlines and tabs to spaces, and preserves spaces' do
|
16
21
|
element.process
|
17
22
|
|
18
|
-
expect(flatten_calls(element.calls)).to include [
|
23
|
+
expect(flatten_calls(element.calls)).to include ['draw_text', ['some text'],
|
24
|
+
{ size: 16, style: :normal, text_anchor: 'start', at: [:relative, :relative], offset: [0, 0] }]
|
19
25
|
end
|
20
26
|
end
|
21
27
|
|
22
|
-
context
|
28
|
+
context 'when xml:space is unspecified' do
|
23
29
|
let(:attributes) { '' }
|
24
30
|
|
25
|
-
it
|
31
|
+
it 'strips space' do
|
26
32
|
element.process
|
27
33
|
|
28
|
-
expect(flatten_calls(element.calls)).to include [
|
34
|
+
expect(flatten_calls(element.calls)).to include ['draw_text', ['some text'],
|
35
|
+
{ size: 16, style: :normal, text_anchor: 'start', at: [:relative, :relative], offset: [0, 0] }]
|
29
36
|
end
|
30
37
|
end
|
31
38
|
end
|
32
39
|
|
33
|
-
describe
|
40
|
+
describe 'conventional whitespace handling' do
|
34
41
|
let(:svg) do
|
35
|
-
|
36
|
-
<text>
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
Even more
|
42
|
-
<tspan></tspan>
|
43
|
-
<tspan>
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
</text>
|
42
|
+
<<~SVG
|
43
|
+
<text>
|
44
|
+
<tspan>
|
45
|
+
</tspan>
|
46
|
+
Some text here
|
47
|
+
<tspan>More text</tspan>
|
48
|
+
Even more
|
49
|
+
<tspan></tspan>
|
50
|
+
<tspan>
|
51
|
+
leading goodness
|
52
|
+
</tspan>
|
53
|
+
ok
|
54
|
+
<tspan>
|
55
|
+
</tspan>
|
56
|
+
</text>
|
50
57
|
SVG
|
51
58
|
end
|
52
59
|
|
53
|
-
it
|
60
|
+
it 'correctly apportions white space between the tags' do
|
54
61
|
element.process
|
55
62
|
calls = element.calls.flatten
|
56
|
-
expect(calls).to include
|
57
|
-
expect(calls).to include
|
58
|
-
expect(calls).to include
|
59
|
-
expect(calls).to include
|
60
|
-
expect(calls).to include
|
63
|
+
expect(calls).to include 'Some text here '
|
64
|
+
expect(calls).to include 'More text'
|
65
|
+
expect(calls).to include 'Even more'
|
66
|
+
expect(calls).to include ' leading goodness '
|
67
|
+
expect(calls).to include 'ok'
|
61
68
|
end
|
62
69
|
end
|
63
70
|
|
64
|
-
describe
|
71
|
+
describe 'when text-anchor is specified' do
|
65
72
|
let(:svg) { '<g text-anchor="middle" font-size="12"><text x="50" y="14">Text</text></g>' }
|
66
73
|
let(:element) { Prawn::SVG::Elements::Container.new(document, document.root, [], fake_state) }
|
67
74
|
|
68
|
-
it
|
75
|
+
it 'should inherit text-anchor from parent element' do
|
69
76
|
element.process
|
70
|
-
expect(element.calls.flatten).to include(:
|
77
|
+
expect(element.calls.flatten).to include(size: 12.0, style: :normal, text_anchor: 'middle',
|
78
|
+
at: [50.0, 586.0], offset: [0, 0])
|
71
79
|
end
|
72
80
|
end
|
73
81
|
|
74
|
-
describe
|
82
|
+
describe 'letter-spacing' do
|
75
83
|
let(:svg) { '<text letter-spacing="5">spaced</text>' }
|
76
84
|
|
77
|
-
it
|
85
|
+
it 'calls character_spacing with the requested size' do
|
78
86
|
element.process
|
79
87
|
|
80
88
|
expect(element.base_calls).to eq [
|
81
|
-
[
|
82
|
-
[
|
83
|
-
[
|
84
|
-
[
|
89
|
+
['text_group', [], {}, [
|
90
|
+
['font', ['Helvetica'], { style: :normal }, []],
|
91
|
+
['character_spacing', [5.0], {}, [
|
92
|
+
['draw_text', ['spaced'], default_style, []]
|
85
93
|
]]
|
86
94
|
]]
|
87
95
|
]
|
88
96
|
end
|
89
97
|
end
|
90
98
|
|
91
|
-
describe
|
99
|
+
describe 'underline' do
|
92
100
|
let(:svg) { '<text text-decoration="underline">underlined</text>' }
|
93
101
|
|
94
|
-
it
|
102
|
+
it 'marks the element to be underlined' do
|
95
103
|
element.process
|
96
104
|
|
97
105
|
expect(element.base_calls).to eq [
|
98
|
-
[
|
99
|
-
[
|
100
|
-
[
|
106
|
+
['text_group', [], {}, [
|
107
|
+
['font', ['Helvetica'], { style: :normal }, []],
|
108
|
+
['draw_text', ['underlined'], default_style.merge(decoration: 'underline'), []]
|
101
109
|
]]
|
102
110
|
]
|
103
111
|
end
|
104
112
|
end
|
105
113
|
|
106
|
-
describe
|
107
|
-
context
|
114
|
+
describe 'fill/stroke modes' do
|
115
|
+
context 'with a stroke and no fill' do
|
108
116
|
let(:svg) { '<text stroke="red" fill="none">stroked</text>' }
|
109
117
|
|
110
|
-
it
|
118
|
+
it 'calls text_rendering_mode with the requested options' do
|
111
119
|
element.process
|
112
120
|
|
113
121
|
expect(element.base_calls).to eq [
|
114
|
-
[
|
115
|
-
[
|
116
|
-
[
|
117
|
-
[
|
118
|
-
[
|
122
|
+
['text_group', [], {}, [
|
123
|
+
['stroke_color', ['ff0000'], {}, []],
|
124
|
+
['font', ['Helvetica'], { style: :normal }, []],
|
125
|
+
['text_rendering_mode', [:stroke], {}, [
|
126
|
+
['draw_text', ['stroked'], default_style, []]
|
119
127
|
]]
|
120
128
|
]]
|
121
129
|
]
|
122
130
|
end
|
123
131
|
end
|
124
132
|
|
125
|
-
context
|
126
|
-
let(:svg)
|
133
|
+
context 'with a mixture of everything' do
|
134
|
+
let(:svg) do
|
135
|
+
'<text stroke="red" fill="none">stroked <tspan fill="black">both</tspan><tspan stroke="none">neither</tspan></text>'
|
136
|
+
end
|
127
137
|
|
128
|
-
it
|
138
|
+
it 'calls text_rendering_mode with the requested options' do
|
129
139
|
element.process
|
130
140
|
|
131
141
|
expect(element.base_calls).to eq [
|
132
|
-
[
|
133
|
-
[
|
134
|
-
[
|
135
|
-
[
|
136
|
-
[
|
137
|
-
[
|
138
|
-
[
|
139
|
-
[
|
140
|
-
[
|
141
|
-
[
|
142
|
+
['text_group', [], {}, [
|
143
|
+
['stroke_color', ['ff0000'], {}, []],
|
144
|
+
['font', ['Helvetica'], { style: :normal }, []],
|
145
|
+
['text_rendering_mode', [:stroke], {}, [
|
146
|
+
['draw_text', ['stroked '], default_style, []],
|
147
|
+
['save', [], {}, []],
|
148
|
+
['fill_color', ['000000'], {}, []],
|
149
|
+
['font', ['Helvetica'], { style: :normal }, []],
|
150
|
+
['text_rendering_mode', [:fill_stroke], {}, [
|
151
|
+
['draw_text', ['both'], default_style, []]
|
142
152
|
]],
|
143
|
-
[
|
144
|
-
[
|
145
|
-
[
|
146
|
-
[
|
147
|
-
[
|
153
|
+
['restore', [], {}, []],
|
154
|
+
['save', [], {}, []],
|
155
|
+
['font', ['Helvetica'], { style: :normal }, []],
|
156
|
+
['text_rendering_mode', [:invisible], {}, [
|
157
|
+
['draw_text', ['neither'], default_style, []]
|
148
158
|
]],
|
149
|
-
[
|
159
|
+
['restore', [], {}, []]
|
150
160
|
]]
|
151
161
|
]]
|
152
162
|
]
|
@@ -154,86 +164,98 @@ Even more
|
|
154
164
|
end
|
155
165
|
end
|
156
166
|
|
157
|
-
describe
|
158
|
-
context
|
167
|
+
describe 'font finding' do
|
168
|
+
context 'with a font that exists' do
|
159
169
|
let(:svg) { '<text font-family="monospace">hello</text>' }
|
160
170
|
|
161
|
-
it
|
171
|
+
it 'finds the font and uses it' do
|
162
172
|
element.process
|
163
|
-
expect(flatten_calls(element.base_calls)).to include ['font', ['Courier'], {style: :normal}]
|
173
|
+
expect(flatten_calls(element.base_calls)).to include ['font', ['Courier'], { style: :normal }]
|
164
174
|
end
|
165
175
|
end
|
166
176
|
|
167
177
|
context "with a font that doesn't exist" do
|
168
178
|
let(:svg) { '<text font-family="does not exist">hello</text>' }
|
169
179
|
|
170
|
-
it
|
180
|
+
it 'uses the fallback font' do
|
171
181
|
element.process
|
172
|
-
expect(flatten_calls(element.base_calls)).to include ['font', ['Times-Roman'], {style: :normal}]
|
182
|
+
expect(flatten_calls(element.base_calls)).to include ['font', ['Times-Roman'], { style: :normal }]
|
173
183
|
end
|
174
184
|
|
175
|
-
context
|
176
|
-
before { document.font_registry.installed_fonts.delete(
|
185
|
+
context 'when there is no fallback font' do
|
186
|
+
before { document.font_registry.installed_fonts.delete('Times-Roman') }
|
177
187
|
|
178
188
|
it "doesn't call the font method and logs a warning" do
|
179
189
|
element.process
|
180
190
|
expect(element.base_calls.flatten).to_not include 'font'
|
181
|
-
expect(document.warnings.first).to include
|
191
|
+
expect(document.warnings.first).to include 'is not a known font'
|
182
192
|
end
|
183
193
|
end
|
184
194
|
end
|
185
195
|
end
|
186
196
|
|
187
|
-
describe
|
197
|
+
describe '<tref>' do
|
188
198
|
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>' }
|
189
199
|
let(:element) { Prawn::SVG::Elements::Root.new(document, document.root, [], fake_state) }
|
190
200
|
|
191
|
-
it
|
201
|
+
it 'references the text' do
|
192
202
|
element.process
|
193
203
|
expect(flatten_calls(element.base_calls)[9..11]).to eq [
|
194
|
-
[
|
195
|
-
[
|
196
|
-
[
|
204
|
+
['fill_color', ['ff0000'], {}],
|
205
|
+
['font', ['Helvetica'], { style: :normal }],
|
206
|
+
['draw_text', ['my reference text'],
|
207
|
+
{ size: 16, style: :normal, text_anchor: 'start', at: [10.0, :relative], offset: [0, 0] }]
|
197
208
|
]
|
198
209
|
end
|
199
210
|
end
|
200
211
|
|
201
|
-
describe
|
212
|
+
describe 'dx and dy attributes' do
|
202
213
|
let(:svg) { '<text x="10 20" dx="30 50 80" dy="2">Hi there, this is a good test</text>' }
|
203
214
|
|
204
|
-
it
|
215
|
+
it 'correctly calculates the positions of the text' do
|
205
216
|
element.process
|
206
217
|
|
207
218
|
expect(flatten_calls(element.base_calls)).to eq [
|
208
|
-
[
|
209
|
-
[
|
210
|
-
[
|
211
|
-
|
212
|
-
[
|
219
|
+
['text_group', [], {}],
|
220
|
+
['font', ['Helvetica'], { style: :normal }],
|
221
|
+
['draw_text', ['H'],
|
222
|
+
{ size: 16, style: :normal, text_anchor: 'start', at: [10.0, :relative], offset: [30.0, 2.0] }],
|
223
|
+
['draw_text', ['i'],
|
224
|
+
{ size: 16, style: :normal, text_anchor: 'start', at: [20.0, :relative], offset: [50.0, 0] }],
|
225
|
+
['draw_text', [' there, this is a good test'],
|
226
|
+
{ size: 16, style: :normal, text_anchor: 'start', at: [:relative, :relative], offset: [80.0, 0] }]
|
213
227
|
]
|
214
228
|
end
|
215
229
|
end
|
216
230
|
|
217
|
-
describe
|
231
|
+
describe 'rotate attribute' do
|
218
232
|
let(:svg) { '<text rotate="10 20 30 40 50 60 70 80 90 100">Hi <tspan rotate="0">this</tspan> ok!</text>' }
|
219
233
|
|
220
|
-
it
|
234
|
+
it 'correctly calculates the positions of the text' do
|
221
235
|
element.process
|
222
236
|
|
223
237
|
expect(flatten_calls(element.base_calls)).to eq [
|
224
|
-
[
|
225
|
-
[
|
226
|
-
[
|
227
|
-
|
228
|
-
[
|
229
|
-
|
230
|
-
[
|
231
|
-
|
232
|
-
[
|
233
|
-
[
|
234
|
-
[
|
235
|
-
|
236
|
-
[
|
238
|
+
['text_group', [], {}],
|
239
|
+
['font', ['Helvetica'], { style: :normal }],
|
240
|
+
['draw_text', ['H'],
|
241
|
+
{ size: 16, style: :normal, text_anchor: 'start', at: [:relative, :relative], offset: [0, 0], rotate: -10.0 }],
|
242
|
+
['draw_text', ['i'],
|
243
|
+
{ size: 16, style: :normal, text_anchor: 'start', at: [:relative, :relative], offset: [0, 0], rotate: -20.0 }],
|
244
|
+
['draw_text', [' '],
|
245
|
+
{ size: 16, style: :normal, text_anchor: 'start', at: [:relative, :relative], offset: [0, 0], rotate: -30.0 }],
|
246
|
+
['save', [], {}],
|
247
|
+
['font', ['Helvetica'], { style: :normal }],
|
248
|
+
['draw_text', ['this'],
|
249
|
+
{ size: 16, style: :normal, text_anchor: 'start', at: [:relative, :relative], offset: [0, 0] }],
|
250
|
+
['restore', [], {}],
|
251
|
+
['draw_text', [' '],
|
252
|
+
{ size: 16, style: :normal, text_anchor: 'start', at: [:relative, :relative], offset: [0, 0], rotate: -80.0 }],
|
253
|
+
['draw_text', ['o'],
|
254
|
+
{ size: 16, style: :normal, text_anchor: 'start', at: [:relative, :relative], offset: [0, 0], rotate: -90.0 }],
|
255
|
+
['draw_text', ['k'],
|
256
|
+
{ size: 16, style: :normal, text_anchor: 'start', at: [:relative, :relative], offset: [0, 0], rotate: -100.0 }],
|
257
|
+
['draw_text', ['!'],
|
258
|
+
{ size: 16, style: :normal, text_anchor: 'start', at: [:relative, :relative], offset: [0, 0], rotate: -100.0 }]
|
237
259
|
]
|
238
260
|
end
|
239
261
|
end
|
@@ -241,26 +263,26 @@ Even more
|
|
241
263
|
describe "when there's a comment inside the text element" do
|
242
264
|
let(:svg) { '<text>Hi <!-- comment --> there</text>' }
|
243
265
|
|
244
|
-
it
|
266
|
+
it 'ignores the comment' do
|
245
267
|
element.process
|
246
268
|
|
247
269
|
expect(flatten_calls(element.calls)).to eq [
|
248
|
-
[
|
249
|
-
[
|
250
|
-
[
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
[
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
270
|
+
['text_group', [], {}],
|
271
|
+
['font', ['Helvetica'], { style: :normal }],
|
272
|
+
['draw_text',
|
273
|
+
['Hi '],
|
274
|
+
{ size: 16,
|
275
|
+
style: :normal,
|
276
|
+
text_anchor: 'start',
|
277
|
+
at: [:relative, :relative],
|
278
|
+
offset: [0, 0] }],
|
279
|
+
['draw_text',
|
280
|
+
['there'],
|
281
|
+
{ size: 16,
|
282
|
+
style: :normal,
|
283
|
+
text_anchor: 'start',
|
284
|
+
at: [:relative, :relative],
|
285
|
+
offset: [0, 0] }]
|
264
286
|
]
|
265
287
|
end
|
266
288
|
end
|
@@ -1,84 +1,84 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
RSpec.describe Prawn::SVG::FontRegistry do
|
4
|
-
describe
|
4
|
+
describe '#load' do
|
5
5
|
let(:pdf) { Prawn::Document.new }
|
6
6
|
let(:font_registry) { Prawn::SVG::FontRegistry.new(pdf.font_families) }
|
7
7
|
|
8
|
-
it
|
8
|
+
it 'matches a built in font' do
|
9
9
|
font_registry.load("blah, 'courier', nothing").name.should == 'Courier'
|
10
10
|
end
|
11
11
|
|
12
|
-
it
|
13
|
-
font_registry.load(
|
14
|
-
font_registry.load(
|
15
|
-
font_registry.load(
|
12
|
+
it 'matches a default font' do
|
13
|
+
font_registry.load('serif').name.should
|
14
|
+
font_registry.load('blah, serif').name.should
|
15
|
+
font_registry.load('blah, serif , test').name.should == 'Times-Roman'
|
16
16
|
end
|
17
17
|
|
18
|
-
if Prawn::SVG::FontRegistry.new({}).installed_fonts[
|
19
|
-
it
|
20
|
-
font_registry.load(
|
21
|
-
font_registry.load(
|
22
|
-
font_registry.load(
|
23
|
-
font_registry.load(
|
18
|
+
if Prawn::SVG::FontRegistry.new({}).installed_fonts['Verdana']
|
19
|
+
it 'matches a font installed on the system' do
|
20
|
+
font_registry.load('verdana, sans-serif').name.should
|
21
|
+
font_registry.load('VERDANA, sans-serif').name.should
|
22
|
+
font_registry.load('something, "Times New Roman", serif').name.should
|
23
|
+
font_registry.load('something, Times New Roman, serif').name.should == 'Times New Roman'
|
24
24
|
end
|
25
25
|
else
|
26
26
|
it "not running font test because we couldn't find Verdana installed on the system"
|
27
27
|
end
|
28
28
|
|
29
29
|
it "returns nil if it can't find any such font" do
|
30
|
-
font_registry.load(
|
31
|
-
font_registry.load(
|
30
|
+
font_registry.load('blah, thing').should be_nil
|
31
|
+
font_registry.load('').should be_nil
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
-
describe
|
36
|
-
let(:ttf) { instance_double(Prawn::SVG::TTF, family:
|
37
|
-
let(:ttf2) { instance_double(Prawn::SVG::TTF, family:
|
35
|
+
describe '#installed_fonts' do
|
36
|
+
let(:ttf) { instance_double(Prawn::SVG::TTF, family: 'Awesome Font', subfamily: 'Italic') }
|
37
|
+
let(:ttf2) { instance_double(Prawn::SVG::TTF, family: 'Awesome Font', subfamily: 'Regular') }
|
38
38
|
before { Prawn::SVG::FontRegistry.external_font_families.clear }
|
39
39
|
|
40
40
|
let(:pdf) do
|
41
41
|
doc = Prawn::Document.new
|
42
42
|
doc.font_families.update({
|
43
|
-
|
43
|
+
'Awesome Font' => { italic: 'second.ttf', normal: 'file.ttf' }
|
44
44
|
})
|
45
45
|
doc
|
46
46
|
end
|
47
47
|
|
48
48
|
let(:font_registry) { Prawn::SVG::FontRegistry.new(pdf.font_families) }
|
49
49
|
|
50
|
-
it
|
51
|
-
expect(Prawn::SVG::FontRegistry).to receive(:font_path).and_return([
|
52
|
-
expect(Dir).to receive(:[]).with(
|
53
|
-
expect(Prawn::SVG::TTF).to receive(:new).with(
|
54
|
-
expect(Prawn::SVG::TTF).to receive(:new).with(
|
50
|
+
it 'does not override existing entries in pdf when loading external fonts' do
|
51
|
+
expect(Prawn::SVG::FontRegistry).to receive(:font_path).and_return(['x'])
|
52
|
+
expect(Dir).to receive(:[]).with('x/**/*').and_return(['file.ttf', 'second.ttf'])
|
53
|
+
expect(Prawn::SVG::TTF).to receive(:new).with('file.ttf').and_return(ttf)
|
54
|
+
expect(Prawn::SVG::TTF).to receive(:new).with('second.ttf').and_return(ttf2)
|
55
55
|
expect(File).to receive(:file?).at_least(:once).and_return(true)
|
56
56
|
|
57
57
|
Prawn::SVG::FontRegistry.load_external_fonts
|
58
58
|
font_registry.installed_fonts
|
59
59
|
|
60
|
-
existing_font = font_registry.installed_fonts[
|
61
|
-
expect(existing_font).to eq(:
|
60
|
+
existing_font = font_registry.installed_fonts['Awesome Font']
|
61
|
+
expect(existing_font).to eq(italic: 'second.ttf', normal: 'file.ttf')
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
|
-
describe
|
66
|
-
let(:ttf) { instance_double(Prawn::SVG::TTF, family:
|
67
|
-
let(:ttf2) { instance_double(Prawn::SVG::TTF, family:
|
65
|
+
describe '::load_external_fonts' do
|
66
|
+
let(:ttf) { instance_double(Prawn::SVG::TTF, family: 'Awesome Font', subfamily: 'Italic') }
|
67
|
+
let(:ttf2) { instance_double(Prawn::SVG::TTF, family: 'Awesome Font', subfamily: 'Regular') }
|
68
68
|
|
69
69
|
before { Prawn::SVG::FontRegistry.external_font_families.clear }
|
70
70
|
|
71
|
-
it
|
72
|
-
expect(Prawn::SVG::FontRegistry).to receive(:font_path).and_return([
|
73
|
-
expect(Dir).to receive(:[]).with(
|
74
|
-
expect(Prawn::SVG::TTF).to receive(:new).with(
|
75
|
-
expect(Prawn::SVG::TTF).to receive(:new).with(
|
71
|
+
it 'scans the font path and loads in some fonts' do
|
72
|
+
expect(Prawn::SVG::FontRegistry).to receive(:font_path).and_return(['x'])
|
73
|
+
expect(Dir).to receive(:[]).with('x/**/*').and_return(['file.ttf', 'second.ttf'])
|
74
|
+
expect(Prawn::SVG::TTF).to receive(:new).with('file.ttf').and_return(ttf)
|
75
|
+
expect(Prawn::SVG::TTF).to receive(:new).with('second.ttf').and_return(ttf2)
|
76
76
|
expect(File).to receive(:file?).at_least(:once).and_return(true)
|
77
77
|
|
78
78
|
Prawn::SVG::FontRegistry.load_external_fonts
|
79
79
|
|
80
80
|
result = Prawn::SVG::FontRegistry.external_font_families
|
81
|
-
expect(result).to eq(
|
81
|
+
expect(result).to eq('Awesome Font' => { italic: 'file.ttf', normal: 'second.ttf' })
|
82
82
|
end
|
83
83
|
end
|
84
84
|
end
|
data/spec/prawn/svg/font_spec.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
|
-
require File.dirname(__FILE__)
|
1
|
+
require "#{File.dirname(__FILE__)}/../../spec_helper"
|
2
2
|
|
3
3
|
describe Prawn::SVG::Font do
|
4
|
-
describe
|
5
|
-
it
|
4
|
+
describe '#initialize' do
|
5
|
+
it 'maps generic font name to built-in font' do
|
6
6
|
font_registry = Prawn::SVG::FontRegistry.new({})
|
7
7
|
font = Prawn::SVG::Font.new('sans-serif', :normal, :normal, font_registry: font_registry)
|
8
8
|
font.name.should == 'Helvetica'
|
9
9
|
end
|
10
10
|
|
11
|
-
it
|
11
|
+
it 'preserves generic font name if mapped' do
|
12
12
|
font_registry = Prawn::SVG::FontRegistry.new('sans-serif' => { normal: 'Times-Roman' })
|
13
13
|
font = Prawn::SVG::Font.new('sans-serif', :normal, :normal, font_registry: font_registry)
|
14
14
|
font.name.should == 'sans-serif'
|