Я пытаюсь создать приложение простого рисования с использованием Python, GTK3 и cairo. Инструмент должен иметь различные кисти и некоторую маркер highlighter. Я решил, что могу использовать альфа-свойство инсульта для его создания. Однако, точки соединения создаются перекрывающимися, что создает странный эффект.
Вот код, отвечающий за эту красную кисть и режим подсветки:
def draw_brush(widget, x, y, odata, width=2.5, r=1, g=0, b=0, alpha=1):
cr = cairo.Context(widget.surface)
cr.set_source_rgba(r, g, b, alpha)
cr.set_line_width(width)
cr.set_line_cap(1)
cr.set_line_join(0)
for stroke in odata:
for i, point in enumerate(stroke):
if len(stroke) == 1:
radius = 2
cr.arc(point['x'], point['y'], radius, 0, 2.0 * math.pi)
cr.fill()
cr.stroke()
elif i != 0:
cr.move_to(stroke[i - 1]['x'], stroke[i - 1]['y'])
cr.line_to(point['x'], point['y'])
cr.stroke()
cr.save()
Код, который нажимает на щелчок мыши:
def motion_notify_event_cb(self, widget, event):
point = {'x': event.x, 'y': event.y, 'time': time.time()}
if self.odata:
self.odata[-1].append(point)
if widget.surface is None:
return False
if event.state & Gdk.EventMask.BUTTON_PRESS_MASK:
if self.buttons['current'] == 'freehand':
draw_brush(widget, event.x, event.y, self.odata)
if self.buttons['current'] == 'highlight':
draw_brush(widget, event.x, event.y, self.odata, width=12.5,
r=220/255, g=240/255, b=90/255, alpha=0.10)
widget.queue_draw()
return True
Может ли кто-нибудь указать способ предотвращения перекрытия точек на этой кривой?
Update
Решение Uli, кажется, предлагает частичное средство, но удар все еще не выглядит красивым, кажется, что он перерисовывается снова и снова:
Обновление с частично работающим кодом
Мне еще не удалось создать маркер с каиром. Самое близкое, что я могу получить, находится в следующем gist. Затвор приложения имеет аналогичную функциональность, но он написан на Perl поверх libgoocanvas, который больше не поддерживается. Надеюсь, щедрость здесь изменит ситуацию...
Обновление
доступные операторы (Linux, GTK + 3):
In [3]: [item for item in dir(cairo) if item.startswith("OPERATOR")]
Out[3]:
['OPERATOR_ADD',
'OPERATOR_ATOP',
'OPERATOR_CLEAR',
'OPERATOR_DEST',
'OPERATOR_DEST_ATOP',
'OPERATOR_DEST_IN',
'OPERATOR_DEST_OUT',
'OPERATOR_DEST_OVER',
'OPERATOR_IN',
'OPERATOR_OUT',
'OPERATOR_OVER',
'OPERATOR_SATURATE',
'OPERATOR_SOURCE',
'OPERATOR_XOR']