r2dsvg 0.4.0 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6da60aae210c67cdc2a6c908e0721ddcfc07a6b516fbdedb49fb8ba33736dd43
4
- data.tar.gz: 3a2735d01e9aaa4e319c4481ecce6d811fac9f7506086627865fe4a8be40a3c3
3
+ metadata.gz: 64d907b1e113033b25cb0f8f103f743c3994298a4bf66e14844c320dcb59c88a
4
+ data.tar.gz: 9ec11cbf12e85142093d766b56426d8cfe67c89cb57f3baf5991171514dfac61
5
5
  SHA512:
6
- metadata.gz: 7370accf36a0322a26c0885f535f6fdc866fbbb65ff8f250d6a827d97251446fa716a71e2859a2f45873433f307001eaf78e48a491c5944fdacf04a3f8515cdc
7
- data.tar.gz: 390bb9e097fb6660f8bc6f73750dab72f6b92500a521c094bf92b103311744cb5d41e7671e590b6d62116a2115afdb278e96a129c7fd0f8a98cad84bbd5e42ac
6
+ metadata.gz: 75fd5bd8348ae09903a12edb5a48b51bce69158b9a5d7630f52e9be2a8d1927669e7916255098aeb4eaf6260bcf39a9a7514f24176034f4dff0b36337b98e473
7
+ data.tar.gz: fdfd7077c881d6892ac2340e2bf10733ef041c3691f37e7a956e7710b09d6f082b16d5416f622dde272ec6d93b4530bff276aac901c87f397865fc83139d0c4a
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -5,487 +5,179 @@
5
5
  # Description: Experimental gem to render SVG within a Ruby2D application.
6
6
 
7
7
 
8
- require 'svgle'
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
- DEFAULT_CSS = <<CSS
15
-
16
- svg {background-color: white}
17
- rect {fill: yellow}
18
- line, polyline {stroke: green; stroke-width: 3}
19
- text {fill: red, size: 20}
20
-
21
- CSS
22
-
23
- module SvgleX
11
+ class Reader
12
+ include R2dEngine
13
+ using ColouredText
24
14
 
25
- refine Svgle::Element do
15
+ def initialize(s, model=Svgle, debug: false)
26
16
 
27
- def obj=(object)
28
- @obj = object
29
- end
17
+ svg, _ = RXFHelper.read(s)
18
+ doc = model.new(svg, debug: debug)
19
+ @a = Render.new(doc, debug: debug).to_a
30
20
 
31
- def obj()
32
- @obj
33
- end
34
21
 
35
22
  end
36
23
 
24
+ def to_a()
25
+ @a
26
+ end
27
+
37
28
  end
38
29
 
39
30
  class R2dSvg
40
31
  include Ruby2D
32
+ include R2dEngine
41
33
  using ColouredText
42
34
  using SvgleX
43
35
 
44
- class Render < DomRender
45
-
46
- def audio(e, attributes, raw_style)
47
-
48
- puts 'inside audio attributes: ' + attributes.inspect if @debug
49
- style = style_filter(attributes).merge(raw_style)
50
- h = attributes
51
-
52
- sources = e.xpath('source').map do |x|
53
- h = x.attributes.to_h
54
- h.delete :style
55
- h
56
- end
57
-
58
- [:embed_audio, sources, e]
59
- end
60
-
61
- def circle(e, attributes, raw_style)
62
-
63
- style = style_filter(attributes).merge(raw_style)
64
-
65
- h = attributes
66
-
67
- x, y, radius= %i(cx cy r).map{|x| h[x].to_i }
68
- fill = h[:fill]
69
-
70
-
71
- [:draw_circle, [x, y], radius, fill, style, render_all(e)]
72
- end
73
-
74
- # not yet implemented
75
- #
76
- def ellipse(e, attributes, raw_style)
77
-
78
- style = style_filter(attributes).merge(raw_style)
79
- h = attributes
80
-
81
- x, y= %i(cx cy).map{|x| h[x].to_i }
82
- width = h[:rx].to_i * 2
83
- height = h[:ry].to_i * 2
84
-
85
- [:draw_arc, [x, y, width, height], style, render_all(e)]
86
- end
87
-
88
- def line(e, attributes, raw_style)
89
-
90
- style = style_filter(attributes).merge(raw_style)
36
+ attr_reader :doc
91
37
 
92
- x1, y1, x2, y2 = %i(x1 y1 x2 y2).map{|x| attributes[x].to_i }
38
+ def initialize(s, title: 'R2dSVG', debug: false, server: false)
93
39
 
94
- [:draw_line, [x1, y1, x2, y2], style, render_all(e)]
95
- end
96
-
40
+ @debug = debug
97
41
 
