📄 cairo-xcb-surface.c
字号:
status = _cairo_xcb_surface_set_attributes (mask, &mask_attr); if (status == CAIRO_STATUS_SUCCESS) XCBRenderComposite (dst->dpy, _render_operator (op), src->picture, mask->picture, dst->picture, src_x + src_attr.x_offset, src_y + src_attr.y_offset, mask_x + mask_attr.x_offset, mask_y + mask_attr.y_offset, dst_x, dst_y, width, height); } else { static XCBRenderPICTURE maskpict = { 0 }; XCBRenderComposite (dst->dpy, _render_operator (op), src->picture, maskpict, dst->picture, src_x + src_attr.x_offset, src_y + src_attr.y_offset, 0, 0, dst_x, dst_y, width, height); } } if (mask) _cairo_pattern_release_surface (mask_pattern, &mask->base, &mask_attr); _cairo_pattern_release_surface (src_pattern, &src->base, &src_attr); return status;}static cairo_int_status_t_cairo_xcb_surface_fill_rectangles (void *abstract_surface, cairo_operator_t op, const cairo_color_t * color, cairo_rectangle_int16_t *rects, int num_rects){ cairo_xcb_surface_t *surface = abstract_surface; XCBRenderCOLOR render_color; if (!CAIRO_SURFACE_RENDER_HAS_FILL_RECTANGLE (surface)) return CAIRO_INT_STATUS_UNSUPPORTED; render_color.red = color->red_short; render_color.green = color->green_short; render_color.blue = color->blue_short; render_color.alpha = color->alpha_short; /* XXX: This XCBRECTANGLE cast is evil... it needs to go away somehow. */ XCBRenderFillRectangles (surface->dpy, _render_operator (op), surface->picture, render_color, num_rects, (XCBRECTANGLE *) rects); return CAIRO_STATUS_SUCCESS;}static cairo_int_status_t_cairo_xcb_surface_composite_trapezoids (cairo_operator_t op, cairo_pattern_t *pattern, void *abstract_dst, cairo_antialias_t antialias, int src_x, int src_y, int dst_x, int dst_y, unsigned int width, unsigned int height, cairo_trapezoid_t *traps, int num_traps){ cairo_surface_attributes_t attributes; cairo_xcb_surface_t *dst = abstract_dst; cairo_xcb_surface_t *src; cairo_int_status_t status; int render_reference_x, render_reference_y; int render_src_x, render_src_y; XCBRenderPICTFORMINFO render_format; if (!CAIRO_SURFACE_RENDER_HAS_TRAPEZOIDS (dst)) return CAIRO_INT_STATUS_UNSUPPORTED; status = _cairo_pattern_acquire_surface (pattern, &dst->base, src_x, src_y, width, height, (cairo_surface_t **) &src, &attributes); if (status) return status; if (traps[0].left.p1.y < traps[0].left.p2.y) { render_reference_x = _cairo_fixed_integer_floor (traps[0].left.p1.x); render_reference_y = _cairo_fixed_integer_floor (traps[0].left.p1.y); } else { render_reference_x = _cairo_fixed_integer_floor (traps[0].left.p2.x); render_reference_y = _cairo_fixed_integer_floor (traps[0].left.p2.y); } render_src_x = src_x + render_reference_x - dst_x; render_src_y = src_y + render_reference_y - dst_y; switch (antialias) { case CAIRO_ANTIALIAS_NONE: render_format = _format_from_cairo (dst->dpy, CAIRO_FORMAT_A1); break; default: render_format = _format_from_cairo (dst->dpy, CAIRO_FORMAT_A8); break; } /* XXX: The XTrapezoid cast is evil and needs to go away somehow. */ /* XXX: _format_from_cairo is slow. should cache something. */ status = _cairo_xcb_surface_set_attributes (src, &attributes); if (status == CAIRO_STATUS_SUCCESS) XCBRenderTrapezoids (dst->dpy, _render_operator (op), src->picture, dst->picture, render_format.id, render_src_x + attributes.x_offset, render_src_y + attributes.y_offset, num_traps, (XCBRenderTRAP *) traps); _cairo_pattern_release_surface (pattern, &src->base, &attributes); return status;}static cairo_int_status_t_cairo_xcb_surface_get_extents (void *abstract_surface, cairo_rectangle_int16_t *rectangle){ cairo_xcb_surface_t *surface = abstract_surface; rectangle->x = 0; rectangle->y = 0; rectangle->width = surface->width; rectangle->height = surface->height; return CAIRO_STATUS_SUCCESS;}static const cairo_surface_backend_t cairo_xcb_surface_backend = { CAIRO_SURFACE_TYPE_XCB, _cairo_xcb_surface_create_similar, _cairo_xcb_surface_finish, _cairo_xcb_surface_acquire_source_image, _cairo_xcb_surface_release_source_image, _cairo_xcb_surface_acquire_dest_image, _cairo_xcb_surface_release_dest_image, _cairo_xcb_surface_clone_similar, _cairo_xcb_surface_composite, _cairo_xcb_surface_fill_rectangles, _cairo_xcb_surface_composite_trapezoids, NULL, /* copy_page */ NULL, /* show_page */ NULL, /* _cairo_xcb_surface_set_clip_region */ NULL, /* intersect_clip_path */ _cairo_xcb_surface_get_extents, NULL, /* old_show_glyphs */ NULL, /* get_font_options */ NULL, /* flush */ NULL, /* mark_dirty_rectangle */ NULL, /* scaled_font_fini */ NULL /* scaled_glyph_fini */};/** * _cairo_surface_is_xcb: * @surface: a #cairo_surface_t * * Checks if a surface is a #cairo_xcb_surface_t * * Return value: True if the surface is an xcb surface **/static cairo_bool_t_cairo_surface_is_xcb (cairo_surface_t *surface){ return surface->backend == &cairo_xcb_surface_backend;}static voidquery_render_version (XCBConnection *c, cairo_xcb_surface_t *surface){ XCBRenderQueryVersionRep *r; surface->render_major = -1; surface->render_minor = -1; if (!XCBRenderInit(c)) return; r = XCBRenderQueryVersionReply(c, XCBRenderQueryVersion(c, 0, 6), 0); if (!r) return; surface->render_major = r->major_version; surface->render_minor = r->minor_version; free(r);}static cairo_surface_t *_cairo_xcb_surface_create_internal (XCBConnection *dpy, XCBDRAWABLE drawable, XCBSCREEN *screen, XCBVISUALTYPE *visual, XCBRenderPICTFORMINFO *format, int width, int height, int depth){ cairo_xcb_surface_t *surface; surface = malloc (sizeof (cairo_xcb_surface_t)); if (surface == NULL) { _cairo_error (CAIRO_STATUS_NO_MEMORY); return (cairo_surface_t*) &_cairo_surface_nil; } _cairo_surface_init (&surface->base, &cairo_xcb_surface_backend, _xcb_render_format_to_content (format)); surface->dpy = dpy; surface->screen = screen; surface->gc.xid = 0; surface->drawable = drawable; surface->owns_pixmap = FALSE; surface->visual = visual; if (format) { surface->format = *format; surface->has_format = 1; } else { surface->format.id.xid = 0; surface->has_format = 0; } surface->use_pixmap = 0; surface->width = width; surface->height = height; surface->depth = depth; if (format) { surface->depth = format->depth; } else if (visual) { XCBDEPTHIter depths; XCBVISUALTYPEIter visuals; /* This is ugly, but we have to walk over all visuals * for the screen to find the depth. */ depths = XCBSCREENAllowedDepthsIter(screen); for(; depths.rem; XCBDEPTHNext(&depths)) { visuals = XCBDEPTHVisualsIter(depths.data); for(; visuals.rem; XCBVISUALTYPENext(&visuals)) { if(visuals.data->visual_id.id == visual->visual_id.id) { surface->depth = depths.data->depth; goto found; } } } found: ; } query_render_version(dpy, surface); surface->picture.xid = 0; if (CAIRO_SURFACE_RENDER_HAS_CREATE_PICTURE (surface)) { XCBRenderPICTFORMAT pict_format = {0}; XCBRenderPICTFORMINFO format_info; surface->picture = XCBRenderPICTURENew(dpy); if (!format) { if (visual) { pict_format = format_from_visual (dpy, visual->visual_id); } else if (depth == 1) { format_info = _format_from_cairo (dpy, CAIRO_FORMAT_A1); pict_format = format_info.id; } XCBRenderCreatePicture (dpy, surface->picture, drawable, pict_format, 0, NULL); } else { XCBRenderCreatePicture (dpy, surface->picture, drawable, format->id, 0, NULL); } } return (cairo_surface_t *) surface;}static XCBSCREEN *_cairo_xcb_screen_from_visual (XCBConnection *c, XCBVISUALTYPE *visual){ XCBSCREENIter s = XCBSetupRootsIter(XCBGetSetup(c)); for (; s.rem; XCBSCREENNext(&s)) { if (s.data->root_visual.id == visual->visual_id.id) return s.data; XCBDEPTHIter d = XCBSCREENAllowedDepthsIter(s.data); for (; d.rem; XCBDEPTHNext(&d)) { XCBVISUALTYPEIter v = XCBDEPTHVisualsIter(d.data); for (; v.rem; XCBVISUALTYPENext(&v)) { if (v.data->visual_id.id == visual->visual_id.id) return s.data; } } } return NULL;}/** * cairo_xcb_surface_create: * @c: an XCB connection * @drawable: an XCB drawable * @visual: the visual to use for drawing to @drawable. The depth * of the visual must match the depth of the drawable. * Currently, only TrueColor visuals are fully supported. * @width: the current width of @drawable. * @height: the current height of @drawable. * * Creates an XCB surface that draws to the given drawable. * The way that colors are represented in the drawable is specified * by the provided visual. * * NOTE: If @drawable is a window, then the function * cairo_xcb_surface_set_size must be called whenever the size of the * window changes. * * Return value: the newly created surface **/cairo_surface_t *cairo_xcb_surface_create (XCBConnection *c, XCBDRAWABLE drawable, XCBVISUALTYPE *visual, int width, int height){ XCBSCREEN *screen = _cairo_xcb_screen_from_visual (c, visual); if (screen == NULL) { _cairo_error (CAIRO_STATUS_INVALID_VISUAL); return (cairo_surface_t*) &_cairo_surface_nil; } return _cairo_xcb_surface_create_internal (c, drawable, screen, visual, NULL, width, height, 0);}/** * cairo_xcb_surface_create_for_bitmap: * @c: an XCB connection * @bitmap: an XCB Pixmap (a depth-1 pixmap) * @screen: an XCB Screen * @width: the current width of @bitmap * @height: the current height of @bitmap * * Creates an XCB surface that draws to the given bitmap. * This will be drawn to as a CAIRO_FORMAT_A1 object. * * Return value: the newly created surface **/cairo_surface_t *cairo_xcb_surface_create_for_bitmap (XCBConnection *c, XCBPIXMAP bitmap, XCBSCREEN *screen, int width, int height){ XCBDRAWABLE drawable; drawable.pixmap = bitmap; return _cairo_xcb_surface_create_internal (c, drawable, screen, NULL, NULL, width, height, 1);}/** * cairo_xcb_surface_create_with_xrender_format: * @c: an XCB connection * @drawable: an XCB drawable * @screen: the XCB screen associated with @drawable * @format: the picture format to use for drawing to @drawable. The * depth of @format mush match the depth of the drawable. * @width: the current width of @drawable * @height: the current height of @drawable * * Creates an XCB surface that draws to the given drawable. * The way that colors are represented in the drawable is specified * by the provided picture format. * * NOTE: If @drawable is a Window, then the function * cairo_xcb_surface_set_size must be called whenever the size of the * window changes. * * Return value: the newly created surface. **/cairo_surface_t *cairo_xcb_surface_create_with_xrender_format (XCBConnection *c, XCBDRAWABLE drawable, XCBSCREEN *screen, XCBRenderPICTFORMINFO *format, int width, int height){ return _cairo_xcb_surface_create_internal (c, drawable, screen, NULL, format, width, height, 0);}/** * cairo_xcb_surface_set_size: * @surface: a #cairo_surface_t for the XCB backend * @width: the new width of the surface * @height: the new height of the surface * * Informs cairo of the new size of the XCB drawable underlying the * surface. For a surface created for a window (rather than a pixmap), * this function must be called each time the size of the window * changes. (For a subwindow, you are normally resizing the window * yourself, but for a toplevel window, it is necessary to listen for * ConfigureNotify events.) * * A pixmap can never change size, so it is never necessary to call * this function on a surface created for a pixmap. **/voidcairo_xcb_surface_set_size (cairo_surface_t *surface, int width, int height){ cairo_xcb_surface_t *xcb_surface = (cairo_xcb_surface_t *)surface; if (! _cairo_surface_is_xcb (surface)) { _cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_TYPE_MISMATCH); return; } xcb_surface->width = width; xcb_surface->height = height;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -