Example #1
0
static void
joy_gfx3d_screen_init(JoyGfx3dScreen *self)
{
	self->priv = ASSIGN_PRIVATE(self);
	struct Private *priv = GET_PRIVATE(self);
	priv->windows = g_queue_new();
	priv->area = cairo_region_create();
	priv->expose = cairo_region_create();
	priv->rects = g_array_sized_new(FALSE, FALSE, sizeof(GFX3D_Rect), 128);
}
Example #2
0
static void
joy_gfx3d_window_init(JoyGfx3dWindow *self)
{
    self->priv = ASSIGN_PRIVATE(self);
    struct Private *priv = GET_PRIVATE(self);
    priv->expose = cairo_region_create();
    priv->area = cairo_region_create();
    priv->fade = joy_animation_fade_new((JoyBubble *)self, 1.);
    if (priv->fade) {
        joy_animation_set_duration(priv->fade, 0.1);
    }
}
Example #3
0
static int new_Region (lua_State *L)
{
    lua_remove(L, 1); // remove cairo.Region

// cairo_public cairo_region_t *
// cairo_region_create (void);

// cairo_public cairo_region_t *
// cairo_region_create_rectangle (const cairo_rectangle_int_t *rectangle);

    cairo_rectangle_int_t *rectangle = NULL;
    int top = lua_gettop(L);
    if (top > 0) rectangle = get_userdata (L, 1, LUACAIRO ".RectangleInt.mt");

    cairo_region_t *reg = NULL;
    if (rectangle)
        reg = cairo_region_create_rectangle (rectangle);
    else
        reg = cairo_region_create ();

    Region *o = (Region *) lua_newuserdata(L, sizeof(Region));
    o->reg_     = reg;
    o->havereg_ = 1;

    luaL_getmetatable(L, LUACAIRO ".Region.mt");
    lua_setmetatable(L, -2);

    return 1;
}
Example #4
0
static void
cheese_flash_init (CheeseFlash *self)
{
  CheeseFlashPrivate *priv = self->priv = CHEESE_FLASH_GET_PRIVATE (self);
  cairo_region_t *input_region;
  GtkWindow *window = GTK_WINDOW (self);
  const GdkRGBA white = { 1.0, 1.0, 1.0, 1.0 };

  priv->flash_timeout_tag = 0;
  priv->fade_timeout_tag  = 0;

  /* make it so it doesn't look like a window on the desktop (+fullscreen) */
  gtk_window_set_decorated (window, FALSE);
  gtk_window_set_skip_taskbar_hint (window, TRUE);
  gtk_window_set_skip_pager_hint (window, TRUE);
  gtk_window_set_keep_above (window, TRUE);

  /* Don't take focus */
  gtk_window_set_accept_focus (window, FALSE);
  gtk_window_set_focus_on_map (window, FALSE);

  /* Make it white */
  gtk_widget_override_background_color (GTK_WIDGET (window), GTK_STATE_NORMAL,
                                        &white);

  /* Don't consume input */
  gtk_widget_realize (GTK_WIDGET (window));
  input_region = cairo_region_create ();
  gdk_window_input_shape_combine_region (gtk_widget_get_window (GTK_WIDGET (window)), input_region, 0, 0);
  cairo_region_destroy (input_region);
}
static void
move_locate_pointer_window (GsdLocatePointerData *data,
                            GdkScreen            *screen)
{
  cairo_region_t *region;
  gint cursor_x, cursor_y;

//
// gdk_window_get_pointer (gdk_screen_get_root_window (screen),
//                         &cursor_x, &cursor_y, NULL);
// use gdk_device_get_position instead of gdk_window_get_device_position
// 'coz we use root window here.
  GdkDisplay *display;
  GdkDeviceManager * device_manager;
  GdkDevice* pointer_device;

  display = gdk_window_get_display (data->window);
  device_manager = gdk_display_get_device_manager (display);
  pointer_device = gdk_device_manager_get_client_pointer (device_manager);
  gdk_device_get_position (pointer_device, NULL, &cursor_x, &cursor_y);
//

  gdk_window_move_resize (data->window,
                          cursor_x - WINDOW_SIZE / 2,
                          cursor_y - WINDOW_SIZE / 2,
                          WINDOW_SIZE, WINDOW_SIZE);

  /* allow events to happen through the window */
  region = cairo_region_create ();
  gdk_window_input_shape_combine_region (data->window, region, 0, 0);
  cairo_region_destroy (region);
}
Example #6
0
static cairo_region_t *
byzanz_layer_cursor_snapshot (ByzanzLayer *layer)
{
  ByzanzLayerCursor *clayer = BYZANZ_LAYER_CURSOR (layer);
  cairo_region_t *region, *area;
  int x, y;
  GdkDevice *device;
  GdkDeviceManager *device_manager;
  GdkDisplay *display;
  GdkWindow *window;

  window = layer->recorder->window;
  display = gdk_window_get_display (window);
  device_manager = gdk_display_get_device_manager (display);
  device = gdk_device_manager_get_client_pointer (device_manager);
  gdk_window_get_device_position (window, device, &x, &y, NULL);
  if (x == clayer->cursor_x &&
      y == clayer->cursor_y &&
      clayer->cursor_next == clayer->cursor)
    return NULL;

  region = cairo_region_create ();
  byzanz_recorder_invalidate_cursor (region, clayer->cursor, clayer->cursor_x, clayer->cursor_y);
  byzanz_recorder_invalidate_cursor (region, clayer->cursor_next, x, y);
  area = cairo_region_create_rectangle (&layer->recorder->area);
  cairo_region_intersect (region, area);
  cairo_region_destroy (area);

  clayer->cursor = clayer->cursor_next;
  clayer->cursor_x = x;
  clayer->cursor_y = y;
  byzanz_layer_cursor_setup_poll (clayer);

  return region;
}
Example #7
0
cairo_region_t *
meta_region_builder_finish (MetaRegionBuilder *builder)
{
  cairo_region_t *result = NULL;
  int i;

  for (i = 0; i < builder->n_levels; i++)
    {
      if (builder->levels[i])
        {
          if (result == NULL)
            result = builder->levels[i];
          else
            {
              cairo_region_union(result, builder->levels[i]);
              cairo_region_destroy (builder->levels[i]);
            }
        }
    }

  if (result == NULL)
    result = cairo_region_create ();

  return result;
}
static void
cheese_flash_init (CheeseFlash *self)
{
  CheeseFlashPrivate *priv = CHEESE_FLASH_GET_PRIVATE (self);
  cairo_region_t *input_region;
  GtkWindow *window;
  GdkScreen *screen;

  priv->flash_timeout_tag = 0;
  priv->fade_timeout_tag  = 0;

  window = GTK_WINDOW (gtk_window_new (GTK_WINDOW_POPUP));

  /* make it so it doesn't look like a window on the desktop (+fullscreen) */
  gtk_window_set_decorated (window, FALSE);
  gtk_window_set_skip_taskbar_hint (window, TRUE);
  gtk_window_set_skip_pager_hint (window, TRUE);
  gtk_window_set_keep_above (window, TRUE);
  gtk_window_set_type_hint (window, GDK_WINDOW_TYPE_HINT_NOTIFICATION);

  /* Don't take focus */
  gtk_window_set_accept_focus (window, FALSE);
  gtk_window_set_focus_on_map (window, FALSE);

  /* Don't consume input */
  gtk_widget_realize (GTK_WIDGET (window));

  input_region = cairo_region_create ();
  gdk_window_input_shape_combine_region (gtk_widget_get_window (GTK_WIDGET (window)), input_region, 0, 0);
  cairo_region_destroy (input_region);

  g_signal_connect (G_OBJECT (window), "draw", G_CALLBACK (cheese_flash_window_draw_event_cb), NULL);
  priv->window = window;
}
Example #9
0
static void
msd_osd_window_real_realize (GtkWidget *widget)
{
        GdkScreen *screen;
        GdkVisual *visual;
        cairo_region_t *region;

        screen = gtk_widget_get_screen (widget);
        visual = gdk_screen_get_rgba_visual (screen);

        if (visual == NULL) {
                visual = gdk_screen_get_system_visual (screen);
        }

        gtk_widget_set_visual (widget, visual);

        if (GTK_WIDGET_CLASS (msd_osd_window_parent_class)->realize) {
                GTK_WIDGET_CLASS (msd_osd_window_parent_class)->realize (widget);
        }

        /* make the whole window ignore events */
        region = cairo_region_create ();
        gtk_widget_input_shape_combine_region (widget, region);
        cairo_region_destroy (region);
}
Example #10
0
void on_monitors_changed ( GdkScreen *screen,
			   gpointer   user_data) 
{
  GromitData *data = (GromitData *) user_data;

  if(data->debug)
    g_printerr("DEBUG: screen size changed!\n");

  // get new sizes
  data->width = gdk_screen_get_width (data->screen);
  data->height = gdk_screen_get_height (data->screen);

  // change size
  gtk_widget_set_size_request(GTK_WIDGET(data->win), data->width, data->height);
  // try to set transparent for input
  cairo_region_t* r =  cairo_region_create();
  gtk_widget_input_shape_combine_region(data->win, r);
  cairo_region_destroy(r);

  /* recreate the shape surface */
  cairo_surface_t *new_shape = cairo_image_surface_create(CAIRO_FORMAT_ARGB32 ,data->width, data->height);
  cairo_t *cr = cairo_create (new_shape);
  cairo_set_source_surface (cr, data->backbuffer, 0, 0);
  cairo_paint (cr);
  cairo_destroy (cr);
  cairo_surface_destroy(data->backbuffer);
  data->backbuffer = new_shape;
 
  /*
     these depend on the shape surface
  */
  GHashTableIter it;
  gpointer value;
  g_hash_table_iter_init (&it, data->tool_config);
  while (g_hash_table_iter_next (&it, NULL, &value)) 
    paint_context_free(value);
  g_hash_table_remove_all(data->tool_config);


  parse_config(data); // also calls paint_context_new() :-(


  data->default_pen = paint_context_new (data, GROMIT_PEN,
					 data->red, 7, 0, 1);
  data->default_eraser = paint_context_new (data, GROMIT_ERASER,
					    data->red, 75, 0, 1);

  if(!data->composited) // set shape
    {
      cairo_region_t* r = gdk_cairo_region_create_from_surface(data->backbuffer);
      gtk_widget_shape_combine_region(data->win, r);
      cairo_region_destroy(r);
    }

  setup_input_devices(data);


  gtk_widget_show_all (data->win);
}
static void
set_transparent_shape (GdkWindow *window)
{
  cairo_region_t *region;

  region = cairo_region_create ();
  gdk_window_shape_combine_region (data->window, region, 0, 0);
  cairo_region_destroy (region);
}
Example #12
0
/* Get a clip region to draw only part of a layout. index_ranges
 * contains alternating range starts/stops. The region is the
 * region which contains the given ranges, i.e. if you draw with the
 * region as clip, only the given ranges are drawn.
 */
static cairo_region_t*
layout_iter_get_line_clip_region (PangoLayoutIter *iter,
				  gint             x_origin,
				  gint             y_origin,
				  const gint      *index_ranges,
				  gint             n_ranges)
{
  PangoLayoutLine *line;
  cairo_region_t *clip_region;
  PangoRectangle logical_rect;
  gint baseline;
  gint i;

  line = pango_layout_iter_get_line_readonly (iter);

  clip_region = cairo_region_create ();

  pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
  baseline = pango_layout_iter_get_baseline (iter);

  i = 0;
  while (i < n_ranges)
    {  
      gint *pixel_ranges = NULL;
      gint n_pixel_ranges = 0;
      gint j;

      /* Note that get_x_ranges returns layout coordinates
       */
      if (index_ranges[i*2+1] >= line->start_index &&
	  index_ranges[i*2] < line->start_index + line->length)
	pango_layout_line_get_x_ranges (line,
					index_ranges[i*2],
					index_ranges[i*2+1],
					&pixel_ranges, &n_pixel_ranges);
  
      for (j = 0; j < n_pixel_ranges; j++)
        {
          GdkRectangle rect;
	  int x_off, y_off;
          
          x_off = PANGO_PIXELS (pixel_ranges[2*j] - logical_rect.x);
	  y_off = PANGO_PIXELS (baseline - logical_rect.y);

          rect.x = x_origin + x_off;
          rect.y = y_origin - y_off;
          rect.width = PANGO_PIXELS (pixel_ranges[2*j + 1] - logical_rect.x) - x_off;
          rect.height = PANGO_PIXELS (baseline - logical_rect.y + logical_rect.height) - y_off;

          cairo_region_union_rectangle (clip_region, &rect);
        }

      g_free (pixel_ranges);
      ++i;
    }
  return clip_region;
}
static void
gimp_tile_handler_projection_init (GimpTileHandlerProjection *projection)
{
  GeglTileSource *source = GEGL_TILE_SOURCE (projection);

  source->command = gimp_tile_handler_projection_command;

  projection->dirty_region = cairo_region_create ();
}
Example #14
0
static void
wl_compositor_create_region (struct wl_client *client,
                             struct wl_resource *compositor_resource,
                             uint32_t id)
{
  MetaWaylandRegion *region = g_slice_new0 (MetaWaylandRegion);

  region->resource = wl_resource_create (client, &wl_region_interface, wl_resource_get_version (compositor_resource), id);
  wl_resource_set_implementation (region->resource, &meta_wayland_region_interface, region, meta_wayland_region_resource_destroy_cb);

  region->region = cairo_region_create ();
}
static void
label_window_realize_cb (GtkWidget *widget)
{
	cairo_region_t *region;

	/* make the whole window ignore events */
	region = cairo_region_create ();
	gtk_widget_input_shape_combine_region (widget, region);
	cairo_region_destroy (region);

	maybe_update_shape (widget);
}
Example #16
0
MetaWaylandRegion *
meta_wayland_region_create (MetaWaylandCompositor *compositor,
                            struct wl_client      *client,
                            struct wl_resource    *compositor_resource,
                            guint32                id)
{
  MetaWaylandRegion *region = g_slice_new0 (MetaWaylandRegion);

  region->resource = wl_resource_create (client, &wl_region_interface, wl_resource_get_version (compositor_resource), id);
  wl_resource_set_implementation (region->resource, &meta_wayland_wl_region_interface, region, wl_region_destructor);

  region->region = cairo_region_create ();

  return region;
}
Example #17
0
cairo_region_t* get_window_input_region(Display* dpy, Window w)
{
    int count = 0;
    int ordering = 0;
    XRectangle  *rects = XShapeGetRectangles(dpy, w, ShapeInput, &count,
                                             &ordering);
    cairo_region_t* reg = cairo_region_create();
    for (int i=0; i<count; i++) {
        cairo_rectangle_int_t rect = {rects[i].x, rects[i].y,
                                      rects[i].width, rects[i].height};
        cairo_region_union_rectangle(reg, &rect);
    }
    XFree(rects);
    return reg;
}
Example #18
0
File: frapi.c Project: 91he/Test
cairo_region_t *make_region(struct Rgn *rgn){
    int i;
    cairo_region_t *ret = NULL;

    if(rgn && rgn->num >= 0){ 
        ret = cairo_region_create();

        for(i = 0; i < rgn->num; i++){
            rgn->rects[i].width -= rgn->rects[i].x;
            rgn->rects[i].height -= rgn->rects[i].y;
            cairo_region_union_rectangle(ret, &rgn->rects[i]);
        }   
    }   

    return ret;
}   
Example #19
0
void
meta_region_builder_add_rectangle (MetaRegionBuilder *builder,
                                   int                x,
                                   int                y,
                                   int                width,
                                   int                height)
{
  cairo_rectangle_int_t rect;
  int i;

  if (builder->levels[0] == NULL)
    builder->levels[0] = cairo_region_create ();

  rect.x = x;
  rect.y = y;
  rect.width = width;
  rect.height = height;

  cairo_region_union_rectangle (builder->levels[0], &rect);
  if (cairo_region_num_rectangles (builder->levels[0]) >= MAX_CHUNK_RECTANGLES)
    {
      for (i = 1; i < builder->n_levels + 1; i++)
        {
          if (builder->levels[i] == NULL)
            {
              if (i < META_REGION_BUILDER_MAX_LEVELS)
                {
                  builder->levels[i] = builder->levels[i - 1];
                  builder->levels[i - 1] = NULL;
                  if (i == builder->n_levels)
                    builder->n_levels++;
                }

              break;
            }
          else
            {
              cairo_region_union (builder->levels[i], builder->levels[i - 1]);
              cairo_region_destroy (builder->levels[i - 1]);
              builder->levels[i - 1] = NULL;
            }
        }
    }
}
static void
move_locate_pointer_window (CsdLocatePointerData *data,
                            GdkScreen            *screen)
{
  cairo_region_t *region;
  gint cursor_x, cursor_y;

  gdk_window_get_pointer (gdk_screen_get_root_window (screen), &cursor_x, &cursor_y, NULL);

  gdk_window_move_resize (data->window,
                          cursor_x - WINDOW_SIZE / 2,
                          cursor_y - WINDOW_SIZE / 2,
                          WINDOW_SIZE, WINDOW_SIZE);

  /* allow events to happen through the window */
  region = cairo_region_create ();
  gdk_window_input_shape_combine_region (data->window, region, 0, 0);
  cairo_region_destroy (region);
}
Example #21
0
/**
 * cairo_region_copy:
 * @original: a #cairo_region_t
 *
 * Allocates a new region object copying the area from @original.
 *
 * Return value: A newly allocated #cairo_region_t. Free with
 *   cairo_region_destroy(). This function always returns a
 *   valid pointer; if memory cannot be allocated, then a special
 *   error object is returned where all operations on the object do nothing.
 *   You can check for this with cairo_region_status().
 *
 * Since: 1.10
 **/
