? cairo.diff ? src/semantic.cache ? test/a8-mask-directfb_bitmap-argb32-out.png ? test/caps-joins-directfb_bitmap-argb32-out.png ? test/caps-sub-paths-directfb_bitmap-argb32-out.png ? test/clip-fill-rule-pixel-aligned-directfb_bitmap-argb32-out.png ? test/composite-integer-translate-over-directfb_bitmap-argb32-out.png ? test/composite-integer-translate-over-repeat-directfb_bitmap-argb32-out.png ? test/composite-integer-translate-source-directfb_bitmap-argb32-out.png ? test/create-from-png-directfb_bitmap-argb32-out.png ? test/create-from-png-stream-directfb_bitmap-argb32-out.png ? test/dash-caps-joins-directfb_bitmap-argb32-out.png ? test/dash-offset-negative-directfb_bitmap-argb32-out.png ? test/dfblog ? test/fill-and-stroke-directfb_bitmap-argb32-out.png ? test/fill-rule-directfb_bitmap-argb32-out.png ? test/filter-nearest-offset-directfb_bitmap-argb32-out.png ? test/gradient-alpha-directfb_bitmap-argb32-out.png ? test/leaky-polygon-directfb_bitmap-argb32-out.png ? test/line-width-directfb_bitmap-argb32-out.png ? test/linear-gradient-directfb_bitmap-argb32-out.png ? test/mask-ctm-directfb_bitmap-argb32-out.png ? test/mask-surface-ctm-directfb_bitmap-argb32-out.png ? test/move-to-show-surface-directfb_bitmap-argb32-out.png ? test/nil-surface-directfb_bitmap-argb32-out.png ? test/operator-clear-directfb_bitmap-argb32-out.png ? test/operator-source-directfb_bitmap-argb32-out.png ? test/paint-directfb_bitmap-argb32-out.png ? test/paint-with-alpha-directfb_bitmap-argb32-out.png ? test/path-data-directfb_bitmap-argb32-out.png ? test/pixman-rotate-directfb_bitmap-argb32-out.png ? test/rectangle-rounding-error-directfb_bitmap-argb32-out.png ? test/rel-path-directfb_bitmap-argb32-out.png ? test/rotate-source-surface-paint ? test/rotate-source-surface-paint-directfb_bitmap-argb32-out.png ? test/rotate-source-surface-paint-ref.png ? test/rotate-source-surface-paint-rgb24-ref.png ? test/scale-source-surface-paint-directfb_bitmap-argb32-out.png ? test/self-copy-directfb_bitmap-argb32-out.png ? test/self-intersecting-directfb_bitmap-argb32-out.png ? test/semantic.cache ? test/set-source-directfb_bitmap-argb32-out.png ? test/show-text-current-point-directfb_bitmap-argb32-out.png ? test/source-clip-directfb_bitmap-argb32-out.png ? test/source-surface-scale-paint-directfb_bitmap-argb32-out.png ? test/surface-pattern-directfb_bitmap-argb32-out.png ? test/text-antialias-gray-directfb_bitmap-argb32-out.png ? test/text-antialias-none-directfb_bitmap-argb32-out.png ? test/text-antialias-subpixel-directfb_bitmap-argb32-out.png ? test/text-pattern-directfb_bitmap-argb32-out.png ? test/text-rotate-directfb_bitmap-argb32-out.png ? test/transforms-directfb_bitmap-argb32-out.png ? test/translate-show-surface-directfb_bitmap-argb32-out.png ? test/unbounded-operator-directfb_bitmap-argb32-out.png Index: pixman/src/fbpict.c =================================================================== RCS file: /cvs/cairo/cairo/pixman/src/fbpict.c,v retrieving revision 1.8 diff -u -p -r1.8 fbpict.c --- pixman/src/fbpict.c 21 Jan 2006 17:39:11 -0000 1.8 +++ pixman/src/fbpict.c 13 Feb 2006 02:06:45 -0000 @@ -1343,6 +1343,138 @@ fbCompositeSolidSrc_nxn (CARD8 op, # define mod(a,b) ((b) == 1 ? 0 : (a) >= 0 ? (a) % (b) : (b) - (-a) % (b)) +static void +pixman_compositeSolidMaskIn_nx8x8 (pixman_operator_t op, + pixman_image_t *pSrc, + pixman_image_t *pMask, + pixman_image_t *pDst, + int16_t xSrc, + int16_t ySrc, + int16_t xMask, + int16_t yMask, + int16_t xDst, + int16_t yDst, + uint16_t width, + uint16_t height) +{ + uint32_t src, srca; + uint8_t *dstLine, *dst, dstMask; + uint8_t *maskLine, *mask, m; + FbStride dstStride, maskStride; + uint16_t w; + uint16_t t; + + fbComposeGetSolid(pSrc,pDst,src); + + dstMask = FbFullMask (pDst->pixels->depth); + srca = src >> 24; + + fbComposeGetStart (pDst, xDst, yDst, uint8_t, dstStride, dstLine, 1); + fbComposeGetStart (pMask, xMask, yMask, uint8_t, maskStride, maskLine, 1); + + if (srca == 0xff) { + while (height--) + { + dst = dstLine; + dstLine += dstStride; + mask = maskLine; + maskLine += maskStride; + w = width; + + while (w--) + { + m = *mask++; + if (m == 0) + { + *dst = 0; + } + else if (m != 0xff) + { + *dst = FbIntMult(m, *dst, t); + } + dst++; + } + } + } + else + { + while (height--) + { + dst = dstLine; + dstLine += dstStride; + mask = maskLine; + maskLine += maskStride; + w = width; + + while (w--) + { + m = *mask++; + m = FbIntMult(m, srca, t); + if (m == 0) + { + *dst = 0; + } + else if (m != 0xff) + { + *dst = FbIntMult(m, *dst, t); + } + dst++; + } + } + } +} + + +static void +pixman_compositeSrcIn_8x8 (pixman_operator_t op, + pixman_image_t *pSrc, + pixman_image_t *pMask, + pixman_image_t *pDst, + int16_t xSrc, + int16_t ySrc, + int16_t xMask, + int16_t yMask, + int16_t xDst, + int16_t yDst, + uint16_t width, + uint16_t height) +{ + uint8_t *dstLine, *dst; + uint8_t *srcLine, *src; + FbStride dstStride, srcStride; + uint16_t w; + uint8_t s; + uint16_t t; + + fbComposeGetStart (pSrc, xSrc, ySrc, uint8_t, srcStride, srcLine, 1); + fbComposeGetStart (pDst, xDst, yDst, uint8_t, dstStride, dstLine, 1); + + while (height--) + { + dst = dstLine; + dstLine += dstStride; + src = srcLine; + srcLine += srcStride; + w = width; + + while (w--) + { + s = *src++; + if (s == 0) + { + *dst = 0; + } + else if (s != 0xff) + { + *dst = FbIntMult(s, *dst, t); + } + dst++; + } + } +} + + + void pixman_composite (pixman_operator_t op, PicturePtr pSrc, @@ -1818,6 +1950,38 @@ pixman_composite (pixman_operator_t op, } } break; + case PIXMAN_OPERATOR_IN: + if (pMask) + { + if (srcRepeat && + pSrc->pixels->width == 1 && + pSrc->pixels->height == 1) + { + if (PICT_FORMAT_COLOR(pSrc->format_code)) { + switch (pMask->format_code) { + case PICT_a8: + switch (pDst->format_code) { + case PICT_a8: + srcRepeat = 0; + func = pixman_compositeSolidMaskIn_nx8x8; + break; + } + } + } + } + } + else + { + switch (pSrc->format_code) { + case PICT_a8: + switch (pDst->format_code) { + case PICT_a8: + func = pixman_compositeSrcIn_8x8; + break; + } + } + } + break; } if (!func) { Index: src/cairo-directfb-surface.c =================================================================== RCS file: /cvs/cairo/cairo/src/cairo-directfb-surface.c,v retrieving revision 1.1 diff -u -p -r1.1 cairo-directfb-surface.c --- src/cairo-directfb-surface.c 29 Dec 2005 15:17:01 -0000 1.1 +++ src/cairo-directfb-surface.c 13 Feb 2006 02:06:47 -0000 @@ -42,11 +42,11 @@ #define DFB_SUPPORTED 1 /* -Glyph support not working + Glyph support not working */ #define DFB_SHOW_GLYPHS 0 /* -Composite support not working + Composite support not working */ #define DFB_COMPOSITE 0 @@ -54,62 +54,62 @@ Composite support not working #if DFB_SHOW_GLYPHS static cairo_int_status_t _cairo_directfb_surface_show_glyphs (cairo_scaled_font_t *scaled_font, - cairo_operator_t operator, - cairo_pattern_t *pattern, - void *abstract_surface, - int source_x, - int source_y, - int dest_x, - int dest_y, - unsigned int width, - unsigned int height, - const cairo_glyph_t *glyphs, - int num_glyphs); + cairo_operator_t operator, + cairo_pattern_t *pattern, + void *abstract_surface, + int source_x, + int source_y, + int dest_x, + int dest_y, + unsigned int width, + unsigned int height, + const cairo_glyph_t *glyphs, + int num_glyphs); #endif typedef struct _cairo_directfb_surface { - cairo_surface_t base; - cairo_format_t format; - IDirectFB *dfb; - IDirectFBSurface *main_surface; - IDirectFBSurface *buffer; - pixman_region16_t *clip; - cairo_surface_t *buffer_image; - void *buffer_data; - int width; - int height; + cairo_surface_t base; + cairo_format_t format; + IDirectFB *dfb; + IDirectFBSurface *main_surface; + IDirectFBSurface *buffer; + pixman_region16_t *clip; + cairo_surface_t *buffer_image; + void *buffer_data; + int width; + int height; } cairo_directfb_surface_t; static int -_dfb_set_operator (cairo_operator_t operator,IDirectFBSurface *dest) +_dfb_set_operator (cairo_operator_t operator, IDirectFBSurface *dest) { - dest->SetDrawingFlags(dest,DSDRAW_BLEND); - dest->SetPorterDuff(dest,DSPD_NONE); + dest->SetDrawingFlags (dest, DSDRAW_BLEND); + dest->SetPorterDuff (dest, DSPD_NONE); switch (operator) { case CAIRO_OPERATOR_CLEAR: - dest->SetPorterDuff(dest,DSPD_CLEAR); + dest->SetPorterDuff (dest, DSPD_CLEAR); break; case CAIRO_OPERATOR_SOURCE: - dest->SetPorterDuff(dest,DSPD_SRC); + dest->SetPorterDuff (dest, DSPD_SRC); break; case CAIRO_OPERATOR_OVER: - dest->SetPorterDuff(dest,DSPD_SRC_OVER); + dest->SetPorterDuff (dest, DSPD_SRC_OVER); break; case CAIRO_OPERATOR_IN: - dest->SetPorterDuff(dest,DSPD_SRC_IN); + dest->SetPorterDuff (dest, DSPD_SRC_IN); break; case CAIRO_OPERATOR_OUT: - dest->SetPorterDuff(dest,DSPD_SRC_OUT); + dest->SetPorterDuff (dest, DSPD_SRC_OUT); break; case CAIRO_OPERATOR_DEST_OVER: - dest->SetPorterDuff(dest,DSPD_DST_OVER); + dest->SetPorterDuff (dest, DSPD_DST_OVER); break; case CAIRO_OPERATOR_DEST_IN: - dest->SetPorterDuff(dest,DSPD_DST_IN); + dest->SetPorterDuff (dest, DSPD_DST_IN); break; case CAIRO_OPERATOR_DEST_OUT: - dest->SetPorterDuff(dest,DSPD_DST_OUT); + dest->SetPorterDuff (dest, DSPD_DST_OUT); break; /*not sure about these yet */ @@ -123,7 +123,7 @@ _dfb_set_operator (cairo_operator_t oper return DFB_UNSUPPORTED; break; case CAIRO_OPERATOR_XOR: - dest->SetDrawingFlags(dest,DSDRAW_XOR); + dest->SetDrawingFlags (dest, DSDRAW_XOR); break; case CAIRO_OPERATOR_ADD: return DFB_UNSUPPORTED; @@ -138,357 +138,376 @@ _dfb_set_operator (cairo_operator_t oper } -static inline int cairo_to_directfb_format(cairo_format_t format ) { - switch( format ) { - case CAIRO_FORMAT_RGB24: - return DSPF_RGB24; - case CAIRO_FORMAT_ARGB32: - return DSPF_ARGB; - case CAIRO_FORMAT_A8: - return DSPF_A8; - case CAIRO_FORMAT_A1: - return DSPF_A1; - default: - { - //assert(0); - return DSPF_UNKNOWN; - } - } -} - -static inline int directfb_to_cairo_format(DFBSurfacePixelFormat dfbformat ) { - switch( dfbformat ) { - case DSPF_RGB24 : - case DSPF_RGB32 : - return CAIRO_FORMAT_RGB24; - break; - case DSPF_AiRGB : - case DSPF_ARGB : - return CAIRO_FORMAT_ARGB32; - break; - case DSPF_A8 : - return CAIRO_FORMAT_A8; - break; - case DSPF_A1 : - return CAIRO_FORMAT_A1; - break; - case DSPF_UNKNOWN : - case DSPF_ARGB1555 : - case DSPF_RGB16 : - case DSPF_YUY2 : - case DSPF_RGB332 : - case DSPF_UYVY : - case DSPF_I420 : - case DSPF_ALUT44 : - case DSPF_NV12 : - case DSPF_NV16 : - default : - return DFB_UNSUPPORTED; - } -} - - -static IDirectFBSurface *cairo_directfb_buffer_surface_create(IDirectFB *dfb,void *data,int pitch, int format, - int width, int height) { - - DFBResult ret; - IDirectFBSurface *buffer; - DFBSurfaceDescription dsc; - - dsc.flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT; - dsc.caps = DSCAPS_NONE; - dsc.width = width; - dsc.height = height; - dsc.pixelformat = format; - if( data ) { - dsc.flags |= DSDESC_CAPS; - dsc.flags |= DSDESC_PREALLOCATED; - dsc.caps = DSCAPS_NONE; - dsc.preallocated[0].data = data; - dsc.preallocated[0].pitch = pitch; - dsc.preallocated[1].data = NULL; - dsc.preallocated[1].pitch = 0; - } - - ret =dfb->CreateSurface (dfb, &dsc, &buffer); - if (ret) { - DirectFBError ("cairo_directfb_buffer_surface_create failed ", ret); - assert(0); - return NULL; - } +static int +cairo_to_directfb_format (cairo_format_t format) { + switch (format) { + case CAIRO_FORMAT_RGB24: + return DSPF_RGB24; + case CAIRO_FORMAT_ARGB32: + return DSPF_ARGB; + case CAIRO_FORMAT_A8: + return DSPF_A8; + case CAIRO_FORMAT_A1: + return DSPF_A1; + default: + return DSPF_UNKNOWN; + } +} + +static int +directfb_to_cairo_format (DFBSurfacePixelFormat dfbformat) { + switch (dfbformat) { + case DSPF_RGB24: + case DSPF_RGB32: + return CAIRO_FORMAT_RGB24; + break; + case DSPF_AiRGB: + case DSPF_ARGB: + return CAIRO_FORMAT_ARGB32; + break; + case DSPF_A8: + return CAIRO_FORMAT_A8; + break; + case DSPF_A1: + return CAIRO_FORMAT_A1; + break; + case DSPF_UNKNOWN: + case DSPF_ARGB1555: + case DSPF_RGB16: + case DSPF_YUY2: + case DSPF_RGB332: + case DSPF_UYVY: + case DSPF_I420: + case DSPF_ALUT44: + case DSPF_NV12: + case DSPF_NV16: + default : + return DFB_UNSUPPORTED; + } +} + + +static IDirectFBSurface * +cairo_directfb_buffer_surface_create(IDirectFB *dfb,void *data,int pitch, int format, + int width, int height) { + + DFBResult ret; + IDirectFBSurface *buffer; + DFBSurfaceDescription dsc; + + dsc.flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT; + dsc.caps = DSCAPS_NONE; + dsc.width = width; + dsc.height = height; + dsc.pixelformat = format; + if (data) { + dsc.flags |= DSDESC_CAPS; + dsc.flags |= DSDESC_PREALLOCATED; + dsc.caps = DSCAPS_NONE; + dsc.preallocated[0].data = data; + dsc.preallocated[0].pitch = pitch; + dsc.preallocated[1].data = NULL; + dsc.preallocated[1].pitch = 0; + } + + ret = dfb->CreateSurface (dfb, &dsc, &buffer); + if (ret) { + DirectFBError ("cairo_directfb_buffer_surface_create failed ", ret); + assert(0); + return NULL; + } #if 0 - { - DFBSurfacePixelFormat dfbformat; - int nwidth=0; - int nheight=0; - int npitch; - void *ndata; - buffer->GetSize(buffer,&nwidth,&nheight); - buffer->GetPixelFormat(buffer,&dfbformat); - buffer->Lock(buffer,DSLF_READ,&ndata,&npitch); - buffer->Unlock(buffer); - assert( ( nwidth == width) && (nheight == height)); - } + { + DFBSurfacePixelFormat dfbformat; + int nwidth=0; + int nheight=0; + int npitch; + void *ndata; + + buffer->GetSize (buffer, &nwidth, &nheight); + buffer->GetPixelFormat (buffer, &dfbformat); + buffer->Lock (buffer, DSLF_READ, &ndata, &npitch); + buffer->Unlock (buffer); + assert ((nwidth == width) && (nheight == height)); + } #endif - return buffer; + return buffer; } static cairo_status_t _cairo_directfb_surface_get_image (cairo_directfb_surface_t *surface, - cairo_rectangle_t *interest, - cairo_image_surface_t **image_out, - cairo_rectangle_t *rect_out, - DFBSurfaceLockFlags flags) -{ - int pitch; - void *data; + cairo_rectangle_t *interest, + cairo_image_surface_t **image_out, + cairo_rectangle_t *rect_out, + DFBSurfaceLockFlags flags) +{ + int pitch; + void *data; + + (void)interest; + if (surface->buffer->Lock (surface->buffer, flags, &data, &pitch) != DFB_OK) + return CAIRO_STATUS_NO_MEMORY; + + /*lock the dest agianst other changes*/ + if (surface->buffer_image) { + if (surface->buffer_data == data) { + cairo_surface_reference (surface->buffer_image); + } + } - (void)interest; - if( surface->buffer->Lock(surface->buffer,flags,&data,&pitch) != DFB_OK ) + if (surface->buffer_data != data) { + /* new off screen buffer */ + int width; + int height; + DFBSurfacePixelFormat dfbformat; + + /*surface moved free image if allocated */ + if (surface->buffer_image) { + cairo_surface_destroy (surface->buffer_image); + surface->buffer_image = NULL; + surface->buffer_data = NULL; + } + surface->buffer->Unlock (surface->buffer); + + + surface->main_surface->GetSize (surface->main_surface, &width, &height); + surface->main_surface->GetPixelFormat (surface->main_surface, &dfbformat); + surface->format = directfb_to_cairo_format (dfbformat); + + if (surface->format == DFB_UNSUPPORTED) { + surface->format = CAIRO_FORMAT_ARGB32; + surface->buffer = cairo_directfb_buffer_surface_create( surface->dfb,NULL, + 0, DSPF_ARGB, + width, height); + if (!surface->buffer) return CAIRO_STATUS_NO_MEMORY; + /*Have to flip the main surface if its double buffered to blit the buffer*/ + surface->main_surface->Flip (surface->main_surface, NULL, 0); + surface->buffer->Blit (surface->buffer, surface->main_surface, NULL, 0, 0); + } else { + surface->buffer = surface->main_surface; + } - /*lock the dest agianst other changes*/ - if( surface->buffer_image ) { - if( surface->buffer_data == data ) { - cairo_surface_reference(surface->buffer_image); - } - } - - if( surface->buffer_data != data ){ - /* new off screen buffer */ - int width; - int height; - DFBSurfacePixelFormat dfbformat; - /*surface moved free image if allocated */ - if( surface->buffer_image ) { - cairo_surface_destroy (surface->buffer_image); - surface->buffer_image=NULL; - surface->buffer_data=NULL; - } - surface->buffer->Unlock(surface->buffer); - + surface->width = width; + surface->height = height; + + if (surface->buffer->Lock(surface->buffer, flags, &data, &pitch) != DFB_OK) + return CAIRO_STATUS_NO_MEMORY; + + surface->buffer_data = data; + surface->buffer_image = cairo_image_surface_create_for_data ( + (unsigned char *)data,surface->format, width, height, pitch); + if (surface->buffer_image == NULL) { + surface->buffer->Release (surface->buffer); + surface->buffer = NULL; + surface->buffer_data = NULL; + return CAIRO_STATUS_NO_MEMORY; + } +#if 0 + if (surface->clip) + _cairo_image_surface_set_clip_region ( + (cairo_image_surface_t *)surface->buffer_image,surface->clip); +#endif + } - surface->main_surface->GetSize(surface->main_surface,&width,&height); - surface->main_surface->GetPixelFormat(surface->main_surface,&dfbformat); - surface->format = directfb_to_cairo_format(dfbformat); - - if( surface->format == DFB_UNSUPPORTED ) { - surface->format = CAIRO_FORMAT_ARGB32; - surface->buffer = cairo_directfb_buffer_surface_create(surface->dfb,NULL, - 0,DSPF_ARGB,width,height); - if( !surface->buffer ) - return CAIRO_STATUS_NO_MEMORY; - /*Have to flip the main surface if its double buffered to blit the buffer*/ - surface->main_surface->Flip(surface->main_surface,NULL,0); - surface->buffer->Blit(surface->buffer,surface->main_surface,NULL,0,0); - }else { - surface->buffer = surface->main_surface; - } - - surface->width=width; - surface->height=height; - - if( surface->buffer->Lock(surface->buffer,flags,&data,&pitch) != DFB_OK ) - return CAIRO_STATUS_NO_MEMORY; - - surface->buffer_data = data; - surface->buffer_image = cairo_image_surface_create_for_data ( - (unsigned char *)data,surface->format,width, height, pitch); - if( surface->buffer_image == NULL ) { - surface->buffer->Release(surface->buffer); - surface->buffer = NULL; - surface->buffer_data = NULL; - return CAIRO_STATUS_NO_MEMORY; - } - #if 0 - if( surface->clip) - _cairo_image_surface_set_clip_region ( - (cairo_image_surface_t *)surface->buffer_image,surface->clip); - #endif - } - - if (rect_out) { - rect_out->x = 0; - rect_out->y = 0; - rect_out->width = surface->width; - rect_out->height = surface->height; - } - if( image_out ) - *image_out=(cairo_image_surface_t *)surface->buffer_image; - return CAIRO_STATUS_SUCCESS; + if (rect_out) { + rect_out->x = 0; + rect_out->y = 0; + rect_out->width = surface->width; + rect_out->height = surface->height; + } + if (image_out) + *image_out=(cairo_image_surface_t *)surface->buffer_image; + return CAIRO_STATUS_SUCCESS; } static cairo_surface_t * _cairo_directfb_surface_create_similar (void *abstract_src, - cairo_content_t content, - int width, - int height) -{ - cairo_format_t format = _cairo_format_from_content (content); - int dfbformat; - switch( content ) { - case CAIRO_CONTENT_COLOR: - dfbformat=DSPF_ARGB; - break; - case CAIRO_CONTENT_ALPHA: - dfbformat=DSPF_A8; - break; - case CAIRO_CONTENT_COLOR_ALPHA: - dfbformat= DSPF_ARGB; - break; - default: - { - return cairo_image_surface_create (format, width, height); - } - } - cairo_directfb_surface_t *src = abstract_src; - IDirectFBSurface *buffer =cairo_directfb_buffer_surface_create(src->dfb, - NULL,0,dfbformat,width,height); - cairo_surface_t *sur =cairo_directfb_surface_create (src->dfb,buffer); - ((cairo_directfb_surface_t *)sur)->format = format; - return sur; + cairo_content_t content, + int width, + int height) +{ + cairo_format_t format = _cairo_format_from_content (content); + cairo_directfb_surface_t *src = abstract_src; + IDirectFBSurface *buffer; + cairo_surface_t *sur; + int dfbformat; + + switch (content) { + case CAIRO_CONTENT_COLOR: + dfbformat=DSPF_ARGB; + break; + case CAIRO_CONTENT_ALPHA: + dfbformat=DSPF_A8; + break; + case CAIRO_CONTENT_COLOR_ALPHA: + dfbformat= DSPF_ARGB; + break; + default: + return cairo_image_surface_create (format, width, height); + } + + buffer =cairo_directfb_buffer_surface_create (src->dfb, + NULL, 0, dfbformat, + width, height); + sur =cairo_directfb_surface_create (src->dfb,buffer); + ((cairo_directfb_surface_t *)sur)->format = format; + + return sur; } static cairo_status_t -_cairo_directfb_surface_finish (void *data ) { - cairo_directfb_surface_t *surface=(cairo_directfb_surface_t *)data; - if( surface->buffer_image ) - cairo_surface_destroy (surface->buffer_image); - if (surface->clip) - pixman_region_destroy (surface->clip); - - if( surface->main_surface != surface->buffer ) { - surface->main_surface->SetClip (surface->main_surface,NULL); - surface->main_surface->Blit(surface->main_surface,surface->buffer,NULL,0,0); - surface->buffer->Release (surface->buffer); - surface->buffer=NULL; - } +_cairo_directfb_surface_finish (void *data) { + cairo_directfb_surface_t *surface = (cairo_directfb_surface_t *)data; + + if( surface->buffer_image ) + cairo_surface_destroy (surface->buffer_image); + if (surface->clip) + pixman_region_destroy (surface->clip); + + if (surface->main_surface != surface->buffer) { + surface->main_surface->SetClip (surface->main_surface, NULL); + surface->main_surface->Blit (surface->main_surface, surface->buffer, NULL, 0, 0); + surface->buffer->Release (surface->buffer); + surface->buffer=NULL; + } #if 0 /* No don't do this */ - surface->main_surface->Flip(surface->main_surface,NULL,0); + surface->main_surface->Flip (surface->main_surface, NULL, 0); #endif - surface->main_surface->Release (surface->main_surface); - surface->main_surface=NULL; - surface->dfb->Release(surface->dfb); - surface->dfb=NULL; - return CAIRO_STATUS_SUCCESS; + surface->main_surface->Release (surface->main_surface); + surface->main_surface = NULL; + surface->dfb->Release (surface->dfb); + surface->dfb = NULL; + + return CAIRO_STATUS_SUCCESS; } static cairo_status_t _cairo_directfb_surface_acquire_source_image (void *abstract_surface, - cairo_image_surface_t **image_out, - void **image_extra) + cairo_image_surface_t **image_out, + void **image_extra) { - cairo_directfb_surface_t *surface = abstract_surface; - *image_extra = surface; - return _cairo_directfb_surface_get_image (surface, NULL,image_out,NULL,DSLF_READ); + cairo_directfb_surface_t *surface = abstract_surface; + + *image_extra = surface; + return _cairo_directfb_surface_get_image (surface, NULL,image_out,NULL,DSLF_READ); } - static void +static void _cairo_directfb_surface_release_source_image (void *abstract_surface, - cairo_image_surface_t *image, - void *image_extra) + cairo_image_surface_t *image, + void *image_extra) { - cairo_directfb_surface_t *surface = abstract_surface; - surface->buffer->Unlock(surface->buffer); + cairo_directfb_surface_t *surface = abstract_surface; + + surface->buffer->Unlock (surface->buffer); } - static cairo_status_t +static cairo_status_t _cairo_directfb_surface_acquire_dest_image (void *abstract_surface, - cairo_rectangle_t *interest_rect, - cairo_image_surface_t **image_out, - cairo_rectangle_t *image_rect_out, - void **image_extra) -{ - cairo_directfb_surface_t *surface = abstract_surface; - *image_extra = interest_rect; - return _cairo_directfb_surface_get_image (surface, interest_rect,image_out, - image_rect_out,DSLF_READ|DSLF_WRITE); + cairo_rectangle_t *interest_rect, + cairo_image_surface_t **image_out, + cairo_rectangle_t *image_rect_out, + void **image_extra) +{ + cairo_directfb_surface_t *surface = abstract_surface; + + *image_extra = interest_rect; + return _cairo_directfb_surface_get_image (surface, interest_rect,image_out, + image_rect_out,DSLF_READ|DSLF_WRITE); } static void _cairo_directfb_surface_release_dest_image (void *abstract_surface, - cairo_rectangle_t *interest_rect, - cairo_image_surface_t *image, - cairo_rectangle_t *image_rect, - void *image_extra) -{ - cairo_directfb_surface_t *surface = abstract_surface; - IDirectFBSurface *buffer=surface->buffer; - buffer->Unlock(buffer); + cairo_rectangle_t *interest_rect, + cairo_image_surface_t *image, + cairo_rectangle_t *image_rect, + void *image_extra) +{ + cairo_directfb_surface_t *surface = abstract_surface; + IDirectFBSurface *buffer = surface->buffer; + + buffer->Unlock (buffer); } static cairo_status_t _cairo_directfb_surface_clone_similar (void *abstract_surface, - cairo_surface_t *src, - cairo_surface_t **clone_out) + cairo_surface_t *src, + cairo_surface_t **clone_out) { - cairo_directfb_surface_t *surface = abstract_surface; - cairo_directfb_surface_t *clone; + cairo_directfb_surface_t *surface = abstract_surface; + cairo_directfb_surface_t *clone; + + if (src->backend == surface->base.backend) { + *clone_out = src; + cairo_surface_reference (src); + + return CAIRO_STATUS_SUCCESS; + } else if (_cairo_surface_is_image (src)) { + cairo_image_surface_t *image_src = (cairo_image_surface_t *) src; + IDirectFBSurface *tmpbuffer; + int format; + + clone = (cairo_directfb_surface_t *) + _cairo_directfb_surface_create_similar (surface, image_src->format, + image_src->width, + image_src->height); + if (!clone) + return CAIRO_STATUS_NO_MEMORY; + format = cairo_to_directfb_format(image_src->format); + tmpbuffer =cairo_directfb_buffer_surface_create(surface->dfb, + (void *)image_src->data, + image_src->stride, format, + image_src->width, image_src->height); + + if (!tmpbuffer) { + cairo_surface_destroy((cairo_surface_t *)surface); + return CAIRO_STATUS_NO_MEMORY; + } - if (src->backend == surface->base.backend) { - *clone_out = src; - cairo_surface_reference (src); - return CAIRO_STATUS_SUCCESS; - } else if (_cairo_surface_is_image (src)) { - cairo_image_surface_t *image_src = (cairo_image_surface_t *) src; - clone = (cairo_directfb_surface_t *) - _cairo_directfb_surface_create_similar (surface, image_src->format, - image_src->width, - image_src->height); - if (!clone) - return CAIRO_STATUS_NO_MEMORY; - IDirectFBSurface *tmpbuffer; - int format = cairo_to_directfb_format(image_src->format); - tmpbuffer =cairo_directfb_buffer_surface_create(surface->dfb, - (void *)image_src->data,image_src->stride,format, - image_src->width,image_src->height); - - if (!tmpbuffer){ - cairo_surface_destroy((cairo_surface_t *)surface); - return CAIRO_STATUS_NO_MEMORY; - } - clone->buffer->Blit(clone->buffer,tmpbuffer,NULL,0,0); - tmpbuffer->Release(tmpbuffer); - *clone_out = &clone->base; - return CAIRO_STATUS_SUCCESS; - } - return CAIRO_INT_STATUS_UNSUPPORTED; + clone->buffer->Blit (clone->buffer, tmpbuffer, NULL, 0, 0); + tmpbuffer->Release (tmpbuffer); + *clone_out = &clone->base; + + return CAIRO_STATUS_SUCCESS; + } + return CAIRO_INT_STATUS_UNSUPPORTED; } #if DFB_COMPOSITE static cairo_int_status_t _cairo_directfb_surface_composite (cairo_operator_t op, - cairo_pattern_t *src_pattern, - cairo_pattern_t *mask_pattern, - void *abstract_dst, - int src_x, - int src_y, - int mask_x, - int mask_y, - int dst_x, - int dst_y, - unsigned int width, - unsigned int height) + cairo_pattern_t *src_pattern, + cairo_pattern_t *mask_pattern, + void *abstract_dst, + int src_x, + int src_y, + int mask_x, + int mask_y, + int dst_x, + int dst_y, + unsigned int width, + unsigned int height) { cairo_directfb_surface_t *dst = abstract_dst; + cairo_directfb_surface_t *surface = abstract_dst; cairo_directfb_surface_t *src; cairo_surface_pattern_t *src_surface_pattern; int alpha; int integer_transform; int itx, ity; - cairo_directfb_surface_t *surface = abstract_dst; - if( _dfb_set_operator(op,surface->buffer) == DFB_UNSUPPORTED ) - return CAIRO_INT_STATUS_UNSUPPORTED; + if( _dfb_set_operator(op, surface->buffer) == DFB_UNSUPPORTED ) + return CAIRO_INT_STATUS_UNSUPPORTED; if (src_pattern->type == CAIRO_PATTERN_SOLID ) { } else if (src_pattern->type != CAIRO_PATTERN_SURFACE || - src_pattern->extend != CAIRO_EXTEND_NONE) { - return CAIRO_INT_STATUS_UNSUPPORTED; - } + src_pattern->extend != CAIRO_EXTEND_NONE) { + return CAIRO_INT_STATUS_UNSUPPORTED; + } if (mask_pattern) { /* FIXME: When we fully support RENDER style 4-channel @@ -497,7 +516,7 @@ _cairo_directfb_surface_composite (cairo if (mask_pattern->type != CAIRO_PATTERN_SOLID) return CAIRO_INT_STATUS_UNSUPPORTED; - alpha = ((cairo_solid_pattern_t *)mask_pattern)->color.alpha_short >> 8; + alpha = ((cairo_solid_pattern_t *)mask_pattern)->color.alpha_short >> 8; } else { alpha = 255; } @@ -507,128 +526,136 @@ _cairo_directfb_surface_composite (cairo if (src->base.backend != dst->base.backend){ return CAIRO_INT_STATUS_UNSUPPORTED; - } + } integer_transform = _cairo_matrix_is_integer_translation (&src_pattern->matrix, &itx, &ity); if (!integer_transform) { return CAIRO_INT_STATUS_UNSUPPORTED; - } - surface->buffer->SetPorterDuff(surface->buffer,DSPD_NONE); - return CAIRO_INT_STATUS_UNSUPPORTED; + } + surface->buffer->SetPorterDuff(surface->buffer,DSPD_NONE); + return CAIRO_INT_STATUS_UNSUPPORTED; } #endif static cairo_int_status_t _cairo_directfb_surface_fill_rectangles (void *abstract_surface, - cairo_operator_t op, - const cairo_color_t *color, - cairo_rectangle_t *rects, - int n_rects) -{ - int i,k; - cairo_directfb_surface_t *surface = abstract_surface; - IDirectFBSurface *buffer = surface->buffer; + cairo_operator_t op, + const cairo_color_t *color, + cairo_rectangle_t *rects, + int n_rects) +{ + int i,k; + cairo_directfb_surface_t *surface = abstract_surface; + IDirectFBSurface *buffer = surface->buffer; - if( _dfb_set_operator(op,buffer) == DFB_UNSUPPORTED ) { - return CAIRO_INT_STATUS_UNSUPPORTED; - } + if (_dfb_set_operator(op,buffer) == DFB_UNSUPPORTED) { + return CAIRO_INT_STATUS_UNSUPPORTED; + } - buffer->SetColor(buffer,color->red_short >> 8, - color->green_short >> 8, - color->blue_short >> 8, - color->alpha_short >> 8 ); - /*Not optimized not sure of the sorting on region*/ - if( surface->clip ) { - DFBRegion region; + buffer->SetColor(buffer,color->red_short >> 8, + color->green_short >> 8, + color->blue_short >> 8, + color->alpha_short >> 8 ); + /*Not optimized not sure of the sorting on region*/ + if( surface->clip ) { + DFBRegion region; int n_boxes = pixman_region_num_rects (surface->clip); pixman_box16_t *boxes = pixman_region_rects (surface->clip); - for( k = 0; k < n_boxes; k++ ) { - region.x1 = boxes[k].x1; - region.y1 = boxes[k].y1; - region.x2 = boxes[k].x2; - region.y2 = boxes[k].y2; - buffer->SetClip (buffer,®ion); - for (i = 0; i < n_rects; i++) { - buffer->FillRectangle(buffer,rects[i].x,rects[i].y, - rects[i].width,rects[i].height); - } - } - buffer->SetClip (buffer, NULL); - }else { - buffer->SetClip (buffer, NULL); + + for( k = 0; k < n_boxes; k++ ) { + region.x1 = boxes[k].x1; + region.y1 = boxes[k].y1; + region.x2 = boxes[k].x2; + region.y2 = boxes[k].y2; + buffer->SetClip (buffer, ®ion); + for (i = 0; i < n_rects; i++) { + buffer->FillRectangle (buffer, rects[i].x, rects[i].y, + rects[i].width, rects[i].height); + } + } + buffer->SetClip (buffer, NULL); + } else { + buffer->SetClip (buffer, NULL); for (i = 0; i < n_rects; i++) { - buffer->FillRectangle(buffer,rects[i].x,rects[i].y, - rects[i].width,rects[i].height); - } + buffer->FillRectangle (buffer, rects[i].x, rects[i].y, + rects[i].width, rects[i].height); } - return CAIRO_STATUS_SUCCESS; + } + return CAIRO_STATUS_SUCCESS; } static cairo_int_status_t _cairo_directfb_surface_set_clip_region (void *abstract_surface, - pixman_region16_t *region) + pixman_region16_t *region) { - cairo_directfb_surface_t *surface = abstract_surface; - if( region == NULL ) { - pixman_region_destroy (surface->clip); - surface->clip = NULL; - }else { - if (!surface->clip) { - surface->clip = pixman_region_create (); - if (!surface->clip) - return CAIRO_STATUS_NO_MEMORY; - } - pixman_region_copy (surface->clip, region); + cairo_directfb_surface_t *surface = abstract_surface; + if (region == NULL) { + pixman_region_destroy (surface->clip); + surface->clip = NULL; + } else { + if (!surface->clip) { + surface->clip = pixman_region_create (); + if (!surface->clip) + return CAIRO_STATUS_NO_MEMORY; } + pixman_region_copy (surface->clip, region); + } #if 0 - if( surface->buffer_image ) - _cairo_image_surface_set_clip_region ( - (cairo_image_surface_t *)surface->buffer_image,region); + if( surface->buffer_image ) + _cairo_image_surface_set_clip_region ( + (cairo_image_surface_t *)surface->buffer_image,region); #endif - - return CAIRO_STATUS_SUCCESS; + + return CAIRO_STATUS_SUCCESS; } static cairo_int_status_t _cairo_directfb_abstract_surface_get_extents (void *abstract_surface, - cairo_rectangle_t *rectangle) + cairo_rectangle_t *rectangle) { - if( rectangle ) { - cairo_directfb_surface_t *surface = abstract_surface; - rectangle->x = 0; - rectangle->y = 0; - rectangle->width = surface->width; - rectangle->height = surface->height; - } - return CAIRO_STATUS_SUCCESS; + if (rectangle) { + cairo_directfb_surface_t *surface = abstract_surface; + + rectangle->x = 0; + rectangle->y = 0; + rectangle->width = surface->width; + rectangle->height = surface->height; + } + return CAIRO_STATUS_SUCCESS; } + static cairo_status_t _cairo_directfb_surface_mark_dirty_rectangle (void * abstract_surface, - int x, - int y, - int width, - int height) + int x, + int y, + int width, + int height) { - cairo_directfb_surface_t *surface = abstract_surface; - if( surface->main_surface != surface->buffer) { - DFBRegion region; - region.x1=x; - region.y1=y; - region.x2=x+width; - region.y2=y+height; - surface->buffer->SetClip (surface->buffer,®ion); - surface->buffer->Blit(surface->buffer,surface->main_surface,NULL,0,0); - surface->buffer->SetClip (surface->buffer,NULL); - } - return CAIRO_STATUS_SUCCESS; + cairo_directfb_surface_t *surface = abstract_surface; + + if (surface->main_surface != surface->buffer) { + DFBRegion region; + + region.x1 = x; + region.y1 = y; + region.x2 = x + width; + region.y2 = y + height; + surface->buffer->SetClip (surface->buffer, ®ion); + surface->buffer->Blit (surface->buffer, surface->main_surface, NULL, 0, 0); + surface->buffer->SetClip (surface->buffer, NULL); + } + + return CAIRO_STATUS_SUCCESS; } + static cairo_status_t _cairo_directfb_surface_flush (void *abstract_surface) { - cairo_directfb_surface_t *surface = abstract_surface; - if( surface->main_surface != surface->buffer) - surface->main_surface->Blit(surface->main_surface,surface->buffer,NULL,0,0); - return CAIRO_STATUS_SUCCESS; + cairo_directfb_surface_t *surface = abstract_surface; + + if( surface->main_surface != surface->buffer) + surface->main_surface->Blit(surface->main_surface,surface->buffer,NULL,0,0); + return CAIRO_STATUS_SUCCESS; } #if DFB_SHOW_GLYPHS @@ -640,7 +667,7 @@ _cairo_directfb_surface_scaled_font_fini font_private = scaled_font->surface_private; if (font_private) { - xxx_destroy (font_private); + xxx_destroy (font_private); } } #endif @@ -648,7 +675,7 @@ _cairo_directfb_surface_scaled_font_fini #if DFB_SHOW_GLYPHS static void _cairo_directfb_surface_scaled_glyph_fini (cairo_scaled_glyph_t *scaled_glyph, - cairo_scaled_font_t *scaled_font) + cairo_scaled_font_t *scaled_font) { cairo_directfb_surface_glyph_private_t *glyph_private; @@ -662,122 +689,127 @@ _cairo_directfb_surface_scaled_glyph_fin static const cairo_surface_backend_t cairo_directfb_surface_backend = { - _cairo_directfb_surface_create_similar, - _cairo_directfb_surface_finish, - _cairo_directfb_surface_acquire_source_image, - _cairo_directfb_surface_release_source_image, - _cairo_directfb_surface_acquire_dest_image, - _cairo_directfb_surface_release_dest_image, - _cairo_directfb_surface_clone_similar, + _cairo_directfb_surface_create_similar, + _cairo_directfb_surface_finish, + _cairo_directfb_surface_acquire_source_image, + _cairo_directfb_surface_release_source_image, + _cairo_directfb_surface_acquire_dest_image, + _cairo_directfb_surface_release_dest_image, + _cairo_directfb_surface_clone_similar, #if DFB_COMPOSITE - _cairo_directfb_surface_composite, + _cairo_directfb_surface_composite, #else - NULL, + NULL, #endif - _cairo_directfb_surface_fill_rectangles, - NULL,/*composite_trapezoids*/ - NULL, /* copy_page */ - NULL, /* show_page */ - _cairo_directfb_surface_set_clip_region, - NULL, /* intersect_clip_path */ - _cairo_directfb_abstract_surface_get_extents, + _cairo_directfb_surface_fill_rectangles, + NULL,/*composite_trapezoids*/ + NULL, /* copy_page */ + NULL, /* show_page */ + _cairo_directfb_surface_set_clip_region, + NULL, /* intersect_clip_path */ + _cairo_directfb_abstract_surface_get_extents, #if DFB_SHOW_GLYPHS - _cairo_directfb_surface_show_glyphs, + _cairo_directfb_surface_show_glyphs, #else - NULL, + NULL, #endif - NULL, /* get_font_options */ - _cairo_directfb_surface_flush, - _cairo_directfb_surface_mark_dirty_rectangle, + NULL, /* get_font_options */ + _cairo_directfb_surface_flush, + _cairo_directfb_surface_mark_dirty_rectangle, #if DFB_SHOW_GLYPHS - _cairo_directfb_surface_scaled_font_fini, - _cairo_directfb_surface_scaled_glyph_fini + _cairo_directfb_surface_scaled_font_fini, + _cairo_directfb_surface_scaled_glyph_fini #else - NULL, - NULL + NULL, + NULL #endif }; #if DFB_SHOW_GLYPHS static cairo_int_status_t _cairo_directfb_surface_show_glyphs (cairo_scaled_font_t *scaled_font, - cairo_operator_t operator, - cairo_pattern_t *pattern, - void *abstract_surface, - int source_x, - int source_y, - int dest_x, - int dest_y, - unsigned int width, - unsigned int height, - const cairo_glyph_t *glyphs, - int num_glyphs) -{ - int i; - cairo_int_status_t status; - cairo_directfb_surface_t *surface = abstract_surface; - cairo_scaled_glyph_t *scaled_glyph; + cairo_operator_t operator, + cairo_pattern_t *pattern, + void *abstract_surface, + int source_x, + int source_y, + int dest_x, + int dest_y, + unsigned int width, + unsigned int height, + const cairo_glyph_t *glyphs, + int num_glyphs) +{ + int i; + cairo_int_status_t status; + cairo_directfb_surface_t *surface = abstract_surface; + cairo_scaled_glyph_t *scaled_glyph; if ((scaled_font->surface_backend != NULL && - scaled_font->surface_backend != &cairo_directfb_surface_backend) ) - return CAIRO_INT_STATUS_UNSUPPORTED; + scaled_font->surface_backend != &cairo_directfb_surface_backend) ) + return CAIRO_INT_STATUS_UNSUPPORTED; if (scaled_font->surface_backend == NULL) { - scaled_font->surface_backend = &cairo_directfb_surface_backend; - } - /* Send all unsent glyphs to the server */ + scaled_font->surface_backend = &cairo_directfb_surface_backend; + } + /* Send all unsent glyphs to the server */ for (i = 0; i < num_glyphs; i++) { IDirectFBSurface *tmpbuffer; - int x; - int y; - cairo_image_surface_t *glyph_img; + int x; + int y; + cairo_image_surface_t *glyph_img; + status = _cairo_scaled_glyph_lookup (scaled_font, - glyphs[i].index, - CAIRO_SCALED_GLYPH_INFO_SURFACE, - &scaled_glyph); - glyph_img = scaled_glyph->surface; + glyphs[i].index, + CAIRO_SCALED_GLYPH_INFO_SURFACE, + &scaled_glyph); + glyph_img = scaled_glyph->surface; if (status != CAIRO_STATUS_SUCCESS) - return status; - /* its a space or something*/ - if( !glyph_img->data ) { - continue; - } + return status; + /* its a space or something*/ + if( !glyph_img->data ) { + continue; + } if (scaled_glyph->surface_private == NULL ) { - int dfbformat = cairo_to_directfb_format(glyph_img->format); - if( dfbformat == DSPF_UNKNOWN ) { - printf(" BAD IMAGE FORMAT[%d] cf=%d dfbf=%d data=%p \n",i,glyph_img->format,dfbformat,glyph_img->data); - continue; - } - tmpbuffer = cairo_directfb_buffer_surface_create(surface->dfb, - (void *)glyph_img->data,glyph_img->stride,dfbformat,glyph_img->width,glyph_img->height); - /*scaled_glyph->surface_private = tmpbuffer;*/ + int dfbformat = cairo_to_directfb_format (glyph_img->format); + if( dfbformat == DSPF_UNKNOWN ) { + printf(" BAD IMAGE FORMAT[%d] cf=%d dfbf=%d data=%p \n", + i, glyph_img->format, dfbformat, glyph_img->data); + continue; + } + tmpbuffer = cairo_directfb_buffer_surface_create (surface->dfb, + (void *)glyph_img->data, + glyph_img->stride, + dfbformat, + glyph_img->width, + glyph_img->height); + /*scaled_glyph->surface_private = tmpbuffer;*/ }else { - tmpbuffer = (IDirectFBSurface *)scaled_glyph->surface_private; - } - if( !tmpbuffer ) { - assert(0); /*something really bad happend*/ - return CAIRO_INT_STATUS_UNSUPPORTED; - } - /* round glyph locations to the nearest pixel */ - x = (int) floor (glyphs[i].x + - glyph_img->base.device_x_offset + - 0.5); - y = (int) floor (glyphs[i].y + - glyph_img->base.device_y_offset + - 0.5); - x +=dest_x; - y +=dest_y; - - printf(" IMAGE FORMAT[%d] src_x=%d src_y=%d cf=%d data=%p x=%d y=%d w=%d h=%d\n",i,source_x,source_y,glyph_img->format,glyph_img->data,x,y,glyph_img->width,glyph_img->height); + tmpbuffer = (IDirectFBSurface *)scaled_glyph->surface_private; + } + if( !tmpbuffer ) { + assert(0); /*something really bad happend*/ + return CAIRO_INT_STATUS_UNSUPPORTED; + } + /* round glyph locations to the nearest pixel */ + x = (int) floor (glyphs[i].x + glyph_img->base.device_x_offset + 0.5); + y = (int) floor (glyphs[i].y + glyph_img->base.device_y_offset + 0.5); + x += dest_x; + y += dest_y; + + printf(" IMAGE FORMAT[%d] src_x=%d src_y=%d cf=%d data=%p x=%d y=%d w=%d h=%d\n", + i, source_x, source_y, glyph_img->format, + glyph_img->data, x, y, glyph_img->width, glyph_img->height); #if 0 - surface->buffer->SetColor(surface->buffer,0,0xff,0,0xff); - surface->buffer->FillRectangle(surface->buffer,x,y,glyph_img->width,glyph_img->height); - surface->buffer->SetColor(surface->buffer,0,0xff,0xff,0xff); + surface->buffer->SetColor(surface->buffer, 0, 0xff, 0, 0xff); + surface->buffer->FillRectangle(surface->buffer, x, y, + glyph_img->width, glyph_img->height); + surface->buffer->SetColor(surface->buffer, 0, 0xff, 0xff, 0xff); #endif - surface->buffer->Blit(surface->buffer,tmpbuffer,NULL,x,y); + surface->buffer->Blit(surface->buffer,tmpbuffer,NULL,x,y); } - return CAIRO_INT_STATUS_UNSUPPORTED; + return CAIRO_INT_STATUS_UNSUPPORTED; } #endif @@ -786,19 +818,21 @@ _cairo_directfb_surface_show_glyphs (cai cairo_surface_t * cairo_directfb_surface_create (IDirectFB *dfb,IDirectFBSurface *dfbsurface) { - cairo_directfb_surface_t *surface = calloc(1,sizeof(cairo_directfb_surface_t)); - if( surface == NULL ) - return NULL; - _cairo_surface_init (&surface->base, &cairo_directfb_surface_backend); - /*Reference the surface */ - dfb->AddRef(dfb); - dfbsurface->AddRef(dfbsurface); - surface->dfb=dfb; - surface->main_surface = dfbsurface; - dfbsurface->GetSize(dfbsurface,&surface->width,&surface->height); - surface->buffer = surface->main_surface; - surface->format = DFB_UNSUPPORTED; - surface->clip=NULL; - return ((cairo_surface_t *)surface); + cairo_directfb_surface_t *surface = calloc(1, sizeof(cairo_directfb_surface_t)); + + if (surface == NULL) + return NULL; + + _cairo_surface_init (&surface->base, &cairo_directfb_surface_backend); + /*Reference the surface */ + dfb->AddRef (dfb); + dfbsurface->AddRef (dfbsurface); + surface->dfb = dfb; + surface->main_surface = dfbsurface; + dfbsurface->GetSize (dfbsurface, &surface->width, &surface->height); + surface->buffer = surface->main_surface; + surface->format = DFB_UNSUPPORTED; + surface->clip = NULL; + return ((cairo_surface_t *)surface); } Index: src/cairo-ft-font.c =================================================================== RCS file: /cvs/cairo/cairo/src/cairo-ft-font.c,v retrieving revision 1.115 diff -u -p -r1.115 cairo-ft-font.c --- src/cairo-ft-font.c 21 Dec 2005 16:19:47 -0000 1.115 +++ src/cairo-ft-font.c 13 Feb 2006 02:06:54 -0000 @@ -96,12 +96,16 @@ struct _cairo_ft_unscaled_font { double x_scale; /* Extracted X scale factor */ double y_scale; /* Extracted Y scale factor */ cairo_bool_t have_shape; /* true if the current scale has a non-scale component*/ + cairo_matrix_t current_shape; int lock; /* count of how many times this font has been locked */ cairo_ft_font_face_t *faces; /* Linked list of faces for this font */ }; +static cairo_user_data_key_t +_cairo_ft_font_face_options_key; + static int _cairo_ft_unscaled_font_keys_equal (void *key_a, void *key_b); @@ -119,10 +123,16 @@ typedef struct _cairo_ft_options { cairo_ft_extra_flags_t extra_flags; /* other flags that affect results */ } cairo_ft_options_t; +typedef struct _cairo_fc_ft_options { + cairo_font_options_t base; + cairo_ft_options_t ft_options; +} cairo_fc_ft_options_t; + struct _cairo_ft_font_face { cairo_font_face_t base; cairo_ft_unscaled_font_t *unscaled; cairo_ft_options_t ft_options; + cairo_font_options_t font_options; cairo_ft_font_face_t *next; }; @@ -391,7 +401,7 @@ _cairo_ft_unscaled_font_create_for_patte if (FcPatternGetString (pattern, FC_FILE, 0, &fc_filename) != FcResultMatch) goto UNWIND; filename = (char *) fc_filename; - + if (FcPatternGetInteger (pattern, FC_INDEX, 0, &id) != FcResultMatch) goto UNWIND; @@ -618,7 +628,12 @@ _cairo_ft_unscaled_font_set_scale (cairo unscaled->x_scale = sf.x_scale; unscaled->y_scale = sf.y_scale; - + + cairo_matrix_init (&unscaled->current_shape, + sf.shape[0][0], sf.shape[0][1], + sf.shape[1][0], sf.shape[1][1], + 0.0, 0.0); + mat.xx = DOUBLE_TO_16_16(sf.shape[0][0]); mat.yx = - DOUBLE_TO_16_16(sf.shape[0][1]); mat.xy = - DOUBLE_TO_16_16(sf.shape[1][0]); @@ -715,12 +730,7 @@ _get_bitmap_surface (FT_Bitmap *bi width = bitmap->width; height = bitmap->rows; - if (width * height == 0) { - if (own_buffer && bitmap->buffer) - free (bitmap->buffer); - - *surface = NULL; - } else { + { switch (bitmap->pixel_mode) { case FT_PIXEL_MODE_MONO: stride = (((width + 31) & ~31) >> 3); @@ -904,6 +914,17 @@ _get_bitmap_surface (FT_Bitmap *bi return CAIRO_STATUS_SUCCESS; } +static cairo_bool_t +_cairo_ft_glyph_embolden (FT_GlyphSlot glyph) +{ +#if HAVE_FT_GLYPHSLOT_EMBOLDEN + FT_GlyphSlot_Embolden (glyph); + return TRUE; +#else + return FALSE; +#endif +} + /* Converts an outline FT_GlyphSlot into an image * * This could go through _render_glyph_bitmap as well, letting @@ -922,17 +943,20 @@ _get_bitmap_surface (FT_Bitmap *bi static cairo_status_t _render_glyph_outline (FT_Face face, cairo_font_options_t *font_options, + cairo_bool_t vert_layout, + cairo_bool_t lazy_embolden, cairo_image_surface_t **surface) { FT_GlyphSlot glyphslot = face->glyph; FT_Outline *outline = &glyphslot->outline; - FT_Bitmap bitmap; + FT_Bitmap bitmap, * target = &bitmap; FT_BBox cbox; FT_Matrix matrix; int hmul = 1; int vmul = 1; unsigned int width, height, stride; cairo_bool_t subpixel = FALSE; + cairo_bool_t owner = TRUE; cairo_status_t status; FT_Outline_Get_CBox (outline, &cbox); @@ -1023,17 +1047,35 @@ _render_glyph_outline (FT_Face return CAIRO_STATUS_NO_MEMORY; } - status = _get_bitmap_surface (&bitmap, TRUE, font_options, surface); + if (lazy_embolden) { + glyphslot->bitmap = bitmap; + glyphslot->format = FT_GLYPH_FORMAT_BITMAP; + + if (_cairo_ft_glyph_embolden (glyphslot) && + glyphslot->bitmap.buffer != bitmap.buffer) { + owner = FALSE; + target = &glyphslot->bitmap; + + free (bitmap.buffer); + } else { + glyphslot->bitmap.buffer = NULL; + } + } + status = _get_bitmap_surface (target, owner, font_options, surface); if (status) return status; } /* * Note: the font's coordinate system is upside down from ours, so the - * Y coordinate of the control box needs to be negated. + * Y coordinate of the control box needs to be negated. Vertical glyphs + * are centred. */ - (*surface)->base.device_x_offset = floor ((double) cbox.xMin / 64.0); + if (vert_layout) + (*surface)->base.device_x_offset = floor (-(double) bitmap.width / 2.0); + else + (*surface)->base.device_x_offset = floor ((double) cbox.xMin / 64.0); (*surface)->base.device_y_offset = floor (-(double) cbox.yMax / 64.0); return CAIRO_STATUS_SUCCESS; @@ -1074,7 +1116,9 @@ _render_glyph_bitmap (FT_Face fac if (error) return CAIRO_STATUS_NO_MEMORY; - _get_bitmap_surface (&glyphslot->bitmap, FALSE, font_options, surface); + status = _get_bitmap_surface (&glyphslot->bitmap, FALSE, font_options, surface); + if (status) + return status; /* * Note: the font's coordinate system is upside down from ours, so the @@ -1087,18 +1131,17 @@ _render_glyph_bitmap (FT_Face fac return status; } -#if 0 -/* XXX */ static cairo_status_t -_transform_glyph_bitmap (cairo_image_glyph_cache_entry_t *val) +_transform_glyph_bitmap (cairo_matrix_t * shape, + cairo_image_surface_t ** surface) { - cairo_ft_font_transform_t sf; cairo_matrix_t original_to_transformed; cairo_matrix_t transformed_to_original; cairo_image_surface_t *old_image; cairo_surface_t *image; double x[4], y[4]; double origin_x, origin_y; + int origin_width, origin_height; int i; int x_min, y_min, x_max, y_max; int width, height; @@ -1106,26 +1149,26 @@ _transform_glyph_bitmap (cairo_image_gly cairo_surface_pattern_t pattern; /* We want to compute a transform that takes the origin - * (val->size.x, val->size.y) to 0,0, then applies the "shape" - * portion of the font transform + * (x, y) to 0.0, then applies the "shape" portion of + * the font transform */ - _compute_transform (&sf, &val->key.scale); - - cairo_matrix_init (&original_to_transformed, - sf.shape[0][0], sf.shape[0][1], - sf.shape[1][0], sf.shape[1][1], - 0, 0); + original_to_transformed = *shape; + + origin_x = (*surface)->base.device_x_offset; + origin_y = (*surface)->base.device_y_offset; + origin_width = cairo_image_surface_get_width (&(*surface)->base); + origin_height = cairo_image_surface_get_height (&(*surface)->base); cairo_matrix_translate (&original_to_transformed, - val->size.x, val->size.y); + origin_x, origin_y); /* Find the bounding box of the original bitmap under that * transform */ - x[0] = 0; y[0] = 0; - x[1] = val->size.width; y[1] = 0; - x[2] = val->size.width; y[2] = val->size.height; - x[3] = 0; y[3] = val->size.height; + x[0] = 0; y[0] = 0; + x[1] = origin_width; y[1] = 0; + x[2] = origin_width; y[2] = origin_height; + x[3] = 0; y[3] = origin_height; for (i = 0; i < 4; i++) cairo_matrix_transform_point (&original_to_transformed, @@ -1188,11 +1231,11 @@ _transform_glyph_bitmap (cairo_image_gly _cairo_pattern_fini (&pattern.base); - /* Now update the cache entry for the new bitmap, recomputing + /* Now update the glyph for the new bitmap, recomputing * the origin based on the final transform. */ - origin_x = - val->size.x; - origin_y = - val->size.y; + origin_x = - origin_x; + origin_y = - origin_y; cairo_matrix_transform_point (&original_to_transformed, &origin_x, &origin_y); @@ -1200,14 +1243,11 @@ _transform_glyph_bitmap (cairo_image_gly (*surface) = (cairo_image_surface_t *)image; cairo_surface_destroy (&old_image->base); - val->size.width = width; - val->size.height = height; - val->size.x = - floor (origin_x + 0.5); - val->size.y = - floor (origin_y + 0.5); - + (*surface)->base.device_x_offset = - floor (origin_x + 0.5); + (*surface)->base.device_y_offset = - floor (origin_y + 0.5); + return status; } -#endif static const cairo_unscaled_font_backend_t cairo_ft_unscaled_font_backend = { _cairo_ft_unscaled_font_destroy, @@ -1221,6 +1261,7 @@ static const cairo_unscaled_font_backend typedef struct _cairo_ft_scaled_font { cairo_scaled_font_t base; cairo_ft_unscaled_font_t *unscaled; + cairo_font_options_t font_options; cairo_ft_options_t ft_options; } cairo_ft_scaled_font_t; @@ -1232,15 +1273,15 @@ const cairo_scaled_font_backend_t cairo_ static cairo_ft_options_t _get_pattern_ft_options (FcPattern *pattern) { - FcBool antialias, vertical_layout, hinting, autohint; + FcBool antialias, vertical_layout, hinting, autohint, global_advance; cairo_ft_options_t ft_options; int rgba; -#ifdef FC_HINT_STYLE +#ifdef FC_HINT_STYLE int hintstyle; -#endif +#endif int target_flags = 0; - ft_options.load_flags = 0; + ft_options.load_flags = FT_LOAD_DEFAULT; ft_options.extra_flags = 0; /* disable antialiasing if requested */ @@ -1258,51 +1299,54 @@ _get_pattern_ft_options (FcPattern *patt FC_HINTING, 0, &hinting) != FcResultMatch) hinting = FcTrue; -#ifdef FC_HINT_STYLE - if (FcPatternGetInteger (pattern, FC_HINT_STYLE, 0, &hintstyle) != FcResultMatch) - hintstyle = FC_HINT_FULL; - - if (!hinting || hintstyle == FC_HINT_NONE) - ft_options.load_flags |= FT_LOAD_NO_HINTING; - - if (antialias) { - switch (hintstyle) { - case FC_HINT_SLIGHT: - case FC_HINT_MEDIUM: - target_flags = FT_LOAD_TARGET_LIGHT; - break; - default: - target_flags = FT_LOAD_TARGET_NORMAL; - break; - } - } else { -#ifdef FT_LOAD_TARGET_MONO - target_flags = FT_LOAD_TARGET_MONO; -#endif - } -#else /* !FC_HINT_STYLE */ if (!hinting) target_flags = FT_LOAD_NO_HINTING; -#endif /* FC_FHINT_STYLE */ - if (FcPatternGetInteger (pattern, - FC_RGBA, 0, &rgba) != FcResultMatch) - rgba = FC_RGBA_UNKNOWN; +#ifdef FC_HINT_STYLE + if (FcPatternGetInteger (pattern, + FC_HINT_STYLE, 0, &hintstyle) != FcResultMatch) + hintstyle = FC_HINT_FULL; +#else + target_flags = FT_LOAD_NO_HINTING; +#endif - switch (rgba) { - case FC_RGBA_UNKNOWN: - case FC_RGBA_NONE: - default: - break; - case FC_RGBA_RGB: - case FC_RGBA_BGR: - target_flags = FT_LOAD_TARGET_LCD; - break; - case FC_RGBA_VRGB: - case FC_RGBA_VBGR: - target_flags = FT_LOAD_TARGET_LCD_V; - break; + if (antialias) { + if (FcPatternGetInteger (pattern, + FC_RGBA, 0, &rgba) != FcResultMatch) + rgba = FC_RGBA_UNKNOWN; + + switch (rgba) { + case FC_RGBA_RGB: + case FC_RGBA_BGR: + target_flags |= FT_LOAD_TARGET_LCD; + break; + case FC_RGBA_VRGB: + case FC_RGBA_VBGR: + target_flags |= FT_LOAD_TARGET_LCD_V; + break; + case FC_RGBA_UNKNOWN: + case FC_RGBA_NONE: + default: +#ifdef FC_HINT_STYLE + if (hinting) { + switch (hintstyle) { + case FC_HINT_SLIGHT: + case FC_HINT_MEDIUM: + target_flags |= FT_LOAD_TARGET_LIGHT; + break; + default: + target_flags |= FT_LOAD_TARGET_NORMAL; + break; + } + } +#endif + break; + } } +#ifdef FT_LOAD_TARGET_MONO + else + target_flags |= FT_LOAD_TARGET_MONO; +#endif ft_options.load_flags |= target_flags; @@ -1320,7 +1364,14 @@ _get_pattern_ft_options (FcPattern *patt if (vertical_layout) ft_options.load_flags |= FT_LOAD_VERTICAL_LAYOUT; + + if (FcPatternGetBool (pattern, + FC_GLOBAL_ADVANCE, 0, &global_advance) != FcResultMatch) + global_advance = FcTrue; + if (!global_advance) + ft_options.load_flags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH; + #ifdef FC_EMBOLDEN { FcBool embolden; @@ -1334,9 +1385,99 @@ _get_pattern_ft_options (FcPattern *patt } #endif +#ifdef FC_EMBEDDED_BITMAP + { + FcBool embed; + if (FcPatternGetBool (pattern, + FC_EMBEDDED_BITMAP, 0, &embed) != FcResultMatch) + embed = FcFalse; + + if (!embed) + ft_options.load_flags |= FT_LOAD_NO_BITMAP; + } +#endif + return ft_options; } +static void +_cairo_ft_font_pattern_to_font_options (FcPattern *pattern, + cairo_font_options_t *options) +{ + FcBool antialias, hinting; + int rgba; +#ifdef FC_HINT_STYLE + int hintstyle; +#endif + + options->antialias = CAIRO_ANTIALIAS_DEFAULT; + options->subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT; + options->hint_style = CAIRO_HINT_STYLE_DEFAULT; + options->hint_metrics = CAIRO_HINT_METRICS_DEFAULT; + + /* disable antialiasing if requested */ + if (FcPatternGetBool (pattern, + FC_ANTIALIAS, 0, &antialias) != FcResultMatch) + antialias = FcTrue; + + /* disable hinting if requested */ + if (FcPatternGetBool (pattern, + FC_HINTING, 0, &hinting) != FcResultMatch) + hinting = FcTrue; + + if (!hinting) + options->hint_style = CAIRO_HINT_STYLE_NONE; + +#ifdef FC_HINT_STYLE + if (FcPatternGetInteger (pattern, + FC_HINT_STYLE, 0, &hintstyle) != FcResultMatch) + hintstyle = FC_HINT_FULL; +#else + options->hinting = CAIRO_HINT_STYLE_NONE; +#endif + + if (FcPatternGetInteger (pattern, + FC_RGBA, 0, &rgba) != FcResultMatch) + rgba = FC_RGBA_UNKNOWN; + +#ifdef FC_HINT_STYLE + switch (hintstyle) { + case FC_HINT_SLIGHT: + options->hint_style = CAIRO_HINT_STYLE_SLIGHT; + break; + case FC_HINT_MEDIUM: + options->hint_style = CAIRO_HINT_STYLE_MEDIUM; + break; + case FC_HINT_FULL: + default: + options->hint_style = CAIRO_HINT_STYLE_FULL; + break; + } +#endif + + if ((rgba != FC_RGBA_UNKNOWN && rgba != FC_RGBA_NONE) && antialias) { + options->antialias = CAIRO_ANTIALIAS_SUBPIXEL; + switch (rgba) { + case FC_RGBA_RGB: + options->subpixel_order = CAIRO_SUBPIXEL_ORDER_RGB; + break; + case FC_RGBA_BGR: + options->subpixel_order = CAIRO_SUBPIXEL_ORDER_BGR; + break; + case FC_RGBA_VRGB: + options->subpixel_order = CAIRO_SUBPIXEL_ORDER_VRGB; + break; + case FC_RGBA_VBGR: + options->subpixel_order = CAIRO_SUBPIXEL_ORDER_VBGR; + break; + } + } +#ifdef FT_LOAD_TARGET_MONO + if (!antialias) + options->antialias = CAIRO_ANTIALIAS_NONE; +#endif +} + static int _get_options_load_flags (const cairo_font_options_t *options) { @@ -1366,24 +1507,23 @@ _get_options_load_flags (const cairo_fon case CAIRO_ANTIALIAS_DEFAULT: case CAIRO_ANTIALIAS_GRAY: load_flags |= FT_LOAD_NO_BITMAP; + /* disable hinting if requested */ + switch (options->hint_style) { + case CAIRO_HINT_STYLE_NONE: + load_flags |= FT_LOAD_NO_HINTING; + break; + case CAIRO_HINT_STYLE_SLIGHT: + case CAIRO_HINT_STYLE_MEDIUM: + load_flags |= FT_LOAD_TARGET_LIGHT; + break; + case CAIRO_HINT_STYLE_FULL: + default: + load_flags |= FT_LOAD_TARGET_NORMAL; + break; + } break; } - /* disable hinting if requested */ - switch (options->hint_style) { - case CAIRO_HINT_STYLE_NONE: - load_flags |= FT_LOAD_NO_HINTING; - break; - case CAIRO_HINT_STYLE_SLIGHT: - case CAIRO_HINT_STYLE_MEDIUM: - load_flags |= FT_LOAD_TARGET_LIGHT; - break; - case CAIRO_HINT_STYLE_FULL: - default: - load_flags |= FT_LOAD_TARGET_NORMAL; - break; - } - return load_flags; } @@ -1398,6 +1538,7 @@ _cairo_ft_scaled_font_create (cairo_ft_u cairo_ft_scaled_font_t *scaled_font = NULL; FT_Face face; FT_Size_Metrics *metrics; + cairo_font_options_t *font_options; cairo_font_extents_t fs_metrics; face = _cairo_ft_unscaled_font_lock_face (unscaled); @@ -1426,6 +1567,13 @@ _cairo_ft_scaled_font_create (cairo_ft_u _cairo_ft_unscaled_font_set_scale (unscaled, &scaled_font->base.scale); + scaled_font->font_options = scaled_font->base.options; + font_options = cairo_font_face_get_user_data (font_face, + &_cairo_ft_font_face_options_key); + if (font_options) + cairo_font_options_merge (&scaled_font->font_options, + font_options); + metrics = &face->size->metrics; /* @@ -1460,7 +1608,7 @@ _cairo_ft_scaled_font_create (cairo_ft_u /* FIXME: this doesn't do vertical layout atm. */ - fs_metrics.max_y_advance = 0.0; + fs_metrics.max_y_advance = fs_metrics.height; _cairo_scaled_font_set_metrics (&scaled_font->base, &fs_metrics); @@ -1489,6 +1637,7 @@ _cairo_ft_scaled_font_create_toy (cairo_ cairo_matrix_t scale; cairo_ft_font_transform_t sf; cairo_ft_options_t ft_options; + cairo_font_options_t *ft_font_options; unsigned char *family = (unsigned char*) toy_face->family; pattern = FcPatternCreate (); @@ -1545,6 +1694,20 @@ _cairo_ft_scaled_font_create_toy (cairo_ goto FREE_RESOLVED; ft_options = _get_pattern_ft_options (resolved); + ft_font_options = cairo_font_face_get_user_data (&toy_face->base, + &_cairo_ft_font_face_options_key); + + if (!ft_font_options) { + ft_font_options = cairo_font_options_create (); + + if (font_options) { + _cairo_ft_font_pattern_to_font_options (pattern, ft_font_options); + cairo_font_face_set_user_data (&toy_face->base, + &_cairo_ft_font_face_options_key, + ft_font_options, + (cairo_destroy_func_t)cairo_font_options_destroy); + } + } new_font = _cairo_ft_scaled_font_create (unscaled, &toy_face->base, @@ -1712,6 +1875,9 @@ _cairo_ft_scaled_glyph_init (void *abs cairo_text_extents_t fs_metrics; cairo_ft_scaled_font_t *scaled_font = abstract_font; cairo_ft_unscaled_font_t *unscaled = scaled_font->unscaled; + cairo_bool_t embolden = FALSE; + cairo_bool_t lazy_embolden = FALSE; + cairo_bool_t vertical_layout = FALSE; FT_GlyphSlot glyph; FT_Face face; FT_Error error; @@ -1723,10 +1889,17 @@ _cairo_ft_scaled_glyph_init (void *abs if (!face) return CAIRO_STATUS_NO_MEMORY; - if ((info & CAIRO_SCALED_GLYPH_INFO_PATH) != 0 && - (info & CAIRO_SCALED_GLYPH_INFO_SURFACE) == 0) + if (((info & CAIRO_SCALED_GLYPH_INFO_PATH) != 0 && + (info & CAIRO_SCALED_GLYPH_INFO_SURFACE) == 0)) load_flags |= FT_LOAD_NO_BITMAP; - + + if (load_flags & FT_LOAD_VERTICAL_LAYOUT) + vertical_layout = TRUE; + + if (scaled_font->ft_options.extra_flags & CAIRO_FT_OPTIONS_EMBOLDEN) + embolden = TRUE; + + error = FT_Load_Glyph (scaled_font->unscaled->face, _cairo_scaled_glyph_index(scaled_glyph), load_flags); @@ -1737,16 +1910,10 @@ _cairo_ft_scaled_glyph_init (void *abs } glyph = face->glyph; - -#if HAVE_FT_GLYPHSLOT_EMBOLDEN - /* - * embolden glyphs if requested - */ - if (scaled_font->ft_options.extra_flags & CAIRO_FT_OPTIONS_EMBOLDEN) - FT_GlyphSlot_Embolden (glyph); -#endif if (info & CAIRO_SCALED_GLYPH_INFO_METRICS) { + if (embolden) + _cairo_ft_glyph_embolden (glyph); /* * Compute font-space metrics */ @@ -1780,34 +1947,56 @@ _cairo_ft_scaled_glyph_init (void *abs FT_Pos y1, y2; FT_Pos advance; - x1 = (metrics->horiBearingX) & -64; - x2 = (metrics->horiBearingX + metrics->width + 63) & -64; - y1 = (-metrics->horiBearingY) & -64; - y2 = (-metrics->horiBearingY + metrics->height + 63) & -64; - - advance = ((metrics->horiAdvance + 32) & -64); - - fs_metrics.x_bearing = DOUBLE_FROM_26_6 (x1) * x_factor; - fs_metrics.y_bearing = DOUBLE_FROM_26_6 (y1) * y_factor; - - fs_metrics.width = DOUBLE_FROM_26_6 (x2 - x1) * x_factor; - fs_metrics.height = DOUBLE_FROM_26_6 (y2 - y1) * y_factor; - - /* - * use untransformed advance values - * XXX uses horizontal advance only at present; should provide FT_LOAD_VERTICAL_LAYOUT - */ - fs_metrics.x_advance = DOUBLE_FROM_26_6 (advance) * x_factor; - fs_metrics.y_advance = 0; + if (!vertical_layout) { + x1 = (metrics->horiBearingX) & -64; + x2 = (metrics->horiBearingX + metrics->width + 63) & -64; + y1 = (-metrics->horiBearingY) & -64; + y2 = (-metrics->horiBearingY + metrics->height + 63) & -64; + + advance = ((metrics->horiAdvance + 32) & -64); + + fs_metrics.x_bearing = DOUBLE_FROM_26_6 (x1) * x_factor; + fs_metrics.y_bearing = DOUBLE_FROM_26_6 (y1) * y_factor; + + fs_metrics.width = DOUBLE_FROM_26_6 (x2 - x1) * x_factor; + fs_metrics.height = DOUBLE_FROM_26_6 (y2 - y1) * y_factor; + + fs_metrics.x_advance = DOUBLE_FROM_26_6 (advance) * x_factor; + fs_metrics.y_advance = 0; + } else { + x1 = (metrics->vertBearingX) & -64; + x2 = (metrics->vertBearingX + metrics->width + 63) & -64; + y1 = (-metrics->vertBearingY) & -64; + y2 = (-metrics->vertBearingY + metrics->height + 63) & -64; + + advance = ((metrics->vertAdvance + 32) & -64); + + fs_metrics.x_bearing = DOUBLE_FROM_26_6 (x1) * x_factor; + fs_metrics.y_bearing = DOUBLE_FROM_26_6 (y1) * y_factor; + + fs_metrics.width = DOUBLE_FROM_26_6 (x2 - x1) * x_factor; + fs_metrics.height = DOUBLE_FROM_26_6 (y2 - y1) * y_factor; + + fs_metrics.x_advance = 0; + fs_metrics.y_advance = DOUBLE_FROM_26_6 (advance) * y_factor; + } } else { - fs_metrics.x_bearing = DOUBLE_FROM_26_6 (metrics->horiBearingX) * x_factor; - fs_metrics.y_bearing = DOUBLE_FROM_26_6 (-metrics->horiBearingY) * y_factor; - - fs_metrics.width = DOUBLE_FROM_26_6 (metrics->width) * x_factor; - fs_metrics.height = DOUBLE_FROM_26_6 (metrics->height) * y_factor; - - fs_metrics.x_advance = DOUBLE_FROM_26_6 (metrics->horiAdvance) * x_factor; - fs_metrics.y_advance = 0 * y_factor; + fs_metrics.width = DOUBLE_FROM_26_6 (metrics->width) * x_factor; + fs_metrics.height = DOUBLE_FROM_26_6 (metrics->height) * y_factor; + + if (!vertical_layout) { + fs_metrics.x_bearing = DOUBLE_FROM_26_6 (metrics->horiBearingX) * x_factor; + fs_metrics.y_bearing = DOUBLE_FROM_26_6 (-metrics->horiBearingY) * y_factor; + + fs_metrics.x_advance = DOUBLE_FROM_26_6 (metrics->horiAdvance) * x_factor; + fs_metrics.y_advance = 0 * y_factor; + } else { + fs_metrics.x_bearing = DOUBLE_FROM_26_6 (metrics->vertBearingX) * x_factor; + fs_metrics.y_bearing = DOUBLE_FROM_26_6 (-metrics->vertBearingY) * y_factor; + + fs_metrics.x_advance = 0 * x_factor; + fs_metrics.y_advance = DOUBLE_FROM_26_6 (metrics->vertAdvance) * y_factor; + } } _cairo_scaled_glyph_set_metrics (scaled_glyph, @@ -1818,12 +2007,37 @@ _cairo_ft_scaled_glyph_init (void *abs if ((info & CAIRO_SCALED_GLYPH_INFO_SURFACE) != 0) { cairo_image_surface_t *surface; cairo_status_t status; + + if (embolden && + scaled_font->font_options.antialias == CAIRO_ANTIALIAS_NONE && + glyph->format == FT_GLYPH_FORMAT_OUTLINE && + (load_flags & FT_LOAD_NO_HINTING) == 0) + lazy_embolden = TRUE; + + if (lazy_embolden && (info & CAIRO_SCALED_GLYPH_INFO_METRICS)) { + error = FT_Load_Glyph (face, + _cairo_scaled_glyph_index(scaled_glyph), + load_flags); + + if (error) { + cairo_ft_scaled_font_unlock_face (abstract_font); + return CAIRO_STATUS_NO_MEMORY; + } + } + + if (embolden && !lazy_embolden) + _cairo_ft_glyph_embolden (glyph); + if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) - status = _render_glyph_outline (face, &scaled_font->base.options, - &surface); - else - status = _render_glyph_bitmap (face, &scaled_font->base.options, + status = _render_glyph_outline (face, &scaled_font->font_options, + vertical_layout, lazy_embolden, &surface); + else { + status = _render_glyph_bitmap (face, &scaled_font->font_options, &surface); + if (!status && unscaled->have_shape) + status = _transform_glyph_bitmap (&unscaled->current_shape, + &surface); + } if (status) { cairo_ft_scaled_font_unlock_face (abstract_font); return status; @@ -1850,9 +2064,13 @@ _cairo_ft_scaled_glyph_init (void *abs cairo_ft_scaled_font_unlock_face (abstract_font); return CAIRO_STATUS_NO_MEMORY; } + + if (embolden) + _cairo_ft_glyph_embolden (glyph); } + if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) - status = _decompose_glyph_outline (face, &scaled_font->base.options, + status = _decompose_glyph_outline (face, &scaled_font->font_options, &path); else status = CAIRO_STATUS_NO_MEMORY; @@ -2115,8 +2333,7 @@ cairo_ft_font_options_substitute (const #ifdef FC_HINT_STYLE if (FcPatternGet (pattern, FC_HINT_STYLE, 0, &v) == FcResultNoMatch) { - int hint_style; - + int hint_style = 0; switch (options->hint_style) { case CAIRO_HINT_STYLE_SLIGHT: hint_style = FC_HINT_SLIGHT; @@ -2166,6 +2383,7 @@ cairo_ft_font_face_create_for_pattern (F { cairo_ft_unscaled_font_t *unscaled; cairo_font_face_t *font_face; + cairo_font_options_t * font_options; unscaled = _cairo_ft_unscaled_font_create_for_pattern (pattern); if (unscaled == NULL) { @@ -2177,12 +2395,28 @@ cairo_ft_font_face_create_for_pattern (F _get_pattern_ft_options (pattern)); _cairo_unscaled_font_destroy (&unscaled->base); - if (font_face) - return font_face; - else { - _cairo_error (CAIRO_STATUS_NO_MEMORY); - return (cairo_font_face_t *)&_cairo_font_face_nil; + if (!font_face) + goto error; + + font_options = cairo_font_face_get_user_data (font_face, + &_cairo_ft_font_face_options_key); + + if (!font_options) { + font_options = cairo_font_options_create (); + + if (font_options) { + _cairo_ft_font_pattern_to_font_options (pattern, font_options); + cairo_font_face_set_user_data (font_face, + &_cairo_ft_font_face_options_key, + font_options, + (cairo_destroy_func_t)cairo_font_options_destroy); + } } + + return font_face; + error: + _cairo_error (CAIRO_STATUS_NO_MEMORY); + return (cairo_font_face_t *)&_cairo_font_face_nil; } /** Index: src/cairo-glitz-surface.c =================================================================== RCS file: /cvs/cairo/cairo/src/cairo-glitz-surface.c,v retrieving revision 1.71 diff -u -p -r1.71 cairo-glitz-surface.c --- src/cairo-glitz-surface.c 5 Jan 2006 13:14:14 -0000 1.71 +++ src/cairo-glitz-surface.c 13 Feb 2006 02:06:55 -0000 @@ -2174,3 +2174,12 @@ cairo_glitz_surface_create (glitz_surfac return (cairo_surface_t *) crsurface; } + +glitz_surface_t * +cairo_glitz_surface_get_glitz_surface(cairo_surface_t * crsurface) +{ + if (crsurface && (crsurface->backend == &cairo_glitz_surface_backend)) + return ((cairo_glitz_surface_t *)crsurface)->surface; + else + return NULL; +} Index: src/cairo-glitz.h =================================================================== RCS file: /cvs/cairo/cairo/src/cairo-glitz.h,v retrieving revision 1.7 diff -u -p -r1.7 cairo-glitz.h --- src/cairo-glitz.h 7 Sep 2005 23:31:22 -0000 1.7 +++ src/cairo-glitz.h 13 Feb 2006 02:06:56 -0000 @@ -48,6 +48,9 @@ CAIRO_BEGIN_DECLS cairo_public cairo_surface_t * cairo_glitz_surface_create (glitz_surface_t *surface); +glitz_surface_t * +cairo_glitz_surface_get_glitz_surface(cairo_surface_t * crsurface); + CAIRO_END_DECLS #else /* CAIRO_HAS_GLITZ_SURFACE */ Index: src/cairo-xlib-surface.c =================================================================== RCS file: /cvs/cairo/cairo/src/cairo-xlib-surface.c,v retrieving revision 1.128 diff -u -p -r1.128 cairo-xlib-surface.c --- src/cairo-xlib-surface.c 16 Dec 2005 11:02:35 -0000 1.128 +++ src/cairo-xlib-surface.c 13 Feb 2006 02:07:00 -0000 @@ -2004,38 +2004,86 @@ cairo_xlib_surface_set_drawable (cairo_s surface->height = height; } -typedef struct _cairo_xlib_surface_font_private { - Display *dpy; +#define GLYPH_INFO_MAX (3) +typedef struct _cairo_xlib_font_glyph_info { GlyphSet glyphset; XRenderPictFormat *format; +} cairo_xlib_font_glyph_info_t; + +typedef struct _cairo_xlib_surface_font_private { + Display *dpy; + cairo_xlib_font_glyph_info_t glyph_info[GLYPH_INFO_MAX]; + int num_formats; } cairo_xlib_surface_font_private_t; static cairo_status_t _cairo_xlib_surface_font_init (Display *dpy, - cairo_scaled_font_t *scaled_font, - cairo_format_t format) + cairo_scaled_font_t *scaled_font) { cairo_xlib_surface_font_private_t *font_private; - + int i; font_private = malloc (sizeof (cairo_xlib_surface_font_private_t)); if (!font_private) return CAIRO_STATUS_NO_MEMORY; font_private->dpy = dpy; - font_private->format = _CAIRO_FORMAT_XRENDER_FORMAT(dpy, format); - font_private->glyphset = XRenderCreateGlyphSet (dpy, font_private->format); + font_private->num_formats = 0; + for (i = 0; i < GLYPH_INFO_MAX; i ++) { + font_private->glyph_info[i].format = NULL; + font_private->glyph_info[i].glyphset = None; + } + scaled_font->surface_private = font_private; scaled_font->surface_backend = &cairo_xlib_surface_backend; return CAIRO_STATUS_SUCCESS; } +static cairo_xlib_font_glyph_info_t * +_cairo_xlib_surface_font_get_glyph_info (cairo_scaled_font_t *scaled_font, + cairo_format_t format) +{ + cairo_xlib_surface_font_private_t *font_private = scaled_font->surface_private; + cairo_xlib_font_glyph_info_t *glyph_info = &font_private->glyph_info[0]; + int i; + + switch (format) { + case CAIRO_FORMAT_A1: + i = 0; + break; + case CAIRO_FORMAT_A8: + i = 1; + break; + case CAIRO_FORMAT_ARGB32: + i = 2; + break; + case CAIRO_FORMAT_RGB24: + default: + ASSERT_NOT_REACHED; + } + + if (glyph_info[i].glyphset == None) { + glyph_info[i].format = _CAIRO_FORMAT_XRENDER_FORMAT(font_private->dpy, + format); + glyph_info[i].glyphset = XRenderCreateGlyphSet (font_private->dpy, + glyph_info[i].format); + font_private->num_formats ++; + } + + return glyph_info + i; +} + static void _cairo_xlib_surface_scaled_font_fini (cairo_scaled_font_t *scaled_font) { cairo_xlib_surface_font_private_t *font_private = scaled_font->surface_private; + int i; if (font_private) { - XRenderFreeGlyphSet (font_private->dpy, font_private->glyphset); + for (i = 0; i < GLYPH_INFO_MAX; i ++) { + if (font_private->glyph_info[i].glyphset) + XRenderFreeGlyphSet (font_private->dpy, + font_private->glyph_info[i].glyphset); + } free (font_private); } } @@ -2048,8 +2096,10 @@ _cairo_xlib_surface_scaled_glyph_fini (c if (font_private != NULL && scaled_glyph->surface_private != NULL) { unsigned long glyph_index = _cairo_scaled_glyph_index(scaled_glyph); + cairo_xlib_font_glyph_info_t *glyph_info = scaled_glyph->surface_private; + XRenderFreeGlyphs (font_private->dpy, - font_private->glyphset, + glyph_info->glyphset, &glyph_index, 1); } } @@ -2072,16 +2122,23 @@ _cairo_xlib_surface_add_glyph (Display * unsigned char *data; cairo_status_t status; cairo_xlib_surface_font_private_t *font_private; + cairo_xlib_font_glyph_info_t * cairo_glyph_info; cairo_image_surface_t *glyph_surface = scaled_glyph->surface; if (scaled_font->surface_private == NULL) { - status = _cairo_xlib_surface_font_init (dpy, scaled_font, - glyph_surface->format); + status = _cairo_xlib_surface_font_init (dpy, scaled_font); if (status) return status; } font_private = scaled_font->surface_private; + cairo_glyph_info = _cairo_xlib_surface_font_get_glyph_info (scaled_font, + glyph_surface->format); + if (cairo_glyph_info->glyphset == None) + return CAIRO_STATUS_NO_MEMORY; + + scaled_glyph->surface_private = cairo_glyph_info; + /* * Most of the font rendering system thinks of glyph tiles as having * an origin at (0,0) and an x and y bounding box "offset" which @@ -2186,7 +2243,7 @@ _cairo_xlib_surface_add_glyph (Display * glyph_index = _cairo_scaled_glyph_index (scaled_glyph); - XRenderAddGlyphs (dpy, font_private->glyphset, + XRenderAddGlyphs (dpy, cairo_glyph_info->glyphset, &glyph_index, &(glyph_info), 1, (char *) data, glyph_surface->stride * glyph_surface->height); @@ -2200,16 +2257,18 @@ _cairo_xlib_surface_add_glyph (Display * #define N_STACK_BUF 1024 static cairo_status_t -_cairo_xlib_surface_old_show_glyphs8 (cairo_scaled_font_t *scaled_font, - cairo_operator_t op, - cairo_xlib_surface_t *src, - cairo_xlib_surface_t *self, - int source_x, - int source_y, - const cairo_glyph_t *glyphs, - int num_glyphs) +_cairo_xlib_surface_old_show_glyphs8 (cairo_scaled_font_t *scaled_font, + cairo_operator_t op, + cairo_xlib_surface_t *src, + cairo_xlib_surface_t *self, + int source_x, + int source_y, + const cairo_glyph_t *glyphs, + int num_glyphs, + cairo_xlib_font_glyph_info_t *glyph_info, + int *x_advance, + int *y_advance) { - cairo_xlib_surface_font_private_t *font_private = scaled_font->surface_private; XGlyphElt8 *elts = NULL; XGlyphElt8 stack_elts [N_STACK_BUF]; @@ -2237,7 +2296,7 @@ _cairo_xlib_surface_old_show_glyphs8 (c chars[i] = glyphs[i].index; elts[i].chars = &(chars[i]); elts[i].nchars = 1; - elts[i].glyphset = font_private->glyphset; + elts[i].glyphset = glyph_info->glyphset; thisX = (int) floor (glyphs[i].x + 0.5); thisY = (int) floor (glyphs[i].y + 0.5); elts[i].xOff = thisX - lastX; @@ -2250,11 +2309,14 @@ _cairo_xlib_surface_old_show_glyphs8 (c _render_operator (op), src->src_picture, self->dst_picture, - font_private->format, + glyph_info->format, source_x + elts[0].xOff, source_y + elts[0].yOff, 0, 0, elts, num_glyphs); + *x_advance = elts[num_glyphs - 1].xOff; + *y_advance = elts[num_glyphs - 1].yOff; + if (elts != stack_elts) free (elts); @@ -2262,16 +2324,18 @@ _cairo_xlib_surface_old_show_glyphs8 (c } static cairo_status_t -_cairo_xlib_surface_old_show_glyphs16 (cairo_scaled_font_t *scaled_font, - cairo_operator_t op, - cairo_xlib_surface_t *src, - cairo_xlib_surface_t *self, - int source_x, - int source_y, - const cairo_glyph_t *glyphs, - int num_glyphs) +_cairo_xlib_surface_old_show_glyphs16 (cairo_scaled_font_t *scaled_font, + cairo_operator_t op, + cairo_xlib_surface_t *src, + cairo_xlib_surface_t *self, + int source_x, + int source_y, + const cairo_glyph_t *glyphs, + int num_glyphs, + cairo_xlib_font_glyph_info_t *glyph_info, + int *x_advance, + int *y_advance) { - cairo_xlib_surface_font_private_t *font_private = scaled_font->surface_private; XGlyphElt16 *elts = NULL; XGlyphElt16 stack_elts [N_STACK_BUF]; @@ -2299,7 +2363,7 @@ _cairo_xlib_surface_old_show_glyphs16 (c chars[i] = glyphs[i].index; elts[i].chars = &(chars[i]); elts[i].nchars = 1; - elts[i].glyphset = font_private->glyphset; + elts[i].glyphset = glyph_info->glyphset; thisX = (int) floor (glyphs[i].x + 0.5); thisY = (int) floor (glyphs[i].y + 0.5); elts[i].xOff = thisX - lastX; @@ -2312,11 +2376,14 @@ _cairo_xlib_surface_old_show_glyphs16 (c _render_operator (op), src->src_picture, self->dst_picture, - font_private->format, + glyph_info->format, source_x + elts[0].xOff, source_y + elts[0].yOff, 0, 0, elts, num_glyphs); + *x_advance = elts[num_glyphs - 1].xOff; + *y_advance = elts[num_glyphs - 1].yOff; + if (elts != stack_elts) free (elts); @@ -2324,16 +2391,18 @@ _cairo_xlib_surface_old_show_glyphs16 (c } static cairo_status_t -_cairo_xlib_surface_old_show_glyphs32 (cairo_scaled_font_t *scaled_font, - cairo_operator_t op, - cairo_xlib_surface_t *src, - cairo_xlib_surface_t *self, - int source_x, - int source_y, - const cairo_glyph_t *glyphs, - int num_glyphs) +_cairo_xlib_surface_old_show_glyphs32 (cairo_scaled_font_t *scaled_font, + cairo_operator_t op, + cairo_xlib_surface_t *src, + cairo_xlib_surface_t *self, + int source_x, + int source_y, + const cairo_glyph_t *glyphs, + int num_glyphs, + cairo_xlib_font_glyph_info_t *glyph_info, + int *x_advance, + int *y_advance) { - cairo_xlib_surface_font_private_t *font_private = scaled_font->surface_private; XGlyphElt32 *elts = NULL; XGlyphElt32 stack_elts [N_STACK_BUF]; @@ -2361,7 +2430,7 @@ _cairo_xlib_surface_old_show_glyphs32 (c chars[i] = glyphs[i].index; elts[i].chars = &(chars[i]); elts[i].nchars = 1; - elts[i].glyphset = font_private->glyphset; + elts[i].glyphset = glyph_info->glyphset; thisX = (int) floor (glyphs[i].x + 0.5); thisY = (int) floor (glyphs[i].y + 0.5); elts[i].xOff = thisX - lastX; @@ -2374,11 +2443,14 @@ _cairo_xlib_surface_old_show_glyphs32 (c _render_operator (op), src->src_picture, self->dst_picture, - font_private->format, + glyph_info->format, source_x + elts[0].xOff, source_y + elts[0].yOff, 0, 0, elts, num_glyphs); + *x_advance = elts[num_glyphs - 1].xOff; + *y_advance = elts[num_glyphs - 1].yOff; + if (elts != stack_elts) free (elts); @@ -2405,9 +2477,13 @@ _cairo_xlib_surface_old_show_glyphs (cai cairo_xlib_surface_t *src; composite_operation_t operation; cairo_scaled_glyph_t *scaled_glyph; + cairo_xlib_font_glyph_info_t *glyphs_info; cairo_xlib_surface_font_private_t *font_private; - int i; unsigned long max_index = 0; + int x_offset, y_offset; + int x_advance, y_advance; + int i, boundary, done; + if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE_TEXT (self) || !self->format) @@ -2423,23 +2499,27 @@ _cairo_xlib_surface_old_show_glyphs (cai (font_private != NULL && font_private->dpy != self->dpy)) return CAIRO_INT_STATUS_UNSUPPORTED; + glyphs_info = malloc (sizeof (cairo_xlib_font_glyph_info_t) * num_glyphs); + if (glyphs_info == NULL) + return CAIRO_STATUS_NO_MEMORY; + status = _cairo_pattern_acquire_surface (pattern, &self->base, source_x, source_y, width, height, (cairo_surface_t **) &src, &attributes); if (status) - return status; + goto FAIL; operation = _recategorize_composite_operation (self, op, src, &attributes, TRUE); if (operation == DO_UNSUPPORTED) { status = CAIRO_INT_STATUS_UNSUPPORTED; - goto FAIL; + goto FAIL1; } status = _cairo_xlib_surface_set_attributes (src, &attributes); if (status) - goto FAIL; - + goto FAIL1; + /* Send all unsent glyphs to the server */ for (i = 0; i < num_glyphs; i++) { if (glyphs[i].index > max_index) @@ -2452,28 +2532,73 @@ _cairo_xlib_surface_old_show_glyphs (cai return status; if (scaled_glyph->surface_private == NULL) { _cairo_xlib_surface_add_glyph (self->dpy, scaled_font, scaled_glyph); - scaled_glyph->surface_private = (void *) 1; } + glyphs_info[i] = *(cairo_xlib_font_glyph_info_t *)scaled_glyph->surface_private; } _cairo_xlib_surface_ensure_dst_picture (self); /* Call the appropriate sub-function. */ + font_private = scaled_font->surface_private; + x_offset = source_x + attributes.x_offset - dest_x; + y_offset = source_y + attributes.y_offset - dest_y; + done = 0; + + if (font_private->num_formats == 1) { + if (max_index < 256) + status = _cairo_xlib_surface_old_show_glyphs8 (scaled_font, op, + src, self, + x_offset, y_offset, + glyphs, num_glyphs, + &glyphs_info[done], + &x_advance, &y_advance); + else if (max_index < 65536) + status = _cairo_xlib_surface_old_show_glyphs16 (scaled_font, op, + src, self, + x_offset, y_offset, + glyphs, num_glyphs, + &glyphs_info[done], + &x_advance, &y_advance); + else + status = _cairo_xlib_surface_old_show_glyphs32 (scaled_font, op, + src, self, + x_offset, y_offset, + glyphs, num_glyphs, + &glyphs_info[done], + &x_advance, &y_advance); + } else { + while (done < num_glyphs && !status) { + for (boundary = done + 1; boundary < num_glyphs; boundary ++) { + if (glyphs_info[boundary - 1].glyphset != glyphs_info[boundary].glyphset) + break; + } - if (max_index < 256) - status = _cairo_xlib_surface_old_show_glyphs8 (scaled_font, op, src, self, - source_x + attributes.x_offset - dest_x, - source_y + attributes.y_offset - dest_y, - glyphs, num_glyphs); - else if (max_index < 65536) - status = _cairo_xlib_surface_old_show_glyphs16 (scaled_font, op, src, self, - source_x + attributes.x_offset - dest_x, - source_y + attributes.y_offset - dest_y, - glyphs, num_glyphs); - else - status = _cairo_xlib_surface_old_show_glyphs32 (scaled_font, op, src, self, - source_x + attributes.x_offset - dest_x, - source_y + attributes.y_offset - dest_y, - glyphs, num_glyphs); + if (max_index < 256) + status = _cairo_xlib_surface_old_show_glyphs8 (scaled_font, op, + src, self, + x_offset, y_offset, + glyphs, boundary - done, + &glyphs_info[done], + &x_advance, &y_advance); + else if (max_index < 65536) + status = _cairo_xlib_surface_old_show_glyphs16 (scaled_font, op, + src, self, + x_offset, y_offset, + glyphs, boundary - done, + &glyphs_info[done], + &x_advance, &y_advance); + else + status = _cairo_xlib_surface_old_show_glyphs32 (scaled_font, op, + src, self, + x_offset, y_offset, + glyphs, boundary - done, + &glyphs_info[done], + &x_advance, &y_advance); + glyphs += boundary - done; + x_offset += x_advance; + y_offset += y_advance; + done = boundary; + } + } if (status == CAIRO_STATUS_SUCCESS && !_cairo_operator_bounded_by_mask (op)) { cairo_rectangle_t extents; @@ -2490,8 +2615,10 @@ _cairo_xlib_surface_old_show_glyphs (cai dest_x, dest_y, width, height); } - FAIL: + FAIL1: _cairo_pattern_release_surface (pattern, &src->base, &attributes); - + FAIL: + free (glyphs_info); + return status; } Index: test/Makefile.am =================================================================== RCS file: /cvs/cairo/cairo/test/Makefile.am,v retrieving revision 1.109 diff -u -p -r1.109 Makefile.am --- test/Makefile.am 18 Jan 2006 00:59:08 -0000 1.109 +++ test/Makefile.am 13 Feb 2006 02:07:01 -0000 @@ -37,6 +37,7 @@ paint-with-alpha \ path-data \ pixman-rotate \ rectangle-rounding-error \ +rotate-source-surface-paint \ scale-source-surface-paint \ select-font-no-show-text \ self-copy \ @@ -161,6 +162,8 @@ rectangle-rounding-error-ref.png \ rectangle-rounding-error-rgb24-ref.png \ rel-path-ref.png \ rel-path-rgb24-ref.png \ +rotate-source-surface-paint-ref.png \ +rotate-source-surface-paint-rgb24-ref.png \ romedalen.png \ scale-source-surface-paint-ref.png \ scale-source-surface-paint-rgb24-ref.png \ @@ -322,6 +325,7 @@ svg_clip_LDADD = $(LDADDS) pixman_rotate_LDADD = $(LDADDS) pthread_show_text_LDADD = $(LDADDS) rectangle_rounding_error_LDADD = $(LDADDS) +rotate_source_surface_paint_LDADD = $(LDADDS) scale_source_surface_paint_LDADD = $(LDADDS) select_font_no_show_text_LDADD = $(LDADDS) self_copy_LDADD = $(LDADDS) Index: test/rotate-source-surface-paint.c =================================================================== RCS file: test/rotate-source-surface-paint.c diff -N test/rotate-source-surface-paint.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ test/rotate-source-surface-paint.c 13 Feb 2006 02:07:02 -0000 @@ -0,0 +1,61 @@ +/* + * Copyright © 2005 Jinghua Luo + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of + * Red Hat, Inc. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Jinghua Luo makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * JINGHUA LUO DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR + * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Jinghua Luo + */ + +#include "cairo-test.h" + +#define SIZE 100 +const char png_filename[] = "romedalen.png"; + +cairo_test_t test = { + "rotate-source-surface-paint", + "Test cairo_rotate, cairo_set_source_surface and cairo_paint", + SIZE, SIZE +}; + +static cairo_test_status_t +draw (cairo_t *cr, int width, int height) +{ + cairo_surface_t *surface; + + surface = cairo_image_surface_create_from_png (png_filename); + + cairo_save (cr); + + cairo_translate (cr, width / 2., height / 2.); + cairo_rotate (cr, 3.14159265 / 6.0); + cairo_set_source_surface (cr, surface, 0, 0); + cairo_paint (cr); + + cairo_restore (cr); + + cairo_surface_destroy (surface); + return CAIRO_TEST_SUCCESS; +} + +int +main (void) +{ + return cairo_test (&test, draw); +}