00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <config.h>
00035
00036 #include <math.h>
00037 #include <string.h>
00038
00039 #include <libgnomeprint/gnome-pgl.h>
00040 #include <libgnomeprint/gnome-font.h>
00041 #include <libgnomeprint/gnome-rfont.h>
00042
00043 #include "plplotcanvas-hacktext.h"
00044
00045
00046
00047
00048
00049
00050 #ifndef __GNOME_PRINT_I18N_H__
00051 #define __GNOME_PRINT_I18N_H__
00052 # define textdomain( String ) ( String )
00053 # define gettext( String ) ( String )
00054 # define dgettext( Domain, Message ) ( Message )
00055 # define dcgettext( Domain, Message, Type ) ( Message )
00056 # define bindtextdomain( Domain, Directory ) ( Domain )
00057 # define _( String ) ( String )
00058 # define N_( String ) ( String )
00059 #endif // __GNOME_PRINT_I18N_H__
00060
00061
00062
00063
00064
00065
00066 enum
00067 {
00068 PROP_0,
00069 PROP_TEXT,
00070 PROP_GLYPHLIST,
00071 PROP_FILL_COLOR,
00072 PROP_FILL_COLOR_RGBA,
00073 PROP_FONT,
00074 PROP_X,
00075 PROP_Y
00076 };
00077
00078
00079 static void plplot_canvas_hacktext_class_init( PlplotCanvasHacktextClass *class );
00080 static void plplot_canvas_hacktext_init( PlplotCanvasHacktext *hacktext );
00081 static void plplot_canvas_hacktext_destroy( GtkObject *object );
00082 static void plplot_canvas_hacktext_set_property( GObject *object,
00083 guint param_id,
00084 const GValue *value,
00085 GParamSpec *pspec );
00086 static void plplot_canvas_hacktext_get_property( GObject *object,
00087 guint param_id,
00088 GValue *value,
00089 GParamSpec *pspec );
00090 static void plplot_canvas_hacktext_update( GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags );
00091 static void plplot_canvas_hacktext_realize( GnomeCanvasItem *item );
00092 static void plplot_canvas_hacktext_unrealize( GnomeCanvasItem *item );
00093 static double plplot_canvas_hacktext_point( GnomeCanvasItem *item, double x, double y,
00094 int cx, int cy, GnomeCanvasItem **actual_item );
00095 static void plplot_canvas_hacktext_bounds( GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y2 );
00096 static void plplot_canvas_hacktext_render( GnomeCanvasItem *item, GnomeCanvasBuf *buf );
00097 static void plplot_canvas_hacktext_req_repaint( PlplotCanvasHacktext *hacktext, ArtIRect *bbox );
00098
00099
00100 static GnomeCanvasItemClass *parent_class;
00101
00102 struct _PlplotCanvasHacktextPriv
00103 {
00104 GnomeFont * font;
00105
00106 GnomeGlyphList * glyphlist;
00107 GnomePosGlyphList * pgl;
00108 double affine[6];
00109 };
00110
00111 GType
00112 plplot_canvas_hacktext_get_type( void )
00113 {
00114 static GType type = 0;
00115 if ( !type )
00116 {
00117 GTypeInfo info = {
00118 sizeof ( PlplotCanvasHacktextClass ),
00119 NULL, NULL,
00120 (GClassInitFunc) plplot_canvas_hacktext_class_init,
00121 NULL, NULL,
00122 sizeof ( PlplotCanvasHacktext ),
00123 0,
00124 (GInstanceInitFunc) plplot_canvas_hacktext_init,
00125 NULL
00126 };
00127 type = g_type_register_static( GNOME_TYPE_CANVAS_ITEM, "PlplotCanvasHacktext", &info, 0 );
00128 }
00129 return type;
00130 }
00131
00132 static void
00133 plplot_canvas_hacktext_class_init( PlplotCanvasHacktextClass *class )
00134 {
00135 GObjectClass *gobject_class;
00136 GtkObjectClass *object_class;
00137 GnomeCanvasItemClass *item_class;
00138
00139 object_class = (GtkObjectClass *) class;
00140 gobject_class = (GObjectClass *) class;
00141 item_class = (GnomeCanvasItemClass *) class;
00142
00143 parent_class = g_type_class_peek_parent( class );
00144
00145 gobject_class->set_property = plplot_canvas_hacktext_set_property;
00146 gobject_class->get_property = plplot_canvas_hacktext_get_property;
00147
00148 g_object_class_install_property
00149 ( gobject_class,
00150 PROP_TEXT,
00151 g_param_spec_string( "text",
00152 _( "Text" ),
00153 _( "Text to render" ),
00154 NULL,
00155 G_PARAM_READABLE | G_PARAM_WRITABLE ) );
00156 g_object_class_install_property
00157 ( gobject_class,
00158 PROP_X,
00159 g_param_spec_double( "x", NULL, NULL,
00160 -G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
00161 ( G_PARAM_READABLE | G_PARAM_WRITABLE ) ) );
00162 g_object_class_install_property
00163 ( gobject_class,
00164 PROP_Y,
00165 g_param_spec_double( "y", NULL, NULL,
00166 -G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
00167 ( G_PARAM_READABLE | G_PARAM_WRITABLE ) ) );
00168 g_object_class_install_property
00169 ( gobject_class,
00170 PROP_GLYPHLIST,
00171 g_param_spec_pointer( "glyphlist",
00172 _( "Glyphlist" ),
00173 _( "Glyphlist" ),
00174 ( G_PARAM_READABLE | G_PARAM_WRITABLE ) ) );
00175 g_object_class_install_property
00176 ( gobject_class,
00177 PROP_FILL_COLOR,
00178 g_param_spec_string( "fill_color",
00179 _( "Color" ),
00180 _( "Text color, as string" ),
00181 NULL,
00182 G_PARAM_WRITABLE ) );
00183 g_object_class_install_property
00184 ( gobject_class,
00185 PROP_FILL_COLOR_RGBA,
00186 g_param_spec_uint( "fill_color_rgba",
00187 _( "Color" ),
00188 _( "Text color, as an R/G/B/A combined integer" ),
00189 0, G_MAXUINT, 0,
00190 ( G_PARAM_READABLE | G_PARAM_WRITABLE ) ) );
00191 g_object_class_install_property
00192 ( gobject_class,
00193 PROP_FONT,
00194 g_param_spec_object( "font",
00195 _( "Font" ),
00196 _( "Font as a GnomeFont struct" ),
00197 GNOME_TYPE_FONT,
00198 ( G_PARAM_READABLE | G_PARAM_WRITABLE ) ) );
00199
00200 object_class->destroy = plplot_canvas_hacktext_destroy;
00201
00202 item_class->update = plplot_canvas_hacktext_update;
00203 item_class->realize = plplot_canvas_hacktext_realize;
00204 item_class->unrealize = plplot_canvas_hacktext_unrealize;
00205 item_class->point = plplot_canvas_hacktext_point;
00206 item_class->bounds = plplot_canvas_hacktext_bounds;
00207 item_class->render = plplot_canvas_hacktext_render;
00208 }
00209
00210 static void
00211 plplot_canvas_hacktext_init( PlplotCanvasHacktext *hacktext )
00212 {
00213 hacktext->text = NULL;
00214 hacktext->priv = g_new( PlplotCanvasHacktextPriv, 1 );
00215 hacktext->priv->pgl = NULL;
00216 hacktext->priv->font = NULL;
00217 hacktext->priv->glyphlist = NULL;
00218
00219 art_affine_identity( hacktext->priv->affine );
00220 }
00221
00222 static void
00223 plplot_canvas_hacktext_destroy( GtkObject *object )
00224 {
00225 PlplotCanvasHacktext *hacktext;
00226
00227 g_return_if_fail( object != NULL );
00228 g_return_if_fail( PLPLOT_IS_CANVAS_HACKTEXT( object ) );
00229
00230 hacktext = PLPLOT_CANVAS_HACKTEXT( object );
00231
00232 if ( hacktext->text )
00233 {
00234 g_free( hacktext->text );
00235 hacktext->text = NULL;
00236 }
00237
00238 if ( hacktext->priv )
00239 {
00240 if ( hacktext->priv->font )
00241 gnome_font_unref( hacktext->priv->font );
00242 if ( hacktext->priv->glyphlist )
00243 gnome_glyphlist_unref( hacktext->priv->glyphlist );
00244 if ( hacktext->priv->pgl )
00245 gnome_pgl_destroy( hacktext->priv->pgl );
00246 g_free( hacktext->priv );
00247 hacktext->priv = NULL;
00248 }
00249
00250 if ( GTK_OBJECT_CLASS( parent_class )->destroy )
00251 ( *GTK_OBJECT_CLASS( parent_class )->destroy )( object );
00252 }
00253
00254 static void
00255 art_drect_hacktext( ArtDRect *bbox, PlplotCanvasHacktext *hacktext )
00256 {
00257 g_assert( bbox != NULL );
00258 g_assert( hacktext != NULL );
00259
00260 g_return_if_fail( hacktext->priv );
00261
00262 if ( GTK_OBJECT_FLAGS( hacktext ) & GNOME_CANVAS_UPDATE_REQUESTED )
00263 {
00264 gnome_canvas_update_now( GNOME_CANVAS_ITEM( hacktext )->canvas );
00265 }
00266
00267 if ( !hacktext->priv->pgl )
00268 return;
00269
00270 gnome_pgl_bbox( hacktext->priv->pgl, bbox );
00271 }
00272
00273
00274
00275
00276 static void
00277 get_bounds( PlplotCanvasHacktext *hacktext, double *bx1, double *by1, double *bx2, double *by2 )
00278 {
00279 ArtDRect bbox;
00280
00281
00282 art_drect_hacktext( &bbox, hacktext );
00283
00284
00285
00286 *bx1 = bbox.x0;
00287 *by1 = bbox.y0;
00288 *bx2 = bbox.x1;
00289 *by2 = bbox.y1;
00290 }
00291
00292 static void
00293 plplot_canvas_hacktext_set_property( GObject *object,
00294 guint param_id,
00295 const GValue *value,
00296 GParamSpec *pspec )
00297 {
00298 GnomeCanvasItem *item;
00299 PlplotCanvasHacktext *bp;
00300 GnomeGlyphList * gl;
00301 GdkColor color;
00302 GnomeFont * font;
00303
00304 item = GNOME_CANVAS_ITEM( object );
00305 bp = PLPLOT_CANVAS_HACKTEXT( object );
00306
00307 switch ( param_id )
00308 {
00309 case PROP_TEXT:
00310 if ( bp->text )
00311 {
00312 g_free( bp->text );
00313 bp->text = NULL;
00314 }
00315
00316 if ( bp->priv->glyphlist )
00317 {
00318 gnome_glyphlist_unref( bp->priv->glyphlist );
00319 bp->priv->glyphlist = NULL;
00320 }
00321
00322 bp->text = g_value_dup_string( value );
00323
00324 gnome_canvas_item_request_update( item );
00325 break;
00326
00327 case PROP_GLYPHLIST:
00328 gl = g_value_get_pointer( value );
00329
00330 if ( bp->text )
00331 {
00332 g_free( bp->text );
00333 bp->text = NULL;
00334 }
00335
00336 if ( bp->priv->glyphlist )
00337 {
00338 gnome_glyphlist_unref( bp->priv->glyphlist );
00339 bp->priv->glyphlist = NULL;
00340 }
00341
00342
00343 if ( gl )
00344 gnome_glyphlist_ref( gl );
00345
00346 bp->priv->glyphlist = gl;
00347
00348 gnome_canvas_item_request_update( item );
00349
00350 break;
00351
00352 case PROP_FILL_COLOR:
00353 if ( gnome_canvas_get_color( item->canvas, g_value_get_string( value ), &color ) )
00354 {
00355 bp->fill_set = TRUE;
00356 bp->fill_pixel = color.pixel;
00357 bp->fill_rgba =
00358 ( ( color.red & 0xff00 ) << 16 ) |
00359 ( ( color.green & 0xff00 ) << 8 ) |
00360 ( color.blue & 0xff00 ) |
00361 0xff;
00362 }
00363 else
00364 {
00365 bp->fill_set = FALSE;
00366 bp->fill_rgba = 0;
00367 }
00368
00369 gnome_canvas_item_request_update( item );
00370 break;
00371
00372 case PROP_FILL_COLOR_RGBA:
00373 bp->fill_set = TRUE;
00374 bp->fill_rgba = g_value_get_uint( value );
00375
00376
00377 gnome_canvas_item_request_update( item );
00378
00379 break;
00380
00381 case PROP_FONT:
00382 font = g_value_get_object( value );
00383 if ( font )
00384 gnome_font_ref( font );
00385 if ( bp->priv->font )
00386 gnome_font_unref( bp->priv->font );
00387 bp->priv->font = font;
00388 bp->size = gnome_font_get_size( bp->priv->font );
00389 gnome_canvas_item_request_update( item );
00390 break;
00391
00392 case PROP_X:
00393 bp->x = g_value_get_double( value );
00394 gnome_canvas_item_request_update( item );
00395 break;
00396
00397 case PROP_Y:
00398 bp->y = g_value_get_double( value );
00399 gnome_canvas_item_request_update( item );
00400 break;
00401
00402 default:
00403 break;
00404 }
00405 }
00406
00407 static void
00408 plplot_canvas_hacktext_get_property( GObject *object,
00409 guint param_id,
00410 GValue *value,
00411 GParamSpec *pspec )
00412 {
00413 PlplotCanvasHacktextPriv *priv;
00414 PlplotCanvasHacktext *bp;
00415
00416 bp = PLPLOT_CANVAS_HACKTEXT( object );
00417 priv = (PlplotCanvasHacktextPriv *) bp->priv;
00418
00419 switch ( param_id )
00420 {
00421 case PROP_TEXT:
00422 g_value_set_string( value, bp->text );
00423 break;
00424 case PROP_GLYPHLIST:
00425 g_value_set_pointer( value, priv->glyphlist );
00426 break;
00427 case PROP_FILL_COLOR_RGBA:
00428 g_value_set_uint( value, bp->fill_color );
00429 break;
00430 case PROP_FONT:
00431 g_value_set_object( value, bp->priv->font );
00432 break;
00433 case PROP_X:
00434 g_value_set_double( value, bp->x );
00435 break;
00436 case PROP_Y:
00437 g_value_set_double( value, bp->y );
00438 break;
00439 default:
00440 G_OBJECT_WARN_INVALID_PROPERTY_ID( object, param_id, pspec );
00441 break;
00442 }
00443 }
00444
00445 static void
00446 plplot_canvas_hacktext_update( GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags )
00447 {
00448 PlplotCanvasHacktext *hacktext;
00449 ArtIRect ibbox = { 0, 0, 0, 0 };
00450
00451 hacktext = (PlplotCanvasHacktext *) item;
00452
00453 if ( parent_class->update )
00454 ( *parent_class->update )( item, affine, clip_path, flags );
00455
00456 if ( hacktext->priv->pgl )
00457 plplot_canvas_hacktext_req_repaint( hacktext, NULL );
00458
00459 gnome_canvas_item_reset_bounds( item );
00460
00461 hacktext->priv->affine[0] = affine[0];
00462 hacktext->priv->affine[1] = affine[1];
00463 hacktext->priv->affine[2] = -affine[2];
00464 hacktext->priv->affine[3] = -affine[3];
00465 hacktext->priv->affine[4] = affine[4] + hacktext->x * affine[0] + hacktext->y * affine[2];
00466 hacktext->priv->affine[5] = affine[5] + hacktext->x * affine[1] + hacktext->y * affine[3];
00467
00468 if ( hacktext->text )
00469 {
00470 if ( hacktext->priv->glyphlist )
00471 {
00472 gnome_glyphlist_unref( hacktext->priv->glyphlist );
00473 hacktext->priv->glyphlist = NULL;
00474 }
00475
00476 if ( !hacktext->priv->font )
00477 return;
00478
00479 hacktext->priv->glyphlist = gnome_glyphlist_from_text_dumb( hacktext->priv->font, hacktext->fill_rgba,
00480 0.0, 0.0,
00481 hacktext->text );
00482 }
00483
00484 if ( hacktext->priv->glyphlist )
00485 {
00486 GnomePosGlyphList * pgl;
00487
00488 pgl = gnome_pgl_from_gl( hacktext->priv->glyphlist, hacktext->priv->affine, GNOME_PGL_RENDER_DEFAULT );
00489
00490 if ( hacktext->priv->pgl )
00491 gnome_pgl_destroy( hacktext->priv->pgl );
00492
00493 hacktext->priv->pgl = pgl;
00494 }
00495
00496 plplot_canvas_hacktext_req_repaint( hacktext, &ibbox );
00497
00498 hacktext->item.x1 = ibbox.x0;
00499 hacktext->item.y1 = ibbox.y0;
00500 hacktext->item.x2 = ibbox.x1;
00501 hacktext->item.y2 = ibbox.y1;
00502 }
00503
00504 static void
00505 plplot_canvas_hacktext_realize( GnomeCanvasItem *item )
00506 {
00507 PlplotCanvasHacktext *hacktext;
00508
00509 hacktext = (PlplotCanvasHacktext *) item;
00510
00511 if ( parent_class->realize )
00512 ( *parent_class->realize )( item );
00513 }
00514
00515 static void
00516 plplot_canvas_hacktext_unrealize( GnomeCanvasItem *item )
00517 {
00518 PlplotCanvasHacktext *hacktext;
00519
00520 hacktext = (PlplotCanvasHacktext *) item;
00521
00522 if ( parent_class->unrealize )
00523 ( *parent_class->unrealize )( item );
00524 }
00525
00526 static double
00527 plplot_canvas_hacktext_point( GnomeCanvasItem *item, double mx, double my,
00528 int cx, int cy, GnomeCanvasItem **actual_item )
00529 {
00530 PlplotCanvasHacktext * hacktext;
00531
00532 hacktext = (PlplotCanvasHacktext *) item;
00533
00534 if ( !hacktext->priv->pgl )
00535 return 1e18;
00536
00537 *actual_item = item;
00538
00539 if ( gnome_pgl_test_point( hacktext->priv->pgl, cx, cy ) )
00540 return 0.0;
00541
00542 return 1e18;
00543 }
00544
00545 static void
00546 plplot_canvas_hacktext_bounds( GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y2 )
00547 {
00548 PlplotCanvasHacktext *hacktext;
00549
00550 g_return_if_fail( item != NULL );
00551 g_return_if_fail( PLPLOT_IS_CANVAS_HACKTEXT( item ) );
00552
00553 hacktext = PLPLOT_CANVAS_HACKTEXT( item );
00554
00555 if ( hacktext->text == NULL )
00556 {
00557 *x1 = *y1 = *x2 = *y2 = 0.0;
00558 return;
00559 }
00560
00561 get_bounds( hacktext, x1, y1, x2, y2 );
00562 }
00563
00564 static void
00565 plplot_canvas_hacktext_req_repaint( PlplotCanvasHacktext *hacktext,
00566 ArtIRect *bbox )
00567 {
00568 ArtDRect gbbox;
00569
00570 g_return_if_fail( hacktext->priv );
00571
00572 if ( !hacktext->priv->pgl )
00573 return;
00574
00575 if ( gnome_pgl_bbox( hacktext->priv->pgl, &gbbox ) )
00576 {
00577 ArtIRect ibox;
00578 art_drect_to_irect( &ibox, &gbbox );
00579 gnome_canvas_request_redraw( hacktext->item.canvas, ibox.x0, ibox.y0, ibox.x1, ibox.y1 );
00580 if ( bbox )
00581 art_irect_union( bbox, bbox, &ibox );
00582 }
00583 }
00584
00585 static void
00586 plplot_canvas_hacktext_render( GnomeCanvasItem *item,
00587 GnomeCanvasBuf *buf )
00588 {
00589 PlplotCanvasHacktext * hacktext;
00590
00591 hacktext = (PlplotCanvasHacktext *) item;
00592
00593 g_return_if_fail( hacktext->priv );
00594
00595 if ( !hacktext->priv->pgl )
00596 return;
00597
00598 gnome_canvas_buf_ensure_buf( buf );
00599 buf->is_buf = TRUE;
00600 buf->is_bg = FALSE;
00601
00602 gnome_rfont_render_pgl_rgb8( hacktext->priv->pgl,
00603 -buf->rect.x0, -buf->rect.y0,
00604 buf->buf,
00605 buf->rect.x1 - buf->rect.x0,
00606 buf->rect.y1 - buf->rect.y0,
00607 buf->buf_rowstride,
00608 GNOME_RFONT_RENDER_DEFAULT );
00609 }
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621