cairo_region_t *
cairo_region_copy (cairo_region_t *original)
{
    cairo_region_t *copy;

    if (original->status)
	return (cairo_region_t *) &_cairo_region_nil;

    copy = cairo_region_create ();
    if (copy->status)
	return copy;

    if (! pixman_region32_copy (&copy->rgn, &original->rgn)) {
	cairo_region_destroy (copy);
	return (cairo_region_t *) &_cairo_region_nil;
    }

    return copy;
}
Example #22
0
/**
 * gdk_pango_layout_get_clip_region: (skip)
 * @layout: a #PangoLayout 
 * @x_origin: X pixel where you intend to draw the layout with this clip
 * @y_origin: Y pixel where you intend to draw the layout with this clip
 * @index_ranges: array of byte indexes into the layout, where even members of array are start indexes and odd elements are end indexes
 * @n_ranges: number of ranges in @index_ranges, i.e. half the size of @index_ranges
 * 
 * Obtains a clip region which contains the areas where the given ranges
 * of text would be drawn. @x_origin and @y_origin are the top left point
 * to center the layout. @index_ranges should contain
 * ranges of bytes in the layout's text.
 * 
 * Note that the regions returned correspond to logical extents of the text
 * ranges, not ink extents. So the drawn layout may in fact touch areas out of
 * the clip region.  The clip region is mainly useful for highlightling parts
 * of text, such as when text is selected.
 * 
 * Return value: a clip region containing the given ranges
 **/
