1 /* vim:set ts=8 sw=4 noet cin: */
2 /* cairo - a vector graphics library with display and print output
4 * Copyright © 2005 Christian Biesinger <cbiesinger@web.de>
6 * This library is free software; you can redistribute it and/or
7 * modify it either under the terms of the GNU Lesser General Public
8 * License version 2.1 as published by the Free Software Foundation
9 * (the "LGPL") or, at your option, under the terms of the Mozilla
10 * Public License Version 1.1 (the "MPL"). If you do not alter this
11 * notice, a recipient may use your version of this file under either
12 * the MPL or the LGPL.
14 * You should have received a copy of the LGPL along with this library
15 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
17 * You should have received a copy of the MPL along with this library
18 * in the file COPYING-MPL-1.1
20 * The contents of this file are subject to the Mozilla Public License
21 * Version 1.1 (the "License"); you may not use this file except in
22 * compliance with the License. You may obtain a copy of the License at
23 * http://www.mozilla.org/MPL/
25 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
26 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
27 * the specific language governing rights and limitations.
29 * The Original Code is the cairo graphics library.
31 * The Initial Developer of the Original Code is Christian Biesinger
37 // This is a C++ file in order to use the C++ BeOS API
41 #include "cairo-beos.h"
43 #include "cairo-error-private.h"
44 #include "cairo-image-surface-inline.h"
51 #include <DirectWindow.h>
58 * SECTION:beos-surface
59 * @Title: BeOS Surfaces
60 * @Short_Description: BeOS surface support
61 * @See_Also: #cairo_surface_t
63 * The BeOS surface is used to render cairo graphics to BeOS views
67 #define CAIRO_INT_STATUS_SUCCESS (cairo_int_status_t)(CAIRO_STATUS_SUCCESS)
69 struct cairo_beos_surface_t
{
72 cairo_region_t
*clip_region
;
77 * A view is either attached to a bitmap, a window, or unattached.
78 * If it is attached to a window, we can copy data out of it using BScreen.
79 * If it is attached to a bitmap, we can read the bitmap data.
80 * If it is not attached, it doesn't draw anything, we need not bother.
82 * Since there doesn't seem to be a way to get the bitmap from a view if it
83 * is attached to one, we have to use a special surface creation function.
88 // If true, surface and view should be deleted when this surface is
90 bool owns_bitmap_view
;
95 AutoLockView(BView
* view
) : mView(view
) {
96 mOK
= mView
->LockLooper();
101 mView
->UnlockLooper();
113 static cairo_surface_t
*
114 _cairo_beos_surface_create_internal (BView
* view
,
116 bool owns_bitmap_view
= false);
119 _cairo_rectangle_to_brect (const cairo_rectangle_int_t
* rect
)
121 // A BRect is one pixel wider than you'd think
122 return BRect (rect
->x
, rect
->y
,
123 rect
->x
+ rect
->width
- 1,
124 rect
->y
+ rect
->height
- 1);
127 static inline cairo_rectangle_int_t
128 _brect_to_cairo_rectangle (const BRect
&rect
)
130 cairo_rectangle_int_t retval
;
131 retval
.x
= floor (rect
.left
);
132 retval
.y
= floor (rect
.top
);
133 retval
.width
= ceil (rect
.right
) - retval
.x
+ 1;
134 retval
.height
= ceil (rect
.bottom
) - rectval
.y
+ 1;
138 static inline rgb_color
139 _cairo_color_to_be_color (const cairo_color_t
*color
)
141 // This factor ensures a uniform distribution of numbers
142 const float factor
= 256 - 1e-5;
143 // Using doubles to have non-premultiplied colors
144 rgb_color be_color
= { uint8(color
->red
* factor
),
145 uint8(color
->green
* factor
),
146 uint8(color
->blue
* factor
),
147 uint8(color
->alpha
* factor
) };
152 enum ViewCopyStatus
{
154 NOT_VISIBLE
, // The view or the interest rect is not visible on screen
155 ERROR
// The view was visible, but the rect could not be copied. Probably OOM
159 * _cairo_beos_view_to_bitmap:
160 * @bitmap: [out] The resulting bitmap.
161 * @rect: [out] The rectangle that was copied, in the view's coordinate system
162 * @interestRect: If non-null, only this part of the view will be copied (view's coord system).
164 * Gets the contents of the view as a BBitmap*. Caller must delete the bitmap.
166 static ViewCopyStatus
167 _cairo_beos_view_to_bitmap (BView
* view
,
170 const BRect
* interestRect
= NULL
)
174 BWindow
* wnd
= view
->Window();
175 // If we have no window, can't do anything
183 // Is it a direct window?
184 BDirectWindow
* directWnd
= dynamic_cast<BDirectWindow
*>(wnd
);
190 // Is it visible? If so, we can copy the content off the screen
194 BRect
rectToCopy(view
->Bounds());
196 rectToCopy
= rectToCopy
& *interestRect
;
198 if (!rectToCopy
.IsValid())
202 BRect
screenRect(view
->ConvertToScreen(rectToCopy
));
203 screenRect
= screenRect
& screen
.Frame();
205 if (!screen
.IsValid())
209 *rect
= view
->ConvertFromScreen(screenRect
);
211 if (screen
.GetBitmap(bitmap
, false, &screenRect
) == B_OK
)
218 unpremultiply_bgra (unsigned char* data
,
222 unsigned char* retdata
)
224 unsigned char* end
= data
+ stride
* height
;
225 for (unsigned char* in
= data
, *out
= retdata
;
227 in
+= stride
, out
+= stride
)
229 for (int i
= 0; i
< width
; i
++) {
230 uint8_t *b
= &out
[4*i
];
234 memcpy (&pixel
, &data
[4*i
], sizeof (uint32_t));
235 alpha
= pixel
& 0xff;
237 b
[0] = b
[1] = b
[2] = b
[3] = 0;
239 b
[0] = (((pixel
>> 24) & 0xff) * 255 + alpha
/ 2) / alpha
;
240 b
[1] = (((pixel
>> 16) & 0xff) * 255 + alpha
/ 2) / alpha
;
241 b
[2] = (((pixel
>> 8) & 0xff) * 255 + alpha
/ 2) / alpha
;
249 multiply_alpha (int alpha
, int color
)
251 int temp
= (alpha
* color
) + 0x80;
252 return ((temp
+ (temp
>> 8)) >> 8);
255 static unsigned char*
256 premultiply_bgra (unsigned char* data
,
261 uint8_t * retdata
= reinterpret_cast<unsigned char*>(_cairo_malloc_ab(height
, stride
));
265 uint8_t * end
= data
+ stride
* height
;
266 for (uint8_t * in
= data
, *out
= retdata
;
268 in
+= stride
, out
+= stride
)
270 for (int i
= 0; i
< width
; i
++) {
271 uint8_t *base
= &in
[4*i
];
272 uint8_t alpha
= base
[3];
278 uint8_t blue
= base
[0];
279 uint8_t green
= base
[1];
280 uint8_t red
= base
[2];
283 blue
= multiply_alpha (alpha
, blue
);
284 green
= multiply_alpha (alpha
, green
);
285 red
= multiply_alpha (alpha
, red
);
287 p
= (alpha
<< 0) | (red
<< 8) | (green
<< 16) | (blue
<< 24);
289 memcpy (&out
[4*i
], &p
, sizeof (uint32_t));
295 static cairo_int_status_t
296 _cairo_beos_surface_set_clip_region (cairo_beos_surface_t
*surface
,
297 cairo_region_t
*region
)
299 cairo_beos_surface_t
*surface
= reinterpret_cast<cairo_beos_surface_t
*>(
301 AutoLockView
locker(surface
->view
);
304 if (region
== surface
->clip_region
)
305 return CAIRO_INT_STATUS_SUCCESS
;
307 cairo_region_destroy (surface
->clip_region
);
308 surface
->clip_region
= cairo_region_reference (region
);
310 if (region
== NULL
) {
312 surface
->view
->ConstrainClippingRegion(NULL
);
313 return CAIRO_INT_STATUS_SUCCESS
;
316 int count
= cairo_region_num_rectangles (region
);
318 for (int i
= 0; i
< count
; ++i
) {
319 cairo_rectangle_int_t rect
;
321 cairo_region_get_rectangle (region
, i
, &rect
);
322 // Have to subtract one, because for pixman, the second coordinate
323 // lies outside the rectangle.
324 bregion
.Include (_cairo_rectangle_to_brect (&rect
));
326 surface
->view
->ConstrainClippingRegion(&bregion
);
327 return CAIRO_INT_STATUS_SUCCESS
;
332 * _cairo_beos_bitmap_to_surface:
334 * Returns an addrefed image surface for a BBitmap. The bitmap need not outlive
337 static cairo_image_surface_t
*
338 _cairo_beos_bitmap_to_surface (BBitmap
* bitmap
)
340 color_space format
= bitmap
->ColorSpace();
341 if (format
!= B_RGB32
&& format
!= B_RGBA32
) {
342 BBitmap
bmp(bitmap
->Bounds(), B_RGB32
, true);
343 BView
view(bitmap
->Bounds(), "Cairo bitmap drawing view",
344 B_FOLLOW_ALL_SIDES
, 0);
349 view
.DrawBitmap(bitmap
, BPoint(0.0, 0.0));
352 cairo_image_surface_t
* imgsurf
= _cairo_beos_bitmap_to_surface(&bmp
);
355 bmp
.RemoveChild(&view
);
359 cairo_format_t cformat
= format
== B_RGB32
?
360 CAIRO_FORMAT_RGB24
: CAIRO_FORMAT_ARGB32
;
362 BRect
bounds(bitmap
->Bounds());
363 unsigned char* bits
= reinterpret_cast<unsigned char*>(bitmap
->Bits());
364 int width
= bounds
.IntegerWidth() + 1;
365 int height
= bounds
.IntegerHeight() + 1;
366 unsigned char* premultiplied
;
367 if (cformat
== CAIRO_FORMAT_ARGB32
) {
368 premultiplied
= premultiply_bgra (bits
, width
, height
,
369 bitmap
->BytesPerRow());
371 premultiplied
= reinterpret_cast<unsigned char*>(
372 _cairo_malloc_ab(bitmap
->BytesPerRow(), height
));
374 memcpy(premultiplied
, bits
, bitmap
->BytesPerRow() * height
);
377 return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY
));
379 cairo_image_surface_t
* surf
= reinterpret_cast<cairo_image_surface_t
*>
380 (cairo_image_surface_create_for_data(premultiplied
,
384 bitmap
->BytesPerRow()));
385 if (surf
->base
.status
)
388 _cairo_image_surface_assume_ownership_of_data(surf
);
393 * _cairo_image_surface_to_bitmap:
395 * Converts an image surface to a BBitmap. The return value must be freed with
399 _cairo_image_surface_to_bitmap (cairo_image_surface_t
* surface
)
401 BRect
size(0.0, 0.0, surface
->width
- 1, surface
->height
- 1);
402 switch (surface
->format
) {
403 case CAIRO_FORMAT_ARGB32
: {
404 BBitmap
* data
= new BBitmap(size
, B_RGBA32
);
405 unpremultiply_bgra (surface
->data
,
409 reinterpret_cast<unsigned char*>(data
->Bits()));
412 case CAIRO_FORMAT_RGB24
: {
413 BBitmap
* data
= new BBitmap(size
, B_RGB32
);
414 memcpy(data
->Bits(), surface
->data
, surface
->height
* surface
->stride
);
424 * _cairo_op_to_be_op:
426 * Converts a cairo drawing operator to a beos drawing_mode. Returns true if
427 * the operator could be converted, false otherwise.
430 _cairo_op_to_be_op (cairo_operator_t cairo_op
,
431 drawing_mode
* beos_op
)
434 case CAIRO_OPERATOR_SOURCE
:
435 *beos_op
= B_OP_COPY
;
437 case CAIRO_OPERATOR_OVER
:
438 *beos_op
= B_OP_ALPHA
;
441 case CAIRO_OPERATOR_ADD
:
442 // Does not actually work
443 // XXX This is a fundamental compositing operator, it has to work!
451 case CAIRO_OPERATOR_CLEAR
:
452 // Does not map to B_OP_ERASE - it replaces the dest with the low
453 // color, instead of transparency; could be done by setting low
454 // color appropriately.
456 case CAIRO_OPERATOR_IN
:
457 case CAIRO_OPERATOR_OUT
:
458 case CAIRO_OPERATOR_ATOP
:
460 case CAIRO_OPERATOR_DEST
:
461 case CAIRO_OPERATOR_DEST_OVER
:
462 case CAIRO_OPERATOR_DEST_IN
:
463 case CAIRO_OPERATOR_DEST_OUT
:
464 case CAIRO_OPERATOR_DEST_ATOP
:
466 case CAIRO_OPERATOR_XOR
:
467 case CAIRO_OPERATOR_SATURATE
:
474 static cairo_surface_t
*
475 _cairo_beos_surface_create_similar (void *abstract_surface
,
476 cairo_content_t content
,
480 cairo_beos_surface_t
*surface
= reinterpret_cast<cairo_beos_surface_t
*>(
488 BRect
rect(0.0, 0.0, width
- 1, height
- 1);
491 case CAIRO_CONTENT_ALPHA
:
493 case CAIRO_CONTENT_COLOR_ALPHA
:
494 bmp
= new BBitmap(rect
, B_RGBA32
, true);
496 case CAIRO_CONTENT_COLOR
:
497 // Match the color depth
498 if (surface
->bitmap
) {
499 color_space space
= surface
->bitmap
->ColorSpace();
500 // No alpha was requested -> make sure not to return
501 // a surface with alpha
502 if (space
== B_RGBA32
)
504 if (space
== B_RGBA15
)
506 bmp
= new BBitmap(rect
, space
, true);
508 BScreen
scr(surface
->view
->Window());
509 color_space space
= B_RGB32
;
511 space
= scr
.ColorSpace();
512 bmp
= new BBitmap(rect
, space
, true);
519 BView
* view
= new BView(rect
, "Cairo bitmap view", B_FOLLOW_ALL_SIDES
, 0);
521 return _cairo_beos_surface_create_internal(view
, bmp
, true);
524 static cairo_status_t
525 _cairo_beos_surface_finish (void *abstract_surface
)
527 cairo_beos_surface_t
*surface
= reinterpret_cast<cairo_beos_surface_t
*>(
529 if (surface
->owns_bitmap_view
) {
531 surface
->bitmap
->RemoveChild(surface
->view
);
533 delete surface
->view
;
534 delete surface
->bitmap
;
536 surface
->view
= NULL
;
537 surface
->bitmap
= NULL
;
540 cairo_region_destroy (surface
->clip_region
);
542 return CAIRO_STATUS_SUCCESS
;
545 static cairo_status_t
546 _cairo_beos_surface_acquire_source_image (void *abstract_surface
,
547 cairo_image_surface_t
**image_out
,
550 cairo_beos_surface_t
*surface
= reinterpret_cast<cairo_beos_surface_t
*>(
552 AutoLockView
locker(surface
->view
);
554 return CAIRO_STATUS_NO_MEMORY
; /// XXX not exactly right, but what can we do?
557 surface
->view
->Sync();
559 if (surface
->bitmap
) {
560 *image_out
= _cairo_beos_bitmap_to_surface (surface
->bitmap
);
561 if (unlikely ((*image_out
)->base
.status
))
562 return (*image_out
)->base
.status
;
565 return CAIRO_STATUS_SUCCESS
;
569 if (_cairo_beos_view_to_bitmap(surface
->view
, &bmp
) != OK
)
570 return CAIRO_STATUS_NO_MEMORY
; /// XXX incorrect if the error was NOT_VISIBLE
572 *image_out
= _cairo_beos_bitmap_to_surface (bmp
);
573 if (unlikely ((*image_out
)->base
.status
)) {
575 return (*image_out
)->base
.status
;
579 return CAIRO_STATUS_SUCCESS
;
583 _cairo_beos_surface_release_source_image (void *abstract_surface
,
584 cairo_image_surface_t
*image
,
587 cairo_surface_destroy (&image
->base
);
589 if (image_extra
!= NULL
) {
590 BBitmap
* bmp
= static_cast<BBitmap
*>(image_extra
);
595 static cairo_status_t
596 _cairo_beos_surface_acquire_dest_image (void *abstract_surface
,
597 cairo_rectangle_int_t
*interest_rect
,
598 cairo_image_surface_t
**image_out
,
599 cairo_rectangle_int_t
*image_rect
,
602 cairo_beos_surface_t
*surface
= reinterpret_cast<cairo_beos_surface_t
*>(
605 AutoLockView
locker(surface
->view
);
609 return (cairo_status_t
) CAIRO_INT_STATUS_NOTHING_TO_DO
;
612 if (surface
->bitmap
) {
613 surface
->view
->Sync();
614 *image_out
= _cairo_beos_bitmap_to_surface(surface
->bitmap
);
615 if (unlikely ((*image_out
)->base
.status
))
616 return (*image_out
)->base
.status
;
620 image_rect
->width
= (*image_out
)->width
;
621 image_rect
->height
= (*image_out
)->height
;
624 return CAIRO_STATUS_SUCCESS
;
627 BRect
b_interest_rect (_cairo_rectangle_to_brect (interest_rect
));
631 ViewCopyStatus status
= _cairo_beos_view_to_bitmap(surface
->view
, &bitmap
,
632 &rect
, &b_interest_rect
);
633 if (status
== NOT_VISIBLE
) {
636 return CAIRO_STATUS_SUCCESS
;
639 return CAIRO_STATUS_NO_MEMORY
;
641 *image_rect
= _brect_to_cairo_rectangle(rect
);
642 *image_out
= _cairo_beos_bitmap_to_surface(bitmap
);
644 if (unlikely ((*image_out
)->base
.status
))
645 return (*image_out
)->base
.status
;
649 return CAIRO_STATUS_SUCCESS
;
654 _cairo_beos_surface_release_dest_image (void *abstract_surface
,
655 cairo_rectangle_int_t
*intersect_rect
,
656 cairo_image_surface_t
*image
,
657 cairo_rectangle_int_t
*image_rect
,
660 cairo_beos_surface_t
*surface
= reinterpret_cast<cairo_beos_surface_t
*>(
663 AutoLockView
locker(surface
->view
);
667 BBitmap
* bitmap_to_draw
= _cairo_image_surface_to_bitmap(image
);
668 surface
->view
->PushState();
670 surface
->view
->SetDrawingMode(B_OP_COPY
);
672 surface
->view
->DrawBitmap (bitmap_to_draw
,
673 _cairo_rectangle_to_brect (image_rect
));
675 surface
->view
->PopState();
677 delete bitmap_to_draw
;
678 cairo_surface_destroy(&image
->base
);
681 static cairo_int_status_t
682 _cairo_beos_surface_composite (cairo_operator_t op
,
683 cairo_pattern_t
*src
,
684 cairo_pattern_t
*mask
,
694 cairo_region_t
*clip_region
)
696 cairo_beos_surface_t
*surface
= reinterpret_cast<cairo_beos_surface_t
*>(
698 cairo_int_status_t status
;
699 AutoLockView
locker(surface
->view
);
701 return CAIRO_INT_STATUS_SUCCESS
;
704 if (!_cairo_op_to_be_op(op
, &mode
))
705 return CAIRO_INT_STATUS_UNSUPPORTED
;
707 // XXX Masks are not yet supported
709 return CAIRO_INT_STATUS_UNSUPPORTED
;
711 // XXX should eventually support the others
712 if (src
->type
!= CAIRO_PATTERN_TYPE_SURFACE
||
713 src
->extend
!= CAIRO_EXTEND_NONE
)
715 return CAIRO_INT_STATUS_UNSUPPORTED
;
718 // Can we maybe support other matrices as well? (scale? if the filter is right)
720 if (!_cairo_matrix_is_integer_translation(&src
->matrix
, &itx
, &ity
))
721 return CAIRO_INT_STATUS_UNSUPPORTED
;
723 status
= _cairo_beos_surface_set_clip_region (surface
, clip_region
);
724 if (unlikely (status
))
727 BRect
srcRect(src_x
+ itx
,
729 src_x
+ itx
+ width
- 1,
730 src_y
+ ity
+ height
- 1);
731 BRect
dstRect(dst_x
, dst_y
, dst_x
+ width
- 1, dst_y
+ height
- 1);
733 cairo_surface_t
* src_surface
= reinterpret_cast<cairo_surface_pattern_t
*>(src
)->
738 bool free_bmp
= false;
739 if (_cairo_surface_is_image(src_surface
)) {
740 cairo_image_surface_t
* img_surface
=
741 reinterpret_cast<cairo_image_surface_t
*>(src_surface
);
743 bmp
= _cairo_image_surface_to_bitmap(img_surface
);
745 } else if (src_surface
->backend
== surface
->base
.backend
) {
746 cairo_beos_surface_t
*beos_surface
=
747 reinterpret_cast<cairo_beos_surface_t
*>(src_surface
);
748 if (beos_surface
->bitmap
) {
749 AutoLockView
locker(beos_surface
->view
);
751 beos_surface
->view
->Sync();
752 bmp
= beos_surface
->bitmap
;
754 _cairo_beos_view_to_bitmap(surface
->view
, &bmp
);
760 return CAIRO_INT_STATUS_UNSUPPORTED
;
762 // So, BeOS seems to screw up painting an opaque bitmap onto a
763 // translucent one (it makes them partly transparent). Just return
765 if (bmp
->ColorSpace() == B_RGB32
&& surface
->bitmap
&&
766 surface
->bitmap
->ColorSpace() == B_RGBA32
&&
767 (mode
== B_OP_COPY
|| mode
== B_OP_ALPHA
))
771 return CAIRO_INT_STATUS_UNSUPPORTED
;
774 // Draw it on screen.
775 surface
->view
->PushState();
777 // If our image rect is only a subrect of the desired size, and we
778 // aren't using B_OP_ALPHA, then we need to fill the rect first.
779 if (mode
== B_OP_COPY
&& !bmp
->Bounds().Contains(srcRect
)) {
780 rgb_color black
= { 0, 0, 0, 0 };
782 surface
->view
->SetDrawingMode(mode
);
783 surface
->view
->SetHighColor(black
);
784 surface
->view
->FillRect(dstRect
);
787 if (mode
== B_OP_ALPHA
&& bmp
->ColorSpace() == B_RGB32
) {
790 surface
->view
->SetDrawingMode(mode
);
792 if (surface
->bitmap
&& surface
->bitmap
->ColorSpace() == B_RGBA32
)
793 surface
->view
->SetBlendingMode(B_PIXEL_ALPHA
, B_ALPHA_COMPOSITE
);
795 surface
->view
->SetBlendingMode(B_PIXEL_ALPHA
, B_ALPHA_OVERLAY
);
797 surface
->view
->DrawBitmap(bmp
, srcRect
, dstRect
);
799 surface
->view
->PopState();
804 return CAIRO_INT_STATUS_SUCCESS
;
808 static cairo_int_status_t
809 _cairo_beos_surface_fill_rectangles (void *abstract_surface
,
811 const cairo_color_t
*color
,
812 cairo_rectangle_int_t
*rects
,
814 cairo_region_t
*clip_region
)
816 cairo_beos_surface_t
*surface
= reinterpret_cast<cairo_beos_surface_t
*>(
818 cairo_int_status_t status
;
821 return CAIRO_INT_STATUS_SUCCESS
;
823 AutoLockView
locker(surface
->view
);
825 return CAIRO_INT_STATUS_SUCCESS
;
828 if (!_cairo_op_to_be_op(op
, &mode
))
829 return CAIRO_INT_STATUS_UNSUPPORTED
;
831 status
= _cairo_beos_surface_set_clip_region (surface
, clip_region
);
832 if (unlikely (status
))
835 rgb_color be_color
= _cairo_color_to_be_color(color
);
837 if (mode
== B_OP_ALPHA
&& be_color
.alpha
== 0xFF)
840 // For CAIRO_OPERATOR_SOURCE, cairo expects us to use the premultiplied
841 // color info. This is only relevant when drawing into an rgb24 buffer
842 // (as for others, we can convert when asked for the image)
843 if (mode
== B_OP_COPY
&& be_color
.alpha
!= 0xFF &&
844 (!surface
->bitmap
|| surface
->bitmap
->ColorSpace() != B_RGBA32
))
846 be_color
.red
= color
->red_short
>> 8;
847 be_color
.green
= color
->green_short
>> 8;
848 be_color
.blue
= color
->blue_short
>> 8;
851 surface
->view
->PushState();
853 surface
->view
->SetDrawingMode(mode
);
854 surface
->view
->SetHighColor(be_color
);
855 if (surface
->bitmap
&& surface
->bitmap
->ColorSpace() == B_RGBA32
)
856 surface
->view
->SetBlendingMode(B_CONSTANT_ALPHA
, B_ALPHA_COMPOSITE
);
858 surface
->view
->SetBlendingMode(B_CONSTANT_ALPHA
, B_ALPHA_OVERLAY
);
860 for (int i
= 0; i
< num_rects
; ++i
)
861 surface
->view
->FillRect (_cairo_rectangle_to_brect (&rects
[i
]));
863 surface
->view
->PopState();
865 return CAIRO_INT_STATUS_SUCCESS
;
869 _cairo_beos_surface_get_extents (void *abstract_surface
,
870 cairo_rectangle_int_t
*rectangle
)
872 cairo_beos_surface_t
*surface
= reinterpret_cast<cairo_beos_surface_t
*>(
874 AutoLockView
locker(surface
->view
);
878 *rectangle
= _brect_to_cairo_rectangle (surface
->view
->Bounds());
882 static const struct _cairo_surface_backend cairo_beos_surface_backend
= {
883 CAIRO_SURFACE_TYPE_BEOS
,
884 _cairo_beos_surface_create_similar
,
885 _cairo_beos_surface_finish
,
886 _cairo_beos_surface_acquire_source_image
,
887 _cairo_beos_surface_release_source_image
,
888 _cairo_beos_surface_acquire_dest_image
,
889 _cairo_beos_surface_release_dest_image
,
890 NULL
, /* clone_similar */
891 _cairo_beos_surface_composite
, /* composite */
892 _cairo_beos_surface_fill_rectangles
,
893 NULL
, /* composite_trapezoids */
894 NULL
, /* create_span_renderer */
895 NULL
, /* check_span_renderer */
896 NULL
, /* copy_page */
897 NULL
, /* show_page */
898 _cairo_beos_surface_get_extents
,
899 NULL
, /* old_show_glyphs */
900 NULL
, /* get_font_options */
902 NULL
, /* mark_dirty_rectangle */
903 NULL
, /* scaled_font_fini */
904 NULL
, /* scaled_glyph_fini */
910 NULL
/* show_glyphs */
913 static cairo_surface_t
*
914 _cairo_beos_surface_create_internal (BView
* view
,
916 bool owns_bitmap_view
)
918 // Must use malloc, because cairo code will use free() on the surface
919 cairo_beos_surface_t
*surface
= static_cast<cairo_beos_surface_t
*>(
920 malloc(sizeof(cairo_beos_surface_t
)));
921 if (surface
== NULL
) {
922 _cairo_error (CAIRO_STATUS_NO_MEMORY
);
923 return const_cast<cairo_surface_t
*>(&_cairo_surface_nil
);
926 cairo_content_t content
= CAIRO_CONTENT_COLOR
;
927 if (bmp
&& (bmp
->ColorSpace() == B_RGBA32
|| bmp
->ColorSpace() == B_RGBA15
))
928 content
= CAIRO_CONTENT_COLOR_ALPHA
;
929 _cairo_surface_init (&surface
->base
,
930 &cairo_beos_surface_backend
,
934 surface
->view
= view
;
935 surface
->bitmap
= bmp
;
936 surface
->owns_bitmap_view
= owns_bitmap_view
;
938 surface
->clip_region
= NULL
;
940 return &surface
->base
;
944 * cairo_beos_surface_create:
945 * @view: The view to draw on
947 * Creates a Cairo surface that draws onto a BeOS BView.
948 * The caller must ensure that the view does not get deleted before the surface.
949 * If the view is attached to a bitmap rather than an on-screen window, use
950 * cairo_beos_surface_create_for_bitmap() instead of this function.
955 cairo_beos_surface_create (BView
* view
)
957 return cairo_beos_surface_create_for_bitmap(view
, NULL
);
961 * cairo_beos_surface_create_for_bitmap:
962 * @view: The view to draw on
963 * @bmp: The bitmap to which the view is attached
965 * Creates a Cairo surface that draws onto a BeOS BView which is attached to a
967 * The caller must ensure that the view and the bitmap do not get deleted
968 * before the surface.
970 * For views that draw to a bitmap (as opposed to a screen), use this function
971 * rather than cairo_beos_surface_create(). Not using this function WILL lead to
972 * incorrect behaviour.
974 * For now, only views that draw to the entire area of bmp are supported.
975 * The view must already be attached to the bitmap.
980 cairo_beos_surface_create_for_bitmap (BView
* view
,
983 return _cairo_beos_surface_create_internal(view
, bmp
);