/* cairo - a vector graphics library with display and print output
 *
 * Copyright © 2003 University of Southern California
 *
 * This library is free software; you can redistribute it and/or
 * modify it either under the terms of the GNU Lesser General Public
 * License version 2.1 as published by the Free Software Foundation
 * (the "LGPL") or, at your option, under the terms of the Mozilla
 * Public License Version 1.1 (the "MPL"). If you do not alter this
 * notice, a recipient may use your version of this file under either
 * the MPL or the LGPL.
 *
 * You should have received a copy of the LGPL along with this library
 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
 * You should have received a copy of the MPL along with this library
 * in the file COPYING-MPL-1.1
 *
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
 * the specific language governing rights and limitations.
 *
 * The Original Code is the cairo graphics library.
 *
 * The Initial Developer of the Original Code is University of Southern
 * California.
 *
 * Contributor(s):
 *    Michael Emmel <mike.emmel@gmail.com>
 *    Claudio Ciccani <klan@users.sf.net>
 */

#include "cairoint.h"
#include "cairo-directfb.h"

#include "cairo-clip-private.h"
#include "cairo-error-private.h"

#include <pixman.h>

#include <directfb.h>
#include <direct/types.h>
#include <direct/debug.h>
#include <direct/memcpy.h>
#include <direct/util.h>

/*
 * Rectangle works fine.
 * Bugs 361377, 359553, 359243 in Gnome BTS are caused
 * by GDK/DirectFB, not by Cairo/DirectFB.
 */
#define DFB_RECTANGLES 1

/*
 * Composite works fine.
 */
#define DFB_COMPOSITE 1

/*
 * CompositeTrapezoids works (without antialiasing).
 */
#define DFB_COMPOSITE_TRAPEZOIDS 1

/*
 * ShowGlyphs works fine.
 */
#define DFB_SHOW_GLYPHS 1

#define PIXMAN_invalid (pixman_format_code_t) 0


D_DEBUG_DOMAIN (CairoDFB_Acquire, "CairoDFB/Acquire", "Cairo DirectFB Acquire");
D_DEBUG_DOMAIN (CairoDFB_Clip,    "CairoDFB/Clip",    "Cairo DirectFB Clipping");
D_DEBUG_DOMAIN (CairoDFB_Font,    "CairoDFB/Font",    "Cairo DirectFB Font Rendering");
D_DEBUG_DOMAIN (CairoDFB_Render,  "CairoDFB/Render",  "Cairo DirectFB Rendering");
D_DEBUG_DOMAIN (CairoDFB_Surface, "CairoDFB/Surface", "Cairo DirectFB Surface");

/*****************************************************************************/

typedef struct _cairo_directfb_surface {
    cairo_surface_t	base;

    pixman_format_code_t	pixman_format;
    cairo_bool_t		supported_destination;

    IDirectFB			*dfb;
    IDirectFBSurface		*dfbsurface;
    IDirectFBSurface		*tmpsurface;
    pixman_format_code_t	 tmpformat;

    int                  width;
    int                  height;

    unsigned             local : 1;
    unsigned             blit_premultiplied : 1;
} cairo_directfb_surface_t;


typedef struct _cairo_directfb_font_cache {
    IDirectFB           *dfb;
    IDirectFBSurface    *dfbsurface;

    int                  width;
    int                  height;

    /* coordinates within the surface
     * of the last loaded glyph */
    int                  x;
    int                  y;
} cairo_directfb_font_cache_t;

static cairo_surface_backend_t _cairo_directfb_surface_backend;

/*****************************************************************************/

static int _directfb_argb_font = 1;

/*****************************************************************************/

#define RUN_CLIPPED(surface, clip_region, clip, func) {\
    if ((clip_region) != NULL) {\
	int n_clips = cairo_region_num_rectangles (clip_region), n; \
        for (n = 0; n < n_clips; n++) {\
            if (clip) {\
                DFBRegion  reg, *cli = (clip); \
		cairo_rectangle_int_t rect; \
		cairo_region_get_rectangle (clip_region, n, &rect); \
		reg.x1 = rect.x; \
		reg.y1 = rect.y; \
		reg.x2 = rect.x + rect.width - 1; \
		reg.y2 = rect.y + rect.height - 1; \
                if (reg.x2 < cli->x1 || reg.y2 < cli->y1 ||\
                    reg.x1 > cli->x2 || reg.y1 > cli->y2)\
                    continue;\
                if (reg.x1 < cli->x1)\
                    reg.x1 = cli->x1;\
                if (reg.y1 < cli->y1)\
                    reg.y1 = cli->y1;\
                if (reg.x2 > cli->x2)\
                    reg.x2 = cli->x2;\
                if (reg.y2 > cli->y2)\
                    reg.y2 = cli->y2;\
                (surface)->dfbsurface->SetClip ((surface)->dfbsurface, &reg);\
            } else {\
		DFBRegion reg; \
		cairo_rectangle_int_t rect; \
		cairo_region_get_rectangle (clip_region, n, &rect); \
		reg.x1 = rect.x; \
		reg.y1 = rect.y; \
		reg.x2 = rect.x + rect.width - 1; \
		reg.y2 = rect.y + rect.height - 1; \
                (surface)->dfbsurface->SetClip ((surface)->dfbsurface, &reg); \
            }\
            func;\
        }\
    } else {\
        (surface)->dfbsurface->SetClip ((surface)->dfbsurface, clip);\
        func;\
    }\
}

#define TRANSFORM_POINT2X(m, x, y, ret_x, ret_y) do { \
    double _x = (x); \
    double _y = (y); \
    (ret_x) = (_x * (m).xx + (m).x0); \
    (ret_y) = (_y * (m).yy + (m).y0); \
} while (0)

#define TRANSFORM_POINT3X(m, x, y, ret_x, ret_y) do { \
    double _x = (x); \
    double _y = (y); \
    (ret_x) = (_x * (m).xx + _y * (m).xy + (m).x0); \
    (ret_y) = (_x * (m).yx + _y * (m).yy + (m).y0); \
} while (0)

static cairo_bool_t _cairo_surface_is_dfb (cairo_surface_t *surface)
{
    return surface->backend == &_cairo_directfb_surface_backend;
}

/* XXX: A1 has a different bits ordering in cairo.
 *      Probably we should drop it.
 */

static cairo_content_t
_directfb_format_to_content (DFBSurfacePixelFormat format)
{
    if (DFB_PIXELFORMAT_HAS_ALPHA (format)) {
        if (DFB_COLOR_BITS_PER_PIXEL (format))
            return CAIRO_CONTENT_COLOR_ALPHA;

        return CAIRO_CONTENT_ALPHA;
    }

    return CAIRO_CONTENT_COLOR;
}

static inline DFBSurfacePixelFormat
_cairo_to_directfb_format (cairo_format_t format)
{
    switch (format) {
    case CAIRO_FORMAT_RGB24:
	return DSPF_RGB32;
    case CAIRO_FORMAT_ARGB32:
	return DSPF_ARGB;
    case CAIRO_FORMAT_A8:
	return DSPF_A8;
    case CAIRO_FORMAT_A1:
	return DSPF_A1;
    default:
	break;
    }

    return -1;
}

static inline pixman_format_code_t
_directfb_to_pixman_format (DFBSurfacePixelFormat format)
{
    switch (format) {
    case DSPF_UNKNOWN: return PIXMAN_invalid;
    case DSPF_ARGB1555: return PIXMAN_a1r5g5b5;
    case DSPF_RGB16: return PIXMAN_r5g6b5;
    case DSPF_RGB24: return PIXMAN_r8g8b8;
    case DSPF_RGB32: return PIXMAN_x8r8g8b8;
    case DSPF_ARGB: return PIXMAN_a8r8g8b8;
    case DSPF_A8: return PIXMAN_a8;
    case DSPF_YUY2: return PIXMAN_yuy2;
    case DSPF_RGB332: return PIXMAN_r3g3b2;
    case DSPF_UYVY: return PIXMAN_invalid;
    case DSPF_I420: return PIXMAN_invalid;
    case DSPF_YV12: return PIXMAN_yv12;
    case DSPF_LUT8: return PIXMAN_invalid;
    case DSPF_ALUT44: return PIXMAN_invalid;
    case DSPF_AiRGB: return PIXMAN_invalid;
    case DSPF_A1: return PIXMAN_a1; /* bit reversed, oops */
    case DSPF_NV12: return PIXMAN_invalid;
    case DSPF_NV16: return PIXMAN_invalid;
    case DSPF_ARGB2554: return PIXMAN_invalid;
    case DSPF_ARGB4444: return PIXMAN_a4r4g4b4;
    case DSPF_NV21: return PIXMAN_invalid;
    case DSPF_AYUV: return PIXMAN_invalid;
    case DSPF_A4: return PIXMAN_a4;
    case DSPF_ARGB1666: return PIXMAN_invalid;
    case DSPF_ARGB6666: return PIXMAN_invalid;
    case DSPF_RGB18: return PIXMAN_invalid;
    case DSPF_LUT2: return PIXMAN_invalid;
    case DSPF_RGB444: return PIXMAN_x4r4g4b4;
    case DSPF_RGB555: return PIXMAN_x1r5g5b5;
#if DFB_NUM_PIXELFORMATS >= 29
    case DSPF_BGR555: return PIXMAN_x1b5g5r5;
#endif
    }
    return PIXMAN_invalid;
}

