r2dsvg 0.4.2 → 0.5.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
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/r2dsvg.rb +56 -467
- metadata +2 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 218f3f75c56256cfbf3ccd9f0755d31bfad7ec53ae8a235e32103118de2fc8e9
|
4
|
+
data.tar.gz: 21aba9150ca1a85bfe48352c02e5bac17b276de41133b97d4e887a823bd85a2d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0250d7a5f4a76af1811e16ad9d38a9e9be12a13708abf20698876a5a94d22fa293ce94bb879d19f900fa802e78b85e73c8eedc455418cf7dd7685f70938a9181
|
7
|
+
data.tar.gz: 8fe0f560dddc4f193338019384356665170fb130a08f03407a3dda0709d03e4b91ed3fbf40c7cb2a0911344a915ab0aa6b9d92b6c28db584e3654a7c1c349200
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/lib/r2dsvg.rb
CHANGED
@@ -5,483 +5,50 @@
|
|
5
5
|
# Description: Experimental gem to render SVG within a Ruby2D application.
|
6
6
|
|
7
7
|
|
8
|
-
require '
|
9
|
-
require 'onedrb'
|
10
|
-
require 'ruby2d' # experimental gem depends upon simple2d binaries
|
11
|
-
require 'dom_render'
|
8
|
+
require 'r2dsvg/r2dsvg_module'
|
12
9
|
|
13
10
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
rect {fill: yellow}
|
18
|
-
line, polyline {stroke: green; stroke-width: 3}
|
19
|
-
text {fill: red, size: 20}
|
20
|
-
|
21
|
-
CSS
|
22
|
-
|
23
|
-
class Svgle
|
11
|
+
class Reader
|
12
|
+
include R2dEngine
|
13
|
+
using ColouredText
|
24
14
|
|
25
|
-
|
26
|
-
|
27
|
-
def initialize(*args)
|
28
|
-
super(*args)
|
29
|
-
@attr_map ||= {fill: :color}
|
30
|
-
end
|
15
|
+
def initialize(s, model=Svgle, debug: false)
|
31
16
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
name = (@attr_map[name].to_s + '=').to_sym
|
36
|
-
@obj.method(name).call(val) if @obj.respond_to? name
|
37
|
-
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
end
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
module SvgleX
|
46
|
-
|
47
|
-
refine Svgle::Element do
|
17
|
+
svg, _ = RXFHelper.read(s)
|
18
|
+
doc = model.new(svg, debug: debug)
|
19
|
+
@a = Render.new(doc, debug: debug).to_a
|
48
20
|
|
49
|
-
def obj=(object)
|
50
|
-
@obj = object
|
51
|
-
end
|
52
21
|
|
53
|
-
def obj()
|
54
|
-
@obj
|
55
|
-
end
|
56
|
-
|
57
22
|
end
|
58
|
-
|
59
23
|
|
60
|
-
|
61
|
-
|
62
|
-
def text=(raw_s)
|
63
|
-
|
64
|
-
oldval = @child_elements.first
|
65
|
-
|
66
|
-
r = super(raw_s)
|
67
|
-
self.obj.text = raw_s if oldval != raw_s
|
68
|
-
|
69
|
-
return r
|
70
|
-
|
71
|
-
end
|
24
|
+
def to_a()
|
25
|
+
@a
|
72
26
|
end
|
73
27
|
|
74
28
|
end
|
75
29
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
30
|
class R2dSvg
|
80
31
|
include Ruby2D
|
32
|
+
include R2dEngine
|
81
33
|
using ColouredText
|
82
34
|
using SvgleX
|
83
35
|
|
84
|
-
class Render < DomRender
|
85
|
-
|
86
|
-
def audio(e, attributes, raw_style)
|
87
|
-
|
88
|
-
puts 'inside audio attributes: ' + attributes.inspect if @debug
|
89
|
-
style = style_filter(attributes).merge(raw_style)
|
90
|
-
h = attributes
|
91
|
-
|
92
|
-
sources = e.xpath('source').map do |x|
|
93
|
-
h = x.attributes.to_h
|
94
|
-
h.delete :style
|
95
|
-
h
|
96
|
-
end
|
97
|
-
|
98
|
-
[:embed_audio, sources, e]
|
99
|
-
end
|
100
|
-
|
101
|
-
def circle(e, attributes, raw_style)
|
102
|
-
|
103
|
-
style = style_filter(attributes).merge(raw_style)
|
104
|
-
|
105
|
-
h = attributes
|
106
|
-
|
107
|
-
x, y, radius= %i(cx cy r).map{|x| h[x].to_i }
|
108
|
-
fill = h[:fill]
|
109
|
-
|
110
|
-
|
111
|
-
[:draw_circle, [x, y], radius, fill, style, render_all(e)]
|
112
|
-
end
|
113
|
-
|
114
|
-
# not yet implemented
|
115
|
-
#
|
116
|
-
def ellipse(e, attributes, raw_style)
|
117
|
-
|
118
|
-
style = style_filter(attributes).merge(raw_style)
|
119
|
-
h = attributes
|
120
|
-
|
121
|
-
x, y= %i(cx cy).map{|x| h[x].to_i }
|
122
|
-
width = h[:rx].to_i * 2
|
123
|
-
height = h[:ry].to_i * 2
|
124
|
-
|
125
|
-
[:draw_arc, [x, y, width, height], style, render_all(e)]
|
126
|
-
end
|
127
|
-
|
128
|
-
def line(e, attributes, raw_style)
|
129
|
-
|
130
|
-
style = style_filter(attributes).merge(raw_style)
|
131
|
-
|
132
|
-
x1, y1, x2, y2 = %i(x1 y1 x2 y2).map{|x| attributes[x].to_i }
|
133
|
-
|
134
|
-
[:draw_line, [x1, y1, x2, y2], style, render_all(e)]
|
135
|
-
end
|
136
|
-
|
137
|
-
|
138
|
-
def image(e, attributes, raw_style)
|
139
|
-
|
140
|
-
style = style_filter(attributes).merge(raw_style)
|
141
|
-
h = attributes
|
142
|
-
|
143
|
-
x, y, width, height = %i(x y width height).map{|x| h[x] ? h[x].to_i : nil }
|
144
|
-
src = h[:'xlink:href']
|
145
|
-
|
146
|
-
[:draw_image, [x, y, width, height], src, style, e, render_all(e)]
|
147
|
-
end
|
148
|
-
|
149
|
-
def polygon(e, attributes, raw_style)
|
150
|
-
|
151
|
-
style = style_filter(attributes).merge(raw_style)
|
152
|
-
points = attributes[:points].split(/\s+/). \
|
153
|
-
map {|x| x.split(/\s*,\s*/).map(&:to_i)}
|
154
|
-
|
155
|
-
[:draw_polygon, points, style, e, render_all(e)]
|
156
|
-
end
|
157
|
-
|
158
|
-
def polyline(e, attributes, raw_style)
|
159
|
-
|
160
|
-
style = style_filter(attributes).merge(raw_style)
|
161
|
-
points = attributes[:points].split(/\s+/). \
|
162
|
-
map {|x| x.split(/\s*,\s*/).map(&:to_i)}
|
163
|
-
|
164
|
-
[:draw_lines, points, style, render_all(e)]
|
165
|
-
end
|
166
|
-
|
167
|
-
def rect(e, attributes, raw_style)
|
168
|
-
|
169
|
-
puts 'inside rect attributes: ' + attributes.inspect if @debug
|
170
|
-
style = style_filter(attributes).merge(raw_style)
|
171
|
-
h = attributes
|
172
|
-
|
173
|
-
x1, y1, width, height = %i(x y width height).map{|x| h[x].to_i }
|
174
|
-
x2, y2, = x1 + width, y1 + height
|
175
|
-
|
176
|
-
[:draw_rectangle, [x1, y1, x2, y2], style, e, render_all(e)]
|
177
|
-
end
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
def svg(e, attributes, raw_style)
|
182
|
-
|
183
|
-
style = style_filter(attributes).merge(raw_style)
|
184
|
-
|
185
|
-
h = attributes
|
186
|
-
width, height = %i(width height).map{|x| h[x].to_i }
|
187
|
-
|
188
|
-
[:draw_rectangle, [0, 0, width, height], style, render_all(e)]
|
189
|
-
end
|
190
|
-
|
191
|
-
def text(e, attributes, raw_style)
|
192
|
-
|
193
|
-
style = style_filter(attributes).merge(raw_style)
|
194
|
-
style.merge!({font_size: '20'})
|
195
|
-
|
196
|
-
x, y = %i(x y).map{|x| attributes[x].to_i }
|
197
|
-
|
198
|
-
[:draw_text, [x, y], e.text, style, e, render_all(e)]
|
199
|
-
end
|
200
|
-
|
201
|
-
private
|
202
|
-
|
203
|
-
def style_filter(attributes)
|
204
|
-
|
205
|
-
%i(stroke stroke-width fill z-index).inject({}) do |r,x|
|
206
|
-
attributes.has_key?(x) ? r.merge(x => attributes[x]) : r
|
207
|
-
end
|
208
|
-
|
209
|
-
end
|
210
|
-
|
211
|
-
end
|
212
|
-
|
213
|
-
class DrawingInstructions
|
214
|
-
using ColouredText
|
215
|
-
|
216
|
-
attr_accessor :area
|
217
|
-
|
218
|
-
|
219
|
-
def initialize(window, debug: false)
|
220
|
-
|
221
|
-
@window, @debug = window, debug
|
222
|
-
|
223
|
-
end
|
224
|
-
|
225
|
-
def draw_arc(args)
|
226
|
-
|
227
|
-
dimensions, style = args
|
228
|
-
|
229
|
-
x, y, width, height = dimensions
|
230
|
-
|
231
|
-
#gc = gc_ini(fill: style[:fill] || :none)
|
232
|
-
#@area.window.draw_arc(gc, 1, x, y, width, height, 0, 64 * 360)
|
233
|
-
end
|
234
|
-
|
235
|
-
def draw_circle(args)
|
236
|
-
|
237
|
-
coords, radius, fill, style, e = args
|
238
|
-
|
239
|
-
x1, y1 = coords
|
240
|
-
|
241
|
-
if @debug then
|
242
|
-
puts 'inside draw_circle'.info
|
243
|
-
puts ('style: ' + style.inspect).debug
|
244
|
-
end
|
245
|
-
|
246
|
-
obj = Circle.new(
|
247
|
-
x: x1, y: y1,
|
248
|
-
radius: radius,
|
249
|
-
sectors: 32,
|
250
|
-
color: style[:fill],
|
251
|
-
z: style[:"z-index"].to_i
|
252
|
-
)
|
253
|
-
e.obj = obj if e.respond_to? :obj=
|
254
|
-
@window.add obj
|
255
|
-
|
256
|
-
end
|
257
|
-
|
258
|
-
def draw_image(args)
|
259
|
-
|
260
|
-
dimensions, src, style, e = args
|
261
|
-
|
262
|
-
x, y, width, height = dimensions
|
263
|
-
|
264
|
-
filepath = Tempfile.new('r2dsvg').path + File.basename(src)
|
265
|
-
puts 'filepath: ' + filepath.inspect if @debug
|
266
|
-
File.write filepath, RXFHelper.read(src).first
|
267
|
-
|
268
|
-
|
269
|
-
if File.exists? filepath then
|
270
|
-
|
271
|
-
obj = Image.new(
|
272
|
-
filepath,
|
273
|
-
x: x, y: y,
|
274
|
-
width: width, height: height,
|
275
|
-
color: style[:fill],
|
276
|
-
z: style[:"z-index"].to_i
|
277
|
-
)
|
278
|
-
|
279
|
-
e.obj = obj if e.respond_to? :obj=
|
280
|
-
@window.add obj
|
281
|
-
end
|
282
|
-
end
|
283
|
-
|
284
|
-
def draw_line(args)
|
285
|
-
|
286
|
-
coords, style, e = args
|
287
|
-
|
288
|
-
x1, y1, x2, y2 = coords
|
289
|
-
|
290
|
-
if @debug then
|
291
|
-
puts 'inside draw_rectangle'.info
|
292
|
-
puts ('style: ' + style.inspect).debug
|
293
|
-
end
|
294
|
-
|
295
|
-
obj = Line.new(
|
296
|
-
x1: x1, y1: y1,
|
297
|
-
x2: x2, y2: y2,
|
298
|
-
width: style[:"stroke-width"].to_f,
|
299
|
-
color: style[:"stroke"],
|
300
|
-
z: style[:"z-index"].to_i
|
301
|
-
)
|
302
|
-
|
303
|
-
e.obj = obj if e.respond_to? :obj=
|
304
|
-
@window.add obj
|
305
|
-
|
306
|
-
end
|
307
|
-
|
308
|
-
def draw_polygon(args)
|
309
|
-
|
310
|
-
vertices, style, e = args
|
311
|
-
|
312
|
-
puts ('vertices: ' + vertices.inspect).debug if @debug
|
313
|
-
|
314
|
-
if @debug then
|
315
|
-
puts 'inside draw_polygon'.info
|
316
|
-
puts ('style: ' + style.inspect).debug
|
317
|
-
end
|
318
|
-
|
319
|
-
puts ('vertices: ' + vertices.inspect).debug if @debug
|
320
|
-
|
321
|
-
h = vertices.map.with_index do |coords,i|
|
322
|
-
|
323
|
-
%w(x y).zip(coords).map {|key, c| [(key + (i+1).to_s).to_sym, c] }
|
324
|
-
|
325
|
-
end.flatten(1).to_h
|
326
|
-
puts ('triangle h: ' + h.inspect).debug if @debug
|
327
|
-
|
328
|
-
puts ('triangle h merged: ' + h.inspect).debug if @debug
|
329
|
-
obj = Triangle.new(h.merge({color: style[:fill], z: style[:"z-index"].to_i}))
|
330
|
-
e.obj = obj if e.respond_to? :obj=
|
331
|
-
@window.add obj
|
332
|
-
end
|
333
|
-
|
334
|
-
|
335
|
-
# not yet implemented
|
336
|
-
#
|
337
|
-
def draw_lines(args)
|
338
|
-
|
339
|
-
coords, width, style, e = args
|
340
|
-
|
341
|
-
x1, y1, x2, y2 = coords
|
342
|
-
|
343
|
-
|
344
|
-
end
|
345
|
-
|
346
|
-
def draw_rectangle(args)
|
347
|
-
|
348
|
-
coords, style, e = args
|
349
|
-
|
350
|
-
x1, y1, x2, y2 = coords
|
351
|
-
|
352
|
-
if @debug then
|
353
|
-
puts 'inside draw_rectangle'.info
|
354
|
-
puts ('style: ' + style.inspect).debug
|
355
|
-
end
|
356
|
-
|
357
|
-
obj = Rectangle.new(
|
358
|
-
x: x1, y: y1,
|
359
|
-
width: x2 - x1, height: y2 - y1,
|
360
|
-
color: style[:fill],
|
361
|
-
z: style[:"z-index"].to_i
|
362
|
-
)
|
363
|
-
e.obj = obj if e.respond_to? :obj=
|
364
|
-
@window.add obj
|
365
|
-
|
366
|
-
end
|
367
|
-
|
368
|
-
def draw_text(args)
|
369
|
-
|
370
|
-
coords, text, style, e = args
|
371
|
-
|
372
|
-
x, y = coords
|
373
|
-
|
374
|
-
if @debug then
|
375
|
-
puts 'inside draw_text'.info
|
376
|
-
puts ('style: ' + style.inspect).debug
|
377
|
-
end
|
378
|
-
|
379
|
-
obj = Text.new(
|
380
|
-
text,
|
381
|
-
x: x, y: y,
|
382
|
-
#font: 'vera.ttf',
|
383
|
-
size: style[:font_size].to_i,
|
384
|
-
color: style[:color],
|
385
|
-
z: style[:"z-index"].to_i
|
386
|
-
)
|
387
|
-
puts 'e: ' + e.inspect
|
388
|
-
e.obj = obj
|
389
|
-
@window.add obj
|
390
|
-
|
391
|
-
end
|
392
|
-
|
393
|
-
# Ruby 2D supports a number of popular audio formats, including WAV,
|
394
|
-
# MP3, Ogg Vorbis, and FLAC.
|
395
|
-
|
396
|
-
def embed_audio(args)
|
397
|
-
|
398
|
-
sources, e = args
|
399
|
-
|
400
|
-
if @debug then
|
401
|
-
puts 'sources: ' + sources.inspect if @debug
|
402
|
-
puts 'inside embed_audio'.info
|
403
|
-
end
|
404
|
-
|
405
|
-
|
406
|
-
audio_files = sources.map do |source|
|
407
|
-
|
408
|
-
filepath = Tempfile.new('r2dsvg').path + File.basename(source[:src])
|
409
|
-
File.write filepath, RXFHelper.read(source[:src]).first
|
410
|
-
filepath
|
411
|
-
end
|
412
|
-
|
413
|
-
audio = audio_files.find {|file| File.exists? file }
|
414
|
-
|
415
|
-
return unless audio
|
416
|
-
|
417
|
-
file = File.exists?(audio) ? audio : nil
|
418
|
-
puts 'file: ' + file.inspect if @debug
|
419
|
-
|
420
|
-
obj = Sound.new(file)
|
421
|
-
e.obj = obj
|
422
|
-
|
423
|
-
def e.play() self.obj.play() end
|
424
|
-
|
425
|
-
end
|
426
|
-
|
427
|
-
def window(args)
|
428
|
-
end
|
429
|
-
|
430
|
-
def render(a)
|
431
|
-
method(a[0]).call(args=a[1..2])
|
432
|
-
draw a[3]
|
433
|
-
end
|
434
|
-
|
435
|
-
def script(args)
|
436
|
-
|
437
|
-
end
|
438
|
-
|
439
|
-
def style(args)
|
440
|
-
end
|
441
|
-
|
442
|
-
private
|
443
|
-
|
444
|
-
def draw(a)
|
445
|
-
|
446
|
-
#threads = []
|
447
|
-
|
448
|
-
a.each do |rawx|
|
449
|
-
|
450
|
-
#threads << Thread.new do
|
451
|
-
x, *remaining = rawx
|
452
|
-
|
453
|
-
if x.is_a? Symbol then
|
454
|
-
method(x).call(args=remaining)
|
455
|
-
elsif x.is_a? String then
|
456
|
-
draw remaining
|
457
|
-
elsif x.is_a? Array
|
458
|
-
draw remaining
|
459
|
-
else
|
460
|
-
method(x).call(remaining.take 2)
|
461
|
-
end
|
462
|
-
#end
|
463
|
-
|
464
|
-
end
|
465
|
-
|
466
|
-
#threads.join
|
467
|
-
|
468
|
-
end
|
469
|
-
|
470
|
-
end
|
471
|
-
|
472
36
|
attr_reader :doc
|
473
37
|
|
474
|
-
def initialize(s, title: 'R2dSVG', debug: false)
|
38
|
+
def initialize(s, title: 'R2dSVG', debug: false, server: false)
|
475
39
|
|
476
40
|
@debug = debug
|
477
41
|
|
478
42
|
@window = window = Window.new
|
479
43
|
@loaded = false
|
44
|
+
@model = Svgle
|
480
45
|
|
481
46
|
read(s, title)
|
482
47
|
|
483
|
-
|
484
|
-
|
48
|
+
if server then
|
49
|
+
drb = OneDrb::Server.new(host: '127.0.0.1', port: '57844', obj: self)
|
50
|
+
Thread.new { drb.start }
|
51
|
+
end
|
485
52
|
|
486
53
|
if @loaded then
|
487
54
|
|
@@ -529,31 +96,53 @@ class R2dSvg
|
|
529
96
|
@window.clear
|
530
97
|
end
|
531
98
|
|
532
|
-
def read(
|
99
|
+
def read(unknown, title=@title)
|
100
|
+
|
533
101
|
@loaded = false
|
534
102
|
@window.clear
|
535
|
-
|
536
|
-
|
537
|
-
|
103
|
+
doc = nil
|
104
|
+
|
105
|
+
if unknown.is_a? String
|
106
|
+
|
107
|
+
svg, _ = RXFHelper.read(unknown)
|
108
|
+
doc = @model.new(svg, callback: self, debug: @debug)
|
109
|
+
instructions = Render.new(doc, debug: @debug).to_a
|
538
110
|
|
111
|
+
elsif unknown.is_a? Array
|
112
|
+
|
113
|
+
puts 'array found' if @debug
|
114
|
+
|
115
|
+
instructions = unknown
|
116
|
+
|
117
|
+
end
|
539
118
|
|
540
119
|
drawing = DrawingInstructions.new @window, debug: @debug
|
541
|
-
puts ('instructions: ' + instructions.inspect).debug if @debug
|
542
120
|
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
threads << Thread.new do
|
549
|
-
doc.root.xpath('//script').each {|x| eval x.text.unescape }
|
550
|
-
drawing.render instructions
|
551
|
-
end
|
121
|
+
if doc then
|
122
|
+
|
123
|
+
@width, @height = %i(width height).map{|x| doc.root.attributes[x].to_i }
|
124
|
+
@window.set title: title, width: @width, height: @height
|
552
125
|
|
553
|
-
threads.join
|
554
126
|
|
555
|
-
|
556
|
-
|
127
|
+
threads = []
|
128
|
+
|
129
|
+
threads << Thread.new do
|
130
|
+
doc.root.xpath('//script').each {|x| eval x.texts.join }
|
131
|
+
drawing.render instructions
|
132
|
+
end
|
133
|
+
|
134
|
+
threads.join
|
135
|
+
|
136
|
+
@loaded = true
|
137
|
+
@doc = doc
|
138
|
+
|
139
|
+
else
|
140
|
+
|
141
|
+
drawing.render instructions
|
142
|
+
h = instructions[2]
|
143
|
+
@width, @height = h[:width].to_i, h[:height].to_i
|
144
|
+
@window.set title: 'Untitled', width: @width, height: @height
|
145
|
+
end
|
557
146
|
|
558
147
|
end
|
559
148
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: r2dsvg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Robertson
|
@@ -35,7 +35,7 @@ cert_chain:
|
|
35
35
|
2z9cm0kGX/0pBfn8cMKC0JgNNNONx3uqiCAhaBEN35C8dqBjua/CK4rMoKEB7XQq
|
36
36
|
OAk+mR2SqyWecmZhdnsnm86T
|
37
37
|
-----END CERTIFICATE-----
|
38
|
-
date: 2020-
|
38
|
+
date: 2020-06-07 00:00:00.000000000 Z
|
39
39
|
dependencies:
|
40
40
|
- !ruby/object:Gem::Dependency
|
41
41
|
name: svgle
|
metadata.gz.sig
CHANGED
Binary file
|