diff options
author | Behdad Esfahbod <behdad@gnome.org> | 2006-02-01 17:10:29 +0000 |
---|---|---|
committer | Behdad Esfahbod <behdad@src.gnome.org> | 2006-02-01 17:10:29 +0000 |
commit | eda8c1ea592c855cc675d7a37dd5b6937c5e996f (patch) | |
tree | 6bae99df2ed2d3d971999b1862eab4befa1aa873 /examples | |
parent | 30e32899299ab73c3ffa5bb4fd5c4a80f6a3b525 (diff) | |
download | pango-eda8c1ea592c855cc675d7a37dd5b6937c5e996f.tar.gz |
Removed.
2006-02-01 Behdad Esfahbod <behdad@gnome.org>
* examples/viewer.c: Removed.
Diffstat (limited to 'examples')
-rw-r--r-- | examples/viewer.c | 709 |
1 files changed, 0 insertions, 709 deletions
diff --git a/examples/viewer.c b/examples/viewer.c deleted file mode 100644 index 6fd698b0..00000000 --- a/examples/viewer.c +++ /dev/null @@ -1,709 +0,0 @@ -/* Pango - * viewer.c: Example program to view a UTF-8 encoding file - * using Pango to render result. - * - * Copyright (C) 1999 Red Hat Software - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include <gtk/gtk.h> -#include <gdk/gdkx.h> - -#include <pango/pango.h> -#include <pango/pangox.h> - -#include <unistd.h> -#include <fcntl.h> -#include <errno.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -#define BUFSIZE 1024 - -typedef struct _Paragraph Paragraph; - -/* Structure representing a paragraph - */ -struct _Paragraph { - char *text; - int length; - int height; /* Height, in pixels */ - PangoLayout *layout; -}; - -GList *paragraphs; - -static PangoFontDescription *font_description; -static Paragraph *highlight_para; -static int highlight_offset; - -GtkWidget *styles_combo; - -static GtkWidget *message_label; -GtkWidget *layout; - -PangoContext *context; - -static void fill_styles_combo (GtkWidget *combo); - -/* Read an entire file into a string - */ -static char * -read_file(char *name) -{ - GString *inbuf; - int fd; - char *text; - char buffer[BUFSIZE]; - - fd = open(name, O_RDONLY); - if (!fd) - { - fprintf(stderr, "gscript-viewer: Cannot open %s: %s\n", - name, g_strerror (errno)); - return NULL; - } - - inbuf = g_string_new (NULL); - while (1) - { - int count = read (fd, buffer, BUFSIZE-1); - if (count < 0) - { - fprintf(stderr, "gscript-viewer: Error reading %s: %s\n", - name, g_strerror (errno)); - g_string_free (inbuf, TRUE); - return NULL; - } - else if (count == 0) - break; - - buffer[count] = '\0'; - - g_string_append (inbuf, buffer); - } - - close (fd); - - text = inbuf->str; - g_string_free (inbuf, FALSE); - - return text; -} - -/* Take a UTF8 string and break it into paragraphs on \n characters - */ -static GList * -split_paragraphs (char *text) -{ - char *p = text; - char *next; - gunichar wc; - GList *result = NULL; - char *last_para = text; - - while (*p) - { - wc = g_utf8_get_char (p); - next = g_utf8_next_char (p); - if (wc == (gunichar)-1) - { - fprintf (stderr, "gscript-viewer: Invalid character in input\n"); - g_list_foreach (result, (GFunc)g_free, NULL); - return NULL; - } - if (!*p || !wc || wc == '\n') - { - Paragraph *para = g_new (Paragraph, 1); - para->text = last_para; - para->length = p - last_para; - para->layout = pango_layout_new (context); - pango_layout_set_text (para->layout, para->text, para->length); - para->height = 0; - - last_para = next; - - result = g_list_prepend (result, para); - } - if (!wc) /* incomplete character at end */ - break; - p = next; - } - - return g_list_reverse (result); -} - -/* Given an x-y position, return the paragraph and offset - * within the paragraph of the click. - */ -gboolean -xy_to_cp (int width, int x, int y, Paragraph **para_return, int *index) -{ - GList *para_list; - int height = 0; - - *para_return = NULL; - - para_list = paragraphs; - while (para_list && height < y) - { - Paragraph *para = para_list->data; - - if (height + para->height >= y) - { - gboolean result = pango_layout_xy_to_index (para->layout, x * 1000, (y - height) * 1000, - index, NULL); - if (result && para_return) - *para_return = para; - - return result; - } - - height += para->height; - para_list = para_list->next; - } - - return FALSE; -} - -/* Given a paragraph and offset in that paragraph, find the - * bounding rectangle for the character at the offset. - */ -void -char_bounds (Paragraph *para, int index, int width, PangoRectangle *rect) -{ - GList *para_list; - - int height = 0; - - para_list = paragraphs; - while (para_list) - { - Paragraph *cur_para = para_list->data; - - if (cur_para == para) - { - PangoRectangle pos; - - pango_layout_index_to_pos (cur_para->layout, index, &pos); - - rect->x = MIN (pos.x, pos.x + pos.width) / 1000; - rect->width = ABS (pos.width) / 1000; - rect->y = height + pos.y / 1000; - rect->height = pos.height / 1000; - } - - height += cur_para->height; - para_list = para_list->next; - } -} - -/* XOR a rectangle over a given character - */ -void -xor_char (GtkWidget *layout, GdkRectangle *clip_rect, - Paragraph *para, int offset) -{ - static GdkGC *gc; - PangoRectangle rect; /* GdkRectangle in 1.2 is too limited - */ - if (!gc) - { - GdkGCValues values; - values.foreground = layout->style->white.pixel ? - layout->style->white : layout->style->black; - values.function = GDK_XOR; - gc = gdk_gc_new_with_values (GTK_LAYOUT (layout)->bin_window, - &values, - GDK_GC_FOREGROUND | GDK_GC_FUNCTION); - } - - gdk_gc_set_clip_rectangle (gc, clip_rect); - - char_bounds (para, offset, layout->allocation.width, &rect); - - rect.y -= GTK_LAYOUT (layout)->yoffset; - - if ((rect.y + rect.height >= 0) && (rect.y < layout->allocation.height)) - gdk_draw_rectangle (GTK_LAYOUT (layout)->bin_window, gc, TRUE, - rect.x, rect.y, rect.width, rect.height); -} - -/* Handle a size allocation by re-laying-out each paragraph to - * the new width, setting the new size for the layout and - * then queing a redraw - */ -void -size_allocate (GtkWidget *layout, GtkAllocation *allocation) -{ - GList *tmp_list; - int height = 0; - PangoDirection base_dir = pango_context_get_base_dir (context); - - tmp_list = paragraphs; - while (tmp_list) - { - Paragraph *para = tmp_list->data; - PangoRectangle logical_rect; - - tmp_list = tmp_list->next; - - pango_layout_set_alignment (para->layout, - base_dir == PANGO_DIRECTION_LTR ? PANGO_ALIGN_LEFT : PANGO_ALIGN_RIGHT); - pango_layout_set_width (para->layout, layout->allocation.width * 1000); - - pango_layout_get_extents (para->layout, NULL, &logical_rect); - para->height = logical_rect.height / 1000; - - height += para->height; - } - - gtk_layout_set_size (GTK_LAYOUT (layout), allocation->width, height); - - if (GTK_LAYOUT (layout)->yoffset + allocation->height > height) - gtk_adjustment_set_value (GTK_LAYOUT (layout)->vadjustment, height - allocation->height); -} - -/* Handle a draw/expose by finding the paragraphs that intersect - * the region and reexposing them. - */ -void -draw (GtkWidget *layout, GdkRectangle *area) -{ - GList *tmp_list; - int height = 0; - - gdk_draw_rectangle (GTK_LAYOUT (layout)->bin_window, - layout->style->base_gc[layout->state], - TRUE, - area->x, area->y, - area->width, area->height); - - gdk_gc_set_clip_rectangle (layout->style->text_gc[layout->state], area); - - tmp_list = paragraphs; - while (tmp_list && - height < area->y + area->height + GTK_LAYOUT (layout)->yoffset) - { - Paragraph *para = tmp_list->data; - tmp_list = tmp_list->next; - - if (height + para->height >= GTK_LAYOUT (layout)->yoffset + area->y) - pango_x_render_layout (GDK_DISPLAY(), GDK_WINDOW_XWINDOW (GTK_LAYOUT (layout)->bin_window), - GDK_GC_XGC (layout->style->text_gc[GTK_STATE_NORMAL]), - para->layout, 0, height - GTK_LAYOUT (layout)->yoffset); - - height += para->height; - } - - gdk_gc_set_clip_rectangle (layout->style->text_gc[layout->state], NULL); - - if (highlight_para) - xor_char (layout, area, highlight_para, highlight_offset); -} - -gboolean -expose (GtkWidget *layout, GdkEventExpose *event) -{ - if (event->window == GTK_LAYOUT (layout)->bin_window) - draw (layout, &event->area); - - return TRUE; -} - -void -button_press (GtkWidget *layout, GdkEventButton *event) -{ - Paragraph *para = NULL; - int offset; - gchar *message; - - xy_to_cp (layout->allocation.width, - event->x, event->y + GTK_LAYOUT (layout)->yoffset, - ¶, &offset); - - if (highlight_para) - xor_char (layout, NULL, highlight_para, highlight_offset); - - highlight_para = para; - highlight_offset = offset; - - if (para) - { - gunichar wc; - - wc = g_utf8_get_char (para->text + offset); - message = g_strdup_printf ("Current char: U%04x", wc); - - xor_char (layout, NULL, highlight_para, highlight_offset); - } - else - message = g_strdup_printf ("Current char:"); - - gtk_label_set_text (GTK_LABEL (message_label), message); - g_free (message); -} - -static void -checkbutton_toggled (GtkWidget *widget, gpointer data) -{ - GList *para_list; - - pango_context_set_base_dir (context, GTK_TOGGLE_BUTTON (widget)->active ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR); - - para_list = paragraphs; - while (para_list) - { - Paragraph *para = para_list->data; - - pango_layout_context_changed (para->layout); - para_list = para_list->next; - } - - gtk_widget_queue_resize (layout); -} - -static void -reload_font () -{ - GList *para_list; - - pango_context_set_font_description (context, &font_description); - - para_list = paragraphs; - while (para_list) - { - Paragraph *para = para_list->data; - - pango_layout_context_changed (para->layout); - para_list = para_list->next; - } - - if (layout) - gtk_widget_queue_resize (layout); -} - -void -set_family (GtkWidget *entry, gpointer data) -{ - pango_font_description_set_family (font_description, gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1)); - fill_styles_combo (styles_combo); -} - -void -set_style (GtkWidget *entry, gpointer data) -{ - char *str = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1); - PangoFontDescription *tmp_desc; - - tmp_desc = pango_font_description_from_string (str); - - pango_font_description_set_style (font_description, pango_font_description_get_style (tmp_desc)); - pango_font_description_set_variant (font_description, pango_font_description_get_variant (tmp_desc)); - pango_font_description_set_weight (font_description, pango_font_description_get_weight (tmp_desc)); - pango_font_description_set_stretch (font_description, pango_font_description_get_stretch (tmp_desc)); - - pango_font_description_free (tmp_desc); - g_free (str); - - reload_font (); -} - -void -font_size_changed (GtkAdjustment *adj) -{ - pango_font_description_set_size (font_description, (int)(adj->value * PANGO_SCALE + 0.5)); - reload_font(); -} - -static int -compare_font_descriptions (const PangoFontDescription *a, const PangoFontDescription *b) -{ - int val = strcmp (a->family_name, b->family_name); - if (val != 0) - return val; - - if (a->weight != b->weight) - return a->weight - b->weight; - - if (a->style != b->style) - return a->style - b->style; - - if (a->stretch != b->stretch) - return a->stretch - b->stretch; - - if (a->variant != b->variant) - return a->variant - b->variant; - - return 0; -} - -static int -font_description_sort_func (const void *a, const void *b) -{ - return compare_font_descriptions (*(PangoFontDescription **)a, *(PangoFontDescription **)b); -} - -typedef struct -{ - PangoFontDescription **descs; - int n_descs; -} FontDescInfo; - -static void -free_info (FontDescInfo *info) -{ - pango_font_descriptions_free (info->descs, info->n_descs); -} - -static void -fill_styles_combo (GtkWidget *combo) -{ - int i; - GList *style_list = NULL; - - FontDescInfo *info = g_new (FontDescInfo, 1); - pango_context_list_fonts (context, pango_font_description_get_family (font_description), &info->descs, &info->n_descs); - gtk_object_set_data_full (GTK_OBJECT (combo), "descs", info, (GtkDestroyNotify)free_info); - - qsort (info->descs, info->n_descs, sizeof(PangoFontDescription *), font_description_sort_func); - - for (i=0; i<info->n_descs; i++) - { - char *str; - - PangoFontDescription *tmp_desc; - - tmp_desc = *info->descs[i]; - tmp_desc.family_name = NULL; - tmp_desc.size = 0; - - str = pango_font_description_to_string (tmp_desc); - style_list = g_list_prepend (style_list, str); - } - - style_list = g_list_reverse (style_list); - - gtk_combo_set_popdown_strings (GTK_COMBO (combo), style_list); - g_list_foreach (style_list, (GFunc)g_free, NULL); -} - -static GtkWidget * -make_styles_combo () -{ - GtkWidget *combo; - - combo = gtk_combo_new (); - gtk_combo_set_value_in_list (GTK_COMBO (combo), TRUE, FALSE); - gtk_editable_set_editable (GTK_EDITABLE (GTK_COMBO (combo)->entry), FALSE); - - gtk_signal_connect (GTK_OBJECT (GTK_COMBO (combo)->entry), "changed", - GTK_SIGNAL_FUNC (set_style), NULL); - - styles_combo = combo; - fill_styles_combo (combo); - - return combo; -} - -static int -cmp_strings (const void *a, const void *b) -{ - return strcmp (*(const char **)a, *(const char **)b); -} - -GtkWidget * -make_families_menu () -{ - GtkWidget *combo; - gchar **families; - int n_families; - GList *family_list = NULL; - int i; - - pango_context_list_families (context, &families, &n_families); - qsort (families, n_families, sizeof(char *), cmp_strings); - - for (i=0; i<n_families; i++) - family_list = g_list_prepend (family_list, families[i]); - - family_list = g_list_reverse (family_list); - - combo = gtk_combo_new (); - gtk_combo_set_popdown_strings (GTK_COMBO (combo), family_list); - gtk_combo_set_value_in_list (GTK_COMBO (combo), TRUE, FALSE); - gtk_editable_set_editable (GTK_EDITABLE (GTK_COMBO (combo)->entry), FALSE); - - gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (combo)->entry), pango_font_description_get_family (font_description)); - - gtk_signal_connect (GTK_OBJECT (GTK_COMBO (combo)->entry), "changed", - GTK_SIGNAL_FUNC (set_family), NULL); - - g_list_free (family_list); - pango_font_map_free_families (families, n_families); - - return combo; -} - - -GtkWidget * -make_font_selector (void) -{ - GtkWidget *hbox; - GtkWidget *util_hbox; - GtkWidget *label; - GtkWidget *option_menu; - GtkWidget *spin_button; - GtkAdjustment *adj; - - hbox = gtk_hbox_new (FALSE, 4); - - util_hbox = gtk_hbox_new (FALSE, 2); - label = gtk_label_new ("Family:"); - gtk_box_pack_start (GTK_BOX (util_hbox), label, FALSE, FALSE, 0); - option_menu = make_families_menu (); - gtk_box_pack_start (GTK_BOX (util_hbox), option_menu, FALSE, FALSE, 0); - - gtk_box_pack_start (GTK_BOX (hbox), util_hbox, FALSE, FALSE, 0); - - util_hbox = gtk_hbox_new (FALSE, 2); - label = gtk_label_new ("Style:"); - gtk_box_pack_start (GTK_BOX (util_hbox), label, FALSE, FALSE, 0); - option_menu = make_styles_combo (); - gtk_box_pack_start (GTK_BOX (util_hbox), option_menu, FALSE, FALSE, 0); - - gtk_box_pack_start (GTK_BOX (hbox), util_hbox, FALSE, FALSE, 0); - - util_hbox = gtk_hbox_new (FALSE, 2); - label = gtk_label_new ("Size:"); - gtk_box_pack_start (GTK_BOX (util_hbox), label, FALSE, FALSE, 0); - spin_button = gtk_spin_button_new (NULL, 1., 0); - gtk_box_pack_start (GTK_BOX (util_hbox), spin_button, FALSE, FALSE, 0); - - gtk_box_pack_start (GTK_BOX (hbox), util_hbox, FALSE, FALSE, 0); - - adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin_button)); - adj->value = pango_font_description_get_size (font_description) / (1.*PANGO_SCALE); - adj->lower = 0; - adj->upper = 1024; - adj->step_increment = 1; - adj->page_size = 10; - gtk_adjustment_changed (adj); - gtk_adjustment_value_changed (adj); - - gtk_signal_connect (GTK_OBJECT (adj), "value_changed", - GTK_SIGNAL_FUNC (font_size_changed), NULL); - - return hbox; -} - -int -main (int argc, char **argv) -{ - char *text; - GtkWidget *window; - GtkWidget *scrollwin; - GtkWidget *vbox, *hbox; - GtkWidget *frame; - GtkWidget *checkbutton; - - gtk_init (&argc, &argv); - - if (argc != 2) - { - fprintf (stderr, "Usage: gscript-viewer FILE\n"); - exit(1); - } - - /* Create the list of paragraphs from the supplied file - */ - text = read_file (argv[1]); - if (!text) - exit(1); - - context = pango_x_get_context (GDK_DISPLAY()); - - paragraphs = split_paragraphs (text); - - pango_context_set_lang (context, "en_US"); - pango_context_set_base_dir (context, PANGO_DIRECTION_LTR); - - pango_font_description_set_family_static (font_description, "sans"); - pango_font_description_set_style (font_description, PANGO_STYLE_NORMAL); - pango_font_description_set_variant (font_description, PANGO_VARIANT_NORMAL); - pango_font_description_set_weight (font_description, 500); - pango_font_description_set_stretch (font_description, PANGO_STRETCH_NORMAL); - pango_font_description_set_size (font_description, 16000); - - pango_context_set_font_description (context, &font_description); - - /* Create the user interface - */ - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_window_set_default_size (GTK_WINDOW (window), 400, 400); - - gtk_signal_connect (GTK_OBJECT (window), "destroy", - GTK_SIGNAL_FUNC (gtk_main_quit), NULL); - - vbox = gtk_vbox_new (FALSE, 4); - gtk_container_add (GTK_CONTAINER (window), vbox); - - hbox = make_font_selector (); - gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); - - scrollwin = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollwin), - GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - - gtk_box_pack_start (GTK_BOX (vbox), scrollwin, TRUE, TRUE, 0); - - layout = gtk_layout_new (NULL, NULL); - gtk_widget_set_events (layout, GDK_BUTTON_PRESS_MASK); - gtk_widget_set_app_paintable (layout, TRUE); - - gtk_signal_connect (GTK_OBJECT (layout), "size_allocate", - GTK_SIGNAL_FUNC (size_allocate), paragraphs); - gtk_signal_connect (GTK_OBJECT (layout), "expose_event", - GTK_SIGNAL_FUNC (expose), paragraphs); - gtk_signal_connect (GTK_OBJECT (layout), "draw", - GTK_SIGNAL_FUNC (draw), paragraphs); - gtk_signal_connect (GTK_OBJECT (layout), "button_press_event", - GTK_SIGNAL_FUNC (button_press), paragraphs); - - gtk_container_add (GTK_CONTAINER (scrollwin), layout); - - frame = gtk_frame_new (NULL); - gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN); - gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); - - message_label = gtk_label_new ("Current char:"); - gtk_misc_set_padding (GTK_MISC (message_label), 1, 1); - gtk_misc_set_alignment (GTK_MISC (message_label), 0.0, 0.5); - gtk_container_add (GTK_CONTAINER (frame), message_label); - - checkbutton = gtk_check_button_new_with_label ("Use RTL global direction"); - gtk_signal_connect (GTK_OBJECT (checkbutton), "toggled", - GTK_SIGNAL_FUNC (checkbutton_toggled), NULL); - gtk_box_pack_start (GTK_BOX (vbox), checkbutton, FALSE, FALSE, 0); - - gtk_widget_show_all (window); - - gtk_main (); - - return 0; -} |