98
- def image(e, attributes, raw_style)
99
-
100
- style = style_filter(attributes).merge(raw_style)
101
- h = attributes
102
-
103
- x, y, width, height = %i(x y width height).map{|x| h[x] ? h[x].to_i : nil }
104
- src = h[:'xlink:href']
105
-
106
- [:draw_image, [x, y, width, height], src, style, e, render_all(e)]
107
- end
42
+ @window = window = Window.new
43
+ @loaded = false
44
+ @model = Svgle
108
45
 
109
- def polygon(e, attributes, raw_style)
110
-
111
- style = style_filter(attributes).merge(raw_style)
112
- points = attributes[:points].split(/\s+/). \
113
- map {|x| x.split(/\s*,\s*/).map(&:to_i)}
46
+ read(s, title)
114
47
 
115
- [:draw_polygon, points, style, e, render_all(e)]
116
- end
117
-
118
- def polyline(e, attributes, raw_style)
119
-
120
- style = style_filter(attributes).merge(raw_style)
121
- points = attributes[:points].split(/\s+/). \
122
- map {|x| x.split(/\s*,\s*/).map(&:to_i)}
123
-
124
- [:draw_lines, points, style, render_all(e)]
125
- end
126
-
127
- def rect(e, attributes, raw_style)
128
-
129
- puts 'inside rect attributes: ' + attributes.inspect if @debug
130
- style = style_filter(attributes).merge(raw_style)
131
- h = attributes
132
-
133
- x1, y1, width, height = %i(x y width height).map{|x| h[x].to_i }
134
- x2, y2, = x1 + width, y1 + height
135
-
136
- [:draw_rectangle, [x1, y1, x2, y2], style, e, render_all(e)]
48
+ if server then
49
+ drb = OneDrb::Server.new(host: '127.0.0.1', port: '57844', obj: self)
50
+ Thread.new { drb.start }
137
51
  end
138
52
 
139
- def script(e, attributes, style)
140
- [:script]
141
- end
142
-
143
- def svg(e, attributes, raw_style)
144
-
145
- style = style_filter(attributes).merge(raw_style)
146
-
147
- h = attributes
148
- width, height = %i(width height).map{|x| h[x].to_i }
53
+ if @loaded then
149
54
 
150
- [:draw_rectangle, [0, 0, width, height], style, render_all(e)]
151
- end
152
-
153
- def text(e, attributes, raw_style)
154
-
155
- style = style_filter(attributes).merge(raw_style)
156
- style.merge!({font_size: '20'})
157
-
158
- x, y = %i(x y).map{|x| attributes[x].to_i }
159
-
160
- [:draw_text, [x, y], e.text, style, e, render_all(e)]
161
- end
55
+ sleep 0.05
56
+
57
+ window.on(:mouse_move) do |event|
58
+ mouse :mousemove, event
59
+ mouse :mouseenter, event
60
+ end
61
+
62
+ window.on(:mouse_down) do |event|
63
+
64
+ if event.button == :left then
65
+
66
+ # click and mousedown do the same thing
67
+ mouse :click, event
68
+ mouse :mousedown, event
69
+ end
162
70
 
163
- private
71
+ end
164
72
 
165
- def style_filter(attributes)
166
-
167
- %i(stroke stroke-width fill z-index).inject({}) do |r,x|
168
- attributes.has_key?(x) ? r.merge(x => attributes[x]) : r
73
+ window.on :key_down do |event|
74
+ # A key was pressed
75
+ keyboard :keydown, event
169
76
  end
170
77
 
171
78
  end
172
-
173
- end
174
-
175
- class DrawingInstructions
176
- using ColouredText
177
-
178
- attr_accessor :area
179
-
180
-
181
- def initialize(window, debug: false)
182
-
183
- @window, @debug = window, debug
184
-
79
+ =begin
80
+ window.on :key_held do |event|
81
+ # A key is being held down
82
+ puts event.key
83
+ keyboard :onkeyheld, event
185
84
  end
186
85
 
