📄 cairo-directfb-surface.c
字号:
/* 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, ®);\ }\ 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 + -