Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
3959 | Serge | 1 | /* cairo - a vector graphics library with display and print output |
2 | * |
||
3 | * Copyright © 2012 Intel Corporation |
||
4 | * |
||
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. |
||
12 | * |
||
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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA |
||
16 | * You should have received a copy of the MPL along with this library |
||
17 | * in the file COPYING-MPL-1.1 |
||
18 | * |
||
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/ |
||
23 | * |
||
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. |
||
27 | * |
||
28 | * The Original Code is the cairo graphics library. |
||
29 | * |
||
30 | * The Initial Developer of the Original Code is Chris Wilson |
||
31 | * |
||
32 | * Contributor(s): |
||
33 | * Chris Wilson |
||
34 | */ |
||
35 | |||
36 | #include "cairoint.h" |
||
37 | #include "cairo-directfb.h" |
||
38 | |||
39 | #include "cairo-clip-private.h" |
||
40 | #include "cairo-compositor-private.h" |
||
41 | #include "cairo-default-context-private.h" |
||
42 | #include "cairo-error-private.h" |
||
43 | #include "cairo-image-surface-inline.h" |
||
44 | #include "cairo-pattern-private.h" |
||
45 | #include "cairo-surface-backend-private.h" |
||
46 | #include "cairo-surface-fallback-private.h" |
||
47 | |||
48 | #include |
||
49 | |||
50 | #include |
||
51 | #include |
||
52 | #include |
||
53 | #include |
||
54 | #include |
||
55 | |||
56 | slim_hidden_proto(cairo_directfb_surface_create); |
||
57 | |||
58 | typedef struct _cairo_dfb_surface { |
||
59 | cairo_image_surface_t image; |
||
60 | |||
61 | IDirectFB *dfb; |
||
62 | IDirectFBSurface *dfb_surface; |
||
63 | |||
64 | unsigned blit_premultiplied : 1; |
||
65 | } cairo_dfb_surface_t; |
||
66 | |||
67 | static cairo_content_t |
||
68 | _directfb_format_to_content (DFBSurfacePixelFormat format) |
||
69 | { |
||
70 | cairo_content_t content = 0; |
||
71 | |||
72 | if (DFB_PIXELFORMAT_HAS_ALPHA (format)) |
||
73 | content |= CAIRO_CONTENT_ALPHA; |
||
74 | if (DFB_COLOR_BITS_PER_PIXEL (format)) |
||
75 | content |= CAIRO_CONTENT_COLOR_ALPHA; |
||
76 | |||
77 | assert(content); |
||
78 | return content; |
||
79 | } |
||
80 | |||
81 | static inline pixman_format_code_t |
||
82 | _directfb_to_pixman_format (DFBSurfacePixelFormat format) |
||
83 | { |
||
84 | switch (format) { |
||
85 | case DSPF_UNKNOWN: return 0; |
||
86 | case DSPF_ARGB1555: return PIXMAN_a1r5g5b5; |
||
87 | case DSPF_RGB16: return PIXMAN_r5g6b5; |
||
88 | case DSPF_RGB24: return PIXMAN_r8g8b8; |
||
89 | case DSPF_RGB32: return PIXMAN_x8r8g8b8; |
||
90 | case DSPF_ARGB: return PIXMAN_a8r8g8b8; |
||
91 | case DSPF_A8: return PIXMAN_a8; |
||
92 | case DSPF_YUY2: return PIXMAN_yuy2; |
||
93 | case DSPF_RGB332: return PIXMAN_r3g3b2; |
||
94 | case DSPF_UYVY: return 0; |
||
95 | case DSPF_I420: return 0; |
||
96 | case DSPF_YV12: return PIXMAN_yv12; |
||
97 | case DSPF_LUT8: return 0; |
||
98 | case DSPF_ALUT44: return 0; |
||
99 | case DSPF_AiRGB: return 0; |
||
100 | case DSPF_A1: return 0; /* bit reversed, oops */ |
||
101 | case DSPF_NV12: return 0; |
||
102 | case DSPF_NV16: return 0; |
||
103 | case DSPF_ARGB2554: return 0; |
||
104 | case DSPF_ARGB4444: return PIXMAN_a4r4g4b4; |
||
105 | case DSPF_NV21: return 0; |
||
106 | case DSPF_AYUV: return 0; |
||
107 | case DSPF_A4: return PIXMAN_a4; |
||
108 | case DSPF_ARGB1666: return 0; |
||
109 | case DSPF_ARGB6666: return 0; |
||
110 | case DSPF_RGB18: return 0; |
||
111 | case DSPF_LUT2: return 0; |
||
112 | case DSPF_RGB444: return PIXMAN_x4r4g4b4; |
||
113 | case DSPF_RGB555: return PIXMAN_x1r5g5b5; |
||
114 | #if DFB_NUM_PIXELFORMATS >= 29 |
||
115 | case DSPF_BGR555: return PIXMAN_x1b5g5r5; |
||
116 | #endif |
||
117 | } |
||
118 | return 0; |
||
119 | } |
||
120 | |||
121 | static cairo_surface_t * |
||
122 | _cairo_dfb_surface_create_similar (void *abstract_src, |
||
123 | cairo_content_t content, |
||
124 | int width, |
||
125 | int height) |
||
126 | { |
||
127 | cairo_dfb_surface_t *other = abstract_src; |
||
128 | DFBSurfacePixelFormat format; |
||
129 | IDirectFBSurface *buffer; |
||
130 | DFBSurfaceDescription dsc; |
||
131 | cairo_surface_t *surface; |
||
132 | |||
133 | if (width <= 0 || height <= 0) |
||
134 | return _cairo_image_surface_create_with_content (content, width, height); |
||
135 | |||
136 | switch (content) { |
||
137 | default: |
||
138 | ASSERT_NOT_REACHED; |
||
139 | case CAIRO_CONTENT_COLOR_ALPHA: |
||
140 | format = DSPF_ARGB; |
||
141 | break; |
||
142 | case CAIRO_CONTENT_COLOR: |
||
143 | format = DSPF_RGB32; |
||
144 | break; |
||
145 | case CAIRO_CONTENT_ALPHA: |
||
146 | format = DSPF_A8; |
||
147 | break; |
||
148 | } |
||
149 | |||
150 | dsc.flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT; |
||
151 | dsc.caps = DSCAPS_PREMULTIPLIED; |
||
152 | dsc.width = width; |
||
153 | dsc.height = height; |
||
154 | dsc.pixelformat = format; |
||
155 | |||
156 | if (other->dfb->CreateSurface (other->dfb, &dsc, &buffer)) |
||
157 | return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_DEVICE_ERROR)); |
||
158 | |||
159 | surface = cairo_directfb_surface_create (other->dfb, buffer); |
||
160 | buffer->Release (buffer); |
||
161 | |||
162 | return surface; |
||
163 | } |
||
164 | |||
165 | static cairo_status_t |
||
166 | _cairo_dfb_surface_finish (void *abstract_surface) |
||
167 | { |
||
168 | cairo_dfb_surface_t *surface = abstract_surface; |
||
169 | |||
170 | surface->dfb_surface->Release (surface->dfb_surface); |
||
171 | return _cairo_image_surface_finish (abstract_surface); |
||
172 | } |
||
173 | |||
174 | static cairo_image_surface_t * |
||
175 | _cairo_dfb_surface_map_to_image (void *abstract_surface, |
||
176 | const cairo_rectangle_int_t *extents) |
||
177 | { |
||
178 | cairo_dfb_surface_t *surface = abstract_surface; |
||
179 | |||
180 | if (surface->image.pixman_image == NULL) { |
||
181 | IDirectFBSurface *buffer = surface->dfb_surface; |
||
182 | pixman_image_t *image; |
||
183 | void *data; |
||
184 | int pitch; |
||
185 | |||
186 | if (buffer->Lock (buffer, DSLF_READ | DSLF_WRITE, &data, &pitch)) |
||
187 | return _cairo_image_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); |
||
188 | |||
189 | image = pixman_image_create_bits (surface->image.pixman_format, |
||
190 | surface->image.width, |
||
191 | surface->image.height, |
||
192 | data, pitch); |
||
193 | if (image == NULL) { |
||
194 | buffer->Unlock (buffer); |
||
195 | return _cairo_image_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); |
||
196 | } |
||
197 | _cairo_image_surface_init (&surface->image, image, surface->image.pixman_format); |
||
198 | } |
||
199 | |||
200 | return _cairo_image_surface_map_to_image (&surface->image.base, extents); |
||
201 | } |
||
202 | |||
203 | static cairo_int_status_t |
||
204 | _cairo_dfb_surface_unmap_image (void *abstract_surface, |
||
205 | cairo_image_surface_t *image) |
||
206 | { |
||
207 | cairo_dfb_surface_t *surface = abstract_surface; |
||
208 | return _cairo_image_surface_unmap_image (&surface->image.base, image); |
||
209 | } |
||
210 | |||
211 | static cairo_status_t |
||
212 | _cairo_dfb_surface_flush (void *abstract_surface, |
||
213 | unsigned flags) |
||
214 | { |
||
215 | cairo_dfb_surface_t *surface = abstract_surface; |
||
216 | |||
217 | if (flags) |
||
218 | return CAIRO_STATUS_SUCCESS; |
||
219 | |||
220 | if (surface->image.pixman_image) { |
||
221 | surface->dfb_surface->Unlock (surface->dfb_surface); |
||
222 | |||
223 | pixman_image_unref (surface->image.pixman_image); |
||
224 | surface->image.pixman_image = NULL; |
||
225 | surface->image.data = NULL; |
||
226 | } |
||
227 | |||
228 | return CAIRO_STATUS_SUCCESS; |
||
229 | } |
||
230 | |||
231 | #if 0 |
||
232 | static inline DFBSurfacePixelFormat |
||
233 | _directfb_from_pixman_format (pixman_format_code_t format) |
||
234 | { |
||
235 | switch ((int) format) { |
||
236 | case PIXMAN_a1r5g5b5: return DSPF_ARGB1555; |
||
237 | case PIXMAN_r5g6b5: return DSPF_RGB16; |
||
238 | case PIXMAN_r8g8b8: return DSPF_RGB24; |
||
239 | case PIXMAN_x8r8g8b8: return DSPF_RGB32; |
||
240 | case PIXMAN_a8r8g8b8: return DSPF_ARGB; |
||
241 | case PIXMAN_a8: return DSPF_A8; |
||
242 | case PIXMAN_yuy2: return DSPF_YUY2; |
||
243 | case PIXMAN_r3g3b2: return DSPF_RGB332; |
||
244 | case PIXMAN_yv12: return DSPF_YV12; |
||
245 | case PIXMAN_a1: return DSPF_A1; /* bit reversed, oops */ |
||
246 | case PIXMAN_a4r4g4b4: return DSPF_ARGB4444; |
||
247 | case PIXMAN_a4: return DSPF_A4; |
||
248 | case PIXMAN_x4r4g4b4: return DSPF_RGB444; |
||
249 | case PIXMAN_x1r5g5b5: return DSPF_RGB555; |
||
250 | #if DFB_NUM_PIXELFORMATS >= 29 |
||
251 | case PIXMAN_x1b5g5r5: return DSPF_BGR555; |
||
252 | #endif |
||
253 | default: return 0; |
||
254 | } |
||
255 | } |
||
256 | |||
257 | static cairo_bool_t |
||
258 | _directfb_get_operator (cairo_operator_t operator, |
||
259 | DFBSurfaceBlendFunction *ret_srcblend, |
||
260 | DFBSurfaceBlendFunction *ret_dstblend) |
||
261 | { |
||
262 | DFBSurfaceBlendFunction srcblend = DSBF_ONE; |
||
263 | DFBSurfaceBlendFunction dstblend = DSBF_ZERO; |
||
264 | |||
265 | switch (operator) { |
||
266 | case CAIRO_OPERATOR_CLEAR: |
||
267 | srcblend = DSBF_ZERO; |
||
268 | dstblend = DSBF_ZERO; |
||
269 | break; |
||
270 | case CAIRO_OPERATOR_SOURCE: |
||
271 | srcblend = DSBF_ONE; |
||
272 | dstblend = DSBF_ZERO; |
||
273 | break; |
||
274 | case CAIRO_OPERATOR_OVER: |
||
275 | srcblend = DSBF_ONE; |
||
276 | dstblend = DSBF_INVSRCALPHA; |
||
277 | break; |
||
278 | case CAIRO_OPERATOR_IN: |
||
279 | srcblend = DSBF_DESTALPHA; |
||
280 | dstblend = DSBF_ZERO; |
||
281 | break; |
||
282 | case CAIRO_OPERATOR_OUT: |
||
283 | srcblend = DSBF_INVDESTALPHA; |
||
284 | dstblend = DSBF_ZERO; |
||
285 | break; |
||
286 | case CAIRO_OPERATOR_ATOP: |
||
287 | srcblend = DSBF_DESTALPHA; |
||
288 | dstblend = DSBF_INVSRCALPHA; |
||
289 | break; |
||
290 | case CAIRO_OPERATOR_DEST: |
||
291 | srcblend = DSBF_ZERO; |
||
292 | dstblend = DSBF_ONE; |
||
293 | break; |
||
294 | case CAIRO_OPERATOR_DEST_OVER: |
||
295 | srcblend = DSBF_INVDESTALPHA; |
||
296 | dstblend = DSBF_ONE; |
||
297 | break; |
||
298 | case CAIRO_OPERATOR_DEST_IN: |
||
299 | srcblend = DSBF_ZERO; |
||
300 | dstblend = DSBF_SRCALPHA; |
||
301 | break; |
||
302 | case CAIRO_OPERATOR_DEST_OUT: |
||
303 | srcblend = DSBF_ZERO; |
||
304 | dstblend = DSBF_INVSRCALPHA; |
||
305 | break; |
||
306 | case CAIRO_OPERATOR_DEST_ATOP: |
||
307 | srcblend = DSBF_INVDESTALPHA; |
||
308 | dstblend = DSBF_SRCALPHA; |
||
309 | break; |
||
310 | case CAIRO_OPERATOR_XOR: |
||
311 | srcblend = DSBF_INVDESTALPHA; |
||
312 | dstblend = DSBF_INVSRCALPHA; |
||
313 | break; |
||
314 | case CAIRO_OPERATOR_ADD: |
||
315 | srcblend = DSBF_ONE; |
||
316 | dstblend = DSBF_ONE; |
||
317 | break; |
||
318 | case CAIRO_OPERATOR_SATURATE: |
||
319 | /* XXX This does not work. */ |
||
320 | #if 0 |
||
321 | srcblend = DSBF_SRCALPHASAT; |
||
322 | dstblend = DSBF_ONE; |
||
323 | break; |
||
324 | #endif |
||
325 | case CAIRO_OPERATOR_MULTIPLY: |
||
326 | case CAIRO_OPERATOR_SCREEN: |
||
327 | case CAIRO_OPERATOR_OVERLAY: |
||
328 | case CAIRO_OPERATOR_DARKEN: |
||
329 | case CAIRO_OPERATOR_LIGHTEN: |
||
330 | case CAIRO_OPERATOR_COLOR_DODGE: |
||
331 | case CAIRO_OPERATOR_COLOR_BURN: |
||
332 | case CAIRO_OPERATOR_HARD_LIGHT: |
||
333 | case CAIRO_OPERATOR_SOFT_LIGHT: |
||
334 | case CAIRO_OPERATOR_DIFFERENCE: |
||
335 | case CAIRO_OPERATOR_EXCLUSION: |
||
336 | case CAIRO_OPERATOR_HSL_HUE: |
||
337 | case CAIRO_OPERATOR_HSL_SATURATION: |
||
338 | case CAIRO_OPERATOR_HSL_COLOR: |
||
339 | case CAIRO_OPERATOR_HSL_LUMINOSITY: |
||
340 | default: |
||
341 | return FALSE; |
||
342 | } |
||
343 | |||
344 | *ret_srcblend = srcblend; |
||
345 | *ret_dstblend = dstblend; |
||
346 | |||
347 | return TRUE; |
||
348 | } |
||
349 | #define RUN_CLIPPED(surface, clip_region, clip, func) {\ |
||
350 | if ((clip_region) != NULL) {\ |
||
351 | int n_clips = cairo_region_num_rectangles (clip_region), n; \ |
||
352 | for (n = 0; n < n_clips; n++) {\ |
||
353 | if (clip) {\ |
||
354 | DFBRegion reg, *cli = (clip); \ |
||
355 | cairo_rectangle_int_t rect; \ |
||
356 | cairo_region_get_rectangle (clip_region, n, &rect); \ |
||
357 | reg.x1 = rect.x; \ |
||
358 | reg.y1 = rect.y; \ |
||
359 | reg.x2 = rect.x + rect.width - 1; \ |
||
360 | reg.y2 = rect.y + rect.height - 1; \ |
||
361 | if (reg.x2 < cli->x1 || reg.y2 < cli->y1 ||\ |
||
362 | reg.x1 > cli->x2 || reg.y1 > cli->y2)\ |
||
363 | continue;\ |
||
364 | if (reg.x1 < cli->x1)\ |
||
365 | reg.x1 = cli->x1;\ |
||
366 | if (reg.y1 < cli->y1)\ |
||
367 | reg.y1 = cli->y1;\ |
||
368 | if (reg.x2 > cli->x2)\ |
||
369 | reg.x2 = cli->x2;\ |
||
370 | if (reg.y2 > cli->y2)\ |
||
371 | reg.y2 = cli->y2;\ |
||
372 | (surface)->dfbsurface->SetClip ((surface)->dfbsurface, ®);\ |
||
373 | } else {\ |
||
374 | DFBRegion reg; \ |
||
375 | cairo_rectangle_int_t rect; \ |
||
376 | cairo_region_get_rectangle (clip_region, n, &rect); \ |
||
377 | reg.x1 = rect.x; \ |
||
378 | reg.y1 = rect.y; \ |
||
379 | reg.x2 = rect.x + rect.width - 1; \ |
||
380 | reg.y2 = rect.y + rect.height - 1; \ |
||
381 | (surface)->dfbsurface->SetClip ((surface)->dfbsurface, ®); \ |
||
382 | }\ |
||
383 | func;\ |
||
384 | }\ |
||
385 | } else {\ |
||
386 | (surface)->dfbsurface->SetClip ((surface)->dfbsurface, clip);\ |
||
387 | func;\ |
||
388 | }\ |
||
389 | } |
||
390 | |||
391 | static cairo_int_status_t |
||
392 | _cairo_dfb_surface_fill_rectangles (void *abstract_surface, |
||
393 | cairo_operator_t op, |
||
394 | const cairo_color_t *color, |
||
395 | cairo_rectangle_int_t *rects, |
||
396 | int n_rects) |
||
397 | { |
||
398 | cairo_dfb_surface_t *dst = abstract_surface; |
||
399 | DFBSurfaceDrawingFlags flags; |
||
400 | DFBSurfaceBlendFunction sblend; |
||
401 | DFBSurfaceBlendFunction dblend; |
||
402 | DFBRectangle r[n_rects]; |
||
403 | int i; |
||
404 | |||
405 | D_DEBUG_AT (CairoDFB_Render, |
||
406 | "%s( dst=%p, op=%d, color=%p, rects=%p, n_rects=%d ).\n", |
||
407 | __FUNCTION__, dst, op, color, rects, n_rects); |
||
408 | |||
409 | if (! dst->supported_destination) |
||
410 | return CAIRO_INT_STATUS_UNSUPPORTED; |
||
411 | |||
412 | if (! _directfb_get_operator (op, &sblend, &dblend)) |
||
413 | return CAIRO_INT_STATUS_UNSUPPORTED; |
||
414 | |||
415 | if (CAIRO_COLOR_IS_OPAQUE (color)) { |
||
416 | if (sblend == DSBF_SRCALPHA) |
||
417 | sblend = DSBF_ONE; |
||
418 | else if (sblend == DSBF_INVSRCALPHA) |
||
419 | sblend = DSBF_ZERO; |
||
420 | |||
421 | if (dblend == DSBF_SRCALPHA) |
||
422 | dblend = DSBF_ONE; |
||
423 | else if (dblend == DSBF_INVSRCALPHA) |
||
424 | dblend = DSBF_ZERO; |
||
425 | } |
||
426 | if ((dst->base.content & CAIRO_CONTENT_ALPHA) == 0) { |
||
427 | if (sblend == DSBF_DESTALPHA) |
||
428 | sblend = DSBF_ONE; |
||
429 | else if (sblend == DSBF_INVDESTALPHA) |
||
430 | sblend = DSBF_ZERO; |
||
431 | |||
432 | if (dblend == DSBF_DESTALPHA) |
||
433 | dblend = DSBF_ONE; |
||
434 | else if (dblend == DSBF_INVDESTALPHA) |
||
435 | dblend = DSBF_ZERO; |
||
436 | } |
||
437 | |||
438 | flags = (sblend == DSBF_ONE && dblend == DSBF_ZERO) ? DSDRAW_NOFX : DSDRAW_BLEND; |
||
439 | dst->dfbsurface->SetDrawingFlags (dst->dfbsurface, flags); |
||
440 | if (flags & DSDRAW_BLEND) { |
||
441 | dst->dfbsurface->SetSrcBlendFunction (dst->dfbsurface, sblend); |
||
442 | dst->dfbsurface->SetDstBlendFunction (dst->dfbsurface, dblend); |
||
443 | } |
||
444 | |||
445 | dst->dfbsurface->SetColor (dst->dfbsurface, |
||
446 | color->red_short >> 8, |
||
447 | color->green_short >> 8, |
||
448 | color->blue_short >> 8, |
||
449 | color->alpha_short >> 8); |
||
450 | |||
451 | for (i = 0; i < n_rects; i++) { |
||
452 | r[i].x = rects[i].x; |
||
453 | r[i].y = rects[i].y; |
||
454 | r[i].w = rects[i].width; |
||
455 | r[i].h = rects[i].height; |
||
456 | } |
||
457 | |||
458 | RUN_CLIPPED (dst, NULL, NULL, |
||
459 | dst->dfbsurface->FillRectangles (dst->dfbsurface, r, n_rects)); |
||
460 | |||
461 | return CAIRO_STATUS_SUCCESS; |
||
462 | } |
||
463 | #endif |
||
464 | |||
465 | static cairo_surface_backend_t |
||
466 | _cairo_dfb_surface_backend = { |
||
467 | CAIRO_SURFACE_TYPE_DIRECTFB, /*type*/ |
||
468 | _cairo_dfb_surface_finish, /*finish*/ |
||
469 | _cairo_default_context_create, |
||
470 | |||
471 | _cairo_dfb_surface_create_similar,/*create_similar*/ |
||
472 | NULL, /* create similar image */ |
||
473 | _cairo_dfb_surface_map_to_image, |
||
474 | _cairo_dfb_surface_unmap_image, |
||
475 | |||
476 | _cairo_surface_default_source, |
||
477 | _cairo_surface_default_acquire_source_image, |
||
478 | _cairo_surface_default_release_source_image, |
||
479 | NULL, |
||
480 | |||
481 | NULL, /* copy_page */ |
||
482 | NULL, /* show_page */ |
||
483 | |||
484 | _cairo_image_surface_get_extents, |
||
485 | _cairo_image_surface_get_font_options, |
||
486 | |||
487 | _cairo_dfb_surface_flush, |
||
488 | NULL, /* mark_dirty_rectangle */ |
||
489 | |||
490 | _cairo_surface_fallback_paint, |
||
491 | _cairo_surface_fallback_mask, |
||
492 | _cairo_surface_fallback_stroke, |
||
493 | _cairo_surface_fallback_fill, |
||
494 | NULL, /* fill-stroke */ |
||
495 | _cairo_surface_fallback_glyphs, |
||
496 | }; |
||
497 | |||
498 | cairo_surface_t * |
||
499 | cairo_directfb_surface_create (IDirectFB *dfb, IDirectFBSurface *dfbsurface) |
||
500 | { |
||
501 | cairo_dfb_surface_t *surface; |
||
502 | DFBSurfacePixelFormat format; |
||
503 | DFBSurfaceCapabilities caps; |
||
504 | pixman_format_code_t pixman_format; |
||
505 | int width, height; |
||
506 | |||
507 | D_ASSERT (dfb != NULL); |
||
508 | D_ASSERT (dfbsurface != NULL); |
||
509 | |||
510 | dfbsurface->GetPixelFormat (dfbsurface, &format); |
||
511 | dfbsurface->GetSize (dfbsurface, &width, &height); |
||
512 | |||
513 | pixman_format = _directfb_to_pixman_format (format); |
||
514 | if (! pixman_format_supported_destination (pixman_format)) |
||
515 | return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT)); |
||
516 | |||
517 | surface = calloc (1, sizeof (cairo_dfb_surface_t)); |
||
518 | if (surface == NULL) |
||
519 | return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); |
||
520 | |||
521 | /* XXX dfb -> device */ |
||
522 | _cairo_surface_init (&surface->image.base, |
||
523 | &_cairo_dfb_surface_backend, |
||
524 | NULL, /* device */ |
||
525 | _directfb_format_to_content (format)); |
||
526 | |||
527 | surface->image.pixman_format = pixman_format; |
||
528 | surface->image.format = _cairo_format_from_pixman_format (pixman_format); |
||
529 | |||
530 | surface->image.width = width; |
||
531 | surface->image.height = height; |
||
532 | surface->image.depth = PIXMAN_FORMAT_DEPTH(pixman_format); |
||
533 | |||
534 | surface->dfb = dfb; |
||
535 | surface->dfb_surface = dfbsurface; |
||
536 | dfbsurface->AddRef (dfbsurface); |
||
537 | |||
538 | dfbsurface->GetCapabilities (dfbsurface, &caps); |
||
539 | if (caps & DSCAPS_PREMULTIPLIED) |
||
540 | surface->blit_premultiplied = TRUE; |
||
541 | |||
542 | return &surface->image.base; |
||
543 | } |
||
544 | slim_hidden_def(cairo_directfb_surface_create);>>>>>>=>=> |