static inline DFBSurfacePixelFormat
_directfb_from_pixman_format (pixman_format_code_t format)
{
    switch ((int) format) {
    case PIXMAN_a1r5g5b5: return DSPF_ARGB1555;
    case PIXMAN_r5g6b5: return DSPF_RGB16;
    case PIXMAN_r8g8b8: return DSPF_RGB24;
    case PIXMAN_x8r8g8b8: return DSPF_RGB32;
    case PIXMAN_a8r8g8b8: return DSPF_ARGB;
    case PIXMAN_a8: return DSPF_A8;
    case PIXMAN_yuy2: return DSPF_YUY2;
    case PIXMAN_r3g3b2: return DSPF_RGB332;
    case PIXMAN_yv12: return DSPF_YV12;
    case PIXMAN_a1: return DSPF_A1; /* bit reversed, oops */
    case PIXMAN_a4r4g4b4: return DSPF_ARGB4444;
    case PIXMAN_a4: return DSPF_A4;
    case PIXMAN_x4r4g4b4: return DSPF_RGB444;
    case PIXMAN_x1r5g5b5: return DSPF_RGB555;
#if DFB_NUM_PIXELFORMATS >= 29
    case PIXMAN_x1b5g5r5: return DSPF_BGR555;
#endif
    default: return 0;
    }
}

static cairo_bool_t
_directfb_get_operator (cairo_operator_t         operator,
                        DFBSurfaceBlendFunction *ret_srcblend,
                        DFBSurfaceBlendFunction *ret_dstblend)
{
    DFBSurfaceBlendFunction srcblend = DSBF_ONE;
    DFBSurfaceBlendFunction dstblend = DSBF_ZERO;

    switch (operator) {
    case CAIRO_OPERATOR_CLEAR:
	srcblend = DSBF_ZERO;
	dstblend = DSBF_ZERO;
	break;
    case CAIRO_OPERATOR_SOURCE:
	srcblend = DSBF_ONE;
	dstblend = DSBF_ZERO;
	break;
    case CAIRO_OPERATOR_OVER:
	srcblend = DSBF_ONE;
	dstblend = DSBF_INVSRCALPHA;
	break;
    case CAIRO_OPERATOR_IN:
	srcblend = DSBF_DESTALPHA;
	dstblend = DSBF_ZERO;
	break;
    case CAIRO_OPERATOR_OUT:
	srcblend = DSBF_INVDESTALPHA;
	dstblend = DSBF_ZERO;
	break;
    case CAIRO_OPERATOR_ATOP:
	srcblend = DSBF_DESTALPHA;
	dstblend = DSBF_INVSRCALPHA;
	break;
    case CAIRO_OPERATOR_DEST:
	srcblend = DSBF_ZERO;
	dstblend = DSBF_ONE;
	break;
    case CAIRO_OPERATOR_DEST_OVER:
	srcblend = DSBF_INVDESTALPHA;
	dstblend = DSBF_ONE;
	break;
    case CAIRO_OPERATOR_DEST_IN:
	srcblend = DSBF_ZERO;
	dstblend = DSBF_SRCALPHA;
	break;
    case CAIRO_OPERATOR_DEST_OUT:
	srcblend = DSBF_ZERO;
	dstblend = DSBF_INVSRCALPHA;
	break;
    case CAIRO_OPERATOR_DEST_ATOP:
	srcblend = DSBF_INVDESTALPHA;
	dstblend = DSBF_SRCALPHA;
	break;
    case CAIRO_OPERATOR_XOR:
	srcblend = DSBF_INVDESTALPHA;
	dstblend = DSBF_INVSRCALPHA;
	break;
    case CAIRO_OPERATOR_ADD:
	srcblend = DSBF_ONE;
	dstblend = DSBF_ONE;
	break;
    case CAIRO_OPERATOR_SATURATE:
	/* XXX This does not work. */
#if 0
	srcblend = DSBF_SRCALPHASAT;
	dstblend = DSBF_ONE;
	break;
#endif
    case CAIRO_OPERATOR_MULTIPLY:
    case CAIRO_OPERATOR_SCREEN:
    case CAIRO_OPERATOR_OVERLAY:
    case CAIRO_OPERATOR_DARKEN:
    case CAIRO_OPERATOR_LIGHTEN:
    case CAIRO_OPERATOR_COLOR_DODGE:
    case CAIRO_OPERATOR_COLOR_BURN:
    case CAIRO_OPERATOR_HARD_LIGHT:
    case CAIRO_OPERATOR_SOFT_LIGHT:
    case CAIRO_OPERATOR_DIFFERENCE:
    case CAIRO_OPERATOR_EXCLUSION:
    case CAIRO_OPERATOR_HSL_HUE:
    case CAIRO_OPERATOR_HSL_SATURATION:
    case CAIRO_OPERATOR_HSL_COLOR:
    case CAIRO_OPERATOR_HSL_LUMINOSITY:
    default:
	return FALSE;
    }

    *ret_srcblend = srcblend;
    *ret_dstblend = dstblend;

    return TRUE;
}

static cairo_status_t
_directfb_buffer_surface_create (IDirectFB             *dfb,
                                 DFBSurfacePixelFormat  format,
                                 int                    width,
                                 int                    height,
				 IDirectFBSurface     **out)
{
    IDirectFBSurface      *buffer;
    DFBSurfaceDescription  dsc;
    DFBResult              ret;

    dsc.flags       = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT;
    dsc.caps        = DSCAPS_PREMULTIPLIED;
    dsc.width       = width;
    dsc.height      = height;
    dsc.pixelformat = format;

    ret = dfb->CreateSurface (dfb, &dsc, &buffer);
    buffer->Clear(buffer,0,0,0,0);
    //printf("CreateSurface _directfb_buffer_surface_create %x\n", buffer);
    if (ret) {
        DirectFBError ("IDirectFB::CreateSurface()", ret);
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
    }

    *out = buffer;
    return CAIRO_STATUS_SUCCESS;
}

static cairo_status_t
_directfb_acquire_surface (cairo_directfb_surface_t  *surface,
                           cairo_rectangle_int_t     *intrest_rec,
                           cairo_image_surface_t    **image_out,
                           cairo_rectangle_int_t     *image_rect_out,
                           void                     **image_extra,
                           DFBSurfaceLockFlags        lock_flags)
{
    //printf("cairo acquire \n");
    IDirectFBSurface *buffer = NULL;
    DFBRectangle source_rect;
    cairo_surface_t *image;
    pixman_image_t *pixman_image;
    pixman_format_code_t pixman_format;
    cairo_status_t status;
    void *data;
    int   pitch;

    if (surface->pixman_format == PIXMAN_invalid) {
        if (intrest_rec != NULL) {
            source_rect.x = intrest_rec->x;
            source_rect.y = intrest_rec->y;
            source_rect.w = intrest_rec->width;
            source_rect.h = intrest_rec->height;
        } else {
            source_rect.x = 0;
            source_rect.y = 0;
            surface->dfbsurface->GetSize (surface->dfbsurface,
                                          &source_rect.w, &source_rect.h);
        }

        if (surface->tmpsurface != NULL) {
            int w, h;

            surface->tmpsurface->GetSize (surface->tmpsurface, &w, &h);
            if (w < source_rect.w || h < source_rect.h) {
                //printf("release dfb surface %x\n", surface->tmpsurface);
                surface->tmpsurface->Release (surface->tmpsurface);
                surface->tmpsurface = NULL;
                surface->tmpformat = PIXMAN_invalid;
            }
        }

        if (surface->tmpsurface == NULL) {
	    DFBSurfacePixelFormat format;

            D_DEBUG_AT (CairoDFB_Acquire, "Allocating buffer for surface %p.\n", surface);

	    format = _cairo_to_directfb_format (_cairo_format_from_content (surface->base.content));
            status =
                _directfb_buffer_surface_create (surface->dfb, format,
                                                 source_rect.w, source_rect.h,
						 &surface->tmpsurface);
            if (unlikely (status))
                goto ERROR;

	    surface->tmpformat = _directfb_to_pixman_format (format);
        }
        buffer = surface->tmpsurface;
	pixman_format = surface->tmpformat;


/*        surface->dfbsurface->GetCapabilities (surface->dfbsurface, &caps);
        DFBSurfaceCapabilities caps;
        if (caps & DSCAPS_FLIPPING) {
            DFBRegion region = { .x1 = source_rect.x, .y1 = source_rect.y,
                                 .x2 = source_rect.x + source_rect.w - 1,
                                 .y2 = source_rect.y + source_rect.h - 1 };
            surface->dfbsurface->Flip (surface->dfbsurface, &region, DSFLIP_BLIT);
        } */
        buffer->Blit (buffer, surface->dfbsurface, &source_rect, 0, 0);
    } else {
        /*might be a subsurface get the offset*/
        surface->dfbsurface->GetVisibleRectangle (surface->dfbsurface, &source_rect);
        pixman_format = surface->pixman_format;
        buffer = surface->dfbsurface;
    }

    if (buffer->Lock (buffer, lock_flags, &data, &pitch)) {
        D_DEBUG_AT (CairoDFB_Acquire, "Couldn't lock surface!\n");
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
        goto ERROR;
    }

    pixman_image = pixman_image_create_bits (pixman_format,
					     source_rect.w, source_rect.h,
					     data, pitch);
    if (pixman_image == NULL) {
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
	goto ERROR;
    }

    //printf("creating an image surface %d\n",__LINE__);
    image = _cairo_image_surface_create_for_pixman_image (pixman_image,
							  pixman_format);
    status = image->status;
    if (status)
        goto ERROR;

    if (image_rect_out) {
        image_rect_out->x = source_rect.x;
        image_rect_out->y = source_rect.y;
        image_rect_out->width = source_rect.w;
        image_rect_out->height = source_rect.h;
    } else {
        /* lock for read */
        /* might be a subsurface */
        if (buffer == surface->dfbsurface) {
            cairo_surface_set_device_offset (image,
					     source_rect.x, source_rect.y);
	}
    }

    *image_extra = buffer;
    *image_out = (cairo_image_surface_t *) image;
    return CAIRO_STATUS_SUCCESS;

ERROR:
    if (buffer) {
        buffer->Unlock (buffer);
        if (buffer != surface->dfbsurface)
            buffer->Release (buffer);
    }
    return status;
}

static cairo_surface_t *
_cairo_directfb_surface_create_internal (IDirectFB *dfb,
					 DFBSurfacePixelFormat format,
					 cairo_content_t content,
					 int              width,
					 int              height)
{
    cairo_directfb_surface_t *surface;
    cairo_status_t	      status;

    surface = calloc (1, sizeof (cairo_directfb_surface_t));
    if (unlikely (surface == NULL))
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));

    surface->dfb = dfb;

