pixelflow_canvas 0.7.1 → 0.7.3

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: c090cdc8db292f899c236139eec7643f7511a3ef0d578a5175fd4ca3a6e77edc
4
- data.tar.gz: 0ec735b7b0c0f63b8174e712d82364b01fc7a1c730d74d49be5f8cd2b9701884
3
+ metadata.gz: 41a7011e19eb27f8dfa28ad15746219181b319916b7e96282cd4d2e4e6763f78
4
+ data.tar.gz: 243ea9344e2497cbd997dc22e7fa9bec85bd8b4b20bc304ecd12b96788431352
5
5
  SHA512:
6
- metadata.gz: dc6baa7cb65f20eb65966c99e248854e0550a16749d77a5544e5219a9a305b8f5a6e1d6fe026ff98995e14550f54b9b85a40f1d443e171bcd40550d080314e79
7
- data.tar.gz: f52a914851f557ee3d5b2cf99726dd70f2c33e439c141ca039bc671f945316dfdf57e14c906ed358a8c8131eb959d4ddd48acf76f5f99d5a823a985ff6e432d6
6
+ metadata.gz: e1a230c46f83f1a526bcf3c52bd30ce54a95576234a1c24f9c6bd6556cb1855186769f788f2a23f7a64146c464473fe7590a09d23bc270714ac484ea27d6ff5e
7
+ data.tar.gz: 122f9cc6306a6a510ddcdfb6922e33a98d0efe71fcf0ae37fff06ef85aa64b416a28dc46f9c85e37e23af6916590739484fccd4622ae19f9ab3623e638e496be
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PixelflowCanvas
4
- VERSION = "0.7.1"
4
+ VERSION = "0.7.3"
5
5
  end
@@ -31,7 +31,7 @@ module Pixelflow
31
31
  :nearest => 0,
32
32
  :bilinear => 1,
33
33
  }
34
- def initialize(width, height, color_mode = nil)
34
+ def initialize(width, height, color_mode = nil, &block)
35
35
  @width = 320
36
36
  @height = 180
37
37
  @x = 0
@@ -39,6 +39,7 @@ module Pixelflow
39
39
  @r = color_mode == :palette ? 15 : 255
40
40
  @g = color_mode == :palette ? 0 : 255
41
41
  @b = color_mode == :palette ? 0 : 255
42
+ @mask = nil
42
43
  @color_mode = :rgb
43
44
  @advance_mode = :right
44
45
  @draw_mode = :direct
@@ -48,9 +49,16 @@ module Pixelflow
48
49
  set_size(width, height)
49
50
  set_color_mode(color_mode) if color_mode
50
51
  @last_timestamp = Time.now.to_f
52
+ if block_given?
53
+ instance_eval(&block)
54
+ end
51
55
  end
52
56
 
53
- attr_reader :width, :height
57
+ attr_reader :width, :height, :color_mode
58
+
59
+ def run(&block)
60
+ instance_eval(&block)
61
+ end
54
62
 
55
63
  def set_size(width, height)
56
64
  @x = 0
@@ -152,6 +160,42 @@ module Pixelflow
152
160
  end
153
161
  end
154
162
 
163
+ class MaskGenerator
164
+ def initialize(canvas)
165
+ @canvas = canvas
166
+ @mask = [false] * canvas.width * canvas.height
167
+ end
168
+
169
+ attr_reader :mask
170
+
171
+ def add_color(r = nil, g = nil, b = nil)
172
+ offset = 0
173
+ (0...@canvas.height).each do |y|
174
+ (0...@canvas.width).each do |x|
175
+ if @canvas.color_mode == :rgb
176
+ if @canvas.get_pixel(x, y) == [r, g, b]
177
+ @mask[offset] = true
178
+ end
179
+ else
180
+ if @canvas.get_pixel(x, y) == r
181
+ @mask[offset] = true
182
+ end
183
+ end
184
+ offset += 1
185
+ end
186
+ end
187
+ end
188
+ end
189
+
190
+ def set_mask(&block)
191
+ @mask = MaskGenerator.new(self)
192
+ @mask.instance_eval(&block)
193
+ end
194
+
195
+ def remove_mask()
196
+ @mask = nil
197
+ end
198
+
155
199
  def set_color(r, g = 0, b = 0)
156
200
  @r = r
157
201
  @g = g
@@ -211,14 +255,15 @@ module Pixelflow
211
255
  r ||= @r
212
256
  g ||= @g
213
257
  b ||= @b
214
- x0 = x0.to_i
215
- y0 = y0.to_i
216
- x1 = x1.to_i
217
- y1 = y1.to_i
258
+ x = x.to_i
259
+ y = y.to_i
218
260
  return if x < 0 || x >= @width || y < 0 || y >= @height
219
261
  unless x == @x && y == @y
220
262
  move_to(x, y)
221
263
  end
264
+ if @mask
265
+ return unless @mask.mask[y * @width + x]
266
+ end
222
267
  if @color_mode == :rgb
223
268
  offset = (@y * @width + @x) * 3
224
269
  if @compose_mode == :add
@@ -260,10 +305,8 @@ module Pixelflow
260
305
  end
261
306
 
262
307
  def get_pixel(x, y)
263
- x0 = x0.to_i
264
- y0 = y0.to_i
265
- x1 = x1.to_i
266
- y1 = y1.to_i
308
+ x = x.to_i
309
+ y = y.to_i
267
310
  return 0 if x < 0 || x >= @width || y < 0 || y >= @height
268
311
  if @color_mode == :rgb
269
312
  return @screen[(y * @width + x) * 3, 3]
@@ -473,6 +516,54 @@ module Pixelflow
473
516
  end
474
517
  end
475
518
 