187
- def draw_arc(args)
188
-
189
- dimensions, style = args
190
-
191
- x, y, width, height = dimensions
192
-
193
- #gc = gc_ini(fill: style[:fill] || :none)
194
- #@area.window.draw_arc(gc, 1, x, y, width, height, 0, 64 * 360)
195
- end
196
-
197
- def draw_circle(args)
198
-
199
- coords, radius, fill, style, e = args
200
-
201
- x1, y1 = coords
202
-
203
- if @debug then
204
- puts 'inside draw_circle'.info
205
- puts ('style: ' + style.inspect).debug
206
- end
207
-
208
- obj = Circle.new(
209
- x: x1, y: y1,
210
- radius: radius,
211
- sectors: 32,
212
- color: style[:fill],
213
- z: style[:"z-index"].to_i
214
- )
215
- e.obj = obj if e.respond_to? :obj=
216
- @window.add obj
217
-
218
- end
219
-
220
- def draw_image(args)
221
-
222
- dimensions, src, style, e = args
223
-
224
- x, y, width, height = dimensions
225
-
226
- filepath = Tempfile.new('r2dsvg').path + File.basename(src)
227
- puts 'filepath: ' + filepath.inspect if @debug
228
- File.write filepath, RXFHelper.read(src).first
229
-
230
-
231
- if File.exists? filepath then
232
-
233
- obj = Image.new(
234
- filepath,
235
- x: x, y: y,
236
- width: width, height: height,
237
- color: style[:fill],
238
- z: style[:"z-index"].to_i
239
- )
240
-
241
- e.obj = obj if e.respond_to? :obj=
242
- @window.add obj
243
- end
244
- end
245
-
246
- def draw_line(args)
247
-
248
- coords, style, e = args
249
-
250
- x1, y1, x2, y2 = coords
251
-
252
- if @debug then
253
- puts 'inside draw_rectangle'.info
254
- puts ('style: ' + style.inspect).debug
255
- end
256
-
257
- obj = Line.new(
258
- x1: x1, y1: y1,
259
- x2: x2, y2: y2,
260
- width: style[:"stroke-width"].to_f,
261
- color: style[:"stroke"],
262
- z: style[:"z-index"].to_i
263
- )
264
-
265
- e.obj = obj if e.respond_to? :obj=
266
- @window.add obj
267
-
86
+ window.on :key_up do |event|
87
+ # A key was released
88
+ puts event.key
89
+ keyboard :onkeyup, event
268
90
  end
91
+ =end
92
+ window.show
269
93
 
270
- def draw_polygon(args)
271
-
272
- vertices, style, e = args
273
-
274
- puts ('vertices: ' + vertices.inspect).debug if @debug
275
-
276
- if @debug then
277
- puts 'inside draw_polygon'.info
278
- puts ('style: ' + style.inspect).debug
279
- end
280
-
281
- puts ('vertices: ' + vertices.inspect).debug if @debug
282
-
283
- h = vertices.map.with_index do |coords,i|
284
-
285
- %w(x y).zip(coords).map {|key, c| [(key + (i+1).to_s).to_sym, c] }
286
-
287
- end.flatten(1).to_h
288
- puts ('triangle h: ' + h.inspect).debug if @debug
289
-
290
- puts ('triangle h merged: ' + h.inspect).debug if @debug
291
- obj = Triangle.new(h.merge({color: style[:fill], z: style[:"z-index"].to_i}))
292
- e.obj = obj if e.respond_to? :obj=
293
- @window.add obj
294
- end
295
-
296
-
297
- # not yet implemented
298
- #
299
- def draw_lines(args)
300
-
301
- coords, width, style, e = args
302
-
303
- x1, y1, x2, y2 = coords
304
-
305
-
306
- end
307
-
308
- def draw_rectangle(args)
309
-
310
- coords, style, e = args
311
-
312
- x1, y1, x2, y2 = coords
313
-
314
- if @debug then
315
- puts 'inside draw_rectangle'.info
316
- puts ('style: ' + style.inspect).debug
317
- end
318
-
319
- obj = Rectangle.new(
320
- x: x1, y: y1,
321
- width: x2 - x1, height: y2 - y1,
322
- color: style[:fill],
323
- z: style[:"z-index"].to_i
324
- )
325
- e.obj = obj if e.respond_to? :obj=
326
- @window.add obj
327
-
328
- end
329
94
 
330
- def draw_text(args)
331
-
332
- coords, text, style, e = args
333
-
334
- x, y = coords
335
-
336
- if @debug then
337
- puts 'inside draw_text'.info
338
- puts ('style: ' + style.inspect).debug
339
- end
340
-
341
- obj = Text.new(
342
- text,
343
- x: x, y: y,
344
- #font: 'vera.ttf',
345
- size: style[:font_size].to_i,
346
- color: style[:color],
347
- z: style[:"z-index"].to_i
348
- )
349
- e.obj = obj
350
- @window.add obj
95
+ end
96
+
97
+ def clear()
98
+ @window.clear
99
+ end
100
+
101
+ def read(unknown, title=@title)
351
102
 
352
- end
103
+ @loaded = false
104
+ @window.clear
105
+ doc = nil
353
106
 
354
- # Ruby 2D supports a number of popular audio formats, including WAV,
355
- # MP3, Ogg Vorbis, and FLAC.
356
-
357
- def embed_audio(args)
107
+ if unknown.is_a? String
358
108
 
359
- sources, e = args
109
+ svg, _ = RXFHelper.read(unknown)
110
+ doc = @model.new(svg, callback: self, debug: @debug)
111
+ instructions = Render.new(doc, debug: @debug).to_a
360
112
 
361
- if @debug then
362
- puts 'sources: ' + sources.inspect if @debug
363
- puts 'inside embed_audio'.info
364
- end
365
-
366
-
367
- audio_files = sources.map do |source|
368
-
369
- filepath = Tempfile.new('r2dsvg').path + File.basename(source[:src])
370
- File.write filepath, RXFHelper.read(source[:src]).first
371
- filepath
372
- end
373
-
374
- audio = audio_files.find {|file| File.exists? file }
113
+ elsif unknown.is_a? Array
375
114
 
376
- return unless audio
115
+ puts 'array found' if @debug
377
116
 
378
- file = File.exists?(audio) ? audio : nil
379
- puts 'file: ' + file.inspect if @debug
380
-
381
- obj = Sound.new(file)
382
- e.obj = obj
117
+ instructions = unknown
383
118
 
384
- def e.play() self.obj.play() end
385
-
386
- end
387
-
388
- def window(args)
389
119
  end
120
+
121
+ drawing = DrawingInstructions.new @window, debug: @debug
390
122
 
391
- def render(a)
392
- method(a[0]).call(args=a[1..2])
393
- draw a[3]
394
- end
123
+ if doc then
124
+
125
+ @width, @height = %i(width height).map{|x| doc.root.attributes[x].to_i }
126
+ @window.set title: title, width: @width, height: @height
395
127
 
396
- def script(args)
397
128
 
398
- end
399
-
400
- private
401
-
402
- def draw(a)
403
-
404
129
  threads = []
405
130
 
406
- a.each do |rawx|
407
-
408
- threads << Thread.new do
409
- x, *remaining = rawx
410
-
411
- if x.is_a? Symbol then
412
- method(x).call(args=remaining)
413
- elsif x.is_a? String then
414
- draw remaining
415
- elsif x.is_a? Array
416
- draw remaining
417
- else
418
- method(x).call(remaining.take 2)
419
- end
420
- end
421
-
131
+ threads << Thread.new do
132
+ doc.root.xpath('//script').each {|x| eval x.texts.join }
133
+ drawing.render instructions
422
134
  end
423
135
 
424
136
  threads.join
425
137
 
138
+ @loaded = true
139
+ @doc = doc
140
+
141
+ else
142
+
143
+ drawing.render instructions
144
+ h = instructions[2]
145
+ @width, @height = h[:width].to_i, h[:height].to_i
146
+ @window.set title: 'Untitled', width: @width, height: @height
426
147
  end
427
-
148
+
149
+ end
150
+
151
+ def refresh()
152
+ puts 'do nothing' if @debug
428
153
  end
429
154
 
430
- attr_reader :doc
431
-
432
- def initialize(s, title: 'R2dSVG', debug: false)
433
-
434
- @debug = debug
155
+
156
+ private
157
+
158
+ def keyboard(action, event)
435
159
 
436
- @window = window = Window.new
160
+ doc = @doc
437
161
 
438
- @doc = read(s, title)
162
+ @doc.root.xpath("//*[@on#{action}]").each do |x|
439
163
 
440
- drb = OneDrb::Server.new host: '127.0.0.1', port: '57844', obj: self
441
- Thread.new { drb.start }
442
-
443
- window.on(:mouse_move) do |event|
444
- mouse :mousemove, event
445
- mouse :mouseenter, event
446
- end
447
-
448
- window.on(:mouse_down) do |event|
449
-
450
- if event.button == :left then
451
-
452
- # click and mousedown do the same thing
453
- mouse :click, event
454
- mouse :mousedown, event
164
+ if block_given? then
165
+ valid = yield(x)
166
+ statement = x.method(('on' + action.to_s).to_sym).call()
167
+ puts 'statement: ' + statement.inspect if @debug
168
+ eval statement if valid
169
+ else
170
+ statement = x.method(('on' + action.to_s).to_sym).call()
171
+ puts 'statement: ' + statement.inspect if @debug
172
+ eval statement
455
173
  end
456
-
457
- end
458
-
459
- window.show
460
-
461
174
 
462
- end
463
-
464
- def read(s, title=@title)
465
-
466
- svg, _ = RXFHelper.read(s)
467
- doc = Svgle.new(svg, callback: self, debug: @debug)
468
- instructions = Render.new(doc, debug: @debug).to_a
469
-
470
-
471
- drawing = DrawingInstructions.new @window, debug: @debug
472
- puts ('instructions: ' + instructions.inspect).debug if @debug
473
-
474
- @width, @height = %i(width height).map{|x| doc.root.attributes[x].to_i }
475
- @window.set title: title, width: @width, height: @height
476
-
477
- Thread.new do
478
- doc.root.xpath('//script').each {|x| eval x.text.unescape }
479
- drawing.render instructions
480
175
  end
481
176
 
482
- doc
483
-
177
+ @doc.event[action].each {|name| method(name).call event }
178
+
484
179
  end
485
180
 
486
-
487
- private
488
-
489
181
  def mouse(action, event)
490
182
 
491
183
  doc = @doc
@@ -533,6 +225,23 @@ class R2dSvg
533
225
  end
534
226
 
535
227
  end
228
+
229
+ private
230
+
231
+ def timeout(duration=0.8)
232
+
233
+ @t = Time.now
234
+
235
+ Thread.new do
236
+
237
+ while @t + duration > Time.now do
238
+ sleep 0.1
239
+ end
240
+
241
+ yield
242
+
243
+ end
244
+ end
536
245
 
537
246
  end
538
247
 
@@ -0,0 +1,586 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # file: r2dsvg_module.rb
4
+
5
+ # Description: Experimental gem to render SVG within a Ruby2D application.
6
+
7
+
8
+ #require 'svgle'
9
+ require 'onedrb'
10
+ require 'svgle'
11
+ require 'dom_render'
12
+ require 'ruby2d' # experimental gem depends upon simple2d binaries
13
+
14
+
15
+ DEFAULT_CSS = <<CSS
16
+ g {background-color: blue}
17
+ svg {background-color: white}
18
+ rect {fill: yellow}
19
+ line, polyline {stroke: green; stroke-width: 3}
20
+ text {fill: red, size: 20}
21
+
22
+ CSS
23
+
24
+
25
+
26
+ class Svgle::Shape
27
+
28
+ def initialize(*args)
29
+ super(*args)
30
+ @attr_map ||= {fill: :color}
31
+ end
32
+
33
+
34
+ end
35
+
36
+
37
+ module SvgleX
38
+
39
+
40
+ refine Svgle::Text do
41
+
42
+ def text=(raw_s)
43
+
44
+ oldval = @child_elements.first
45
+
46
+ r = super(raw_s)
47
+ self.obj.text = raw_s if oldval != raw_s
48
+
49
+ return r
50
+
51
+ end
52
+ end
53
+
54
+ end
55
+
56
+
57
+ module R2dEngine
58
+
59
+
60
+
61
+ class Render < DomRender
62
+
63
+ def audio(e, attributes)
64
+
65
+ puts 'inside audio attributes: ' + attributes.inspect if @debug
66
+
67
+ h = attributes
68
+
69
+ sources = e.xpath('source').map do |x|
70
+ h = x.attributes.to_h
71
+ h.delete :style
72
+ h
73
+ end
74
+
75
+ [:embed_audio, sources, e]
76
+ end
77
+
78
+ def circle(e, attributes)
79
+
80
+
81
+
82
+ h = attributes
83
+
84
+ x, y, radius= %i(cx cy r).map{|x| h[x].to_i }
85
+ fill = h[:fill]
86
+
87
+
88
+ [:draw_circle, [x, y], radius, fill, attributes, render_all(e)]
89
+ end
90
+
91
+ # not yet implemented
92
+ #
93
+ def ellipse(e, attributes)
94
+
95
+ h = attributes
96
+
97
+ x, y= %i(cx cy).map{|x| h[x].to_i }
98
+ width = h[:rx].to_i * 2
99
+ height = h[:ry].to_i * 2
100
+
101
+ [:draw_arc, [x, y, width, height], attributes, render_all(e)]
102
+ end
103
+
104
+ def g(e, attributes)
105
+
106
+ puts 'inside rect attributes: ' + attributes.inspect if @debug
107
+
108
+ h = attributes
109
+
110
+ x1, y1, width, height = %i(x y width height).map{|x| h[x].to_i }
111
+ x2, y2, = x1 + width, y1 + height
112
+
113
+ [:draw_rectangle, [x1, y1, x2, y2], attributes, e, render_all(e)]
114
+ end
115
+
116
+
117
+
118
+ def line(e, attributes)
119
+
120
+
121
+ x1, y1, x2, y2 = %i(x1 y1 x2 y2).map{|x| attributes[x].to_i }
122
+
123
+ [:draw_line, [x1, y1, x2, y2], attributes, render_all(e)]
124
+ end
125
+
126
+
127
+ def image(e, attributes)
128
+
129
+ h = attributes
130
+
131
+ x, y, width, height = %i(x y width height).map{|x| h[x] ? h[x].to_i : nil }
132
+ src = h[:'xlink:href']
133
+
134
+ [:draw_image, [x, y, width, height], src, attributes, e, render_all(e)]
135
+ end
136
+
137
+ def polygon(e, attributes)
138
+
139
+
140
+ points = attributes[:points].split(/\s+/). \
141
+ map {|x| x.split(/\s*,\s*/).map(&:to_i)}
142
+
143
+ [:draw_polygon, points, attributes, e, render_all(e)]
144
+ end
145
+
146
+ def polyline(e, attributes)
147
+
148
+ points = attributes[:points].split(/\s+/). \
149
+ map {|x| x.split(/\s*,\s*/).map(&:to_i)}
150
+
151
+ [:draw_lines, points, attributes, render_all(e)]
152
+ end
153
+
154
+ def rect(e, attributes)
155
+
156
+ puts 'inside rect attributes: ' + attributes.inspect if @debug
157
+
158
+ h = attributes
159
+
160
+ x1, y1, width, height = %i(x y width height).map{|x| h[x].to_i }
161
+ x2, y2, = x1 + width, y1 + height
162
+
163
+ [:draw_rectangle, [x1, y1, x2, y2], attributes, e, render_all(e)]
164
+ end
165
+
166
+
167
+
168
+ def svg(e, attributes)
169
+
170
+ h = attributes
171
+ width, height = %i(width height).map{|x| h[x].to_i }
172
+
173
+ [:draw_rectangle, [0, 0, width, height], attributes, render_all(e)]
174
+ end
175
+
176
+ def text(e, attributes)
177
+
178
+
179
+ attributes.merge!({font_size: '20'})
180
+
181
+ x, y = %i(x y).map{|x| attributes[x].to_i }
182
+
183
+ [:draw_text, [x, y], e.text, attributes, e, render_all(e)]
184
+ end
185
+
186
+
187
+ end
188
+
189
+ class DrawingInstructions
190
+ using ColouredText
191
+
192
+ attr_accessor :area
193
+
194
+
195
+ def initialize(window, debug: false)
196
+
197
+ @window, @debug = window, debug
198
+
199
+ end
200
+
201
+ def draw_arc(args)
202
+
203
+ dimensions, style = args
204
+
205
+ x, y, width, height = dimensions
206
+
207
+ #gc = gc_ini(fill: style[:fill] || :none)
208
+ #@area.window.draw_arc(gc, 1, x, y, width, height, 0, 64 * 360)
209
+ end
210
+
211
+ def draw_circle(args)
212
+
213
+ coords, radius, fill, style, e = args
214
+
215
+ x1, y1 = coords
216
+
217
+ if @debug then
218
+ puts 'inside draw_circle'.info
219
+ puts ('style: ' + style.inspect).debug
220
+ end
221
+
222
+ obj = Circle.new(
223
+ x: x1, y: y1,
224
+ radius: radius,
225
+ sectors: 32,
226
+ color: style[:fill],
227
+ z: style[:"z-index"].to_i
228
+ )
229
+ e.obj = obj if e.respond_to? :obj=
230
+ @window.add obj
231
+
232
+ end
233
+
234
+ def draw_image(args)
235
+
236
+ dimensions, src, style, e = args
237
+
238
+ x, y, width, height = dimensions
239
+
240
+ filepath = Tempfile.new('r2dsvg').path + File.basename(src)
241
+ puts 'filepath: ' + filepath.inspect if @debug
242
+ File.write filepath, RXFHelper.read(src).first
243
+
244
+
245
+ if File.exists? filepath then
246
+
247
+ obj = Image.new(
248
+ filepath,
249
+ x: x, y: y,
250
+ width: width, height: height,
251
+ color: style[:fill],
252
+ z: style[:"z-index"].to_i
253
+ )
254
+
255
+ e.obj = obj if e.respond_to? :obj=
256
+ @window.add obj
257
+ end
258
+ end
259
+
260
+ def draw_line(args)
261
+
262
+ coords, style, e = args
263
+
264
+ x1, y1, x2, y2 = coords
265
+
266
+ if @debug then
267
+ puts 'inside draw_rectangle'.info
268
+ puts ('style: ' + style.inspect).debug
269
+ end
270
+
271
+ obj = Line.new(
272
+ x1: x1, y1: y1,
273
+ x2: x2, y2: y2,
274
+ width: style[:"stroke-width"].to_f,
275
+ color: style[:"stroke"],
276
+ z: style[:"z-index"].to_i
277
+ )
278
+
279
+ e.obj = obj if e.respond_to? :obj=
280
+ @window.add obj
281
+
282
+ end
283
+
284
+ def draw_polygon(args)
285
+
286
+ vertices, style, e = args
287
+
288
+ puts ('vertices: ' + vertices.inspect).debug if @debug
289
+
290
+ if @debug then
291
+ puts 'inside draw_polygon'.info
292
+ puts ('style: ' + style.inspect).debug
293
+ end
294
+
295
+ puts ('vertices: ' + vertices.inspect).debug if @debug
296
+
297
+ h = vertices.map.with_index do |coords,i|
298
+
299
+ %w(x y).zip(coords).map {|key, c| [(key + (i+1).to_s).to_sym, c] }
300
+
301
+ end.flatten(1).to_h
302
+ puts ('triangle h: ' + h.inspect).debug if @debug
303
+
304
+ puts ('triangle h merged: ' + h.inspect).debug if @debug
305
+ obj = Triangle.new(h.merge({color: style[:fill], z: style[:"z-index"].to_i}))
306
+ e.obj = obj if e.respond_to? :obj=
307
+ @window.add obj
308
+ end
309
+
310
+
311
+ # not yet implemented
312
+ #
313
+ def draw_lines(args)
314
+
315
+ coords, width, style, e = args
316
+
317
+ x1, y1, x2, y2 = coords
318
+
319
+
320
+ end
321
+
322
+ def draw_rectangle(args)
323
+
324
+ coords, style, e = args
325
+
326
+ x1, y1, x2, y2 = coords
327
+
328
+ if @debug then
329
+ puts 'inside draw_rectangle'.info
330
+ puts ('style: ' + style.inspect).debug
331
+ end
332
+
333
+ obj = Rectangle.new(
334
+ x: x1, y: y1,
335
+ width: x2 - x1, height: y2 - y1,
336
+ color: style[:fill],
337
+ z: style[:"z-index"].to_i
338
+ )
339
+ e.obj = obj if e.respond_to? :obj=
340
+ @window.add obj
341
+
342
+ end
343
+
344
+ def draw_text(args)
345
+
346
+ coords, text, style, e = args
347
+
348
+ x, y = coords
349
+
350
+ if @debug then
351
+ puts 'inside draw_text'.info
352
+ puts ('style: ' + style.inspect).debug
353
+ end
354
+
355
+ obj = Text.new(
356
+ text,
357
+ x: x, y: y,
358
+ #font: 'vera.ttf',
359
+ size: style[:font_size].to_i,
360
+ color: style[:color],
361
+ z: style[:"z-index"].to_i
362
+ )
363
+ puts 'e: ' + e.inspect
364
+ e.obj = obj
365
+ @window.add obj
366
+
367
+ end
368
+
369
+ # Ruby 2D supports a number of popular audio formats, including WAV,
370
+ # MP3, Ogg Vorbis, and FLAC.
371
+
372
+ def embed_audio(args)
373
+
374
+ sources, e = args
375
+
376
+ if @debug then
377
+ puts 'sources: ' + sources.inspect if @debug
378
+ puts 'inside embed_audio'.info
379
+ end
380
+
381
+
382
+ audio_files = sources.map do |source|
383
+
384
+ filepath = Tempfile.new('r2dsvg').path + File.basename(source[:src])
385
+ File.write filepath, RXFHelper.read(source[:src]).first
386
+ filepath
387
+ end
388
+
389
+ audio = audio_files.find {|file| File.exists? file }
390
+
391
+ return unless audio
392
+
393
+ file = File.exists?(audio) ? audio : nil
394
+ puts 'file: ' + file.inspect if @debug
395
+
396
+ obj = Sound.new(file)
397
+ e.obj = obj
398
+
399
+ def e.play() self.obj.play() end
400
+
401
+ end
402
+
403
+ def window(args)
404
+ end
405
+
406
+ def render(a)
407
+
408
+ stylex, e = a[-3..-2]
409
+
410
+ if e.respond_to? :attr_map then
411
+
412
+ h = e.attr_map.inject({}) do |r, x|
413
+ key, value = x
414
+ r.merge!({value => stylex[key]})
415
+ end
416
+ a[-3].merge!(h)
417
+ end
418
+
419
+
420
+ method(a[0]).call(args=a[1..2])
421
+ draw a[3]
422
+ end
423
+
424
+ def script(args)
425
+
426
+ end
427
+
428
+ def style(args)
429
+ end
430
+
431
+ private
432
+
433
+ def draw(a)
434
+
435
+ #threads = []
436
+
437
+ a.each do |rawx|
438
+
439
+ #threads << Thread.new do
440
+ puts 'rawx: ;' + rawx.inspect if @debug
441
+ x, *remaining = rawx
442
+
443
+ puts 'x: ;' + x.inspect if @debug
444
+ puts 'remaining: ' + remaining.inspect if @debug
445
+
446
+ if x.is_a? Symbol then
447
+ method(x).call(args=remaining)
448
+ draw(remaining[3])
449
+ elsif x.is_a? String then
450
+ draw remaining
451
+ elsif x.is_a? Array
452
+ draw remaining
453
+ else
454
+ method(x).call(remaining.take 2)
455
+ end
456
+ #end
457
+
458
+ end
459
+
460
+ #threads.join
461
+
462
+ end
463
+
464
+ end
465
+
466
+
467
+
468
+ class App
469
+
470
+ attr_reader :doc
471
+
472
+
473
+ def clear()
474
+ @window.clear
475
+ end
476
+
477
+ def read(s, title=@title)
478
+ @loaded = false
479
+ @window.clear
480
+ svg, _ = RXFHelper.read(s)
481
+ doc = Svgle.new(svg, callback: self, debug: @debug)
482
+ instructions = Render.new(doc, debug: @debug).to_a
483
+
484
+
485
+ drawing = DrawingInstructions.new @window, debug: @debug
486
+ puts ('instructions: ' + instructions.inspect).debug if @debug
487
+
488
+ @width, @height = %i(width height).map{|x| doc.root.attributes[x].to_i }
489
+ @window.set title: title, width: @width, height: @height
490
+
491
+ threads = []
492
+
493
+ threads << Thread.new do
494
+ doc.root.xpath('//script').each {|x| eval x.text.unescape }
495
+ drawing.render instructions
496
+ end
497
+
498
+ threads.join
499
+
500
+ @loaded = true
501
+ @doc = doc
502
+
503
+ end
504
+
505
+ def refresh()
506
+ puts 'do nothing' if @debug
507
+ end
508
+
509
+
510
+ private
511
+
512
+ def keyboard(action, event)
513
+
514
+ doc = @doc
515
+
516
+ @doc.root.xpath("//*[@on#{action}]").each do |x|
517
+
518
+ if block_given? then
519
+ valid = yield(x)
520
+ statement = x.method(('on' + action.to_s).to_sym).call()
521
+ puts 'statement: ' + statement.inspect if @debug
522
+ eval statement if valid
523
+ else
524
+ statement = x.method(('on' + action.to_s).to_sym).call()
525
+ puts 'statement: ' + statement.inspect if @debug
526
+ eval statement
527
+ end
528
+
529
+ end
530
+
531
+ @doc.event[action].each {|name| method(name).call event }
532
+
533
+ end
534
+
535
+ def mouse(action, event)
536
+
537
+ doc = @doc
538
+
539
+ @doc.root.xpath("//*[@on#{action}]").each do |x|
540
+
541
+ #puts 'x.class: ' + x.inspect if @debug
542
+ if x.obj and x.obj.contains? event.x, event.y then
543
+
544
+
545
+ if not x.active? then
546
+ x.active = true
547
+ elsif action == :mouseenter
548
+ next
549
+ end
550
+
551
+ if block_given? then
552
+ valid = yield(x)
553
+ statement = x.method(('on' + action.to_s).to_sym).call()
554
+ puts 'statement: ' + statement.inspect if @debug
555
+ eval statement if valid
556
+ else
557
+ statement = x.method(('on' + action.to_s).to_sym).call()
558
+ puts 'statement: ' + statement.inspect if @debug
559
+ eval statement
560
+ end
561
+
562
+ else
563
+
564
+ if x.active? then
565
+ x.active = false
566
+ onleave
567
+ end
568
+ end
569
+
570
+ end
571
+
572
+ end
573
+
574
+ def onleave()
575
+
576
+ @doc.root.xpath("//*[@onmouseleave]").each do |x|
577
+ puts 'onleave'.info if @debug
578
+ eval x.method(:onmouseleave).call()
579
+ end
580
+
581
+ end
582
+
583
+ end
584
+
585
+ end
586
+
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.0
4
+ version: 0.5.2
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-04-30 00:00:00.000000000 Z
38
+ date: 2020-09-19 00:00:00.000000000 Z
39
39
  dependencies:
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: svgle
@@ -46,7 +46,7 @@ dependencies:
46
46
  version: '0.4'
