r2dsvg 0.4.0 → 0.5.2

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 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