Home | History | Annotate | Download | only in patches
      1  10827      jedy diff -Nrup cairo-1.2.4-old/src/cairo-xlib-surface.c cairo-1.2.4/src/cairo-xlib-surface.c
      2  10827      jedy --- cairo-1.2.4-old/src/cairo-xlib-surface.c	2007-03-09 11:11:09.769585000 +0800
      3  10827      jedy +++ cairo-1.2.4/src/cairo-xlib-surface.c	2007-03-09 11:10:13.642282000 +0800
      4   9346   erwannc @@ -81,6 +81,8 @@ _cairo_xlib_surface_show_glyphs (void   
      5   8386   erwannc  
      6   8386   erwannc  #define CAIRO_ASSUME_PIXMAP	20
      7   8386   erwannc  
      8   8386   erwannc +struct clut_r3g3b2;
      9   8386   erwannc +
     10   8386   erwannc  struct _cairo_xlib_surface {
     11   8386   erwannc      cairo_surface_t base;
     12   8386   erwannc  
     13   9346   erwannc @@ -126,6 +128,9 @@ struct _cairo_xlib_surface {
     14   8386   erwannc      int num_clip_rects;
     15   8386   erwannc  
     16   8663  dc144907      XRenderPictFormat *xrender_format;
     17   8386   erwannc +
     18   8386   erwannc +    struct clut_r3g3b2 *clut;
     19   8386   erwannc +    int workaround;
     20   8386   erwannc  };
     21   8386   erwannc  
     22   8386   erwannc  #define CAIRO_SURFACE_RENDER_AT_LEAST(surface, major, minor)	\
     23   9346   erwannc @@ -504,6 +509,158 @@ _swap_ximage_to_native (XImage *ximage)
     24   8386   erwannc      }
     25   8386   erwannc  }
     26   8386   erwannc  
     27   8386   erwannc +#if 0
     28   8386   erwannc +static void _set_optimal_cmap(Display *dpy, Colormap cmap) {
     29   8386   erwannc +    int i, r, g, b;
     30   8386   erwannc +    XColor cm[256];
     31   8386   erwannc +
     32   8386   erwannc +    for (i = 0; i < 256; i++) {
     33   8386   erwannc +	r = i >> 5;
     34   8386   erwannc +	g = (i >> 2) & 0x7;
     35   8386   erwannc +	b = (i << 1) & 0x7;
     36   8386   erwannc +	cm[i].pixel = i;
     37   8386   erwannc +	cm[i].flags = DoRed | DoGreen | DoBlue;
     38   8386   erwannc +	cm[i].red   = r << 13 | r << 10 | r << 7 | r << 4 | r << 1 | r >> 2;
     39   8386   erwannc +	cm[i].green = g << 13 | g << 10 | g << 7 | g << 4 | g << 1 | g >> 2;
     40   8386   erwannc +	cm[i].blue  = b << 13 | b << 10 | b << 7 | b << 4 | b << 1 | b >> 2;
     41   8386   erwannc +    }
     42   8386   erwannc +    XStoreColors(dpy, cmap, cm, 256);
     43   8386   erwannc +}
     44   8386   erwannc +#endif
     45   8386   erwannc +
     46   8386   erwannc +struct clut_r3g3b2 {
     47   8386   erwannc +    struct clut_r3g3b2 *next;
     48   8386   erwannc +    Display            *dpy;
     49   8386   erwannc +    Colormap           cmap;
     50   8386   erwannc +    uint32_t           clut[256];
     51   8386   erwannc +    unsigned char      ilut[256];
     52   8386   erwannc +};
     53   8386   erwannc +
     54   8386   erwannc +static struct clut_r3g3b2 * _get_clut_r3g3b2(Display *dpy, Colormap cmap) {
     55   8386   erwannc +    static struct clut_r3g3b2 *first = NULL;
     56   8386   erwannc +    int i,j, min, d;
     57   8386   erwannc +    struct clut_r3g3b2 *clut;
     58   8386   erwannc +    unsigned char r,g,b, r2,g2,b2;
     59   8386   erwannc +    
     60   8386   erwannc +    clut = first;
     61   8386   erwannc +    while(clut) {
     62   8386   erwannc +	if ( clut->dpy == dpy && clut->cmap == cmap )
     63   8386   erwannc +	    return clut;
     64   8386   erwannc +	clut = clut->next;
     65   8386   erwannc +    }
     66   8386   erwannc +    
     67   8386   erwannc +    clut = calloc(1, sizeof(*clut));
     68   8386   erwannc +    if(clut == NULL)
     69   8386   erwannc +	return NULL;
     70   8386   erwannc +    
     71   8386   erwannc +    clut->next = first;
     72   8386   erwannc +    clut->dpy = dpy;
     73   8386   erwannc +    clut->cmap = cmap;
     74   8386   erwannc +    first = clut;
     75   8386   erwannc +
     76   8386   erwannc +    /* Construct the clut from Colormap */
     77   8386   erwannc +    for (i = 0; i < 256; i++) {
     78   8386   erwannc +	XColor xcol;
     79   8386   erwannc +	xcol.pixel = i;
     80   8386   erwannc +	XQueryColor(dpy, cmap, &xcol);
     81   8386   erwannc +	clut->clut[i] = ( ( ((uint32_t)xcol.red   & 0xff00 ) << 8) |
     82   8386   erwannc +			  ( ((uint32_t)xcol.green & 0xff00 ) ) |
     83   8386   erwannc +			  ( ((uint32_t)xcol.blue  & 0xff00 ) >> 8) );
     84   8386   erwannc +    }
     85   8386   erwannc +    /*
     86   8386   erwannc +      
     87   8386   erwannc +    Find the best matching color in the colormap for all r3g3b2
     88   8386   erwannc +    values. The distance is maybe not perceptively valid, but it
     89   8386   erwannc +    should not be too bad.
     90   8386   erwannc +    
     91   8386   erwannc +    */
     92   8386   erwannc +    for (i = 0; i < 256; i++) {
     93   8386   erwannc +	r = i >> 5;
     94   8386   erwannc +	g = (i >> 2) & 0x7;
     95   8386   erwannc +	b = (i << 1) & 0x7;
     96   8386   erwannc +	min = 255;
     97   8386   erwannc +	for(j = 0; j < 256; j++) {
     98   8386   erwannc +	    r2 = (clut->clut[j] & 0xff0000) >> 21;
     99   8386   erwannc +	    g2 = (clut->clut[j] & 0x00ff00) >> 13;
    100   8386   erwannc +	    b2 = (clut->clut[j] & 0x0000ff) >> 5;
    101   8386   erwannc +	    if ( r2 == r && g2 == g && (b2 & 0x6) == b ) {
    102   8386   erwannc +		clut->ilut[i] = j;
    103   8386   erwannc +		break;
    104   8386   erwannc +	    }
    105   8386   erwannc +	    /*
    106   8386   erwannc +	      Squares make higher bits much more important than lower
    107   8386   erwannc +	      ones.
    108   8386   erwannc +	    */
    109   8386   erwannc +	    d  = (r2 ^ r) * (r2 ^ r);
    110   8386   erwannc +	    d += (g2 ^ g) * (g2 ^ g);
    111   8386   erwannc +	    d += (b2 ^ b) * (b2 ^ b);
    112   8386   erwannc +	    if(d < min) {
    113   8386   erwannc +		clut->ilut[i] = j;
    114   8386   erwannc +		min = d;
    115   8386   erwannc +	    }
    116   8386   erwannc +	}
    117   8386   erwannc +    }
    118   8386   erwannc +    
    119   8386   erwannc +    return clut;
    120   8386   erwannc +}
    121   8386   erwannc +
    122   8386   erwannc +static const char * _visualClass[] = {
    123   8386   erwannc +    "StaticGray",
    124   8386   erwannc +    "GrayScale",
    125   8386   erwannc +    "StaticColor",
    126   8386   erwannc +    "PseudoColor",
    127   8386   erwannc +    "TrueColor",
    128   8386   erwannc +    "DirectColor"
    129   8386   erwannc +};
    130   8386   erwannc +
    131   8386   erwannc +
    132   8386   erwannc +static void _print_visual(Visual *v) {
    133   8386   erwannc +    printf("Visual: class=%s, bpRGB=%i, CM=%i, r=%lx, g=%lx, b=%lx\n",
    134   8386   erwannc +	   _visualClass[v->class],
    135   8386   erwannc +	   v->bits_per_rgb,
    136   8386   erwannc +	   v->map_entries,
    137   8386   erwannc +	   v->red_mask, v->green_mask, v->blue_mask);
    138   8386   erwannc +}
    139   8386   erwannc +
    140   8386   erwannc +
    141   8386   erwannc +#if 0
    142   8386   erwannc +static void _print_ximage(XImage *x) {
    143   8386   erwannc +    const char * format[] = { "XYBitmap", "XYPixmap", "ZPixmap" };
    144   8386   erwannc +    printf("XImage: size=(%i,%i), xoffset=%i, format=%s, depth=%i, bpp=%i, stride=%i\n        r=%lx, g=%lx, b=%lx, unit=%i, pad=%i\n",
    145   8386   erwannc +	   x->width,
    146   8386   erwannc +	   x->height,
    147   8386   erwannc +	   x->xoffset,
    148   8386   erwannc +	   format[x->format],
    149   8386   erwannc +	   x->depth,
    150   8386   erwannc +	   x->bits_per_pixel,
    151   8386   erwannc +	   x->bytes_per_line,
    152   8386   erwannc +	   x->red_mask, x->green_mask, x->blue_mask,
    153   8386   erwannc +	   x->bitmap_unit, x->bitmap_pad);
    154   8386   erwannc +}
    155   8386   erwannc +
    156   8386   erwannc +const char * _cairoFormats[] = { "ARGB32", "RGB24", "A8", "A1" };
    157   8386   erwannc +
    158   8386   erwannc +static void _print_cairoimage(cairo_image_surface_t *i) {
    159   8386   erwannc +    
    160   8386   erwannc +    printf("CairoImage: size=(%i,%i), format=%s, depth=%i, stride=%i\n",
    161   8386   erwannc +	   i->width,
    162   8386   erwannc +	   i->height,
    163   8386   erwannc +	   _cairoFormats[i->format],
    164   8386   erwannc +	   i->depth,
    165   8386   erwannc +	   i->stride);
    166   8386   erwannc +}
    167   8386   erwannc +
    168   8386   erwannc +static void _print_cairomasks(cairo_format_masks_t *m) {
    169   8386   erwannc +    printf("CairoFormatMask: bpp=%i, a=%lx, r=%lx, g=%lx, b=%lx\n",
    170   8386   erwannc +	   m->bpp, m->alpha_mask, m->red_mask, m->green_mask, m->blue_mask);
    171   8386   erwannc +}
    172   8386   erwannc +#endif
    173   8386   erwannc +
    174   8386   erwannc +#define WORKAROUND_NONE           0
    175   8386   erwannc +#define WORKAROUND_8BIT_GRAYLEVEL 1
    176   8386   erwannc +#define WORKAROUND_8BIT_PALETTE   2
    177   8386   erwannc +#define WORKAROUND_R5G6B5         3
    178   8386   erwannc +
    179   8386   erwannc  static cairo_status_t
    180   9346   erwannc  _get_image_surface (cairo_xlib_surface_t    *surface,
    181   9346   erwannc  		    cairo_rectangle_int16_t *interest_rect,
    182   9346   erwannc @@ -657,20 +814,127 @@ _get_image_surface (cairo_xlib_surface_t
    183   8386   erwannc      }
    184   8386   erwannc      else
    185   8386   erwannc      {
    186   8663  dc144907 +       /*
    187   8663  dc144907 +        * Otherwise, we construct a buffer containing RGB24 data
    188   8663  dc144907 +        * using the specified workaround.
    189   8663  dc144907 +        */
    190   8663  dc144907 +       uint32_t *data, *dst, *clut;
    191   8663  dc144907 +       uint8_t  *src8;
    192   8663  dc144907 +       uint16_t *src16;
    193   8663  dc144907 +       int i,j;
    194   8386   erwannc +
    195   8663  dc144907 +       if(surface->visual == NULL) {
    196   8663  dc144907 +           printf("No visual for surface\n");
    197   8663  dc144907 +           goto FAIL;
    198   8663  dc144907 +       }
    199   8663  dc144907 +
    200   8663  dc144907 +       if (surface->workaround == WORKAROUND_NONE) {
    201   9346   erwannc +         /*printf("No workaround for this pixel format: ");
    202   8663  dc144907 +           _print_visual(surface->visual);
    203   8663  dc144907 +           goto FAIL;*/
    204   8663  dc144907  	/*
    205   8663  dc144907  	 * XXX This can't work.  We must convert the data to one of the
    206   8438   erwannc  	 * supported pixman formats.  Pixman needs another function
    207   8438   erwannc  	 * which takes data in an arbitrary format and converts it
    208   8438   erwannc  	 * to something supported by that library.
    209   8438   erwannc  	 */
    210   8663  dc144907 -	image = (cairo_image_surface_t*)
    211   8386   erwannc -	    _cairo_image_surface_create_with_masks ((unsigned char *) ximage->data,
    212   8386   erwannc -						    &masks,
    213   8663  dc144907 -						    ximage->width,
    214   8386   erwannc -						    ximage->height,
    215   8386   erwannc -						    ximage->bytes_per_line);
    216   8386   erwannc -	if (image->base.status)
    217   8663  dc144907 -	    goto FAIL;
    218   8663  dc144907 +         image = (cairo_image_surface_t*) _cairo_image_surface_create_with_masks ((unsigned char *) ximage->data,
    219   8663  dc144907 +                       &masks,
    220   8663  dc144907 +                       ximage->width,
    221   8663  dc144907 +                       ximage->height,
    222   8663  dc144907 +                       ximage->bytes_per_line);
    223   8386   erwannc +
    224   8663  dc144907 +         if (image->base.status)
    225   8663  dc144907 +           goto FAIL;
    226   8663  dc144907 +         /* Let the surface take ownership of the data */
    227   8663  dc144907 +         _cairo_image_surface_assume_ownership_of_data (image);
    228   8663  dc144907 +         ximage->data = NULL;
    229   8663  dc144907 +         XDestroyImage (ximage);
    230   8386   erwannc +
    231   8663  dc144907 +         *image_out = image;
    232   8663  dc144907 +         return CAIRO_STATUS_SUCCESS;
    233   8663  dc144907 +       }
    234   8386   erwannc +
    235   8663  dc144907 +       data = (uint32_t*)malloc(ximage->height * ximage->width * 4);
    236   8663  dc144907 +       if(data == NULL) {
    237   8663  dc144907 +           printf("Cannot allocate RGB buffer\n");
    238   8663  dc144907 +           goto FAIL;
    239   8663  dc144907 +       }
    240   8386   erwannc +
    241   8663  dc144907 +       switch (surface->workaround) {
    242   8386   erwannc +
    243   8663  dc144907 +       case WORKAROUND_8BIT_GRAYLEVEL:
    244   8438   erwannc +
    245   8663  dc144907 +           dst = data;
    246   8663  dc144907 +           for(j = 0; j < ximage->height; j++) {
    247   8663  dc144907 +               src8 = (uint8_t *) (ximage->data + ximage->bytes_per_line * j);
    248   8663  dc144907 +               for(i = 0; i < ximage->width; i++) {
    249   8663  dc144907 +                   *dst++ = (*src8 << 16) | (*src8 << 8) | *src8;
    250   8663  dc144907 +                   src8++;
    251   8663  dc144907 +               }
    252   8663  dc144907 +           }
    253   8663  dc144907 +           break;
    254   8547   erwannc +
    255   8663  dc144907 +       case WORKAROUND_8BIT_PALETTE:
    256   8547   erwannc +
    257   8663  dc144907 +           if(surface->clut == NULL) {
    258   8663  dc144907 +               surface->clut = _get_clut_r3g3b2(
    259   8663  dc144907 +                   surface->dpy,
    260   8663  dc144907 +                   DefaultColormapOfScreen(surface->screen));
    261   8663  dc144907 +           }
    262   8547   erwannc +
    263   8663  dc144907 +           if(surface->clut == NULL) {
    264   8663  dc144907 +               free(data);
    265   8663  dc144907 +               goto FAIL;
    266   8663  dc144907 +           }
    267   8547   erwannc +
    268   8663  dc144907 +           clut = surface->clut->clut;
    269   8663  dc144907 +           src8 = (uint8_t*) ximage->data;
    270   8663  dc144907 +           dst = data;
    271   8663  dc144907 +           for(j = 0; j < ximage->height; j++) {
    272   8663  dc144907 +               for(i = 0; i < ximage->width; i++)
    273   8663  dc144907 +                   *dst++ = clut[src8[i]];
    274   8663  dc144907 +               src8 += ximage->bytes_per_line;
    275   8663  dc144907 +           }
    276   8663  dc144907 +           break;
    277   8547   erwannc +
    278   8663  dc144907 +       case WORKAROUND_R5G6B5:
    279   8547   erwannc +
    280   8663  dc144907 +           src16 = (uint16_t*)ximage->data;
    281   8663  dc144907 +           dst = data;
    282   8663  dc144907 +           for(j = 0; j < ximage->height; j++) {
    283   8663  dc144907 +               for(i = 0; i < ximage->width; i++) {
    284   8663  dc144907 +                              *dst++ = ( ( ((src16[i] & 0xf800) << 8) | ((src16[i] & 0xe000) << 3) ) |
    285   8663  dc144907 +                              ( ((src16[i] & 0x07e0) << 5) | ((src16[i] & 0x0600) >> 1) ) |
    286   8663  dc144907 +                              ( ((src16[i] & 0x001f) << 3) | ((src16[i] & 0x001f) >> 2) ) );
    287   8663  dc144907 +               }
    288   8663  dc144907 +               src16 += ximage->bytes_per_line / sizeof(*src16);
    289   8663  dc144907 +           }
    290   8663  dc144907 +           break;
    291   8547   erwannc +
    292   8663  dc144907 +       default:
    293   8663  dc144907 +           printf("Dunno what to do with: ");
    294   8663  dc144907 +           _print_visual(surface->visual);
    295   8663  dc144907 +           goto FAIL;
    296   8663  dc144907 +       }
    297   8663  dc144907 +       free(ximage->data);
    298   8663  dc144907 +        image = (cairo_image_surface_t*)
    299   8663  dc144907 +        cairo_image_surface_create_for_data((unsigned char *)data, CAIRO_FORMAT_RGB24, ximage->width, ximage->height, ximage->width*4);
    300   8547   erwannc +
    301   8663  dc144907 +       if (image->base.status) {
    302   8663  dc144907 +           printf("Failed!\n");
    303   8663  dc144907 +           free(data);
    304   8663  dc144907 +           goto FAIL;
    305   8663  dc144907 +       }
    306   8547   erwannc +
    307   8663  dc144907 +        cairo_image_surface_create_for_data((unsigned char *)data, CAIRO_FORMAT_RGB24, ximage->width, ximage->height, ximage->width*4);
    308   8547   erwannc +
    309   8663  dc144907 +       if (image->base.status) {
    310   8663  dc144907 +           printf("Failed!\n");
    311   8663  dc144907 +           free(data);
    312   8663  dc144907 +            goto FAIL;
    313   8663  dc144907 +       }
    314   8547   erwannc +
    315   8547   erwannc      }
    316   8547   erwannc  
    317   8547   erwannc      /* Let the surface take ownership of the data */
    318  10827      jedy @@ -743,29 +1007,139 @@ _cairo_xlib_surface_ensure_gc (cairo_xli
    319   8547   erwannc      _cairo_xlib_surface_set_gc_clip_rects (surface);
    320   8547   erwannc  }
    321   8547   erwannc  
    322   8547   erwannc +static int
    323   8547   erwannc +make_space_for(unsigned char ** buf, int *size, int *stride, int width, int height, int Bpp) {
    324   8547   erwannc +    unsigned char * data;
    325   8547   erwannc +    int l;
    326   8547   erwannc +
    327   8547   erwannc +    *stride = width * Bpp;
    328   8547   erwannc +    if(*stride%4)
    329   8955  dc144907 +        *stride += 4 - *stride % 4;
    330   8547   erwannc +    l = (*stride * height);
    331   8547   erwannc +    if (*size < l) {
    332   8955  dc144907 +        if(*buf)
    333   8955  dc144907 +            data = realloc(*buf, l);
    334   8955  dc144907 +        else
    335   8955  dc144907 +            data = malloc(l);
    336   8955  dc144907 +        if(data) {
    337   8955  dc144907 +            *buf = data;
    338   8955  dc144907 +            *size = l;
    339   8955  dc144907 +        } else {
    340   8955  dc144907 +            return -1;
    341   8955  dc144907 +        }
    342   8663  dc144907 +    }
    343   8547   erwannc +    return 0;
    344   8547   erwannc +}
    345   8547   erwannc +
    346   8547   erwannc  static cairo_status_t
    347   8547   erwannc  _draw_image_surface (cairo_xlib_surface_t   *surface,
    348   8547   erwannc  		     cairo_image_surface_t  *image,
    349   8547   erwannc  		     int                    dst_x,
    350   8547   erwannc  		     int                    dst_y)
    351   8547   erwannc  {
    352   8547   erwannc +    static unsigned char *buf = NULL;
    353   8547   erwannc +    static int size = 0;
    354   8547   erwannc      XImage ximage;
    355   8955  dc144907 -    unsigned int bpp, alpha, red, green, blue;
    356   8955  dc144907 +    unsigned int bpp, alpha, red, green, blue, stride, depth, i, j;
    357   8547   erwannc +    unsigned char *data, *c, *ilut;
    358   8547   erwannc +    uint32_t *src;
    359   8547   erwannc +    uint8_t *dst8;
    360   8547   erwannc +    uint16_t *dst16;
    361   8547   erwannc      int native_byte_order = _native_byte_order_lsb () ? LSBFirst : MSBFirst;
    362   8663  dc144907  
    363   8547   erwannc      pixman_format_get_masks (pixman_image_get_format (image->pixman_image),
    364   8547   erwannc  			     &bpp, &alpha, &red, &green, &blue);
    365   8663  dc144907  
    366   8547   erwannc +    switch(surface->workaround) {
    367   8547   erwannc +    case WORKAROUND_NONE:
    368   8955  dc144907 +        /* Default behaviour is supposed to work */
    369   8955  dc144907 +        stride = image->stride;
    370   8955  dc144907 +        depth = image->depth;
    371   8955  dc144907 +        data = image->data;
    372   8955  dc144907 +        break;
    373   8547   erwannc +
    374   8547   erwannc +    case WORKAROUND_8BIT_GRAYLEVEL:
    375   8547   erwannc +
    376   8955  dc144907 +        if (make_space_for(&buf, &size, &stride, image->width, image->height, 1))
    377   8955  dc144907 +            return CAIRO_STATUS_NO_MEMORY;
    378   8955  dc144907 +        data = buf;
    379   8663  dc144907 +
    380   8663  dc144907 +       for(j=0;j<image->height;j++) {
    381   8955  dc144907 +            src = image->data;
    382   8955  dc144907 +            dst8 = data + j * stride;
    383   8955  dc144907 +            for(i=0;i<image->width;i++) {
    384   8955  dc144907 +                /* XXX use correct factor for each channel */
    385   8955  dc144907 +                dst8[i] = ( ((*src >> 16) & 0xff) +
    386   8955  dc144907 +                            ((*src >> 8) & 0xff) +
    387   8955  dc144907 +                            (*src & 0xff) ) / 3;
    388   8955  dc144907 +                src++;
    389   8955  dc144907 +            }
    390   8955  dc144907 +        }
    391   8663  dc144907 +
    392   8955  dc144907 +        alpha = red = green = blue = 0;
    393   8955  dc144907 +        depth = bpp = 8;
    394   8955  dc144907 +        break;
    395   8663  dc144907 +
    396   8547   erwannc +    case WORKAROUND_8BIT_PALETTE:
    397   8663  dc144907 +
    398  10827      jedy +        if(surface->clut == NULL) {
    399  10827      jedy +           surface->clut = _get_clut_r3g3b2(
    400  10827      jedy +       	   surface->dpy,
    401  10827      jedy +	       DefaultColormapOfScreen(surface->screen));
    402  10827      jedy +        }
    403  10827      jedy +
    404  10827      jedy +        if(surface->clut == NULL) {
    405  10827      jedy +           free(data);
    406  10827      jedy +           break;
    407  10827      jedy +        }
    408   8955  dc144907 +        if (make_space_for(&buf, &size, &stride, image->width, image->height, 1))
    409   8955  dc144907 +            return CAIRO_STATUS_NO_MEMORY;
    410   8955  dc144907 +        data = buf;
    411   8955  dc144907 +        src = image->data;
    412   8955  dc144907 +        ilut = surface->clut->ilut;
    413   8955  dc144907 +        for(j=0;j<image->height;j++) {
    414   8955  dc144907 +            dst8 = data + j * stride;
    415   8955  dc144907 +            for(i=0;i<image->width;i++) {
    416   8955  dc144907 +                dst8[i] = ilut[ ((*src >> 16) & 0xe0) |
    417   8955  dc144907 +                                ((*src >> 11) & 0x1c) |
    418   8955  dc144907 +                                ((*src >> 6)  & 0x03) ];
    419   8955  dc144907 +                src++;
    420   8955  dc144907 +            }
    421   8955  dc144907 +        }
    422   8955  dc144907 +        alpha = red = green = blue = 0;
    423   8955  dc144907 +        depth = bpp = 8;
    424   8955  dc144907 +        break;
    425   8663  dc144907 +
    426   8547   erwannc +    case WORKAROUND_R5G6B5:
    427   8955  dc144907 +        if (make_space_for(&buf, &size, &stride, image->width, image->height, 2))
    428   8955  dc144907 +            return CAIRO_STATUS_NO_MEMORY;
    429   8955  dc144907 +        data = buf;
    430   8955  dc144907 +        src = image->data;
    431   8955  dc144907 +        for(j=0;j<image->height;j++) {
    432   8955  dc144907 +            dst16 = (uint16_t*)(data + j * stride);
    433   8955  dc144907 +            for(i=0;i<image->width;i++) {
    434   8955  dc144907 +                dst16[i] = ( ((*src >> 8) & 0xf800) |
    435   8955  dc144907 +                             ((*src >> 5) & 0x07e0) |
    436   8955  dc144907 +                             ((*src >> 3) & 0x001f) );
    437   8955  dc144907 +                src++;
    438   8955  dc144907 +            }
    439   8955  dc144907 +        }
    440   8955  dc144907 +        alpha = 0; red = 0xf800; green = 0x07e0; blue = 0x001f;
    441   8955  dc144907 +        depth = bpp = 16;
    442   8955  dc144907 +        break;
    443   8663  dc144907 +
    444   8547   erwannc +    }
    445   8663  dc144907 +
    446   8547   erwannc      ximage.width = image->width;
    447   8547   erwannc      ximage.height = image->height;
    448   8547   erwannc      ximage.format = ZPixmap;
    449   8547   erwannc -    ximage.data = (char *)image->data;
    450   8547   erwannc +    ximage.data = data;
    451   8547   erwannc      ximage.byte_order = native_byte_order;
    452   8663  dc144907      ximage.bitmap_unit = 32;	/* always for libpixman */
    453   8547   erwannc      ximage.bitmap_bit_order = native_byte_order;
    454   8955  dc144907      ximage.bitmap_pad = 32;	/* always for libpixman */
    455   8547   erwannc -    ximage.depth = image->depth;
    456   8547   erwannc -    ximage.bytes_per_line = image->stride;
    457   8547   erwannc +    ximage.depth = depth;
    458   8547   erwannc +    ximage.bytes_per_line = stride;
    459   8547   erwannc      ximage.bits_per_pixel = bpp;
    460   8547   erwannc      ximage.red_mask = red;
    461   8547   erwannc      ximage.green_mask = green;
    462  10827      jedy @@ -1891,6 +2265,36 @@ _cairo_xlib_surface_create_internal (Dis
    463   8547   erwannc      surface->clip_rects = NULL;
    464   8547   erwannc      surface->num_clip_rects = 0;
    465   8547   erwannc  
    466   8547   erwannc +    surface->clut = NULL;
    467   8547   erwannc +    surface->workaround = WORKAROUND_NONE;
    468   8547   erwannc +
    469   8666  dc144907 +    if (surface->xrender_format == NULL) {
    470   8663  dc144907 +       /* Install the correct workaround */
    471   8663  dc144907 +      if (visual) {
    472   8663  dc144907 +       switch (visual->class) {
    473   8663  dc144907 +       case StaticGray:
    474   8663  dc144907 +       case GrayScale:
    475   8663  dc144907 +           surface->workaround = WORKAROUND_8BIT_GRAYLEVEL;
    476   8663  dc144907 +           break;
    477   8663  dc144907 +       case PseudoColor:
    478   8663  dc144907 +       case StaticColor:
    479   8663  dc144907 +           surface->workaround = WORKAROUND_8BIT_PALETTE;
    480   8663  dc144907 +           break;
    481   8663  dc144907 +       case TrueColor:
    482   8663  dc144907 +           if (visual->red_mask   == 0xf800 &&
    483   8663  dc144907 +               visual->green_mask == 0x07e0 &&
    484   8663  dc144907 +               visual->blue_mask  == 0x001f) {
    485   8663  dc144907 +               surface->workaround = WORKAROUND_R5G6B5;
    486   8663  dc144907 +               }
    487   8547   erwannc +
    488   8663  dc144907 +       }
    489   8663  dc144907 +      }
    490   8547   erwannc +    }
    491   9346   erwannc +    else if (depth == 8)
    492   9346   erwannc +      {
    493   9346   erwannc +	surface->workaround = WORKAROUND_8BIT_PALETTE;
    494   9346   erwannc +      }
    495   8663  dc144907 +
    496   8547   erwannc      return (cairo_surface_t *) surface;
    497   8547   erwannc  }
    498   8547   erwannc  
    499