⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cairo-beos-surface.cpp

📁 按照官方的说法:Cairo is a vector graphics library with cross-device output support. 翻译过来
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* vim:set ts=8 sw=4 noet cin: *//* cairo - a vector graphics library with display and print output * * Copyright © 2005 Christian Biesinger <cbiesinger@web.de> * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public * License version 2.1 as published by the Free Software Foundation * (the "LGPL") or, at your option, under the terms of the Mozilla * Public License Version 1.1 (the "MPL"). If you do not alter this * notice, a recipient may use your version of this file under either * the MPL or the LGPL. * * You should have received a copy of the LGPL along with this library * in the file COPYING-LGPL-2.1; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * You should have received a copy of the MPL along with this library * in the file COPYING-MPL-1.1 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY * OF ANY KIND, either express or implied. See the LGPL or the MPL for * the specific language governing rights and limitations. * * The Original Code is the cairo graphics library. * * The Initial Developer of the Original Code is Christian Biesinger * <cbiesinger@web.de> * * Contributor(s): */// This is a C++ file in order to use the C++ BeOS API#include <new>#include <Bitmap.h>#include <Region.h>#if 0#include <DirectWindow.h>#endif#include <Screen.h>#include <Window.h>#include <Locker.h>#include "cairoint.h"#include "cairo-beos.h"#define CAIRO_INT_STATUS_SUCCESS (cairo_int_status_t)(CAIRO_STATUS_SUCCESS)struct cairo_beos_surface_t {    cairo_surface_t base;    BView* view;    /*     * A view is either attached to a bitmap, a window, or unattached.     * If it is attached to a window, we can copy data out of it using BScreen.     * If it is attached to a bitmap, we can read the bitmap data.     * If it is not attached, it doesn't draw anything, we need not bother.     *     * Since there doesn't seem to be a way to get the bitmap from a view if it     * is attached to one, we have to use a special surface creation function.     */    BBitmap* bitmap;    // If true, surface and view should be deleted when this surface is    // destroyed    bool owns_bitmap_view;};class AutoLockView {    public:	AutoLockView(BView* view) : mView(view) {	    mOK = mView->LockLooper();	}	~AutoLockView() {	    if (mOK)		mView->UnlockLooper();	}	operator bool() {	    return mOK;	}    private:	BView* mView;	bool   mOK;};static cairo_surface_t *_cairo_beos_surface_create_internal (BView*   view,				     BBitmap* bmp,				     bool     owns_bitmap_view = false);static BRect_cairo_rect_to_brect (const cairo_rectangle_fixed_t* rect){    // A BRect is one pixel wider than you'd think    return BRect(rect->x, rect->y, rect->x + rect->width - 1,	    	 rect->y + rect->height - 1);}static cairo_rectangle_fixed_t_brect_to_cairo_rect (const BRect& rect){    cairo_rectangle_fixed_t retval;    retval.x = int(rect.left + 0.5);    retval.y = int(rect.top + 0.5);    retval.width = rect.IntegerWidth() + 1;    retval.height = rect.IntegerHeight() + 1;    return retval;}static rgb_color_cairo_color_to_be_color (const cairo_color_t* color){    // This factor ensures a uniform distribution of numbers    const float factor = 256 - 1e-5;    // Using doubles to have non-premultiplied colors    rgb_color be_color = { uint8(color->red * factor),			   uint8(color->green * factor),			   uint8(color->blue * factor),			   uint8(color->alpha * factor) };    return be_color;}enum ViewCopyStatus {    OK,    NOT_VISIBLE, // The view or the interest rect is not visible on screen    ERROR        // The view was visible, but the rect could not be copied. Probably OOM};/** * _cairo_beos_view_to_bitmap: * @bitmap: [out] The resulting bitmap. * @rect: [out] The rectangle that was copied, in the view's coordinate system * @interestRect: If non-null, only this part of the view will be copied (view's coord system). * * Gets the contents of the view as a BBitmap*. Caller must delete the bitmap. **/static ViewCopyStatus_cairo_beos_view_to_bitmap (BView*       view,			    BBitmap**    bitmap,			    BRect*       rect = NULL,			    const BRect* interestRect = NULL){    *bitmap = NULL;    BWindow* wnd = view->Window();    // If we have no window, can't do anything    if (!wnd)	return NOT_VISIBLE;    view->Sync();    wnd->Sync();#if 0    // Is it a direct window?    BDirectWindow* directWnd = dynamic_cast<BDirectWindow*>(wnd);    if (directWnd) {	// WRITEME    }#endif    // Is it visible? If so, we can copy the content off the screen    if (wnd->IsHidden())	return NOT_VISIBLE;    BRect rectToCopy(view->Bounds());    if (interestRect)	rectToCopy = rectToCopy & *interestRect;    if (!rectToCopy.IsValid())	return NOT_VISIBLE;    BScreen screen(wnd);    BRect screenRect(view->ConvertToScreen(rectToCopy));    screenRect = screenRect & screen.Frame();    if (!screen.IsValid())	return NOT_VISIBLE;    if (rect)	*rect = view->ConvertFromScreen(screenRect);    if (screen.GetBitmap(bitmap, false, &screenRect) == B_OK)	return OK;    return ERROR;}inline unsigned charunpremultiply (unsigned char color,	       unsigned char alpha){    if (alpha == 0)	return 0;    // plus alpha/2 to round instead of truncate    return (color * 255 + alpha / 2) / alpha;}inline unsigned charpremultiply (unsigned char color,	     unsigned char alpha){    // + 127 to round, instead of truncate    return (color * alpha + 127) / 255;}/** * unpremultiply_rgba: * * Takes an input in ABGR premultiplied image data and unmultiplies it. * The result is stored in retdata. **/static voidunpremultiply_rgba (unsigned char* data,		    int            width,		    int            height,		    int            stride,		    unsigned char* retdata){    unsigned char* end = data + stride * height;    for (unsigned char* in = data, *out = retdata;	 in < end;	 in += stride, out += stride)    {	for (int i = 0; i < width; ++i) {	    // XXX for a big-endian platform this'd have to change	    int idx = 4 * i;	    unsigned char alpha = in[idx + 3];	    out[idx + 0] = unpremultiply(in[idx + 0], alpha); // B	    out[idx + 1] = unpremultiply(in[idx + 1], alpha); // G	    out[idx + 2] = unpremultiply(in[idx + 2], alpha); // R	    out[idx + 3] = in[idx + 3]; // Alpha	}    }}/** * premultiply_rgba: * * Takes an input in ABGR non-premultiplied image data and premultiplies it. * The returned data must be freed with free(). **/static unsigned char*premultiply_rgba (unsigned char* data,		  int            width,		  int            height,		  int            stride){    unsigned char* retdata = reinterpret_cast<unsigned char*>(malloc(stride * height));    if (!retdata)	return NULL;    unsigned char* end = data + stride * height;    for (unsigned char* in = data, *out = retdata;	 in < end;	 in += stride, out += stride)    {	for (int i = 0; i < width; ++i) {	    // XXX for a big-endian platform this'd have to change	    int idx = 4 * i;	    unsigned char alpha = in[idx + 3];	    out[idx + 0] = premultiply(in[idx + 0], alpha); // B	    out[idx + 1] = premultiply(in[idx + 1], alpha); // G	    out[idx + 2] = premultiply(in[idx + 2], alpha); // R	    out[idx + 3] = in[idx + 3]; // Alpha	}    }    return retdata;}/** * _cairo_beos_bitmap_to_surface: * * Returns an addrefed image surface for a BBitmap. The bitmap need not outlive * the surface. **/static cairo_image_surface_t*_cairo_beos_bitmap_to_surface (BBitmap* bitmap){    color_space format = bitmap->ColorSpace();    if (format != B_RGB32 && format != B_RGBA32) {	BBitmap bmp(bitmap->Bounds(), B_RGB32, true);	BView view(bitmap->Bounds(), "Cairo bitmap drawing view",		   B_FOLLOW_ALL_SIDES, 0);	bmp.AddChild(&view);	view.LockLooper();	view.DrawBitmap(bitmap, BPoint(0.0, 0.0));	view.Sync();	cairo_image_surface_t* imgsurf = _cairo_beos_bitmap_to_surface(&bmp);	view.UnlockLooper();	bmp.RemoveChild(&view);	return imgsurf;    }    cairo_format_t cformat = format == B_RGB32 ? CAIRO_FORMAT_RGB24						: CAIRO_FORMAT_ARGB32;    BRect bounds(bitmap->Bounds());    unsigned char* bits = reinterpret_cast<unsigned char*>(bitmap->Bits());    int width = bounds.IntegerWidth() + 1;    int height = bounds.IntegerHeight() + 1;    unsigned char* premultiplied;    if (cformat == CAIRO_FORMAT_ARGB32) {       premultiplied = premultiply_rgba(bits, width, height,					bitmap->BytesPerRow());    } else {	premultiplied = reinterpret_cast<unsigned char*>(					malloc(bitmap->BytesPerRow() * height));	if (premultiplied)	    memcpy(premultiplied, bits, bitmap->BytesPerRow() * height);    }    if (!premultiplied)	return NULL;    cairo_image_surface_t* surf = reinterpret_cast<cairo_image_surface_t*>	(cairo_image_surface_create_for_data(premultiplied,					     cformat,					     width,					     height,					     bitmap->BytesPerRow()));    if (surf->base.status)	free(premultiplied);    else	_cairo_image_surface_assume_ownership_of_data(surf);    return surf;}/** * _cairo_image_surface_to_bitmap: * * Converts an image surface to a BBitmap. The return value must be freed with * delete. **/static BBitmap*_cairo_image_surface_to_bitmap (cairo_image_surface_t* surface){    BRect size(0.0, 0.0, surface->width - 1, surface->height - 1);    switch (surface->format) {	case CAIRO_FORMAT_ARGB32: {	    BBitmap* data = new BBitmap(size, B_RGBA32);	    unpremultiply_rgba(surface->data,			       surface->width,			       surface->height,			       surface->stride,			       reinterpret_cast<unsigned char*>(data->Bits()));	    return data;        }	case CAIRO_FORMAT_RGB24: {	    BBitmap* data = new BBitmap(size, B_RGB32);	    memcpy(data->Bits(), surface->data, surface->height * surface->stride);	    return data;	}	default:	    assert(0);	    return NULL;    }}/** * _cairo_op_to_be_op: * * Converts a cairo drawing operator to a beos drawing_mode. Returns true if * the operator could be converted, false otherwise. **/static bool_cairo_op_to_be_op (cairo_operator_t cairo_op,		    drawing_mode*    beos_op){    switch (cairo_op) {	case CAIRO_OPERATOR_SOURCE:	    *beos_op = B_OP_COPY;	    return true;	case CAIRO_OPERATOR_OVER:	    *beos_op = B_OP_ALPHA;	    return true;	case CAIRO_OPERATOR_ADD:	    // Does not actually work#if 1	    return false;#else	    *beos_op = B_OP_ADD;	    return true;#endif	case CAIRO_OPERATOR_CLEAR:	    // Does not map to B_OP_ERASE - it replaces the dest with the low	    // color, instead of transparency; could be done by setting low	    // color appropriately.	case CAIRO_OPERATOR_IN:	case CAIRO_OPERATOR_OUT:	case CAIRO_OPERATOR_ATOP:	case CAIRO_OPERATOR_DEST:	case CAIRO_OPERATOR_DEST_OVER:	case CAIRO_OPERATOR_DEST_IN:	case CAIRO_OPERATOR_DEST_OUT:	case CAIRO_OPERATOR_DEST_ATOP:	case CAIRO_OPERATOR_XOR:	case CAIRO_OPERATOR_SATURATE:	default:	    return false;    };}static cairo_surface_t *_cairo_beos_surface_create_similar (void            *abstract_surface,				    cairo_content_t  content,				    int              width,				    int              height){    fprintf(stderr, "Creating similar\n");    cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(							abstract_surface);    if (width <= 0)	width = 1;    if (height <= 0)	height = 1;    BRect rect(0.0, 0.0, width - 1, height - 1);    BBitmap* bmp;    switch (content) {	case CAIRO_CONTENT_ALPHA:	    // Can't support this natively	    return _cairo_image_surface_create_with_content(content, width,							    height);	case CAIRO_CONTENT_COLOR_ALPHA:	    bmp = new BBitmap(rect, B_RGBA32, true);	    break;	case CAIRO_CONTENT_COLOR:	    // Match the color depth	    if (surface->bitmap) {		color_space space = surface->bitmap->ColorSpace();		// No alpha was requested -> make sure not to return		// a surface with alpha		if (space == B_RGBA32)		    space = B_RGB32;		if (space == B_RGBA15)		    space = B_RGB15;		bmp = new BBitmap(rect, space, true);	    } else {		BScreen scr(surface->view->Window());		color_space space = B_RGB32;		if (scr.IsValid())		    space = scr.ColorSpace();		bmp = new BBitmap(rect, space, true);	    }	    break;	default:	    assert(0);	    return NULL;	        };    BView* view = new BView(rect, "Cairo bitmap view", B_FOLLOW_ALL_SIDES, 0);    bmp->AddChild(view);    return _cairo_beos_surface_create_internal(view, bmp, true);}static cairo_status_t_cairo_beos_surface_finish (void *abstract_surface){    cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(							abstract_surface);    if (surface->owns_bitmap_view) {	if (surface->bitmap)	    surface->bitmap->RemoveChild(surface->view);	delete surface->view;	delete surface->bitmap;	surface->view = NULL;	surface->bitmap = NULL;    }    return CAIRO_STATUS_SUCCESS;}static cairo_status_t_cairo_beos_surface_acquire_source_image (void                   *abstract_surface,					  cairo_image_surface_t **image_out,					  void                  **image_extra){    fprintf(stderr, "Getting source image\n");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -