forked from AuroraMiddleware/gtk
API: Remove gdk_draw_pixbuf()
This commit is contained in:
parent
11ee2abacc
commit
4f8dbd4a8d
@ -413,7 +413,6 @@ gdk_draw_point
|
||||
gdk_draw_points
|
||||
gdk_draw_line
|
||||
gdk_draw_lines
|
||||
gdk_draw_pixbuf
|
||||
gdk_draw_segments
|
||||
GdkSegment
|
||||
gdk_draw_rectangle
|
||||
|
@ -129,19 +129,6 @@ static gboolean accelerated_alpha_blending = FALSE;
|
||||
static gpointer parent_class = NULL;
|
||||
static const cairo_user_data_key_t gdk_directfb_cairo_key;
|
||||
|
||||
static void (*real_draw_pixbuf) (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
GdkPixbuf *pixbuf,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dither,
|
||||
gint x_dither,
|
||||
gint y_dither);
|
||||
|
||||
|
||||
/**********************************************************
|
||||
* DirectFB specific implementations of generic functions *
|
||||
@ -963,438 +950,6 @@ gdk_directfb_draw_image (GdkDrawable *drawable,
|
||||
temp_region_deinit( &clip );
|
||||
}
|
||||
|
||||
static void
|
||||
composite (guchar *src_buf,
|
||||
gint src_rowstride,
|
||||
guchar *dest_buf,
|
||||
gint dest_rowstride,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
guchar *src = src_buf;
|
||||
guchar *dest = dest_buf;
|
||||
|
||||
while (height--)
|
||||
{
|
||||
gint twidth = width;
|
||||
guchar *p = src;
|
||||
guchar *q = dest;
|
||||
|
||||
while (twidth--)
|
||||
{
|
||||
guchar a = p[3];
|
||||
guint t;
|
||||
|
||||
t = a * p[0] + (255 - a) * q[0] + 0x80;
|
||||
q[0] = (t + (t >> 8)) >> 8;
|
||||
t = a * p[1] + (255 - a) * q[1] + 0x80;
|
||||
q[1] = (t + (t >> 8)) >> 8;
|
||||
t = a * p[2] + (255 - a) * q[2] + 0x80;
|
||||
q[2] = (t + (t >> 8)) >> 8;
|
||||
|
||||
p += 4;
|
||||
q += 3;
|
||||
}
|
||||
|
||||
src += src_rowstride;
|
||||
dest += dest_rowstride;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
composite_0888 (guchar *src_buf,
|
||||
gint src_rowstride,
|
||||
guchar *dest_buf,
|
||||
gint dest_rowstride,
|
||||
GdkByteOrder dest_byte_order,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
guchar *src = src_buf;
|
||||
guchar *dest = dest_buf;
|
||||
|
||||
while (height--)
|
||||
{
|
||||
gint twidth = width;
|
||||
guchar *p = src;
|
||||
guchar *q = dest;
|
||||
|
||||
if (dest_byte_order == GDK_LSB_FIRST)
|
||||
{
|
||||
while (twidth--)
|
||||
{
|
||||
guint t;
|
||||
|
||||
t = p[3] * p[2] + (255 - p[3]) * q[0] + 0x80;
|
||||
q[0] = (t + (t >> 8)) >> 8;
|
||||
t = p[3] * p[1] + (255 - p[3]) * q[1] + 0x80;
|
||||
q[1] = (t + (t >> 8)) >> 8;
|
||||
t = p[3] * p[0] + (255 - p[3]) * q[2] + 0x80;
|
||||
q[2] = (t + (t >> 8)) >> 8;
|
||||
p += 4;
|
||||
q += 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (twidth--)
|
||||
{
|
||||
guint t;
|
||||
|
||||
t = p[3] * p[0] + (255 - p[3]) * q[1] + 0x80;
|
||||
q[1] = (t + (t >> 8)) >> 8;
|
||||
t = p[3] * p[1] + (255 - p[3]) * q[2] + 0x80;
|
||||
q[2] = (t + (t >> 8)) >> 8;
|
||||
t = p[3] * p[2] + (255 - p[3]) * q[3] + 0x80;
|
||||
q[3] = (t + (t >> 8)) >> 8;
|
||||
p += 4;
|
||||
q += 4;
|
||||
}
|
||||
}
|
||||
|
||||
src += src_rowstride;
|
||||
dest += dest_rowstride;
|
||||
}
|
||||
}
|
||||
|
||||
/* change the last value to adjust the size of the device (1-4) */
|
||||
#define SET_PIXEL_DUFFS_DEVICE( D, S, w ) \
|
||||
SET_PIXEL_DUFFS_DEVICE_N( D, S, w, 2 )
|
||||
|
||||
/* From DirectFB's gfx/generic/generic.c" */
|
||||
#define SET_PIXEL( D, S ) \
|
||||
switch (S >> 26) { \
|
||||
case 0: \
|
||||
break; \
|
||||
case 0x3f: \
|
||||
D = ((S << 8) & 0xF800) | \
|
||||
((S >> 5) & 0x07E0) | \
|
||||
((S >> 19) & 0x001F); \
|
||||
break; \
|
||||
default: \
|
||||
D = (((( (((S<<8) & 0xf800) | ((S>>19) & 0x001f)) \
|
||||
- (D & 0xf81f)) * ((S>>26)+1) + ((D & 0xf81f)<<6)) & 0x003e07c0) \
|
||||
+ \
|
||||
((( ((S>>5) & 0x07e0) \
|
||||
- (D & 0x07e0)) * ((S>>26)+1) + ((D & 0x07e0)<<6)) & 0x0001f800)) >> 6; \
|
||||
}
|
||||
|
||||
static void
|
||||
composite_565 (guchar *src_buf,
|
||||
gint src_rowstride,
|
||||
guchar *dest_buf,
|
||||
gint dest_rowstride,
|
||||
GdkByteOrder dest_byte_order,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
while (height--) {
|
||||
int w = width;
|
||||
u16 *D = (u16*) dest_buf;
|
||||
u32 *S = (u32*) src_buf;
|
||||
#if 1
|
||||
if ((unsigned long)D & 2) {
|
||||
SET_PIXEL( D[0], S[0] );
|
||||
w--;
|
||||
D++;
|
||||
S++;
|
||||
}
|
||||
|
||||
int i;
|
||||
int w2 = w / 2;
|
||||
u32 *D32 = (u32*) D;
|
||||
|
||||
for (i=0; i<w2; i++) {
|
||||
register u32 S0 = S[(i << 1) + 0];
|
||||
register u32 S1 = S[(i << 1) + 1];
|
||||
|
||||
if ((S0 >> 26) == 0x3f && (S1 >> 26) == 0x3f) {
|
||||
D32[i] = ((S0 << 8) & 0x0000F800) |
|
||||
((S0 >> 5) & 0x000007E0) |
|
||||
((S0 >> 19) & 0x0000001F) |
|
||||
((S1 << 24) & 0xF8000000) |
|
||||
((S1 << 11) & 0x07E00000) |
|
||||
((S1 >> 3) & 0x001F0000);
|
||||
}
|
||||
else {
|
||||
SET_PIXEL( D[(i << 1) + 0], S0 );
|
||||
SET_PIXEL( D[(i << 1) + 1], S1 );
|
||||
}
|
||||
}
|
||||
|
||||
if (w & 1)
|
||||
SET_PIXEL( D[w-1], S[w-1] );
|
||||
#else
|
||||
SET_PIXEL_DUFFS_DEVICE( D, S, w );
|
||||
#endif
|
||||
|
||||
dest_buf += dest_rowstride;
|
||||
src_buf += src_rowstride;
|
||||
}
|
||||
}
|
||||
|
||||
#undef SET_PIXEL
|
||||
#undef SET_PIXEL_DUFFS_DEVICE
|
||||
|
||||
static void
|
||||
gdk_directfb_draw_pixbuf (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
GdkPixbuf *pixbuf,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dither,
|
||||
gint x_dither,
|
||||
gint y_dither)
|
||||
{
|
||||
GdkPixbuf *composited = NULL;
|
||||
#if 0
|
||||
cairo_region_t *clip;
|
||||
cairo_region_t *drect;
|
||||
GdkRectangle tmp_rect;
|
||||
#endif
|
||||
GdkDrawableImplDirectFB *impl = GDK_DRAWABLE_IMPL_DIRECTFB (drawable);
|
||||
|
||||
g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
|
||||
g_return_if_fail (pixbuf->colorspace == GDK_COLORSPACE_RGB);
|
||||
g_return_if_fail (pixbuf->n_channels == 3 || pixbuf->n_channels == 4);
|
||||
g_return_if_fail (pixbuf->bits_per_sample == 8);
|
||||
|
||||
g_return_if_fail (drawable != NULL);
|
||||
|
||||
if (width == -1)
|
||||
width = pixbuf->width;
|
||||
if (height == -1)
|
||||
height = pixbuf->height;
|
||||
|
||||
g_return_if_fail (width >= 0 && height >= 0);
|
||||
g_return_if_fail (src_x >= 0 && src_x + width <= pixbuf->width);
|
||||
g_return_if_fail (src_y >= 0 && src_y + height <= pixbuf->height);
|
||||
|
||||
D_DEBUG_AT( GDKDFB_Drawable, "%s( %p, %p, %p, %4d,%4d -> %4d,%4d - %dx%d )\n", G_STRFUNC,
|
||||
drawable, gc, pixbuf, src_x, src_y, dest_x, dest_y, width, height );
|
||||
|
||||
/* Clip to the drawable; this is required for get_from_drawable() so
|
||||
* can't be done implicitly
|
||||
*/
|
||||
|
||||
if (dest_x < 0)
|
||||
{
|
||||
src_x -= dest_x;
|
||||
width += dest_x;
|
||||
dest_x = 0;
|
||||
}
|
||||
|
||||
if (dest_y < 0)
|
||||
{
|
||||
src_y -= dest_y;
|
||||
height += dest_y;
|
||||
dest_y = 0;
|
||||
}
|
||||
|
||||
if ((dest_x + width) > impl->width)
|
||||
width = impl->width - dest_x;
|
||||
|
||||
if ((dest_y + height) > impl->height)
|
||||
height = impl->height - dest_y;
|
||||
|
||||
if (width <= 0 || height <= 0)
|
||||
return;
|
||||
|
||||
#if 0
|
||||
/* Clip to the clip region; this avoids getting more
|
||||
* image data from the server than we need to.
|
||||
*/
|
||||
|
||||
tmp_rect.x = dest_x;
|
||||
tmp_rect.y = dest_y;
|
||||
tmp_rect.width = width;
|
||||
tmp_rect.height = height;
|
||||
|
||||
drect = cairo_region_create_rectangle (&tmp_rect);
|
||||
clip = gdk_drawable_get_clip_region (drawable);
|
||||
|
||||
cairo_region_intersect (drect, clip);
|
||||
|
||||
cairo_region_get_extents (drect, &tmp_rect);
|
||||
|
||||
cairo_region_destroy (drect);
|
||||
cairo_region_destroy (clip);
|
||||
|
||||
if (tmp_rect.width == 0 ||
|
||||
tmp_rect.height == 0)
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (pixbuf->has_alpha && impl->format == DSPF_RGB16) {
|
||||
void *data;
|
||||
int pitch;
|
||||
|
||||
if (impl->surface->Lock( impl->surface, DSLF_READ | DSLF_WRITE, &data, &pitch ) == DFB_OK) {
|
||||
composite_565( pixbuf->pixels + src_y * pixbuf->rowstride + src_x * 4,
|
||||
pixbuf->rowstride,
|
||||
data + dest_y * pitch + dest_x * 2,
|
||||
pitch,
|
||||
#if G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
GDK_MSB_FIRST,
|
||||
#else
|
||||
GDK_LSB_FIRST,
|
||||
#endif
|
||||
width, height );
|
||||
|
||||
impl->surface->Unlock( impl->surface );
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Actually draw */
|
||||
if (!gc)
|
||||
gc = _gdk_drawable_get_scratch_gc (drawable, FALSE);
|
||||
|
||||
if (pixbuf->has_alpha)
|
||||
{
|
||||
GdkVisual *visual = gdk_drawable_get_visual (drawable);
|
||||
void (*composite_func) (guchar *src_buf,
|
||||
gint src_rowstride,
|
||||
guchar *dest_buf,
|
||||
gint dest_rowstride,
|
||||
GdkByteOrder dest_byte_order,
|
||||
gint width,
|
||||
gint height) = NULL;
|
||||
|
||||
/* First we see if we have a visual-specific composition function that can composite
|
||||
* the pixbuf data directly onto the image
|
||||
*/
|
||||
if (visual)
|
||||
{
|
||||
gint bits_per_pixel = _gdk_windowing_get_bits_for_depth (gdk_drawable_get_display (drawable),
|
||||
visual->depth);
|
||||
|
||||
if (visual->byte_order == (G_BYTE_ORDER == G_BIG_ENDIAN ? GDK_MSB_FIRST : GDK_LSB_FIRST) &&
|
||||
visual->depth == 16 &&
|
||||
visual->red_mask == 0xf800 &&
|
||||
visual->green_mask == 0x07e0 &&
|
||||
visual->blue_mask == 0x001f)
|
||||
composite_func = composite_565;
|
||||
else if (visual->depth == 24 && bits_per_pixel == 32 &&
|
||||
visual->red_mask == 0xff0000 &&
|
||||
visual->green_mask == 0x00ff00 &&
|
||||
visual->blue_mask == 0x0000ff)
|
||||
composite_func = composite_0888;
|
||||
}
|
||||
|
||||
/* We can't use our composite func if we are required to dither
|
||||
*/
|
||||
if (composite_func && !(dither == GDK_RGB_DITHER_MAX && visual->depth != 24))
|
||||
{
|
||||
#if 0
|
||||
gint x0, y0;
|
||||
for (y0 = 0; y0 < height; y0 += GDK_SCRATCH_IMAGE_HEIGHT)
|
||||
{
|
||||
gint height1 = MIN (height - y0, GDK_SCRATCH_IMAGE_HEIGHT);
|
||||
for (x0 = 0; x0 < width; x0 += GDK_SCRATCH_IMAGE_WIDTH)
|
||||
{
|
||||
gint xs0, ys0;
|
||||
|
||||
gint width1 = MIN (width - x0, GDK_SCRATCH_IMAGE_WIDTH);
|
||||
|
||||
GdkImage *image = _gdk_image_get_scratch (gdk_drawable_get_screen (drawable),
|
||||
width1, height1,
|
||||
gdk_drawable_get_depth (drawable), &xs0, &ys0);
|
||||
|
||||
gdk_drawable_copy_to_image (drawable, image,
|
||||
dest_x + x0, dest_y + y0,
|
||||
xs0, ys0,
|
||||
width1, height1);
|
||||
(*composite_func) (pixbuf->pixels + (src_y + y0) * pixbuf->rowstride + (src_x + x0) * 4,
|
||||
pixbuf->rowstride,
|
||||
(guchar*)image->mem + ys0 * image->bpl + xs0 * image->bpp,
|
||||
image->bpl,
|
||||
visual->byte_order,
|
||||
width1, height1);
|
||||
gdk_draw_image (drawable, gc, image,
|
||||
xs0, ys0,
|
||||
dest_x + x0, dest_y + y0,
|
||||
width1, height1);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void *data;
|
||||
int pitch;
|
||||
|
||||
if (impl->surface->Lock( impl->surface, DSLF_READ | DSLF_WRITE, &data, &pitch ) == DFB_OK) {
|
||||
(*composite_func) (pixbuf->pixels + src_y * pixbuf->rowstride + src_x * 4,
|
||||
pixbuf->rowstride,
|
||||
data + dest_y * pitch + DFB_BYTES_PER_LINE( impl->format, dest_x ),
|
||||
pitch,
|
||||
visual->byte_order,
|
||||
width, height);
|
||||
|
||||
impl->surface->Unlock( impl->surface );
|
||||
}
|
||||
#endif
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No special composition func, convert dest to 24 bit RGB data, composite against
|
||||
* that, and convert back.
|
||||
*/
|
||||
composited = gdk_pixbuf_get_from_drawable (NULL,
|
||||
drawable,
|
||||
NULL,
|
||||
dest_x, dest_y,
|
||||
0, 0,
|
||||
width, height);
|
||||
|
||||
if (composited)
|
||||
composite (pixbuf->pixels + src_y * pixbuf->rowstride + src_x * 4,
|
||||
pixbuf->rowstride,
|
||||
composited->pixels,
|
||||
composited->rowstride,
|
||||
width, height);
|
||||
}
|
||||
}
|
||||
|
||||
if (composited)
|
||||
{
|
||||
src_x = 0;
|
||||
src_y = 0;
|
||||
pixbuf = composited;
|
||||
}
|
||||
|
||||
if (pixbuf->n_channels == 4)
|
||||
{
|
||||
guchar *buf = pixbuf->pixels + src_y * pixbuf->rowstride + src_x * 4;
|
||||
|
||||
gdk_draw_rgb_32_image_dithalign (drawable, gc,
|
||||
dest_x, dest_y,
|
||||
width, height,
|
||||
dither,
|
||||
buf, pixbuf->rowstride,
|
||||
x_dither, y_dither);
|
||||
}
|
||||
else /* n_channels == 3 */
|
||||
{
|
||||
guchar *buf = pixbuf->pixels + src_y * pixbuf->rowstride + src_x * 3;
|
||||
|
||||
gdk_draw_rgb_image_dithalign (drawable, gc,
|
||||
dest_x, dest_y,
|
||||
width, height,
|
||||
dither,
|
||||
buf, pixbuf->rowstride,
|
||||
x_dither, y_dither);
|
||||
}
|
||||
|
||||
out:
|
||||
if (composited)
|
||||
g_object_unref (composited);
|
||||
}
|
||||
|
||||
static inline void
|
||||
convert_rgba_pixbuf_to_image (guint32 *src,
|
||||
guint src_pitch,
|
||||
|
@ -560,7 +560,6 @@ gdk_draw_glyphs_transformed
|
||||
gdk_draw_image
|
||||
gdk_draw_line
|
||||
gdk_draw_lines
|
||||
gdk_draw_pixbuf
|
||||
gdk_draw_point
|
||||
gdk_draw_points
|
||||
gdk_draw_polygon
|
||||
|
526
gdk/gdkdraw.c
526
gdk/gdkdraw.c
@ -49,18 +49,6 @@ static GdkDrawable* gdk_drawable_real_get_composite_drawable (GdkDrawable *draw
|
||||
gint *composite_x_offset,
|
||||
gint *composite_y_offset);
|
||||
static cairo_region_t * gdk_drawable_real_get_visible_region (GdkDrawable *drawable);
|
||||
static void gdk_drawable_real_draw_pixbuf (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
GdkPixbuf *pixbuf,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dither,
|
||||
gint x_dither,
|
||||
gint y_dither);
|
||||
static void gdk_drawable_real_draw_drawable (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
GdkDrawable *src,
|
||||
@ -82,7 +70,6 @@ gdk_drawable_class_init (GdkDrawableClass *klass)
|
||||
/* Default implementation for clip and visible region is the same */
|
||||
klass->get_clip_region = gdk_drawable_real_get_visible_region;
|
||||
klass->get_visible_region = gdk_drawable_real_get_visible_region;
|
||||
klass->draw_pixbuf = gdk_drawable_real_draw_pixbuf;
|
||||
klass->draw_drawable = gdk_drawable_real_draw_drawable;
|
||||
}
|
||||
|
||||
@ -551,71 +538,6 @@ gdk_draw_image (GdkDrawable *drawable,
|
||||
xdest, ydest, width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_draw_pixbuf:
|
||||
* @drawable: Destination drawable.
|
||||
* @gc: (allow-none): a #GdkGC, used for clipping, or %NULL
|
||||
* @pixbuf: a #GdkPixbuf
|
||||
* @src_x: Source X coordinate within pixbuf.
|
||||
* @src_y: Source Y coordinates within pixbuf.
|
||||
* @dest_x: Destination X coordinate within drawable.
|
||||
* @dest_y: Destination Y coordinate within drawable.
|
||||
* @width: Width of region to render, in pixels, or -1 to use pixbuf width.
|
||||
* @height: Height of region to render, in pixels, or -1 to use pixbuf height.
|
||||
* @dither: Dithering mode for #GdkRGB.
|
||||
* @x_dither: X offset for dither.
|
||||
* @y_dither: Y offset for dither.
|
||||
*
|
||||
* Renders a rectangular portion of a pixbuf to a drawable. The destination
|
||||
* drawable must have a colormap. All windows have a colormap, however, pixmaps
|
||||
* only have colormap by default if they were created with a non-%NULL window
|
||||
* argument. Otherwise a colormap must be set on them with
|
||||
* gdk_drawable_set_colormap().
|
||||
*
|
||||
* On older X servers, rendering pixbufs with an alpha channel involves round
|
||||
* trips to the X server, and may be somewhat slow.
|
||||
*
|
||||
* If GDK is built with the Sun mediaLib library, the gdk_draw_pixbuf
|
||||
* function is accelerated using mediaLib, which provides hardware
|
||||
* acceleration on Intel, AMD, and Sparc chipsets. If desired, mediaLib
|
||||
* support can be turned off by setting the GDK_DISABLE_MEDIALIB environment
|
||||
* variable.
|
||||
*
|
||||
* Since: 2.2
|
||||
**/
|
||||
void
|
||||
gdk_draw_pixbuf (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
const GdkPixbuf *pixbuf,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dither,
|
||||
gint x_dither,
|
||||
gint y_dither)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DRAWABLE (drawable));
|
||||
g_return_if_fail (gc == NULL || GDK_IS_GC (gc));
|
||||
g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
|
||||
|
||||
if (width == 0 || height == 0)
|
||||
return;
|
||||
|
||||
if (width == -1)
|
||||
width = gdk_pixbuf_get_width (pixbuf);
|
||||
if (height == -1)
|
||||
height = gdk_pixbuf_get_height (pixbuf);
|
||||
|
||||
GDK_DRAWABLE_GET_CLASS (drawable)->draw_pixbuf (drawable, gc,
|
||||
(GdkPixbuf *) pixbuf,
|
||||
src_x, src_y, dest_x, dest_y,
|
||||
width, height,
|
||||
dither, x_dither, y_dither);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_draw_points:
|
||||
* @drawable: a #GdkDrawable (a #GdkWindow or a #GdkPixmap).
|
||||
@ -1121,214 +1043,6 @@ _gdk_drawable_ref_cairo_surface (GdkDrawable *drawable)
|
||||
return GDK_DRAWABLE_GET_CLASS (drawable)->ref_cairo_surface (drawable);
|
||||
}
|
||||
|
||||
static void
|
||||
composite (guchar *src_buf,
|
||||
gint src_rowstride,
|
||||
guchar *dest_buf,
|
||||
gint dest_rowstride,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
guchar *src = src_buf;
|
||||
guchar *dest = dest_buf;
|
||||
|
||||
while (height--)
|
||||
{
|
||||
gint twidth = width;
|
||||
guchar *p = src;
|
||||
guchar *q = dest;
|
||||
|
||||
while (twidth--)
|
||||
{
|
||||
guchar a = p[3];
|
||||
guint t;
|
||||
|
||||
t = a * p[0] + (255 - a) * q[0] + 0x80;
|
||||
q[0] = (t + (t >> 8)) >> 8;
|
||||
t = a * p[1] + (255 - a) * q[1] + 0x80;
|
||||
q[1] = (t + (t >> 8)) >> 8;
|
||||
t = a * p[2] + (255 - a) * q[2] + 0x80;
|
||||
q[2] = (t + (t >> 8)) >> 8;
|
||||
|
||||
p += 4;
|
||||
q += 3;
|
||||
}
|
||||
|
||||
src += src_rowstride;
|
||||
dest += dest_rowstride;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
composite_0888 (guchar *src_buf,
|
||||
gint src_rowstride,
|
||||
guchar *dest_buf,
|
||||
gint dest_rowstride,
|
||||
GdkByteOrder dest_byte_order,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
guchar *src = src_buf;
|
||||
guchar *dest = dest_buf;
|
||||
|
||||
while (height--)
|
||||
{
|
||||
gint twidth = width;
|
||||
guchar *p = src;
|
||||
guchar *q = dest;
|
||||
|
||||
if (dest_byte_order == GDK_LSB_FIRST)
|
||||
{
|
||||
while (twidth--)
|
||||
{
|
||||
guint t;
|
||||
|
||||
t = p[3] * p[2] + (255 - p[3]) * q[0] + 0x80;
|
||||
q[0] = (t + (t >> 8)) >> 8;
|
||||
t = p[3] * p[1] + (255 - p[3]) * q[1] + 0x80;
|
||||
q[1] = (t + (t >> 8)) >> 8;
|
||||
t = p[3] * p[0] + (255 - p[3]) * q[2] + 0x80;
|
||||
q[2] = (t + (t >> 8)) >> 8;
|
||||
p += 4;
|
||||
q += 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (twidth--)
|
||||
{
|
||||
guint t;
|
||||
|
||||
t = p[3] * p[0] + (255 - p[3]) * q[1] + 0x80;
|
||||
q[1] = (t + (t >> 8)) >> 8;
|
||||
t = p[3] * p[1] + (255 - p[3]) * q[2] + 0x80;
|
||||
q[2] = (t + (t >> 8)) >> 8;
|
||||
t = p[3] * p[2] + (255 - p[3]) * q[3] + 0x80;
|
||||
q[3] = (t + (t >> 8)) >> 8;
|
||||
p += 4;
|
||||
q += 4;
|
||||
}
|
||||
}
|
||||
|
||||
src += src_rowstride;
|
||||
dest += dest_rowstride;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_MEDIALIB
|
||||
static void
|
||||
composite_0888_medialib (guchar *src_buf,
|
||||
gint src_rowstride,
|
||||
guchar *dest_buf,
|
||||
gint dest_rowstride,
|
||||
GdkByteOrder dest_byte_order,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
guchar *src = src_buf;
|
||||
guchar *dest = dest_buf;
|
||||
|
||||
mlib_image img_src, img_dst;
|
||||
|
||||
mlib_ImageSetStruct (&img_dst,
|
||||
MLIB_BYTE,
|
||||
4,
|
||||
width,
|
||||
height,
|
||||
dest_rowstride,
|
||||
dest_buf);
|
||||
|
||||
mlib_ImageSetStruct (&img_src,
|
||||
MLIB_BYTE,
|
||||
4,
|
||||
width,
|
||||
height,
|
||||
src_rowstride,
|
||||
src_buf);
|
||||
|
||||
if (dest_byte_order == GDK_LSB_FIRST)
|
||||
mlib_ImageBlendRGBA2BGRA (&img_dst, &img_src);
|
||||
else
|
||||
mlib_ImageBlendRGBA2ARGB (&img_dst, &img_src);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
composite_565 (guchar *src_buf,
|
||||
gint src_rowstride,
|
||||
guchar *dest_buf,
|
||||
gint dest_rowstride,
|
||||
GdkByteOrder dest_byte_order,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
guchar *src = src_buf;
|
||||
guchar *dest = dest_buf;
|
||||
|
||||
while (height--)
|
||||
{
|
||||
gint twidth = width;
|
||||
guchar *p = src;
|
||||
gushort *q = (gushort *)dest;
|
||||
|
||||
while (twidth--)
|
||||
{
|
||||
guchar a = p[3];
|
||||
guint tr, tg, tb;
|
||||
guint tr1, tg1, tb1;
|
||||
guint tmp = *q;
|
||||
|
||||
#if 1
|
||||
/* This is fast, and corresponds to what composite() above does
|
||||
* if we converted to 8-bit first.
|
||||
*/
|
||||
tr = (tmp & 0xf800);
|
||||
tr1 = a * p[0] + (255 - a) * ((tr >> 8) + (tr >> 13)) + 0x80;
|
||||
tg = (tmp & 0x07e0);
|
||||
tg1 = a * p[1] + (255 - a) * ((tg >> 3) + (tg >> 9)) + 0x80;
|
||||
tb = (tmp & 0x001f);
|
||||
tb1 = a * p[2] + (255 - a) * ((tb << 3) + (tb >> 2)) + 0x80;
|
||||
|
||||
*q = (((tr1 + (tr1 >> 8)) & 0xf800) |
|
||||
(((tg1 + (tg1 >> 8)) & 0xfc00) >> 5) |
|
||||
((tb1 + (tb1 >> 8)) >> 11));
|
||||
#else
|
||||
/* This version correspond to the result we get with XRENDER -
|
||||
* a bit of precision is lost since we convert to 8 bit after premultiplying
|
||||
* instead of at the end
|
||||
*/
|
||||
guint tr2, tg2, tb2;
|
||||
guint tr3, tg3, tb3;
|
||||
|
||||
tr = (tmp & 0xf800);
|
||||
tr1 = (255 - a) * ((tr >> 8) + (tr >> 13)) + 0x80;
|
||||
tr2 = a * p[0] + 0x80;
|
||||
tr3 = ((tr1 + (tr1 >> 8)) >> 8) + ((tr2 + (tr2 >> 8)) >> 8);
|
||||
|
||||
tg = (tmp & 0x07e0);
|
||||
tg1 = (255 - a) * ((tg >> 3) + (tg >> 9)) + 0x80;
|
||||
tg2 = a * p[0] + 0x80;
|
||||
tg3 = ((tg1 + (tg1 >> 8)) >> 8) + ((tg2 + (tg2 >> 8)) >> 8);
|
||||
|
||||
tb = (tmp & 0x001f);
|
||||
tb1 = (255 - a) * ((tb << 3) + (tb >> 2)) + 0x80;
|
||||
tb2 = a * p[0] + 0x80;
|
||||
tb3 = ((tb1 + (tb1 >> 8)) >> 8) + ((tb2 + (tb2 >> 8)) >> 8);
|
||||
|
||||
*q = (((tr3 & 0xf8) << 8) |
|
||||
((tg3 & 0xfc) << 3) |
|
||||
((tb3 >> 3)));
|
||||
#endif
|
||||
|
||||
p += 4;
|
||||
q++;
|
||||
}
|
||||
|
||||
src += src_rowstride;
|
||||
dest += dest_rowstride;
|
||||
}
|
||||
}
|
||||
|
||||
/* Implementation of the old vfunc in terms of the new one
|
||||
in case someone calls it directly (which they shouldn't!) */
|
||||
static void
|
||||
@ -1354,246 +1068,6 @@ gdk_drawable_real_draw_drawable (GdkDrawable *drawable,
|
||||
src);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drawable_real_draw_pixbuf (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
GdkPixbuf *pixbuf,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dither,
|
||||
gint x_dither,
|
||||
gint y_dither)
|
||||
{
|
||||
GdkPixbuf *composited = NULL;
|
||||
gint dwidth, dheight;
|
||||
cairo_region_t *clip;
|
||||
cairo_region_t *drect;
|
||||
GdkRectangle tmp_rect;
|
||||
GdkDrawable *real_drawable;
|
||||
|
||||
g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
|
||||
g_return_if_fail (gdk_pixbuf_get_colorspace (pixbuf) == GDK_COLORSPACE_RGB);
|
||||
g_return_if_fail (gdk_pixbuf_get_n_channels (pixbuf) == 3 ||
|
||||
gdk_pixbuf_get_n_channels (pixbuf) == 4);
|
||||
g_return_if_fail (gdk_pixbuf_get_bits_per_sample (pixbuf) == 8);
|
||||
|
||||
g_return_if_fail (drawable != NULL);
|
||||
|
||||
if (width == -1)
|
||||
width = gdk_pixbuf_get_width (pixbuf);
|
||||
if (height == -1)
|
||||
height = gdk_pixbuf_get_height (pixbuf);
|
||||
|
||||
g_return_if_fail (width >= 0 && height >= 0);
|
||||
g_return_if_fail (src_x >= 0 && src_x + width <= gdk_pixbuf_get_width (pixbuf));
|
||||
g_return_if_fail (src_y >= 0 && src_y + height <= gdk_pixbuf_get_height (pixbuf));
|
||||
|
||||
/* Clip to the drawable; this is required for get_from_drawable() so
|
||||
* can't be done implicitly
|
||||
*/
|
||||
|
||||
if (dest_x < 0)
|
||||
{
|
||||
src_x -= dest_x;
|
||||
width += dest_x;
|
||||
dest_x = 0;
|
||||
}
|
||||
|
||||
if (dest_y < 0)
|
||||
{
|
||||
src_y -= dest_y;
|
||||
height += dest_y;
|
||||
dest_y = 0;
|
||||
}
|
||||
|
||||
gdk_drawable_get_size (drawable, &dwidth, &dheight);
|
||||
|
||||
if ((dest_x + width) > dwidth)
|
||||
width = dwidth - dest_x;
|
||||
|
||||
if ((dest_y + height) > dheight)
|
||||
height = dheight - dest_y;
|
||||
|
||||
if (width <= 0 || height <= 0)
|
||||
return;
|
||||
|
||||
/* Clip to the clip region; this avoids getting more
|
||||
* image data from the server than we need to.
|
||||
*/
|
||||
|
||||
tmp_rect.x = dest_x;
|
||||
tmp_rect.y = dest_y;
|
||||
tmp_rect.width = width;
|
||||
tmp_rect.height = height;
|
||||
|
||||
drect = cairo_region_create_rectangle (&tmp_rect);
|
||||
clip = gdk_drawable_get_clip_region (drawable);
|
||||
|
||||
cairo_region_intersect (drect, clip);
|
||||
|
||||
cairo_region_get_extents (drect, &tmp_rect);
|
||||
|
||||
cairo_region_destroy (drect);
|
||||
cairo_region_destroy (clip);
|
||||
|
||||
if (tmp_rect.width == 0 ||
|
||||
tmp_rect.height == 0)
|
||||
return;
|
||||
|
||||
/* Actually draw */
|
||||
if (!gc)
|
||||
gc = _gdk_drawable_get_scratch_gc (drawable, FALSE);
|
||||
|
||||
/* Drawable is a wrapper here, but at this time we
|
||||
have already retargeted the destination to any
|
||||
impl window and set the clip, so what we really
|
||||
want to do is draw directly on the impl, ignoring
|
||||
client side subwindows. We also use the impl
|
||||
in the pixmap target case to avoid resetting the
|
||||
already set clip on the GC. */
|
||||
if (GDK_IS_WINDOW (drawable))
|
||||
real_drawable = GDK_WINDOW_OBJECT (drawable)->impl;
|
||||
else
|
||||
real_drawable = GDK_PIXMAP_OBJECT (drawable)->impl;
|
||||
|
||||
if (gdk_pixbuf_get_has_alpha (pixbuf))
|
||||
{
|
||||
GdkVisual *visual = gdk_drawable_get_visual (drawable);
|
||||
void (*composite_func) (guchar *src_buf,
|
||||
gint src_rowstride,
|
||||
guchar *dest_buf,
|
||||
gint dest_rowstride,
|
||||
GdkByteOrder dest_byte_order,
|
||||
gint width,
|
||||
gint height) = NULL;
|
||||
|
||||
/* First we see if we have a visual-specific composition function that can composite
|
||||
* the pixbuf data directly onto the image
|
||||
*/
|
||||
if (visual)
|
||||
{
|
||||
gint bits_per_pixel = _gdk_windowing_get_bits_for_depth (gdk_drawable_get_display (drawable),
|
||||
visual->depth);
|
||||
|
||||
if (visual->byte_order == (G_BYTE_ORDER == G_BIG_ENDIAN ? GDK_MSB_FIRST : GDK_LSB_FIRST) &&
|
||||
visual->depth == 16 &&
|
||||
visual->red_mask == 0xf800 &&
|
||||
visual->green_mask == 0x07e0 &&
|
||||
visual->blue_mask == 0x001f)
|
||||
composite_func = composite_565;
|
||||
else if (visual->depth == 24 && bits_per_pixel == 32 &&
|
||||
visual->red_mask == 0xff0000 &&
|
||||
visual->green_mask == 0x00ff00 &&
|
||||
visual->blue_mask == 0x0000ff)
|
||||
{
|
||||
#ifdef USE_MEDIALIB
|
||||
if (_gdk_use_medialib ())
|
||||
composite_func = composite_0888_medialib;
|
||||
else
|
||||
composite_func = composite_0888;
|
||||
#else
|
||||
composite_func = composite_0888;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* We can't use our composite func if we are required to dither
|
||||
*/
|
||||
if (composite_func && !(dither == GDK_RGB_DITHER_MAX && visual->depth != 24))
|
||||
{
|
||||
gint x0, y0;
|
||||
for (y0 = 0; y0 < height; y0 += GDK_SCRATCH_IMAGE_HEIGHT)
|
||||
{
|
||||
gint height1 = MIN (height - y0, GDK_SCRATCH_IMAGE_HEIGHT);
|
||||
for (x0 = 0; x0 < width; x0 += GDK_SCRATCH_IMAGE_WIDTH)
|
||||
{
|
||||
gint xs0, ys0;
|
||||
|
||||
gint width1 = MIN (width - x0, GDK_SCRATCH_IMAGE_WIDTH);
|
||||
|
||||
GdkImage *image = _gdk_image_get_scratch (gdk_drawable_get_screen (drawable),
|
||||
width1, height1,
|
||||
gdk_drawable_get_depth (drawable), &xs0, &ys0);
|
||||
|
||||
gdk_drawable_copy_to_image (drawable, image,
|
||||
dest_x + x0, dest_y + y0,
|
||||
xs0, ys0,
|
||||
width1, height1);
|
||||
(*composite_func) (gdk_pixbuf_get_pixels (pixbuf) + (src_y + y0) * gdk_pixbuf_get_rowstride (pixbuf) + (src_x + x0) * 4,
|
||||
gdk_pixbuf_get_rowstride (pixbuf),
|
||||
(guchar*)image->mem + ys0 * image->bpl + xs0 * image->bpp,
|
||||
image->bpl,
|
||||
visual->byte_order,
|
||||
width1, height1);
|
||||
gdk_draw_image (real_drawable, gc, image,
|
||||
xs0, ys0,
|
||||
dest_x + x0, dest_y + y0,
|
||||
width1, height1);
|
||||
}
|
||||
}
|
||||
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No special composition func, convert dest to 24 bit RGB data, composite against
|
||||
* that, and convert back.
|
||||
*/
|
||||
composited = gdk_pixbuf_get_from_drawable (NULL,
|
||||
drawable,
|
||||
NULL,
|
||||
dest_x, dest_y,
|
||||
0, 0,
|
||||
width, height);
|
||||
|
||||
if (composited)
|
||||
composite (gdk_pixbuf_get_pixels (pixbuf) + src_y * gdk_pixbuf_get_rowstride (pixbuf) + src_x * 4,
|
||||
gdk_pixbuf_get_rowstride (pixbuf),
|
||||
gdk_pixbuf_get_pixels (composited),
|
||||
gdk_pixbuf_get_rowstride (composited),
|
||||
width, height);
|
||||
}
|
||||
}
|
||||
|
||||
if (composited)
|
||||
{
|
||||
src_x = 0;
|
||||
src_y = 0;
|
||||
pixbuf = composited;
|
||||
}
|
||||
|
||||
if (gdk_pixbuf_get_n_channels (pixbuf) == 4)
|
||||
{
|
||||
guchar *buf = gdk_pixbuf_get_pixels (pixbuf) + src_y * gdk_pixbuf_get_rowstride (pixbuf) + src_x * 4;
|
||||
|
||||
gdk_draw_rgb_32_image_dithalign (real_drawable, gc,
|
||||
dest_x, dest_y,
|
||||
width, height,
|
||||
dither,
|
||||
buf, gdk_pixbuf_get_rowstride (pixbuf),
|
||||
x_dither, y_dither);
|
||||
}
|
||||
else /* n_channels == 3 */
|
||||
{
|
||||
guchar *buf = gdk_pixbuf_get_pixels (pixbuf) + src_y * gdk_pixbuf_get_rowstride (pixbuf) + src_x * 3;
|
||||
|
||||
gdk_draw_rgb_image_dithalign (real_drawable, gc,
|
||||
dest_x, dest_y,
|
||||
width, height,
|
||||
dither,
|
||||
buf, gdk_pixbuf_get_rowstride (pixbuf),
|
||||
x_dither, y_dither);
|
||||
}
|
||||
|
||||
out:
|
||||
if (composited)
|
||||
g_object_unref (composited);
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
/**
|
||||
|
@ -151,18 +151,6 @@ struct _GdkDrawableClass
|
||||
gint *composite_x_offset,
|
||||
gint *composite_y_offset);
|
||||
|
||||
void (*draw_pixbuf) (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
GdkPixbuf *pixbuf,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dither,
|
||||
gint x_dither,
|
||||
gint y_dither);
|
||||
GdkImage* (*_copy_to_image) (GdkDrawable *drawable,
|
||||
GdkImage *image,
|
||||
gint src_x,
|
||||
@ -300,18 +288,6 @@ void gdk_draw_lines (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
const GdkPoint *points,
|
||||
gint n_points);
|
||||
void gdk_draw_pixbuf (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
const GdkPixbuf *pixbuf,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dither,
|
||||
gint x_dither,
|
||||
gint y_dither);
|
||||
|
||||
void gdk_draw_glyphs (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
|
@ -531,41 +531,6 @@ gdk_offscreen_window_draw_image (GdkDrawable *drawable,
|
||||
add_damage (offscreen, xdest, ydest, width, height, FALSE);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gdk_offscreen_window_draw_pixbuf (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
GdkPixbuf *pixbuf,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dither,
|
||||
gint x_dither,
|
||||
gint y_dither)
|
||||
{
|
||||
GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
|
||||
GdkDrawable *real_drawable = get_real_drawable (offscreen);
|
||||
|
||||
gdk_draw_pixbuf (real_drawable,
|
||||
gc,
|
||||
pixbuf,
|
||||
src_x,
|
||||
src_y,
|
||||
dest_x,
|
||||
dest_y,
|
||||
width,
|
||||
height,
|
||||
dither,
|
||||
x_dither,
|
||||
y_dither);
|
||||
|
||||
add_damage (offscreen, dest_x, dest_y, width, height, FALSE);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_offscreen_window_new (GdkWindow *window,
|
||||
GdkScreen *screen,
|
||||
@ -1199,7 +1164,6 @@ gdk_offscreen_window_class_init (GdkOffscreenWindowClass *klass)
|
||||
drawable_class->draw_segments = gdk_offscreen_window_draw_segments;
|
||||
drawable_class->draw_lines = gdk_offscreen_window_draw_lines;
|
||||
drawable_class->draw_image = gdk_offscreen_window_draw_image;
|
||||
drawable_class->draw_pixbuf = gdk_offscreen_window_draw_pixbuf;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -158,7 +158,7 @@ gdk_pixbuf_render_threshold_alpha (GdkPixbuf *pixbuf,
|
||||
* and @mask_return arguments, respectively, and renders a pixbuf and its
|
||||
* corresponding thresholded alpha mask to them. This is merely a convenience
|
||||
* function; applications that need to render pixbufs with dither offsets or to
|
||||
* given drawables should use gdk_draw_pixbuf() and gdk_pixbuf_render_threshold_alpha().
|
||||
* given drawables should use Cairo and gdk_pixbuf_render_threshold_alpha().
|
||||
*
|
||||
* The pixmap that is created is created for the colormap returned
|
||||
* by gdk_colormap_get_system(). You normally will want to instead use
|
||||
@ -219,7 +219,7 @@ remove_alpha_channel (GdkPixbuf *pixbuf)
|
||||
* and @mask_return arguments, respectively, and renders a pixbuf and its
|
||||
* corresponding tresholded alpha mask to them. This is merely a convenience
|
||||
* function; applications that need to render pixbufs with dither offsets or to
|
||||
* given drawables should use gdk_draw_pixbuf(), and gdk_pixbuf_render_threshold_alpha().
|
||||
* given drawables should use Cairo and gdk_pixbuf_render_threshold_alpha().
|
||||
*
|
||||
* The pixmap that is created uses the #GdkColormap specified by @colormap.
|
||||
* This colormap must match the colormap of the window where the pixmap
|
||||
|
@ -101,18 +101,6 @@ static void gdk_pixmap_draw_image (GdkDrawable *drawable,
|
||||
gint ydest,
|
||||
gint width,
|
||||
gint height);
|
||||
static void gdk_pixmap_draw_pixbuf (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
GdkPixbuf *pixbuf,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dither,
|
||||
gint x_dither,
|
||||
gint y_dither);
|
||||
static void gdk_pixmap_draw_trapezoids (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
GdkTrapezoid *trapezoids,
|
||||
@ -194,7 +182,6 @@ gdk_pixmap_class_init (GdkPixmapObjectClass *klass)
|
||||
drawable_class->draw_glyphs = gdk_pixmap_draw_glyphs;
|
||||
drawable_class->draw_glyphs_transformed = gdk_pixmap_draw_glyphs_transformed;
|
||||
drawable_class->draw_image = gdk_pixmap_draw_image;
|
||||
drawable_class->draw_pixbuf = gdk_pixmap_draw_pixbuf;
|
||||
drawable_class->draw_trapezoids = gdk_pixmap_draw_trapezoids;
|
||||
drawable_class->get_depth = gdk_pixmap_real_get_depth;
|
||||
drawable_class->get_screen = gdk_pixmap_real_get_screen;
|
||||
@ -430,29 +417,6 @@ gdk_pixmap_draw_image (GdkDrawable *drawable,
|
||||
width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_pixmap_draw_pixbuf (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
GdkPixbuf *pixbuf,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dither,
|
||||
gint x_dither,
|
||||
gint y_dither)
|
||||
{
|
||||
GdkPixmapObject *private = (GdkPixmapObject *)drawable;
|
||||
|
||||
if (gc)
|
||||
_gdk_gc_remove_drawable_clip (gc);
|
||||
gdk_draw_pixbuf (private->impl, gc, pixbuf,
|
||||
src_x, src_y, dest_x, dest_y, width, height,
|
||||
dither, x_dither, y_dither);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_pixmap_draw_trapezoids (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
@ -579,7 +543,7 @@ gdk_pixmap_colormap_new_from_pixbuf (GdkColormap *colormap,
|
||||
{
|
||||
GdkPixmap *pixmap;
|
||||
GdkPixbuf *render_pixbuf;
|
||||
GdkGC *tmp_gc;
|
||||
cairo_t *cr;
|
||||
GdkScreen *screen = gdk_colormap_get_screen (colormap);
|
||||
|
||||
pixmap = gdk_pixmap_new (gdk_screen_get_root_window (screen),
|
||||
@ -600,11 +564,10 @@ gdk_pixmap_colormap_new_from_pixbuf (GdkColormap *colormap,
|
||||
else
|
||||
render_pixbuf = pixbuf;
|
||||
|
||||
tmp_gc = _gdk_drawable_get_scratch_gc (pixmap, FALSE);
|
||||
gdk_draw_pixbuf (pixmap, tmp_gc, render_pixbuf, 0, 0, 0, 0,
|
||||
gdk_pixbuf_get_width (render_pixbuf),
|
||||
gdk_pixbuf_get_height (render_pixbuf),
|
||||
GDK_RGB_DITHER_NORMAL, 0, 0);
|
||||
cr = gdk_cairo_create (pixmap);
|
||||
gdk_cairo_set_source_pixbuf (cr, render_pixbuf, 0, 0);
|
||||
cairo_paint (cr);
|
||||
cairo_destroy (cr);
|
||||
|
||||
if (render_pixbuf != pixbuf)
|
||||
g_object_unref (render_pixbuf);
|
||||
|
@ -297,19 +297,6 @@ static void gdk_window_draw_image (GdkDrawable *drawable,
|
||||
gint width,
|
||||
gint height);
|
||||
|
||||
static void gdk_window_draw_pixbuf (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
GdkPixbuf *pixbuf,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dither,
|
||||
gint x_dither,
|
||||
gint y_dither);
|
||||
|
||||
static void gdk_window_draw_trapezoids (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
GdkTrapezoid *trapezoids,
|
||||
@ -511,7 +498,6 @@ gdk_window_class_init (GdkWindowObjectClass *klass)
|
||||
drawable_class->draw_glyphs = gdk_window_draw_glyphs;
|
||||
drawable_class->draw_glyphs_transformed = gdk_window_draw_glyphs_transformed;
|
||||
drawable_class->draw_image = gdk_window_draw_image;
|
||||
drawable_class->draw_pixbuf = gdk_window_draw_pixbuf;
|
||||
drawable_class->draw_trapezoids = gdk_window_draw_trapezoids;
|
||||
drawable_class->get_depth = gdk_window_real_get_depth;
|
||||
drawable_class->get_screen = gdk_window_real_get_screen;
|
||||
@ -4849,48 +4835,6 @@ gdk_window_draw_image (GdkDrawable *drawable,
|
||||
END_DRAW;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_window_draw_pixbuf (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
GdkPixbuf *pixbuf,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dither,
|
||||
gint x_dither,
|
||||
gint y_dither)
|
||||
{
|
||||
GdkWindowObject *private = (GdkWindowObject *)drawable;
|
||||
GdkDrawableClass *klass;
|
||||
|
||||
if (GDK_WINDOW_DESTROYED (drawable))
|
||||
return;
|
||||
|
||||
/* If no gc => no user clipping, but we need clipping
|
||||
for window emulation, so use a scratch gc */
|
||||
if (!gc)
|
||||
gc = _gdk_drawable_get_scratch_gc (drawable, FALSE);
|
||||
|
||||
BEGIN_DRAW;
|
||||
|
||||
klass = GDK_DRAWABLE_GET_CLASS (impl);
|
||||
|
||||
if (private->paint_stack)
|
||||
klass->draw_pixbuf (impl, gc, pixbuf, src_x, src_y,
|
||||
dest_x - x_offset, dest_y - y_offset,
|
||||
width, height,
|
||||
dither, x_dither - x_offset, y_dither - y_offset);
|
||||
else
|
||||
klass->draw_pixbuf (impl, gc, pixbuf, src_x, src_y,
|
||||
dest_x - x_offset, dest_y - y_offset,
|
||||
width, height,
|
||||
dither, x_dither, y_dither);
|
||||
END_DRAW;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_window_draw_trapezoids (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
|
@ -506,64 +506,6 @@ gdk_quartz_draw_lines (GdkDrawable *drawable,
|
||||
gdk_quartz_drawable_release_context (drawable, context);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_draw_pixbuf (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
GdkPixbuf *pixbuf,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dither,
|
||||
gint x_dither,
|
||||
gint y_dither)
|
||||
{
|
||||
CGContextRef context = gdk_quartz_drawable_get_context (drawable, FALSE);
|
||||
CGColorSpaceRef colorspace;
|
||||
CGDataProviderRef data_provider;
|
||||
CGImageRef image;
|
||||
void *data;
|
||||
int rowstride, pixbuf_width, pixbuf_height;
|
||||
gboolean has_alpha;
|
||||
|
||||
if (!context)
|
||||
return;
|
||||
|
||||
pixbuf_width = gdk_pixbuf_get_width (pixbuf);
|
||||
pixbuf_height = gdk_pixbuf_get_height (pixbuf);
|
||||
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
|
||||
has_alpha = gdk_pixbuf_get_has_alpha (pixbuf);
|
||||
|
||||
data = gdk_pixbuf_get_pixels (pixbuf);
|
||||
|
||||
colorspace = CGColorSpaceCreateDeviceRGB ();
|
||||
data_provider = CGDataProviderCreateWithData (NULL, data, pixbuf_height * rowstride, NULL);
|
||||
|
||||
image = CGImageCreate (pixbuf_width, pixbuf_height, 8,
|
||||
has_alpha ? 32 : 24, rowstride,
|
||||
colorspace,
|
||||
has_alpha ? kCGImageAlphaLast : 0,
|
||||
data_provider, NULL, FALSE,
|
||||
kCGRenderingIntentDefault);
|
||||
|
||||
CGDataProviderRelease (data_provider);
|
||||
CGColorSpaceRelease (colorspace);
|
||||
|
||||
_gdk_quartz_gc_update_cg_context (gc, drawable, context,
|
||||
GDK_QUARTZ_CONTEXT_STROKE);
|
||||
|
||||
CGContextClipToRect (context, CGRectMake (dest_x, dest_y, width, height));
|
||||
CGContextTranslateCTM (context, dest_x - src_x, dest_y - src_y + pixbuf_height);
|
||||
CGContextScaleCTM (context, 1, -1);
|
||||
|
||||
CGContextDrawImage (context, CGRectMake (0, 0, pixbuf_width, pixbuf_height), image);
|
||||
CGImageRelease (image);
|
||||
|
||||
gdk_quartz_drawable_release_context (drawable, context);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_draw_image (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
@ -640,7 +582,6 @@ gdk_drawable_impl_quartz_class_init (GdkDrawableImplQuartzClass *klass)
|
||||
drawable_class->draw_segments = gdk_quartz_draw_segments;
|
||||
drawable_class->draw_lines = gdk_quartz_draw_lines;
|
||||
drawable_class->draw_image = gdk_quartz_draw_image;
|
||||
drawable_class->draw_pixbuf = gdk_quartz_draw_pixbuf;
|
||||
|
||||
drawable_class->ref_cairo_surface = gdk_quartz_ref_cairo_surface;
|
||||
|
||||
|
@ -100,18 +100,6 @@ static void gdk_win32_draw_image (GdkDrawable *drawable,
|
||||
gint ydest,
|
||||
gint width,
|
||||
gint height);
|
||||
static void gdk_win32_draw_pixbuf (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
GdkPixbuf *pixbuf,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dither,
|
||||
gint x_dither,
|
||||
gint y_dither);
|
||||
|
||||
static cairo_surface_t *gdk_win32_ref_cairo_surface (GdkDrawable *drawable);
|
||||
|
||||
@ -150,7 +138,6 @@ _gdk_drawable_impl_win32_class_init (GdkDrawableImplWin32Class *klass)
|
||||
drawable_class->draw_segments = gdk_win32_draw_segments;
|
||||
drawable_class->draw_lines = gdk_win32_draw_lines;
|
||||
drawable_class->draw_image = gdk_win32_draw_image;
|
||||
drawable_class->draw_pixbuf = gdk_win32_draw_pixbuf;
|
||||
|
||||
drawable_class->ref_cairo_surface = gdk_win32_ref_cairo_surface;
|
||||
|
||||
@ -1634,27 +1621,6 @@ gdk_win32_draw_image (GdkDrawable *drawable,
|
||||
xsrc, ysrc, xdest, ydest, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_draw_pixbuf (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
GdkPixbuf *pixbuf,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dither,
|
||||
gint x_dither,
|
||||
gint y_dither)
|
||||
{
|
||||
GdkDrawable *wrapper = GDK_DRAWABLE_IMPL_WIN32 (drawable)->wrapper;
|
||||
GDK_DRAWABLE_CLASS (_gdk_drawable_impl_win32_parent_class)->draw_pixbuf (wrapper, gc, pixbuf,
|
||||
src_x, src_y, dest_x, dest_y,
|
||||
width, height,
|
||||
dither, x_dither, y_dither);
|
||||
}
|
||||
|
||||
/**
|
||||
* _gdk_win32_drawable_acquire_dc
|
||||
* @drawable: a Win32 #GdkDrawable implementation
|
||||
|
@ -101,18 +101,6 @@ static void gdk_x11_draw_image (GdkDrawable *drawable,
|
||||
gint ydest,
|
||||
gint width,
|
||||
gint height);
|
||||
static void gdk_x11_draw_pixbuf (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
GdkPixbuf *pixbuf,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dither,
|
||||
gint x_dither,
|
||||
gint y_dither);
|
||||
|
||||
static cairo_surface_t *gdk_x11_ref_cairo_surface (GdkDrawable *drawable);
|
||||
|
||||
@ -147,7 +135,6 @@ _gdk_drawable_impl_x11_class_init (GdkDrawableImplX11Class *klass)
|
||||
drawable_class->draw_segments = gdk_x11_draw_segments;
|
||||
drawable_class->draw_lines = gdk_x11_draw_lines;
|
||||
drawable_class->draw_image = gdk_x11_draw_image;
|
||||
drawable_class->draw_pixbuf = gdk_x11_draw_pixbuf;
|
||||
|
||||
drawable_class->ref_cairo_surface = gdk_x11_ref_cairo_surface;
|
||||
|
||||
@ -310,79 +297,6 @@ _gdk_x11_have_render (GdkDisplay *display)
|
||||
return x11display->have_render == GDK_YES;
|
||||
}
|
||||
|
||||
static Picture
|
||||
gdk_x11_drawable_get_picture (GdkDrawable *drawable)
|
||||
{
|
||||
GdkDrawableImplX11 *impl = GDK_DRAWABLE_IMPL_X11 (drawable);
|
||||
|
||||
if (!impl->picture)
|
||||
{
|
||||
Display *xdisplay = GDK_SCREEN_XDISPLAY (impl->screen);
|
||||
XRenderPictFormat *format;
|
||||
|
||||
GdkVisual *visual = gdk_drawable_get_visual (GDK_DRAWABLE_IMPL_X11 (drawable)->wrapper);
|
||||
if (!visual)
|
||||
return None;
|
||||
|
||||
format = XRenderFindVisualFormat (xdisplay, GDK_VISUAL_XVISUAL (visual));
|
||||
if (format)
|
||||
{
|
||||
XRenderPictureAttributes attributes;
|
||||
attributes.graphics_exposures = False;
|
||||
|
||||
impl->picture = XRenderCreatePicture (xdisplay, impl->xid, format,
|
||||
CPGraphicsExposure, &attributes);
|
||||
}
|
||||
}
|
||||
|
||||
return impl->picture;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_x11_drawable_update_picture_clip (GdkDrawable *drawable,
|
||||
GdkGC *gc)
|
||||
{
|
||||
GdkDrawableImplX11 *impl = GDK_DRAWABLE_IMPL_X11 (drawable);
|
||||
Display *xdisplay = GDK_SCREEN_XDISPLAY (impl->screen);
|
||||
Picture picture = gdk_x11_drawable_get_picture (drawable);
|
||||
cairo_region_t *clip_region = gc ? _gdk_gc_get_clip_region (gc) : NULL;
|
||||
|
||||
if (clip_region)
|
||||
{
|
||||
XRectangle *rects;
|
||||
int n_rects;
|
||||
|
||||
_gdk_region_get_xrectangles (clip_region,
|
||||
gc->clip_x_origin,
|
||||
gc->clip_y_origin,
|
||||
&rects,
|
||||
&n_rects);
|
||||
XRenderSetPictureClipRectangles (xdisplay, picture,
|
||||
0, 0, rects, n_rects);
|
||||
g_free (rects);
|
||||
}
|
||||
else
|
||||
{
|
||||
XRenderPictureAttributes pa;
|
||||
GdkBitmap *mask;
|
||||
gulong pa_mask;
|
||||
|
||||
pa_mask = CPClipMask;
|
||||
if (gc && (mask = _gdk_gc_get_clip_mask (gc)))
|
||||
{
|
||||
pa.clip_mask = GDK_PIXMAP_XID (mask);
|
||||
pa.clip_x_origin = gc->clip_x_origin;
|
||||
pa.clip_y_origin = gc->clip_y_origin;
|
||||
pa_mask |= CPClipXOrigin | CPClipYOrigin;
|
||||
}
|
||||
else
|
||||
pa.clip_mask = None;
|
||||
|
||||
XRenderChangePicture (xdisplay, picture,
|
||||
pa_mask, &pa);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
* X11 specific implementations of generic functions *
|
||||
*****************************************************/
|
||||
@ -846,137 +760,6 @@ gdk_x11_pixmap_get_drawable_impl (GdkPixmap *pixmap)
|
||||
return ((GdkPixmapObject *)pixmap)->impl;
|
||||
}
|
||||
|
||||
/* Code for accelerated alpha compositing using the RENDER extension.
|
||||
* It's a bit long because there are lots of possibilities for
|
||||
* what's the fastest depending on the available picture formats,
|
||||
* whether we can used shared pixmaps, etc.
|
||||
*/
|
||||
|
||||
static GdkX11FormatType
|
||||
select_format (GdkDisplay *display,
|
||||
XRenderPictFormat **format,
|
||||
XRenderPictFormat **mask)
|
||||
{
|
||||
Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
|
||||
XRenderPictFormat pf;
|
||||
|
||||
if (!_gdk_x11_have_render (display))
|
||||
return GDK_X11_FORMAT_NONE;
|
||||
|
||||
/* Look for a 32-bit xRGB and Axxx formats that exactly match the
|
||||
* in memory data format. We can use them as pixmap and mask
|
||||
* to deal with non-premultiplied data.
|
||||
*/
|
||||
|
||||
pf.type = PictTypeDirect;
|
||||
pf.depth = 32;
|
||||
pf.direct.redMask = 0xff;
|
||||
pf.direct.greenMask = 0xff;
|
||||
pf.direct.blueMask = 0xff;
|
||||
|
||||
pf.direct.alphaMask = 0;
|
||||
if (ImageByteOrder (xdisplay) == LSBFirst)
|
||||
{
|
||||
/* ABGR */
|
||||
pf.direct.red = 0;
|
||||
pf.direct.green = 8;
|
||||
pf.direct.blue = 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* RGBA */
|
||||
pf.direct.red = 24;
|
||||
pf.direct.green = 16;
|
||||
pf.direct.blue = 8;
|
||||
}
|
||||
|
||||
*format = XRenderFindFormat (xdisplay,
|
||||
(PictFormatType | PictFormatDepth |
|
||||
PictFormatRedMask | PictFormatRed |
|
||||
PictFormatGreenMask | PictFormatGreen |
|
||||
PictFormatBlueMask | PictFormatBlue |
|
||||
PictFormatAlphaMask),
|
||||
&pf,
|
||||
0);
|
||||
|
||||
pf.direct.alphaMask = 0xff;
|
||||
if (ImageByteOrder (xdisplay) == LSBFirst)
|
||||
{
|
||||
/* ABGR */
|
||||
pf.direct.alpha = 24;
|
||||
}
|
||||
else
|
||||
{
|
||||
pf.direct.alpha = 0;
|
||||
}
|
||||
|
||||
*mask = XRenderFindFormat (xdisplay,
|
||||
(PictFormatType | PictFormatDepth |
|
||||
PictFormatAlphaMask | PictFormatAlpha),
|
||||
&pf,
|
||||
0);
|
||||
|
||||
if (*format && *mask)
|
||||
return GDK_X11_FORMAT_EXACT_MASK;
|
||||
|
||||
/* OK, that failed, now look for xRGB and Axxx formats in
|
||||
* RENDER's preferred order
|
||||
*/
|
||||
pf.direct.alphaMask = 0;
|
||||
/* ARGB */
|
||||
pf.direct.red = 16;
|
||||
pf.direct.green = 8;
|
||||
pf.direct.blue = 0;
|
||||
|
||||
*format = XRenderFindFormat (xdisplay,
|
||||
(PictFormatType | PictFormatDepth |
|
||||
PictFormatRedMask | PictFormatRed |
|
||||
PictFormatGreenMask | PictFormatGreen |
|
||||
PictFormatBlueMask | PictFormatBlue |
|
||||
PictFormatAlphaMask),
|
||||
&pf,
|
||||
0);
|
||||
|
||||
pf.direct.alphaMask = 0xff;
|
||||
pf.direct.alpha = 24;
|
||||
|
||||
*mask = XRenderFindFormat (xdisplay,
|
||||
(PictFormatType | PictFormatDepth |
|
||||
PictFormatAlphaMask | PictFormatAlpha),
|
||||
&pf,
|
||||
0);
|
||||
|
||||
if (*format && *mask)
|
||||
return GDK_X11_FORMAT_ARGB_MASK;
|
||||
|
||||
/* Finally, if neither of the above worked, fall back to
|
||||
* looking for combined ARGB -- we'll premultiply ourselves.
|
||||
*/
|
||||
|
||||
pf.type = PictTypeDirect;
|
||||
pf.depth = 32;
|
||||
pf.direct.red = 16;
|
||||
pf.direct.green = 8;
|
||||
pf.direct.blue = 0;
|
||||
pf.direct.alphaMask = 0xff;
|
||||
pf.direct.alpha = 24;
|
||||
|
||||
*format = XRenderFindFormat (xdisplay,
|
||||
(PictFormatType | PictFormatDepth |
|
||||
PictFormatRedMask | PictFormatRed |
|
||||
PictFormatGreenMask | PictFormatGreen |
|
||||
PictFormatBlueMask | PictFormatBlue |
|
||||
PictFormatAlphaMask | PictFormatAlpha),
|
||||
&pf,
|
||||
0);
|
||||
*mask = NULL;
|
||||
|
||||
if (*format)
|
||||
return GDK_X11_FORMAT_ARGB;
|
||||
|
||||
return GDK_X11_FORMAT_NONE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
list_formats (XRenderPictFormat *pf)
|
||||
@ -1149,260 +932,6 @@ _gdk_x11_convert_to_format (guchar *src_buf,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
draw_with_images (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
GdkX11FormatType format_type,
|
||||
XRenderPictFormat *format,
|
||||
XRenderPictFormat *mask_format,
|
||||
guchar *src_rgb,
|
||||
gint src_rowstride,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
GdkScreen *screen = GDK_DRAWABLE_IMPL_X11 (drawable)->screen;
|
||||
Display *xdisplay = GDK_SCREEN_XDISPLAY (screen);
|
||||
GdkImage *image;
|
||||
GdkPixmap *pix;
|
||||
GdkGC *pix_gc;
|
||||
Picture pict;
|
||||
Picture dest_pict;
|
||||
Picture mask = None;
|
||||
gint x0, y0;
|
||||
|
||||
pix = gdk_pixmap_new (gdk_screen_get_root_window (screen), width, height, 32);
|
||||
|
||||
pict = XRenderCreatePicture (xdisplay,
|
||||
GDK_PIXMAP_XID (pix),
|
||||
format, 0, NULL);
|
||||
if (mask_format)
|
||||
mask = XRenderCreatePicture (xdisplay,
|
||||
GDK_PIXMAP_XID (pix),
|
||||
mask_format, 0, NULL);
|
||||
|
||||
dest_pict = gdk_x11_drawable_get_picture (drawable);
|
||||
|
||||
pix_gc = _gdk_drawable_get_scratch_gc (pix, FALSE);
|
||||
|
||||
for (y0 = 0; y0 < height; y0 += GDK_SCRATCH_IMAGE_HEIGHT)
|
||||
{
|
||||
gint height1 = MIN (height - y0, GDK_SCRATCH_IMAGE_HEIGHT);
|
||||
for (x0 = 0; x0 < width; x0 += GDK_SCRATCH_IMAGE_WIDTH)
|
||||
{
|
||||
gint xs0, ys0;
|
||||
|
||||
gint width1 = MIN (width - x0, GDK_SCRATCH_IMAGE_WIDTH);
|
||||
|
||||
image = _gdk_image_get_scratch (screen, width1, height1, 32, &xs0, &ys0);
|
||||
|
||||
_gdk_x11_convert_to_format (src_rgb + y0 * src_rowstride + 4 * x0, src_rowstride,
|
||||
(guchar *)image->mem + ys0 * image->bpl + xs0 * image->bpp, image->bpl,
|
||||
format_type, image->byte_order,
|
||||
width1, height1);
|
||||
|
||||
gdk_draw_image (pix, pix_gc,
|
||||
image, xs0, ys0, x0, y0, width1, height1);
|
||||
}
|
||||
}
|
||||
|
||||
XRenderComposite (xdisplay, PictOpOver, pict, mask, dest_pict,
|
||||
0, 0, 0, 0, dest_x, dest_y, width, height);
|
||||
|
||||
XRenderFreePicture (xdisplay, pict);
|
||||
if (mask)
|
||||
XRenderFreePicture (xdisplay, mask);
|
||||
|
||||
g_object_unref (pix);
|
||||
}
|
||||
|
||||
typedef struct _ShmPixmapInfo ShmPixmapInfo;
|
||||
|
||||
struct _ShmPixmapInfo
|
||||
{
|
||||
Display *display;
|
||||
Pixmap pix;
|
||||
Picture pict;
|
||||
Picture mask;
|
||||
};
|
||||
|
||||
static void
|
||||
shm_pixmap_info_destroy (gpointer data)
|
||||
{
|
||||
ShmPixmapInfo *info = data;
|
||||
|
||||
if (info->pict != None)
|
||||
XRenderFreePicture (info->display, info->pict);
|
||||
if (info->mask != None)
|
||||
XRenderFreePicture (info->display, info->mask);
|
||||
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
|
||||
/* Returns FALSE if we can't get a shm pixmap */
|
||||
static gboolean
|
||||
get_shm_pixmap_for_image (Display *xdisplay,
|
||||
GdkImage *image,
|
||||
XRenderPictFormat *format,
|
||||
XRenderPictFormat *mask_format,
|
||||
Pixmap *pix,
|
||||
Picture *pict,
|
||||
Picture *mask)
|
||||
{
|
||||
ShmPixmapInfo *info;
|
||||
|
||||
if (image->type != GDK_IMAGE_SHARED)
|
||||
return FALSE;
|
||||
|
||||
info = g_object_get_data (G_OBJECT (image), "gdk-x11-shm-pixmap");
|
||||
if (!info)
|
||||
{
|
||||
*pix = _gdk_x11_image_get_shm_pixmap (image);
|
||||
|
||||
if (!*pix)
|
||||
return FALSE;
|
||||
|
||||
info = g_new (ShmPixmapInfo, 1);
|
||||
info->display = xdisplay;
|
||||
info->pix = *pix;
|
||||
|
||||
info->pict = XRenderCreatePicture (xdisplay, info->pix,
|
||||
format, 0, NULL);
|
||||
if (mask_format)
|
||||
info->mask = XRenderCreatePicture (xdisplay, info->pix,
|
||||
mask_format, 0, NULL);
|
||||
else
|
||||
info->mask = None;
|
||||
|
||||
g_object_set_data_full (G_OBJECT (image), "gdk-x11-shm-pixmap", info,
|
||||
shm_pixmap_info_destroy);
|
||||
}
|
||||
|
||||
*pix = info->pix;
|
||||
*pict = info->pict;
|
||||
*mask = info->mask;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#ifdef USE_SHM
|
||||
/* Returns FALSE if drawing with ShmPixmaps is not possible */
|
||||
static gboolean
|
||||
draw_with_pixmaps (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
GdkX11FormatType format_type,
|
||||
XRenderPictFormat *format,
|
||||
XRenderPictFormat *mask_format,
|
||||
guchar *src_rgb,
|
||||
gint src_rowstride,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
Display *xdisplay = GDK_SCREEN_XDISPLAY (GDK_DRAWABLE_IMPL_X11 (drawable)->screen);
|
||||
GdkImage *image;
|
||||
Pixmap pix;
|
||||
Picture pict;
|
||||
Picture dest_pict;
|
||||
Picture mask = None;
|
||||
gint x0, y0;
|
||||
|
||||
dest_pict = gdk_x11_drawable_get_picture (drawable);
|
||||
|
||||
for (y0 = 0; y0 < height; y0 += GDK_SCRATCH_IMAGE_HEIGHT)
|
||||
{
|
||||
gint height1 = MIN (height - y0, GDK_SCRATCH_IMAGE_HEIGHT);
|
||||
for (x0 = 0; x0 < width; x0 += GDK_SCRATCH_IMAGE_WIDTH)
|
||||
{
|
||||
gint xs0, ys0;
|
||||
|
||||
gint width1 = MIN (width - x0, GDK_SCRATCH_IMAGE_WIDTH);
|
||||
|
||||
image = _gdk_image_get_scratch (GDK_DRAWABLE_IMPL_X11 (drawable)->screen,
|
||||
width1, height1, 32, &xs0, &ys0);
|
||||
if (!get_shm_pixmap_for_image (xdisplay, image, format, mask_format, &pix, &pict, &mask))
|
||||
return FALSE;
|
||||
|
||||
_gdk_x11_convert_to_format (src_rgb + y0 * src_rowstride + 4 * x0, src_rowstride,
|
||||
(guchar *)image->mem + ys0 * image->bpl + xs0 * image->bpp, image->bpl,
|
||||
format_type, image->byte_order,
|
||||
width1, height1);
|
||||
|
||||
XRenderComposite (xdisplay, PictOpOver, pict, mask, dest_pict,
|
||||
xs0, ys0, xs0, ys0, x0 + dest_x, y0 + dest_y,
|
||||
width1, height1);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
gdk_x11_draw_pixbuf (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
GdkPixbuf *pixbuf,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint dest_x,
|
||||
gint dest_y,
|
||||
gint width,
|
||||
gint height,
|
||||
GdkRgbDither dither,
|
||||
gint x_dither,
|
||||
gint y_dither)
|
||||
{
|
||||
GdkX11FormatType format_type;
|
||||
XRenderPictFormat *format, *mask_format;
|
||||
gint rowstride;
|
||||
#ifdef USE_SHM
|
||||
gboolean use_pixmaps = TRUE;
|
||||
#endif /* USE_SHM */
|
||||
|
||||
format_type = select_format (gdk_drawable_get_display (drawable),
|
||||
&format, &mask_format);
|
||||
|
||||
if (format_type == GDK_X11_FORMAT_NONE ||
|
||||
!gdk_pixbuf_get_has_alpha (pixbuf) ||
|
||||
gdk_drawable_get_depth (drawable) == 1 ||
|
||||
(dither == GDK_RGB_DITHER_MAX && gdk_drawable_get_depth (drawable) != 24) ||
|
||||
gdk_x11_drawable_get_picture (drawable) == None)
|
||||
{
|
||||
GdkDrawable *wrapper = GDK_DRAWABLE_IMPL_X11 (drawable)->wrapper;
|
||||
GDK_DRAWABLE_CLASS (_gdk_drawable_impl_x11_parent_class)->draw_pixbuf (wrapper, gc, pixbuf,
|
||||
src_x, src_y, dest_x, dest_y,
|
||||
width, height,
|
||||
dither, x_dither, y_dither);
|
||||
return;
|
||||
}
|
||||
|
||||
gdk_x11_drawable_update_picture_clip (drawable, gc);
|
||||
|
||||
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
|
||||
|
||||
#ifdef USE_SHM
|
||||
if (use_pixmaps)
|
||||
{
|
||||
if (!draw_with_pixmaps (drawable, gc,
|
||||
format_type, format, mask_format,
|
||||
gdk_pixbuf_get_pixels (pixbuf) + src_y * rowstride + src_x * 4,
|
||||
rowstride,
|
||||
dest_x, dest_y, width, height))
|
||||
use_pixmaps = FALSE;
|
||||
}
|
||||
|
||||
if (!use_pixmaps)
|
||||
#endif /* USE_SHM */
|
||||
draw_with_images (drawable, gc,
|
||||
format_type, format, mask_format,
|
||||
gdk_pixbuf_get_pixels (pixbuf) + src_y * rowstride + src_x * 4,
|
||||
rowstride,
|
||||
dest_x, dest_y, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_x11_cairo_surface_destroy (void *data)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user