//    if (width < 8 || height < 8) {
    if(0){
        IDirectFBSurface *tmp;
	DFBRectangle rect = { .x=0, .y=0, .w=width, .h=height };

        /* Some cards (e.g. Matrox) don't support surfaces smaller than 8x8 */
        status =  _directfb_buffer_surface_create (dfb, format,
                                        MAX (width, 8), MAX (height, 8),
					&tmp);
	if (status) {
	    free (surface);
	    return _cairo_surface_create_in_error (status);
	}

	tmp->GetSubSurface (tmp, &rect, &surface->dfbsurface);
        //printf("release surface %x %d\n", tmp, __LINE__);
	tmp->Release (tmp);
    } else {
	status = _directfb_buffer_surface_create (dfb, format,
						  width, height,
						  &surface->dfbsurface);
	if (status) {
	    free (surface);
	    return _cairo_surface_create_in_error (status);
	}
    }

    _cairo_surface_init (&surface->base,
			 &_cairo_directfb_surface_backend,
			 NULL, /* device */
			 content);
    surface->pixman_format = _directfb_to_pixman_format (format);
    surface->supported_destination = pixman_format_supported_destination (surface->pixman_format);

    surface->width   = width;
    surface->height  = height;
    surface->local   = TRUE;
    surface->blit_premultiplied = TRUE;
    
//    cairo_surface_set_user_data(&surface->base, (const cairo_user_data_key_t *) 1234, surface->dfbsurface, NULL);

    return &surface->base;
}

static cairo_surface_t *
_cairo_directfb_surface_create_similar (void            *abstract_src,
                                        cairo_content_t  content,
                                        int              width,
                                        int              height)
{
    cairo_directfb_surface_t *other  = abstract_src;
    DFBSurfacePixelFormat     format;

    D_DEBUG_AT (CairoDFB_Surface,
                "%s( src=%p, content=0x%x, width=%d, height=%d).\n",
                __FUNCTION__, other, content, width, height);

    width = (width <= 0) ? 1 : width;
    height = (height<= 0) ? 1 : height;

    format = _cairo_to_directfb_format (_cairo_format_from_content (content));
    return _cairo_directfb_surface_create_internal (other->dfb, format,
						    content, width, height);
}

