1
/* cairo - a vector graphics library with display and print output
3
* Copyright Ā© 2003 University of Southern California
5
* This library is free software; you can redistribute it and/or
6
* modify it either under the terms of the GNU Lesser General Public
7
* License version 2.1 as published by the Free Software Foundation
8
* (the "LGPL") or, at your option, under the terms of the Mozilla
9
* Public License Version 1.1 (the "MPL"). If you do not alter this
10
* notice, a recipient may use your version of this file under either
11
* the MPL or the LGPL.
13
* You should have received a copy of the LGPL along with this library
14
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
15
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
* You should have received a copy of the MPL along with this library
17
* in the file COPYING-MPL-1.1
19
* The contents of this file are subject to the Mozilla Public License
20
* Version 1.1 (the "License"); you may not use this file except in
21
* compliance with the License. You may obtain a copy of the License at
22
* http://www.mozilla.org/MPL/
24
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
25
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
26
* the specific language governing rights and limitations.
28
* The Original Code is the cairo graphics library.
30
* The Initial Developer of the Original Code is University of Southern
34
* Michael Emmel <mike.emmel@gmail.com>
35
* Claudio Ciccani <klan@users.sf.net>
40
#include "cairo-directfb.h"
45
#include <direct/types.h>
46
#include <direct/debug.h>
47
#include <direct/memcpy.h>
48
#include <direct/util.h>
52
* Rectangle works fine.
53
* Bugs 361377, 359553, 359243 in Gnome BTS are caused
54
* by GDK/DirectFB, not by Cairo/DirectFB.
56
#define DFB_RECTANGLES 1
59
* Composite works fine.
61
#define DFB_COMPOSITE 1
64
* CompositeTrapezoids works (without antialiasing).
66
#define DFB_COMPOSITE_TRAPEZOIDS 0
69
* ShowGlyphs works fine.
71
#define DFB_SHOW_GLYPHS 1
74
D_DEBUG_DOMAIN (Cairo_DirectFB, "Cairo/DirectFB", "Cairo DirectFB backend");
76
/*****************************************************************************/
79
typedef struct _cairo_directfb_surface {
81
cairo_format_t format;
82
cairo_content_t content;
85
IDirectFBSurface *dfbsurface;
86
IDirectFBSurface *tmpsurface;
89
cairo_surface_t *color;
98
} cairo_directfb_surface_t;
101
typedef struct _cairo_directfb_font_cache {
103
IDirectFBSurface *dfbsurface;
108
/* coordinates within the surface
109
* of the last loaded glyph */
112
} cairo_directfb_font_cache_t;
115
static cairo_surface_backend_t cairo_directfb_surface_backend;
117
/*****************************************************************************/
119
static int _directfb_argb_font = 0;
121
/*****************************************************************************/
124
#define RUN_CLIPPED( surface, clip, func ) {\
125
if ((surface)->clips) {\
127
for (k = 0; k < (surface)->n_clips; k++) {\
129
DFBRegion reg = (surface)->clips[k];\
130
DFBRegion *cli = (clip);\
131
if (reg.x2 < cli->x1 || reg.y2 < cli->y1 ||\
132
reg.x1 > cli->x2 || reg.y1 > cli->y2)\
134
if (reg.x1 < cli->x1)\
136
if (reg.y1 < cli->y1)\
138
if (reg.x2 > cli->x2)\
140
if (reg.y2 > cli->y2)\
142
(surface)->dfbsurface->SetClip ((surface)->dfbsurface, ®);\
145
(surface)->dfbsurface->SetClip ((surface)->dfbsurface,\
146
&(surface)->clips[k]);\
152
(surface)->dfbsurface->SetClip ((surface)->dfbsurface, clip);\
157
#define TRANSFORM_POINT2X( m, x, y, ret_x, ret_y ) {\
160
(ret_x) = (_x * (m).xx + (m).x0);\
161
(ret_y) = (_y * (m).yy + (m).y0);\
164
#define TRANSFORM_POINT3X( m, x, y, ret_x, ret_y ) {\
167
(ret_x) = (_x * (m).xx + _y * (m).xy + (m).x0);\
168
(ret_y) = (_x * (m).yx + _y * (m).yy + (m).y0);\
171
/* XXX: A1 has a different bits ordering in cairo.
172
* Probably we should drop it.
175
static cairo_content_t
176
_directfb_format_to_content (DFBSurfacePixelFormat format)
178
if (DFB_PIXELFORMAT_HAS_ALPHA(format)) {
179
if (DFB_COLOR_BITS_PER_PIXEL(format))
180
return CAIRO_CONTENT_COLOR_ALPHA;
182
return CAIRO_CONTENT_ALPHA;
185
return CAIRO_CONTENT_COLOR;
189
static inline DFBSurfacePixelFormat
190
_cairo_to_directfb_format (cairo_format_t format)
193
case CAIRO_FORMAT_RGB24:
195
case CAIRO_FORMAT_ARGB32:
197
case CAIRO_FORMAT_A8:
199
case CAIRO_FORMAT_A1:
208
static inline cairo_format_t
209
_directfb_to_cairo_format (DFBSurfacePixelFormat format)
213
return CAIRO_FORMAT_RGB24;
215
return CAIRO_FORMAT_ARGB32;
217
return CAIRO_FORMAT_A8;
219
return CAIRO_FORMAT_A1;
228
static cairo_status_t
229
_directfb_get_operator (cairo_operator_t operator,
230
DFBSurfaceBlendFunction *ret_srcblend,
231
DFBSurfaceBlendFunction *ret_dstblend )
233
DFBSurfaceBlendFunction srcblend = DSBF_ONE;
234
DFBSurfaceBlendFunction dstblend = DSBF_ZERO;
237
case CAIRO_OPERATOR_CLEAR:
238
srcblend = DSBF_ZERO;
239
dstblend = DSBF_ZERO;
241
case CAIRO_OPERATOR_SOURCE:
243
dstblend = DSBF_ZERO;
245
case CAIRO_OPERATOR_OVER:
247
dstblend = DSBF_INVSRCALPHA;
249
case CAIRO_OPERATOR_IN:
250
srcblend = DSBF_DESTALPHA;
251
dstblend = DSBF_ZERO;
253
case CAIRO_OPERATOR_OUT:
254
srcblend = DSBF_INVDESTALPHA;
255
dstblend = DSBF_ZERO;
257
case CAIRO_OPERATOR_ATOP:
258
srcblend = DSBF_DESTALPHA;
259
dstblend = DSBF_INVSRCALPHA;
261
case CAIRO_OPERATOR_DEST:
262
srcblend = DSBF_ZERO;
265
case CAIRO_OPERATOR_DEST_OVER:
266
srcblend = DSBF_INVDESTALPHA;
269
case CAIRO_OPERATOR_DEST_IN:
270
srcblend = DSBF_ZERO;
271
dstblend = DSBF_SRCALPHA;
273
case CAIRO_OPERATOR_DEST_OUT:
274
srcblend = DSBF_ZERO;
275
dstblend = DSBF_INVSRCALPHA;
277
case CAIRO_OPERATOR_DEST_ATOP:
278
srcblend = DSBF_INVDESTALPHA;
279
dstblend = DSBF_SRCALPHA;
281
case CAIRO_OPERATOR_XOR:
282
srcblend = DSBF_INVDESTALPHA;
283
dstblend = DSBF_INVSRCALPHA;
285
case CAIRO_OPERATOR_ADD:
289
case CAIRO_OPERATOR_SATURATE:
290
srcblend = DSBF_SRCALPHASAT;
294
return CAIRO_INT_STATUS_UNSUPPORTED;
298
*ret_srcblend = srcblend;
300
*ret_dstblend = dstblend;
302
return CAIRO_STATUS_SUCCESS;
305
static IDirectFBSurface*
306
_directfb_buffer_surface_create (IDirectFB *dfb,
307
DFBSurfacePixelFormat format,
311
IDirectFBSurface *buffer;
312
DFBSurfaceDescription dsc;
315
dsc.flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT;
318
dsc.pixelformat = format;
320
ret = dfb->CreateSurface (dfb, &dsc, &buffer);
322
DirectFBError ("IDirectFB::CreateSurface()", ret);
329
static cairo_status_t
330
_directfb_acquire_surface (cairo_directfb_surface_t *surface,
331
cairo_rectangle_int_t *intrest_rec,
332
cairo_image_surface_t **image_out,
333
cairo_rectangle_int_t *image_rect_out,
335
DFBSurfaceLockFlags lock_flags)
337
IDirectFBSurface *buffer = NULL;
338
DFBRectangle source_rect;
339
cairo_format_t cairo_format;
343
if (surface->format == (cairo_format_t) -1) {
344
DFBSurfaceCapabilities caps;
347
source_rect.x = intrest_rec->x;
348
source_rect.y = intrest_rec->y;
349
source_rect.w = intrest_rec->width;
350
source_rect.h = intrest_rec->height;
354
surface->dfbsurface->GetSize (surface->dfbsurface,
355
&source_rect.w, &source_rect.h);
358
if (surface->tmpsurface) {
360
surface->tmpsurface->GetSize (surface->tmpsurface, &w, &h);
361
if (w < source_rect.w || h < source_rect.h) {
362
surface->tmpsurface->Release (surface->tmpsurface);
363
surface->tmpsurface = NULL;
367
cairo_format = _cairo_format_from_content (surface->content);
368
if (!surface->tmpsurface) {
369
D_DEBUG_AT (Cairo_DirectFB, "Allocating buffer for surface %p.\n", surface);
371
surface->tmpsurface =
372
_directfb_buffer_surface_create (surface->dfb,
373
_cairo_to_directfb_format (cairo_format),
374
source_rect.w, source_rect.h);
375
if (!surface->tmpsurface)
378
buffer = surface->tmpsurface;
380
surface->dfbsurface->GetCapabilities (surface->dfbsurface, &caps);
381
if (caps & DSCAPS_FLIPPING) {
382
DFBRegion region = { .x1 = source_rect.x, .y1 = source_rect.y,
383
.x2 = source_rect.x + source_rect.w - 1,
384
.y2 = source_rect.y + source_rect.h - 1 };
385
surface->dfbsurface->Flip (surface->dfbsurface, ®ion, DSFLIP_BLIT);
387
buffer->Blit (buffer, surface->dfbsurface, &source_rect, 0, 0);
390
/*might be a subsurface get the offset*/
391
surface->dfbsurface->GetVisibleRectangle (surface->dfbsurface, &source_rect);
392
cairo_format = surface->format;
393
buffer = surface->dfbsurface;
396
*image_extra = buffer;
398
if (buffer->Lock (buffer, lock_flags, &data, &pitch)) {
399
D_DEBUG_AT (Cairo_DirectFB, "Couldn't lock surface!\n");
403
*image_out = (cairo_image_surface_t *)
404
cairo_image_surface_create_for_data (data, cairo_format,
405
source_rect.w, source_rect.h, pitch);
406
if (*image_out == NULL)
409
if (image_rect_out) {
410
image_rect_out->x = source_rect.x;
411
image_rect_out->y = source_rect.y;
412
image_rect_out->width = source_rect.w;
413
image_rect_out->height = source_rect.h;
416
cairo_surface_t *sur = &((*image_out)->base);
417
/* might be a subsurface */
418
if (buffer == surface->dfbsurface)
419
cairo_surface_set_device_offset (sur, source_rect.x, source_rect.y);
422
return CAIRO_STATUS_SUCCESS;
427
buffer->Unlock (buffer);
428
if (buffer != surface->dfbsurface)
429
buffer->Release (buffer);
431
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
436
static cairo_surface_t *
437
_cairo_directfb_surface_create_similar (void *abstract_src,
438
cairo_content_t content,
442
cairo_directfb_surface_t *source = abstract_src;
443
cairo_directfb_surface_t *surface;
444
cairo_format_t format;
446
D_DEBUG_AT (Cairo_DirectFB,
447
"%s( src=%p, content=0x%x, width=%d, height=%d).\n",
448
__FUNCTION__, source, content, width, height);
450
width = (width <= 0) ? 1 : width;
451
height = (height<= 0) ? 1 : height;
453
format = _cairo_format_from_content (content);
454
surface = calloc (1, sizeof(cairo_directfb_surface_t));
456
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
460
surface->dfb = source->dfb;
462
if (width < 8 || height < 8) {
463
IDirectFBSurface *tmp;
464
/* Some cards (e.g. Matrox) don't support surfaces smaller than 8x8 */
465
tmp = _directfb_buffer_surface_create (surface->dfb,
466
_cairo_to_directfb_format (format),
467
MAX (width, 8), MAX (height, 8));
469
DFBRectangle rect = { .x=0, .y=0, .w=width, .h=height };
470
tmp->GetSubSurface (tmp, &rect, &surface->dfbsurface);
475
surface->dfbsurface = _directfb_buffer_surface_create (surface->dfb,
476
_cairo_to_directfb_format (format), width, height);
479
if (!surface->dfbsurface) {
480
D_ASSERT (surface->dfbsurface != NULL);
485
_cairo_surface_init (&surface->base, &cairo_directfb_surface_backend, content);
486
surface->format = format;
487
surface->content = content;
488
surface->width = width;
489
surface->height = height;
490
surface->local = true;
492
return &surface->base;
495
static cairo_status_t
496
_cairo_directfb_surface_finish (void *data)
498
cairo_directfb_surface_t *surface = (cairo_directfb_surface_t *)data;
500
D_DEBUG_AT (Cairo_DirectFB,
501
"%s( surface=%p ).\n", __FUNCTION__, surface);
503
if (surface->clips) {
504
free (surface->clips);
505
surface->clips = NULL;
506
surface->n_clips = 0;
509
if (surface->color) {
510
cairo_surface_destroy (surface->color);
511
surface->color = NULL;
514
if (surface->tmpsurface) {
515
surface->tmpsurface->Release (surface->tmpsurface);
516
surface->tmpsurface = NULL;
519
if (surface->dfbsurface) {
520
surface->dfbsurface->Release (surface->dfbsurface);
521
surface->dfbsurface = NULL;
527
return CAIRO_STATUS_SUCCESS;
530
static cairo_status_t
531
_cairo_directfb_surface_acquire_source_image (void *abstract_surface,
532
cairo_image_surface_t **image_out,
535
cairo_directfb_surface_t *surface = abstract_surface;
537
D_DEBUG_AT (Cairo_DirectFB,
538
"%s( surface=%p ).\n", __FUNCTION__, surface);
540
return _directfb_acquire_surface (surface, NULL, image_out,
541
NULL, image_extra, DSLF_READ);
545
_cairo_directfb_surface_release_source_image (void *abstract_surface,
546
cairo_image_surface_t *image,
549
cairo_directfb_surface_t *surface = abstract_surface;
550
IDirectFBSurface *buffer = image_extra;
552
D_DEBUG_AT (Cairo_DirectFB,
553
"%s( surface=%p ).\n", __FUNCTION__, surface);
555
buffer->Unlock (buffer);
557
cairo_surface_destroy (&image->base);
560
static cairo_status_t
561
_cairo_directfb_surface_acquire_dest_image (void *abstract_surface,
562
cairo_rectangle_int_t *interest_rect,
563
cairo_image_surface_t **image_out,
564
cairo_rectangle_int_t *image_rect_out,
567
cairo_directfb_surface_t *surface = abstract_surface;
569
D_DEBUG_AT (Cairo_DirectFB,
570
"%s( surface=%p, interest_rect={ %d %d %d %d } ).\n",
571
__FUNCTION__, surface,
572
interest_rect ? interest_rect->x : 0,
573
interest_rect ? interest_rect->y : 0,
574
interest_rect ? interest_rect->width : surface->width,
575
interest_rect ? interest_rect->height : surface->height);
577
return _directfb_acquire_surface (surface, interest_rect, image_out,
578
image_rect_out, image_extra, DSLF_READ | DSLF_WRITE);
582
_cairo_directfb_surface_release_dest_image (void *abstract_surface,
583
cairo_rectangle_int_t *interest_rect,
584
cairo_image_surface_t *image,
585
cairo_rectangle_int_t *image_rect,
588
cairo_directfb_surface_t *surface = abstract_surface;
589
IDirectFBSurface *buffer = image_extra;
591
D_DEBUG_AT (Cairo_DirectFB,
592
"%s( surface=%p ).\n", __FUNCTION__, surface);
594
buffer->Unlock (buffer);
596
if (surface->dfbsurface != buffer) {
597
DFBRegion region = { .x1 = interest_rect->x, .y1 = interest_rect->y,
598
.x2 = interest_rect->x+interest_rect->width-1,
599
.y2 = interest_rect->y+interest_rect->height-1 };
600
surface->dfbsurface->SetClip (surface->dfbsurface, ®ion);
601
surface->dfbsurface->SetBlittingFlags (surface->dfbsurface, DSBLIT_NOFX);
602
surface->dfbsurface->Blit (surface->dfbsurface, buffer,
603
NULL, image_rect->x, image_rect->y);
606
cairo_surface_destroy (&image->base);
609
static cairo_status_t
610
_cairo_directfb_surface_clone_similar (void *abstract_surface,
611
cairo_surface_t *src,
616
cairo_surface_t **clone_out)
618
cairo_directfb_surface_t *surface = abstract_surface;
619
cairo_directfb_surface_t *clone;
621
D_DEBUG_AT (Cairo_DirectFB,
622
"%s( surface=%p, src=%p ).\n", __FUNCTION__, surface, src);
624
if (src->backend == surface->base.backend) {
625
cairo_surface_reference (src);
628
return CAIRO_STATUS_SUCCESS;
630
else if (_cairo_surface_is_image (src)) {
631
cairo_image_surface_t *image_src = (cairo_image_surface_t *) src;
632
unsigned char *dst, *src = image_src->data;
637
clone = (cairo_directfb_surface_t *)
638
_cairo_directfb_surface_create_similar (surface,
639
_cairo_content_from_format (image_src->format),
640
image_src->width, image_src->height);
642
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
644
ret = clone->dfbsurface->Lock (clone->dfbsurface,
645
DSLF_WRITE, (void *)&dst, &pitch);
647
DirectFBError ("IDirectFBSurface::Lock()", ret);
648
cairo_surface_destroy ((cairo_surface_t *)clone);
649
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
652
dst += pitch * src_y;
653
src += image_src->stride * src_y;
655
if (image_src->format == CAIRO_FORMAT_A1) {
657
for (i = 0; i < height; i++) {
658
for (j = src_x; j < src_x + width; j++)
659
dst[j] = (src[j>>3] & (1 << (j&7))) ? 0xff : 0x00;
661
src += image_src->stride;
667
if (image_src->format == CAIRO_FORMAT_A8) {
677
for (i = 0; i < height; i++) {
678
direct_memcpy (dst+src_x, src+src_x, len);
680
src += image_src->stride;
684
clone->dfbsurface->Unlock (clone->dfbsurface);
686
*clone_out = &clone->base;
688
return CAIRO_STATUS_SUCCESS;
691
return CAIRO_INT_STATUS_UNSUPPORTED;
694
#if DFB_COMPOSITE || DFB_COMPOSITE_TRAPEZOIDS
695
static cairo_int_status_t
696
_directfb_prepare_composite (cairo_directfb_surface_t *dst,
697
cairo_pattern_t *src_pattern,
698
cairo_pattern_t *mask_pattern,
700
int *src_x, int *src_y,
701
int *mask_x, int *mask_y,
704
cairo_directfb_surface_t **ret_src,
705
cairo_surface_attributes_t *ret_src_attr)
707
cairo_directfb_surface_t *src;
708
cairo_surface_attributes_t src_attr;
710
DFBSurfaceBlittingFlags flags;
711
DFBSurfaceBlendFunction sblend;
712
DFBSurfaceBlendFunction dblend;
715
if (_directfb_get_operator (op, &sblend, &dblend))
716
return CAIRO_INT_STATUS_UNSUPPORTED;
719
cairo_solid_pattern_t *pattern;
721
if (mask_pattern->type != CAIRO_PATTERN_TYPE_SOLID) {
722
cairo_pattern_t *tmp;
725
if (src_pattern->type != CAIRO_PATTERN_TYPE_SOLID ||
726
sblend == DSBF_INVDESTALPHA) /* Doesn't work correctly */
727
return CAIRO_INT_STATUS_UNSUPPORTED;
729
D_DEBUG_AT (Cairo_DirectFB, "Replacing src pattern by mask pattern.\n");
732
tmp_x = *src_x; tmp_y = *src_y;
734
src_pattern = mask_pattern;
735
*src_x = *mask_x; *src_y = *mask_y;
738
*mask_x = tmp_x; *mask_y = tmp_y;
740
if (sblend == DSBF_ONE) {
741
sblend = DSBF_SRCALPHA;
742
/*dblend = DSBF_INVSRCALPHA;*/
746
pattern = (cairo_solid_pattern_t *)mask_pattern;
747
color.a = pattern->color.alpha_short >> 8;
748
color.r = pattern->color.red_short >> 8;
749
color.g = pattern->color.green_short >> 8;
750
color.b = pattern->color.blue_short >> 8;
753
color.a = color.r = color.g = color.b = 0xff;
756
if (src_pattern->type == CAIRO_PATTERN_TYPE_SOLID) {
757
cairo_solid_pattern_t *pattern = (cairo_solid_pattern_t *)src_pattern;
760
dst->color = _cairo_directfb_surface_create_similar (dst,
761
CAIRO_CONTENT_COLOR_ALPHA, 1, 1);
763
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
766
src = (cairo_directfb_surface_t *)dst->color;
767
src->dfbsurface->Clear (src->dfbsurface,
768
pattern->color.red_short >> 8,
769
pattern->color.green_short >> 8,
770
pattern->color.blue_short >> 8,
771
pattern->color.alpha_short >> 8);
773
src_attr.matrix = src_pattern->matrix;
774
src_attr.extend = CAIRO_EXTEND_NONE;
775
src_attr.filter = CAIRO_FILTER_NEAREST;
777
src_attr.y_offset = 0;
780
ret = _cairo_pattern_acquire_surface (src_pattern, &dst->base,
781
*src_x, *src_y, width, height,
782
(cairo_surface_t **)&src, &src_attr);
787
if (src->content == CAIRO_CONTENT_COLOR) {
788
if (sblend == DSBF_SRCALPHA)
790
else if (sblend == DSBF_INVSRCALPHA)
793
if (dblend == DSBF_SRCALPHA)
795
else if (dblend == DSBF_INVSRCALPHA)
798
if (dst->content == CAIRO_CONTENT_COLOR) {
799
if (sblend == DSBF_DESTALPHA)
801
else if (sblend == DSBF_INVDESTALPHA)
804
if (dblend == DSBF_DESTALPHA)
806
else if (dblend == DSBF_INVDESTALPHA)
810
flags = (sblend == DSBF_ONE && dblend == DSBF_ZERO)
811
? DSBLIT_NOFX : DSBLIT_BLEND_ALPHACHANNEL;
813
flags |= DSBLIT_BLEND_COLORALPHA;
814
if (color.r != 0xff || color.g != 0xff || color.b != 0xff)
815
flags |= DSBLIT_COLORIZE;
817
dst->dfbsurface->SetBlittingFlags (dst->dfbsurface, flags);
819
if (flags & (DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA)) {
820
dst->dfbsurface->SetSrcBlendFunction (dst->dfbsurface, sblend);
821
dst->dfbsurface->SetDstBlendFunction (dst->dfbsurface, dblend);
824
if (flags & (DSBLIT_BLEND_COLORALPHA | DSBLIT_COLORIZE))
825
dst->dfbsurface->SetColor (dst->dfbsurface, color.r, color.g, color.b, color.a);
828
*ret_src_attr = src_attr;
830
return CAIRO_STATUS_SUCCESS;
834
_directfb_finish_composite (cairo_directfb_surface_t *dst,
835
cairo_pattern_t *src_pattern,
836
cairo_surface_t *src,
837
cairo_surface_attributes_t *src_attr)
839
if (src != dst->color)
840
_cairo_pattern_release_surface (src_pattern, src, src_attr);
842
#endif /* DFB_COMPOSITE || DFB_COMPOSITE_TRAPEZOIDS */
845
static DFBAccelerationMask
846
_directfb_categorize_operation (cairo_surface_attributes_t *src_attr)
848
cairo_matrix_t *m = &src_attr->matrix;
850
if (m->xy != 0 || m->yx != 0 || m->xx < 0 || m->yy < 0) {
851
if (src_attr->extend != CAIRO_EXTEND_NONE)
853
return DFXL_TEXTRIANGLES;
856
if (m->xx != 1 || m->yy != 1) {
857
if (src_attr->extend != CAIRO_EXTEND_NONE)
859
return DFXL_STRETCHBLIT;
862
if (src_attr->extend != CAIRO_EXTEND_NONE &&
863
src_attr->extend != CAIRO_EXTEND_REPEAT)
869
static cairo_int_status_t
870
_cairo_directfb_surface_composite (cairo_operator_t op,
871
cairo_pattern_t *src_pattern,
872
cairo_pattern_t *mask_pattern,
874
int src_x, int src_y,
875
int mask_x, int mask_y,
876
int dst_x, int dst_y,
880
cairo_directfb_surface_t *dst = abstract_dst;
881
cairo_directfb_surface_t *src;
882
cairo_surface_attributes_t src_attr;
883
DFBAccelerationMask accel, mask;
884
cairo_int_status_t ret;
886
D_DEBUG_AT (Cairo_DirectFB,
887
"%s( op=%d, src_pattern=%p, mask_pattern=%p, dst=%p,"
888
" src_x=%d, src_y=%d, mask_x=%d, mask_y=%d, dst_x=%d,"
889
" dst_y=%d, width=%u, height=%u ).\n",
890
__FUNCTION__, op, src_pattern, mask_pattern, dst,
891
src_x, src_y, mask_x, mask_y, dst_x, dst_y, width, height);
893
ret = _directfb_prepare_composite (dst, src_pattern, mask_pattern, op,
894
&src_x, &src_y, &mask_x, &mask_y,
895
width, height, &src, &src_attr);
899
accel = _directfb_categorize_operation (&src_attr);
901
dst->dfbsurface->GetAccelerationMask (dst->dfbsurface, src->dfbsurface, &mask);
902
if (!(mask & accel)) {
903
D_DEBUG_AT (Cairo_DirectFB, "No acceleration (%08x)!\n", accel);
904
if (accel != DFXL_BLIT) {
905
_directfb_finish_composite (dst, src_pattern, &src->base, &src_attr);
906
return CAIRO_INT_STATUS_UNSUPPORTED;
910
src_x += src_attr.x_offset;
911
src_y += src_attr.y_offset;
917
sr.x = src_x + _cairo_lround (src_attr.matrix.x0);
918
sr.y = src_y + _cairo_lround (src_attr.matrix.y0);
922
if (src_attr.extend == CAIRO_EXTEND_NONE) {
923
D_DEBUG_AT (Cairo_DirectFB, "Running Blit().\n");
925
RUN_CLIPPED( dst, NULL,
926
dst->dfbsurface->Blit (dst->dfbsurface,
927
src->dfbsurface, &sr, dst_x, dst_y));
929
else if (src_attr.extend == CAIRO_EXTEND_REPEAT) {
934
clip.x2 = dst_x + width - 1;
935
clip.y2 = dst_y + height - 1;
937
D_DEBUG_AT (Cairo_DirectFB, "Running TileBlit().\n");
939
RUN_CLIPPED( dst, &clip,
940
dst->dfbsurface->TileBlit (dst->dfbsurface,
941
src->dfbsurface, &sr, dst_x, dst_y));
945
case DFXL_STRETCHBLIT: {
947
double x1, y1, x2, y2;
949
TRANSFORM_POINT2X (src_attr.matrix,
950
src_x, src_y, x1, y1);
951
TRANSFORM_POINT2X (src_attr.matrix,
952
src_x+width, src_y+height, x2, y2);
954
sr.x = _cairo_lround (x1);
955
sr.y = _cairo_lround (y1);
956
sr.w = _cairo_lround (x2-x1);
957
sr.h = _cairo_lround (y2-y1);
964
D_DEBUG_AT (Cairo_DirectFB, "Running StretchBlit().\n");
966
RUN_CLIPPED (dst, NULL,
967
dst->dfbsurface->StretchBlit (dst->dfbsurface,
968
src->dfbsurface, &sr, &dr));
971
case DFXL_TEXTRIANGLES: {
974
float x1, y1, x2, y2;
977
if (cairo_matrix_invert (&src_attr.matrix) != CAIRO_STATUS_SUCCESS) {
978
ret = CAIRO_INT_STATUS_UNSUPPORTED;
982
x1 = src_attr.x_offset;
983
y1 = src_attr.y_offset;
984
x2 = src->width - x1;
985
y2 = src->height - y1;
987
src->dfbsurface->GetSize (src->dfbsurface, &w, &h);
989
TRANSFORM_POINT3X (src_attr.matrix,
990
x1, y1, v[0].x, v[0].y);
996
TRANSFORM_POINT3X (src_attr.matrix,
997
x2, y1, v[1].x, v[1].y);
1003
TRANSFORM_POINT3X (src_attr.matrix,
1004
x2, y2, v[2].x, v[2].y);
1010
TRANSFORM_POINT3X (src_attr.matrix,
1011
x1, y2, v[3].x, v[3].y);
1019
clip.x2 = dst_x + width - 1;
1020
clip.y2 = dst_y + height - 1;
1022
D_DEBUG_AT (Cairo_DirectFB, "Running TextureTriangles().\n");
1024
RUN_CLIPPED (dst, &clip,
1025
dst->dfbsurface->TextureTriangles (dst->dfbsurface,
1026
src->dfbsurface, v, NULL, 4, DTTF_FAN));
1030
D_BUG ("Unexpected operation");
1034
_directfb_finish_composite (dst, src_pattern, &src->base, &src_attr);
1038
#endif /* DFB_COMPOSITE */
1041
static cairo_int_status_t
1042
_cairo_directfb_surface_fill_rectangles (void *abstract_surface,
1043
cairo_operator_t op,
1044
const cairo_color_t *color,
1045
cairo_rectangle_int_t *rects,
1048
cairo_directfb_surface_t *dst = abstract_surface;
1049
DFBSurfaceDrawingFlags flags;
1050
DFBSurfaceBlendFunction sblend;
1051
DFBSurfaceBlendFunction dblend;
1052
DFBRectangle r[n_rects];
1055
D_DEBUG_AT (Cairo_DirectFB,
1056
"%s( dst=%p, op=%d, color=%p, rects=%p, n_rects=%d ).\n",
1057
__FUNCTION__, dst, op, color, rects, n_rects);
1059
if (_directfb_get_operator (op, &sblend, &dblend))
1060
return CAIRO_INT_STATUS_UNSUPPORTED;
1062
if (color->alpha_short >= 0xff00) {
1063
if (sblend == DSBF_SRCALPHA)
1065
else if (sblend == DSBF_INVSRCALPHA)
1068
if (dblend == DSBF_SRCALPHA)
1070
else if (dblend == DSBF_INVSRCALPHA)
1073
if (dst->content == CAIRO_CONTENT_COLOR) {
1074
if (sblend == DSBF_DESTALPHA)
1076
else if (sblend == DSBF_INVDESTALPHA)
1079
if (dblend == DSBF_DESTALPHA)
1081
else if (dblend == DSBF_INVDESTALPHA)
1085
flags = (sblend == DSBF_ONE && dblend == DSBF_ZERO) ? DSDRAW_NOFX : DSDRAW_BLEND;
1086
dst->dfbsurface->SetDrawingFlags (dst->dfbsurface, flags);
1087
if (flags & DSDRAW_BLEND) {
1088
dst->dfbsurface->SetSrcBlendFunction (dst->dfbsurface, sblend);
1089
dst->dfbsurface->SetDstBlendFunction (dst->dfbsurface, dblend);
1092
dst->dfbsurface->SetColor (dst->dfbsurface,
1093
color->red_short >> 8,
1094
color->green_short >> 8,
1095
color->blue_short >> 8,
1096
color->alpha_short >> 8 );
1098
for (i = 0; i < n_rects; i++) {
1099
r[i].x = rects[i].x;
1100
r[i].y = rects[i].y;
1101
r[i].w = rects[i].width;
1102
r[i].h = rects[i].height;
1105
RUN_CLIPPED (dst, NULL,
1106
dst->dfbsurface->FillRectangles (dst->dfbsurface, r, n_rects));
1108
return CAIRO_STATUS_SUCCESS;
1112
#if DFB_COMPOSITE_TRAPEZOIDS
1113
static cairo_int_status_t
1114
_cairo_directfb_surface_composite_trapezoids (cairo_operator_t op,
1115
cairo_pattern_t *pattern,
1117
cairo_antialias_t antialias,
1118
int src_x, int src_y,
1119
int dst_x, int dst_y,
1121
unsigned int height,
1122
cairo_trapezoid_t *traps,
1125
cairo_directfb_surface_t *dst = abstract_dst;
1126
cairo_directfb_surface_t *src;
1127
cairo_surface_attributes_t src_attr;
1129
DFBAccelerationMask accel;
1131
D_DEBUG_AT (Cairo_DirectFB,
1132
"%s( op=%d, pattern=%p, dst=%p, antialias=%d,"
1133
" src_x=%d, src_y=%d, dst_x=%d, dst_y=%d,"
1134
" width=%u, height=%u, traps=%p, num_traps=%d ).\n",
1135
__FUNCTION__, op, pattern, dst, antialias,
1136
src_x, src_y, dst_x, dst_y, width, height, traps, num_traps);
1138
if (antialias != CAIRO_ANTIALIAS_NONE)
1139
return CAIRO_INT_STATUS_UNSUPPORTED;
1141
/* Textures are not supported yet. */
1142
if (pattern->type != CAIRO_PATTERN_TYPE_SOLID)
1143
return CAIRO_INT_STATUS_UNSUPPORTED;
1145
ret = _directfb_prepare_composite (dst, pattern, NULL, op,
1146
&src_x, &src_y, NULL, NULL,
1147
width, height, &src, &src_attr);
1151
dst->dfbsurface->GetAccelerationMask (dst->dfbsurface, src->dfbsurface, &accel);
1153
ret = CAIRO_INT_STATUS_UNSUPPORTED;
1155
if (accel & DFXL_TEXTRIANGLES) {
1156
DFBVertex vertex[6*num_traps];
1157
DFBVertex *v = &vertex[0];
1160
#define ADD_TRI(id, x1, y1, s1, t1, x2, y2, s2, t2, x3, y3, s3, t3) {\
1161
const int p = (id)*3;\
1162
v[p+0].x=(x1); v[p+0].y=(y1); v[p+0].z=0; v[p+0].w=1; v[p+0].s=(s1); v[p+0].t=(t1);\
1163
v[p+1].x=(x2); v[p+1].y=(y2); v[p+1].z=0; v[p+1].w=1; v[p+1].s=(s2); v[p+1].t=(t2);\
1164
v[p+2].x=(x3); v[p+2].y=(y3); v[p+2].z=0; v[p+2].w=1; v[p+2].s=(s3); v[p+2].t=(t3);\
1167
for (n = 0; num_traps; num_traps--) {
1168
float lx1, ly1, lx2, ly2;
1169
float rx1, ry1, rx2, ry2;
1171
/* XXX: Do we need to validate the trapezoid? */
1173
lx1 = traps->left.p1.x/65536.0;
1174
ly1 = traps->left.p1.y/65536.0;
1175
lx2 = traps->left.p2.x/65536.0;
1176
ly2 = traps->left.p2.y/65536.0;
1177
rx1 = traps->right.p1.x/65536.0;
1178
ry1 = traps->right.p1.y/65536.0;
1179
rx2 = traps->right.p2.x/65536.0;
1180
ry2 = traps->right.p2.y/65536.0;
1182
if (traps->left.p1.y < traps->top) {
1183
float y = traps->top/65536.0;
1185
lx1 = (y - ly1) * (lx2 - lx1) / (ly2 - ly1) + lx1;
1188
if (traps->left.p2.y > traps->bottom) {
1189
float y = traps->bottom/65536.0;
1191
lx2 = (y - ly1) * (lx2 - lx1) / (ly2 - ly1) + lx1;
1195
if (traps->right.p1.y < traps->top) {
1196
float y = traps->top/65536.0;
1198
rx1 = (y - ry1) * (rx2 - rx1) / (ry2 - ry1) + rx1;
1201
if (traps->right.p2.y > traps->bottom) {
1202
float y = traps->bottom/65536.0;
1204
rx2 = (y - ry1) * (rx2 - rx1) / (ry2 - ry1) + rx1;
1208
if (lx1 == rx1 && ly1 == ry1) {
1209
ADD_TRI (0, lx2, ly2, 0, 0,
1215
else if (lx2 == rx2 && ly2 == ry2) {
1216
ADD_TRI (0, lx1, ly1, 0, 0,
1223
ADD_TRI (0, lx1, ly1, 0, 0,
1226
ADD_TRI (1, lx2, ly2, 0, 0,
1238
D_DEBUG_AT (Cairo_DirectFB, "Running TextureTriangles().\n");
1240
RUN_CLIPPED (dst, NULL,
1241
dst->dfbsurface->TextureTriangles (dst->dfbsurface, src->dfbsurface,
1242
vertex, NULL, n, DTTF_LIST));
1244
ret = CAIRO_STATUS_SUCCESS;
1247
_directfb_finish_composite (dst, pattern, &src->base, &src_attr);
1251
#endif /* DFB_COMPOSITE_TRAPEZOIDS */
1253
static cairo_int_status_t
1254
_cairo_directfb_surface_set_clip_region (void *abstract_surface,
1255
cairo_region_t *region)
1257
cairo_directfb_surface_t *surface = abstract_surface;
1259
D_DEBUG_AT (Cairo_DirectFB,
1260
"%s( surface=%p, region=%p ).\n",
1261
__FUNCTION__, surface, region);
1264
cairo_box_int_t *boxes;
1266
cairo_status_t status;
1269
status = _cairo_region_get_boxes (region, &n_boxes, &boxes);
1273
if (surface->n_clips != n_boxes) {
1275
free (surface->clips);
1277
surface->clips = _cairo_malloc_ab (n_boxes, sizeof(DFBRegion));
1278
if (!surface->clips) {
1279
surface->n_clips = 0;
1280
_cairo_region_boxes_fini (region, boxes);
1281
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1284
surface->n_clips = n_boxes;
1287
for (i = 0; i < n_boxes; i++) {
1288
surface->clips[i].x1 = boxes[i].p1.x;
1289
surface->clips[i].y1 = boxes[i].p1.y;
1290
surface->clips[i].x2 = boxes[i].p2.x;
1291
surface->clips[i].y2 = boxes[i].p2.y;
1294
_cairo_region_boxes_fini (region, boxes);
1297
if (surface->clips) {
1298
free (surface->clips);
1299
surface->clips = NULL;
1300
surface->n_clips = 0;
1304
return CAIRO_STATUS_SUCCESS;
1307
static cairo_int_status_t
1308
_cairo_directfb_abstract_surface_get_extents (void *abstract_surface,
1309
cairo_rectangle_int_t *rectangle)
1311
cairo_directfb_surface_t *surface = abstract_surface;
1313
D_DEBUG_AT (Cairo_DirectFB,
1314
"%s( surface=%p, rectangle=%p ).\n",
1315
__FUNCTION__, surface, rectangle);
1318
if (!surface->local) {
1319
surface->dfbsurface->GetSize (surface->dfbsurface,
1320
&surface->width, &surface->height);
1324
rectangle->width = surface->width;
1325
rectangle->height = surface->height;
1328
return CAIRO_STATUS_SUCCESS;
1332
static cairo_directfb_font_cache_t*
1333
_directfb_allocate_font_cache (IDirectFB *dfb, int width, int height)
1335
cairo_directfb_font_cache_t *cache;
1337
cache = calloc (1, sizeof(cairo_directfb_font_cache_t));
1342
cache->dfbsurface = _directfb_buffer_surface_create (dfb,
1343
_directfb_argb_font ? DSPF_ARGB : DSPF_A8, width, height);
1344
if (!cache->dfbsurface) {
1348
cache->width = width;
1349
cache->height = height;
1355
_directfb_destroy_font_cache (cairo_directfb_font_cache_t *cache)
1357
cache->dfbsurface->Release (cache->dfbsurface);
1361
static cairo_status_t
1362
_directfb_acquire_font_cache (cairo_directfb_surface_t *surface,
1363
cairo_scaled_font_t *scaled_font,
1364
const cairo_glyph_t *glyphs,
1366
cairo_directfb_font_cache_t **ret_cache,
1367
DFBRectangle *rects,
1372
cairo_scaled_glyph_t *chars[num_glyphs];
1374
cairo_directfb_font_cache_t *cache = NULL;
1382
if (scaled_font->surface_private) {
1383
cache = scaled_font->surface_private;
1388
for (i = 0; i < num_glyphs; i++) {
1389
cairo_scaled_glyph_t *scaled_glyph;
1390
cairo_image_surface_t *img;
1392
ret = _cairo_scaled_glyph_lookup (scaled_font, glyphs[i].index,
1393
CAIRO_SCALED_GLYPH_INFO_SURFACE,
1398
img = scaled_glyph->surface;
1399
switch (img->format) {
1400
case CAIRO_FORMAT_A1:
1401
case CAIRO_FORMAT_A8:
1402
case CAIRO_FORMAT_ARGB32:
1405
D_DEBUG_AT (Cairo_DirectFB,
1406
"Unsupported font format %d!\n", img->format);
1407
return CAIRO_INT_STATUS_UNSUPPORTED;
1410
points[n].x = _cairo_lround (glyphs[i].x - img->base.device_transform.x0);
1411
points[n].y = _cairo_lround (glyphs[i].y - img->base.device_transform.y0);
1413
if (points[n].x >= surface->width ||
1414
points[n].y >= surface->height ||
1415
points[n].x+img->width <= 0 ||
1416
points[n].y+img->height <= 0)
1419
if (!scaled_glyph->surface_private) {
1422
if (x+img->width > 2048) {
1430
rects[n].w = img->width;
1431
rects[n].h = img->height;
1434
h = MAX (h, img->height);
1437
/* Remember glyph location */
1438
rect = malloc (sizeof(DFBRectangle));
1440
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1443
scaled_glyph->surface_private = rect;
1444
chars[num_chars++] = scaled_glyph;
1446
/*D_DEBUG_AT (Cairo_DirectFB,
1447
"Glyph %lu will be loaded at (%d,%d).\n",
1448
glyphs[i].index, rects[n].x, rects[n].y);*/
1451
rects[n] = *((DFBRectangle *)scaled_glyph->surface_private);
1453
/*D_DEBUG_AT (Cairo_DirectFB,
1454
"Glyph %lu already loaded at (%d,%d).\n",
1455
glyphs[i].index, rects[n].x, rects[n].y);*/
1462
return CAIRO_INT_STATUS_NOTHING_TO_DO;
1469
if (cache->width < w || cache->height < h) {
1470
cairo_directfb_font_cache_t *new_cache;
1472
w = MAX (w, cache->width);
1473
h = MAX (h, cache->height);
1475
D_DEBUG_AT (Cairo_DirectFB,
1476
"Reallocating font cache (%dx%d).\n", w, h);
1478
new_cache = _directfb_allocate_font_cache (surface->dfb, w, h);
1480
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1482
new_cache->dfbsurface->Blit (new_cache->dfbsurface,
1483
cache->dfbsurface, NULL, 0, 0);
1485
_directfb_destroy_font_cache (cache);
1486
scaled_font->surface_private = cache = new_cache;
1490
D_DEBUG_AT (Cairo_DirectFB,
1491
"Allocating font cache (%dx%d).\n", w, h);
1493
cache = _directfb_allocate_font_cache (surface->dfb, w, h);
1495
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1497
scaled_font->surface_backend = &cairo_directfb_surface_backend;
1498
scaled_font->surface_private = cache;
1502
unsigned char *data;
1505
if (cache->dfbsurface->Lock (cache->dfbsurface,
1506
DSLF_WRITE, (void *)&data, &pitch))
1507
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1509
for (i = 0; i < num_chars; i++) {
1510
cairo_image_surface_t *img = chars[i]->surface;
1511
DFBRectangle *rect = chars[i]->surface_private;
1512
unsigned char *dst = data;
1513
unsigned char *src = img->data;
1516
dst += rect->y * pitch + (_directfb_argb_font ? (rect->x<<2) : rect->x);
1518
if (img->format == CAIRO_FORMAT_A1) {
1519
for (h = rect->h; h; h--) {
1520
if (_directfb_argb_font) {
1521
for (j = 0; j < rect->w; j++)
1522
((uint32_t *)dst)[j] = (src[j>>3] & (1 << (j&7))) ? 0xffffffff : 0;
1525
for (j = 0; j < rect->w; j++)
1526
dst[j] = (src[j>>3] & (1 << (j&7))) ? 0xff : 0;
1533
else if (img->format == CAIRO_FORMAT_A8) {
1534
for (h = rect->h; h; h--) {
1535
if (_directfb_argb_font) {
1536
for (j = 0; j < rect->w; j++)
1537
((uint32_t *)dst)[j] = src[j] * 0x01010101;
1540
direct_memcpy (dst, src, rect->w);
1548
for (h = rect->h; h; h--) {
1549
if (_directfb_argb_font) {
1550
direct_memcpy (dst, src, rect->w<<2);
1553
for (j = 0; j < rect->w; j++)
1554
dst[j] = ((uint32_t *)src)[j] >> 24;
1563
cache->dfbsurface->Unlock (cache->dfbsurface);
1572
return CAIRO_STATUS_SUCCESS;
1576
_cairo_directfb_surface_scaled_font_fini (cairo_scaled_font_t *scaled_font)
1578
cairo_directfb_font_cache_t *cache = scaled_font->surface_private;
1580
D_DEBUG_AT (Cairo_DirectFB,
1581
"%s( scaled_font=%p ).\n", __FUNCTION__, scaled_font);
1584
_directfb_destroy_font_cache (cache);
1585
scaled_font->surface_private = NULL;
1590
_cairo_directfb_surface_scaled_glyph_fini (cairo_scaled_glyph_t *scaled_glyph,
1591
cairo_scaled_font_t *scaled_font)
1593
D_DEBUG_AT (Cairo_DirectFB,
1594
"%s( scaled_glyph=%p, scaled_font=%p ).\n",
1595
__FUNCTION__, scaled_glyph, scaled_font);
1597
if (scaled_glyph->surface_private) {
1598
free (scaled_glyph->surface_private);
1599
scaled_glyph->surface_private = NULL;
1603
static cairo_int_status_t
1604
_cairo_directfb_surface_show_glyphs (void *abstract_dst,
1605
cairo_operator_t op,
1606
cairo_pattern_t *pattern,
1607
cairo_glyph_t *glyphs,
1609
cairo_scaled_font_t *scaled_font)
1611
cairo_directfb_surface_t *dst = abstract_dst;
1612
cairo_directfb_font_cache_t *cache;
1614
DFBSurfaceBlittingFlags flags;
1615
DFBSurfaceBlendFunction sblend;
1616
DFBSurfaceBlendFunction dblend;
1618
DFBRectangle rects[num_glyphs];
1619
DFBPoint points[num_glyphs];
1622
D_DEBUG_AT (Cairo_DirectFB,
1623
"%s( dst=%p, op=%d, pattern=%p, glyphs=%p, num_glyphs=%d, scaled_font=%p ).\n",
1624
__FUNCTION__, dst, op, pattern, glyphs, num_glyphs, scaled_font);
1626
if (pattern->type != CAIRO_PATTERN_TYPE_SOLID)
1627
return CAIRO_INT_STATUS_UNSUPPORTED;
1629
if (_directfb_get_operator (op, &sblend, &dblend) ||
1630
sblend == DSBF_DESTALPHA || sblend == DSBF_INVDESTALPHA)
1631
return CAIRO_INT_STATUS_UNSUPPORTED;
1633
ret = _directfb_acquire_font_cache (dst, scaled_font, glyphs, num_glyphs,
1634
&cache, &rects[0], &points[0], &num);
1636
if (ret == CAIRO_INT_STATUS_NOTHING_TO_DO)
1637
ret = CAIRO_STATUS_SUCCESS;
1641
color.a = ((cairo_solid_pattern_t *)pattern)->color.alpha_short >> 8;
1642
color.r = ((cairo_solid_pattern_t *)pattern)->color.red_short >> 8;
1643
color.g = ((cairo_solid_pattern_t *)pattern)->color.green_short >> 8;
1644
color.b = ((cairo_solid_pattern_t *)pattern)->color.blue_short >> 8;
1646
flags = DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_COLORIZE;
1647
if (color.a != 0xff)
1648
flags |= DSBLIT_BLEND_COLORALPHA;
1650
if (!_directfb_argb_font) {
1651
if (sblend == DSBF_ONE) {
1652
sblend = DSBF_SRCALPHA;
1653
if (dblend == DSBF_ZERO)
1654
dblend = DSBF_INVSRCALPHA;
1658
dst->dfbsurface->SetBlittingFlags (dst->dfbsurface, flags);
1659
dst->dfbsurface->SetSrcBlendFunction (dst->dfbsurface, sblend);
1660
dst->dfbsurface->SetDstBlendFunction (dst->dfbsurface, dblend);
1661
dst->dfbsurface->SetColor (dst->dfbsurface, color.r, color.g, color.b, color.a);
1663
D_DEBUG_AT (Cairo_DirectFB, "Running BatchBlit().\n");
1665
RUN_CLIPPED (dst, NULL,
1666
dst->dfbsurface->BatchBlit (dst->dfbsurface,
1667
cache->dfbsurface, rects, points, num));
1669
return CAIRO_STATUS_SUCCESS;
1671
#endif /* DFB_SHOW_GLYPHS */
1675
_cairo_directfb_surface_is_similar (void *surface_a, void *surface_b, cairo_content_t content)
1677
cairo_directfb_surface_t *a = (cairo_directfb_surface_t *) surface_a;
1678
cairo_directfb_surface_t *b = (cairo_directfb_surface_t *) surface_b;
1680
return a->dfb == b->dfb;
1683
static cairo_surface_backend_t cairo_directfb_surface_backend = {
1684
CAIRO_SURFACE_TYPE_DIRECTFB, /*type*/
1685
_cairo_directfb_surface_create_similar,/*create_similar*/
1686
_cairo_directfb_surface_finish, /*finish*/
1687
_cairo_directfb_surface_acquire_source_image,/*acquire_source_image*/
1688
_cairo_directfb_surface_release_source_image,/*release_source_image*/
1689
_cairo_directfb_surface_acquire_dest_image,/*acquire_dest_image*/
1690
_cairo_directfb_surface_release_dest_image,/*release_dest_image*/
1691
_cairo_directfb_surface_clone_similar,/*clone_similar*/
1693
_cairo_directfb_surface_composite,/*composite*/
1698
_cairo_directfb_surface_fill_rectangles,/*fill_rectangles*/
1700
NULL,/*fill_rectangles*/
1702
#if DFB_COMPOSITE_TRAPEZOIDS
1703
_cairo_directfb_surface_composite_trapezoids,/*composite_trapezoids*/
1705
NULL,/*composite_trapezoids*/
1707
NULL, /* copy_page */
1708
NULL, /* show_page */
1709
_cairo_directfb_surface_set_clip_region,/* set_clip_region */
1710
NULL, /* intersect_clip_path */
1711
_cairo_directfb_abstract_surface_get_extents,/* get_extents */
1712
NULL, /* old_show_glyphs */
1713
NULL, /* get_font_options */
1715
NULL, /* mark_dirty_rectangle */
1717
_cairo_directfb_surface_scaled_font_fini,/* scaled_font_fini */
1718
_cairo_directfb_surface_scaled_glyph_fini,/* scaled_glyph_fini */
1728
_cairo_directfb_surface_show_glyphs,/* show_glyphs */
1730
NULL, /* show_glyphs */
1732
NULL, /* snapshot */
1733
_cairo_directfb_surface_is_similar,
1739
cairo_directfb_surface_backend_init (IDirectFB *dfb)
1741
static int done = 0;
1746
if (getenv ("CAIRO_DIRECTFB_NO_ACCEL")) {
1748
cairo_directfb_surface_backend.fill_rectangles = NULL;
1751
cairo_directfb_surface_backend.composite = NULL;
1753
#if DFB_COMPOSITE_TRAPEZOIDS
1754
cairo_directfb_surface_backend.composite_trapezoids = NULL;
1757
cairo_directfb_surface_backend.scaled_font_fini = NULL;
1758
cairo_directfb_surface_backend.scaled_glyph_fini = NULL;
1759
cairo_directfb_surface_backend.show_glyphs = NULL;
1761
D_DEBUG_AT (Cairo_DirectFB, "Acceleration disabled.\n");
1764
DFBGraphicsDeviceDescription dsc;
1766
dfb->GetDeviceDescription (dfb, &dsc);
1769
if (!(dsc.acceleration_mask & DFXL_BLIT))
1770
cairo_directfb_surface_backend.composite = NULL;
1773
#if DFB_COMPOSITE_TRAPEZOIDS
1774
if (!(dsc.acceleration_mask & DFXL_TEXTRIANGLES))
1775
cairo_directfb_surface_backend.composite_trapezoids = NULL;
1779
if (getenv ("CAIRO_DIRECTFB_ARGB_FONT")) {
1780
_directfb_argb_font = 1;
1781
D_DEBUG_AT (Cairo_DirectFB, "Using ARGB fonts.\n");
1789
cairo_directfb_surface_create (IDirectFB *dfb, IDirectFBSurface *dfbsurface)
1791
cairo_directfb_surface_t *surface;
1792
DFBSurfacePixelFormat format;
1794
D_ASSERT (dfb != NULL);
1795
D_ASSERT (dfbsurface != NULL);
1797
cairo_directfb_surface_backend_init (dfb);
1799
surface = calloc (1, sizeof(cairo_directfb_surface_t));
1803
dfbsurface->AddRef (dfbsurface);
1804
dfbsurface->GetPixelFormat (dfbsurface, &format);
1805
dfbsurface->GetSize (dfbsurface, &surface->width, &surface->height);
1807
surface->dfbsurface = dfbsurface;
1808
surface->format = _directfb_to_cairo_format (format);
1809
surface->content = _directfb_format_to_content (format);
1811
_cairo_surface_init (&surface->base,
1812
&cairo_directfb_surface_backend, surface->content);
1814
return &surface->base;