⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cairo-directfb-surface.c

📁 按照官方的说法:Cairo is a vector graphics library with cross-device output support. 翻译过来
💻 C
📖 第 1 页 / 共 4 页
字号:
/* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 <stdio.h>#include <stdlib.h>#include <math.h>#include <directfb.h>#include <direct/types.h>#include <direct/debug.h>#include <direct/memcpy.h>#include <direct/util.h>#include "cairo-directfb.h"#include "cairoint.h"/* * Composite works fine. */#define DFB_COMPOSITE 1/* * CompositeTrapezoids works (without antialiasing). */#define DFB_COMPOSITE_TRAPEZOIDS 1/* * ShowGlyphs works fine. */#define DFB_SHOW_GLYPHS 1D_DEBUG_DOMAIN (Cairo_DirectFB, "Cairo/DirectFB", "Cairo DirectFB backend");/*****************************************************************************/typedef struct _cairo_directfb_surface {    cairo_surface_t      base;            cairo_format_t       format;            IDirectFB           *dfb;    IDirectFBSurface    *surface;    IDirectFBSurface    *buffer;        /* color buffer */    cairo_surface_t     *color;            DFBRegion           *clips;    int                  n_clips;            cairo_surface_t     *buffer_image;            int                  width;    int                  height;        bool                 local;} cairo_directfb_surface_t;typedef struct _cairo_directfb_font_cache {    IDirectFB           *dfb;     IDirectFBSurface    *buffer;    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;/*****************************************************************************/#define RUN_CLIPPED( surface, clip, func ) {\    if ((surface)->clips) {\        int k;\        for (k = 0; k < (surface)->n_clips; k++) {\            if (clip) {\                DFBRegion  reg = (surface)->clips[k];\                DFBRegion *cli = (clip);\                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)->buffer->SetClip ((surface)->buffer, &reg);\            }\            else {\                (surface)->buffer->SetClip ((surface)->buffer,\                                           &(surface)->clips[k]);\            }\            func;\        }\    }\    else {\        (surface)->buffer->SetClip ((surface)->buffer, clip);\        func;\    }\}#define TRANSFORM_POINT( m, x, y, ret_x, ret_y ) {\    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);\}/* XXX: A1 has a different bits ordering in cairo. *      Probably we should drop it. */static cairo_content_t _directfb_format_to_content ( DFBSurfacePixelFormat format ){    switch (format) {        case DSPF_ARGB:            return CAIRO_CONTENT_COLOR_ALPHA;        case DSPF_A8:             return CAIRO_CONTENT_ALPHA;        case DSPF_RGB32:        case DSPF_A1:         default:            return CAIRO_CONTENT_COLOR;         break;    }}                                                           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 cairo_format_tdirectfb_to_cairo_format (DFBSurfacePixelFormat format){    switch (format) {        case DSPF_RGB32:            return CAIRO_FORMAT_RGB24;        case DSPF_ARGB:            return CAIRO_FORMAT_ARGB32;        case DSPF_A8 :            return CAIRO_FORMAT_A8;        case DSPF_A1 :            return CAIRO_FORMAT_A1;        default:            break;    }        return -1;}static cairo_status_t_directfb_get_operator (cairo_operator_t         operator,                        DFBSurfaceDrawingFlags  *ret_drawing,                        DFBSurfaceBlittingFlags *ret_blitting,                        DFBSurfaceBlendFunction *ret_srcblend,                        DFBSurfaceBlendFunction *ret_dstblend ){     DFBSurfaceDrawingFlags  drawing  = DSDRAW_BLEND;    DFBSurfaceBlittingFlags blitting = DSBLIT_BLEND_ALPHACHANNEL;    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:            drawing  = DSDRAW_NOFX;            blitting = DSBLIT_NOFX;            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:            srcblend = DSBF_SRCALPHASAT;            dstblend = DSBF_ONE;            break;        default:            return CAIRO_INT_STATUS_UNSUPPORTED;    }        if (ret_drawing)        *ret_drawing = drawing;    if (ret_blitting)        *ret_blitting = blitting;    if (ret_srcblend)        *ret_srcblend = srcblend;    if (ret_dstblend)        *ret_dstblend = dstblend;        return CAIRO_STATUS_SUCCESS;}static IDirectFBSurface*_directfb_buffer_surface_create (IDirectFB             *dfb,                                  DFBSurfacePixelFormat  format,                                 int                    width,                                 int                    height){    IDirectFBSurface      *buffer;    DFBSurfaceDescription  dsc;    DFBResult              ret;        dsc.flags       = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT;    dsc.width       = width;    dsc.height      = height;    dsc.pixelformat = format;    ret = dfb->CreateSurface (dfb, &dsc, &buffer);    if (ret) {        DirectFBError ("IDirectFB::CreateSurface()", ret);        return NULL;    }        return buffer;}static cairo_status_t_directfb_acquire_surface (cairo_directfb_surface_t *surface,                            DFBSurfaceLockFlags       lock_flags){       if (!surface->local) {        int width, height;            surface->surface->GetSize (surface->surface, &width, &height);                   if (surface->width != width || surface->height != height) {            DFBSurfacePixelFormat format;                    if (surface->buffer_image) {                cairo_surface_destroy (surface->buffer_image);                surface->buffer_image = NULL;            }                    if (surface->buffer)                surface->buffer->Release (surface->buffer);                    surface->surface->GetPixelFormat (surface->surface, &format);            surface->format = directfb_to_cairo_format (format);                    if (surface->format == -1) {                D_DEBUG_AT (Cairo_DirectFB, "%s buffer for surface.\n",                            surface->buffer ? "Reallocating" : "Allocating");                            surface->buffer = _directfb_buffer_surface_create (surface->dfb,                                                        DSPF_ARGB, width, height);                if (!surface->buffer)                    return CAIRO_STATUS_NO_MEMORY;                                surface->buffer->Blit (surface->buffer,                                        surface->surface, NULL, 0, 0);                            surface->format = CAIRO_FORMAT_ARGB32;            }            else {                surface->surface->AddRef (surface->surface);                surface->buffer = surface->surface;            }                    surface->width  = width;            surface->height = height;        }    }        if (lock_flags) {        void      *data;        int        pitch;        DFBResult  ret;                ret = surface->buffer->Lock (surface->buffer,                                      lock_flags, &data, &pitch);        if (ret) {            DirectFBError ("IDirectFBSurface::Lock()", ret);            return CAIRO_STATUS_NO_MEMORY;        }                    if (!surface->buffer_image) {                        surface->buffer_image = cairo_image_surface_create_for_data (data,                                                    surface->format, surface->width,                                                    surface->height, pitch);            if (!surface->buffer_image) {                surface->buffer->Unlock (surface->buffer);                return CAIRO_STATUS_NO_MEMORY;            }        }        else {            cairo_surface_reference (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_directfb_surface_t *source  = abstract_src;    cairo_directfb_surface_t *surface;    cairo_format_t            format;        D_DEBUG_AT (Cairo_DirectFB,                 "%s( src=%p, content=0x%x, width=%d, height=%d).\n",                __FUNCTION__, source, content, width, height);        format = _cairo_format_from_content (content);             

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -