Re: Any simple text rendering





Frank Hrebabetzky ha scritto lo scorso 29/09/2004 15:00:
I am working on a Program which draws diagrams on a drawing area and therefore I need to draw some simple text such as 'y-Axis' or '0.00', '1.00' and so on, nothing fancy, no chinese or arab, just plain english monospaced text. Now how should I do that ?

Label widgets? I didn't see how to get ascent and descent which I need to place the text correctly. Besides that, I need to allocate each label, but as the number of axis numbers depends on the size of the drawing area (grid spacing), this must be done anew after each resizing and labels would accumulate contiuously.

Pango? No idea where to start reading. Seems a huge engine. Use this just to display a few characters?

So what would you guys do?

This is how I managed a similar issue - drawing a simple x-y chart; sorry for the comments (they are in italian). HTH.

void on_drawGraph_expose_event (GtkWidget * draw,
                                GdkEventExpose * event,
                                gpointer user_data) {
        GdkGC    * gc;
        GdkPoint * points = NULL;
        gint       i, np;
        guint      width, height, x0, y0, x1, y1;
        gchar    * buf;
        gchar    * ulabel = NULL;
        gchar      label[64];
        gsize      len;
        GIOChannel
                 * dati;
        gfloat     fx, fy;
        GdkColor * nero,
                 * grigio,
                 * rosso;
        PangoLayout
                 * pl;
        PangoFontDescription
                 * lblfont;
        GdkWChar * wlabel;

        /* Dimensioni della finestra
         */
gdk_window_get_geometry (draw->window, NULL, NULL, & width, & height, NULL);

        x0 = 50;
        y0 = 10;
        x1 = width - 10;
        y1 = height - 50;

        /* Impostazione dei colori personalizzati
         */
        rosso = (GdkColor *)g_malloc (sizeof (GdkColor));
        rosso->pixel = 0;
        rosso->red   = 0xffff;
        rosso->green = 0;
        rosso->blue  = 0;
        nero = (GdkColor *)g_malloc (sizeof (GdkColor));
        nero->pixel = 0;
        nero->red   = 0;
        nero->green = 0;
        nero->blue  = 0;
        grigio = (GdkColor *)g_malloc (sizeof (GdkColor));
        grigio->pixel = 0;
        grigio->red   = 0x8fff;
        grigio->green = 0x8fff;
        grigio->blue  = 0x8fff;

        /* Ora non resta che disegnare il grafico
         */
        gc = gdk_gc_new (draw->window);

        /* ticks & labels; il grafico avrà range fissi
         * [0 < fx < 65, 550 < fy < 950] e tick prefissati
         */
        points = (GdkPoint *)g_malloc (2 * sizeof (GdkPoint));

        pl = gtk_widget_create_pango_layout (draw, " ");
        lblfont = pango_font_description_from_string ("Sans 8");
        pango_layout_set_font_description (pl, lblfont);

        /* Asse X
         */
        for (i = 0; i < 9; i ++) {
                points[0].y = y1;
                points[0].x = points[1].x = (guint)(x0 + (x1 - x0) * (i * 10)/ 65);
                points[1].y = y1 + 3;
                /* Imposta gli stili della linea e traccia le ticks
                 */
gdk_gc_set_line_attributes (gc, 0, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
                gdk_gc_set_rgb_fg_color (gc, nero);
                gdk_draw_lines (draw->window, gc, points, 2);

                points[0].y = y1;
                points[1].y = y0;
                /* Imposta gli stili della linea e traccia le linee di divisione
                 */
gdk_gc_set_line_attributes (gc, 0, GDK_LINE_ON_OFF_DASH, GDK_CAP_ROUND, GDK_JOIN_ROUND);
                gdk_gc_set_rgb_fg_color (gc, grigio);
                gdk_draw_lines (draw->window, gc, points, 2);

                /* labels
                 */
                g_sprintf (label, "%8.1f\0", (gfloat)(i * 10));
                ulabel = g_locale_to_utf8 (label, -1, NULL, NULL, NULL);
                pango_layout_set_text (pl, ulabel, -1);
                g_free (ulabel);
                points[0].x -= 21;
                points[0].y += 10;
gdk_draw_layout_with_colors (draw->window, gc, points[0].x, points[0].y, pl, grigio, NULL);
        }

        /* Asse Y
         */
        for (i = 0; i < 9; i ++) {
                points[0].x = x0 - 3;
                points[0].y = points[1].y = (guint)(y1 - (y1 - y0) * (i * 50)/ 400);
                points[1].x = x0;
                /* Imposta gli stili della linea e traccia le ticks
                 */
gdk_gc_set_line_attributes (gc, 0, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
                gdk_gc_set_rgb_fg_color (gc, nero);
                gdk_draw_lines (draw->window, gc, points, 2);

                points[0].x = x0;
                points[1].x = x1;
                /* Imposta gli stili della linea e traccia le linee di divisione
                 */
gdk_gc_set_line_attributes (gc, 0, GDK_LINE_ON_OFF_DASH, GDK_CAP_ROUND, GDK_JOIN_ROUND);
                gdk_gc_set_rgb_fg_color (gc, grigio);
                gdk_draw_lines (draw->window, gc, points, 2);

                /* labels
                 */
                g_sprintf (label, "%d \260C\0", (i * 50 + 550));
                ulabel = g_locale_to_utf8 (label, -1, NULL, NULL, NULL);
                pango_layout_set_text (pl, ulabel, -1);
                g_free (ulabel);
                points[0].x -= 45;
                points[0].y -= 7;
gdk_draw_layout_with_colors (draw->window, gc, points[0].x, points[0].y, pl, grigio, NULL);
        }

        /*
         * Risultati: legge i punti da graficare da SimulaDeb.out
         */
        dati   = g_io_channel_new_file ("SimulaDeb.out", "r", NULL);
        np     = 1;
        while (g_io_channel_read_line (dati, & buf, & len, NULL, NULL) !=
                G_IO_STATUS_EOF) {
                points = (GdkPoint *)g_realloc (points, np * sizeof (GdkPoint));
                sscanf (buf, "%f %f", & fx, & fy);
                /* I valori spazio-Temp letti devono ora essere trasformati in
                   posizioni sul gc [ 0 < fx < 65, 500 < fy < 1000]
            */
                points[np-1].x = (guint)(x0 + (x1-x0) * fx/ 65);
                points[np-1].y = (guint)(y1 - (y1-y0) * (fy - 550)/ 400);
                np ++;
                g_free (buf);
        }

        /*
         * Traccia il grafico
         *
         * Imposta il colore (rosso)
         */
        gdk_gc_set_rgb_fg_color (gc, rosso);
        /* Imposta gli stili della linea
         */
gdk_gc_set_line_attributes (gc, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);

        /* Traccia la linea
         */
        gdk_draw_lines (draw->window, gc, points, np - 1);

        /* e infine il frame-box
         */
gdk_gc_set_line_attributes (gc, 0, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
        gdk_gc_set_rgb_fg_color (gc, nero);
        gdk_draw_rectangle (draw->window, gc, FALSE,
                        x0, y0, x1 - x0, y1 - y0);

        /* Libera tutti
         */
        g_io_channel_shutdown (dati, FALSE, NULL);
        g_io_channel_unref (dati);
        pango_font_description_free (lblfont);
        g_object_unref (pl);
        g_free (points);
        g_free (nero);
        g_free (rosso);
        g_free (grigio);
        g_object_unref (gc);
        
}



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