sodipodi-ctrl.cpp revision 208e5a33acc4a8ad9d8c0488f047c260346f1258
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiang * We render it by hand to reduce allocing/freeing svps & to get clean
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiang * (non-aa) images
806bce66335c88260a63e7524b1efc68d8dfacc1Heng Jiangstatic void sp_ctrl_class_init (SPCtrlClass *klass);
806bce66335c88260a63e7524b1efc68d8dfacc1Heng Jiangstatic void sp_ctrl_set_arg (GtkObject *object, GtkArg *arg, guint arg_id);
806bce66335c88260a63e7524b1efc68d8dfacc1Heng Jiangstatic void sp_ctrl_update (SPCanvasItem *item, NR::Matrix const &affine, unsigned int flags);
806bce66335c88260a63e7524b1efc68d8dfacc1Heng Jiangstatic void sp_ctrl_render (SPCanvasItem *item, SPCanvasBuf *buf);
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiangstatic double sp_ctrl_point (SPCanvasItem *item, NR::Point p, SPCanvasItem **actual_item);
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiang 0, /* n_preallocs */
806bce66335c88260a63e7524b1efc68d8dfacc1Heng Jiang ctrl_type = g_type_register_static (SP_TYPE_CANVAS_ITEM, "SPCtrl", &ctrl_info, (GTypeFlags)0);
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiang parent_class = (SPCanvasItemClass *)gtk_type_class (sp_canvas_item_get_type ());
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiang gtk_object_add_arg_type ("SPCtrl::shape", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_SHAPE);
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiang gtk_object_add_arg_type ("SPCtrl::mode", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_MODE);
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiang gtk_object_add_arg_type ("SPCtrl::anchor", GTK_TYPE_ANCHOR_TYPE, GTK_ARG_READWRITE, ARG_ANCHOR);
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiang gtk_object_add_arg_type ("SPCtrl::size", GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_SIZE);
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiang gtk_object_add_arg_type ("SPCtrl::pixbuf", GTK_TYPE_POINTER, GTK_ARG_READWRITE, ARG_PIXBUF);
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiang gtk_object_add_arg_type ("SPCtrl::filled", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_FILLED);
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiang gtk_object_add_arg_type ("SPCtrl::fill_color", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_FILL_COLOR);
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiang gtk_object_add_arg_type ("SPCtrl::stroked", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_STROKED);
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiang gtk_object_add_arg_type ("SPCtrl::stroke_color", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_STROKE_COLOR);
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiang ctrl->box.x0 = ctrl->box.y0 = ctrl->box.x1 = ctrl->box.y1 = 0;
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiang (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
31ac08a9e5233b83a63fd5aaac494c32305c4c77Heng Jiangsp_ctrl_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
6c8dc7ab7cb52a12cba748fe0f6b8d8d17a95eb9Heng Jiang ctrl->shape = (SPCtrlShapeType)(GTK_VALUE_INT (*arg));
6c8dc7ab7cb52a12cba748fe0f6b8d8d17a95eb9Heng Jiang ctrl->mode = (SPCtrlModeType)(GTK_VALUE_INT (*arg));
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiang ctrl->anchor = (GtkAnchorType)(GTK_VALUE_INT (*arg));
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiang ctrl->span = (gint) ((GTK_VALUE_DOUBLE (*arg) - 1.0) / 2.0 + 0.5);
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiang ctrl->pixbuf = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0);
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiangsp_ctrl_update (SPCanvasItem *item, NR::Matrix const &affine, unsigned int flags)
36089fe7ad5167b48f702514056071fd8739faeaHeng Jiang if (((SPCanvasItemClass *) parent_class)->update)
175c9e5fde43fc804a8d25198133288669b9d54cKlaus Luettich (* ((SPCanvasItemClass *) parent_class)->update) (item, affine, flags);
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiang sp_canvas_request_redraw (item->canvas, ctrl->box.x0, ctrl->box.y0, ctrl->box.x1 + 1, ctrl->box.y1 + 1);
44ea7e3effe9200ccc6abd3231ae56cf5cfb0fb8Heng Jiang if (!ctrl->defined) return;
44ea7e3effe9200ccc6abd3231ae56cf5cfb0fb8Heng Jiang x = (gint) ((affine[4] > 0) ? (affine[4] + 0.5) : (affine[4] - 0.5)) - ctrl->span;
44ea7e3effe9200ccc6abd3231ae56cf5cfb0fb8Heng Jiang y = (gint) ((affine[5] > 0) ? (affine[5] + 0.5) : (affine[5] - 0.5)) - ctrl->span;
67d5e49547d78aa56a8f9ba5e64a950b730eba66Till Mossakowski ctrl->box.y1 = ctrl->box.y0 + 2 * ctrl->span;
67d5e49547d78aa56a8f9ba5e64a950b730eba66Till Mossakowski sp_canvas_update_bbox (item, ctrl->box.x0, ctrl->box.y0, ctrl->box.x1 + 1, ctrl->box.y1 + 1);
67d5e49547d78aa56a8f9ba5e64a950b730eba66Till Mossakowskisp_ctrl_point (SPCanvasItem *item, NR::Point p, SPCanvasItem **actual_item)
44ea7e3effe9200ccc6abd3231ae56cf5cfb0fb8Heng Jiang double const x = p[NR::X];
67d5e49547d78aa56a8f9ba5e64a950b730eba66Till Mossakowski double const y = p[NR::Y];
67d5e49547d78aa56a8f9ba5e64a950b730eba66Till Mossakowski if ((x >= ctrl->box.x0) && (x <= ctrl->box.x1) && (y >= ctrl->box.y0) && (y <= ctrl->box.y1)) return 0.0;
44ea7e3effe9200ccc6abd3231ae56cf5cfb0fb8Heng Jiang for (x=0; x < side; x++) {
44ea7e3effe9200ccc6abd3231ae56cf5cfb0fb8Heng Jiang for (x=0; x < side; x++) {
44ea7e3effe9200ccc6abd3231ae56cf5cfb0fb8Heng Jiang for (y = 0; y < side; y++) {
44ea7e3effe9200ccc6abd3231ae56cf5cfb0fb8Heng Jiang z = abs (c - y);
44ea7e3effe9200ccc6abd3231ae56cf5cfb0fb8Heng Jiang for (x = 0; x < z; x++) {
44ea7e3effe9200ccc6abd3231ae56cf5cfb0fb8Heng Jiang *p++ = 0x00; *p++ = 0x00; *p++ = 0x00; *p++ = 0x00;
44ea7e3effe9200ccc6abd3231ae56cf5cfb0fb8Heng Jiang if (z != c) {
44ea7e3effe9200ccc6abd3231ae56cf5cfb0fb8Heng Jiang for (; x < side; x++) {
44ea7e3effe9200ccc6abd3231ae56cf5cfb0fb8Heng Jiang *p++ = 0x00; *p++ = 0x00; *p++ = 0x00; *p++ = 0x00;
44ea7e3effe9200ccc6abd3231ae56cf5cfb0fb8Heng Jiang for (y = 0; y <= c ; y++) {
44ea7e3effe9200ccc6abd3231ae56cf5cfb0fb8Heng Jiang a = abs (c - y);
44ea7e3effe9200ccc6abd3231ae56cf5cfb0fb8Heng Jiang while (x < c-z) {
44ea7e3effe9200ccc6abd3231ae56cf5cfb0fb8Heng Jiang *p++ = 0x00; *p++ = 0x00; *p++ = 0x00; *p++ = 0x00;
44ea7e3effe9200ccc6abd3231ae56cf5cfb0fb8Heng Jiang *q-- = 0x00; *q-- = 0x00; *q-- = 0x00; *q-- = 0x00;
44ea7e3effe9200ccc6abd3231ae56cf5cfb0fb8Heng Jiang } while (x < c-s);
44ea7e3effe9200ccc6abd3231ae56cf5cfb0fb8Heng Jiang } while (x <= c+z);
44ea7e3effe9200ccc6abd3231ae56cf5cfb0fb8Heng Jiang while (x < side) {
44ea7e3effe9200ccc6abd3231ae56cf5cfb0fb8Heng Jiang *p++ = 0x00; *p++ = 0x00; *p++ = 0x00; *p++ = 0x00;
44ea7e3effe9200ccc6abd3231ae56cf5cfb0fb8Heng Jiang *q-- = 0x00; *q-- = 0x00; *q-- = 0x00; *q-- = 0x00;
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiang for (y = 0; y < side; y++) {
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiang z = abs (c - y);
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiang for (x = 0; x < c-z; x++) {
c10df434f8e16b46ccf703bf2e38b799f7bcb38bHeng Jiang *p++ = 0x00; *p++ = 0x00; *p++ = 0x00; *p++ = 0x00;
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiang for (; x < c + z; x++) {
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiang *p++ = 0x00; *p++ = 0x00; *p++ = 0x00; *p++ = 0x00;
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiang if (z != 0) {
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiang for (; x < side; x++) {
b91c4dbd00294ce29ab1ae84ad4e8c93ca5ad943Heng Jiang *p++ = 0x00; *p++ = 0x00; *p++ = 0x00; *p++ = 0x00;
44ea7e3effe9200ccc6abd3231ae56cf5cfb0fb8Heng Jiang unsigned char *px;
b3c65285705f6d184b5f8b00b1a328d96b6b19c5Heng Jiang unsigned int rs;
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiang for (y = 0; y < side; y++){
b91c4dbd00294ce29ab1ae84ad4e8c93ca5ad943Heng Jiang unsigned char *s, *d;
3d59ee7815197f19948fc512cd90f9f26fd4d78fHeng Jiang for (x = 0; x < side; x++) {
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiang d[0] = 0x00;
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiang } else if (s[0] < 0x80) {
b3c65285705f6d184b5f8b00b1a328d96b6b19c5Heng Jiang guint r = gdk_pixbuf_get_rowstride (ctrl->pixbuf);
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiang for (y = 0; y < side; y++){
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiang pix = q + (y * r);
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiang for (x = 0; x < side; x++) {
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiang// composite background, foreground, alpha for xor mode
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiang#define COMPOSE_X(b,f,a) ( ( ((guchar) b) * ((guchar) (0xff - a)) + ((guchar) ((b ^ ~f) + b/4 - (b>127? 63 : 0))) * ((guchar) a) ) / 0xff )
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiang// composite background, foreground, alpha for color mode
36089fe7ad5167b48f702514056071fd8739faeaHeng Jiang#define COMPOSE_N(b,f,a) ( ( ((guchar) b) * ((guchar) (0xff - a)) + ((guchar) f) * ((guchar) a) ) / 0xff )
95242ab07e9aa13b37c16cac36a75d190e1766e4Heng Jiangsp_ctrl_render (SPCanvasItem *item, SPCanvasBuf *buf)
if (!ctrl->defined) return;
bool colormode;
// 00000000 is the only way to get invisible; all other colors with alpha 00 are treated as mode_color with alpha ff
colormode = false;
colormode = true;
p[0] = COMPOSE_N (p[0], q[0], a);
p[0] = COMPOSE_X (p[0], q[0], a);
_moved = true;