def test_region_cmp_hash(): region = cairo.Region() other = cairo.Region() differ = cairo.Region(cairo.RectangleInt(0, 0, 10, 10)) with pytest.raises(TypeError): hash(region) assert region == region assert region == other assert not region != other assert region != differ with pytest.raises(TypeError): region < region with pytest.raises(TypeError): region > region rect = cairo.RectangleInt(1, 2, 10, 13) same = cairo.RectangleInt(1, 2, 10, 13) other = cairo.RectangleInt(2, 2, 10, 13) with pytest.raises(TypeError): hash(rect) assert rect == same assert rect != other with pytest.raises(TypeError): rect < same with pytest.raises(TypeError): rect > same
def rectangle_stroke_region(rect: Optional[Rect2[float]], width: float) -> cairo.Region: if rect is None: return cairo.Region() left_side = cairo.RectangleInt( int(math.floor(rect.x0 - width - 1)), int(math.floor(rect.y0 - width - 1)), int(math.ceil(2 * width + 2)), int(math.ceil(rect.h + 2 * width + 2)), ) right_side = cairo.RectangleInt( int(math.floor(rect.x1 - width - 1)), int(math.floor(rect.y0 - width - 1)), int(math.ceil(2 * width + 2)), int(math.ceil(rect.h + 2 * width + 2)), ) top_side = cairo.RectangleInt( int(math.floor(rect.x0 - width - 1)), int(math.floor(rect.y0 - width - 1)), int(math.ceil(rect.w + 2 * width + 2)), int(math.ceil(2 * width + 2)), ) bottom_side = cairo.RectangleInt( int(math.floor(rect.x0 - width - 1)), int(math.floor(rect.y1 - width - 1)), int(math.ceil(rect.w + 2 * width + 2)), int(math.ceil(2 * width + 2)), ) return cairo.Region([left_side, right_side, top_side, bottom_side])
def draw(self): self.painted = True if self.rgba_support or self.width < 4 or self.height < 4: return outer = cairo.Region(cairo.RectangleInt(0, 0, self.width, self.height)) inner = cairo.Region( cairo.RectangleInt(2, 2, self.width - 4, self.height - 4)) outer.subtract(inner) self.shape_combine_region(outer)
def region(self): # TODO x1 = int(self.left()) x2 = int(self.right()) y1 = int(self.top()) y2 = int(self.bottom()) w = int(self.w) h = int(self.h) r = cairo.Region(cairo.RectangleInt(x=x1, y=y1, width=1, height=h)) r.union(cairo.RectangleInt(x=x1, y=y1, width=w, height=1)) r.union(cairo.RectangleInt(x=x2, y=y1, width=1, height=h)) r.union(cairo.RectangleInt(x=x1, y=y2, width=w, height=1)) return r
def draw_rectangle(self, event_x, event_y): w_context = cairo.Context(self.get_surface()) w_context.set_source_rgba(0.5, 0.5, 0.5, 0.5) w_context.set_dash([3, 3]) w_context.append_path(self.get_image().selection_path) press_x, press_y = w_context.get_current_point() x0 = int( min(press_x, event_x) ) y0 = int( min(press_y, event_y) ) x1 = int( max(press_x, event_x) ) y1 = int( max(press_y, event_y) ) w = x1 - x0 h = y1 - y0 if w <= 0 or h <= 0: self.get_image().selection_path = None return self.get_image().selection_x = x0 self.get_image().selection_y = y0 temp_surface = Gdk.cairo_surface_create_from_pixbuf(self.get_main_pixbuf(), 0, None) temp_surface = temp_surface.map_to_image(cairo.RectangleInt(x0, y0, w, h)) self.get_image().set_selection_pixbuf( Gdk.pixbuf_get_from_surface(temp_surface, \ 0, 0, temp_surface.get_width(), temp_surface.get_height()) ) w_context.new_path() w_context.move_to(x0, y0) w_context.line_to(x1, y0) w_context.line_to(x1, y1) w_context.line_to(x0, y1) w_context.close_path() self.get_image().selection_path = w_context.copy_path() self.temp_path = w_context.copy_path() self.set_temp()
def _artist_invalidated(self, artist: Artist, region: Optional[cairo.Region]) -> None: if region is None: self.invalidate() return if self._last_draw_transform is None: self.invalidate() return xx, xy, yx, yy, x0, y0 = self._last_draw_transform if yx or xy: # XXX: Calculating invalidated region for skew/rotations not implemented. self.invalidate() return region = cairo.Region([ cairo.RectangleInt( math.floor(x0 + xx * rect.x), math.floor(y0 + yy * rect.y), math.ceil(xx * rect.width), math.ceil(yy * rect.height), ) for rect in map(region.get_rectangle, range(region.num_rectangles())) ]) self.invalidate(region)
def test_region_contains_rectangle(): rect = cairo.RectangleInt(1, 2, 10, 13) region = cairo.Region() assert region.contains_rectangle(rect) == cairo.RegionOverlap.OUT assert isinstance(region.contains_rectangle(rect), cairo.RegionOverlap) with pytest.raises(TypeError): region.contains_rectangle(object())
def test_contains_point(): rect = cairo.RectangleInt(0, 0, 10, 10) r = cairo.Region(rect) assert r.contains_point(0, 0) assert not r.contains_point(0, 20) with pytest.raises(TypeError): r.contains_point(0, object())
def cut_pointer(self, region, x, y): d = self.click_box_width region.subtract( cairo.RectangleInt(x=int(x - d), y=int(y - d), width=1 + 2 * d, height=1 + 2 * d))
def test_subtract(): rect = cairo.RectangleInt(0, 0, 10, 10) r = cairo.Region(rect) r.subtract(r) with pytest.raises(TypeError): r.subtract(object()) with pytest.raises(TypeError): r.subtract()
def test_equal(): rect = cairo.RectangleInt(0, 0, 10, 10) r = cairo.Region(rect) assert r.equal(r) with pytest.raises(TypeError): r.equal(object()) with pytest.raises(TypeError): r.equal()
def test_xor(): rect = cairo.RectangleInt(0, 0, 10, 10) r = cairo.Region(rect) r.xor(r) r.xor(rect) with pytest.raises(TypeError): r.xor(object()) with pytest.raises(TypeError): r.xor()
def region(self): w = int(abs(self.x2 - self.x1)) h = int(abs(self.y2 - self.y1)) w = max(w, 1) h = max(h, 1) return cairo.RectangleInt(x=int(self.x1), y=int(self.y1), width=w, height=h)
def test_get_rectangle(): rect = cairo.RectangleInt(0, 0, 10, 10) r = cairo.Region(rect) with pytest.raises(ValueError): r.get_rectangle(-1) with pytest.raises(ValueError): r.get_rectangle(1) assert r.get_rectangle(0) == rect with pytest.raises(TypeError): r.get_rectangle(object())
def region(self): w, h = self.size() pad = self.padding w += 2 * pad h += 2 * pad left, top = self._pos() return cairo.RectangleInt(x=left - pad, y=top - pad, width=w + pad, height=h + pad)
def test_rect_int(x, y, width, height): try: r = cairo.RectangleInt(x, y, width, height) except OverflowError: pass else: assert r.x == x assert r.y == y assert r.width == width assert r.height == height
def test_intersect(): rect = cairo.RectangleInt(0, 0, 10, 10) r = cairo.Region(rect) r.intersect(r) r.intersect(rect) with pytest.raises(TypeError): r.intersect(object()) with pytest.raises(TypeError): r.intersect() assert r.__eq__(object()) == NotImplemented assert rect.__eq__(object()) == NotImplemented
def on_configure(self, *_): window_x, window_y = self.get_position() window_width, window_height = self.get_size() # set event mask for click-through self.input_shape_combine_region( cairo.Region(cairo.RectangleInt(0, 0, 0, 0))) # set some proportional inner padding self.label.set_padding(window_width // 100, 0) self.update_font()
def circle_region(x: float, y: float, radius: float): radius = math.fabs(radius) if radius == 0.0: return cairo.Region() return cairo.Region( cairo.RectangleInt( x=int(math.floor(x - radius)), y=int(math.floor(y - radius)), width=int(math.ceil(2 * radius)), height=int(math.ceil(2 * radius)), ))
def get_mask(self): w, h = self.get_size() region = cairo.Region(cairo.RectangleInt(width=0, height=0)) for i in list(self.ui.actions.keys()): r = i.region() if r: region.union(r) else: logger.warning("warning: no region for " + str(i)) p = self.root.get_pointer() self.cut_pointer(region, p.x, p.y) return region
def extents(self, extents: Optional[Rect2[float]]) -> None: self._extents = extents inv_region = self._last_drawn_region if extents: to_draw = cairo.Region( cairo.RectangleInt(int(extents.x - 1), int(extents.y - 1), int(extents.w + 2), int(extents.h + 2))) if inv_region is not None: inv_region.union(to_draw) else: inv_region = to_draw if inv_region is not None: self.invalidate(inv_region)
def cairo_region_create_from_surface(surface, mask_accuracy): rect = cairo.RectangleInt() extents = _cairo_surface_extents(surface) if extents != False: if surface.get_content() == cairo.CONTENT_COLOR: return cairo.Region(extents) if type( surface ) != cairo.ImageSurface or surface.get_format != cairo.FORMAT_A1: image = cairo.ImageSurface(cairo.FORMAT_A1, extents.width, extents.height) cr = cairo.Context(image) cr.set_source_surface(surface, -extents.x, -extents.y) cr.paint() else: image = surface image.flush() data = image.get_data() stride = image.get_stride() region = cairo.Region() for y in range(0, extents.height, mask_accuracy): for x in range(0, extents.width, mask_accuracy): x0 = x while x < extents.width: if sys.byteorder == 'little': if ((data[y * stride + x // 8] >> (x % 8)) & 1) == 0: break if sys.byteorder == 'big': if ((data[y * stride + x // 8] >> (7 - (x % 8))) & 1) == 0: break x += mask_accuracy if x > x0: rect.x = x0 rect.width = x - x0 rect.y = y rect.height = mask_accuracy region.union(rect) region.translate(extents.x, extents.y) return region
def _calculate_lens_rect(self, x: int, y: int, width: int, height: int): """ Calculates the area where the lens will be drawn on screen. This method takes screen space into calculation and moves the rectangle accordingly when the the rectangle would otherwise flow over the allocated area """ lens_x = max(x - width // 2, 0) lens_y = max(y - height // 2, 0) max_width, max_height = self.__window.get_visible_area_size() max_width += int(self.__window.get_hadjust().get_value()) max_height += int(self.__window.get_vadjust().get_value()) lens_x = min(lens_x, max_width - width) lens_y = min(lens_y, max_height - height) # Don't forget 1 pixel border... return cairo.RectangleInt(lens_x, lens_y, width + 2, height + 2)
def _cairo_surface_extents(surface): if surface == None: return False cr = cairo.Context(surface) x1, y1, x2, y2 = cr.clip_extents() x1 = floor(x1) y1 = floor(y1) x2 = ceil(x2) y2 = ceil(y2) x2 -= x1 y2 -= y1 extents = cairo.RectangleInt() extents.x = x1 extents.y = y1 extents.width = x2 extents.height = y2 return extents
def draw(self, cr: cairo.Context) -> None: polyline = self._polyline stroke_width = self._stroke_width stroke_color = self._stroke_color if polyline is None or len(polyline) == 0: self._last_drawn_region = None return if self._path_cache is not None: cr.append_path(self._path_cache) else: self._show_polyline(cr, polyline) self._path_cache = cr.copy_path() extents = Rect2(cr.path_extents()) dx = 1 / cr.get_matrix().xx dy = 1 / cr.get_matrix().yy cr.save() if self._scale_strokes: stroke_scale = max(dx, dy) cr.identity_matrix() else: stroke_scale = 1.0 cr.set_line_width(stroke_width) cr.set_source_rgba(*stroke_color) cr.stroke() cr.restore() extents = expand_rect(extents, max(stroke_width * stroke_scale, dx, dy)) self._last_drawn_region = cairo.Region( cairo.RectangleInt( int(math.floor(extents.x)), int(math.floor(extents.y)), int(math.ceil(extents.w)), int(math.ceil(extents.h)), ))
def cb_draw(self, widget, cr): cr.set_source_rgba(0.0, 0.0, 0.0, 0.0) cr.set_operator(cairo.OPERATOR_SOURCE) cr.paint() surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, self.w, self.h) surface_ctx = cairo.Context(surface) surface_ctx.set_source_rgba(1.0, 1.0, 1.0, 0.0) surface_ctx.set_operator(cairo.OPERATOR_SOURCE) surface_ctx.paint() rect = cairo.RectangleInt(0, 0, 1, 1) reg = cairo.Region(rect) if (not reg.is_empty()): widget.input_shape_combine_region(None) widget.input_shape_combine_region(reg) cr.move_to(0, 0) cr.set_source_rgba(1.0, 0.0, 0.0, 0.8) cr.set_line_width(2.0) # # Seriously? # The thing is, windows cannot overlap Panel or Launcher. # Ugly code taking care of this overlapping is below. # if self.y > self.panel_height - 1: cr.line_to(self.w, 0) else: cr.move_to(self.w, 0) if self.x + self.w < HW.screens[self.screen.get_number()]['width']: cr.line_to(self.w, self.h) else: cr.move_to(self.w, self.h) if self.y + self.h < HW.screens[self.screen.get_number()]['height']: cr.line_to(0, self.h) else: cr.move_to(0, self.h) if self.x > self.launcher_width: cr.line_to(0, 0) cr.stroke() cr.set_operator(cairo.OPERATOR_OVER)
def draw_rectangle(self, event_x, event_y): """Define the selection pixbuf and draw an overlay for a rectangle selection beginning where the "press" event was made and ending where the "release" event is made (its coordinates are parameters). This method is specific to the "rectangle selection" mode.""" if self.selection_path is None: return cairo_context = cairo.Context(self.get_surface()) cairo_context.set_source_rgba(0.5, 0.5, 0.5, 0.5) cairo_context.set_dash([3, 3]) cairo_context.append_path(self.selection_path) press_x, press_y = cairo_context.get_current_point() x0 = int(min(press_x, event_x)) y0 = int(min(press_y, event_y)) x1 = int(max(press_x, event_x)) y1 = int(max(press_y, event_y)) w = x1 - x0 h = y1 - y0 if w <= 0 or h <= 0: self.selection_path = None return self.selection_x = x0 self.selection_y = y0 temp_surface = Gdk.cairo_surface_create_from_pixbuf( self.get_main_pixbuf(), 0, None) temp_surface = temp_surface.map_to_image( cairo.RectangleInt(x0, y0, w, h)) self.set_selection_pixbuf( Gdk.pixbuf_get_from_surface(temp_surface, \ 0, 0, temp_surface.get_width(), temp_surface.get_height()) ) cairo_context.new_path() cairo_context.move_to(x0, y0) cairo_context.line_to(x1, y0) cairo_context.line_to(x1, y1) cairo_context.line_to(x0, y1) cairo_context.close_path() self.selection_path = cairo_context.copy_path() self.temp_path = cairo_context.copy_path() self.set_temp()
def test_surface_map_to_image_data(): main = cairo.ImageSurface(cairo.Format.RGB24, 2, 1) main.flush() assert bytes(main.get_data()) == b"\x00\x00\x00\x00\x00\x00\x00\x00" image = main.map_to_image(None) ctx = cairo.Context(image) ctx.set_source_rgb(1, 1, 1) ctx.paint() main.unmap_image(image) main.flush() assert bytes(main.get_data()) == b"\xff\xff\xff\xff\xff\xff\xff\xff" main = cairo.ImageSurface(cairo.Format.RGB24, 2, 1) image = main.map_to_image(cairo.RectangleInt(0, 0, 1, 1)) ctx = cairo.Context(image) ctx.set_source_rgb(1, 1, 1) ctx.paint() main.unmap_image(image) main.flush() assert bytes(main.get_data()) == b"\xff\xff\xff\xff\x00\x00\x00\x00"
def draw(self, cr: cairo.Context) -> None: if self._extents is None or self._surface is None: return extents = self._extents surface = self._surface matrix = cairo.Matrix() matrix.scale(surface.get_width() / extents.w, surface.get_height() / extents.h) matrix.translate(-extents.x, -extents.y) pattern = cairo.SurfacePattern(surface) pattern.set_filter(cairo.Filter.FAST) pattern.set_matrix(matrix) cr.set_source(pattern) cr.paint() self._last_drawn_region = cairo.Region( cairo.RectangleInt(int(extents.x - 1), int(extents.y - 1), int(extents.w + 2), int(extents.h + 2)))
def _do_draw(self, _, cr: cairo.Context): height = self.get_allocated_height() timeline_canvas = self.timeline_canvas # Show a guiding line under the mouse if self.current_moused_datetime is not None: timeline_x = timeline_canvas.timeline_helper.datetime_to_pixel( self.current_moused_datetime) cr.set_source_rgb(0.55, 0.55, 0.55) cr.new_path() cr.move_to(timeline_x, 0) cr.line_to(timeline_x, height) cr.stroke() current_guidingline_rectangle = cairo.RectangleInt( int(timeline_x) - 2, 0, 4, height) self.dirty_rectangles.append(current_guidingline_rectangle) # Highlight the hovered over entry moused_entry = None if self.moused_over_entity is None else self.moused_over_entity.entry if type(moused_entry) is LoggedEntry: le = self.moused_over_entity cr.set_source_rgba(0.7, 0.7, 0.7, 0.2) cr.rectangle(le.start_x, timeline_canvas.le_start_y, le.width, timeline_canvas.timeline_height) cr.fill() elif type(moused_entry) is TaggedEntry: te = self.moused_over_entity cr.set_source_rgba(0.7, 0.7, 0.7, 0.2) cr.rectangle(te.start_x, timeline_canvas.te_start_y, te.width, timeline_canvas.timeline_height) cr.fill() # Show the tooltip if self.tooltip_attributes is not None: self._show_details_tooltip(self.tooltip_attributes, cr) return True