cairo_region_t*
gdk_pango_layout_get_clip_region (PangoLayout *layout,
                                  gint         x_origin,
                                  gint         y_origin,
                                  const gint  *index_ranges,
                                  gint         n_ranges)
{
  PangoLayoutIter *iter;  
  cairo_region_t *clip_region;
  
  g_return_val_if_fail (PANGO_IS_LAYOUT (layout), NULL);
  g_return_val_if_fail (index_ranges != NULL, NULL);
  
  clip_region = cairo_region_create ();
  
  iter = pango_layout_get_iter (layout);
  
  do
    {
      PangoRectangle logical_rect;
      cairo_region_t *line_region;
      gint baseline;
      
      pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
      baseline = pango_layout_iter_get_baseline (iter);      

      line_region = layout_iter_get_line_clip_region(iter, 
						     x_origin + PANGO_PIXELS (logical_rect.x),
						     y_origin + PANGO_PIXELS (baseline),
						     index_ranges,
						     n_ranges);

      cairo_region_union (clip_region, line_region);
      cairo_region_destroy (line_region);
    }
  while (pango_layout_iter_next_line (iter));

  pango_layout_iter_free (iter);

  return clip_region;
}
Example #23
0
/**
 * cairo_region_copy:
 * @original: a #cairo_region_t
 *
 * Allocates a new region object copying the area from @original.
 *
 * Return value: A newly allocated #cairo_region_t. Free with
 *   cairo_region_destroy(). This function always returns a
 *   valid pointer; if memory cannot be allocated, then a special
 *   error object is returned where all operations on the object do nothing.
 *   You can check for this with cairo_region_status().
 *
 * Since: 1.10
 **/
