Re: DrawingArea and Text display.



On Thu, 6 Mar 2003, Tony Denault wrote:

> Trying to convert some 1.2 gtk code to 2.0. Trying not to use any
> deprecated functions. I used the DrawingArea to display my own
> text using different font & colors. However documentation is very scarce.

Thanks to all who replied. I'll summaried what I learn for the mailing
list:

1. Here is a simple example that illustrates some text rendering in
   a drawing area:

   Note I pre-allocate some colors and GC for my application, ie:

      gdk_colormap_alloc_color( CM.colormap, &CM.colors[i], FALSE, TRUE );
      Nor_gc = gdk_gc_new(base_window->window);

/*----------------------------------------------------------------------------
**  draw_view_2() - Example showing to render text in drawing area
**----------------------------------------------------------------------------
*/
void draw_view_2( GtkWidget *da, int da_wid, int da_hgt )
{
   PangoFontDescription * font;
   PangoContext *context;
   PangoLayout  *layout;

   // obtain pango font object
   font =  pango_font_description_from_string ("Courier,Medium 8");

   // obtain pango layout object
   context = gtk_widget_create_pango_context (da);
   layout  = pango_layout_new (context);
   g_object_unref (context);

   // Draw some text
   pango_layout_set_font_description (layout, font);
   pango_layout_set_text (layout, "Some UTF-8 text", -1);
   gdk_gc_set_foreground( Nor_gc, &CM.colors[CM_YELLOW] );
   gdk_draw_layout (da->window, Nor_gc, 50, 50, layout);

   // Draw 2nd line
   pango_layout_set_text (layout, "This is more text", -1);
   gdk_gc_set_foreground( Nor_gc, &CM.colors[CM_GREEN] );
   gdk_draw_layout (da->window, Nor_gc, 50, 100, layout);

   // Overwrite part of 2nd line.
   pango_layout_set_text (layout, "overwrite", -1);
   gdk_draw_layout_with_colors (da->window, Nor_gc, 50, 100, layout,
      &CM.colors[CM_RED], &CM.colors[CM_BLACK] );

   // 3rd line -> gray back ground, Green Text.
   pango_layout_set_text (layout, "overwrite Part II", -1);
   gdk_draw_layout_with_colors (da->window, Nor_gc, 50, 150, layout,
      &CM.colors[CM_GREEN], &CM.colors[CM_GRAY] );

   pango_layout_set_text (layout, "The End", -1);
   gdk_draw_layout (da->window, Nor_gc, 50, 200, layout);

   g_object_unref (layout);
   g_object_unref (font);

}

