PLplot: plplotcanvas-hacktext.c Source File

PLplot 5.10.0

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
plplotcanvas-hacktext.c
Go to the documentation of this file.
1 // -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
2 //
3 // plplotcanvas-hacktext.c: Hacktext CanvasItem, cloned from the
4 // gnome-print project
5 //
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Library General Public License
8 // as published by the Free Software Foundation; either version 2 of
9 // the License, or (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU Library General Public License for more details.
15 //
16 // You should have received a copy of the GNU Library General Public
17 // License along with this program; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 //
20 // Authors:
21 // Federico Mena <federico@nuclecu.unam.mx>
22 // Raph Levien <raph@acm.org>
23 // Lauris Kaplinski <lauris@helixcode.com>
24 //
25 // Copyright (C) 1998-1999 The Free Software Foundation
26 // Copyright (C) 2000-2002 Ximian Inc.
27 //
28 //
29
30 //
31 // FIXME: TODO: Clipping
32 //
33
34 #include <plplot_config.h>
35
36 #include <math.h>
37 #include <string.h>
38
39 #include <libgnomeprint/gnome-pgl.h>
40 #include <libgnomeprint/gnome-font.h>
41 #include <libgnomeprint/gnome-rfont.h>
42
43 #include "plplotcanvas-hacktext.h"
44
45
46 //
47 // Macros from gnome-print-i18n.h in gnome-print
48 //
49
50 #ifndef __GNOME_PRINT_I18N_H__
51 #define __GNOME_PRINT_I18N_H__
52 # define textdomain( String ) ( String )
53 # define gettext( String ) ( String )
54 # define dgettext( Domain, Message ) ( Message )
55 # define dcgettext( Domain, Message, Type ) ( Message )
56 # define bindtextdomain( Domain, Directory ) ( Domain )
57 # define _( String ) ( String )
58 # define N_( String ) ( String )
59 #endif // __GNOME_PRINT_I18N_H__
60
61
62 //
63 // Continue with hacktext code
64 //
65
66 enum
67 {
68 PROP_0,
69 PROP_TEXT,
70 PROP_GLYPHLIST,
71 PROP_FILL_COLOR,
72 PROP_FILL_COLOR_RGBA,
73 PROP_FONT,
74 PROP_X,
75 PROP_Y
76 };
77
78
79 static void plplot_canvas_hacktext_class_init( PlplotCanvasHacktextClass *class );
80 static void plplot_canvas_hacktext_init( PlplotCanvasHacktext *hacktext );
81 static void plplot_canvas_hacktext_destroy( GtkObject *object );
82 static void plplot_canvas_hacktext_set_property( GObject *object,
83 guint param_id,
84 const GValue *value,
85 GParamSpec *pspec );
86 static void plplot_canvas_hacktext_get_property( GObject *object,
87 guint param_id,
88 GValue *value,
89 GParamSpec *pspec );
90 static void plplot_canvas_hacktext_update( GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags );
91 static void plplot_canvas_hacktext_realize( GnomeCanvasItem *item );
92 static void plplot_canvas_hacktext_unrealize( GnomeCanvasItem *item );
93 static double plplot_canvas_hacktext_point( GnomeCanvasItem *item, double x, double y,
94 int cx, int cy, GnomeCanvasItem **actual_item );
95 static void plplot_canvas_hacktext_bounds( GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y2 );
96 static void plplot_canvas_hacktext_render( GnomeCanvasItem *item, GnomeCanvasBuf *buf );
97 static void plplot_canvas_hacktext_req_repaint( PlplotCanvasHacktext *hacktext, ArtIRect *bbox );
98
99
100 static GnomeCanvasItemClass *parent_class;
101
102 struct _PlplotCanvasHacktextPriv
103 {
104 GnomeFont * font;
105
106 GnomeGlyphList * glyphlist;
107 GnomePosGlyphList * pgl;
108 double affine[6]; // the text to world transform (NB! mirrored Y)
109 };
110
111 GType
112 plplot_canvas_hacktext_get_type( void )
113 {
114 static GType type = 0;
115 if ( !type )
116 {
117 GTypeInfo info = {
118 sizeof ( PlplotCanvasHacktextClass ),
119 NULL, NULL,
120 (GClassInitFunc) plplot_canvas_hacktext_class_init,
121 NULL, NULL,
122 sizeof ( PlplotCanvasHacktext ),
123 0,
124 (GInstanceInitFunc) plplot_canvas_hacktext_init,
125 NULL
126 };
127 type = g_type_register_static( GNOME_TYPE_CANVAS_ITEM, "PlplotCanvasHacktext", &info, 0 );
128 }
129 return type;
130 }
131
132 static void
133 plplot_canvas_hacktext_class_init( PlplotCanvasHacktextClass *class )
134 {
135 GObjectClass *gobject_class;
136 GtkObjectClass *object_class;
137 GnomeCanvasItemClass *item_class;
138
139 object_class = (GtkObjectClass *) class;
140 gobject_class = (GObjectClass *) class;
141 item_class = (GnomeCanvasItemClass *) class;
142
143 parent_class = g_type_class_peek_parent( class );
144
145 gobject_class->set_property = plplot_canvas_hacktext_set_property;
146 gobject_class->get_property = plplot_canvas_hacktext_get_property;
147
148 g_object_class_install_property
149 ( gobject_class,
150 PROP_TEXT,
151 g_param_spec_string( "text",
152 _( "Text" ),
153 _( "Text to render" ),
154 NULL,
155 G_PARAM_READABLE | G_PARAM_WRITABLE ) );
156 g_object_class_install_property
157 ( gobject_class,
158 PROP_X,
159 g_param_spec_double( "x", NULL, NULL,
160 -G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
161 ( G_PARAM_READABLE | G_PARAM_WRITABLE ) ) );
162 g_object_class_install_property
163 ( gobject_class,
164 PROP_Y,
165 g_param_spec_double( "y", NULL, NULL,
166 -G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
167 ( G_PARAM_READABLE | G_PARAM_WRITABLE ) ) );
168 g_object_class_install_property
169 ( gobject_class,
170 PROP_GLYPHLIST,
171 g_param_spec_pointer( "glyphlist",
172 _( "Glyphlist" ),
173 _( "Glyphlist" ),
174 ( G_PARAM_READABLE | G_PARAM_WRITABLE ) ) );
175 g_object_class_install_property
176 ( gobject_class,
177 PROP_FILL_COLOR,
178 g_param_spec_string( "fill_color",
179 _( "Color" ),
180 _( "Text color, as string" ),
181 NULL,
182 G_PARAM_WRITABLE ) );
183 g_object_class_install_property
184 ( gobject_class,
185 PROP_FILL_COLOR_RGBA,
186 g_param_spec_uint( "fill_color_rgba",
187 _( "Color" ),
188 _( "Text color, as an R/G/B/A combined integer" ),
189 0, G_MAXUINT, 0,
190 ( G_PARAM_READABLE | G_PARAM_WRITABLE ) ) );
191 g_object_class_install_property
192 ( gobject_class,
193 PROP_FONT,
194 g_param_spec_object( "font",
195 _( "Font" ),
196 _( "Font as a GnomeFont struct" ),
197 GNOME_TYPE_FONT,
198 ( G_PARAM_READABLE | G_PARAM_WRITABLE ) ) );
199
200 object_class->destroy = plplot_canvas_hacktext_destroy;
201
202 item_class->update = plplot_canvas_hacktext_update;
203 item_class->realize = plplot_canvas_hacktext_realize;
204 item_class->unrealize = plplot_canvas_hacktext_unrealize;
205 item_class->point = plplot_canvas_hacktext_point;
206 item_class->bounds = plplot_canvas_hacktext_bounds;
207 item_class->render = plplot_canvas_hacktext_render;
208 }
209
210 static void
211 plplot_canvas_hacktext_init( PlplotCanvasHacktext *hacktext )
212 {
213 hacktext->text = NULL;
214 hacktext->priv = g_new( PlplotCanvasHacktextPriv, 1 );
215 hacktext->priv->pgl = NULL;
216 hacktext->priv->font = NULL;
217 hacktext->priv->glyphlist = NULL;
218
219 art_affine_identity( hacktext->priv->affine );
220 }
221
222 static void
223 plplot_canvas_hacktext_destroy( GtkObject *object )
224 {
225 PlplotCanvasHacktext *hacktext;
226
227 g_return_if_fail( object != NULL );
228 g_return_if_fail( PLPLOT_IS_CANVAS_HACKTEXT( object ) );
229
230 hacktext = PLPLOT_CANVAS_HACKTEXT( object );
231
232 if ( hacktext->text )
233 {
234 g_free( hacktext->text );
235 hacktext->text = NULL;
236 }
237
238 if ( hacktext->priv )
239 {
240 if ( hacktext->priv->font )
241 gnome_font_unref( hacktext->priv->font );
242 if ( hacktext->priv->glyphlist )
243 gnome_glyphlist_unref( hacktext->priv->glyphlist );
244 if ( hacktext->priv->pgl )
245 gnome_pgl_destroy( hacktext->priv->pgl );
246 g_free( hacktext->priv );
247 hacktext->priv = NULL;
248 }
249
250 if ( GTK_OBJECT_CLASS( parent_class )->destroy )
251 ( *GTK_OBJECT_CLASS( parent_class )->destroy )( object );
252 }
253
254 static void
255 art_drect_hacktext( ArtDRect *bbox, PlplotCanvasHacktext *hacktext )
256 {
257 g_assert( bbox != NULL );
258 g_assert( hacktext != NULL );
259
260 g_return_if_fail( hacktext->priv );
261
262 if ( GTK_OBJECT_FLAGS( hacktext ) & GNOME_CANVAS_UPDATE_REQUESTED )
263 {
264 gnome_canvas_update_now( GNOME_CANVAS_ITEM( hacktext )->canvas );
265 }
266
267 if ( !hacktext->priv->pgl )
268 return;
269
270 gnome_pgl_bbox( hacktext->priv->pgl, bbox );
271 }
272
273 // Computes the bounding box of the hacktext. Assumes that the number of points in the hacktext is
274 // not zero.
275 //
276 static void
277 get_bounds( PlplotCanvasHacktext *hacktext, double *bx1, double *by1, double *bx2, double *by2 )
278 {
279 ArtDRect bbox;
280
281 // Compute bounds of hacktext
282 art_drect_hacktext( &bbox, hacktext );
283
284 // Done
285
286 *bx1 = bbox.x0;
287 *by1 = bbox.y0;
288 *bx2 = bbox.x1;
289 *by2 = bbox.y1;
290 }
291
292 static void
293 plplot_canvas_hacktext_set_property( GObject *object,
294 guint param_id,
295 const GValue *value,
296 GParamSpec *pspec )
297 {
298 GnomeCanvasItem *item;
299 PlplotCanvasHacktext *bp;
300 GnomeGlyphList * gl;
301 GdkColor color;
302 GnomeFont * font;
303
304 item = GNOME_CANVAS_ITEM( object );
305 bp = PLPLOT_CANVAS_HACKTEXT( object );
306
307 switch ( param_id )
308 {
309 case PROP_TEXT:
310 if ( bp->text )
311 {
312 g_free( bp->text );
313 bp->text = NULL;
314 }
315
316 if ( bp->priv->glyphlist )
317 {
318 gnome_glyphlist_unref( bp->priv->glyphlist );
319 bp->priv->glyphlist = NULL;
320 }
321
322 bp->text = g_value_dup_string( value );
323
324 gnome_canvas_item_request_update( item );
325 break;
326
327 case PROP_GLYPHLIST:
328 gl = g_value_get_pointer( value );
329
330 if ( bp->text )
331 {
332 g_free( bp->text );
333 bp->text = NULL;
334 }
335
336 if ( bp->priv->glyphlist )
337 {
338 gnome_glyphlist_unref( bp->priv->glyphlist );
339 bp->priv->glyphlist = NULL;
340 }
341
342 // FIXME: should be duplicate() (Lauris)
343 if ( gl )
344 gnome_glyphlist_ref( gl );
345
346 bp->priv->glyphlist = gl;
347
348 gnome_canvas_item_request_update( item );
349
350 break;
351
352 case PROP_FILL_COLOR:
353 if ( gnome_canvas_get_color( item->canvas, g_value_get_string( value ), &color ) )
354 {
355 bp->fill_set = TRUE;
356 bp->fill_pixel = color.pixel;
357 bp->fill_rgba =
358 ( ( color.red & 0xff00 ) << 16 ) |
359 ( ( color.green & 0xff00 ) << 8 ) |
360 ( color.blue & 0xff00 ) |
361 0xff;
362 }
363 else
364 {
365 bp->fill_set = FALSE;
366 bp->fill_rgba = 0;
367 }
368
369 gnome_canvas_item_request_update( item );
370 break;
371
372 case PROP_FILL_COLOR_RGBA:
373 bp->fill_set = TRUE;
374 bp->fill_rgba = g_value_get_uint( value );
375
376 // should probably request repaint on the fill_svp
377 gnome_canvas_item_request_update( item );
378
379 break;
380
381 case PROP_FONT:
382 font = g_value_get_object( value );
383 if ( font )
384 gnome_font_ref( font );
385 if ( bp->priv->font )
386 gnome_font_unref( bp->priv->font );
387 bp->priv->font = font;
388 bp->size = gnome_font_get_size( bp->priv->font );
389 gnome_canvas_item_request_update( item );
390 break;
391
392 case PROP_X:
393 bp->x = g_value_get_double( value );
394 gnome_canvas_item_request_update( item );
395 break;
396
397 case PROP_Y:
398 bp->y = g_value_get_double( value );
399 gnome_canvas_item_request_update( item );
400 break;
401
402 default:
403 break;
404 }
405 }
406
407 static void
408 plplot_canvas_hacktext_get_property( GObject *object,
409 guint param_id,
410 GValue *value,
411 GParamSpec *pspec )
412 {
413 PlplotCanvasHacktextPriv *priv;
414 PlplotCanvasHacktext *bp;
415
416 bp = PLPLOT_CANVAS_HACKTEXT( object );
417 priv = (PlplotCanvasHacktextPriv *) bp->priv;
418
419 switch ( param_id )
420 {
421 case PROP_TEXT:
422 g_value_set_string( value, bp->text );
423 break;
424 case PROP_GLYPHLIST:
425 g_value_set_pointer( value, priv->glyphlist );
426 break;
427 case PROP_FILL_COLOR_RGBA:
428 g_value_set_uint( value, bp->fill_color );
429 break;
430 case PROP_FONT:
431 g_value_set_object( value, bp->priv->font );
432 break;
433 case PROP_X:
434 g_value_set_double( value, bp->x );
435 break;
436 case PROP_Y:
437 g_value_set_double( value, bp->y );
438 break;
439 default:
440 G_OBJECT_WARN_INVALID_PROPERTY_ID( object, param_id, pspec );
441 break;
442 }
443 }
444
445 static void
446 plplot_canvas_hacktext_update( GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags )
447 {
448 PlplotCanvasHacktext *hacktext;
449 ArtIRect ibbox = { 0, 0, 0, 0 };
450
451 hacktext = (PlplotCanvasHacktext *) item;
452
453 if ( parent_class->update )
454 ( *parent_class->update )( item, affine, clip_path, flags );
455
456 if ( hacktext->priv->pgl )
457 plplot_canvas_hacktext_req_repaint( hacktext, NULL );
458
459 gnome_canvas_item_reset_bounds( item );
460
461 hacktext->priv->affine[0] = affine[0];
462 hacktext->priv->affine[1] = affine[1];
463 hacktext->priv->affine[2] = -affine[2];
464 hacktext->priv->affine[3] = -affine[3];
465 hacktext->priv->affine[4] = affine[4] + hacktext->x * affine[0] + hacktext->y * affine[2];
466 hacktext->priv->affine[5] = affine[5] + hacktext->x * affine[1] + hacktext->y * affine[3];
467
468 if ( hacktext->text )
469 {
470 if ( hacktext->priv->glyphlist )
471 {
472 gnome_glyphlist_unref( hacktext->priv->glyphlist );
473 hacktext->priv->glyphlist = NULL;
474 }
475
476 if ( !hacktext->priv->font )
477 return;
478
479 hacktext->priv->glyphlist = gnome_glyphlist_from_text_dumb( hacktext->priv->font, hacktext->fill_rgba,
480 0.0, 0.0,
481 hacktext->text );
482 }
483
484 if ( hacktext->priv->glyphlist )
485 {
486 GnomePosGlyphList * pgl;
487
488 pgl = gnome_pgl_from_gl( hacktext->priv->glyphlist, hacktext->priv->affine, GNOME_PGL_RENDER_DEFAULT );
489
490 if ( hacktext->priv->pgl )
491 gnome_pgl_destroy( hacktext->priv->pgl );
492
493 hacktext->priv->pgl = pgl;
494 }
495
496 plplot_canvas_hacktext_req_repaint( hacktext, &ibbox );
497
498 hacktext->item.x1 = ibbox.x0;
499 hacktext->item.y1 = ibbox.y0;
500 hacktext->item.x2 = ibbox.x1;
501 hacktext->item.y2 = ibbox.y1;
502 }
503
504 static void
505 plplot_canvas_hacktext_realize( GnomeCanvasItem *item )
506 {
507 PlplotCanvasHacktext *hacktext;
508
509 hacktext = (PlplotCanvasHacktext *) item;
510
511 if ( parent_class->realize )
512 ( *parent_class->realize )( item );
513 }
514
515 static void
516 plplot_canvas_hacktext_unrealize( GnomeCanvasItem *item )
517 {
518 PlplotCanvasHacktext *hacktext;
519
520 hacktext = (PlplotCanvasHacktext *) item;
521
522 if ( parent_class->unrealize )
523 ( *parent_class->unrealize )( item );
524 }
525
526 static double
527 plplot_canvas_hacktext_point( GnomeCanvasItem *item, double mx, double my,
528 int cx, int cy, GnomeCanvasItem **actual_item )
529 {
530 PlplotCanvasHacktext * hacktext;
531
532 hacktext = (PlplotCanvasHacktext *) item;
533
534 if ( !hacktext->priv->pgl )
535 return 1e18;
536
537 *actual_item = item;
538
539 if ( gnome_pgl_test_point( hacktext->priv->pgl, cx, cy ) )
540 return 0.0;
541
542 return 1e18;
543 }
544
545 static void
546 plplot_canvas_hacktext_bounds( GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y2 )
547 {
548 PlplotCanvasHacktext *hacktext;
549
550 g_return_if_fail( item != NULL );
551 g_return_if_fail( PLPLOT_IS_CANVAS_HACKTEXT( item ) );
552
553 hacktext = PLPLOT_CANVAS_HACKTEXT( item );
554
555 if ( hacktext->text == NULL )
556 {
557 *x1 = *y1 = *x2 = *y2 = 0.0;
558 return;
559 }
560
561 get_bounds( hacktext, x1, y1, x2, y2 );
562 }
563
564 static void
565 plplot_canvas_hacktext_req_repaint( PlplotCanvasHacktext *hacktext,
566 ArtIRect *bbox )
567 {
568 ArtDRect gbbox;
569
570 g_return_if_fail( hacktext->priv );
571
572 if ( !hacktext->priv->pgl )
573 return;
574
575 if ( gnome_pgl_bbox( hacktext->priv->pgl, &gbbox ) )
576 {
577 ArtIRect ibox;
578 art_drect_to_irect( &ibox, &gbbox );
579 gnome_canvas_request_redraw( hacktext->item.canvas, ibox.x0, ibox.y0, ibox.x1, ibox.y1 );
580 if ( bbox )
581 art_irect_union( bbox, bbox, &ibox );
582 }
583 }
584
585 static void
586 plplot_canvas_hacktext_render( GnomeCanvasItem *item,
587 GnomeCanvasBuf *buf )
588 {
589 PlplotCanvasHacktext * hacktext;
590
591 hacktext = (PlplotCanvasHacktext *) item;
592
593 g_return_if_fail( hacktext->priv );
594
595 if ( !hacktext->priv->pgl )
596 return;
597
598 gnome_canvas_buf_ensure_buf( buf );
599 buf->is_buf = TRUE;
600 buf->is_bg = FALSE;
601
602 gnome_rfont_render_pgl_rgb8( hacktext->priv->pgl,
603 -buf->rect.x0, -buf->rect.y0,
604 buf->buf,
605 buf->rect.x1 - buf->rect.x0,
606 buf->rect.y1 - buf->rect.y0,
607 buf->buf_rowstride,
608 GNOME_RFONT_RENDER_DEFAULT );
609 }
610
611
612
613
614
615
616
617
618
619
620
621