dyna-draw-context.cpp revision f951374eef04129c6a0d213e7ab4d9ed2095ca69
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix * Handwriting-like drawing mode
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix * Mitsuru Oka <oka326@parkcity.ne.jp>
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix * Lauris Kaplinski <lauris@kaplinski.com>
3cfad782faf34c654ec837780ed7b3fe95e82c2eJohan B. C. Engelen * bulia byak <buliabyak@users.sf.net>
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix * The original dynadraw code:
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix * Paul Haeberli <paul@sgi.com>
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix * Copyright (C) 1998 The Free Software Foundation
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix * Copyright (C) 1999-2005 authors
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix * Copyright (C) 2001-2002 Ximian, Inc.
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix * Released under GNU GPL, read the file 'COPYING' for more information
3cfad782faf34c654ec837780ed7b3fe95e82c2eJohan B. C. Engelen * TODO: Tue Oct 2 22:57:15 2001
3cfad782faf34c654ec837780ed7b3fe95e82c2eJohan B. C. Engelen * - Decide control point behavior when use_calligraphic==1.
3cfad782faf34c654ec837780ed7b3fe95e82c2eJohan B. C. Engelen * - Decide to use NORMALIZED_COORDINATE or not.
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix * - Bug fix.
b320a8d186114a5122ddc3afbe95110eb6cb10cecilixstatic void sp_dyna_draw_context_class_init(SPDynaDrawContextClass *klass);
99fae8b11f74e464ad0f55a7bfcc02933c4c1747johanengelenstatic void sp_dyna_draw_context_init(SPDynaDrawContext *ddc);
99fae8b11f74e464ad0f55a7bfcc02933c4c1747johanengelenstatic void sp_dyna_draw_context_dispose(GObject *object);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilixstatic void sp_dyna_draw_context_setup(SPEventContext *ec);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilixstatic void sp_dyna_draw_context_set(SPEventContext *ec, gchar const *key, gchar const *val);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilixstatic gint sp_dyna_draw_context_root_handler(SPEventContext *ec, GdkEvent *event);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilixstatic void concat_current_line(SPDynaDrawContext *dc);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilixstatic void accumulate_calligraphic(SPDynaDrawContext *dc);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilixstatic void fit_and_split(SPDynaDrawContext *ddc, gboolean release);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilixstatic void fit_and_split_line(SPDynaDrawContext *ddc, gboolean release);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilixstatic void fit_and_split_calligraphics(SPDynaDrawContext *ddc, gboolean release);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilixstatic void sp_dyna_draw_reset(SPDynaDrawContext *ddc, NR::Point p);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilixstatic NR::Point sp_dyna_draw_get_npoint(SPDynaDrawContext const *ddc, NR::Point v);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilixstatic NR::Point sp_dyna_draw_get_vpoint(SPDynaDrawContext const *ddc, NR::Point n);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilixstatic NR::Point sp_dyna_draw_get_curr_vpoint(SPDynaDrawContext const *ddc);
3cfad782faf34c654ec837780ed7b3fe95e82c2eJohan B. C. Engelen (GClassInitFunc) sp_dyna_draw_context_class_init,
3cfad782faf34c654ec837780ed7b3fe95e82c2eJohan B. C. Engelen (GInstanceInitFunc) sp_dyna_draw_context_init,
3cfad782faf34c654ec837780ed7b3fe95e82c2eJohan B. C. Engelen type = g_type_register_static(SP_TYPE_EVENT_CONTEXT, "SPDynaDrawContext", &info, (GTypeFlags)0);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilixsp_dyna_draw_context_class_init(SPDynaDrawContextClass *klass)
3cfad782faf34c654ec837780ed7b3fe95e82c2eJohan B. C. Engelen GObjectClass *object_class = (GObjectClass *) klass;
3cfad782faf34c654ec837780ed7b3fe95e82c2eJohan B. C. Engelen SPEventContextClass *event_context_class = (SPEventContextClass *) klass;
947fb2f89245c19c5bad9dbefb9fd44c2aaed2eccilix parent_class = (SPEventContextClass*)g_type_class_peek_parent(klass);
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix event_context_class->setup = sp_dyna_draw_context_setup;
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix event_context_class->root_handler = sp_dyna_draw_context_root_handler;
3cfad782faf34c654ec837780ed7b3fe95e82c2eJohan B. C. Engelen SPEventContext *event_context = SP_EVENT_CONTEXT(ddc);
5b20351508dc029f37f23fb7add6d0b43bf47f20johanengelen event_context->cursor_shape = cursor_calligraphy_xpm;
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix /* DynaDraw values */
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix /* attributes */
sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(ddc->currentshape), 0x00000000, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT);
g_signal_connect(G_OBJECT(ddc->currentshape), "event", G_CALLBACK(sp_desktop_root_handler), ec->desktop);
return NR::Point(dc->cur[NR::X] * max + drect.min()[NR::X], dc->cur[NR::Y] * max + drect.min()[NR::Y]);
static gboolean
return FALSE;
double a1;
if (length > 0) {
return FALSE;
bool flipped = false;
flipped = true;
// FIXME: when dc->vel is oscillating around the fixed angle, the new_ang flips back and forth. How to avoid this?
return TRUE;
static gint
return TRUE;
return TRUE;
case GDK_BUTTON_PRESS:
return TRUE;
? ( GDK_KEY_PRESS_MASK |
: ( GDK_KEY_PRESS_MASK |
NULL,
case GDK_MOTION_NOTIFY:
case GDK_BUTTON_RELEASE:
case GDK_KEY_PRESS:
case GDK_Up:
case GDK_KP_Up:
if (!MOD__CTRL_ONLY) {
case GDK_Down:
case GDK_KP_Down:
if (!MOD__CTRL_ONLY) {
case GDK_Right:
case GDK_KP_Right:
if (!MOD__CTRL_ONLY) {
case GDK_Left:
case GDK_KP_Left:
if (!MOD__CTRL_ONLY) {
case GDK_x:
case GDK_X:
if (MOD__ALT_ONLY) {
case GDK_Escape:
if (!ret) {
return ret;
static double square(double const x)
double const tolerance_sq = square( NR::expansion(SP_EVENT_CONTEXT(dc)->desktop->w2d()) * TOLERANCE_LINE );
if ( n_segs > 0
#ifdef DYNA_DRAW_VERBOSE
#ifdef DYNA_DRAW_VERBOSE
NULL);
sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(cbp), 0x000000ff, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT);
g_signal_connect(G_OBJECT(cbp), "event", G_CALLBACK(sp_desktop_root_handler), SP_EVENT_CONTEXT(dc)->desktop);
double const tolerance_sq = square( NR::expansion(SP_EVENT_CONTEXT(dc)->desktop->w2d()) * TOLERANCE_CALLIGRAPHIC );
#ifdef DYNA_DRAW_VERBOSE
#ifdef DYNA_DRAW_VERBOSE
#ifdef DYNA_DRAW_VERBOSE
if (! release) {
#ifdef DYNA_DRAW_VERBOSE
#ifdef DYNA_DRAW_VERBOSE
if (!release) {
NULL);
sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(cbp), 0x00000000, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT);
g_signal_connect(G_OBJECT(cbp), "event", G_CALLBACK(sp_desktop_root_handler), SP_EVENT_CONTEXT(dc)->desktop);