47
47
  - - ">="
48
48
  - !ruby/object:Gem::Version
49
- version: 0.4.5
49
+ version: 0.4.7
50
50
  type: :runtime
51
51
  prerelease: false
52
52
  version_requirements: !ruby/object:Gem::Requirement
@@ -56,7 +56,7 @@ dependencies:
56
56
  version: '0.4'
57
57
  - - ">="
58
58
  - !ruby/object:Gem::Version
59
- version: 0.4.5
59
+ version: 0.4.7
60
60
  - !ruby/object:Gem::Dependency
61
61
  name: onedrb
62
62
  requirement: !ruby/object:Gem::Requirement
@@ -103,20 +103,20 @@ dependencies:
103
103
  requirements:
104
104
  - - "~>"
105
105
  - !ruby/object:Gem::Version
106
- version: '0.3'
106
+ version: '0.4'
107
107
  - - ">="
108
108
  - !ruby/object:Gem::Version
109
- version: 0.3.2
109
+ version: 0.4.1
110
110
  type: :runtime
111
111
  prerelease: false
112
112
  version_requirements: !ruby/object:Gem::Requirement
113
113
  requirements:
114
114
  - - "~>"
115
115
  - !ruby/object:Gem::Version
116
- version: '0.3'
116
+ version: '0.4'
117
117
  - - ">="
118
118
  - !ruby/object:Gem::Version
119
- version: 0.3.2
119
+ version: 0.4.1
120
120
  description:
121
121
  email: james@jamesrobertson.eu
122
122
  executables: []
@@ -124,6 +124,7 @@ extensions: []
124
124
  extra_rdoc_files: []
125
125
  files:
126
126
  - lib/r2dsvg.rb
127
+ - lib/r2dsvg/r2dsvg_module.rb
127
128
  homepage: https://github.com/jrobertson/r2dsvg
128
129
  licenses:
129
130
  - MIT
metadata.gz.sig CHANGED
Binary file