gwaterfall/0000755000175000001440000000000010232641172013141 5ustar ogiusers00000000000000gwaterfall/Makefile.am0000644000175000001440000000101610232641065015174 0ustar ogiusers00000000000000## ## $Id: Makefile.am,v 1.1 2003/04/28 02:45:45 nlevitt Exp $ ## ## Copyright (c) 2003 Noah Levitt ## ## This program is free software; the author gives unlimited permission to ## copy and/or distribute it, with or without modifications, as long as ## this notice is preserved. ## ## This program is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY, to the extent permitted by law; without even the ## implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ## SUBDIRS = src gwaterfall/autogen.sh0000644000175000001440000000236610232641113015141 0ustar ogiusers00000000000000#! /bin/sh # # $Id: autogen.sh,v 1.1 2003/04/28 02:45:45 nlevitt Exp $ # # runs autotools to create ./configure and friends # PROJECT=waterfall srcdir=`dirname "$0"` test -z $srcdir && srcdir=. origdir=`pwd` cd "$srcdir" if test -z "$AUTOGEN_SUBDIR_MODE" && test -z "$*" then echo "I am going to run ./configure with no arguments - if you wish " echo "to pass any to it, please specify them on the $0 command line." fi # Use the versioned executables if available. aclocal=aclocal-1.7 automake=automake-1.7 $aclocal --version /dev/null 2>&1 || aclocal=aclocal $automake --version /dev/null 2>&1 || automake=automake rm -f config.guess config.sub depcomp install-sh missing mkinstalldirs rm -f config.cache acconfig.h rm -rf autom4te.cache set_option=':' test -n "${BASH_VERSION+set}" && set_option='set' $set_option -x $aclocal $ACLOCAL_FLAGS || exit 1 libtoolize --force --copy || exit 1 autoheader || exit 1 $automake --foreign --add-missing --copy || exit 1 autoconf || exit 1 cd "$origdir" || exit 1 if test -z "$AUTOGEN_SUBDIR_MODE" then "$srcdir/configure" "$@" || exit 1 $set_option +x fi exit 0 gwaterfall/configure.ac0000644000175000001440000000157210232641137015435 0ustar ogiusers00000000000000dnl dnl $Id: configure.ac,v 1.1 2003/04/28 02:45:45 nlevitt Exp $ dnl dnl Copyright (c) 2003 Noah Levitt dnl dnl This program is free software; the author gives unlimited permission to dnl copy and/or distribute it, with or without modifications, as long as dnl this notice is preserved. dnl dnl This program is distributed in the hope that it will be useful, but dnl WITHOUT ANY WARRANTY, to the extent permitted by law; without even the dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. dnl AC_PREREQ([2.50]) AC_INIT([waterfall], [0.1]) AM_CONFIG_HEADER([config.h]) AM_INIT_AUTOMAKE([waterfall], [0.1]) # checks for progs AC_PROG_LIBTOOL # no need to check for fontconfig, xft brings it in PKG_CHECK_MODULES(WATERFALL, gtk+-2.0 >= 2.2.0 xft >= 2.0.0) AC_SUBST(WATERFALL_CFLAGS) AC_SUBST(WATERFALL_LIBS) AC_OUTPUT([Makefile src/Makefile]) gwaterfall/.cvsignore0000644000175000001440000000030310232641164015136 0ustar ogiusers00000000000000Makefile Makefile.in aclocal.m4 autom4te.cache config.guess config.h config.h.in config.log config.status config.sub configure depcomp install-sh libtool ltmain.sh missing mkinstalldirs stamp-h1 gwaterfall/src/0000755000175000001440000000000010232641247013733 5ustar ogiusers00000000000000gwaterfall/src/Makefile.am0000644000175000001440000000122210232641310015753 0ustar ogiusers00000000000000## ## $Id: Makefile.am,v 1.1 2003/04/28 02:45:45 nlevitt Exp $ ## ## Copyright (c) 2003 Noah Levitt ## ## This program is free software; the author gives unlimited permission to ## copy and/or distribute it, with or without modifications, as long as ## this notice is preserved. ## ## This program is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY, to the extent permitted by law; without even the ## implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ## AM_CFLAGS = $(WATERFALL_CFLAGS) bin_PROGRAMS = waterfall waterfall_SOURCES = main.c waterfall.c waterfall.h waterfall_LDADD = @WATERFALL_LIBS@ gwaterfall/src/.cvsignore0000644000175000001440000000005310232641311015721 0ustar ogiusers00000000000000.deps .libs Makefile Makefile.in waterfall gwaterfall/src/main.c0000644000175000001440000004602510232641313015024 0ustar ogiusers00000000000000/* * $Id: main.c,v 1.4 2003/04/29 03:09:45 nlevitt Exp $ * * Copyright (c) 2003 Noah Levitt * * This program is free software; the author gives unlimited permission to * copy and/or distribute it, with or without modifications, as long as * this notice is preserved. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include static GtkWidget *page_label = NULL; static GtkWidget *style_combo = NULL; static GtkWidget *autohint_check_button = NULL; static GtkWidget *rgba_hbox = NULL; static void set_style_choices (Waterfall *waterfall) { FcObjectSet *set; FcPattern *pattern; FcFontSet *list; GList *styles = NULL; FcChar8 *style; gint i; if (style_combo == NULL) return; set = FcObjectSetBuild (FC_STYLE, 0); pattern = FcPatternBuild (0, FC_FAMILY, FcTypeString, waterfall_get_font_family (waterfall), 0); g_assert (pattern != NULL); list = FcFontList (0, pattern, set); FcPatternDestroy (pattern); for (i = 0; i < list->nfont; i++) { FcPatternGetString (list->fonts[i], FC_STYLE, 0, &style); styles = g_list_append (styles, style); } if (styles) gtk_combo_set_popdown_strings (GTK_COMBO (style_combo), styles); FcFontSetDestroy (list); } static void family_changed (GtkEntry *entry, Waterfall *waterfall) { const gchar *new_family = gtk_entry_get_text (entry); /* ignore empty string (it sends these a lot) */ if (new_family[0] == '\0') return; waterfall_set_font_family (waterfall, new_family); set_style_choices (waterfall); } static void style_changed (GtkEntry *entry, Waterfall *waterfall) { const gchar *new_style = gtk_entry_get_text (entry); /* ignore empty string (it sends these a lot) */ if (new_style[0] == '\0') return; waterfall_set_font_style (waterfall, new_style); } static GtkWidget * construct_font_family_chooser (Waterfall *waterfall) { GtkWidget *combo; FcFontSet *list; FcObjectSet *set = FcObjectSetBuild (FC_FAMILY, 0); FcPattern *pattern = FcPatternCreate (); GList *family_names = NULL; FcChar8 *family_name; int i; combo = gtk_combo_new (); gtk_widget_show (combo); gtk_editable_set_editable (GTK_EDITABLE (GTK_COMBO (combo)->entry), FALSE); g_signal_connect (GTK_COMBO (combo)->entry, "changed", G_CALLBACK (family_changed), waterfall); list = FcFontList (0, pattern, set); FcObjectSetDestroy (set); FcPatternDestroy (pattern); g_assert (list->nfont > 0); for (i = 0; i < list->nfont; i++) { FcPatternGetString (list->fonts[i], FC_FAMILY, 0, &family_name); family_names = g_list_append (family_names, family_name); } /* family_names = g_list_append (family_names, "Serif"); family_names = g_list_append (family_names, "Sans"); family_names = g_list_append (family_names, "Monospace"); */ family_names = g_list_sort (family_names, (GCompareFunc) FcStrCmpIgnoreCase); gtk_combo_set_popdown_strings (GTK_COMBO (combo), family_names); g_list_free (family_names); FcFontSetDestroy (list); return combo; } static GtkWidget * construct_font_style_chooser (Waterfall *waterfall) { style_combo = gtk_combo_new (); gtk_widget_show (style_combo); gtk_editable_set_editable (GTK_EDITABLE (GTK_COMBO (style_combo)->entry), FALSE); g_signal_connect (GTK_COMBO (style_combo)->entry, "changed", G_CALLBACK (style_changed), waterfall); set_style_choices (waterfall); return style_combo; } static void hint_toggled (GtkToggleButton *toggle_button, Waterfall *waterfall) { waterfall_set_hint (waterfall, gtk_toggle_button_get_active (toggle_button)); gtk_widget_set_sensitive (autohint_check_button, gtk_toggle_button_get_active (toggle_button)); } static void autohint_toggled (GtkToggleButton *toggle_button, Waterfall *waterfall) { waterfall_set_autohint (waterfall, gtk_toggle_button_get_active (toggle_button)); } static void antialias_toggled (GtkToggleButton *toggle_button, Waterfall *waterfall) { waterfall_set_antialias (waterfall, gtk_toggle_button_get_active (toggle_button)); gtk_widget_set_sensitive (rgba_hbox, waterfall_get_antialias (waterfall)); } static void min_size_changed (GtkAdjustment *adjustment, Waterfall *waterfall) { waterfall_set_min_size (waterfall, gtk_adjustment_get_value (adjustment)); } static void max_size_changed (GtkAdjustment *adjustment, Waterfall *waterfall) { waterfall_set_max_size (waterfall, gtk_adjustment_get_value (adjustment)); } static void increment_changed (GtkAdjustment *adjustment, Waterfall *waterfall) { waterfall_set_increment (waterfall, gtk_adjustment_get_value (adjustment)); } static void aspect_changed (GtkAdjustment *adjustment, Waterfall *waterfall) { waterfall_set_aspect (waterfall, gtk_adjustment_get_value (adjustment)); } static GtkWidget * construct_size_bar (Waterfall *waterfall) { GtkWidget *hbox; GtkObject *adjustment; GtkWidget *spin_button; GtkWidget *label; hbox = gtk_hbox_new (FALSE, 12); gtk_widget_show (hbox); label = gtk_label_new ("Smallest:"); gtk_widget_show (label); gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); adjustment = gtk_adjustment_new (waterfall_get_min_size (waterfall), 1.0, 1000.0, 2.0, 12.0, 0); g_signal_connect (adjustment, "value-changed", G_CALLBACK (min_size_changed), waterfall); spin_button = gtk_spin_button_new (GTK_ADJUSTMENT (adjustment), 0, 1); gtk_widget_show (spin_button); gtk_box_pack_start (GTK_BOX (hbox), spin_button, FALSE, FALSE, 0); label = gtk_label_new ("Biggest:"); gtk_widget_show (label); gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); adjustment = gtk_adjustment_new (waterfall_get_max_size (waterfall), 1.0, 1000.0, 2.0, 12.0, 0); g_signal_connect (adjustment, "value-changed", G_CALLBACK (max_size_changed), waterfall); spin_button = gtk_spin_button_new (GTK_ADJUSTMENT (adjustment), 0, 1); gtk_widget_show (spin_button); gtk_box_pack_start (GTK_BOX (hbox), spin_button, FALSE, FALSE, 0); label = gtk_label_new ("Increment:"); gtk_widget_show (label); gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); adjustment = gtk_adjustment_new (waterfall_get_increment (waterfall), 0.1, 100.0, 0.1, 1.0, 0); g_signal_connect (adjustment, "value-changed", G_CALLBACK (increment_changed), waterfall); spin_button = gtk_spin_button_new (GTK_ADJUSTMENT (adjustment), 0, 1); gtk_widget_show (spin_button); gtk_box_pack_start (GTK_BOX (hbox), spin_button, FALSE, FALSE, 0); return hbox; } static GtkWidget * construct_aspect_bar (Waterfall *waterfall) { GtkWidget *hbox; GtkObject *adjustment; GtkWidget *spin_button; GtkWidget *label; hbox = gtk_hbox_new (FALSE, 6); gtk_widget_show (hbox); label = gtk_label_new ("Aspect:"); gtk_widget_show (label); gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); adjustment = gtk_adjustment_new (waterfall_get_aspect (waterfall), 0.01, 100.0, 0.05, 0.5, 0); g_signal_connect (adjustment, "value-changed", G_CALLBACK (aspect_changed), waterfall); spin_button = gtk_spin_button_new (GTK_ADJUSTMENT (adjustment), 0, 1); gtk_widget_show (spin_button); gtk_box_pack_start (GTK_BOX (hbox), spin_button, FALSE, FALSE, 0); return hbox; } static void set_page_label (Waterfall *waterfall) { gchar *label; gint page = waterfall_get_page (waterfall); if (page == -1) label = g_strdup ("Quick Brown"); /* strdup just so it can be freed */ else label = g_strdup_printf ("U+%4.4X", page * WATERFALL_PAGE_SIZE); gtk_label_set_text (GTK_LABEL (page_label), label); g_free (label); } /* direction should be +1 or -1 */ static void set_page (Waterfall *waterfall, gint page, gint direction) { while (waterfall_is_page_empty (waterfall, page) && page + direction <= WATERFALL_LAST_PAGE && page + direction >= -1) page += direction; waterfall_set_page (waterfall, page); set_page_label (waterfall); } static void back_back_clicked (GtkButton *button, Waterfall *waterfall) { set_page (waterfall, waterfall_get_page (waterfall) - 16, -1); } static void back_clicked (GtkButton *button, Waterfall *waterfall) { set_page (waterfall, waterfall_get_page (waterfall) - 1, -1); } static void forward_clicked (GtkButton *button, Waterfall *waterfall) { set_page (waterfall, waterfall_get_page (waterfall) + 1, 1); } static void forward_forward_clicked (GtkButton *button, Waterfall *waterfall) { set_page (waterfall, waterfall_get_page (waterfall) + 16, 1); } static void forward_forward_forward_clicked (GtkButton *button, Waterfall *waterfall) { set_page (waterfall, WATERFALL_LAST_PAGE, 1); } static void back_back_back_clicked (GtkButton *button, Waterfall *waterfall) { set_page (waterfall, 0, -1); } static void quick_brown_clicked (GtkButton *button, Waterfall *waterfall) { set_page (waterfall, -1, -1); } static GtkWidget * construct_page_navigator (Waterfall *waterfall) { GtkWidget *hbox; GtkWidget *button; hbox = gtk_hbox_new (FALSE, 3); gtk_widget_show (hbox); button = gtk_button_new_with_label (" <<< "); gtk_widget_show (button); gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (back_back_back_clicked), waterfall); button = gtk_button_new_with_label (" << "); gtk_widget_show (button); gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (back_back_clicked), waterfall); button = gtk_button_new_with_label (" < "); gtk_widget_show (button); gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (back_clicked), waterfall); page_label = gtk_label_new (NULL); gtk_widget_show (page_label); gtk_label_set_selectable (GTK_LABEL (page_label), TRUE); gtk_box_pack_start (GTK_BOX (hbox), page_label, FALSE, FALSE, 0); set_page_label (waterfall); button = gtk_button_new_with_label (" > "); gtk_widget_show (button); gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (forward_clicked), waterfall); button = gtk_button_new_with_label (" >> "); gtk_widget_show (button); gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (forward_forward_clicked), waterfall); button = gtk_button_new_with_label (" >>> "); gtk_widget_show (button); gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (forward_forward_forward_clicked), waterfall); button = gtk_button_new_with_label ("Quick Brown"); gtk_widget_show (button); gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (quick_brown_clicked), waterfall); return hbox; } static void set_rgba_none (GtkMenuItem *menu_item, Waterfall *waterfall) { waterfall_set_rgba (waterfall, FC_RGBA_NONE); } static void set_rgba_rgb (GtkMenuItem *menu_item, Waterfall *waterfall) { waterfall_set_rgba (waterfall, FC_RGBA_RGB); } static void set_rgba_bgr (GtkMenuItem *menu_item, Waterfall *waterfall) { waterfall_set_rgba (waterfall, FC_RGBA_BGR); } static void set_rgba_vrgb (GtkMenuItem *menu_item, Waterfall *waterfall) { waterfall_set_rgba (waterfall, FC_RGBA_VRGB); } static void set_rgba_vbgr (GtkMenuItem *menu_item, Waterfall *waterfall) { waterfall_set_rgba (waterfall, FC_RGBA_VBGR); } static GtkWidget * construct_rgba_menu (Waterfall *waterfall) { GtkWidget *option_menu; GtkWidget *menu; GtkWidget *menu_item; GtkWidget *label; rgba_hbox = gtk_hbox_new (FALSE, 6); gtk_widget_show (rgba_hbox); label = gtk_label_new ("Subpixel smoothing:"); gtk_widget_show (label); gtk_box_pack_start (GTK_BOX (rgba_hbox), label, FALSE, FALSE, 0); menu = gtk_menu_new (); gtk_widget_show (menu); menu_item = gtk_menu_item_new_with_label ("None"); gtk_widget_show (menu_item); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); g_signal_connect (menu_item, "activate", G_CALLBACK (set_rgba_none), waterfall); menu_item = gtk_menu_item_new_with_label ("RGB"); gtk_widget_show (menu_item); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); g_signal_connect (menu_item, "activate", G_CALLBACK (set_rgba_rgb), waterfall); menu_item = gtk_menu_item_new_with_label ("BGR"); gtk_widget_show (menu_item); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); g_signal_connect (menu_item, "activate", G_CALLBACK (set_rgba_bgr), waterfall); menu_item = gtk_menu_item_new_with_label ("VRGB"); gtk_widget_show (menu_item); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); g_signal_connect (menu_item, "activate", G_CALLBACK (set_rgba_vrgb), waterfall); menu_item = gtk_menu_item_new_with_label ("VBGR"); gtk_widget_show (menu_item); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); g_signal_connect (menu_item, "activate", G_CALLBACK (set_rgba_vbgr), waterfall); option_menu = gtk_option_menu_new (); gtk_widget_show (option_menu); gtk_box_pack_start (GTK_BOX (rgba_hbox), option_menu, FALSE, FALSE, 0); gtk_option_menu_set_menu (GTK_OPTION_MENU (option_menu), menu); gtk_widget_set_sensitive (rgba_hbox, waterfall_get_antialias (waterfall)); return rgba_hbox; } static GtkWidget * construct_options_bar (Waterfall *waterfall) { GtkWidget *vbox; GtkWidget *hbox; GtkWidget *check_button; GtkWidget *separator; vbox = gtk_vbox_new (FALSE, 6); gtk_widget_show (vbox); hbox = gtk_hbox_new (FALSE, 12); gtk_widget_show (hbox); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), construct_font_family_chooser (waterfall), FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), construct_font_style_chooser (waterfall), FALSE, FALSE, 0); separator = gtk_vseparator_new (); gtk_widget_show (separator); gtk_box_pack_start (GTK_BOX (hbox), separator, FALSE, FALSE, 0); check_button = gtk_check_button_new_with_label ("Hinting"); gtk_widget_show (check_button); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button), waterfall_get_hint (waterfall)); gtk_box_pack_start (GTK_BOX (hbox), check_button, FALSE, FALSE, 0); g_signal_connect (G_OBJECT (check_button), "toggled", G_CALLBACK (hint_toggled), waterfall); autohint_check_button = gtk_check_button_new_with_label ("Autohinting"); gtk_widget_show (autohint_check_button); gtk_widget_set_sensitive (autohint_check_button, waterfall_get_hint (waterfall)); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (autohint_check_button), waterfall_get_autohint (waterfall)); gtk_box_pack_start (GTK_BOX (hbox), autohint_check_button, FALSE, FALSE, 0); g_signal_connect (G_OBJECT (autohint_check_button), "toggled", G_CALLBACK (autohint_toggled), waterfall); separator = gtk_vseparator_new (); gtk_widget_show (separator); gtk_box_pack_start (GTK_BOX (hbox), separator, FALSE, FALSE, 0); check_button = gtk_check_button_new_with_label ("Anti-Aliasing"); gtk_widget_show (check_button); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button), waterfall_get_antialias (waterfall)); gtk_box_pack_start (GTK_BOX (hbox), check_button, FALSE, FALSE, 0); g_signal_connect (G_OBJECT (check_button), "toggled", G_CALLBACK (antialias_toggled), waterfall); gtk_box_pack_start (GTK_BOX (hbox), construct_rgba_menu (waterfall), FALSE, FALSE, 0); separator = gtk_vseparator_new (); gtk_widget_show (separator); gtk_box_pack_start (GTK_BOX (hbox), separator, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), construct_aspect_bar (waterfall), FALSE, FALSE, 0); hbox = gtk_hbox_new (FALSE, 12); gtk_widget_show (hbox); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), construct_size_bar (waterfall), FALSE, FALSE, 0); separator = gtk_vseparator_new (); gtk_widget_show (separator); gtk_box_pack_start (GTK_BOX (hbox), separator, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), construct_page_navigator (waterfall), FALSE, FALSE, 0); return vbox; } gint main (gint argc, gchar **argv) { GtkWidget *window; GtkWidget *vbox; GtkWidget *waterfall; GtkWidget *scrolled_window; GdkScreen *screen; gtk_init (&argc, &argv); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title (GTK_WINDOW (window), "Waterfall"); g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (gtk_main_quit), NULL); screen = gtk_window_get_screen (GTK_WINDOW (window)); gtk_window_set_default_size (GTK_WINDOW (window), gdk_screen_get_width (screen) * 3/4, gdk_screen_get_height (screen) * 3/4); vbox = gtk_vbox_new (FALSE, 6); gtk_widget_show (vbox); gtk_container_add (GTK_CONTAINER (window), vbox); waterfall = waterfall_new (); gtk_widget_show (waterfall); scrolled_window = gtk_scrolled_window_new (NULL, NULL); gtk_widget_show (scrolled_window); gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), waterfall); gtk_box_pack_start (GTK_BOX (vbox), construct_options_bar (WATERFALL (waterfall)), FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), scrolled_window, TRUE, TRUE, 0); gtk_widget_show (window); gtk_main (); return 0; } gwaterfall/src/waterfall.h0000644000175000001440000000702710232641317016071 0ustar ogiusers00000000000000/* * $Id: waterfall.h,v 1.4 2003/04/29 03:09:45 nlevitt Exp $ * * Copyright (c) 2003 Noah Levitt * * This program is free software; the author gives unlimited permission to * copy and/or distribute it, with or without modifications, as long as * this notice is preserved. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef WATERFALL_H #define WATERFALL_H #include #include G_BEGIN_DECLS #define WATERFALL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ waterfall_get_type (), Waterfall)) #define WATERFALL_CLASS(clazz) (G_TYPE_CHECK_CLASS_CAST ((clazz), \ waterfall_get_type (),\ WaterfallClass)) #define IS_WATERFALL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ waterfall_get_type ())) typedef struct _Waterfall Waterfall; typedef struct _WaterfallClass WaterfallClass; enum { UNICODE_MAX = 0x10ffff }; enum { WATERFALL_PAGE_SIZE = 128 }; enum { WATERFALL_LAST_PAGE = UNICODE_MAX / WATERFALL_PAGE_SIZE }; struct _Waterfall { GtkDrawingArea parent; GdkPixmap *pixmap; XftDraw *xftdraw; gchar *font_family; gchar *font_style; XftFont *font; gdouble min_size; gdouble max_size; gdouble increment; gboolean hint; gboolean antialias; gboolean autohint; gint rgba; /* subpixel geometry */ gdouble aspect; gint page; }; struct _WaterfallClass { GtkDrawingAreaClass parent_class; }; GType waterfall_get_type (); GtkWidget *waterfall_new (); const gchar * waterfall_get_font_family (Waterfall *waterfall); void waterfall_set_font_family (Waterfall *waterfall, const gchar *new_family); void waterfall_set_font_style (Waterfall *waterfall, const gchar *new_style); const gchar * waterfall_get_font_style (Waterfall *waterfall); void waterfall_set_antialias (Waterfall *waterfall, gboolean antialias); void waterfall_set_hint (Waterfall *waterfall, gboolean hint); gboolean waterfall_get_antialias (Waterfall *waterfall); gboolean waterfall_get_hint (Waterfall *waterfall); gdouble waterfall_get_min_size (Waterfall *waterfall); gdouble waterfall_get_max_size (Waterfall *waterfall); gdouble waterfall_get_increment (Waterfall *waterfall); void waterfall_set_min_size (Waterfall *waterfall, gdouble min_size); void waterfall_set_max_size (Waterfall *waterfall, gdouble max_size); void waterfall_set_increment (Waterfall *waterfall, gdouble increment); gint waterfall_get_page (Waterfall *waterfall); void waterfall_set_page (Waterfall *waterfall, gint page); gboolean waterfall_is_page_empty (Waterfall *waterfall, gint page); gboolean waterfall_get_autohint (Waterfall *waterfall); void waterfall_set_autohint (Waterfall *waterfall, gboolean autohint); gint waterfall_get_rgba (Waterfall *waterfall); void waterfall_set_rgba (Waterfall *waterfall, gboolean rgba); gdouble waterfall_get_aspect (Waterfall *waterfall); void waterfall_set_aspect (Waterfall *waterfall, gdouble aspect); G_END_DECLS #endif /* #ifndef WATERFALL_H */ gwaterfall/src/waterfall.c0000644000175000001440000003165410232641321016062 0ustar ogiusers00000000000000/* * $Id: waterfall.c,v 1.6 2003/04/29 03:09:45 nlevitt Exp $ * * Copyright (c) 2003 Noah Levitt * * This program is free software; the author gives unlimited permission to * copy and/or distribute it, with or without modifications, as long as * this notice is preserved. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include "waterfall.h" #define DEFAULT_STRING \ "the quick brown fox jumps over the lazy dog. " \ "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG. " \ "0123456789!\"#$%&'()*+,-./:;<=>?@[\\]{|}~" enum { BUFFER = 12 }; /* buf should have at least WATERFALL_PAGE_SIZE slots */ static void get_string_for_page (Waterfall *waterfall, gunichar *buf, gint *len) { gint i; if (waterfall->page == -1) { gchar *p = DEFAULT_STRING; for (i = 0; p && i < WATERFALL_PAGE_SIZE; i++) { buf[i] = g_utf8_get_char (p); p = g_utf8_find_next_char (p, NULL); } *len = i; } else { for (i = 0; i < WATERFALL_PAGE_SIZE; i++) buf[i] = (gunichar) (waterfall->page * WATERFALL_PAGE_SIZE + i); *len = WATERFALL_PAGE_SIZE; } } static XftFont * open_font (Waterfall *waterfall, gdouble size) { FcPattern *pattern, *match; FcResult result; XftFont *font; pattern = FcPatternCreate (); if (waterfall->font_family != NULL) FcPatternAddString (pattern, FC_FAMILY, waterfall->font_family); if (waterfall->font_style != NULL) FcPatternAddString (pattern, FC_STYLE, waterfall->font_style); FcPatternAddDouble (pattern, FC_PIXEL_SIZE, size); FcPatternAddBool (pattern, FC_HINTING, waterfall->hint); FcPatternAddBool (pattern, FC_ANTIALIAS, waterfall->antialias); FcPatternAddBool (pattern, FC_AUTOHINT, waterfall->autohint); FcPatternAddInteger (pattern, FC_RGBA, waterfall->rgba); FcPatternAddDouble (pattern, FC_ASPECT, waterfall->aspect); match = XftFontMatch (GDK_DISPLAY (), gdk_x11_get_default_screen (), pattern, &result); FcPatternDestroy (pattern); if (!match) return NULL; font = XftFontOpenPattern (GDK_DISPLAY (), match); if (!font) FcPatternDestroy (match); return font; } static void optimal_size (Waterfall *waterfall, gint *width, gint *height) { XGlyphInfo extents; gdouble lines; XftFont *big_font, *small_font, *theme_font; gchar *buf; gunichar ucs[128]; gint ucs_len; small_font = open_font (waterfall, waterfall->min_size); big_font = open_font (waterfall, waterfall->max_size); theme_font = XftFontOpenName (GDK_DISPLAY (), gdk_x11_get_default_screen (), pango_font_description_to_string ( GTK_WIDGET (waterfall)->style->font_desc)); get_string_for_page (waterfall, ucs, &ucs_len); XftTextExtents32 (GDK_DISPLAY (), big_font, ucs, ucs_len, &extents); *width = extents.width + BUFFER; buf = g_strdup_printf ("%5.1f", waterfall->max_size); XftTextExtentsUtf8 (GDK_DISPLAY (), theme_font, buf, strlen (buf), &extents); *width += extents.width + BUFFER; g_free (buf); if (*width > 6000) { g_warning ("Calculated width %d is too big, clipping at 6000.", *width); *width = 6000; } lines = (waterfall->max_size - waterfall->min_size) / waterfall->increment + 1; *height = 0.5 * (big_font->height + small_font->height) * lines + BUFFER; if (*height > 3000) { g_warning ("Calculated height %d is too big, clipping at 3000.", *height); *height = 3000; } XftFontClose (GDK_DISPLAY (), big_font); XftFontClose (GDK_DISPLAY (), small_font); XftFontClose (GDK_DISPLAY (), theme_font); } static void draw_pixmap (Waterfall *waterfall) { Colormap colormap; Drawable drawable; Visual *visual; gint width, height; XGlyphInfo extents; XftFont *theme_font; XftColor fg; XftFont *font; XftDraw *xftdraw; gdouble size; gint y; gint size_width; /* width allotted to "12.0", etc */ gchar *buf; gunichar ucs[128]; gint ucs_len; width = GTK_WIDGET (waterfall)->allocation.width; height = GTK_WIDGET (waterfall)->allocation.height; theme_font = XftFontOpenName (GDK_DISPLAY (), gdk_x11_get_default_screen (), pango_font_description_to_string ( GTK_WIDGET (waterfall)->style->font_desc)); waterfall->pixmap = gdk_pixmap_new (GTK_WIDGET (waterfall)->window, width, height, -1); gdk_draw_rectangle (GDK_DRAWABLE (waterfall->pixmap), GTK_WIDGET (waterfall)->style->base_gc[GTK_STATE_NORMAL], TRUE, 0, 0, width, height); colormap = gdk_x11_colormap_get_xcolormap ( gdk_drawable_get_colormap (GTK_WIDGET (waterfall)->window)); drawable = gdk_x11_drawable_get_xid (GDK_DRAWABLE (waterfall->pixmap)); visual = gdk_x11_visual_get_xvisual ( gtk_widget_get_visual (GTK_WIDGET (waterfall))); xftdraw = XftDrawCreate (GDK_DISPLAY (), drawable, visual, colormap); fg.color.red = GTK_WIDGET (waterfall)->style->fg[GTK_STATE_NORMAL].red; fg.color.green = GTK_WIDGET (waterfall)->style->fg[GTK_STATE_NORMAL].green; fg.color.blue = GTK_WIDGET (waterfall)->style->fg[GTK_STATE_NORMAL].blue; fg.color.alpha = 0xffff; buf = g_strdup_printf ("%5.1f", waterfall->max_size); XftTextExtentsUtf8 (GDK_DISPLAY (), theme_font, buf, strlen (buf), &extents); size_width = extents.width + BUFFER; g_free (buf); for (y = 0, size = waterfall->min_size; size <= waterfall->max_size; size += waterfall->increment) { font = open_font (waterfall, size); y += font->height; buf = g_strdup_printf ("%5.1f", size); XftDrawStringUtf8 (xftdraw, &fg, theme_font, 0, y, buf, strlen (buf)); g_free (buf); get_string_for_page (waterfall, ucs, &ucs_len); XftDrawString32(xftdraw, &fg, font, size_width, y, ucs, ucs_len); XftFontClose (GDK_DISPLAY (), font); } XftFontClose (GDK_DISPLAY (), theme_font); XftDrawDestroy (xftdraw); } static gint expose_event (Waterfall *waterfall, GdkEventExpose *event) { gdk_window_set_back_pixmap (GTK_WIDGET (waterfall)->window, NULL, FALSE); if (waterfall->pixmap == NULL) draw_pixmap (waterfall); gdk_draw_drawable (GTK_WIDGET (waterfall)->window, GTK_WIDGET (waterfall)->style->fg_gc[GTK_STATE_NORMAL], waterfall->pixmap, event->area.x, event->area.y, event->area.x, event->area.y, event->area.width, event->area.height); return FALSE; } static void size_allocate (GtkWidget *widget, GtkAllocation *allocation) { } void waterfall_init (Waterfall *waterfall) { waterfall->font_family = NULL; waterfall->font_style = NULL; waterfall->min_size = 5.0; waterfall->max_size = 36.0; waterfall->increment = 1.0; waterfall->hint = TRUE; waterfall->antialias = TRUE; waterfall->autohint = FALSE; waterfall->rgba = FC_RGBA_NONE; waterfall->aspect = 1.0; waterfall->page = -1; gtk_widget_set_events (GTK_WIDGET (waterfall), GDK_EXPOSURE_MASK); g_signal_connect (G_OBJECT (waterfall), "expose-event", G_CALLBACK (expose_event), NULL); g_signal_connect (G_OBJECT (waterfall), "size-allocate", G_CALLBACK (size_allocate), NULL); } GType waterfall_get_type () { static GType waterfall_type = 0; if (!waterfall_type) { static const GTypeInfo waterfall_info = { sizeof (WaterfallClass), NULL, /* base_init */ NULL, /* base_finalize */ NULL, /* class_init */ NULL, /* class_finalize */ NULL, /* class_data */ sizeof (Waterfall), 0, /* n_preallocs */ (GInstanceInitFunc) waterfall_init, }; waterfall_type = g_type_register_static (GTK_TYPE_DRAWING_AREA, "Waterfall", &waterfall_info, 0); } return waterfall_type; } GtkWidget * waterfall_new () { return GTK_WIDGET (g_object_new (waterfall_get_type (), NULL)); } static void queue_redraw (Waterfall *waterfall) { gint width, height; if (waterfall->pixmap) { g_object_unref (waterfall->pixmap); waterfall->pixmap = NULL; } optimal_size (waterfall, &width, &height); gtk_widget_set_size_request (GTK_WIDGET (waterfall), width, height); gtk_widget_queue_draw (GTK_WIDGET (waterfall)); } void waterfall_set_font_family (Waterfall *waterfall, const gchar *new_family) { if (waterfall->font_family) g_free (waterfall->font_family); if (waterfall->font) XftFontClose (GDK_DISPLAY (), waterfall->font); waterfall->font_family = g_strdup (new_family); waterfall->font = open_font (waterfall, waterfall->min_size); queue_redraw (waterfall); } const gchar * waterfall_get_font_family (Waterfall *waterfall) { return waterfall->font_family; } void waterfall_set_font_style (Waterfall *waterfall, const gchar *new_style) { if (waterfall->font_style) g_free (waterfall->font_style); if (waterfall->font) XftFontClose (GDK_DISPLAY (), waterfall->font); waterfall->font_style = g_strdup (new_style); waterfall->font = open_font (waterfall, waterfall->min_size); queue_redraw (waterfall); } const gchar * waterfall_get_font_style (Waterfall *waterfall) { return waterfall->font_style; } gboolean waterfall_get_hint (Waterfall *waterfall) { return waterfall->hint; } void waterfall_set_hint (Waterfall *waterfall, gboolean hint) { if (hint != waterfall->hint) { waterfall->hint = hint; queue_redraw (waterfall); } } gboolean waterfall_get_antialias (Waterfall *waterfall) { return waterfall->antialias; } void waterfall_set_antialias (Waterfall *waterfall, gboolean antialias) { if (antialias != waterfall->antialias) { waterfall->antialias = antialias; queue_redraw (waterfall); } } gboolean waterfall_get_autohint (Waterfall *waterfall) { return waterfall->autohint; } void waterfall_set_autohint (Waterfall *waterfall, gboolean autohint) { if (autohint != waterfall->autohint) { waterfall->autohint = autohint; queue_redraw (waterfall); } } gdouble waterfall_get_min_size (Waterfall *waterfall) { return waterfall->min_size; } gdouble waterfall_get_max_size (Waterfall *waterfall) { return waterfall->max_size; } gdouble waterfall_get_increment (Waterfall *waterfall) { return waterfall->increment; } void waterfall_set_min_size (Waterfall *waterfall, gdouble min_size) { if (min_size != waterfall->min_size) { waterfall->min_size = min_size; queue_redraw (waterfall); } } void waterfall_set_max_size (Waterfall *waterfall, gdouble max_size) { if (max_size == waterfall->max_size) return; waterfall->max_size = max_size; queue_redraw (waterfall); } void waterfall_set_increment (Waterfall *waterfall, gdouble increment) { if (increment == waterfall->increment) return; waterfall->increment = increment; queue_redraw (waterfall); } gint waterfall_get_page (Waterfall *waterfall) { return waterfall->page; } void waterfall_set_page (Waterfall *waterfall, gint page) { if (page > WATERFALL_LAST_PAGE) page = WATERFALL_LAST_PAGE; else if (page < -1) page = -1; if (page != waterfall->page) { waterfall->page = page; queue_redraw (waterfall); } } gboolean waterfall_is_page_empty (Waterfall *waterfall, gint page) { FcCharSet *charset; FcChar32 count; guint i; if (page == -1) return FALSE; charset = FcCharSetCreate (); for (i = 0; i < WATERFALL_PAGE_SIZE; i++) FcCharSetAddChar (charset, page * WATERFALL_PAGE_SIZE + i); count = FcCharSetIntersectCount (waterfall->font->charset, charset); FcCharSetDestroy (charset); return count == 0; } gint waterfall_get_rgba (Waterfall *waterfall) { return waterfall->rgba; } void waterfall_set_rgba (Waterfall *waterfall, gboolean rgba) { if (rgba != waterfall->rgba) { waterfall->rgba = rgba; queue_redraw (waterfall); } } gdouble waterfall_get_aspect (Waterfall *waterfall) { return waterfall->aspect; } void waterfall_set_aspect (Waterfall *waterfall, gdouble aspect) { if (aspect != waterfall->aspect) { waterfall->aspect = aspect; queue_redraw (waterfall); } }