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); }
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); } }
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; }
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); }
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; }
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; }
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); }
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); }
/* 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 (); }
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); }
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; }
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; }
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; }
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); }
/** * 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 (©->rgn, &original->rgn)) { cairo_region_destroy (copy); return (cairo_region_t *) &_cairo_region_nil; } return copy; }
/** * 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; }
/** * 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 (©->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; }
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); }
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; }
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, ®ion); 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, ®ion); } 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; }