static cairo_status_t
_cairo_directfb_surface_finish (void *data)
{
    cairo_directfb_surface_t *surface = (cairo_directfb_surface_t *)data;

    D_DEBUG_AT (CairoDFB_Surface, "%s( surface=%p ).\n", __FUNCTION__, surface);

    if (surface->tmpsurface) {
        //printf("Release %x %d\n", surface->tmpsurface, __LINE__);
        surface->tmpsurface->Release (surface->tmpsurface);
        surface->tmpsurface = NULL;
    }

    if (surface->dfbsurface) {
        //printf("Release %x %d\n", surface->dfbsurface, __LINE__);
        surface->dfbsurface->Release (surface->dfbsurface);
        surface->dfbsurface = NULL;
    }

    if (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)
{
    //printf("_cairo_directfb_surface_acquire_source_image\n");
    cairo_directfb_surface_t *surface = abstract_surface;

    D_DEBUG_AT (CairoDFB_Acquire,
		"%s( surface=%p ).\n", __FUNCTION__, surface);

    return _directfb_acquire_surface (surface, NULL, image_out,
				      NULL, image_extra, DSLF_READ);
}

static void
_cairo_directfb_surface_release_source_image (void                  *abstract_surface,
                                              cairo_image_surface_t *image,
                                              void                  *image_extra)
{
    //printf("_cairo_directfb_surface_release_source_image\n");
    IDirectFBSurface *buffer = image_extra;

    D_DEBUG_AT (CairoDFB_Acquire,
		"%s( release=%p ).\n", __FUNCTION__, abstract_surface);

    buffer->Unlock (buffer);

    cairo_surface_destroy (&image->base);
}

static cairo_status_t
_cairo_directfb_surface_acquire_dest_image (void                     *abstract_surface,
                                            cairo_rectangle_int_t    *interest_rect,
                                            cairo_image_surface_t   **image_out,
                                            cairo_rectangle_int_t    *image_rect_out,
                                            void                    **image_extra)
{
    //printf("_cairo_directfb_surface_acquire_dest_image\n");
       
    cairo_directfb_surface_t *surface = abstract_surface;

    D_DEBUG_AT (CairoDFB_Acquire,
		"%s( surface=%p (%dx%d), interest_rect={ %u %u %u %u } ).\n",
		__FUNCTION__, surface, surface->width, surface->height,
		interest_rect ? interest_rect->x : 0,
		interest_rect ? interest_rect->y : 0,
		interest_rect ? interest_rect->width  : (unsigned) surface->width,
		interest_rect ? interest_rect->height : (unsigned) surface->height);

    return _directfb_acquire_surface (surface, interest_rect, image_out,
				      image_rect_out, image_extra,
				      DSLF_READ | DSLF_WRITE);
}

static void
_cairo_directfb_surface_release_dest_image (void                  *abstract_surface,
                                            cairo_rectangle_int_t *interest_rect,
                                            cairo_image_surface_t *image,
                                            cairo_rectangle_int_t *image_rect,
                                            void                  *image_extra)
{
    //printf("_cairo_directfb_surface_release_dest_image\n");
    cairo_directfb_surface_t *surface = abstract_surface;
    IDirectFBSurface *buffer = image_extra;

    D_DEBUG_AT (CairoDFB_Acquire,
		"%s( surface=%p ).\n", __FUNCTION__, surface);

    buffer->Unlock (buffer);

    if (surface->dfbsurface != buffer) {
	DFBRegion region = {
	    .x1 = interest_rect->x,
	    .y1 = interest_rect->y,
	    .x2 = interest_rect->x + interest_rect->width - 1,
	    .y2 = interest_rect->y + interest_rect->height - 1
	};
	surface->dfbsurface->SetBlittingFlags (surface->dfbsurface, DSBLIT_NOFX);
        surface->dfbsurface->SetClip (surface->dfbsurface, &region);
	surface->dfbsurface->Blit (surface->dfbsurface,
				   buffer, NULL,
				   image_rect->x, image_rect->y);
    }

    cairo_surface_destroy (&image->base);
}

static cairo_status_t
_cairo_directfb_surface_clone_similar (void             *abstract_surface,
                                       cairo_surface_t  *src,
                                       int               src_x,
                                       int               src_y,
                                       int               width,
                                       int               height,
                                       int              *clone_offset_x,
                                       int              *clone_offset_y,
                                       cairo_surface_t **clone_out)
{
    cairo_directfb_surface_t *surface = abstract_surface;
    cairo_directfb_surface_t *clone;

    D_DEBUG_AT (CairoDFB_Surface,
		"%s( surface=%p, src=%p ).\n", __FUNCTION__, surface, src);

    if (src->backend == surface->base.backend) {
	*clone_offset_x = 0;
	*clone_offset_y = 0;
	*clone_out = 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;
	DFBSurfacePixelFormat format;
	DFBResult              ret;
	pixman_image_t	      *pixman_image;
	void *data;
	int pitch;

	format = _directfb_from_pixman_format (image_src->pixman_format);
	if (format == 0)
	    return CAIRO_INT_STATUS_UNSUPPORTED;

	clone = (cairo_directfb_surface_t *)
	    _cairo_directfb_surface_create_internal (surface->dfb, format,
						     image_src->base.content,
						     width, height);
	if (unlikely (clone->base.status))
	    return clone->base.status;

	ret = clone->dfbsurface->Lock (clone->dfbsurface,
				       DSLF_WRITE, (void *)&data, &pitch);
	if (ret) {
	    DirectFBError ("IDirectFBSurface::Lock()", ret);
	    cairo_surface_destroy (&clone->base);
	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
	}

	pixman_image = pixman_image_create_bits (clone->pixman_format,
						 width, height,
						 data, pitch);
	if (unlikely (pixman_image == NULL)) {
	    DirectFBError ("IDirectFBSurface::Lock()", ret);
	    cairo_surface_destroy (&clone->base);
	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
	}

	pixman_image_composite32 (PIXMAN_OP_SRC,
                                  image_src->pixman_image,
                                  NULL,
                                  pixman_image,
                                  src_x, src_y,
                                  0, 0,
                                  0, 0,
                                  width, height);

	pixman_image_unref (pixman_image);

	clone->dfbsurface->Unlock (clone->dfbsurface);

	*clone_offset_x = src_x;
	*clone_offset_y = src_y;
	*clone_out = &clone->base;
	return CAIRO_STATUS_SUCCESS;
    }

    return CAIRO_INT_STATUS_UNSUPPORTED;
}

#if DFB_COMPOSITE || DFB_COMPOSITE_TRAPEZOIDS
static cairo_int_status_t
_directfb_prepare_composite (cairo_directfb_surface_t    *dst,
                             const cairo_pattern_t       *src_pattern,
                             const cairo_pattern_t       *mask_pattern,
                             cairo_operator_t             op,
                             int *src_x,             int *src_y,
                             int *mask_x,            int *mask_y,
                             unsigned int                 width,
                             unsigned int                 height,
                             cairo_directfb_surface_t   **ret_src,
                             cairo_surface_attributes_t  *ret_src_attr)
{
    cairo_directfb_surface_t   *src;
    cairo_surface_attributes_t  src_attr;
    cairo_status_t              status;
    DFBSurfaceBlittingFlags     flags;
    DFBSurfaceBlendFunction     sblend;
    DFBSurfaceBlendFunction     dblend;
    const cairo_color_t        *color;

    /* XXX Unbounded operators are not handled correctly */
    //if (!(mask_pattern == NULL && (op == CAIRO_OPERATOR_SOURCE || op == CAIRO_OPERATOR_CLEAR)) && ! _cairo_operator_bounded_by_source (op))
    if (!mask_pattern == NULL && ! _cairo_operator_bounded_by_source (op))
    {
        //printf("NOT Support %d - %x %d\n",__LINE__, mask_pattern, op);
        return CAIRO_INT_STATUS_UNSUPPORTED;
    }

    if (! _directfb_get_operator (op, &sblend, &dblend))
    {
        //printf("NOT Support %d\n",__LINE__);
	return CAIRO_INT_STATUS_UNSUPPORTED;
    }
    if (mask_pattern) {
        //printf("NOT Support %d\n",__LINE__);
 	//	return CAIRO_INT_STATUS_UNSUPPORTED;
        /*
	if (mask_pattern->type != CAIRO_PATTERN_TYPE_SOLID) {
	    const cairo_pattern_t *tmp;
	    int              tmp_x, tmp_y;

	    if (src_pattern->type != CAIRO_PATTERN_TYPE_SOLID ||
		sblend == DSBF_INVDESTALPHA) // Doesn't work correctly 
		return CAIRO_INT_STATUS_UNSUPPORTED;

	    D_DEBUG_AT (CairoDFB_Render, "Replacing src pattern by mask pattern.\n");

	    tmp = src_pattern;
	    tmp_x = *src_x; tmp_y = *src_y;

	    src_pattern = mask_pattern;
	    *src_x = *mask_x; *src_y = *mask_y;

	    mask_pattern = tmp;
	    *mask_x = tmp_x; *mask_y = tmp_y;

	    if (sblend == DSBF_ONE) {
		sblend = DSBF_SRCALPHA;
		//dblend = DSBF_INVSRCALPHA;
	    }
	}
        */
        if (mask_pattern->type == CAIRO_PATTERN_TYPE_SOLID && *src_x == *mask_x && *src_y == *mask_y)
        {
            color = &((cairo_solid_pattern_t *) mask_pattern)->color;
        }
        else
            return CAIRO_INT_STATUS_UNSUPPORTED;
    } else {
	color = _cairo_stock_color (CAIRO_STOCK_WHITE);
    }

    status = _cairo_pattern_acquire_surface (src_pattern, &dst->base,
					     *src_x, *src_y, width, height,
					     CAIRO_PATTERN_ACQUIRE_NO_REFLECT,
					     (cairo_surface_t **) &src,
					     &src_attr);
    if (status)
	return status;

    if (src->base.backend != &_cairo_directfb_surface_backend ||
	src->dfb != dst->dfb)
    {
	_cairo_pattern_release_surface (src_pattern, &src->base, &src_attr);
        //printf("NOT Support %d\n",__LINE__);
	return CAIRO_INT_STATUS_UNSUPPORTED;
    }

    if ((src->base.content & CAIRO_CONTENT_ALPHA) == 0) {
	if (sblend == DSBF_SRCALPHA)
	    sblend = DSBF_ONE;
	else if (sblend == DSBF_INVSRCALPHA)
	    sblend = DSBF_ZERO;

	if (dblend == DSBF_SRCALPHA)
	    dblend = DSBF_ONE;
	else if (dblend == DSBF_INVSRCALPHA)
	    dblend = DSBF_ZERO;
    }

    if ((dst->base.content & CAIRO_CONTENT_ALPHA) == 0) {
	if (sblend == DSBF_DESTALPHA)
	    sblend = DSBF_ONE;
	else if (sblend == DSBF_INVDESTALPHA)
	    sblend = DSBF_ZERO;

	if (dblend == DSBF_DESTALPHA)
	    dblend = DSBF_ONE;
	else if (dblend == DSBF_INVDESTALPHA)
	    dblend = DSBF_ZERO;
    }

   flags = (sblend == DSBF_ONE && dblend == DSBF_ZERO)
	? DSBLIT_NOFX : DSBLIT_BLEND_ALPHACHANNEL;
    if (! CAIRO_COLOR_IS_OPAQUE (color))
	//flags |= DSBLIT_BLEND_COLORALPHA | DSBLIT_DST_PREMULTIPLY;
	flags |= DSBLIT_BLEND_COLORALPHA | DSBLIT_SRC_PREMULTCOLOR;
    cairo_color_t* color_w = _cairo_stock_color (CAIRO_STOCK_BLACK);
    if (mask_pattern)
    {
    
        if (!(color->red_short   == color_w->red_short   &&
                color->green_short == color_w->green_short && 
                color->blue_short  == color_w->blue_short))
	
            flags |= DSBLIT_COLORIZE;
    }
    
    dst->dfbsurface->SetBlittingFlags (dst->dfbsurface, flags);

    if (flags & (DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA)) {
	dst->dfbsurface->SetSrcBlendFunction (dst->dfbsurface, sblend);
	dst->dfbsurface->SetDstBlendFunction (dst->dfbsurface, dblend);
    }

//    printf("flags : alphachannel %d colorize %d coloralpha %d  - %d %d  - %d\n", flags & DSBLIT_BLEND_ALPHACHANNEL, flags & DSBLIT_COLORIZE, flags & DSBLIT_BLEND_COLORALPHA, sblend, dblend, op);
    if (flags & (DSBLIT_BLEND_COLORALPHA | DSBLIT_COLORIZE)) {
	if (dst->blit_premultiplied) {
	    dst->dfbsurface->SetColor (dst->dfbsurface,
				       color->red_short >> 8,
				       color->green_short >> 8,
				       color->blue_short >> 8,
				       color->alpha_short >> 8);
	} else {
	    dst->dfbsurface->SetColor (dst->dfbsurface,
				       color->red * 0xff,
				       color->green * 0xff,
				       color->blue * 0xff,
				       color->alpha * 0xff);
	}
    }

    *ret_src = src;
    *ret_src_attr = src_attr;

    return CAIRO_STATUS_SUCCESS;
}

static void
_directfb_finish_composite (cairo_directfb_surface_t   *dst,
                            const cairo_pattern_t      *src_pattern,
                            cairo_surface_t            *src,
                            cairo_surface_attributes_t *src_attr)
{
    dst->dfbsurface->SetBlittingFlags(dst->dfbsurface, DSBLIT_NOFX);
    dst->dfbsurface->SetColor(dst->dfbsurface,0,0,0,0);
    dst->dfbsurface->SetDrawingFlags(dst->dfbsurface, DSDRAW_NOFX);
    dst->dfbsurface->SetSrcBlendFunction(dst->dfbsurface, DSBF_ZERO);
    dst->dfbsurface->SetDstBlendFunction(dst->dfbsurface, DSBF_ZERO);
     _cairo_pattern_release_surface (src_pattern, src, src_attr);
}
#endif /* DFB_COMPOSITE || DFB_COMPOSITE_TRAPEZOIDS */

#if DFB_COMPOSITE
static DFBAccelerationMask
_directfb_categorize_operation (cairo_surface_attributes_t *src_attr)
{
    cairo_matrix_t *m = &src_attr->matrix;

    if (m->xy != 0 || m->yx != 0 || m->xx < 0 || m->yy < 0) {
	if (src_attr->extend != CAIRO_EXTEND_NONE)
	    return DFXL_NONE;

	return DFXL_TEXTRIANGLES;
    }

    if (m->xx != 1 || m->yy != 1) {
	if (src_attr->extend != CAIRO_EXTEND_NONE)
	    return DFXL_NONE;

	return DFXL_STRETCHBLIT;
    }

    switch (src_attr->extend) {
    case CAIRO_EXTEND_NONE:
    case CAIRO_EXTEND_REPEAT:
	if (_cairo_matrix_is_integer_translation (&src_attr->matrix,
						  NULL, NULL))
	{
	    return DFXL_BLIT;
	}
	else
	{
	    return DFXL_STRETCHBLIT;
	}

    default:
    case CAIRO_EXTEND_REFLECT:
    case CAIRO_EXTEND_PAD:
	return DFXL_NONE;
    }
}

static cairo_int_status_t
_cairo_directfb_surface_composite (cairo_operator_t  op,
                                   const cairo_pattern_t  *src_pattern,
                                   const 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_region_t   *clip_region)
{
    cairo_directfb_surface_t   *dst = abstract_dst;
    cairo_directfb_surface_t   *src;
    cairo_surface_attributes_t  src_attr;
    cairo_bool_t                is_integer_translation;
    DFBAccelerationMask         accel, mask;
    cairo_int_status_t          status;
    int                         tx, ty;

    D_DEBUG_AT (CairoDFB_Render,
		"%s( op=%d, src_pattern=%p, mask_pattern=%p, dst=%p,"
		" src_x=%d, src_y=%d, mask_x=%d, mask_y=%d, dst_x=%d,"
		" dst_y=%d, width=%u, height=%u ).\n",
		__FUNCTION__, op, src_pattern, mask_pattern, dst,
		src_x, src_y, mask_x, mask_y, dst_x, dst_y, width, height);

    if (! dst->supported_destination)
    {
        //printf("NOT Support %d\n",__LINE__);
        return CAIRO_INT_STATUS_UNSUPPORTED;
    }

    status = _directfb_prepare_composite (dst, src_pattern, mask_pattern, op,
					  &src_x, &src_y, &mask_x, &mask_y,
					  width, height, &src, &src_attr);
    if (status)
	return status;

    accel = _directfb_categorize_operation (&src_attr);
    if (accel == DFXL_NONE) {
	_directfb_finish_composite (dst, src_pattern, &src->base, &src_attr);
        //printf("NOT Support %d\n",__LINE__);


	return CAIRO_INT_STATUS_UNSUPPORTED;
    }

    dst->dfbsurface->GetAccelerationMask (dst->dfbsurface,
					  src->dfbsurface,
					  &mask);
    if ((mask & accel) == 0) {
	D_DEBUG_AT (CairoDFB_Render, "No acceleration (%08x)!\n", accel);
	if (accel != DFXL_BLIT) {
	    _directfb_finish_composite (dst, src_pattern, &src->base, &src_attr);
//      printf("NOT Support %d\n",__LINE__);
	    return CAIRO_INT_STATUS_UNSUPPORTED;
	}
    }

    src_x += src_attr.x_offset;
    src_y += src_attr.y_offset;

    switch ((int) accel) {
    case DFXL_BLIT:
	{
	    DFBRectangle sr;

	    is_integer_translation =
		_cairo_matrix_is_integer_translation (&src_attr.matrix,
						      &tx, &ty);
	    assert (is_integer_translation);

	    sr.x = src_x + tx;
	    sr.y = src_y + ty;
	    sr.w = width;
	    sr.h = height;

	    if (src_attr.extend == CAIRO_EXTEND_NONE) {
		D_DEBUG_AT (CairoDFB_Render, "Running Blit().\n");

		RUN_CLIPPED (dst, clip_region, NULL,
			     dst->dfbsurface->Blit (dst->dfbsurface,
						    src->dfbsurface,
						    &sr, dst_x, dst_y));
	    } else if (src_attr.extend == CAIRO_EXTEND_REPEAT) {
		DFBRegion clip;

		clip.x1 = dst_x;
		clip.y1 = dst_y;
		clip.x2 = dst_x + width  - 1;
		clip.y2 = dst_y + height - 1;

		D_DEBUG_AT (CairoDFB_Render, "Running TileBlit().\n");

		RUN_CLIPPED (dst, clip_region, &clip,
			     dst->dfbsurface->TileBlit (dst->dfbsurface,
							src->dfbsurface,
							&sr, dst_x, dst_y));
	    }
	    break;
	}

    case DFXL_STRETCHBLIT:
	{
	    DFBRectangle sr, dr;
	    double       x1, y1, x2, y2;

	    TRANSFORM_POINT2X (src_attr.matrix,
			       src_x, src_y, x1, y1);
	    TRANSFORM_POINT2X (src_attr.matrix,
			       src_x+width, src_y+height, x2, y2);

	    sr.x = floor (x1);
	    sr.y = floor (y1);
	    sr.w = ceil (x2) - sr.x;
	    sr.h = ceil (y2) - sr.y;

	    dr.x = dst_x;
	    dr.y = dst_y;
	    dr.w = width;
	    dr.h = height;

	    D_DEBUG_AT (CairoDFB_Render, "Running StretchBlit().\n");

	    RUN_CLIPPED (dst, clip_region, NULL,
			 dst->dfbsurface->StretchBlit (dst->dfbsurface,
						       src->dfbsurface,
						       &sr, &dr));
	    break;
	}

    case DFXL_TEXTRIANGLES:
	{
	    DFBRegion clip;
	    DFBVertex v[4];
	    float     x1, y1, x2, y2;
	    int       w, h;

	    status = cairo_matrix_invert (&src_attr.matrix);
	    /* guaranteed by cairo_pattern_set_matrix (); */
	    assert (status == CAIRO_STATUS_SUCCESS);

	    x1 = src_x;
	    y1 = src_y;
	    x2 = width  + x1;
	    y2 = height + y1;

	    src->dfbsurface->GetSize (src->dfbsurface, &w, &h);

	    TRANSFORM_POINT3X (src_attr.matrix, x1, y1, v[0].x, v[0].y);
	    v[0].z = 0;
	    v[0].w = 1;
	    v[0].s = x1 / w;
	    v[0].t = y1 / h;

	    TRANSFORM_POINT3X (src_attr.matrix, x2, y1, v[1].x, v[1].y);
	    v[1].z = 0;
	    v[1].w = 1;
	    v[1].s = x2 / w;
	    v[1].t = y1 / h;

	    TRANSFORM_POINT3X (src_attr.matrix, x2, y2, v[2].x, v[2].y);
	    v[2].z = 0;
	    v[2].w = 1;
	    v[2].s = x2 / w;
	    v[2].t = y2 / h;

	    TRANSFORM_POINT3X (src_attr.matrix, x1, y2, v[3].x, v[3].y);
	    v[3].z = 0;
	    v[3].w = 1;
	    v[3].s = x1 / w;
	    v[3].t = y2 / h;

	    clip.x1 = dst_x;
	    clip.y1 = dst_y;
	    clip.x2 = dst_x + width  - 1;
	    clip.y2 = dst_y + height - 1;

	    D_DEBUG_AT (CairoDFB_Render, "Running TextureTriangles().\n");

	    RUN_CLIPPED (dst, clip_region, &clip,
			 dst->dfbsurface->TextureTriangles (dst->dfbsurface,
							    src->dfbsurface,
							    v, NULL,
							    4, DTTF_FAN));
	    break;
	}

    default:
	D_BUG ("Unexpected operation");
	break;
    }

    _directfb_finish_composite (dst, src_pattern, &src->base, &src_attr);

    return CAIRO_STATUS_SUCCESS;
}
#endif /* DFB_COMPOSITE */

#if DFB_RECTANGLES
static cairo_int_status_t
_cairo_directfb_surface_fill_rectangles (void                  *abstract_surface,
                                         cairo_operator_t       op,
                                         const cairo_color_t   *color,
                                         cairo_rectangle_int_t *rects,
                                         int                    n_rects)
{
    cairo_directfb_surface_t *dst   = abstract_surface;
    DFBSurfaceDrawingFlags    flags;
    DFBSurfaceBlendFunction   sblend;
    DFBSurfaceBlendFunction   dblend;
    DFBRectangle              r[n_rects];
    int                       i;
    D_DEBUG_AT (CairoDFB_Render,
		"%s( dst=%p, op=%d, color=%p, rects=%p, n_rects=%d ).\n",
		__FUNCTION__, dst, op, color, rects, n_rects);

    if (! dst->supported_destination)
    {
        //printf("NOT Support %d\n",__LINE__);
        return CAIRO_INT_STATUS_UNSUPPORTED;
    }

    dst->dfbsurface->SetBlittingFlags(dst->dfbsurface, DSBLIT_NOFX);
    dst->dfbsurface->SetColor(dst->dfbsurface,0,0,0,0);
    dst->dfbsurface->SetDrawingFlags(dst->dfbsurface, DSDRAW_NOFX);
    dst->dfbsurface->SetSrcBlendFunction(dst->dfbsurface, DSBF_ZERO);
    dst->dfbsurface->SetDstBlendFunction(dst->dfbsurface, DSBF_ZERO);
 
    if (! _directfb_get_operator (op, &sblend, &dblend))
    {
       //printf("NOT Support %d\n",__LINE__);
        return CAIRO_INT_STATUS_UNSUPPORTED;
    }

    if (CAIRO_COLOR_IS_OPAQUE (color)) {
	if (sblend == DSBF_SRCALPHA)
	    sblend = DSBF_ONE;
	else if (sblend == DSBF_INVSRCALPHA)
	    sblend = DSBF_ZERO;

	if (dblend == DSBF_SRCALPHA)
	    dblend = DSBF_ONE;
	else if (dblend == DSBF_INVSRCALPHA)
	    dblend = DSBF_ZERO;
    }
    if ((dst->base.content & CAIRO_CONTENT_ALPHA) == 0) {
	if (sblend == DSBF_DESTALPHA)
	    sblend = DSBF_ONE;
	else if (sblend == DSBF_INVDESTALPHA)
	    sblend = DSBF_ZERO;

	if (dblend == DSBF_DESTALPHA)
	    dblend = DSBF_ONE;
	else if (dblend == DSBF_INVDESTALPHA)
	    dblend = DSBF_ZERO;
    }

    flags = (sblend == DSBF_ONE && dblend == DSBF_ZERO) ? DSDRAW_NOFX : DSDRAW_BLEND;
    dst->dfbsurface->SetDrawingFlags (dst->dfbsurface, flags);
    if (flags & DSDRAW_BLEND) {
	dst->dfbsurface->SetSrcBlendFunction (dst->dfbsurface, sblend);
	dst->dfbsurface->SetDstBlendFunction (dst->dfbsurface, dblend);
    }

    dst->dfbsurface->SetColor (dst->dfbsurface,
			       color->red_short >> 8,
			       color->green_short >> 8,
			       color->blue_short >> 8,
			       color->alpha_short >> 8);

    for (i = 0; i < n_rects; i++) {
	r[i].x = rects[i].x;
	r[i].y = rects[i].y;
	r[i].w = rects[i].width;
	r[i].h = rects[i].height;
    }

    RUN_CLIPPED (dst, NULL, NULL,
		 dst->dfbsurface->FillRectangles (dst->dfbsurface, r, n_rects));

    dst->dfbsurface->SetBlittingFlags(dst->dfbsurface, DSBLIT_NOFX);
    dst->dfbsurface->SetColor(dst->dfbsurface,0,0,0,0);
    dst->dfbsurface->SetDrawingFlags(dst->dfbsurface, DSDRAW_NOFX);
    dst->dfbsurface->SetSrcBlendFunction(dst->dfbsurface, DSBF_ZERO);
    dst->dfbsurface->SetDstBlendFunction(dst->dfbsurface, DSBF_ZERO);
 
    return CAIRO_STATUS_SUCCESS;
}
#endif

#if DFB_COMPOSITE_TRAPEZOIDS
static cairo_int_status_t
_cairo_directfb_surface_composite_trapezoids (cairo_operator_t   op,
                                              const cairo_pattern_t   *pattern,
                                              void              *abstract_dst,
                                              cairo_antialias_t  antialias,
                                              int  src_x,   int  src_y,
                                              int  dst_x,   int  dst_y,
                                              unsigned int       width,
                                              unsigned int       height,
                                              cairo_trapezoid_t *traps,
                                              int                num_traps,
					      cairo_region_t	*clip_region)
{
    cairo_directfb_surface_t   *dst = abstract_dst;
    cairo_directfb_surface_t   *src;
    cairo_surface_attributes_t  src_attr;
    cairo_status_t              status;
    DFBAccelerationMask         accel;
    	return CAIRO_INT_STATUS_UNSUPPORTED;
    D_DEBUG_AT (CairoDFB_Render,
                "%s( op=%d, pattern=%p, dst=%p, antialias=%d,"
                   " src_x=%d, src_y=%d, dst_x=%d, dst_y=%d,"
                   " width=%u, height=%u, traps=%p, num_traps=%d ).\n",
                __FUNCTION__, op, pattern, dst, antialias,
                src_x, src_y, dst_x, dst_y, width, height, traps, num_traps);

    if (! dst->supported_destination)
    {
//        printf("waived - NOT Support %d\n",__LINE__);
    	return CAIRO_INT_STATUS_UNSUPPORTED;
    }
    dst->dfbsurface->SetBlittingFlags(dst->dfbsurface, DSBLIT_NOFX);
    dst->dfbsurface->SetColor(dst->dfbsurface,0,0,0,0);
    dst->dfbsurface->SetDrawingFlags(dst->dfbsurface, DSDRAW_NOFX);
    dst->dfbsurface->SetSrcBlendFunction(dst->dfbsurface, DSBF_ZERO);
    dst->dfbsurface->SetDstBlendFunction(dst->dfbsurface, DSBF_ZERO);
 
    if (antialias != CAIRO_ANTIALIAS_NONE)
    {
//        printf("NOT Support %d\n",__LINE__);
//        return CAIRO_INT_STATUS_UNSUPPORTED;
    }
    /* Textures are not supported yet. */
    if (pattern->type != CAIRO_PATTERN_TYPE_SOLID)
    {
        //printf("NOT Support %d\n",__LINE__);
        return CAIRO_INT_STATUS_UNSUPPORTED;

    }

    status = _directfb_prepare_composite (dst, pattern, NULL, op,
					  &src_x, &src_y, NULL, NULL,
					  width, height, &src, &src_attr);
    if (status)
    {
        dst->dfbsurface->SetBlittingFlags(dst->dfbsurface, DSBLIT_NOFX);
        dst->dfbsurface->SetColor(dst->dfbsurface,0,0,0,0);
        dst->dfbsurface->SetDrawingFlags(dst->dfbsurface, DSDRAW_NOFX);
        dst->dfbsurface->SetSrcBlendFunction(dst->dfbsurface, DSBF_ZERO);
        dst->dfbsurface->SetDstBlendFunction(dst->dfbsurface, DSBF_ZERO);
        return status;
    }

    dst->dfbsurface->GetAccelerationMask (dst->dfbsurface,
            src->dfbsurface,
            &accel);

    status = CAIRO_INT_STATUS_UNSUPPORTED;
    if (0 & accel & DFXL_TEXTRIANGLES) {
        DFBVertex  vertex[6*num_traps];
        DFBVertex *v = &vertex[0];
        int        n = 0;

#define ADD_TRI_V(V, X, Y) do { \
    (V)->x = (X); (V)->y = (Y); (V)->w = 1; (V)->z = (V)->s = (V)->t = 0; \
} while (0)
#define ADD_TRI(id, x1, y1, x2, y2, x3, y3) do {\
    const int p = (id)*3;\
    ADD_TRI_V (v+p+0, x1, y1); \
    ADD_TRI_V (v+p+1, x2, y2); \
    ADD_TRI_V (v+p+2, x3, y3); \
} while (0)
	while (num_traps--) {
            double lx1, ly1, lx2, ly2;
            double rx1, ry1, rx2, ry2;

            lx1 = _cairo_fixed_to_double (traps->left.p1.x);
            ly1 = _cairo_fixed_to_double (traps->left.p1.y);
            lx2 = _cairo_fixed_to_double (traps->left.p2.x);
            ly2 = _cairo_fixed_to_double (traps->left.p2.y);
            rx1 = _cairo_fixed_to_double (traps->right.p1.x);
            ry1 = _cairo_fixed_to_double (traps->right.p1.y);
            rx2 = _cairo_fixed_to_double (traps->right.p2.x);
            ry2 = _cairo_fixed_to_double (traps->right.p2.y);

            if (traps->left.p1.y < traps->top) {
                double y = _cairo_fixed_to_double (traps->top);
                if (lx2 != lx1)
                    lx1 = (y - ly1) * (lx2 - lx1) / (ly2 - ly1) + lx1;
                ly1 = y;
            }
            if (traps->left.p2.y > traps->bottom) {
                double y = _cairo_fixed_to_double (traps->bottom);
                if (lx2 != lx1)
                    lx2 = (y - ly1) * (lx2 - lx1) / (ly2 - ly1) + lx1;
                ly2 = y;
            }

            if (traps->right.p1.y < traps->top) {
                double y = _cairo_fixed_to_double (traps->top);
                if (rx2 != rx1)
                    rx1 = (y - ry1) * (rx2 - rx1) / (ry2 - ry1) + rx1;
                ry1 = y;
            }
            if (traps->right.p2.y > traps->bottom) {
                double y = _cairo_fixed_to_double (traps->bottom);
                if (rx2 != rx1)
                    rx2 = (y - ry1) * (rx2 - rx1) / (ry2 - ry1) + rx1;
                ry2 = y;
            }

            if (lx1 == rx1 && ly1 == ry1) {
                ADD_TRI (0, lx2, ly2, lx1, ly1, rx2, ry2);
                v += 3;
                n += 3;
            } else if (lx2 == rx2 && ly2 == ry2) {
                ADD_TRI (0, lx1, ly1, lx2, ly2, rx1, ry1);
                v += 3;
                n += 3;
            } else {
                ADD_TRI (0, lx1, ly1, rx1, ry1, lx2, ly2);
                ADD_TRI (1, lx2, ly2, rx1, ry1, rx2, ry2);
                v += 6;
                n += 6;
            }

            traps++;
        }
#undef ADD_TRI
#undef ADD_TRI_V

        D_DEBUG_AT (CairoDFB_Render, "Running TextureTriangles().\n");

        RUN_CLIPPED (dst, clip_region, NULL,
                     dst->dfbsurface->TextureTriangles (dst->dfbsurface,
							src->dfbsurface,
							vertex, NULL, n,
							DTTF_LIST));

        status = CAIRO_STATUS_SUCCESS;
    }

    _directfb_finish_composite (dst, pattern, &src->base, &src_attr);
        //printf("NOT Support %d\n",__LINE__);
    dst->dfbsurface->SetBlittingFlags(dst->dfbsurface, DSBLIT_NOFX);
    dst->dfbsurface->SetColor(dst->dfbsurface,0,0,0,0);
    dst->dfbsurface->SetDrawingFlags(dst->dfbsurface, DSDRAW_NOFX);
    dst->dfbsurface->SetSrcBlendFunction(dst->dfbsurface, DSBF_ZERO);
    dst->dfbsurface->SetDstBlendFunction(dst->dfbsurface, DSBF_ZERO);
 
    return status;
}
#endif /* DFB_COMPOSITE_TRAPEZOIDS */

static cairo_bool_t
_cairo_directfb_abstract_surface_get_extents (void                  *abstract_surface,
                                              cairo_rectangle_int_t *rectangle)
{
    cairo_directfb_surface_t *surface = abstract_surface;

    D_DEBUG_AT (CairoDFB_Surface,
		"%s( surface=%p, rectangle=%p ).\n",
		__FUNCTION__, surface, rectangle);

    if (!surface->local) {
	surface->dfbsurface->GetSize (surface->dfbsurface,
				      &surface->width, &surface->height);
    }

    rectangle->x = 0;
    rectangle->y = 0;
    rectangle->width  = surface->width;
    rectangle->height = surface->height;

    return TRUE;
}

#if DFB_SHOW_GLYPHS
static cairo_status_t
_directfb_allocate_font_cache (IDirectFB *dfb,
			       int width, int height,
			       cairo_directfb_font_cache_t **out)
{
    cairo_directfb_font_cache_t *cache;
    cairo_status_t status;

    cache = calloc (1, sizeof (cairo_directfb_font_cache_t));
    if (cache == NULL)
        return _cairo_error (CAIRO_STATUS_NO_MEMORY);

    cache->dfb = dfb;
    status = _directfb_buffer_surface_create (dfb,
                            _directfb_argb_font ? DSPF_ARGB : DSPF_A8,
			    width, height,
			    &cache->dfbsurface);
    if (status) {
        free (cache);
	return status;
    }

    cache->width  = width;
    cache->height = height;
    *out = cache;
    return CAIRO_STATUS_SUCCESS;
}

static void
_directfb_destroy_font_cache (cairo_directfb_font_cache_t *cache)
{
    cache->dfbsurface->Release (cache->dfbsurface);
    free (cache);
}

/* XXX hook into rtree font cache from drm */
static cairo_status_t
_directfb_acquire_font_cache (cairo_directfb_surface_t     *surface,
                              cairo_scaled_font_t          *scaled_font,
                              const cairo_glyph_t          *glyphs,
                              int                           num_glyphs,
                              cairo_directfb_font_cache_t **ret_cache,
                              DFBRectangle                 *rects,
                              DFBPoint                     *points,
			      int                          *ret_num)
{
    cairo_status_t               status;
    cairo_scaled_glyph_t        *chars[num_glyphs];
    int                          num_chars = 0;
    cairo_directfb_font_cache_t *cache     = NULL;
    int                          n         = 0;
    int                          x         = 0;
    int                          y         = 0;
    int                          w         = 8;
    int                          h         = 8;
    int                          i;

    D_DEBUG_AT (CairoDFB_Font, "%s( %p [%d] )\n", __FUNCTION__, glyphs, num_glyphs );

    _cairo_scaled_font_freeze_cache (scaled_font);

    if (scaled_font->surface_private) {
	cache = scaled_font->surface_private;
	x = cache->x;
	y = cache->y;
    }

    for (i = 0; i < num_glyphs; i++) {
	cairo_scaled_glyph_t  *scaled_glyph;
	cairo_image_surface_t *img;

	D_DEBUG_AT (CairoDFB_Font, "  -> [%2d] = %4lu\n", i, glyphs[i].index );

	status = _cairo_scaled_glyph_lookup (scaled_font, glyphs[i].index,
					  CAIRO_SCALED_GLYPH_INFO_SURFACE,
					  &scaled_glyph);
	if (status) {
	    _cairo_scaled_font_thaw_cache (scaled_font);
	    return status;
	}

	img = scaled_glyph->surface;
	switch (img->format) {
	case CAIRO_FORMAT_A1:
	case CAIRO_FORMAT_A8:
	case CAIRO_FORMAT_ARGB32:
	    break;
	case CAIRO_FORMAT_RGB24:
	default:
	    D_DEBUG_AT (CairoDFB_Font,
			"  -> Unsupported font format %d!\n", img->format);
	    _cairo_scaled_font_thaw_cache (scaled_font);
	    return CAIRO_INT_STATUS_UNSUPPORTED;
	}

	points[n].x = _cairo_lround (glyphs[i].x - img->base.device_transform.x0);
	points[n].y = _cairo_lround (glyphs[i].y - img->base.device_transform.y0);

	//        D_DEBUG_AT (CairoDFB_Font, "            (%4d,%4d) [%2d]\n", points[n].x, points[n].y, n );

	if (points[n].x >= surface->width  ||
	    points[n].y >= surface->height ||
	    points[n].x+img->width  <= 0   ||
	    points[n].y+img->height <= 0)
	{
	    continue;
	}

	if (scaled_glyph->surface_private == NULL) {
	    DFBRectangle *rect;

	    if (x+img->width > 2048) {
		x = 0;
		y = h;
		h = 0;
	    }

	    rects[n].x = x;
	    rects[n].y = y;
	    rects[n].w = img->width;
	    rects[n].h = img->height;

	    x += img->width;
	    h  = MAX (h, img->height);
	    w  = MAX (w, x);

	    /* Remember glyph location */
	    rect = malloc (sizeof (DFBRectangle));
	    if (rect == NULL) {
		_cairo_scaled_font_thaw_cache (scaled_font);
		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
	    }
	    *rect = rects[n];

	    scaled_glyph->surface_private = rect;
	    chars[num_chars++] = scaled_glyph;

	    D_DEBUG_AT (CairoDFB_Font, "  -> loading at %4d,%2d <- rect %p, img %p, entry %p\n",
			rects[n].x, rects[n].y, rect, scaled_glyph->surface, scaled_glyph);
	} else {
	    rects[n] = *(DFBRectangle *) scaled_glyph->surface_private;

	    D_DEBUG_AT (CairoDFB_Font, "  -> exists at  %4d,%2d\n", rects[n].x, rects[n].y);
	}

	n++;
    }

    if (n == 0) {
	_cairo_scaled_font_thaw_cache (scaled_font);
	return CAIRO_INT_STATUS_NOTHING_TO_DO;
    }

    h += y;
    w = MAX (w, 8);
    h = MAX (h, 8);

    /* XXX query maximum surface size */
    if (w > 2048 || h > 2048) {
	_cairo_scaled_font_thaw_cache (scaled_font);
	return CAIRO_INT_STATUS_UNSUPPORTED;
    }

    if (cache) {
	if (cache->width < w || cache->height < h) {
	    cairo_directfb_font_cache_t *new_cache;

	    w = MAX (w, cache->width);
	    h = MAX (h, cache->height);

	    D_DEBUG_AT (CairoDFB_Font, "  -> Reallocating font cache (%dx%d).\n", w, h);

	    status = _directfb_allocate_font_cache (surface->dfb,
						    w, h,
						    &new_cache);
	    if (status) {
		_cairo_scaled_font_thaw_cache (scaled_font);
		return status;
	    }

	    new_cache->dfbsurface->Blit (new_cache->dfbsurface,
					 cache->dfbsurface, NULL, 0, 0);

	    _directfb_destroy_font_cache (cache);
	    scaled_font->surface_private = cache = new_cache;
	}
    } else {
	D_DEBUG_AT (CairoDFB_Font, "  -> Allocating font cache (%dx%d).\n", w, h);

	status = _directfb_allocate_font_cache (surface->dfb, w, h, &cache);
	if (status) {
	    _cairo_scaled_font_thaw_cache (scaled_font);
	    return status;
	}

	scaled_font->surface_backend = &_cairo_directfb_surface_backend;
	scaled_font->surface_private = cache;
    }

    if (num_chars) {
	unsigned char *data;
	int            pitch;

	if (cache->dfbsurface->Lock (cache->dfbsurface,
				     DSLF_WRITE, (void *)&data, &pitch))
	{
	    _cairo_scaled_font_thaw_cache (scaled_font);
	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
	}

	D_DEBUG_AT (CairoDFB_Font, "  => %d chars to load, cache %dx%d\n", num_chars, cache->width, cache->height);

	for (i = 0; i < num_chars; i++) {
	    cairo_image_surface_t *img  = chars[i]->surface;
	    DFBRectangle          *rect = chars[i]->surface_private;
	    unsigned char         *dst  = data;
	    unsigned char         *src;
	    int                    j;

	    D_DEBUG_AT (CairoDFB_Font, "  -> loading [%2d] <- rect %p, img %p, entry %p\n", i, rect, img, chars[i]);

	    src = img->data;

	    D_DEBUG_AT (CairoDFB_Font, "     from %p\n", src);

	    dst += rect->y * pitch + (_directfb_argb_font ? (rect->x<<2) : rect->x);

	    D_DEBUG_AT (CairoDFB_Font, "     to %4d,%2d (%p)\n", rect->x, rect->y, dst);

	    if (img->format == CAIRO_FORMAT_A1) {
		for (h = rect->h; h; h--) {
		    if (_directfb_argb_font) {
			for (j = 0; j < rect->w; j++)
			    ((uint32_t *) dst)[j] = (src[j>>3] & (1 << (j&7))) ? 0xffffffff : 0;
		    } else {
			for (j = 0; j < rect->w; j++)
			    dst[j] = (src[j>>3] & (1 << (j&7))) ? 0xff : 0;
		    }

		    dst += pitch;
		    src += img->stride;
		}
	    } else if (img->format == CAIRO_FORMAT_A8) {
		for (h = rect->h; h; h--) {
		    if (_directfb_argb_font) {
			for (j = 0; j < rect->w; j++)
			    ((uint32_t *) dst)[j] = src[j] * 0x01010101;
		    } else {
			direct_memcpy (dst, src, rect->w);
		    }

		    dst += pitch;
		    src += img->stride;
		}
	    } else { /* ARGB32 */
		for (h = rect->h; h; h--) {
		    if (_directfb_argb_font) {
			direct_memcpy (dst, src, rect->w<<2);
		    } else {
			for (j = 0; j < rect->w; j++)
			    dst[j] = ((uint32_t *) src)[j] >> 24;
		    }

		    dst += pitch;
		    src += img->stride;
		}
	    }
	}

	cache->dfbsurface->Unlock (cache->dfbsurface);
    }

    _cairo_scaled_font_thaw_cache (scaled_font);

    cache->x = x;
    cache->y = y;

    D_DEBUG_AT (CairoDFB_Font, "  => cache %d,%d, %p [%d]\n", x, y, cache, n);

    *ret_cache = cache;
    *ret_num   = n;

    return CAIRO_STATUS_SUCCESS;
}