cairo_region_t *
cairo_region_copy (const cairo_region_t *original)
{
    cairo_region_t *copy;

    if (original != NULL && original->status)
	return (cairo_region_t *) &_cairo_region_nil;

    copy = cairo_region_create ();
    if (unlikely (copy->status))
	return copy;

    if (original != NULL &&
	! pixman_region32_copy (&copy->rgn, CONST_CAST &original->rgn))
    {
	cairo_region_destroy (copy);
	return (cairo_region_t *) &_cairo_region_nil;
    }

    return copy;
}
static cairo_region_t *
make_region_with_monitors (GdkScreen *screen)
{
  cairo_region_t *region;
  int num_monitors;
  int i;

  num_monitors = gdk_screen_get_n_monitors (screen);

  region = cairo_region_create ();

  for (i = 0; i < num_monitors; i++)
    {
      GdkRectangle rect;

      gdk_screen_get_monitor_geometry (screen, i, &rect);
      cairo_region_union_rectangle (region, &rect);
    }

  return region;
}
Example #25
0
static cairo_region_t *
byzanz_recorder_get_invalid_region (ByzanzRecorder *recorder)
{
  cairo_region_t *invalid, *layer_invalid;
  GSequenceIter *iter;

  invalid = cairo_region_create ();
  for (iter = g_sequence_get_begin_iter (recorder->layers);
       !g_sequence_iter_is_end (iter);
       iter = g_sequence_iter_next (iter)) {
    ByzanzLayer *layer = g_sequence_get (iter);
    ByzanzLayerClass *klass = BYZANZ_LAYER_GET_CLASS (layer);

    layer_invalid = klass->snapshot (layer);
    if (layer_invalid) {
      cairo_region_union (invalid, layer_invalid);
      cairo_region_destroy (layer_invalid);
    }
  }

  return invalid;
}
void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int /* offset */, const Color& color)
{
    if (paintingDisabled())
        return;

    unsigned rectCount = rects.size();

    cairo_t* cr = platformContext()->cr();
    cairo_save(cr);
    cairo_push_group(cr);
    cairo_new_path(cr);

#if PLATFORM(GTK)
#ifdef GTK_API_VERSION_2
    GdkRegion* reg = gdk_region_new();
#else
    cairo_region_t* reg = cairo_region_create();
#endif

    for (unsigned i = 0; i < rectCount; i++) {
#ifdef GTK_API_VERSION_2
        GdkRectangle rect = rects[i];
        gdk_region_union_with_rect(reg, &rect);
#else
        cairo_rectangle_int_t rect = rects[i];
        cairo_region_union_rectangle(reg, &rect);
#endif
    }
    gdk_cairo_region(cr, reg);
#ifdef GTK_API_VERSION_2
    gdk_region_destroy(reg);
#else
    cairo_region_destroy(reg);
#endif
#else
    int radius = (width - 1) / 2;
    Path path;
    for (unsigned i = 0; i < rectCount; ++i) {
        if (i > 0)
            path.clear();
        path.addRoundedRect(rects[i], FloatSize(radius, radius));
        appendWebCorePathToCairoContext(cr, path);
    }
#endif
    Color ringColor = color;
    adjustFocusRingColor(ringColor);
    adjustFocusRingLineWidth(width);
    setSourceRGBAFromColor(cr, ringColor);
    cairo_set_line_width(cr, width);
    setPlatformStrokeStyle(focusRingStrokeStyle());

    cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
    cairo_stroke_preserve(cr);

    cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
    cairo_set_fill_rule(cr, CAIRO_FILL_RULE_WINDING);
    cairo_fill(cr);

    cairo_pop_group_to_source(cr);
    cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
    cairo_paint(cr);
    cairo_restore(cr);
}
Example #27
0
static inline
cairo_region_t *
get_cairo_region_create_from_surface(struct qp_graph *gr,
    cairo_surface_t *surface, int width, int height)
{
  /* TODO: this is a resource pig.  Make it better. */

  cairo_rectangle_int_t rect;
  cairo_surface_t *image;
  cairo_region_t *region;
  cairo_t *cr;
  uint32_t *data, bg;
  int x, y, stride;

  if(!gr->x11)
    /* Creates region that covers the area where the
     * given surface is more than 50% opaque.
     * The below code copies this method.  This GDK
     * code is a pig too. */
    return gdk_cairo_region_create_from_surface(surface);

  if(!gr->x11->background_set)
  {
    /* We need to see what the background color is when it is
     * applied to an image.  A small image. */
    image = cairo_image_surface_create(CAIRO_FORMAT_RGB24, 1, 1);
    cr = cairo_create(image);
    cairo_set_source_rgba(cr, gr->background_color.r,
        gr->background_color.g, gr->background_color.b,
        gr->background_color.a);
    cairo_paint (cr);
    cairo_destroy (cr);
    data = (void *) cairo_image_surface_get_data(image);
    gr->x11->background = (data[0] & 0x00FFFFFF);
    cairo_surface_destroy(image);
    gr->x11->background_set = 1;
  }

  bg = gr->x11->background;

  image = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, height);
  cr = cairo_create(image);
  cairo_set_source_surface(cr, surface, 0, 0);
  cairo_paint (cr);
  cairo_destroy (cr);

  data = (void *) cairo_image_surface_get_data(image);
  stride = cairo_image_surface_get_stride(image);

  region = cairo_region_create();

  for(y=0; y < height; y++)
    {
      for(x=0; x < width; x++)
        {
          /* Search for a continuous range of "background pixels"*/
          gint x0=x;
          while(x < width)
            {
              if((data[x] & 0x00FFFFFF) == bg)
                /* This pixel is the background color */
                break;
              x++;
            }

          if(x > x0)
            {
              /* Add the pixels (x0, y) to (x, y+1) as a new rectangle
               * in the region
               */
              rect.x = x0;
              rect.width = x - x0;
              rect.y = y;
              rect.height = 1;

              cairo_region_union_rectangle(region, &rect);
            }
        }
      data += stride/4;
    }

  cairo_surface_destroy(image);

  return region;
}
Example #28
0
static void
grab_screenshot (ClutterActor *stage,
                 _screenshot_data *screenshot_data)
{
  MetaScreen *screen = shell_global_get_screen (screenshot_data->screenshot->global);
  MetaCursorTracker *tracker;
  int width, height;
  GSimpleAsyncResult *result;
  GSettings *settings;

  meta_screen_get_size (screen, &width, &height);

  do_grab_screenshot (screenshot_data, 0, 0, width, height);

  if (meta_screen_get_n_monitors (screen) > 1)
    {
      cairo_region_t *screen_region = cairo_region_create ();
      cairo_region_t *stage_region;
      MetaRectangle monitor_rect;
      cairo_rectangle_int_t stage_rect;
      int i;
      cairo_t *cr;

      for (i = meta_screen_get_n_monitors (screen) - 1; i >= 0; i--)
        {
          meta_screen_get_monitor_geometry (screen, i, &monitor_rect);
          cairo_region_union_rectangle (screen_region, (const cairo_rectangle_int_t *) &monitor_rect);
        }

      stage_rect.x = 0;
      stage_rect.y = 0;
      stage_rect.width = width;
      stage_rect.height = height;

      stage_region = cairo_region_create_rectangle ((const cairo_rectangle_int_t *) &stage_rect);
      cairo_region_xor (stage_region, screen_region);
      cairo_region_destroy (screen_region);

      cr = cairo_create (screenshot_data->image);

      for (i = 0; i < cairo_region_num_rectangles (stage_region); i++)
        {
          cairo_rectangle_int_t rect;
          cairo_region_get_rectangle (stage_region, i, &rect);
          cairo_rectangle (cr, (double) rect.x, (double) rect.y, (double) rect.width, (double) rect.height);
          cairo_fill (cr);
        }

      cairo_destroy (cr);
      cairo_region_destroy (stage_region);
    }

  screenshot_data->screenshot_area.x = 0;
  screenshot_data->screenshot_area.y = 0;
  screenshot_data->screenshot_area.width = width;
  screenshot_data->screenshot_area.height = height;

  settings = g_settings_new (A11Y_APPS_SCHEMA);
  if (screenshot_data->include_cursor &&
      !g_settings_get_boolean (settings, MAGNIFIER_ACTIVE_KEY))
    {
      tracker = meta_cursor_tracker_get_for_screen (screen);
      _draw_cursor_image (tracker, screenshot_data->image, screenshot_data->screenshot_area);
    }
  g_object_unref (settings);

  g_signal_handlers_disconnect_by_func (stage, (void *)grab_screenshot, (gpointer)screenshot_data);

  result = g_simple_async_result_new (NULL, on_screenshot_written, (gpointer)screenshot_data, grab_screenshot);
  g_simple_async_result_run_in_thread (result, write_screenshot_thread, G_PRIORITY_DEFAULT, NULL);
  g_object_unref (result);
}
/* This special-case filler supports only a path that describes a
 * device-axis aligned rectangle. It exists to avoid the overhead of
 * the general tessellator when drawing very common rectangles.
 *
 * If the path described anything but a device-axis aligned rectangle,
 * this function will abort.
 */
