static cairo_int_status_t _cairo_beos_surface_fill_rectangles (void *abstract_surface, cairo_operator_t op, const cairo_color_t *color, cairo_rectangle_int16_t *rects, int num_rects) { fprintf(stderr, "Drawing %i rectangles\n", num_rects); cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>( abstract_surface); if (num_rects <= 0) return CAIRO_INT_STATUS_SUCCESS; AutoLockView locker(surface->view); if (!locker) return CAIRO_INT_STATUS_SUCCESS; drawing_mode mode; if (!_cairo_op_to_be_op(op, &mode)) return CAIRO_INT_STATUS_UNSUPPORTED; rgb_color be_color = _cairo_color_to_be_color(color); if (mode == B_OP_ALPHA && be_color.alpha == 0xFF) mode = B_OP_COPY; // For CAIRO_OPERATOR_SOURCE, cairo expects us to use the premultiplied // color info. This is only relevant when drawing into an rgb24 buffer // (as for others, we can convert when asked for the image) if (mode == B_OP_COPY && be_color.alpha != 0xFF && (!surface->bitmap || surface->bitmap->ColorSpace() != B_RGBA32)) { be_color.red = premultiply(be_color.red, be_color.alpha); be_color.green = premultiply(be_color.green, be_color.alpha); be_color.blue = premultiply(be_color.blue, be_color.alpha); } surface->view->PushState(); surface->view->SetDrawingMode(mode); surface->view->SetHighColor(be_color); if (surface->bitmap && surface->bitmap->ColorSpace() == B_RGBA32) surface->view->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_COMPOSITE); else surface->view->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_OVERLAY); for (int i = 0; i < num_rects; ++i) { _cairo_beos_surface_fill_rectangle(surface, &rects[i]); } surface->view->PopState(); return CAIRO_INT_STATUS_SUCCESS; }
static cairo_int_status_t _cairo_beos_surface_composite (cairo_operator_t op, cairo_pattern_t *src, cairo_pattern_t *mask, void *dst, int src_x, int src_y, int mask_x, int mask_y, int dst_x, int dst_y, unsigned int width, unsigned int height) { cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>( dst); AutoLockView locker(surface->view); if (!locker) return CAIRO_INT_STATUS_SUCCESS; drawing_mode mode; if (!_cairo_op_to_be_op(op, &mode)) return CAIRO_INT_STATUS_UNSUPPORTED; // XXX Masks are not yet supported if (mask) return CAIRO_INT_STATUS_UNSUPPORTED; // XXX should eventually support the others if (src->type != CAIRO_PATTERN_TYPE_SURFACE || src->extend != CAIRO_EXTEND_NONE) { return CAIRO_INT_STATUS_UNSUPPORTED; } // Can we maybe support other matrices as well? (scale? if the filter is right) int itx, ity; if (!_cairo_matrix_is_integer_translation(&src->matrix, &itx, &ity)) return CAIRO_INT_STATUS_UNSUPPORTED; BRect srcRect(src_x + itx, src_y + ity, src_x + itx + width - 1, src_y + ity + height - 1); BRect dstRect(dst_x, dst_y, dst_x + width - 1, dst_y + height - 1); cairo_surface_t* src_surface = reinterpret_cast<cairo_surface_pattern_t*>(src)-> surface; // Get a bitmap BBitmap* bmp = NULL; bool free_bmp = false; if (_cairo_surface_is_image(src_surface)) { cairo_image_surface_t* img_surface = reinterpret_cast<cairo_image_surface_t*>(src_surface); bmp = _cairo_image_surface_to_bitmap(img_surface); free_bmp = true; } else if (src_surface->backend == surface->base.backend) { cairo_beos_surface_t *beos_surface = reinterpret_cast<cairo_beos_surface_t*>(src_surface); if (beos_surface->bitmap) { AutoLockView locker(beos_surface->view); if (locker) beos_surface->view->Sync(); bmp = beos_surface->bitmap; } else { _cairo_beos_view_to_bitmap(surface->view, &bmp); free_bmp = true; } } if (!bmp) return CAIRO_INT_STATUS_UNSUPPORTED; // So, BeOS seems to screw up painting an opaque bitmap onto a // translucent one (it makes them partly transparent). Just return // unsupported. if (bmp->ColorSpace() == B_RGB32 && surface->bitmap && surface->bitmap->ColorSpace() == B_RGBA32 && (mode == B_OP_COPY || mode == B_OP_ALPHA)) { if (free_bmp) delete bmp; return CAIRO_INT_STATUS_UNSUPPORTED; } fprintf(stderr, "Composite\n"); // Draw it on screen. surface->view->PushState(); // If our image rect is only a subrect of the desired size, and we // aren't using B_OP_ALPHA, then we need to fill the rect first. if (mode == B_OP_COPY && !bmp->Bounds().Contains(srcRect)) { rgb_color black = { 0, 0, 0, 0 }; surface->view->SetDrawingMode(mode); surface->view->SetHighColor(black); surface->view->FillRect(dstRect); } if (mode == B_OP_ALPHA && bmp->ColorSpace() == B_RGB32) { mode = B_OP_COPY; } surface->view->SetDrawingMode(mode); if (surface->bitmap && surface->bitmap->ColorSpace() == B_RGBA32) surface->view->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_COMPOSITE); else surface->view->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY); surface->view->DrawBitmap(bmp, srcRect, dstRect); surface->view->PopState(); if (free_bmp) delete bmp; return CAIRO_INT_STATUS_SUCCESS; }
static cairo_int_status_t _cairo_beos_composite (cairo_operator_t op, cairo_pattern_t *src, cairo_pattern_t *mask, void *dst, int src_x, int src_y, int mask_x, int mask_y, int dst_x, int dst_y, unsigned int width, unsigned int height) { cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>( dst); AutoLockView locker(surface->view); if (!locker) return CAIRO_INT_STATUS_SUCCESS; drawing_mode mode; if (!_cairo_op_to_be_op(op, &mode)) return CAIRO_INT_STATUS_UNSUPPORTED; // XXX Masks are not yet supported if (mask) return CAIRO_INT_STATUS_UNSUPPORTED; // XXX should eventually support the others if (src->type != CAIRO_PATTERN_SURFACE || src->extend != CAIRO_EXTEND_NONE) { return CAIRO_INT_STATUS_UNSUPPORTED; } // Can we maybe support other matrices as well? (scale? if the filter is right) int itx, ity; if (!_cairo_matrix_is_integer_translation(&src->matrix, &itx, &ity)) return CAIRO_INT_STATUS_UNSUPPORTED; BRect srcRect(src_x + itx, src_y + ity, src_x + itx + width - 1, src_y + ity + height - 1); BRect dstRect(dst_x, dst_y, dst_x + width - 1, dst_y + height - 1); cairo_surface_t* src_surface = reinterpret_cast<cairo_surface_pattern_t*>(src)-> surface; if (_cairo_surface_is_image(src_surface)) { fprintf(stderr, "Composite\n"); // Draw it on screen. cairo_image_surface_t* img_surface = reinterpret_cast<cairo_image_surface_t*>(src_surface); BBitmap* bmp = _cairo_image_surface_to_bitmap(img_surface); surface->view->PushState(); // If our image rect is only a subrect of the desired size, and we // aren't using B_OP_ALPHA, then we need to fill the rect first. if (mode == B_OP_COPY && !bmp->Bounds().Contains(srcRect)) { rgb_color black = { 0, 0, 0, 0 }; surface->view->SetDrawingMode(mode); surface->view->SetHighColor(black); surface->view->FillRect(dstRect); } if (mode == B_OP_ALPHA && img_surface->format != CAIRO_FORMAT_ARGB32) { mode = B_OP_COPY; } surface->view->SetDrawingMode(mode); if (surface->bitmap && surface->bitmap->ColorSpace() == B_RGBA32) surface->view->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_COMPOSITE); else surface->view->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY); surface->view->DrawBitmap(bmp, srcRect, dstRect); surface->view->PopState(); delete bmp; return CAIRO_INT_STATUS_SUCCESS; } return CAIRO_INT_STATUS_UNSUPPORTED; }