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 +4 -4
- data/lib/pixelflow_canvas/version.rb +1 -1
- data/lib/pixelflow_canvas.rb +183 -10
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 41a7011e19eb27f8dfa28ad15746219181b319916b7e96282cd4d2e4e6763f78
|
4
|
+
data.tar.gz: 243ea9344e2497cbd997dc22e7fa9bec85bd8b4b20bc304ecd12b96788431352
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e1a230c46f83f1a526bcf3c52bd30ce54a95576234a1c24f9c6bd6556cb1855186769f788f2a23f7a64146c464473fe7590a09d23bc270714ac484ea27d6ff5e
|
7
|
+
data.tar.gz: 122f9cc6306a6a510ddcdfb6922e33a98d0efe71fcf0ae37fff06ef85aa64b416a28dc46f9c85e37e23af6916590739484fccd4622ae19f9ab3623e638e496be
|
data/lib/pixelflow_canvas.rb
CHANGED
@@ -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
|
-
|
215
|
-
|
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
|
-
|
264
|
-
|
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)
|