source: trunk/third/gnome-utils/gdictsrc/gdict-defbox.c @ 18366

Revision 18366, 20.5 KB checked in by ghudson, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18365, which included commits to RCS files with non-trunk default branches.
Line 
1/* $Id: gdict-defbox.c,v 1.1.1.3 2003-01-04 21:13:18 ghudson Exp $ */
2
3/*
4 *  Mike Hughes <mfh@psilord.com>
5 *  Papadimitriou Spiros <spapadim+@cs.cmu.edu>
6 *  Bradford Hovinen <hovinen@udel.edu>
7 *
8 *  This code released under the GNU GPL.
9 *  Read the file COPYING for more information.
10 *
11 *  GDict main window
12 *
13 */
14
15#ifdef HAVE_CONFIG_H
16#  include <config.h>
17#endif
18
19#include <stdio.h>
20#include <stdlib.h>
21#include <assert.h>
22#include <string.h>
23#include <ctype.h>
24
25#define GTK_ENABLE_BROKEN
26#include <gnome.h>
27
28#include "gdict-defbox.h"
29#include "gdict-app.h"
30#include "gdict-pref.h"
31
32#ifdef HAVE_GNOME_PRINT
33#  include <math.h>
34#endif /* HAVE_GNOME_PRINT */
35
36enum {
37    WORD_LOOKUP_START_SIGNAL,
38    WORD_LOOKUP_DONE_SIGNAL,
39    WORD_NOT_FOUND_SIGNAL,
40    SUBSTR_NOT_FOUND_SIGNAL,
41    SOCKET_ERROR_SIGNAL,
42    LAST_SIGNAL
43};
44
45static gint gdict_defbox_signals[LAST_SIGNAL] = { 0, 0, 0, 0 };
46
47static void gdict_defbox_init (GDictDefbox *defbox);
48static void gdict_defbox_class_init (GDictDefboxClass *class);
49
50static void def_error_cb  (dict_command_t *command, DictStatusCode code,
51                           gchar *message, gpointer data);
52static void def_status_cb (dict_command_t *command, DictStatusCode code,
53                           int num_found, gpointer data);
54static void def_data_cb   (dict_command_t *command, dict_res_t *res,
55                           gpointer data);
56
57static gboolean is_xref   (gchar *str, int len);
58static gboolean is_number (gchar *str, int len);
59static gboolean is_part   (gchar *str, int len);
60static void defbox_add    (GDictDefbox *defbox, gchar *def);
61
62#ifdef HAVE_GNOME_PRINT
63static GnomeTextLine *get_line (const char *fontlist, const char *string,
64                                double size);
65#endif
66
67/* gdict_defbox_get_type
68 *
69 * Register the GDictDefbox type with Gtk's type system if necessary and
70 * return the type identifier code
71 */
72
73GType
74gdict_defbox_get_type (void) {
75    static GType gdict_defbox_type = 0;
76   
77    if (!gdict_defbox_type) {
78        static const GTypeInfo gdict_defbox_info = {
79            sizeof (GDictDefboxClass),
80            NULL,
81            NULL,
82            (GClassInitFunc) gdict_defbox_class_init,
83            NULL,
84            NULL,
85            sizeof (GDictDefbox),
86            0,
87            (GInstanceInitFunc) gdict_defbox_init
88        };
89       
90        gdict_defbox_type =
91            g_type_register_static (GTK_TYPE_TEXT_VIEW, "GDictDefboxClass", &gdict_defbox_info, 0);
92
93    }
94   
95    return gdict_defbox_type;
96}
97
98/* gdict_defbox_init
99 *
100 * Initialises an instance of a GDictDefbox object
101 */
102
103static void
104gdict_defbox_init (GDictDefbox *defbox) {
105    defbox->context = NULL;
106    defbox->def_cmd = NULL;
107}
108
109/* gdict_defbox_class_init
110 *
111 * Initialises a structure describing the GDictDefbox class; sets up signals
112 * for defbox events in the Gtk signal management system
113 */
114
115static void
116gdict_defbox_class_init (GDictDefboxClass *class) {
117    GtkObjectClass *object_class;
118   
119    object_class = (GtkObjectClass *) class;
120   
121    gdict_defbox_signals[WORD_LOOKUP_START_SIGNAL] =
122        gtk_signal_new ("word_lookup_start", GTK_RUN_FIRST, GTK_CLASS_TYPE (object_class),
123                        GTK_SIGNAL_OFFSET (GDictDefboxClass, word_lookup_start),
124                        gtk_signal_default_marshaller, GTK_TYPE_NONE, 0);
125   
126    gdict_defbox_signals[WORD_LOOKUP_DONE_SIGNAL] =
127        gtk_signal_new ("word_lookup_done", GTK_RUN_FIRST, GTK_CLASS_TYPE (object_class),
128                        GTK_SIGNAL_OFFSET (GDictDefboxClass, word_lookup_done),
129                        gtk_signal_default_marshaller, GTK_TYPE_NONE, 0);
130   
131    gdict_defbox_signals[WORD_NOT_FOUND_SIGNAL] =
132        gtk_signal_new ("word_not_found", GTK_RUN_FIRST, GTK_CLASS_TYPE (object_class),
133                        GTK_SIGNAL_OFFSET (GDictDefboxClass, word_not_found),
134                        gtk_signal_default_marshaller, GTK_TYPE_NONE, 0);
135   
136    gdict_defbox_signals[SUBSTR_NOT_FOUND_SIGNAL] =
137        gtk_signal_new ("substr_not_found", GTK_RUN_FIRST, GTK_CLASS_TYPE (object_class),
138                        GTK_SIGNAL_OFFSET (GDictDefboxClass, substr_not_found),
139                        gtk_signal_default_marshaller, GTK_TYPE_NONE, 0);
140   
141    gdict_defbox_signals[SOCKET_ERROR_SIGNAL] =
142        gtk_signal_new ("socket_error", GTK_RUN_FIRST, GTK_CLASS_TYPE (object_class),
143                        GTK_SIGNAL_OFFSET (GDictDefboxClass, socket_error),
144                        gtk_marshal_VOID__STRING, GTK_TYPE_NONE, 1,
145                        GTK_TYPE_STRING);
146 /*   
147    gtk_object_class_add_signals (object_class, gdict_defbox_signals,
148                                  LAST_SIGNAL);
149 */ 
150    class->word_lookup_start = NULL;
151    class->word_lookup_done = NULL;
152    class->word_not_found = NULL;
153    class->substr_not_found = NULL;
154}
155
156/* gdict_defbox_new
157 *
158 * Creates a new GDictDefbox object
159 */
160
161GtkWidget *
162gdict_defbox_new (void) {
163    GDictDefbox *defbox;
164   
165    defbox = GDICT_DEFBOX (gtk_type_new (gdict_defbox_get_type ()));
166    return GTK_WIDGET (defbox);
167}
168
169/* Setup textview tags
170 */
171void
172defbox_setup_tags (GDictDefbox *defbox) {
173    GtkTextBuffer *buffer;
174       
175    buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (defbox));
176       
177    gtk_text_buffer_create_tag (buffer, "italic",
178                                "style", PANGO_STYLE_ITALIC, NULL);
179    gtk_text_buffer_create_tag (buffer, "bold",
180                                "weight", PANGO_WEIGHT_BOLD, NULL);
181    gtk_text_buffer_create_tag (buffer, "underline",
182                                "underline", PANGO_UNDERLINE_SINGLE, NULL);
183}
184
185/* gdict_defbox_destroy
186 *
187 * Deallocates memory associated with the defbox
188 */
189
190void
191gdict_defbox_destroy (GDictDefbox *defbox) {
192    g_free (defbox->database);
193}
194
195/* gdict_defbox_lookup
196 *
197 * Sends the command to the server to commence looking up the definition
198 * of a word and sets the callbacks so that the definition will be displayed
199 * in this defbox
200 *
201 * Returns 0 on success and -1 on command invocation error
202 */
203
204gint
205gdict_defbox_lookup (GDictDefbox *defbox, gchar *text) {
206    g_return_val_if_fail (defbox != NULL, -1);
207    g_return_val_if_fail (IS_GDICT_DEFBOX (defbox), -1);
208    g_return_val_if_fail (text != NULL, -1);
209   
210    while (isspace (*text)) text++;
211   
212    if (*text == '\0')
213        return 0;
214   
215    gtk_signal_emit (GTK_OBJECT (defbox),
216                     gdict_defbox_signals[WORD_LOOKUP_START_SIGNAL]);
217   
218    gdict_defbox_clear (defbox);
219   
220    if (defbox->database)
221            g_free (defbox->database);
222   
223    defbox->database = g_strdup (gdict_pref.database);
224   
225    defbox->def_cmd = dict_define_command_new (defbox->database, text);
226    defbox->def_cmd->error_notify_cb = def_error_cb;
227    defbox->def_cmd->status_notify_cb = def_status_cb;
228    defbox->def_cmd->data_notify_cb = def_data_cb;
229    defbox->def_cmd->user_data = defbox;
230
231    if (dict_command_invoke (defbox->def_cmd, defbox->context) < 0)
232        return -1;
233
234    return 0;
235}
236
237/* gdict_defbox_clear
238 *
239 * Clears the text in a defbox and eliminates the current command structure
240 */
241
242void
243gdict_defbox_clear (GDictDefbox *defbox) {
244    GtkTextBuffer *buffer;
245    GtkTextIter start, end;
246   
247    g_return_if_fail (defbox != NULL);
248    g_return_if_fail (IS_GDICT_DEFBOX (defbox));
249   
250    buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (defbox));
251    gtk_text_buffer_get_start_iter (buffer, &start);
252    gtk_text_buffer_get_end_iter (buffer, &end);
253    gtk_text_buffer_delete (buffer, &start, &end);
254 
255    if (defbox->def_cmd) {
256        dict_command_destroy (defbox->def_cmd);
257        defbox->def_cmd = NULL;
258    }
259}
260
261/* gdict_defbox_find
262 *
263 * Finds a string of text in the current definition
264 */
265
266gboolean
267gdict_defbox_find (GDictDefbox *defbox, const gchar *text, gboolean start) {
268    GtkTextBuffer *buffer;
269    GtkTextIter start_iter, end_iter, iter;
270    GtkTextIter match_start, match_end;
271    GtkTextMark *mark = NULL;
272    static gchar *lastp = NULL;
273    static gchar *deftext = NULL;
274    gchar *findp;
275    gint i = 0;
276
277    g_return_if_fail (defbox != NULL);
278    g_return_if_fail (IS_GDICT_DEFBOX (defbox));
279   
280    buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (defbox));
281   
282    gtk_text_buffer_get_bounds (buffer, &start_iter, &end_iter);
283       
284    if (start)
285        iter = start_iter;
286    else {
287        mark = gtk_text_buffer_get_mark (buffer, "last_search");
288       
289        if (mark)
290            gtk_text_buffer_get_iter_at_mark (buffer, &iter, mark);
291        else
292            iter = start_iter;
293    }
294   
295    if (gtk_text_iter_forward_search (&iter, text,
296                                      GTK_TEXT_SEARCH_VISIBLE_ONLY |
297                                      GTK_TEXT_SEARCH_TEXT_ONLY,
298                                      &match_start, &match_end,
299                                      NULL))
300    {
301        gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (defbox), &match_start,
302                                      0.0, TRUE, 0.5, 0.5);
303        gtk_text_buffer_place_cursor (buffer, &match_end);
304        gtk_text_buffer_move_mark (buffer,
305                               gtk_text_buffer_get_mark (buffer, "selection_bound"),
306                               &match_start);     
307        gtk_text_buffer_create_mark (buffer, "last_search", &match_end, FALSE);
308
309        return TRUE;
310    }
311    else
312    {
313        gtk_signal_emit (GTK_OBJECT (defbox),
314                         gdict_defbox_signals[SUBSTR_NOT_FOUND_SIGNAL]);
315
316        return FALSE;
317    }
318}
319
320/* gdict_defbox_reset
321 *
322 * Resets the defbox by re-invoking the define command on a new database
323 * and/or server
324 */
325
326void
327gdict_defbox_reset (GDictDefbox *defbox, dict_context_t *context) {
328    gchar *word;
329   
330    if (context != defbox->context ||
331        defbox->database == NULL ||
332        strcmp (defbox->database, gdict_pref.database))
333    {
334        defbox->context = context;
335       
336        if (defbox->def_cmd) {
337            word = g_strdup (defbox->def_cmd->search_term);
338            dict_command_destroy (defbox->def_cmd);
339            defbox->def_cmd = NULL;
340            gdict_defbox_lookup (defbox, word);
341            g_free (word);
342        }
343    }
344}
345
346#ifdef HAVE_GNOME_PRINT
347
348/* gdict_defbox_print
349 *
350 * Prints the current definition
351 */
352
353void
354gdict_defbox_print (GDictDefbox *defbox) {
355    GnomePrintContext *pc;
356    GList *node;
357    dict_res_t *res;
358    int x = 32, y = 700;
359
360    g_return_if_fail (defbox != NULL);
361    g_return_if_fail (IS_GDICT_DEFBOX (defbox));
362    g_return_if_fail (gdict_printer != NULL);
363
364    if (defbox->def_cmd == NULL)
365        return;
366
367    pc = gnome_print_context_new (gdict_printer);
368    g_return_if_fail(pc != NULL);
369
370    for (node = defbox->def_cmd->res_list; node; node = g_list_next (node)) {
371        gchar *linep, line[1024];  /* FIXME */
372        GnomeTextLine *textline;
373       
374        res = (dict_res_t *) node->data;
375        linep = res->desc;
376
377        while (linep && *linep) {
378            gchar *endp = strchr(linep, '\n') - 1;
379
380            bzero(line, sizeof(line));
381            strncpy(line, linep, endp - linep);
382            textline = get_line("Times", line, 12.0);
383            gnome_print_moveto(pc, x, y);
384            gnome_print_textline(pc, textline);
385            gnome_text_line_free(textline);
386            y -= 14;
387            linep = endp + 2;
388        }
389        textline = get_line("Times", "", 12.0);
390        gnome_print_moveto(pc, x, y);
391        gnome_print_textline(pc, textline);
392        gnome_text_line_free(textline);
393        y -= 14;
394    }
395
396    gnome_print_context_close(pc);
397}
398
399#endif /* HAVE_GNOME_PRINT */
400
401/* gdict_defbox_get_word
402 *
403 * Returns the word defined in the defbox, if any
404 */
405
406gchar *
407gdict_defbox_get_word (GDictDefbox *defbox) {
408    g_return_val_if_fail (defbox != NULL, NULL);
409    g_return_val_if_fail (IS_GDICT_DEFBOX (defbox), NULL);
410   
411    return defbox->def_cmd ? defbox->def_cmd->search_term : NULL;
412}
413
414/* is_xref
415 *
416 * Returns true if the substring str[0..len-1] is a cross reference
417 */
418
419static gboolean
420is_xref (gchar *str, int len) {
421    gint i;
422    for (i = 0;  i < len;  i++)
423        if (!isupper(str[i]) && !ispunct(str[i]))
424            return FALSE;
425    return TRUE;
426}
427
428/* is_number
429 *
430 * Returns true if the substring given by str[0..len-1] is a heading number
431 */
432
433static gboolean
434is_number (gchar *str, int len) {
435    gint i;
436
437    if (str[len-1] != '.')
438        return FALSE;
439       
440    for (i = 0;  i < len - 1;  i++)
441        if (!isdigit(str[i]))
442            return FALSE;
443
444    return TRUE;
445}
446
447/* is_part
448 *
449 * Returns true if the substring given by str[0..len-1] is a part of speech
450 */
451
452static gboolean
453is_part (gchar *str, int len) {
454    gchar buf[3];
455
456    if ((len < 1) || (len > 2))
457        return FALSE;
458
459    strncpy(buf, str, 2);
460    buf[len] = 0;
461
462    return (strcmp(buf, "n") == 0) || \
463           (strcmp(buf, "vt") == 0) || \
464           (strcmp(buf, "vi") == 0) || \
465           (strcmp(buf, "vb") == 0) || \
466           (strcmp(buf, "aj") == 0) || \
467           (strcmp(buf, "av") == 0);
468}
469
470static void
471insert_text_with_tags (GtkTextBuffer *buffer, GtkTextIter *iter, gchar *p, gint len,
472                       gboolean bold, gboolean italic, gboolean underline) {
473       
474        GtkTextMark *mark;
475        GtkTextIter start;
476       
477        mark = gtk_text_buffer_create_mark (buffer, "start_insert", iter, TRUE);
478        gtk_text_buffer_insert (buffer, iter, p, len);
479        gtk_text_buffer_get_iter_at_mark (buffer, &start, mark);
480        gtk_text_buffer_delete_mark (buffer, mark);
481        if (bold)
482                gtk_text_buffer_apply_tag_by_name (buffer, "bold", &start, iter);
483        if (italic)
484                gtk_text_buffer_apply_tag_by_name (buffer, "italic", &start, iter);
485        if (underline)
486                gtk_text_buffer_apply_tag_by_name (buffer, "underline", &start, iter);
487                               
488}
489
490/* defbox_add
491 *
492 * Adds a definition to the defbox, performing all necessary formatting
493 */
494
495static void
496defbox_add (GDictDefbox *defbox, gchar *def) {
497    GtkTextBuffer *buffer;
498    GtkTextIter iter, prev_iter;
499    gchar *p;
500    gint len;
501    GdkFont *font;
502    GdkColor *color;
503    gboolean italic, bold, underline;
504
505    buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (defbox));
506    gtk_text_buffer_get_end_iter (buffer, &iter);
507   
508    gtk_text_buffer_insert (buffer, &iter, "\n", -1);
509         
510    font = gdict_pref.typefaces[TYPEFACE_HEADWORD].font;
511    color = gdict_pref.typefaces[TYPEFACE_HEADWORD].color;
512
513    p = defbox->def_cmd->db_full_name;
514    len = strlen(p);
515
516    gtk_text_buffer_insert (buffer, &iter, p, len);
517
518    p = def;
519    len = strcspn(def, " ");
520   
521    bold = TRUE;
522    italic = FALSE;
523    underline = TRUE; /* only for the header */
524
525    while (*p) {
526        /* Handle word token */
527        insert_text_with_tags (buffer, &iter, p, len, bold, italic, underline);
528       
529        if ((font == gdict_pref.typefaces[TYPEFACE_HEADWORD].font) || \
530            (font == gdict_pref.typefaces[TYPEFACE_NUMBER].font) || \
531            (font == gdict_pref.typefaces[TYPEFACE_PART].font) || \
532            (font == gdict_pref.typefaces[TYPEFACE_XREF].font))
533        {
534            font = gdict_pref.typefaces[TYPEFACE_BODY].font;
535            color = gdict_pref.typefaces[TYPEFACE_BODY].color;
536            bold = FALSE;
537            italic = FALSE;
538            underline = FALSE;
539        }
540        p += len;
541       
542        /* ... then handle spaces ... */
543        len = strspn(p, " ");
544       
545        if (len > 0) {
546            insert_text_with_tags (buffer, &iter, p, len, bold, italic, underline);
547        }
548#if 0
549        if (len > 0)
550            gtk_text_insert (GTK_TEXT (defbox),  font, color, NULL, p, len);
551#endif
552        p += len;
553
554        /* ... handle special characters ... */
555        if (*p == '\\') {
556            /*font = (font == gdict_pref.typefaces[TYPEFACE_BODY].font) ? \
557                gdict_pref.typefaces[TYPEFACE_PRONUNCIATION].font : \
558                gdict_pref.typefaces[TYPEFACE_BODY].font;*/
559            color = (color == gdict_pref.typefaces[TYPEFACE_BODY].color) ? \
560                gdict_pref.typefaces[TYPEFACE_PRONUNCIATION].color : \
561                gdict_pref.typefaces[TYPEFACE_BODY].color;
562            if (font == gdict_pref.typefaces[TYPEFACE_BODY].font) {
563                font = gdict_pref.typefaces[TYPEFACE_PRONUNCIATION].font;
564                bold = FALSE;
565                italic = TRUE;
566                underline = FALSE;
567            }
568            else {
569                font = gdict_pref.typefaces[TYPEFACE_BODY].font;
570                bold = FALSE;
571                italic = FALSE;
572                underline = FALSE;
573            }
574            ++p;
575        } else if (*p == '[') {
576            font = gdict_pref.typefaces[TYPEFACE_ETYMOLOGY].font;
577            color = gdict_pref.typefaces[TYPEFACE_ETYMOLOGY].color;
578            bold = FALSE;
579            italic = TRUE;
580            underline = FALSE;
581            ++p;
582        } else if (*p == '{') {
583            font = gdict_pref.typefaces[TYPEFACE_EXAMPLE].font;
584            color = gdict_pref.typefaces[TYPEFACE_EXAMPLE].color;
585            bold = FALSE;
586            italic = TRUE;
587            underline = FALSE;
588            ++p;
589        } else if ((*p == ']') || (*p == '}')) {
590            font = gdict_pref.typefaces[TYPEFACE_BODY].font;
591            color = gdict_pref.typefaces[TYPEFACE_BODY].color;
592            bold = FALSE;
593            italic = FALSE;
594            underline = FALSE;
595            ++p;
596        }
597       
598        len = strcspn (p, " \\[]{}");
599
600        if (font == gdict_pref.typefaces[TYPEFACE_BODY].font) {
601            if (is_xref(p, len)) {
602                font = gdict_pref.typefaces[TYPEFACE_XREF].font;
603                color = gdict_pref.typefaces[TYPEFACE_XREF].color;
604                bold = FALSE;
605                italic = FALSE;
606                underline = FALSE;
607            } else if (is_number(p, len)) {
608                font = gdict_pref.typefaces[TYPEFACE_NUMBER].font;
609                color = gdict_pref.typefaces[TYPEFACE_NUMBER].color;
610                bold = TRUE;
611                italic = FALSE;
612                underline = FALSE;
613            } else if (is_part(p, len)) {
614                font = gdict_pref.typefaces[TYPEFACE_PART].font;
615                color = gdict_pref.typefaces[TYPEFACE_PART].color;
616                bold = FALSE;
617                italic = FALSE;
618                underline = FALSE;
619            }
620        }
621    }   
622   
623}
624
625/* def_error_cb
626 *
627 * Callback invoked when there was an error in the last query
628 */
629
630static void
631def_error_cb (dict_command_t *command, DictStatusCode code,
632              gchar *message, gpointer data)
633{
634    GtkObject *defbox;
635    dict_command_t *sec_cmd;
636    gchar *string;
637   
638    defbox = GTK_OBJECT (data);
639   
640    if (code != DICT_SOCKET_ERROR) {
641        GtkWidget *dialog;
642       
643        string = g_strdup_printf (_("Error invoking query: %s"), message);
644        dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_DESTROY_WITH_PARENT,
645                                         GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
646                                         "%s", string, NULL);
647        gtk_dialog_run (GTK_DIALOG (dialog));
648        gtk_widget_destroy (dialog);
649       
650        g_free (string);
651        sec_cmd = dict_disconnect_command_new ();
652        dict_command_invoke (sec_cmd, command->context);
653       
654        gtk_signal_emit (defbox, gdict_defbox_signals[WORD_LOOKUP_DONE_SIGNAL]);
655    }
656    else {
657        gtk_signal_emit (defbox, gdict_defbox_signals[SOCKET_ERROR_SIGNAL],
658                         message);
659    }
660}
661
662/* def_data_cb
663 *
664 * Callback used when a new definition has arrived over the link
665 */
666
667static void
668def_data_cb (dict_command_t *command, dict_res_t *res, gpointer data) {
669    GDictDefbox *defbox;
670   
671    defbox = GDICT_DEFBOX (data);
672    defbox_add (defbox, res->desc);
673}
674
675/* def_status_cb
676 *
677 * Callback used when a status code has arrived over the link
678 */
679
680static void
681def_status_cb (dict_command_t *command, DictStatusCode code,
682               int num_found, gpointer data)
683{
684    GtkObject *defbox;
685   
686    defbox = GTK_OBJECT (data);
687   
688    if (code == DICT_STATUS_OK)
689      gtk_signal_emit (defbox, gdict_defbox_signals[WORD_LOOKUP_DONE_SIGNAL]);
690    else if (code == DICT_STATUS_NO_MATCH)
691      gtk_signal_emit (defbox, gdict_defbox_signals[WORD_NOT_FOUND_SIGNAL]);
692}
693
694#ifdef HAVE_GNOME_PRINT
695
696/* get_line
697 *
698 * Formats a single line of text for printing and returns it
699 */
700
701static GnomeTextLine *
702get_line (const char *fontlist, const char *string, double size) {
703    GnomeTextAttrEl attrs[4];
704    int n_chars, i;
705    GnomeTextLayout *layout;
706    GnomeTextLine *line;
707
708    n_chars = 0;
709    for (i = 0; string[i]; i++)
710      if ((string[i] & 0xc0) != 0x80)
711        n_chars++;
712
713    i = 0;
714    attrs[i].char_pos = 0;
715    attrs[i].attr = GNOME_TEXT_FONT_LIST;
716    attrs[i++].attr_val = gnome_text_intern_font_list (fontlist);
717    attrs[i].char_pos = 0;
718    attrs[i].attr = GNOME_TEXT_SIZE;
719    attrs[i++].attr_val = floor (size * 1000 + 0.5);
720    attrs[i].char_pos = n_chars;
721    attrs[i].attr = GNOME_TEXT_END;
722    attrs[i++].attr_val = 0;
723
724    layout = gnome_text_layout_new (string, attrs);
725
726    line = gnome_text_line_from_layout (layout);
727
728    gnome_text_layout_free (layout);
729
730    return line;
731}
732
733#endif /* HAVE_GNOME_PRINT */
Note: See TracBrowser for help on using the repository browser.