summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorTor Lillqvist <tml@iki.fi>2000-08-20 08:36:41 +0000
committerTor Lillqvist <tml@src.gnome.org>2000-08-20 08:36:41 +0000
commit79546feb86a232b0d3e01b1f436e258aef32b840 (patch)
treed35f417b2a3112bb3e0fb18d4fc057a37ab79f40 /examples
parente95590dd006740ab6bdcf71cae31efbf8404033e (diff)
downloadpango-79546feb86a232b0d3e01b1f436e258aef32b840.tar.gz
Add parameter telling whether to print warning or not if string isn't
2000-08-20 Tor Lillqvist <tml@iki.fi> * pango/pango-utils.c (pango_parse_*): Add parameter telling whether to print warning or not if string isn't recognised. Use g_strncasecmp(). * pango/pango-utils.h: Change prototype accordingly. * pango/pangox-fontmap.c * pango/pangowin32-fontmap.c: Change calls correspondingly. * pango/pangowin32.h: * pango/pangowin32.c: Cosmetic changes, dead code removal. * pango/pangoft2.h * pango/pangoft2-private.h * pango/pangoft2.c * pango/pangoft2-fontmap.c * pango/pangoft2-fontcache.c: New files implementing a FreeType2 backend. Used only on Win32 so far, but doesn't contain Win32-specific code per se, so if somebody wants to try it out on X11, too, be my guest. It works, more or less, but there are some details still to sort out. Performance needs to be improved. Debugging printouts still present. Font path currently hardcoded to C:\windows\fonts, heh. Owen says he doesn't think it's a good idea to use ths on Win32, but I'll try anyway. If it turns out using the native Win32 GDI backend is better after all, oh well. * pango/makefile.mingw: Delete. Move contents to makefile.mingw.in. * pango/makefile.mingw.in: New file. Add rules for FreeType2 backend. Add FreeType2 CFLAGS and LIBS. * pango/Makefile.am: Generate makefile.mingw. (EXTRA_DIST): Add FreeType2 backend sources, and makefile.mingw{,.in} * modules/basic/basic-win32.c: Couple of cosmetic changes. * modules/basic/Makefile.am: Generate makefile.mingw. (EXTRA_DIST): Add basic-ft2.c, and makefile.mingw{,.in} * modules/basic/makefile.mingw: Delete. Move contents to makefile.mingw.in. * modules/basic/makefile.mingw.in: New file. Add rule for basic-ft2. Add FreeType2 CFLAGS and LIBS. * examples/viewer-win32.c (read_file): Fix error messages. (draw): Get HDC from GDK once for all paragraphs. * examples/viewer-ft2.c: New file. The FT_Bitmap (256-level bitmap) produced by the FreeType2 backend is copied to the GtkLayout window using gdk_draw_gray_image from GdkRGB (!). Yes, this is kinda circular dependency between Pango and GTK+. * examples/makefile.mingw: Delete. Move contents to makefile.mingw.in. * examples/makefile.mingw.in: New file. Add rules for viewer-ft2. Add FreeType2 CFLAGS and LIBS. * examples/Makefile.am: Generate makefile.mingw. (EXTRA_DIST): Add viewer-win32.c and viewer-ft2.c, and makefile.mingw{,.in}
Diffstat (limited to 'examples')
-rw-r--r--examples/Makefile.am13
-rw-r--r--examples/makefile.mingw22
-rw-r--r--examples/makefile.mingw.in31
-rw-r--r--examples/viewer-ft2.c748
-rw-r--r--examples/viewer-win32.c28
5 files changed, 803 insertions, 39 deletions
diff --git a/examples/Makefile.am b/examples/Makefile.am
index 225498d1..2fbdfc1e 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -34,7 +34,18 @@ pango.modules:
( cd ../modules && \
../pango/pango-querymodules `find . -name '*.so'` > ../examples/pango.modules )
-EXTRA_DIST=HELLO.utf8 muru.utf pangox.aliases
+EXTRA_DIST= \
+ viewer-win32.c \
+ viewer-ft2.c \
+ makefile.mingw \
+ makefile.mingw.in \
+ HELLO.utf8 \
+ muru.utf \
+ pangox.aliases
alias_DATA = pangox.aliases
+makefile.mingw: $(top_builddir)/config.status $(top_srcdir)/examples/makefile.mingw.in
+ cd $(top_builddir) && CONFIG_FILES=examples/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
diff --git a/examples/makefile.mingw b/examples/makefile.mingw
deleted file mode 100644
index b20101d0..00000000
--- a/examples/makefile.mingw
+++ /dev/null
@@ -1,22 +0,0 @@
-PANGO_VER = 0.12
-
-TOP = ../..
-
-include $(TOP)/build/win32/make.mingw
-
-OPTIMIZE = -g
-
-INCLUDES = -I .. -I .
-DEFINES =
-DEPCFLAGS = $(GTK_CFLAGS) $(GLIB_CFLAGS)
-
-all : \
- ../config.h \
- viewer-win32.exe
-
-../config.h : ../config.h.win32
- cp $< $@
-
-viewer-win32.exe : viewer-win32.o
- $(CC) -o $@ $< $(OPTIMIZE) -L ../pango -lpango-$(PANGO_VER) -lpangowin32-$(PANGO_VER) $(GTK_LIBS) $(GLIB_LIBS) -gdi32
-
diff --git a/examples/makefile.mingw.in b/examples/makefile.mingw.in
new file mode 100644
index 00000000..cc086b78
--- /dev/null
+++ b/examples/makefile.mingw.in
@@ -0,0 +1,31 @@
+TOP = ../..
+
+include $(TOP)/build/win32/make.mingw
+
+# Possibly override Pango version from build/win32/module.defs
+PANGO_VER = @VERSION@
+
+OPTIMIZE = -g -Wall
+
+INCLUDES = -I .. -I .
+DEFINES =
+DEPCFLAGS = $(GTK_CFLAGS) $(GLIB_CFLAGS) $(FREETYPE2_CFLAGS)
+
+all : \
+ ../config.h \
+ viewer-win32.exe \
+ viewer-ft2.exe \
+
+../config.h : ../config.h.win32
+ cp $< $@
+
+viewer-win32.exe : viewer-win32.o
+ $(CC) -o $@ $< $(OPTIMIZE) -L ../pango -lpango-$(PANGO_VER) -lpangowin32-$(PANGO_VER) $(GTK_LIBS) $(GLIB_LIBS) -gdi32
+
+viewer-ft2.exe : viewer-ft2.o
+ $(CC) -mwindows -o $@ $< $(OPTIMIZE) -L ../pango -lpango-$(PANGO_VER) -lpangoft2-$(PANGO_VER) $(FREETYPE2_LIBS) $(GTK_LIBS) $(GLIB_LIBS)
+
+# Hack to get an updated makefile.mingw automatically after updating
+# makefile.mingw.in. Only for developer use.
+makefile.mingw: makefile.mingw.in
+ sed -e 's,@VER[S]ION@,@VERSION@,' <$< >$@
diff --git a/examples/viewer-ft2.c b/examples/viewer-ft2.c
new file mode 100644
index 00000000..d5235472
--- /dev/null
+++ b/examples/viewer-ft2.c
@@ -0,0 +1,748 @@
+/* Pango
+ * viewer-ft2.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/gdkrgb.h>
+
+#include <pango/pango.h>
+#include <pango/pangoft2.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;
+ FILE *file;
+ char *text;
+ char buffer[BUFSIZE];
+
+ file = fopen (name, "r");
+ if (!file)
+ {
+ fprintf (stderr, "%s: Cannot open %s\n", g_get_prgname (), name);
+ return NULL;
+ }
+
+ inbuf = g_string_new (NULL);
+ while (1)
+ {
+ char *bp = fgets (buffer, BUFSIZE-1, file);
+ if (ferror (file))
+ {
+ fprintf(stderr, "%s: Error reading %s\n", g_get_prgname (), name);
+ g_string_free (inbuf, TRUE);
+ return NULL;
+ }
+ else if (bp == NULL)
+ break;
+
+ g_string_append (inbuf, buffer);
+ }
+
+ fclose (file);
+
+ 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, "%s: Invalid character in input\n", g_get_prgname ());
+ 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;
+ GdkVisual *visual = gdk_drawable_get_visual (GTK_LAYOUT (layout)->bin_window);
+
+ g_assert (visual->type == GDK_VISUAL_GRAYSCALE ||
+ visual->type == GDK_VISUAL_TRUE_COLOR);
+
+ 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);
+#if 0
+ g_print ("viewer-ft2.c: draw: area: %dx%d, x:%d y:%d layout->yoffset:%d\n", area->width, area->height, area->x, area->y, GTK_LAYOUT (layout)->yoffset);
+#endif
+ 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 0
+ g_print (" para->height:%d\n", para->height);
+#endif
+ if (height + para->height >= GTK_LAYOUT (layout)->yoffset + area->y)
+ {
+ FT_Bitmap bitmap;
+ guchar *buf = g_malloc (area->width * para->height);
+
+ memset (buf, 0xFF, area->width * para->height);
+ bitmap.rows = para->height;
+ bitmap.width = area->width;
+ bitmap.pitch = bitmap.width;
+ bitmap.buffer = buf;
+ bitmap.num_grays = 256;
+ bitmap.pixel_mode = ft_pixel_mode_grays;
+
+ pango_ft2_render_layout (&bitmap, para->layout,
+ 0, 0);
+
+ gdk_draw_gray_image (GTK_LAYOUT (layout)->bin_window,
+ layout->style->text_gc[GTK_STATE_NORMAL],
+ 0, height - GTK_LAYOUT (layout)->yoffset,
+ bitmap.width, bitmap.rows,
+ GDK_RGB_DITHER_NORMAL,
+ bitmap.buffer,
+ bitmap.pitch);
+ g_free (buf);
+ }
+
+ 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,
+ &para, &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)
+{
+ font_description.family_name = 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);
+
+ font_description.style = tmp_desc->style;
+ font_description.variant = tmp_desc->variant;
+ font_description.weight = tmp_desc->weight;
+ font_description.stretch = tmp_desc->stretch;
+
+ pango_font_description_free (tmp_desc);
+ g_free (str);
+
+ reload_font ();
+}
+
+void
+font_size_changed (GtkAdjustment *adj)
+{
+ font_description.size = (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, font_description.family_name, &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), font_description.family_name);
+
+ 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 = font_description.size / 1000.;
+ 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);
+
+ gdk_rgb_init ();
+
+#if 0
+ if (argc != 2)
+ {
+ fprintf (stderr, "Usage: %s FILE\n", g_get_prgname ());
+ exit(1);
+ }
+
+ /* Create the list of paragraphs from the supplied file
+ */
+ text = read_file (argv[1]);
+#else
+ text = read_file ("koe2.txt");
+#endif
+ if (!text)
+ exit(1);
+
+ context = pango_ft2_get_context ();
+
+ paragraphs = split_paragraphs (text);
+
+ pango_context_set_lang (context, "en_US");
+ pango_context_set_base_dir (context, PANGO_DIRECTION_LTR);
+
+ font_description.family_name = g_strdup ("sans");
+ font_description.style = PANGO_STYLE_NORMAL;
+ font_description.variant = PANGO_VARIANT_NORMAL;
+ font_description.weight = PANGO_WEIGHT_NORMAL;
+ font_description.stretch = PANGO_STRETCH_NORMAL;
+ font_description.size = 24000;
+
+ 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;
+}
+
+int _stdcall
+WinMain (struct HINSTANCE__ *hInstance,
+ struct HINSTANCE__ *hPrevInstance,
+ char *lpszCmdLine,
+ int nCmdShow)
+{
+ return main (__argc, __argv);
+}
+
diff --git a/examples/viewer-win32.c b/examples/viewer-win32.c
index 969b6e9b..62086513 100644
--- a/examples/viewer-win32.c
+++ b/examples/viewer-win32.c
@@ -72,7 +72,7 @@ read_file(char *name)
file = fopen (name, "r");
if (!file)
{
- fprintf (stderr, "%s: Cannot open %s\n", g_get_prgname ());
+ fprintf (stderr, "%s: Cannot open %s\n", g_get_prgname (), name);
return NULL;
}
@@ -82,7 +82,7 @@ read_file(char *name)
char *bp = fgets (buffer, BUFSIZE-1, file);
if (ferror (file))
{
- fprintf(stderr, "%s: Error reading %s\n", g_get_prgname ());
+ fprintf (stderr, "%s: Error reading %s\n", g_get_prgname (), name);
g_string_free (inbuf, TRUE);
return NULL;
}
@@ -281,6 +281,8 @@ draw (GtkWidget *layout, GdkRectangle *area)
{
GList *tmp_list;
int height = 0;
+ HDC hdc;
+ const GdkGCValuesMask mask = GDK_GC_FOREGROUND|GDK_GC_BACKGROUND|GDK_GC_FONT;
gdk_draw_rectangle (GTK_LAYOUT (layout)->bin_window,
layout->style->base_gc[layout->state],
@@ -290,6 +292,9 @@ draw (GtkWidget *layout, GdkRectangle *area)
gdk_gc_set_clip_rectangle (layout->style->text_gc[layout->state], area);
+ hdc = gdk_win32_hdc_get (GTK_LAYOUT (layout)->bin_window,
+ layout->style->text_gc[GTK_STATE_NORMAL],
+ mask);
tmp_list = paragraphs;
while (tmp_list &&
height < area->y + area->height + GTK_LAYOUT (layout)->yoffset)
@@ -298,23 +303,14 @@ draw (GtkWidget *layout, GdkRectangle *area)
tmp_list = tmp_list->next;
if (height + para->height >= GTK_LAYOUT (layout)->yoffset + area->y)
- {
- GdkGCValuesMask mask = GDK_GC_FOREGROUND|GDK_GC_BACKGROUND|GDK_GC_FONT;
- HDC hdc;
-
- hdc = gdk_win32_hdc_get (GTK_LAYOUT (layout)->bin_window,
- layout->style->text_gc[GTK_STATE_NORMAL],
- mask);
- pango_win32_render_layout (hdc, para->layout,
- 0, height - GTK_LAYOUT (layout)->yoffset);
- gdk_win32_hdc_release (GTK_LAYOUT (layout)->bin_window,
- layout->style->text_gc[GTK_STATE_NORMAL],
- mask);
- }
-
+ pango_win32_render_layout (hdc, para->layout,
+ 0, height - GTK_LAYOUT (layout)->yoffset);
height += para->height;
}
+ gdk_win32_hdc_release (GTK_LAYOUT (layout)->bin_window,
+ layout->style->text_gc[GTK_STATE_NORMAL],
+ mask);
gdk_gc_set_clip_rectangle (layout->style->text_gc[layout->state], NULL);
if (highlight_para)