1
# -*- coding: utf-8 -*-
3
# This file is part of emesene.
5
# Emesene is free software; you can redistribute it and/or modify
6
# it under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 2 of the License, or
8
# (at your option) any later version.
10
# emesene is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
15
# You should have received a copy of the GNU General Public License
16
# along with emesene; if not, write to the Free Software
17
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25
''' A set of useful cairo related methods '''
26
def set_context_color(context, color = gtk.gdk.color_parse('#000000')):
27
r = float(color.red) / 65535
28
g = float(color.green) / 65535
29
b = float(color.blue) / 65535
30
context.set_source_rgb(r,g,b)
32
def image_surface_from_pixbuf( pixbuf=None):
33
if pixbuf is not None:
34
return cairo.ImageSurface.create_for_data(
35
pixbuf.get_pixels_array(),
39
pixbuf.get_rowstride())
41
return cairo.ImageSurface(cairo.FORMAT_ARGB32, 1, 1)
43
def resize_image_surface(surface, new_width, new_height):
44
new_surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, new_width, new_height)
45
cr = cairo.Context(new_surface)
46
cr.set_source_surface(surface, 0, 0)
50
class ToolType(object):
51
Paintbrush, Eraser = range(2)
54
def __init__(self,x,y):
58
def __eq__(self, other):
59
if (self.x == other.x) and (self.y == other.y):
65
class DrawAttributes( object ):
66
def __init__( self, color=gtk.gdk.Color(0, 0, 0), stroke_size=8, tool_type=ToolType.Paintbrush ):
68
self.stroke_size = stroke_size
69
self.tool_type = tool_type
71
class BrushPath(object):
72
""" represents a single brush path and has the ability to draw itself """
73
def __init__(self, start_point, draw_attr):
75
self._stroke_size = draw_attr.stroke_size
76
self._shift = int((draw_attr.stroke_size/2) + 1)
77
self._color = draw_attr.color
78
self._tool_type = draw_attr.tool_type
79
if self._tool_type == ToolType.Paintbrush:
80
self._operator = cairo.OPERATOR_OVER
81
else: # self._tool_type == ToolType.Eraser
82
self._operator = cairo.OPERATOR_CLEAR
83
self._path_rectangle = gtk.gdk.Rectangle()
84
self._intermediate_rectangle = gtk.gdk.Rectangle()
88
self._points.append(point)
89
#--- update path rectangle
90
i_rec = self.__create_point_rectangle(point)
91
self._path_rectangle = self._path_rectangle.union(i_rec)
93
#... update intermediate rectangle
94
i_points = self._points[-2:len(self._points)]
95
for pnt in i_points[0:len(i_points)-1]:
96
z_rec = self.__create_point_rectangle(pnt)
97
i_rec = i_rec.union(z_rec)
98
self._intermediate_rectangle = i_rec
100
def get_path_rectangle(self):
101
return self._path_rectangle
102
def get_intermediate_rectangle(self):
103
return self._intermediate_rectangle
105
def draw(self, ctx, x=0, y=0):
106
points = self._points
107
if not points: return
109
ctx.set_operator(self._operator)
111
x, y, width, height = self._path_rectangle
112
ctx.rectangle(x,y, width, height)
114
ctx.set_antialias(cairo.ANTIALIAS_SUBPIXEL)
115
ctx.set_line_cap(cairo.LINE_CAP_ROUND)
116
ctx.set_line_join(cairo.LINE_JOIN_ROUND)
117
set_context_color(ctx, self._color)
118
ctx.set_line_width(self._stroke_size)
119
ctx.move_to(points[0].x, points[0].y)
120
for point in points[1:len(points)]:
121
ctx.line_to(point.x, point.y)
123
ctx.line_to(points[0].x, points[0].y)
127
def print_info(self):
128
for pt in self._points:
131
def __create_point_rectangle(self, point):
132
return gtk.gdk.Rectangle(
133
int(point.x - self._shift), int(point.y - self._shift),
134
int(self._shift * 2), int(self._shift * 2))