static void
_cairo_directfb_surface_scaled_font_fini (cairo_scaled_font_t *scaled_font)
{
    cairo_directfb_font_cache_t *cache = scaled_font->surface_private;

    D_DEBUG_AT (CairoDFB_Font,
		"%s( scaled_font=%p ).\n", __FUNCTION__, scaled_font);

    if (cache != NULL) {
	_directfb_destroy_font_cache (cache);
	scaled_font->surface_private = NULL;
    }
}

static void
_cairo_directfb_surface_scaled_glyph_fini (cairo_scaled_glyph_t *scaled_glyph,
                                           cairo_scaled_font_t  *scaled_font)
{
     D_DEBUG_AT (CairoDFB_Font,
                 "%s( scaled_glyph=%p, scaled_font=%p ).\n",
                 __FUNCTION__, scaled_glyph, scaled_font);

     if (scaled_glyph->surface_private != NULL) {
          free (scaled_glyph->surface_private);
          scaled_glyph->surface_private = NULL;
     }
}

static cairo_int_status_t
_cairo_directfb_surface_show_glyphs (void		    *abstract_dst,
                                     cairo_operator_t	     op,
                                     const cairo_pattern_t  *pattern,
                                     cairo_glyph_t	    *glyphs,
                                     int		     num_glyphs,
                                     cairo_scaled_font_t    *scaled_font,
				     cairo_clip_t	    *clip,
				     int		    *remaining_glyphs)
{
    cairo_directfb_surface_t    *dst = abstract_dst;
    cairo_directfb_font_cache_t *cache;
    cairo_status_t               status;
    DFBSurfaceBlittingFlags      flags;
    DFBSurfaceBlendFunction      sblend;
    DFBSurfaceBlendFunction      dblend;
    DFBRectangle                 rects[num_glyphs];
    DFBPoint                     points[num_glyphs];
    int                          num;
    const cairo_color_t         *color;
    cairo_region_t		*clip_region = NULL;

    D_DEBUG_AT (CairoDFB_Font,
		"%s( dst=%p, op=%d, pattern=%p, glyphs=%p, num_glyphs=%d, scaled_font=%p ).\n",
		__FUNCTION__, dst, op, pattern, glyphs, num_glyphs, scaled_font);

    if (! dst->supported_destination)
	return CAIRO_INT_STATUS_UNSUPPORTED;

    if (pattern->type != CAIRO_PATTERN_TYPE_SOLID)
	return CAIRO_INT_STATUS_UNSUPPORTED;

    /* Fallback if we need to emulate clip regions */
    if (clip != NULL) {
	status = _cairo_clip_get_region (clip, &clip_region);
	assert (status != CAIRO_INT_STATUS_NOTHING_TO_DO);
	if (status)
	    return status;
    }

    /* XXX Unbounded operators are not handled correctly */
    if (! _cairo_operator_bounded_by_mask (op))
        return CAIRO_INT_STATUS_UNSUPPORTED;

    if (! _directfb_get_operator (op, &sblend, &dblend) ||
	sblend == DSBF_DESTALPHA || sblend == DSBF_INVDESTALPHA)
    {
	return CAIRO_INT_STATUS_UNSUPPORTED;
    }

    status = _directfb_acquire_font_cache (dst, scaled_font, glyphs, num_glyphs,
					   &cache, &rects[0], &points[0], &num);
    if (status) {
	if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
	    status = CAIRO_STATUS_SUCCESS;
	return status;
    }

    color = &((cairo_solid_pattern_t *) pattern)->color;

    flags = DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_COLORIZE;
    if (! CAIRO_COLOR_IS_OPAQUE (color))
	flags |= DSBLIT_BLEND_COLORALPHA;

    if (!_directfb_argb_font) {
	if (sblend == DSBF_ONE) {
	    sblend = DSBF_SRCALPHA;
	    if (dblend == DSBF_ZERO)
		dblend = DSBF_INVSRCALPHA;
	}
    }

    dst->dfbsurface->SetBlittingFlags (dst->dfbsurface, flags);
    dst->dfbsurface->SetSrcBlendFunction (dst->dfbsurface, sblend);
    dst->dfbsurface->SetDstBlendFunction (dst->dfbsurface, dblend);
    if (dst->blit_premultiplied) {
	dst->dfbsurface->SetColor (dst->dfbsurface,
				   color->red_short >> 8,
				   color->green_short >> 8,
				   color->blue_short >> 8,
				   color->alpha_short >> 8);
    } else {
	dst->dfbsurface->SetColor (dst->dfbsurface,
				   color->red * 0xff,
				   color->green * 0xff,
				   color->blue * 0xff,
				   color->alpha * 0xff);
    }

    int jj;
    int sWidth, sHeight;
    cache->dfbsurface->GetSize(cache->dfbsurface, &sWidth, &sHeight);
    for(jj=0; jj<num_glyphs; jj++)
    {
        if(rects[jj].x >= sWidth || rects[jj].y >= sHeight || rects[jj].x < 0 || rects[jj].y < 0)
        {
            rects[jj].x = 0;
            rects[jj].y = 0;
            rects[jj].w = 0;
            rects[jj].h = 0;
        }
    }

    D_DEBUG_AT (CairoDFB_Font, "Running BatchBlit().\n");

    RUN_CLIPPED (dst, clip_region, NULL,
		 dst->dfbsurface->BatchBlit (dst->dfbsurface,
					     cache->dfbsurface, rects, points, num));


    dst->dfbsurface->SetBlittingFlags(dst->dfbsurface, DSBLIT_NOFX);
    dst->dfbsurface->SetColor(dst->dfbsurface,0,0,0,0);
    dst->dfbsurface->SetDrawingFlags(dst->dfbsurface, DSDRAW_NOFX);
    dst->dfbsurface->SetSrcBlendFunction(dst->dfbsurface, DSBF_ZERO);
    dst->dfbsurface->SetDstBlendFunction(dst->dfbsurface, DSBF_ZERO);
    return CAIRO_STATUS_SUCCESS;
}
#endif /* DFB_SHOW_GLYPHS */


