Class: Clogs::Painter

Inherits:
Object
  • Object
show all
Defined in:
lib/clogs/painter.rb

Overview

An immediate-mode drawing surface over a uiDrawContext.

Shoes is a canvas library: everything from a rect to a button is ultimately painted. libui's draw API is closely modelled on Cairo (paths, brushes, matrices, clipping, save/restore), so the mapping is direct.

Constant Summary collapse

WINDING =
UI::WINDING
ALTERNATE =
UI::ALTERNATE

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(context, width, height) ⇒ Painter

Returns a new instance of Painter.



93
94
95
96
97
# File 'lib/clogs/painter.rb', line 93

def initialize(context, width, height)
  @context = context
  @width = width
  @height = height
end

Instance Attribute Details

#contextObject (readonly)

Returns the value of attribute context.



91
92
93
# File 'lib/clogs/painter.rb', line 91

def context
  @context
end

#heightObject (readonly)

Returns the value of attribute height.



91
92
93
# File 'lib/clogs/painter.rb', line 91

def height
  @height
end

#widthObject (readonly)

Returns the value of attribute width.



91
92
93
# File 'lib/clogs/painter.rb', line 91

def width
  @width
end

Instance Method Details

#clip_rect(x, y, w, h) ⇒ Object



126
127
128
129
130
131
132
# File 'lib/clogs/painter.rb', line 126

def clip_rect(x, y, w, h)
  p = Path.new(WINDING)
  p.rect(x, y, w, h).end!
  UI::L.draw_clip(@context, p.ptr)
ensure
  p&.free
end

#draw(fill: nil, stroke: nil, thickness: 1, cap: UI::CAP_FLAT, join: UI::JOIN_MITER, dashes: nil, fill_mode: WINDING) ⇒ Object

The workhorse: build a path in the block, then fill and/or stroke it.



159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/clogs/painter.rb', line 159

def draw(fill: nil, stroke: nil, thickness: 1, cap: UI::CAP_FLAT, join: UI::JOIN_MITER,
  dashes: nil, fill_mode: WINDING)
  p = Path.new(fill_mode)
  yield p
  p.end!
  UI::L.draw_fill(@context, p.ptr, brush_for(fill).to_ptr) if fill
  if stroke
    sp = UI.stroke_params(thickness, cap: cap, join: join, dashes: dashes)
    UI::L.draw_stroke(@context, p.ptr, brush_for(stroke).to_ptr, sp.to_ptr)
  end
ensure
  p&.free
end

#draw_text(layout, x, y) ⇒ Object



173
174
175
# File 'lib/clogs/painter.rb', line 173

def draw_text(layout, x, y)
  UI::L.draw_text(@context, layout, x, y)
end

#fill_oval(x, y, w, h, paint) ⇒ Object



144
145
146
# File 'lib/clogs/painter.rb', line 144

def fill_oval(x, y, w, h, paint)
  draw(fill: paint) { |p| p.oval(x, y, w, h) }
end

#fill_rect(x, y, w, h, paint) ⇒ Object



134
135
136
137
138
# File 'lib/clogs/painter.rb', line 134

def fill_rect(x, y, w, h, paint)
  return if w <= 0 || h <= 0

  draw(fill: paint) { |p| p.rect(x, y, w, h) }
end

#line(x1, y1, x2, y2, paint, thickness: 1, cap: UI::CAP_FLAT) ⇒ Object



152
153
154
155
156
# File 'lib/clogs/painter.rb', line 152

def line(x1, y1, x2, y2, paint, thickness: 1, cap: UI::CAP_FLAT)
  draw(stroke: paint, thickness: thickness, cap: cap) do |p|
    p.move_to(x1, y1).line_to(x2, y2)
  end
end

#rotate(degrees, cx = 0, cy = 0) ⇒ Object



114
115
116
# File 'lib/clogs/painter.rb', line 114

def rotate(degrees, cx = 0, cy = 0)
  apply_matrix { |m| UI::L.draw_matrix_rotate(m, cx, cy, degrees * Math::PI / 180.0) }
end

#saveObject

libui has no "unclip" and no way to read back the current transform, so every clip or transform must be scoped by save/restore.



101
102
103
104
105
106
# File 'lib/clogs/painter.rb', line 101

def save
  UI::L.draw_save(@context)
  yield self
ensure
  UI::L.draw_restore(@context)
end

#scale(sx, sy, cx = 0, cy = 0) ⇒ Object



118
119
120
# File 'lib/clogs/painter.rb', line 118

def scale(sx, sy, cx = 0, cy = 0)
  apply_matrix { |m| UI::L.draw_matrix_scale(m, cx, cy, sx, sy) }
end

#skew(ax, ay, cx = 0, cy = 0) ⇒ Object



122
123
124
# File 'lib/clogs/painter.rb', line 122

def skew(ax, ay, cx = 0, cy = 0)
  apply_matrix { |m| UI::L.draw_matrix_skew(m, cx, cy, ax * Math::PI / 180.0, ay * Math::PI / 180.0) }
end

#stroke_oval(x, y, w, h, paint, thickness: 1) ⇒ Object



148
149
150
# File 'lib/clogs/painter.rb', line 148

def stroke_oval(x, y, w, h, paint, thickness: 1)
  draw(stroke: paint, thickness: thickness) { |p| p.oval(x, y, w, h) }
end

#stroke_rect(x, y, w, h, paint, thickness: 1) ⇒ Object



140
141
142
# File 'lib/clogs/painter.rb', line 140

def stroke_rect(x, y, w, h, paint, thickness: 1)
  draw(stroke: paint, thickness: thickness) { |p| p.rect(x, y, w, h) }
end

#translate(x, y) ⇒ Object



108
109
110
111
112
# File 'lib/clogs/painter.rb', line 108

def translate(x, y)
  return if x.zero? && y.zero?

  apply_matrix { |m| UI::L.draw_matrix_translate(m, x, y) }
end