📄 cairo-beos-surface.cpp
字号:
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>( abstract_surface); AutoLockView locker(surface->view); if (!locker) return CAIRO_STATUS_NO_MEMORY; /// XXX not exactly right, but what can we do? surface->view->Sync(); if (surface->bitmap) { *image_out = _cairo_beos_bitmap_to_surface(surface->bitmap); if (!*image_out) return CAIRO_STATUS_NO_MEMORY; *image_extra = NULL; return CAIRO_STATUS_SUCCESS; } BBitmap* bmp; if (_cairo_beos_view_to_bitmap(surface->view, &bmp) != OK) return CAIRO_STATUS_NO_MEMORY; /// XXX incorrect if the error was NOT_VISIBLE *image_out = _cairo_beos_bitmap_to_surface(bmp); if (!*image_out) { delete bmp; return CAIRO_STATUS_NO_MEMORY; } *image_extra = bmp; return CAIRO_STATUS_SUCCESS;}static void_cairo_beos_surface_release_source_image (void *abstract_surface, cairo_image_surface_t *image, void *image_extra){ cairo_surface_destroy (&image->base); BBitmap* bmp = static_cast<BBitmap*>(image_extra); delete bmp;}static cairo_status_t_cairo_beos_surface_acquire_dest_image (void *abstract_surface, cairo_rectangle_fixed_t *interest_rect, cairo_image_surface_t **image_out, cairo_rectangle_fixed_t *image_rect, void **image_extra){ cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>( abstract_surface); AutoLockView locker(surface->view); if (!locker) { *image_out = NULL; *image_extra = NULL; return CAIRO_STATUS_SUCCESS; } if (surface->bitmap) { surface->view->Sync(); *image_out = _cairo_beos_bitmap_to_surface(surface->bitmap); if (!*image_out) return CAIRO_STATUS_NO_MEMORY; image_rect->x = 0; image_rect->y = 0; image_rect->width = (*image_out)->width; image_rect->height = (*image_out)->height; *image_extra = NULL; return CAIRO_STATUS_SUCCESS; } BRect b_interest_rect(_cairo_rect_to_brect(interest_rect)); BRect rect; BBitmap* bitmap; ViewCopyStatus status = _cairo_beos_view_to_bitmap(surface->view, &bitmap, &rect, &b_interest_rect); if (status == NOT_VISIBLE) { *image_out = NULL; *image_extra = NULL; return CAIRO_STATUS_SUCCESS; } if (status == ERROR) return CAIRO_STATUS_NO_MEMORY; *image_rect = _brect_to_cairo_rect(rect);#if 0 fprintf(stderr, "Requested: (cairo rects) (%ix%i) dim (%u, %u) returning (%ix%i) dim (%u, %u)\n", interest_rect->x, interest_rect->y, interest_rect->width, interest_rect->height, image_rect->x, image_rect->y, image_rect->width, image_rect->height);#endif *image_out = _cairo_beos_bitmap_to_surface(bitmap); delete bitmap; if (!*image_out) return CAIRO_STATUS_NO_MEMORY; *image_extra = NULL; return CAIRO_STATUS_SUCCESS;}static void_cairo_beos_surface_release_dest_image (void *abstract_surface, cairo_rectangle_fixed_t *intersect_rect, cairo_image_surface_t *image, cairo_rectangle_fixed_t *image_rect, void *image_extra){ fprintf(stderr, "Fallback drawing\n"); cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>( abstract_surface); AutoLockView locker(surface->view); if (!locker) return; BBitmap* bitmap_to_draw = _cairo_image_surface_to_bitmap(image); surface->view->PushState(); surface->view->SetDrawingMode(B_OP_COPY); BRect rect(_cairo_rect_to_brect(image_rect)); surface->view->DrawBitmap(bitmap_to_draw, rect); surface->view->PopState(); delete bitmap_to_draw; cairo_surface_destroy(&image->base);}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 void_cairo_beos_surface_fill_rectangle (cairo_beos_surface_t *surface, cairo_rectangle_fixed_t *rect){ BRect brect(_cairo_rect_to_brect(rect)); surface->view->FillRect(brect);}static cairo_int_status_t_cairo_beos_surface_fill_rectangles (void *abstract_surface, cairo_operator_t op, const cairo_color_t *color, cairo_rectangle_fixed_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_set_clip_region (void *abstract_surface, pixman_region16_t *region){ fprintf(stderr, "Setting clip region\n"); cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>( abstract_surface); AutoLockView locker(surface->view); if (!locker) return CAIRO_INT_STATUS_SUCCESS; if (region == NULL) { // No clipping surface->view->ConstrainClippingRegion(NULL); return CAIRO_INT_STATUS_SUCCESS; } int count = pixman_region_num_rects(region); pixman_box16_t* rects = pixman_region_rects(region); BRegion bregion; for (int i = 0; i < count; ++i) { // Have to substract one, because for pixman, the second coordinate // lies outside the rectangle. bregion.Include(BRect(rects[i].x1, rects[i].y1, rects[i].x2 - 1, rects[i].y2 - 1)); } surface->view->ConstrainClippingRegion(&bregion); return CAIRO_INT_STATUS_SUCCESS;}static cairo_int_status_t_cairo_beos_surface_get_extents (void *abstract_surface, cairo_rectangle_fixed_t *rectangle){ cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>( abstract_surface); AutoLockView locker(surface->view); if (!locker) return CAIRO_INT_STATUS_UNSUPPORTED; BRect size = surface->view->Bounds(); *rectangle = _brect_to_cairo_rect(size); // Make sure to have our upperleft edge as (0,0) rectangle->x = 0; rectangle->y = 0; return CAIRO_INT_STATUS_SUCCESS;}static const struct _cairo_surface_backend cairo_beos_surface_backend = { CAIRO_SURFACE_TYPE_BEOS, _cairo_beos_surface_create_similar, _cairo_beos_surface_finish, _cairo_beos_surface_acquire_source_image, _cairo_beos_surface_release_source_image, _cairo_beos_surface_acquire_dest_image, _cairo_beos_surface_release_dest_image, NULL, /* clone_similar */ _cairo_beos_surface_composite, /* composite */ _cairo_beos_surface_fill_rectangles, NULL, /* composite_trapezoids */ NULL, /* copy_page */ NULL, /* show_page */ _cairo_beos_surface_set_clip_region, NULL, /* intersect_clip_path */ _cairo_beos_surface_get_extents, NULL, /* old_show_glyphs */ NULL, /* get_font_options */ NULL, /* flush */ NULL, /* mark_dirty_rectangle */ NULL, /* scaled_font_fini */ NULL, /* scaled_glyph_fini */ NULL, /* paint */ NULL, /* mask */ NULL, /* stroke */ NULL, /* fill */ NULL /* show_glyphs */};static cairo_surface_t *_cairo_beos_surface_create_internal (BView* view, BBitmap* bmp, bool owns_bitmap_view){ // Must use malloc, because cairo code will use free() on the surface cairo_beos_surface_t *surface = static_cast<cairo_beos_surface_t*>( malloc(sizeof(cairo_beos_surface_t))); if (surface == NULL) { _cairo_error (CAIRO_STATUS_NO_MEMORY); return const_cast<cairo_surface_t*>(&_cairo_surface_nil); } cairo_content_t content = CAIRO_CONTENT_COLOR; if (bmp && (bmp->ColorSpace() == B_RGBA32 || bmp->ColorSpace() == B_RGBA15)) content = CAIRO_CONTENT_COLOR_ALPHA; _cairo_surface_init(&surface->base, &cairo_beos_surface_backend, content); surface->view = view; surface->bitmap = bmp; surface->owns_bitmap_view = owns_bitmap_view; return (cairo_surface_t *) surface;}/** * cairo_beos_surface_create: * @view: The view to draw on * * Creates a Cairo surface that draws onto a BeOS BView. * The caller must ensure that the view does not get deleted before the surface. * If the view is attached to a bitmap rather than an on-screen window, use * cairo_beos_surface_create_for_bitmap instead of this function. **/cairo_surface_t *cairo_beos_surface_create (BView* view){ return cairo_beos_surface_create_for_bitmap(view, NULL);}/** * cairo_beos_surface_create_for_bitmap: * @view: The view to draw on * @bmp: The bitmap to which the view is attached * * Creates a Cairo surface that draws onto a BeOS BView which is attached to a * BBitmap. * The caller must ensure that the view and the bitmap do not get deleted * before the surface. * * For views that draw to a bitmap (as opposed to a screen), use this function * rather than cairo_beos_surface_create. Not using this function WILL lead to * incorrect behaviour. * * For now, only views that draw to the entire area of bmp are supported. * The view must already be attached to the bitmap. **/cairo_surface_t *cairo_beos_surface_create_for_bitmap (BView* view, BBitmap* bmp){ return _cairo_beos_surface_create_internal(view, bmp);}// ---------------------------------------------------------------------------// Cairo uses locks without explicit initialization. To support that, we// provide a class here which manages the locks and is in global scope, so the// compiler will instantiate it on library load and destroy it on library// unload.class BeLocks { public: BLocker cairo_toy_font_face_hash_table_mutex; BLocker cairo_scaled_font_map_mutex; BLocker cairo_ft_unscaled_font_map_mutex;};static BeLocks locks;void* cairo_toy_font_face_hash_table_mutex = &locks.cairo_toy_font_face_hash_table_mutex;void* cairo_scaled_font_map_mutex = &locks.cairo_scaled_font_map_mutex;void* cairo_ft_unscaled_font_map_mutex = &locks.cairo_ft_unscaled_font_map_mutex;void _cairo_beos_lock (void* locker) { BLocker* bLocker = reinterpret_cast<BLocker*>(locker); bLocker->Lock();}void _cairo_beos_unlock (void* locker) { BLocker* bLocker = reinterpret_cast<BLocker*>(locker); bLocker->Unlock();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -