• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

plplotcanvas-hacktext.c

Go to the documentation of this file.
00001 // -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
00002 //
00003 //  plplotcanvas-hacktext.c: Hacktext CanvasItem, cloned from the
00004 //                            gnome-print project
00005 //
00006 //  This program is free software; you can redistribute it and/or
00007 //  modify it under the terms of the GNU Library General Public License
00008 //  as published by the Free Software Foundation; either version 2 of
00009 //  the License, or (at your option) any later version.
00010 //
00011 //  This program is distributed in the hope that it will be useful,
00012 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //  GNU Library General Public License for more details.
00015 //
00016 //  You should have received a copy of the GNU Library General Public
00017 //  License along with this program; if not, write to the Free Software
00018 //  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019 //
00020 //  Authors:
00021 //    Federico Mena <federico@nuclecu.unam.mx>
00022 //    Raph Levien <raph@acm.org>
00023 //    Lauris Kaplinski <lauris@helixcode.com>
00024 //
00025 //  Copyright (C) 1998-1999 The Free Software Foundation
00026 //  Copyright (C) 2000-2002 Ximian Inc.
00027 //
00028 //
00029 
00030 //
00031 // FIXME: TODO: Clipping
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 // Macros from gnome-print-i18n.h in gnome-print
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 // Continue with hacktext code
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]; // the text to world transform (NB! mirrored Y)
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 // Computes the bounding box of the hacktext.  Assumes that the number of points in the hacktext is
00274 // not zero.
00275 //
00276 static void
00277 get_bounds( PlplotCanvasHacktext *hacktext, double *bx1, double *by1, double *bx2, double *by2 )
00278 {
00279     ArtDRect bbox;
00280 
00281     // Compute bounds of hacktext
00282     art_drect_hacktext( &bbox, hacktext );
00283 
00284     // Done
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         // FIXME: should be duplicate() (Lauris)
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         // should probably request repaint on the fill_svp
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 

Generated on Wed Oct 12 2011 20:42:22 for PLplot by  doxygen 1.7.1