cairo_region_t *
_cairo_path_fixed_fill_rectilinear_to_region (const cairo_path_fixed_t	*path,
					      cairo_fill_rule_t	 fill_rule,
					      const cairo_rectangle_int_t *extents)
{
    cairo_rectangle_int_t rectangle_stack[CAIRO_STACK_ARRAY_LENGTH (cairo_rectangle_int_t)];
    cairo_box_t box;
    cairo_region_t *region = NULL;

    assert (path->maybe_fill_region);
    assert (! path->is_empty_fill);

    if (_cairo_path_fixed_is_box (path, &box)) {
	rectangle_stack[0].x = _cairo_fixed_integer_part (box.p1.x);
	rectangle_stack[0].y = _cairo_fixed_integer_part (box.p1.y);
	rectangle_stack[0].width = _cairo_fixed_integer_part (box.p2.x) -
	                            rectangle_stack[0].x;
	rectangle_stack[0].height = _cairo_fixed_integer_part (box.p2.y) -
	                            rectangle_stack[0].y;
	if (! _cairo_rectangle_intersect (&rectangle_stack[0], extents))
	    region = cairo_region_create ();
	else
	    region = cairo_region_create_rectangle (&rectangle_stack[0]);
    } else if (fill_rule == CAIRO_FILL_RULE_WINDING) {
	cairo_rectangle_int_t *rects = rectangle_stack;
	cairo_path_fixed_iter_t iter;
	int last_cw = -1;
	int size = ARRAY_LENGTH (rectangle_stack);
	int count = 0;

	/* Support a series of rectangles as can be expected to describe a
	 * GdkRegion clip region during exposes.
	 */
	_cairo_path_fixed_iter_init (&iter, path);
	while (_cairo_path_fixed_iter_is_fill_box (&iter, &box)) {
	    int cw = 0;

	    if (box.p1.x > box.p2.x) {
		cairo_fixed_t t;

		t = box.p1.x;
		box.p1.x = box.p2.x;
		box.p2.x = t;

		cw = ! cw;
	    }

	    if (box.p1.y > box.p2.y) {
		cairo_fixed_t t;

		t = box.p1.y;
		box.p1.y = box.p2.y;
		box.p2.y = t;

		cw = ! cw;
	    }

	    if (last_cw < 0)
		last_cw = cw;
	    else if (last_cw != cw)
		goto TESSELLATE;

	    if (count == size) {
		cairo_rectangle_int_t *new_rects;

		size *= 4;
		if (rects == rectangle_stack) {
		    new_rects = _cairo_malloc_ab (size,
						  sizeof (cairo_rectangle_int_t));
		    if (unlikely (new_rects == NULL)) {
			/* XXX _cairo_region_nil */
			break;
		    }
		    memcpy (new_rects, rects, sizeof (rectangle_stack));
		} else {
		    new_rects = _cairo_realloc_ab (rects, size,
						   sizeof (cairo_rectangle_int_t));
		    if (unlikely (new_rects == NULL)) {
			/* XXX _cairo_region_nil */
			break;
		    }
		}
		rects = new_rects;
	    }

	    rects[count].x = _cairo_fixed_integer_part (box.p1.x);
	    rects[count].y = _cairo_fixed_integer_part (box.p1.y);
	    rects[count].width = _cairo_fixed_integer_part (box.p2.x) - rects[count].x;
	    rects[count].height = _cairo_fixed_integer_part (box.p2.y) - rects[count].y;
	    if (_cairo_rectangle_intersect (&rects[count], extents))
		count++;
	}

	if (_cairo_path_fixed_iter_at_end (&iter))
	    region = cairo_region_create_rectangles (rects, count);

TESSELLATE:
	if (rects != rectangle_stack)
	    free (rects);
    }

    if (region == NULL) {
	/* Hmm, complex polygon */
	region = _cairo_path_fixed_fill_rectilinear_tessellate_to_region (path,
									  fill_rule,
									  extents);


    }

    return region;
}
static cairo_region_t *
_cairo_path_fixed_fill_rectilinear_tessellate_to_region (const cairo_path_fixed_t	*path,
							 cairo_fill_rule_t	 fill_rule,
							 const cairo_rectangle_int_t *extents)
{
    cairo_box_t box;
    cairo_polygon_t polygon;
    cairo_traps_t traps;
    cairo_status_t status;
    cairo_region_t *region;

    /* first try to bypass fill-to-polygon */
    _cairo_traps_init (&traps);
    status = _cairo_path_fixed_fill_rectilinear_to_traps (path,
							  fill_rule,
							  &traps);
    if (_cairo_status_is_error (status))
	goto CLEANUP_TRAPS;

    if (status == CAIRO_STATUS_SUCCESS) {
	status = _cairo_traps_extract_region (&traps, &region);
	goto CLEANUP_TRAPS;
    }

    /* path is not rectangular, try extracting clipped rectilinear edges */
    _cairo_polygon_init (&polygon);
    if (extents != NULL) {
	_cairo_box_from_rectangle (&box, extents);
	_cairo_polygon_limit (&polygon, &box, 1);
    }

    /* tolerance will be ignored as the path is rectilinear */
    status = _cairo_path_fixed_fill_to_polygon (path, 0., &polygon);
    if (unlikely (status))
	goto CLEANUP_POLYGON;

    if (polygon.num_edges == 0) {
	region = cairo_region_create ();
    } else {
	status =
	    _cairo_bentley_ottmann_tessellate_rectilinear_polygon (&traps,
								   &polygon,
								   fill_rule);
	if (likely (status == CAIRO_STATUS_SUCCESS))
	    status = _cairo_traps_extract_region (&traps, &region);
    }

  CLEANUP_POLYGON:
    _cairo_polygon_fini (&polygon);

  CLEANUP_TRAPS:
    _cairo_traps_fini (&traps);

    if (unlikely (status)) { /* XXX _cairo_region_create_in_error() */
	region = cairo_region_create ();
	if (likely (region->status) == CAIRO_STATUS_SUCCESS)
	    region->status = status;
    }

    return region;
}