Module: ChunkyPNG::Canvas::Drawing

Included in:
ChunkyPNG::Canvas
Defined in:
lib/chunky_png/canvas/drawing.rb

Instance Method Summary collapse

Instance Method Details

#line_xiaolin_wu(x0, y0, x1, y1, color) ⇒ Object Also known as: line

Draws an anti-aliased line using Xiaolin Wu’s algorithm.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/chunky_png/canvas/drawing.rb', line 13

def line_xiaolin_wu(x0, y0, x1, y1, color)
  y0, y1, x0, x1 = y1, y0, x1, x0 if y0 > y1
  dx = x1 - x0
  sx = dx < 0 ? -1 : 1
  dx *= sx
  dy = y1 - y0
  
  if dy == 0 # vertical line
    Range.new(*[x0,x1].sort).each do |x|
      point(x, y0, color)
    end
  elsif dx == 0 # horizontal line
    (y0..y1).each do |y|
      point(x0, y, color)
    end
  elsif dx == dy # diagonal
    x0.step(x1, sx) do |x|
      point(x, y0, color)
      y0 += 1
    end
    
  elsif dy > dx  # vertical displacement
    point(x0, y0, color)
    e_acc = 0          
    e = ((dx << 16) / dy.to_f).round
    (y0...y1-1).each do |i|
      e_acc_temp, e_acc = e_acc, (e_acc + e) & 0xffff
      x0 = x0 + sx if (e_acc <= e_acc_temp)
      w = 0xff - (e_acc >> 8)
      point(x0, y0, ChunkyPNG::Color.fade(color, w)) if include_xy?(x0, y0)
      y0 = y0 + 1
      point(x0 + sx, y0, ChunkyPNG::Color.fade(color, 0xff - w)) if include_xy?(x0 + sx, y0)
    end
    point(x1, y1, color)
    
  else # horizontal displacement
    point(x0, y0, color)
    e_acc = 0
    e = (dy << 16) / dx
    (dx - 1).downto(0) do |i|
      e_acc_temp, e_acc = e_acc, (e_acc + e) & 0xffff
      y0 += 1 if (e_acc <= e_acc_temp)
      w = 0xff - (e_acc >> 8)
      point(x0, y0, ChunkyPNG::Color.fade(color, w)) if include_xy?(x0, y0)
      x0 += sx
      point(x0, y0 + 1, ChunkyPNG::Color.fade(color, 0xff - w)) if include_xy?(x0, y0 + 1)
    end
    point(x1, y1, color)
  end
  
  return self
end

#point(x, y, color) ⇒ Object

Sets a point on the canvas by composing a pixel with its background color.



7
8
9
# File 'lib/chunky_png/canvas/drawing.rb', line 7

def point(x, y, color)
  set_pixel(x, y, ChunkyPNG::Color.compose(color, get_pixel(x, y)))
end

#rect(x0, y0, x1, y1, line_color, fill_color = ChunkyPNG::COLOR::TRANSPARENT) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/chunky_png/canvas/drawing.rb', line 68

def rect(x0, y0, x1, y1, line_color, fill_color = ChunkyPNG::COLOR::TRANSPARENT)

  # Fill
  [x0, x1].min.upto([x0, x1].max) do |x|
    [y0, y1].min.upto([y0, y1].max) do |y|
      point(x, y, fill_color)
    end
  end
  
  # Stroke
  line(x0, y0, x0, y1, line_color)
  line(x0, y1, x1, y1, line_color)
  line(x1, y1, x1, y0, line_color)
  line(x1, y0, x0, y0, line_color)
  
  return self
end