class AbstractBrushStroke: def __init__(self, goghview, current_layer_key, brush_options): self.goghview = goghview self.goghdoc = self.goghview.goghdoc self.current_layer_key = current_layer_key self.brush_options = brush_options self.brush_provider = BrushProvider(brush_options) self.bounding_rectangle = None self.offset = 0 def start_draw(self, x, y): if len(self.goghdoc.layers) == 0 : return self.last_x = x self.last_y = y self.last_pressure = 0 def draw_to(self, x, y, pressure): if(len(self.goghdoc.layers) == 0): return delta_x = x-self.last_x delta_y = y-self.last_y delta_pressure = pressure-self.last_pressure if delta_x==0 and delta_y==0: return h = math.hypot(delta_x, delta_y) intermediate_points = arange(self.offset, h, self.brush_options.step) intermediate_coords = [(self.last_x+delta_x*t/h, self.last_y+delta_y*t/h, self.last_pressure+delta_pressure*t/h) for t in intermediate_points] self.dab_rect_coords = DabRectCoords(self.last_x, self.last_y, x, y, self.brush_provider, pressure) self.expand_bounding_rectangle(self.dab_rect_coords.get_rectangle()) self.apply_brush_stroke(self.last_x, self.last_y, x, y, intermediate_coords, max(self.last_pressure, pressure)) x_r, y_r, w_r, h_r = rect_to_list(self.dab_rect_coords.get_rectangle()) self.goghview.update_view_pixbuf(x_r, y_r, w_r, h_r) self.goghview.redraw_image_fragment_for_model_coord(x_r, y_r, w_r, h_r) if len(intermediate_points)>0 : self.offset = self.brush_options.step-(h-intermediate_points[-1]) else : self.offset -= h self.last_x, self.last_y, self.last_pressure = x, y, pressure def get_dab_rectangle(self, x0, y0, x1, y1, pressure): brush_width, brush_height = self.brush_provider.get_brush_dimensions(pressure) x, y = int(floor(min(x0, x1)))-brush_width//2, int(floor(min(y0, y1)))-brush_height//2 width, height = int(ceil(abs(x0-x1)))+brush_width, int(ceil(abs(y0-y1)))+brush_height return gtk.gdk.Rectangle(x, y, width, height) def expand_bounding_rectangle(self, new_rect): if self.bounding_rectangle : self.bounding_rectangle = self.bounding_rectangle.union(new_rect) else: self.bounding_rectangle = new_rect.copy() self.bounding_rectangle = self.bounding_rectangle.intersect(gtk.gdk.Rectangle(0, 0, self.goghdoc.width, self.goghdoc.height)) def apply_brush_stroke(self, x0, y0, x1, y1, intermediate_coords, pressure): raise NotImplementedError('Must be implemented in subclass')