static cairo_bool_t
_cairo_directfb_surface_is_similar (void *surface_a, void *surface_b)
{
    cairo_directfb_surface_t *a = (cairo_directfb_surface_t *) surface_a;
    cairo_directfb_surface_t *b = (cairo_directfb_surface_t *) surface_b;

    return a->dfb == b->dfb;
}

static cairo_surface_backend_t
_cairo_directfb_surface_backend = {
         CAIRO_SURFACE_TYPE_DIRECTFB, /*type*/
        _cairo_directfb_surface_create_similar,/*create_similar*/
        _cairo_directfb_surface_finish, /*finish*/
        _cairo_directfb_surface_acquire_source_image,/*acquire_source_image*/
        _cairo_directfb_surface_release_source_image,/*release_source_image*/
        _cairo_directfb_surface_acquire_dest_image,/*acquire_dest_image*/
        _cairo_directfb_surface_release_dest_image,/*release_dest_image*/
        _cairo_directfb_surface_clone_similar,/*clone_similar*/
#if DFB_COMPOSITE
        _cairo_directfb_surface_composite,/*composite*/
#else
        NULL,/*composite*/
#endif
#if DFB_RECTANGLES
        _cairo_directfb_surface_fill_rectangles,/*fill_rectangles*/
#else
        NULL,/*fill_rectangles*/
#endif
#if DFB_COMPOSITE_TRAPEZOIDS
        _cairo_directfb_surface_composite_trapezoids,/*composite_trapezoids*/
#else
        NULL,/*composite_trapezoids*/
#endif
        NULL, /* create_span_renderer */
        NULL, /* check_span_renderer */
        NULL, /* copy_page */
        NULL, /* show_page */
        _cairo_directfb_abstract_surface_get_extents,/* get_extents */
        NULL, /* old_show_glyphs */
        NULL, /* get_font_options */
        NULL, /* flush */
        NULL, /* mark_dirty_rectangle */
#if DFB_SHOW_GLYPHS
        _cairo_directfb_surface_scaled_font_fini,/* scaled_font_fini */
        _cairo_directfb_surface_scaled_glyph_fini,/* scaled_glyph_fini */
#else
        NULL,
        NULL,
#endif
        NULL, /* paint */
        NULL, /* mask */
        NULL, /* stroke */
        NULL, /* fill */
#if DFB_SHOW_GLYPHS
        _cairo_directfb_surface_show_glyphs,/* show_glyphs */
#else
        NULL, /* show_glyphs */
#endif
        NULL, /* snapshot */
        _cairo_directfb_surface_is_similar,
};


static void
cairo_directfb_surface_backend_init (IDirectFB *dfb)
{
    static int done = 0;

    if (done)
	return;

    if (getenv ("CAIRO_DIRECTFB_NO_ACCEL")) {
#if DFB_RECTANGLES
	_cairo_directfb_surface_backend.fill_rectangles = NULL;
#endif
#if DFB_COMPOSITE
	_cairo_directfb_surface_backend.composite = NULL;
#endif
#if DFB_COMPOSITE_TRAPEZOIDS
	_cairo_directfb_surface_backend.composite_trapezoids = NULL;
#endif
#if DFB_SHOW_GLYPHS
	_cairo_directfb_surface_backend.scaled_font_fini = NULL;
	_cairo_directfb_surface_backend.scaled_glyph_fini = NULL;
	_cairo_directfb_surface_backend.show_glyphs = NULL;
#endif
	D_DEBUG_AT (CairoDFB_Surface, "Acceleration disabled.\n");
    } else {
	DFBGraphicsDeviceDescription dsc;

	dfb->GetDeviceDescription (dfb, &dsc);

#if DFB_COMPOSITE
	//        if (!(dsc.acceleration_mask & DFXL_BLIT))
	//            _cairo_directfb_surface_backend.composite = NULL;
#endif

#if DFB_COMPOSITE_TRAPEZOIDS
	//        if (!(dsc.acceleration_mask & DFXL_TEXTRIANGLES))
	//            _cairo_directfb_surface_backend.composite_trapezoids = NULL;
#endif
    }

    if (getenv ("CAIRO_DIRECTFB_ARGB_FONT")) {
	_directfb_argb_font = 1;
	D_DEBUG_AT (CairoDFB_Surface, "Using ARGB fonts.\n");
    }

    done = 1;
}

cairo_surface_t *
cairo_directfb_surface_create (IDirectFB *dfb, IDirectFBSurface *dfbsurface)
{
    cairo_directfb_surface_t *surface;
    DFBSurfacePixelFormat     format;
    DFBSurfaceCapabilities caps;

    D_ASSERT (dfb != NULL);
    D_ASSERT (dfbsurface != NULL);

    cairo_directfb_surface_backend_init (dfb);

    surface = calloc (1, sizeof (cairo_directfb_surface_t));
    if (surface == NULL)
        return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));

    dfbsurface->AddRef (dfbsurface);
    dfbsurface->GetPixelFormat (dfbsurface, &format);
    dfbsurface->GetSize (dfbsurface, &surface->width, &surface->height);
    surface->dfb = dfb;
    surface->dfbsurface = dfbsurface;
    surface->pixman_format = _directfb_to_pixman_format (format);
    surface->supported_destination = pixman_format_supported_destination (surface->pixman_format);

    dfbsurface->GetCapabilities (dfbsurface, &caps);
    if (caps & DSCAPS_PREMULTIPLIED)
	surface->blit_premultiplied = TRUE;

    _cairo_surface_init (&surface->base,
                         &_cairo_directfb_surface_backend,
			 NULL, /* device */
			 _directfb_format_to_content (format));

    return &surface->base;
}

IDirectFB* cairo_directfb_surface_get_dfb(cairo_surface_t* surface)
{
    cairo_directfb_surface_t *dfbsurface = (cairo_directfb_surface_t*)surface;
    if(!_cairo_surface_is_dfb(surface))
        return NULL;
    return dfbsurface->dfb; 
}

IDirectFBSurface* cairo_directfb_surface_get_dfb_surface(cairo_surface_t* surface)
{
    cairo_directfb_surface_t *dfbsurface = (cairo_directfb_surface_t*)surface;
    if(!_cairo_surface_is_dfb(surface))
        return NULL;
    return dfbsurface->dfbsurface; 
}


cairo_public int
cairo_directfb_surface_get_width (cairo_surface_t *surface) {
    cairo_directfb_surface_t *dfbsurface = (cairo_directfb_surface_t*)surface;
    if(!_cairo_surface_is_dfb(surface))
        return 0;
    return dfbsurface->width;
}

cairo_public int
cairo_directfb_surface_get_height (cairo_surface_t *surface) {
    cairo_directfb_surface_t *dfbsurface = (cairo_directfb_surface_t*)surface;
    if(!_cairo_surface_is_dfb(surface))
        return 0;
    return dfbsurface->height;
}

