Example #1
0
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])
Example #2
0
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
Example #3
0
def test_region():
    with pytest.raises(TypeError):
        cairo.Region(object())

    with pytest.raises(TypeError):
        cairo.Region(object(), object())

    with pytest.raises(TypeError):
        cairo.Region([object()])
Example #4
0
    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)
Example #5
0
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)),
        ))
Example #6
0
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())
Example #7
0
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())
Example #8
0
    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)
Example #9
0
    def _draw_lens(self, x: int, y: int):
        """
        Calculate what image data to put in the lens and update the cursor
        with it; <x> and <y> are the positions of the cursor within the
        main window layout area
        """

        if self.__window.images[0].get_storage_type() not in (Gtk.ImageType.PIXBUF, Gtk.ImageType.ANIMATION):
            return

        rectangle = self._calculate_lens_rect(x, y, config['LENS_SIZE'], config['LENS_SIZE'])
        rectangle_alt = [rectangle.x, rectangle.y, rectangle.width, rectangle.height]
        pixbuf = self._get_lens_pixbuf(x, y)

        draw_region = cairo.Region(rectangle=rectangle)

        window = self.__window.get_main_layout().get_bin_window()
        window.end_draw_frame(window.begin_draw_frame(draw_region))

        self._clear_lens(rectangle_alt)

        cr = window.cairo_create()
        surface = Gdk.cairo_surface_create_from_pixbuf(pixbuf, 0, window)
        cr.set_source_surface(surface, rectangle.x, rectangle.y)
        cr.paint()

        window.end_paint()

        self.__last_lens_rect = rectangle_alt
Example #10
0
    def _draw_lens(self, x: int, y: int):
        """
        Calculate what image data to put in the lens and update the cursor
        with it; <x> and <y> are the positions of the cursor within the
        main window layout area
        """

        rectangle = self._calculate_lens_rect(x, y, config['LENS_SIZE'], config['LENS_SIZE'])
        pixbuf = self._get_lens_pixbuf(x, y)

        draw_region = cairo.Region(rectangle=rectangle)

        window = self.__window.main_layout.get_window()
        frame = window.begin_draw_frame(draw_region)

        self._clear_lens(rectangle)

        cr = Gdk.DrawingContext.get_cairo_context(frame)
        surface = Gdk.cairo_surface_create_from_pixbuf(pixbuf, 0, window)
        cr.set_source_surface(surface, rectangle.x, rectangle.y)
        cr.paint()

        window.end_paint()
        window.end_draw_frame(frame)

        self.__last_lens_rect = rectangle
Example #11
0
 def toggle_pass_through(self):
     if not self.pass_through:
         self.input_shape_combine_region(cairo.Region())
         self.pass_through = True
     else:
         self.input_shape_combine_region(None)
         self.pass_through = False
     self.queue_draw()
Example #12
0
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()
Example #13
0
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()
Example #14
0
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
Example #15
0
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()
Example #16
0
    def _invalidate(self) -> None:
        xc = self._xc
        yc = self._yc
        radius = self._radius
        radius_scale = self._last_drawn_radius_scale

        inv_region = self._last_drawn_region or cairo.Region()
        inv_region.union(circle_region(xc, yc, radius_scale * radius))

        self.invalidate(inv_region)
Example #17
0
    def _invalidate(self) -> None:
        extents = self._extents
        stroke_width = self._stroke_width
        stroke_scale = self._last_drawn_stroke_scale

        inv_region = self._last_drawn_region or cairo.Region()
        inv_region.union(
            rectangle_stroke_region(extents, stroke_width * stroke_scale))

        self.invalidate(inv_region)
Example #18
0
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())
Example #19
0
    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()
Example #20
0
    def __init__(self, title='veil'):
        super(Veil, self).__init__()
        self.brush_id = 0
        self.brushes = [
            PolygonBrush(),
            FilledRectangleBrush(),
            LineBrush(),
            FreehandBrush(),
            CircleBrush()
        ]
        self.active_tool = self.brushes[0]
        self.images = []

        self.connect("destroy", Gtk.main_quit)
        self.set_title(title)
        self.screen = self.get_screen()  # type: GdkX11.X11Screen
        s = Gdk.Screen.get_default()
        self.width = s.get_width()
        self.height = s.get_height()
        #self.set_size_request(s.get_width(), s.get_height())  # unresizeable
        self.fullscreen()

        # toggles, user-controlled vars
        self.pass_through = False
        self.hidden = False
        self.grid = False
        self.glow = 0

        self.rgbtheme = [0, 1, 0]
        self.rgbatheme = [0, 1, 0, 0.1]

        visual = self.screen.get_rgba_visual()
        if visual and self.screen.is_composited():
            self.set_visual(visual)
            if self.pass_through:
                self.input_shape_combine_region(cairo.Region())

        self.set_decorated(False)
        self.set_app_paintable(True)
        self.set_keep_above(True)
        self.connect('draw', self.veil_update)

        self.connect('button-press-event', self.mouse_press)
        self.connect('motion-notify-event', self.mouse_move)
        self.connect('button-release-event', self.mouse_release)
        self.connect('key-press-event', self.key_press)
        self.connect('key-release-event', self.key_release)
        self.set_events(self.get_events() | Gdk.EventMask.BUTTON_PRESS_MASK
                        | Gdk.EventMask.POINTER_MOTION_MASK
                        | Gdk.EventMask.BUTTON_RELEASE_MASK
                        | Gdk.EventMask.KEY_PRESS_MASK
                        | Gdk.EventMask.KEY_RELEASE_MASK)
        self.show()
Example #21
0
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
Example #22
0
 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
Example #23
0
    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
Example #24
0
 def show(self):
     """Show this mouse indicator and ignore awaiting fade away request."""
     if self.timeout_timer and self.shown:
         # There is a fade away request, ignore it
         if (GLib.main_context_default().find_source_by_id(
                 self.timeout_timer)
                 and not GLib.main_context_default().find_source_by_id(
                     self.timeout_timer).is_destroyed()):
             GLib.source_remove(self.timeout_timer)
         self.timeout_timer = None
         # This method only is called when mouse is pressed, so there will be a
         # release and fade_away call, no need to set up another timer.
     super(ShapedWindow, self).show()
     # Fix click-through
     self.input_shape_combine_region(cairo.Region())
Example #25
0
    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)
Example #26
0
 def reload(self):
     '''重新设定属性, 然后重绘'''
     if self.app.conf['osd-locked']:
         self.toolbar.hide()
         try:
             region = cairo.Region()
         except AttributeError:
             print('cairo.Region is missing, a patch is required:',
                   'http://bugs.debian.org/688079')
             logger.error(traceback.format_exc())
             return
         self.input_shape_combine_region(region)
     else:
         self.toolbar.show_all()
         self.app.conf['osd-toolbar-y'] = self.toolbar.get_allocated_height(
         )
         self.auto_hide_toolbar()
         self.input_shape_combine_region(None)
     self.move(self.app.conf['osd-x'], self.app.conf['osd-y'])
Example #27
0
    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)),
            ))
Example #28
0
    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)
Example #29
0
    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)))
Example #30
0
    def on_draw(self, *args):
        # FIXME: This is running constantly, I only want it to run once after window is initialised
        # Tell the window manager to fullscreen this window

        # FIXME [1]: Before this
        self.fullscreen()
        # Tell the window manager to keep this window on every workspace
        self.stick()
        # Tell the window manager to keep this window on top
        self.set_keep_above(True)
        # I'm not sure whether the WM or X11 handles this, but make the window not accept focus
        self.set_accept_focus(False)

        # Tell the Window manager not to show it in the alt-tab menu or taskbar
        self.set_skip_taskbar_hint(True)
        # FIXME: This just don't seem to work
        self.set_skip_pager_hint(True)

        # Tell the compositor that mouse clicks anywhere on the window go through to what's behind it
        # NOTE: This can't be done before the window has been created
        # NOTE: Is there any problem with this happening before the window has been sized?
        self.input_shape_combine_region(cairo.Region(cairo.RectangleInt(0, 0, 1, 1)))

        self.hide()  # DEBUGGING: Minimize the window because it's all broken at the moment anyway