static void
set_unobscured_region (MetaShapedTexture *self,
                       cairo_region_t    *unobscured_region)
{
  MetaShapedTexturePrivate *priv = self->priv;

  g_clear_pointer (&priv->unobscured_region, (GDestroyNotify) cairo_region_destroy);
  if (unobscured_region)
    {
      guint width, height;

      if (priv->texture)
        {
          width = priv->tex_width;
          height = priv->tex_height;
        }
      else
        {
          width = priv->fallback_width;
          height = priv->fallback_height;
        }

      cairo_rectangle_int_t bounds = { 0, 0, width, height };
      priv->unobscured_region = cairo_region_copy (unobscured_region);
      cairo_region_intersect_rectangle (priv->unobscured_region, &bounds);
    }
}
Example #2
0
// cairo_public cairo_status_t
// cairo_region_intersect_rectangle (cairo_region_t *dst,
// 				  const cairo_rectangle_int_t *rectangle);
static int l_cairo_region_intersect_rectangle (lua_State* L)
{
    cairo_region_t *dst = get_cairo_region_t (L, 1);
    const cairo_rectangle_int_t *rectangle = get_cairo_rectangle_int_t (L, 2);
    cairo_status_t v = cairo_region_intersect_rectangle (dst, rectangle);
    lua_pushinteger(L, v);
    return 1;
}
Example #3
0
/* Region is in canvas coordinates */
void
_gtk_pixel_cache_invalidate (GtkPixelCache *cache,
			     cairo_region_t *region)
{
  cairo_rectangle_int_t r;
  cairo_region_t *free_region = NULL;

  if (cache->surface == NULL ||
      (region != NULL && cairo_region_is_empty (region)))
    return;

  if (region == NULL)
    {
      r.x = cache->surface_x;
      r.y = cache->surface_y;
      r.width = cache->surface_w;
      r.height = cache->surface_h;

      free_region = region =
	cairo_region_create_rectangle (&r);
    }

  if (cache->surface_dirty == NULL)
    {
      cache->surface_dirty = cairo_region_copy (region);
      cairo_region_translate (cache->surface_dirty,
			      -cache->surface_x,
			      -cache->surface_y);
    }
  else
    {
      cairo_region_translate (region,
			      -cache->surface_x,
			      -cache->surface_y);
      cairo_region_union (cache->surface_dirty, region);
      cairo_region_translate (region,
			      cache->surface_x,
			      cache->surface_y);
    }

  if (free_region)
    cairo_region_destroy (free_region);

  r.x = 0;
  r.y = 0;
  r.width = cache->surface_w;
  r.height = cache->surface_h;

  cairo_region_intersect_rectangle (cache->surface_dirty, &r);
}
Example #4
0
void
gtk_snapshot_push_rounded_clip (GtkSnapshot          *snapshot,
                                const GskRoundedRect *bounds,
                                const char           *name,
                                ...)
{
  GskRoundedRect *real_bounds;
  cairo_region_t *clip;
  cairo_rectangle_int_t rect;
  char *str;

  real_bounds = g_slice_new (GskRoundedRect);
  gsk_rounded_rect_init_copy (real_bounds, bounds);
  gsk_rounded_rect_offset (real_bounds, snapshot->state->translate_x, snapshot->state->translate_y);

  if (name)
    {
      va_list args;

      va_start (args, name);
      str = g_strdup_vprintf (name, args);
      va_end (args);
    }
  else
    str = NULL;
  
  rectangle_init_from_graphene (&rect, &real_bounds->bounds);
  if (snapshot->state->clip_region)
    {
      clip = cairo_region_copy (snapshot->state->clip_region);
      cairo_region_intersect_rectangle (clip, &rect);
    }
  else
    {
      clip = cairo_region_create_rectangle (&rect);
    }
  snapshot->state = gtk_snapshot_state_new (snapshot->state,
                                            str,
                                            clip,
                                            snapshot->state->translate_x,
                                            snapshot->state->translate_y,
                                            gtk_snapshot_collect_rounded_clip,
                                            real_bounds);

  cairo_region_destroy (clip);
}
Example #5
0
void
_gtk_pixel_cache_set_position (GtkPixelCache         *cache,
			       cairo_rectangle_int_t *view_rect,
			       cairo_rectangle_int_t *canvas_rect)
{
  cairo_rectangle_int_t r, view_pos;
  cairo_region_t *copy_region;
  int new_surf_x, new_surf_y;
  cairo_t *backing_cr;

  if (cache->surface == NULL)
    return;

  /* Position of view inside canvas */
  view_pos.x = -canvas_rect->x;
  view_pos.y = -canvas_rect->y;
  view_pos.width = view_rect->width;
  view_pos.height = view_rect->height;

  /* Reposition so all is visible */
  if (view_pos.x < cache->surface_x ||
      view_pos.x + view_pos.width >
      cache->surface_x + cache->surface_w ||
      view_pos.y < cache->surface_y ||
      view_pos.y + view_pos.height >
      cache->surface_y + cache->surface_h)
    {
      new_surf_x = cache->surface_x;
      if (view_pos.x < cache->surface_x)
	new_surf_x = MAX (view_pos.x + view_pos.width - cache->surface_w, 0);
      else if (view_pos.x + view_pos.width >
	       cache->surface_x + cache->surface_w)
	new_surf_x = MIN (view_pos.x, canvas_rect->width - cache->surface_w);

      new_surf_y = cache->surface_y;
      if (view_pos.y < cache->surface_y)
	new_surf_y = MAX (view_pos.y + view_pos.height - cache->surface_h, 0);
      else if (view_pos.y + view_pos.height >
	       cache->surface_y + cache->surface_h)
	new_surf_y = MIN (view_pos.y, canvas_rect->height - cache->surface_h);

      r.x = 0;
      r.y = 0;
      r.width = cache->surface_w;
      r.height = cache->surface_h;
      copy_region = cairo_region_create_rectangle (&r);

      if (cache->surface_dirty)
	{
	  cairo_region_subtract (copy_region, cache->surface_dirty);
	  cairo_region_destroy (cache->surface_dirty);
	  cache->surface_dirty = NULL;
	}

      cairo_region_translate (copy_region,
			      cache->surface_x - new_surf_x,
			      cache->surface_y - new_surf_y);
      cairo_region_intersect_rectangle (copy_region, &r);

      backing_cr = cairo_create (cache->surface);
      gdk_cairo_region (backing_cr, copy_region);
      cairo_set_operator (backing_cr, CAIRO_OPERATOR_SOURCE);
      cairo_clip (backing_cr);
      cairo_push_group (backing_cr);
      cairo_set_source_surface (backing_cr, cache->surface,
				cache->surface_x - new_surf_x,
				cache->surface_y - new_surf_y);
      cairo_paint (backing_cr);
      cairo_pop_group_to_source (backing_cr);
      cairo_paint (backing_cr);
      cairo_destroy (backing_cr);

      cache->surface_x = new_surf_x;
      cache->surface_y = new_surf_y;

      cairo_region_xor_rectangle (copy_region, &r);
      cache->surface_dirty = copy_region;
    }
}
static GeglTile *
gimp_tile_handler_projection_validate (GeglTileSource *source,
                                       GeglTile       *tile,
                                       gint            x,
                                       gint            y)
{
  GimpTileHandlerProjection *projection;
  cairo_region_t            *tile_region;
  cairo_rectangle_int_t      tile_rect;

  projection = GIMP_TILE_HANDLER_PROJECTION (source);

  if (cairo_region_is_empty (projection->dirty_region))
    return tile;

  tile_region = cairo_region_copy (projection->dirty_region);

  tile_rect.x      = x * projection->tile_width;
  tile_rect.y      = y * projection->tile_height;
  tile_rect.width  = projection->tile_width;
  tile_rect.height = projection->tile_height;

  cairo_region_intersect_rectangle (tile_region, &tile_rect);

  if (! cairo_region_is_empty (tile_region))
    {
      gint tile_bpp;
      gint tile_stride;
      gint n_rects;
      gint i;

      if (! tile)
        tile = gegl_tile_handler_create_tile (GEGL_TILE_HANDLER (source),
                                              x, y, 0);

      cairo_region_subtract_rectangle (projection->dirty_region, &tile_rect);

      tile_bpp    = babl_format_get_bytes_per_pixel (projection->format);
      tile_stride = tile_bpp * projection->tile_width;

      gegl_tile_lock (tile);

      n_rects = cairo_region_num_rectangles (tile_region);

#if 0
      g_printerr ("%d ", n_rects);
#endif

      for (i = 0; i < n_rects; i++)
        {
          cairo_rectangle_int_t blit_rect;

          cairo_region_get_rectangle (tile_region, i, &blit_rect);

#if 0
          g_printerr ("constructing projection at %d %d %d %d\n",
                      blit_rect.x,
                      blit_rect.y,
                      blit_rect.width,
                      blit_rect.height);
#endif

          gegl_node_blit (projection->graph, 1.0,
                          GEGL_RECTANGLE (blit_rect.x,
                                          blit_rect.y,
                                          blit_rect.width,
                                          blit_rect.height),
                          projection->format,
                          gegl_tile_get_data (tile) +
                          (blit_rect.y % projection->tile_height) * tile_stride +
                          (blit_rect.x % projection->tile_width)  * tile_bpp,
                          tile_stride,
                          GEGL_ABYSS_NONE);
        }

      gegl_tile_unlock (tile);
    }

  cairo_region_destroy (tile_region);

  return tile;
}