519
+ def draw_arc(x, y, r, a0, a1, close_path = false)
520
+ # x = x.to_i
521
+ # y = y.to_i
522
+ # r = r.to_i
523
+ a0 = a0.to_f
524
+ a1 = a1.to_f
525
+ a0 = a0 * Math::PI / 180.0
526
+ a1 = a1 * Math::PI / 180.0
527
+ da = 1.0 / r
528
+ a = a0
529
+ while a < a1
530
+ x0 = x + r * Math.cos(a)
531
+ y0 = y + r * Math.sin(a)
532
+ a += da
533
+ x1 = x + r * Math.cos(a)
534
+ y1 = y + r * Math.sin(a)
535
+ draw_line(x0, y0, x1, y1)
536
+ end
537
+ if close_path
538
+ x0 = x + r * Math.cos(a0)
539
+ y0 = y + r * Math.sin(a0)
540
+ draw_line(x, y, x0, y0)
541
+ x0 = x + r * Math.cos(a1)
542
+ y0 = y + r * Math.sin(a1)
543
+ draw_line(x, y, x0, y0)
544
+ end
545
+ end
546
+
547
+ def fill_arc(x, y, r, a0, a1)
548
+ # x = x.to_i
549
+ # y = y.to_i
550
+ # r = r.to_i
551
+ a0 = a0.to_f
552
+ a1 = a1.to_f
553
+ a0 = a0 * Math::PI / 180.0
554
+ a1 = a1 * Math::PI / 180.0
555
+ da = 1.0 / r
556
+ a = a0
557
+ while a < a1
558
+ x0 = x + r * Math.cos(a)
559
+ y0 = y + r * Math.sin(a)
560
+ a += da
561
+ x1 = x + r * Math.cos(a)
562
+ y1 = y + r * Math.sin(a)
563
+ fill_triangle(x, y, x0, y0, x1, y1)
564
+ end
565
+ end
566
+
476
567
  def draw_quadratic_bezier(x0, y0, x1, y1, x2, y2, steps = 100)
477
568
  steps = steps.to_i
478
569
  xp = nil
@@ -511,6 +602,88 @@ module Pixelflow
511
602
  draw_line(x2, y2, x0, y0)
512
603
  end
513
604
 
605
+ def fill_triangle(x0, y0, x1, y1, x2, y2)
606
+ x0 = x0.to_i
607
+ y0 = y0.to_i
608
+ x1 = x1.to_i
609
+ y1 = y1.to_i
610
+ x2 = x2.to_i
611
+ y2 = y2.to_i
612
+ if y0 > y1
613
+ x0, x1 = x1, x0
614
+ y0, y1 = y1, y0
615
+ end
616
+ if y1 > y2
617
+ x1, x2 = x2, x1
618
+ y1, y2 = y2, y1
619
+ end
620
+ if y0 > y1
621
+ x0, x1 = x1, x0
622
+ y0, y1 = y1, y0
623
+ end
624
+ total_height = y2 - y0
625
+ (0...total_height).each do |i|
626
+ second_half = i > y1 - y0 || y1 == y0
627
+ segment_height = second_half ? y2 - y1 : y1 - y0
628
+ alpha = i.to_f / total_height
629
+ beta = (i - (second_half ? y1 - y0 : 0)).to_f / segment_height
630
+ ax = x0 + (x2 - x0) * alpha
631
+ ay = y0 + (y2 - y0) * alpha
632
+ bx = second_half ? x1 + (x2 - x1) * beta : x0 + (x1 - x0) * beta
633
+ by = second_half ? y1 + (y2 - y1) * beta : y0 + (y1 - y0) * beta
634
+ if ax > bx
635
+ ax, bx = bx, ax
636
+ ay, by = by, ay
637
+ end
638
+ (ax.to_i..bx.to_i).each do |j|
639
+ set_pixel(j, y0 + i)
640
+ end
641
+ end
642
+ end
643
+
644
+ def flood_fill(x, y, r = nil, g = nil, b = nil)
645
+ x = x.to_i
646
+ y = y.to_i
647
+ r ||= @r
648
+ g ||= @g
649
+ b ||= @b
650
+ return if x < 0 || x >= @width || y < 0 || y >= @height
651
+ sr = 0
652
+ sg = 0
653
+ sb = 0
654
+ if @color_mode == :rgb
655
+ sr = @screen[(y * @width + x) * 3 + 0]
656
+ sg = @screen[(y * @width + x) * 3 + 1]
657
+ sb = @screen[(y * @width + x) * 3 + 2]
658
+ else
659
+ sr = @screen[y * @width + x]
660
+ end
661
+ stack = [[x, y]]
662
+ while stack.any?
663
+ x, y = stack.pop
664
+ next if x < 0 || x >= @width || y < 0 || y >= @height
665
+ if @color_mode == :rgb
666
+ offset = (y * @width + x) * 3
667
+ if @screen[offset + 0] == sr && @screen[offset + 1] == sg && @screen[offset + 2] == sb
668
+ set_pixel(x, y)
669
+ stack.push([x - 1, y])
670
+ stack.push([x + 1, y])
671
+ stack.push([x, y - 1])
672
+ stack.push([x, y + 1])
673
+ end
674
+ else
675
+ offset = y * @width + x
676
+ if @screen[offset] == sr
677
+ set_pixel(x, y)
678
+ stack.push([x - 1, y])
679
+ stack.push([x + 1, y])
680
+ stack.push([x, y - 1])
681
+ stack.push([x, y + 1])
682
+ end
683
+ end
684
+ end
685
+ end
686
+
514
687
  # FONT RENDERING
515
688
 
516
689
  def self.load_font(font)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pixelflow_canvas
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 0.7.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Specht