diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | ChangeLog.pre-1-10 | 9 | ||||
-rw-r--r-- | ChangeLog.pre-1-4 | 9 | ||||
-rw-r--r-- | ChangeLog.pre-1-6 | 9 | ||||
-rw-r--r-- | ChangeLog.pre-1-8 | 9 | ||||
-rw-r--r-- | configure.in | 69 | ||||
-rw-r--r-- | examples/Makefile.am | 32 | ||||
-rw-r--r-- | examples/viewer-qt.cc | 528 | ||||
-rw-r--r-- | examples/viewer-qt.h | 116 | ||||
-rw-r--r-- | examples/viewer.c | 709 |
10 files changed, 45 insertions, 1454 deletions
@@ -1,3 +1,12 @@ +Thu Jul 24 15:09:22 2003 Owen Taylor <otaylor@redhat.com> + + * configure.in examples/Makefile.am examples/viewer-qt.{cc,h}: + Remove Qt-based example; it was only testing the obsolete + pango-x backend, and was causing more problems for people + trying to configure Pango then it was worth. + + * examples/viewer.c: Remove obsolete test case from CVS. + Thu Jul 24 15:02:56 2003 Owen Taylor <otaylor@redhat.com> * pango/glyphstring.c (pango_glyph_string_get_logical_widths): diff --git a/ChangeLog.pre-1-10 b/ChangeLog.pre-1-10 index 15b8cf24..bf4094ee 100644 --- a/ChangeLog.pre-1-10 +++ b/ChangeLog.pre-1-10 @@ -1,3 +1,12 @@ +Thu Jul 24 15:09:22 2003 Owen Taylor <otaylor@redhat.com> + + * configure.in examples/Makefile.am examples/viewer-qt.{cc,h}: + Remove Qt-based example; it was only testing the obsolete + pango-x backend, and was causing more problems for people + trying to configure Pango then it was worth. + + * examples/viewer.c: Remove obsolete test case from CVS. + Thu Jul 24 15:02:56 2003 Owen Taylor <otaylor@redhat.com> * pango/glyphstring.c (pango_glyph_string_get_logical_widths): diff --git a/ChangeLog.pre-1-4 b/ChangeLog.pre-1-4 index 15b8cf24..bf4094ee 100644 --- a/ChangeLog.pre-1-4 +++ b/ChangeLog.pre-1-4 @@ -1,3 +1,12 @@ +Thu Jul 24 15:09:22 2003 Owen Taylor <otaylor@redhat.com> + + * configure.in examples/Makefile.am examples/viewer-qt.{cc,h}: + Remove Qt-based example; it was only testing the obsolete + pango-x backend, and was causing more problems for people + trying to configure Pango then it was worth. + + * examples/viewer.c: Remove obsolete test case from CVS. + Thu Jul 24 15:02:56 2003 Owen Taylor <otaylor@redhat.com> * pango/glyphstring.c (pango_glyph_string_get_logical_widths): diff --git a/ChangeLog.pre-1-6 b/ChangeLog.pre-1-6 index 15b8cf24..bf4094ee 100644 --- a/ChangeLog.pre-1-6 +++ b/ChangeLog.pre-1-6 @@ -1,3 +1,12 @@ +Thu Jul 24 15:09:22 2003 Owen Taylor <otaylor@redhat.com> + + * configure.in examples/Makefile.am examples/viewer-qt.{cc,h}: + Remove Qt-based example; it was only testing the obsolete + pango-x backend, and was causing more problems for people + trying to configure Pango then it was worth. + + * examples/viewer.c: Remove obsolete test case from CVS. + Thu Jul 24 15:02:56 2003 Owen Taylor <otaylor@redhat.com> * pango/glyphstring.c (pango_glyph_string_get_logical_widths): diff --git a/ChangeLog.pre-1-8 b/ChangeLog.pre-1-8 index 15b8cf24..bf4094ee 100644 --- a/ChangeLog.pre-1-8 +++ b/ChangeLog.pre-1-8 @@ -1,3 +1,12 @@ +Thu Jul 24 15:09:22 2003 Owen Taylor <otaylor@redhat.com> + + * configure.in examples/Makefile.am examples/viewer-qt.{cc,h}: + Remove Qt-based example; it was only testing the obsolete + pango-x backend, and was causing more problems for people + trying to configure Pango then it was worth. + + * examples/viewer.c: Remove obsolete test case from CVS. + Thu Jul 24 15:02:56 2003 Owen Taylor <otaylor@redhat.com> * pango/glyphstring.c (pango_glyph_string_get_logical_widths): diff --git a/configure.in b/configure.in index bba72c71..ecf4c5cc 100644 --- a/configure.in +++ b/configure.in @@ -463,75 +463,6 @@ fi AC_SUBST(USP10_H) AM_CONDITIONAL(HAVE_USP10_H, test "$USP10_H" != no) -# -# Check for Qt - which we use for building the viewer example, if -# present -# - -AC_ARG_WITH(qt, [ --with-qt=DIR location where Qt is installed],,with_qt=yes) - -if test "$CXX" != "" ; then - AC_MSG_CHECKING(For Qt location) - - if test "x$with_qt" = xyes ; then - # Search for Qt in a common location. The ls -r is an attempt to find the newest - if test "x$QTDIR" != x ; then - if test -x $QTDIR/bin/moc ; then : ; else - QTDIR= - fi - else - dirs=`cd /usr/lib && ls -d -r qt* 2>/dev/null` - for dir in $dirs ; do - case $dir in - qt2*|qt-2*|qt3*|qt-3*) - if test -x /usr/lib/$dir/bin/moc ; then - QTDIR=/usr/lib/$dir - break - fi - ;; - esac - done - fi - else - if test "x$with_qt" != xno ; then - if test -x $with_qt/bin/moc ; then - QTDIR=$with_qt - fi - else - QTDIR="" - fi - fi - - if test "x$QTDIR" = x ; then - AC_MSG_RESULT(none) - else - AC_MSG_RESULT($QTDIR) - fi -else - QTDIR="" -fi - -if test x"$QTDIR" != "x" ; then - AC_MSG_CHECKING(For working Qt) - - pango_save_libs="$LIBS" - pango_save_cppflags="$CPPFLAGS" - LIBS="-L$QTDIR/lib -lqt $LIBS" - CPPFLAGS="-I $QTDIR/include" - AC_LANG_SAVE - AC_LANG_CPLUSPLUS - AC_TRY_LINK([#include <qapplication.h>], - [QApplication a ();], - [AC_MSG_RESULT(yes)], - [QTDIR=""; AC_MSG_RESULT(no)]) - AC_LANG_RESTORE - LIBS="$pango_save_libs" - CPPFLAGS="$pango_save_cppflags" -fi - -AM_CONDITIONAL(BUILD_QT_TEST, test "x$QTDIR" != x) -AC_SUBST(QTDIR) - dnl ************************** dnl *** Checks for gtk-doc *** dnl ************************** diff --git a/examples/Makefile.am b/examples/Makefile.am index 3dc00654..f580dc10 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -6,40 +6,11 @@ INCLUDES = \ -DG_DISABLE_DEPRECATED \ $(PANGO_DEBUG_FLAGS) \ -I$(top_srcdir) \ - $(QT_INCLUDES) \ $(GLIB_CFLAGS) \ $(FREETYPE_CFLAGS) ################################################### -if BUILD_QT_TEST - -QT_INCLUDES=-I$(QTDIR)/include -QT_LIBS=-L$(QTDIR)/lib -lqt -MOC=$(QTDIR)/bin/moc - -viewer_programs = pango-viewer - -BUILT_SOURCES=moc_viewer-qt.cc - -moc_viewer-qt.cc: viewer-qt.h - $(MOC) $< -o $@ - -endif - -pango_viewer_SOURCES = \ - viewer-qt.cc \ - viewer-qt.h - -CLEANFILES = moc_viewer-qt.cc -pango_viewer_LDADD = \ - ../pango/libpangox-$(PANGO_API_VERSION).la \ - ../pango/libpango-$(PANGO_API_VERSION).la \ - $(FRIBIDI_LIBS) \ - $(QT_LIBS) \ - moc_viewer-qt.$(OBJEXT) -################################################### - ################################################### if HAVE_FREETYPE ft2_programs = pangoft2topgm @@ -52,7 +23,6 @@ pangoft2topgm_LDADD = \ $(FREETYPE_LIBS) ################################################### -bin_PROGRAMS = $(viewer_programs) noinst_PROGRAMS = $(ft2_programs) if CROSS_COMPILING @@ -71,8 +41,6 @@ pango.modules: fi EXTRA_DIST= \ - viewer-qt.cc \ - viewer-qt.h \ viewer-win32.c \ pangoft2topgm.c \ makefile.msc \ diff --git a/examples/viewer-qt.cc b/examples/viewer-qt.cc deleted file mode 100644 index 1ec8262f..00000000 --- a/examples/viewer-qt.cc +++ /dev/null @@ -1,528 +0,0 @@ -/* Pango - * viewer-qt.cc: Example program to view a UTF-8 encoding file - * using Pango to render result. - * - * Copyright (C) 1999-2000 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 <string.h> -#include <stdlib.h> -#include <stdio.h> - -#include <qapplication.h> -#include <qcombobox.h> -#include <qfile.h> -#include <qfileinfo.h> -#include <qmenubar.h> -#include <qpainter.h> -#include <qpopupmenu.h> -#include <qspinbox.h> -#include <qscrollview.h> -#include <qstatusbar.h> -#include <qtextcodec.h> -#include <qtextstream.h> -#include <qtoolbar.h> - -#include <pango/pango.h> -#include <pango/pangox.h> - -#include "viewer-qt.h" - -ViewerPara::ViewerPara (PangoContext *context, const QString &text) -{ - text_ = text.utf8(); - - layout_ = pango_layout_new (context); - pango_layout_set_text (layout_, (char *)(const char *)text_, text_.length()); - height_ = -1; -} - -ViewerPara::~ViewerPara () -{ - g_object_unref (G_OBJECT (layout_)); -} - -void -ViewerPara::setWidth (int width) -{ - pango_layout_set_width (layout_, width * PANGO_SCALE); - height_ = -1; -} - -void -ViewerPara::contextChanged () -{ - pango_layout_context_changed (layout_); - height_ = -1; - - PangoContext *context; - PangoAlignment align; - - context = pango_layout_get_context (layout_); - if (pango_context_get_base_dir (context) == PANGO_DIRECTION_LTR) - align = PANGO_ALIGN_LEFT; - else - align = PANGO_ALIGN_RIGHT; - - pango_layout_set_alignment (layout_, align); -} - -int -ViewerPara::height () -{ - if (height_ < 0) - { - PangoRectangle logical_rect; - - pango_layout_get_extents (layout_, NULL, &logical_rect); - height_ = logical_rect.height / PANGO_SCALE; - } - - return height_; -} - -void -ViewerPara::draw (QPainter *painter, GC gc, int y) -{ - QPoint devicePt = painter->xForm (QPoint (0, y)); - - pango_x_render_layout (painter->device()->x11Display(), - painter->device()->handle(), - gc, layout_, 0, devicePt.y()); -} - -gunichar -ViewerPara::getChar (int index) -{ - gunichar result; - - return g_utf8_get_char ((const char *)text_ + index); -} - -QRect -ViewerPara::charBounds (int index) -{ - PangoRectangle pos; - - pango_layout_index_to_pos (layout_, index, &pos); - - return QRect (MIN (pos.x, pos.x + pos.width) / PANGO_SCALE, - pos.y / PANGO_SCALE, - ABS (pos.width) / PANGO_SCALE, - pos.height / PANGO_SCALE); -} - -int -ViewerPara::findPoint (int x, int y) -{ - int index; - - bool result = pango_layout_xy_to_index (layout_, - x * PANGO_SCALE, y * PANGO_SCALE, - &index, NULL); - if (result) - return index; - else - return -1; -} - -ViewerView::ViewerView (QWidget *parent, QStatusBar *status) : QScrollView (parent) -{ - status_ = status; - - viewport()->setBackgroundMode( QWidget::PaletteBase ); - - setHScrollBarMode (QScrollView::AlwaysOff); - - context_ = pango_x_get_context (x11Display()); - pango_context_set_language (context_, pango_language_from_string ("en-us")); - - highlight_para_ = NULL; - highlight_index_ = 0; -} - -ViewerView::~ViewerView () -{ - g_object_unref (G_OBJECT (context_)); -} - -void -ViewerView::readFile (const QString &name) -{ - QFile file (name); - - if (!file.open (IO_ReadOnly)) - { - fprintf (stderr, "Cannot open file '%s'\n", (const char *)name.local8Bit()); - return; - } - - QTextStream ts (&file);; - - ts.setCodec (QTextCodec::codecForName ("utf8")); - - while (!ts.atEnd()) - paragraphs_.append (new ViewerPara (context (), ts.readLine())); -} - -void -ViewerView::contextChanged () -{ - QListIterator<ViewerPara> it(paragraphs_); - for (; it.current(); ++it) - it.current()->contextChanged(); - - computeHeight(); - updateContents (0, 0, contentsWidth(), contentsHeight()); -} - -void -ViewerView::setFontDesc (PangoFontDescription *font_desc) -{ - pango_context_set_font_description (context_, font_desc); - contextChanged(); -} - -void -ViewerView::setDirection (PangoDirection base_dir) -{ - QListIterator<ViewerPara> it(paragraphs_); - for (; it.current(); ++it) - it.current()->contextChanged(); - - pango_context_set_base_dir (context_, base_dir); - contextChanged(); -} - -void -ViewerView::drawContents (QPainter *p, int clipx, int clipy, int clipw, int cliph) -{ - XGCValues values; - QRect clip = p->xForm (QRect (clipx, clipy, clipw, cliph)); - - GC gc = XCreateGC (x11Display(), handle(), 0, &values); - - XSetForeground (x11Display(), gc, colorGroup().text().pixel()); - - XRectangle xclip = { clip.x(), clip.y(), clip.width(), clip.height() }; - XSetClipRectangles (x11Display(), gc, 0, 0, &xclip, 1, YXBanded); - - int y = 0; - QListIterator<ViewerPara> it(paragraphs_); - for (; it.current(); ++it) - { - ViewerPara *para = it.current(); - int y_end = y + para->height (); - - if (y_end > clipy && y < clipy + cliph) - para->draw (p, gc, y); - - if (para == highlight_para_) - { - QRect bounds = highlight_para_->charBounds (highlight_index_); - bounds.moveBy (0, y); - bounds = p->xForm (bounds); - - XRectangle xbounds = { bounds.x(), bounds.y(), bounds.width(), bounds.height() }; - - XFillRectangle (x11Display(), p->device()->handle(), gc, - xbounds.x, xbounds.y, xbounds.width, xbounds.height); - - XSetClipRectangles (x11Display(), gc, 0, 0, &xbounds, 1, YXBanded); - XSetForeground (x11Display(), gc, colorGroup().base().pixel()); - - para->draw (p, gc, y); - - XSetForeground (x11Display(), gc, colorGroup().text().pixel()); - XSetClipRectangles (x11Display(), gc, 0, 0, &xclip, 1, YXBanded); - } - - y = y_end; - } - - XFreeGC (x11Display(), gc); -} - -void -ViewerView::computeHeight () -{ - int width = visibleWidth(); - int height = 0; - - QListIterator<ViewerPara> it(paragraphs_); - for (; it.current(); ++it) - { - ViewerPara *para = it.current(); - para->setWidth (width); - height += para->height (); - } - - resizeContents (width, height); - repaintContents (0, 0, contentsWidth(), contentsHeight()); -} - -void -ViewerView::viewportResizeEvent (QResizeEvent *event) -{ - computeHeight (); -} - -void -ViewerView::updateHighlightChar () -{ - if (highlight_para_) - { - int y = 0; - QListIterator<ViewerPara> it(paragraphs_); - - for (; it.current(); ++it) - { - ViewerPara *para = it.current(); - if (para == highlight_para_) - { - QRect bounds = para->charBounds (highlight_index_); - bounds.moveBy (0, y); - updateContents (bounds.x(), bounds.y(), bounds.width(), bounds.height()); - - break; - } - - y += para->height (); - } - } -} - -void -ViewerView::contentsMousePressEvent (QMouseEvent *event) -{ - updateHighlightChar (); - highlight_para_ = NULL; - - int y = 0; - QListIterator<ViewerPara> it(paragraphs_); - for (; it.current(); ++it) - { - ViewerPara *para = it.current(); - int y_end = y + para->height (); - - if (y <= event->y() && event->y() < y_end) - { - int index = para->findPoint (event->x(), event->y() - y); - gunichar wc = para->getChar (index); - - if (index >= 0 && wc != (gunichar)-1) - { - highlight_para_ = para; - highlight_index_ = index; - - if (status_) - { - QString num = QString::number (wc, 16).rightJustify (4, '0'); - - status_->message (QString ("Current char: U+") + num); - } - } - - break; - } - y = y_end; - } - - if (status_ && !highlight_para_) - status_->clear (); - - updateHighlightChar(); -} - -static int -cmp_families (const void *a, const void *b) -{ - const char *a_name = pango_font_family_get_name (*(PangoFontFamily **)a); - const char *b_name = pango_font_family_get_name (*(PangoFontFamily **)b); - - return strcmp (a_name, b_name); -} - -ViewerWindow::ViewerWindow (const QString &filename) -{ - // Create menu - - file_menu_ = new QPopupMenu (this); - file_menu_->setCheckable (true); - - menuBar()->insertItem ("&File", file_menu_); - - file_menu_->insertItem( "&Quit", qApp, SLOT( closeAllWindows() ), CTRL+Key_Q ); - - right_to_left_item_ = file_menu_->insertItem( "&Right-to-Left", this, SLOT( setRightToLeft() ), 0 ); - - view_ = new ViewerView (this, new QStatusBar (this)); - - setCentralWidget (view_); - - // Create families combo box - - QToolBar *toolbar = new QToolBar ("Font", this); - - family_combo_ = new QComboBox (toolbar); - - int n_families, i; - - pango_context_list_families (view_->context(), &families_, &n_families); - qsort (families_, n_families, sizeof(PangoFontFamily *), cmp_families); - - for (i=0; i<n_families; i++) - { - const char *name = pango_font_family_get_name (families_[i]); - - family_combo_->insertItem (name); - if (!strcmp (name, "sans")) - family_combo_->setCurrentItem (i); - } - - QObject::connect (family_combo_, SIGNAL(activated(int)), this, SLOT(fillStyleCombo(int))); - - faces_ = NULL; - - style_combo_ = new QComboBox (toolbar); - fillStyleCombo (family_combo_->currentItem ()); - - size_box_ = new QSpinBox (1, 1000, 1, toolbar); - size_box_->setValue (16); - - QObject::connect (family_combo_, SIGNAL(activated(int)), this, SLOT(fontChanged())); - QObject::connect (style_combo_, SIGNAL(activated(int)), this, SLOT(fontChanged())); - QObject::connect (size_box_, SIGNAL(valueChanged(int)), this, SLOT(fontChanged())); - - fontChanged (); - - view_->readFile (filename); - - resize (500, 500); -} - -static int -compare_font_descriptions (const PangoFontDescription *a, const PangoFontDescription *b) -{ - int val = strcmp (pango_font_description_get_family (a), pango_font_description_get_family (b)); - if (val != 0) - return val; - - if (pango_font_description_get_weight (a) != pango_font_description_get_weight (b)) - return pango_font_description_get_weight (a) - pango_font_description_get_weight (b); - - if (pango_font_description_get_style (a) != pango_font_description_get_style (b)) - return pango_font_description_get_style (a) - pango_font_description_get_style (b); - - if (pango_font_description_get_stretch (a) != pango_font_description_get_stretch (b)) - return pango_font_description_get_stretch (a) - pango_font_description_get_stretch (b); - - if (pango_font_description_get_variant (a) != pango_font_description_get_variant (b)) - return pango_font_description_get_variant (a) - pango_font_description_get_variant (b); - - return 0; -} - -static int -faces_sort_func (const void *a, const void *b) -{ - PangoFontDescription *desc_a = pango_font_face_describe (*(PangoFontFace **)a); - PangoFontDescription *desc_b = pango_font_face_describe (*(PangoFontFace **)b); - - int ord = compare_font_descriptions (desc_a, desc_b); - - pango_font_description_free (desc_a); - pango_font_description_free (desc_b); - - return ord; -} - -void -ViewerWindow::fillStyleCombo (int index) -{ - PangoFontFamily *family = families_[index]; - int n_faces; - - if (faces_) - g_free (faces_); - - pango_font_family_list_faces (family, &faces_, &n_faces); - - qsort (faces_, n_faces, sizeof(PangoFontFace *), faces_sort_func); - - style_combo_->clear(); - for (int i = 0; i < n_faces; i++) - { - const char *str = pango_font_face_get_face_name (faces_[i]); - style_combo_->insertItem (str); - } -} - -void -ViewerWindow::fontChanged () -{ - PangoFontFace *face = faces_[style_combo_->currentItem()]; - - QString style = style_combo_->currentText(); - - PangoFontDescription *font_desc = pango_font_face_describe (face); - pango_font_description_set_size (font_desc, size_box_->value () * PANGO_SCALE); - - view_->setFontDesc (font_desc); - - pango_font_description_free (font_desc); -} - -void -ViewerWindow::setRightToLeft () -{ - bool new_value = !file_menu_->isItemChecked (right_to_left_item_); - - file_menu_->setItemChecked (right_to_left_item_, new_value); - view_->setDirection (new_value ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR); -} - -ViewerWindow::~ViewerWindow () -{ - delete view_; -} - -int -main (int argc, char **argv) -{ - QApplication a (argc, argv); - const char *filename; - - g_type_init (); - - if (QFileInfo ("./pangorc").exists ()) - putenv ("PANGO_RC_FILE=./pangorc"); - - if (argc == 2) - filename = argv[1]; - else - filename = "HELLO.utf8"; - - ViewerWindow *vw = new ViewerWindow (QString::fromLocal8Bit (filename)); - - vw->show(); - - a.connect (&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit())); - return a.exec (); -} - diff --git a/examples/viewer-qt.h b/examples/viewer-qt.h deleted file mode 100644 index 21307111..00000000 --- a/examples/viewer-qt.h +++ /dev/null @@ -1,116 +0,0 @@ -/* Pango - * viewer-qt.cc: Example program to view a UTF-8 encoding file - * using Pango to render result. - * - * Copyright (C) 1999-2000 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 <qscrollview.h> -#include <qlist.h> -#include <qmainwindow.h> -#include <pango/pango.h> - -class QComboBox; -class QSpinBox; - -class ViewerPara -{ - public: - ViewerPara (PangoContext *context, const QString &text); - ~ViewerPara (); - - void setWidth (int width); - void contextChanged (); - int height (); - void draw (QPainter *painter, GC gc, int y); - QRect charBounds (int index); - gunichar getChar (int index); - int findPoint (int x, int y); - - private: - QCString text_; - int height_; - PangoLayout *layout_; -}; - -class ViewerView : public QScrollView -{ - Q_OBJECT - - public: - - ViewerView::ViewerView (QWidget *parent, QStatusBar *status = NULL); - ~ViewerView (); - - void readFile (const QString &name); - void setFontDesc (PangoFontDescription *font_desc); - void setDirection (PangoDirection base_dir); - - void computeHeight (); - - PangoContext *context() { return context_; } - - protected: - virtual void drawContents (QPainter *p, int clipx, int clipy, int clipw, int cliph); - virtual void viewportResizeEvent ( QResizeEvent *event ); - virtual void contentsMousePressEvent (QMouseEvent *event); - - private: - void contextChanged (); - void updateHighlightChar (); - - QStatusBar *status_; - - PangoContext *context_; - QList<ViewerPara> paragraphs_; - - ViewerPara *highlight_para_; - int highlight_index_; -}; - -class ViewerWindow : public QMainWindow -{ - Q_OBJECT - - public: - - ViewerWindow (const QString &filename); - ~ViewerWindow (); - - private: - ViewerView *view_; - - PangoContext *context_; - - QComboBox *family_combo_; - PangoFontFamily **families_; - - QComboBox *style_combo_; - PangoFontFace **faces_; - - QSpinBox *size_box_; - - QPopupMenu *file_menu_; - - int right_to_left_item_; - - private slots: - void fillStyleCombo (int index); - void fontChanged (); - void setRightToLeft (); -}; diff --git a/examples/viewer.c b/examples/viewer.c deleted file mode 100644 index 65a251e7..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) -{ - 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); - - 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); - - font_description.family_name = g_strdup ("sans"); - font_description.style = PANGO_STYLE_NORMAL; - font_description.variant = PANGO_VARIANT_NORMAL; - font_description.weight = 500; - font_description.stretch = PANGO_STRETCH_NORMAL; - font_description.size = 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; -} |