2. Since my application refreshes my drawing area frequently and I have
   a lot of text, I actually allocate fonts and a layout. Then used
   a printf style function to put text on my drawing area. Here is the
   code:

 2.1. Initialize some colors and a GC for my application:

    gdk_colormap_alloc_color( CM.colormap, &CM.colors[i], FALSE, TRUE );
    Nor_gc = gdk_gc_new(base_window->window);

 2.2. Initalize a font and layout for my application. I save this
      information in a global variable.

   struct app_font_info_t Fixed_font;
   app_font_init( &Fixed_font, base_window, "Courier,Medium 5")

   where:

     struct app_font_info_t            // font, pango layout info to  render
     text to drawing area
     {
        PangoFontDescription * font;    // font reference
        PangoLayout          * layout;  // Pango reference
        int                  wid;
        int                  hgt;
        int                  ascent;
        int                  descent;
     };



      /*---------------------------------------------------------------------------
      **  app_font_init() - fill af with a pango Font and Layout  reference. Also
      **    initializes af with some font information (wid, hgt,etc).
      **---------------------------------------------------------------------------
      */
      int app_font_init(
         struct app_font_info_t *af,  // O: application font & layout  information.
         GtkWidget * gtk_widget,      // I: need to reference a widget.  ie: base_window
         char * font_name             // I: name of pango font to  allocate.
      )
      {
         PangoContext *context;
         PangoFontMetrics *metrics;

         if( (af->font = pango_font_description_from_string ("Courier,Medium 5")) == NULL )
         {
           printf("app_font_initialize()->pango_font_description_from_string() error!\n");
            return ERR_NOT_AVAILABLE;
         }

         if( (context = gtk_widget_create_pango_context (gtk_widget)) == NULL )
         {
            printf("app_font_initialize()->gtk_widget_create_pango_context() error!\n");
            return ERR_NOT_AVAILABLE;
         }

         if( (af->layout = pango_layout_new ( context )) == NULL )
         {
            printf("app_font_initialize()->pango_layout_new() error!\n");
            return ERR_NOT_AVAILABLE;
         }

         pango_layout_set_font_description (af->layout, af->font);

         // determine width & height of font.
         metrics = pango_context_get_metrics (context, af->font,
                            pango_context_get_language(context));

         af->wid = PANGO_PIXELS(  pango_font_metrics_get_approximate_digit_width(metrics) );
         af->ascent = PANGO_PIXELS( pango_font_metrics_get_ascent  (metrics) );
         af->descent = PANGO_PIXELS( pango_font_metrics_get_descent  (metrics) );
         af->hgt = af->ascent + af->descent;

         g_object_unref (context);
         pango_font_metrics_unref(metrics);

         printf("app_font_initialize() got[%s] size=%dx%d \n", font_name,  af->wid, af->hgt);
         return ERR_NONE;
      }


 2.3 Wrote some printf sytle function to render text to drawing area:

   /*----------------------------------------------------
   **  drawtext( ) - draws text on a drawing area widget.
   **----------------------------------------------------
   */
   void drawtext(
      GtkWidget *da,               // render text to this drawing area
      struct app_font_info_t *ap,  // font & layout information
      GdkGC * gc,                  // graphic contents
      int x, int y,                // col, row where place text
      char * fmt, ...
   )
   {
      char buf[256];
      va_list argptr;

      va_start( argptr, fmt );
      vsprintf( buf, fmt, argptr );
      va_end( argptr );

      pango_layout_set_text ( ap->layout, buf, -1);
      gdk_draw_layout (da->window, gc, x*ap->wid, y*ap->hgt, ap->layout);
   }

   /*-----------------------------------------------------------
   **   drawimagetext( ) - draws text (filling in background) on a
   **      drawing area widget.
   **------------------------------------------------------------
   */
   void drawimagetext(
      GtkWidget *da,                 // render text to this drawing area
      struct app_font_info_t *ap,    // font & layout information
      GdkGC * gc,                    // graphic contents
      GdkColor *fg, GdkColor * bg,   // foreground, background for text
      int x, int y,                  // col, row where place text
      char * fmt, ...
   )
   {
      char buf[256];
      va_list argptr;

      va_start( argptr, fmt );
      vsprintf( buf, fmt, argptr );
      va_end( argptr );

      pango_layout_set_text ( ap->layout, buf, -1);
      gdk_draw_layout_with_colors (da->window, gc, x*ap->wid, y*ap->hgt, ap->layout, fg, bg);
   }


 2.4 So, my redraw function for my drawing area can be simple:

   /*----------------------------------------------------------------------------
   **  draw_view_3() - Render text in drawing area using da_printf()
   **----------------------------------------------------------------------------
   */
   void draw_view_3( GtkWidget *da, int da_wid, int da_hgt )
   {
      gdk_gc_set_foreground( Nor_gc, &CM.colors[CM_YELLOW] );
      drawtext( da, &Fixed_font, Nor_gc, 0, 0, "Hello, this is yellow text");

      gdk_gc_set_foreground( Nor_gc, &CM.colors[CM_RED] );
      drawtext( da, &Fixed_font, Nor_gc, 1, 1, "Stop, if you see red");

      drawimagetext( da, &Fixed_font, Nor_gc, &CM.colors[CM_RED], &CM.colors[CM_GREEN],
         5, 2, "Red text on Green background");
   }


Thanks again!

Tony

/-----------------------------------------------------------------------\
| Tony Denault                     | Email: denault irtf ifa hawaii edu |
| Institute for Astronomy          |              Phone: (808) 932-2378 |
| 640 North Aohoku Place           |                Fax: (808) 933-0737 |
| Hilo, Hawaii 96720               |                                    |
\-----------------------------------------------------------------------/






[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]