summaryrefslogtreecommitdiff
path: root/pango
diff options
context:
space:
mode:
authorAlexander Larsson <alla@lysator.liu.se>2001-11-18 16:06:02 +0000
committerAlexander Larsson <alexl@src.gnome.org>2001-11-18 16:06:02 +0000
commit0766534429b5830716e782418179ea63f8f1f65d (patch)
tree1ab6b8c50e572af8320c8f3623b8135276c010f6 /pango
parentb12c0fb6263fd542bb03f8bb10076a0653694f12 (diff)
downloadpango-0766534429b5830716e782418179ea63f8f1f65d.tar.gz
Check for LEX and YACC. This will be made optional later, with the build
2001-11-17 Alexander Larsson <alla@lysator.liu.se> * configure.in: Check for LEX and YACC. This will be made optional later, with the build sources checked in to cvs. Generate pango/mini-xft/Makefile * modules/basic/basic-ft2.c: Use the new pangoft2 API. * pango/Makefile.am: Build mini-xft. Add new files. * pango/pango-context.[ch]: Support only one fontmap per context. Use pango_font_map_load_fontset() and PangoFontset instead of internal fontset. * pango/pango-fontmap.[ch]: New virtual function pango_font_map_load_fontset() and default implementation that uses pango_font_map_load_font(). * pango/pango-utils.[ch] (pango_lookup_aliases): Utility function for looking up aliases. This can be used by backend that has no backend specific aliases. * pango/pangoft2-fontcache.c: Removed file. * pango/pangoft2-fontmap.c: * pango/pangoft2-private.h: * pango/pangoft2.c: * pango/pangoft2.h: Major rewrite. Doesn't handle fontsets. Uses mini-xft so that it will always match the PangoXft backend. Simplified the public API. * pango/pangowin32.c: * pango/pangox.c: pango_context_add_font_map -> pango_context_set_font_map * pango/pangoxft-font.c: * pango/pangoxft-fontmap.c: * pango/pangoxft-private.h: New code to handle fontsets. * pango/mini-xft/*: Mini version of libXft from XFree86 in order to have the pangoFT2 and pangXft backends have same config files and generate the same fonts.
Diffstat (limited to 'pango')
-rw-r--r--pango/Makefile.am12
-rw-r--r--pango/mini-xft/Makefile.am53
-rw-r--r--pango/mini-xft/MiniXft.h340
-rw-r--r--pango/mini-xft/MiniXftFreetype.h54
-rw-r--r--pango/mini-xft/README14
-rw-r--r--pango/mini-xft/Xemu.h15
-rw-r--r--pango/mini-xft/minixftcache.c608
-rw-r--r--pango/mini-xft/minixftcfg.c665
-rw-r--r--pango/mini-xft/minixftdbg.c230
-rw-r--r--pango/mini-xft/minixftdir.c136
-rw-r--r--pango/mini-xft/minixftdpy.c321
-rw-r--r--pango/mini-xft/minixftfont.c111
-rw-r--r--pango/mini-xft/minixftfreetype.c190
-rw-r--r--pango/mini-xft/minixftfs.c74
-rw-r--r--pango/mini-xft/minixftgram.c1498
-rw-r--r--pango/mini-xft/minixftgram.h49
-rw-r--r--pango/mini-xft/minixftgram.y452
-rw-r--r--pango/mini-xft/minixftinit.c48
-rw-r--r--pango/mini-xft/minixftint.h395
-rw-r--r--pango/mini-xft/minixftlex.c1985
-rw-r--r--pango/mini-xft/minixftlex.l275
-rw-r--r--pango/mini-xft/minixftlist.c303
-rw-r--r--pango/mini-xft/minixftmatch.c330
-rw-r--r--pango/mini-xft/minixftmatrix.c104
-rw-r--r--pango/mini-xft/minixftname.c391
-rw-r--r--pango/mini-xft/minixftpat.c411
-rw-r--r--pango/mini-xft/minixftstr.c156
-rw-r--r--pango/pango-context.c335
-rw-r--r--pango/pango-context.h2
-rw-r--r--pango/pango-fontmap.c153
-rw-r--r--pango/pango-fontmap.h30
-rw-r--r--pango/pango-utils.c244
-rw-r--r--pango/pango-utils.h3
-rw-r--r--pango/pangoft2-fontcache.c310
-rw-r--r--pango/pangoft2-fontmap.c1313
-rw-r--r--pango/pangoft2-private.h76
-rw-r--r--pango/pangoft2.c509
-rw-r--r--pango/pangoft2.h50
-rw-r--r--pango/pangowin32.c2
-rw-r--r--pango/pangox.c2
-rw-r--r--pango/pangoxft-font.c90
-rw-r--r--pango/pangoxft-fontmap.c422
-rw-r--r--pango/pangoxft-private.h8
43 files changed, 10692 insertions, 2077 deletions
diff --git a/pango/Makefile.am b/pango/Makefile.am
index 35040d0a..9823c28c 100644
--- a/pango/Makefile.am
+++ b/pango/Makefile.am
@@ -6,6 +6,9 @@ GPATH = $(srcdir)
if HAVE_FREETYPE
OPENTYPE_SUBDIR=opentype
+XFT_SUBDIR = mini-xft
+else
+XFT_SUBDIR =
endif
if HAVE_FRIBIDI
@@ -13,9 +16,9 @@ else
FRIBIDI_SUBDIR = mini-fribidi
endif
-SUBDIRS = $(OPENTYPE_SUBDIR) $(FRIBIDI_SUBDIR)
+SUBDIRS = $(OPENTYPE_SUBDIR) $(FRIBIDI_SUBDIR) $(XFT_SUBDIR)
-DIST_SUBDIRS = mini-fribidi opentype
+DIST_SUBDIRS = mini-fribidi mini-xft opentype
INCLUDES = \
-DPANGO_ENABLE_BACKEND \
@@ -122,6 +125,7 @@ libpango_la_SOURCES = \
pango-context.c \
pango-coverage.c \
pango-fontmap.c \
+ pango-fontset.c \
pango-intset.c \
pango-intset.h \
pango-item.c \
@@ -183,11 +187,10 @@ libpangoft2_la_SOURCES = \
pangoft2.h \
pangoft2.c \
pangoft2-private.h \
- pangoft2-fontcache.c \
pangoft2-fontmap.c \
module-defs-ft2.c
-libpangoft2_la_LIBADD = $(INCLUDED_FT2_MODULES) $(FREETYPE_LIBS) libpango.la
+libpangoft2_la_LIBADD = $(INCLUDED_FT2_MODULES) $(FREETYPE_LIBS) mini-xft/libmini-xft.la libpango.la
libpangoft2_la_LDFLAGS = -release $(VERSION) $(GLIB_LIBS) $(no_undefined) $(pangoft2_export_symbols)
libpangoft2_la_DEPENDENCIES = $(INCLUDED_FT2_MODULES) libpango.la
@@ -202,6 +205,7 @@ pango_headers= \
pango-engine.h \
pango-font.h \
pango-fontmap.h \
+ pango-fontset.h \
pango-glyph.h \
pango-indic.h \
pango-item.h \
diff --git a/pango/mini-xft/Makefile.am b/pango/mini-xft/Makefile.am
new file mode 100644
index 00000000..b8dfe6fe
--- /dev/null
+++ b/pango/mini-xft/Makefile.am
@@ -0,0 +1,53 @@
+## Process this file with automake to produce Makefile.in
+
+INCLUDES = \
+ -DSYSCONFDIR=\"$(sysconfdir)\" \
+ -DLIBDIR=\"$(libdir)\" \
+ $(FREETYPE_CFLAGS) \
+ -I$(top_srcdir)
+
+LDADDS = @STRIP_BEGIN@ \
+ @GLIB_LIBS@ \
+ -lm \
+@STRIP_END@
+
+noinst_LTLIBRARIES = libmini-xft.la
+
+minixftgram.c: minixftgram.y
+ $(YACC) -d minixftgram.y
+ sed 's/yy/MiniXftConfig/g' y.tab.c | sed 's/__REALLY_YY__/yy/' > minixftgram.c && $(RM) y.tab.c
+ sed 's/yy/MiniXftConfig/g' y.tab.h | sed 's/__REALLY_YY__/yy/' > minixftgram.h && $(RM) y.tab.h
+
+minixftlex.c: minixftlex.l
+ $(LEX) minixftlex.l
+ sed 's/yy/MiniXftConfig/g' lex.yy.c | sed 's/__REALLY_YY__/yy/' > minixftlex.c && $(RM) lex.yy.c
+
+libmini_xft_la_SOURCES = \
+ Xemu.h \
+ MiniXft.h \
+ MiniXftFreetype.h \
+ minixftgram.h \
+ minixftint.h \
+ minixftgram.c \
+ minixftlex.c \
+ minixftdbg.c \
+ minixftfont.c \
+ minixftfs.c \
+ minixftlist.c \
+ minixftname.c \
+ minixftcache.c \
+ minixftdir.c \
+ minixftfreetype.c \
+ minixftmatch.c \
+ minixftpat.c \
+ minixftcfg.c \
+ minixftdpy.c \
+ minixftinit.c \
+ minixftmatrix.c \
+ minixftstr.c
+
+EXTRA_DIST = \
+ minixftgram.y \
+ minixftlex.l \
+ README
+
diff --git a/pango/mini-xft/MiniXft.h b/pango/mini-xft/MiniXft.h
new file mode 100644
index 00000000..31cfb1cf
--- /dev/null
+++ b/pango/mini-xft/MiniXft.h
@@ -0,0 +1,340 @@
+/*
+ * $XFree86: xc/lib/MiniXft/MiniXft.h,v 1.19 2001/04/29 03:21:17 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _XFT_H_
+#define _XFT_H_
+
+#include "Xemu.h"
+
+#include <stdarg.h>
+
+typedef unsigned char MiniXftChar8;
+typedef unsigned short MiniXftChar16;
+typedef unsigned int MiniXftChar32;
+
+#define XFT_FAMILY "family" /* String */
+#define XFT_STYLE "style" /* String */
+#define XFT_SLANT "slant" /* Int */
+#define XFT_WEIGHT "weight" /* Int */
+#define XFT_SIZE "size" /* Double */
+#define XFT_PIXEL_SIZE "pixelsize" /* Double */
+#define XFT_ENCODING "encoding" /* String */
+#define XFT_SPACING "spacing" /* Int */
+#define XFT_FOUNDRY "foundry" /* String */
+#define XFT_CORE "core" /* Bool */
+#define XFT_ANTIALIAS "antialias" /* Bool */
+#define XFT_XLFD "xlfd" /* String */
+#define XFT_FILE "file" /* String */
+#define XFT_INDEX "index" /* Int */
+#define XFT_RASTERIZER "rasterizer"/* String */
+#define XFT_OUTLINE "outline" /* Bool */
+#define XFT_SCALABLE "scalable" /* Bool */
+#define XFT_RGBA "rgba" /* Int */
+
+/* defaults from resources */
+#define XFT_SCALE "scale" /* double */
+#define XFT_RENDER "render" /* Bool */
+#define XFT_MINSPACE "minspace" /* Bool use minimum line spacing */
+#define XFT_DPI "dpi" /* double */
+
+/* specific to FreeType rasterizer */
+#define XFT_CHAR_WIDTH "charwidth" /* Int */
+#define XFT_CHAR_HEIGHT "charheight"/* Int */
+#define XFT_MATRIX "matrix" /* MiniXftMatrix */
+
+#define XFT_WEIGHT_LIGHT 0
+#define XFT_WEIGHT_MEDIUM 100
+#define XFT_WEIGHT_DEMIBOLD 180
+#define XFT_WEIGHT_BOLD 200
+#define XFT_WEIGHT_BLACK 210
+
+#define XFT_SLANT_ROMAN 0
+#define XFT_SLANT_ITALIC 100
+#define XFT_SLANT_OBLIQUE 110
+
+#define XFT_PROPORTIONAL 0
+#define XFT_MONO 100
+#define XFT_CHARCELL 110
+
+#define XFT_RGBA_NONE 0
+#define XFT_RGBA_RGB 1
+#define XFT_RGBA_BGR 2
+#define XFT_RGBA_VRGB 3
+#define XFT_RGBA_VBGR 4
+
+typedef enum _MiniXftType {
+ MiniXftTypeVoid,
+ MiniXftTypeInteger,
+ MiniXftTypeDouble,
+ MiniXftTypeString,
+ MiniXftTypeBool,
+ MiniXftTypeMatrix
+} MiniXftType;
+
+typedef struct _MiniXftMatrix {
+ double xx, xy, yx, yy;
+} MiniXftMatrix;
+
+#define MiniXftMatrixInit(m) ((m)->xx = (m)->yy = 1, \
+ (m)->xy = (m)->yx = 0)
+
+typedef enum _MiniXftResult {
+ MiniXftResultMatch, MiniXftResultNoMatch, MiniXftResultTypeMismatch, MiniXftResultNoId
+} MiniXftResult;
+
+typedef struct _MiniXftValue {
+ MiniXftType type;
+ union {
+ char *s;
+ int i;
+ Bool b;
+ double d;
+ MiniXftMatrix *m;
+ } u;
+} MiniXftValue;
+
+typedef struct _MiniXftValueList {
+ struct _MiniXftValueList *next;
+ MiniXftValue value;
+} MiniXftValueList;
+
+typedef struct _MiniXftPatternElt {
+ const char *object;
+ MiniXftValueList *values;
+} MiniXftPatternElt;
+
+typedef struct _MiniXftPattern {
+ int num;
+ int size;
+ MiniXftPatternElt *elts;
+} MiniXftPattern;
+
+typedef struct _MiniXftFontSet {
+ int nfont;
+ int sfont;
+ MiniXftPattern **fonts;
+} MiniXftFontSet;
+
+typedef struct _MiniXftObjectSet {
+ int nobject;
+ int sobject;
+ const char **objects;
+} MiniXftObjectSet;
+
+_XFUNCPROTOBEGIN
+
+/* xftcfg.c */
+Bool
+MiniXftConfigSubstitute (MiniXftPattern *p);
+
+/* xftdbg.c */
+void
+MiniXftValuePrint (MiniXftValue v);
+
+void
+MiniXftValueListPrint (MiniXftValueList *l);
+
+void
+MiniXftPatternPrint (MiniXftPattern *p);
+
+void
+MiniXftFontSetPrint (MiniXftFontSet *s);
+
+/* xftdir.c */
+/* xftdpy.c */
+void
+MiniXftSetDPI (double dpi);
+
+Bool
+MiniXftDefaultHasRender (Display *dpy);
+
+Bool
+MiniXftDefaultSet (Display *dpy, MiniXftPattern *defaults);
+
+void
+MiniXftDefaultSubstitute (Display *dpy, int screen, MiniXftPattern *pattern);
+
+/* xftfont.c */
+MiniXftPattern *
+MiniXftFontMatch (Display *dpy, int screen, MiniXftPattern *pattern, MiniXftResult *result);
+
+/* xftfreetype.c */
+/* xftfs.c */
+
+MiniXftFontSet *
+MiniXftFontSetCreate (void);
+
+void
+MiniXftFontSetDestroy (MiniXftFontSet *s);
+
+Bool
+MiniXftFontSetAdd (MiniXftFontSet *s, MiniXftPattern *font);
+
+/* xftglyphs.c */
+/* see MiniXftFreetype.h */
+
+/* xftgram.y */
+
+/* xftinit.c */
+extern MiniXftFontSet *_MiniXftFontSet;
+
+Bool
+MiniXftInit (char *config);
+
+/* xftlex.l */
+
+/* xftlist.c */
+MiniXftObjectSet *
+MiniXftObjectSetCreate (void);
+
+Bool
+MiniXftObjectSetAdd (MiniXftObjectSet *os, const char *object);
+
+void
+MiniXftObjectSetDestroy (MiniXftObjectSet *os);
+
+MiniXftObjectSet *
+MiniXftObjectSetVaBuild (const char *first, va_list va);
+
+MiniXftObjectSet *
+MiniXftObjectSetBuild (const char *first, ...);
+
+MiniXftFontSet *
+MiniXftListFontSets (MiniXftFontSet **sets,
+ int nsets,
+ MiniXftPattern *p,
+ MiniXftObjectSet *os);
+
+MiniXftFontSet *
+MiniXftListFontsPatternObjects (Display *dpy,
+ int screen,
+ MiniXftPattern *pattern,
+ MiniXftObjectSet *os);
+
+MiniXftFontSet *
+MiniXftListFonts (Display *dpy,
+ int screen,
+ ...);
+
+/* xftmatch.c */
+MiniXftPattern *
+MiniXftFontSetMatch (MiniXftFontSet **sets,
+ int nsets,
+ MiniXftPattern *p,
+ MiniXftResult *result);
+
+/* xftmatrix.c */
+int
+MiniXftMatrixEqual (const MiniXftMatrix *mat1, const MiniXftMatrix *mat2);
+
+void
+MiniXftMatrixMultiply (MiniXftMatrix *result, MiniXftMatrix *a, MiniXftMatrix *b);
+
+void
+MiniXftMatrixRotate (MiniXftMatrix *m, double c, double s);
+
+void
+MiniXftMatrixScale (MiniXftMatrix *m, double sx, double sy);
+
+void
+MiniXftMatrixShear (MiniXftMatrix *m, double sh, double sv);
+
+/* xftname.c */
+MiniXftPattern *
+MiniXftNameParse (const char *name);
+
+Bool
+MiniXftNameUnparse (MiniXftPattern *pat, char *dest, int len);
+
+/* xftpat.c */
+MiniXftPattern *
+MiniXftPatternCreate (void);
+
+MiniXftPattern *
+MiniXftPatternDuplicate (MiniXftPattern *p);
+
+void
+MiniXftValueDestroy (MiniXftValue v);
+
+void
+MiniXftValueListDestroy (MiniXftValueList *l);
+
+void
+MiniXftPatternDestroy (MiniXftPattern *p);
+
+MiniXftPatternElt *
+MiniXftPatternFind (MiniXftPattern *p, const char *object, Bool insert);
+
+Bool
+MiniXftPatternAdd (MiniXftPattern *p, const char *object, MiniXftValue value, Bool append);
+
+MiniXftResult
+MiniXftPatternGet (MiniXftPattern *p, const char *object, int id, MiniXftValue *v);
+
+Bool
+MiniXftPatternDel (MiniXftPattern *p, const char *object);
+
+Bool
+MiniXftPatternAddInteger (MiniXftPattern *p, const char *object, int i);
+
+Bool
+MiniXftPatternAddDouble (MiniXftPattern *p, const char *object, double d);
+
+Bool
+MiniXftPatternAddString (MiniXftPattern *p, const char *object, const char *s);
+
+Bool
+MiniXftPatternAddMatrix (MiniXftPattern *p, const char *object, const MiniXftMatrix *s);
+
+Bool
+MiniXftPatternAddBool (MiniXftPattern *p, const char *object, Bool b);
+
+MiniXftResult
+MiniXftPatternGetInteger (MiniXftPattern *p, const char *object, int n, int *i);
+
+MiniXftResult
+MiniXftPatternGetDouble (MiniXftPattern *p, const char *object, int n, double *d);
+
+MiniXftResult
+MiniXftPatternGetString (MiniXftPattern *p, const char *object, int n, char **s);
+
+MiniXftResult
+MiniXftPatternGetMatrix (MiniXftPattern *p, const char *object, int n, MiniXftMatrix **s);
+
+MiniXftResult
+MiniXftPatternGetBool (MiniXftPattern *p, const char *object, int n, Bool *b);
+
+MiniXftPattern *
+MiniXftPatternVaBuild (MiniXftPattern *orig, va_list va);
+
+MiniXftPattern *
+MiniXftPatternBuild (MiniXftPattern *orig, ...);
+
+/* xftrender.c */
+/* see MiniXftFreetype.h */
+
+/* xftstr.c */
+_XFUNCPROTOEND
+
+#endif /* _XFT_H_ */
diff --git a/pango/mini-xft/MiniXftFreetype.h b/pango/mini-xft/MiniXftFreetype.h
new file mode 100644
index 00000000..a69c6a47
--- /dev/null
+++ b/pango/mini-xft/MiniXftFreetype.h
@@ -0,0 +1,54 @@
+/*
+ * $XFree86: xc/lib/MiniXft/MiniXftFreetype.h,v 1.15 2001/03/31 23:07:29 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _XFTFREETYPE_H_
+#define _XFTFREETYPE_H_
+
+#include "MiniXft.h"
+#include <freetype/freetype.h>
+
+extern FT_Library _MiniXftFTlibrary;
+
+_XFUNCPROTOBEGIN
+
+/* xftdir.c */
+Bool
+MiniXftDirScan (MiniXftFontSet *set, const char *dir, Bool force);
+
+Bool
+MiniXftDirSave (MiniXftFontSet *set, const char *dir);
+
+/* xftfreetype.c */
+MiniXftPattern *
+MiniXftFreeTypeQuery (const char *file, int id, int *count);
+
+Bool
+MiniXftInitFtLibrary(void);
+
+_XFUNCPROTOEND
+
+#endif /* _XFTFREETYPE_H_ */
+
+
+
diff --git a/pango/mini-xft/README b/pango/mini-xft/README
new file mode 100644
index 00000000..11ea3392
--- /dev/null
+++ b/pango/mini-xft/README
@@ -0,0 +1,14 @@
+This is a copy of the libXft library from the XFree86 cvs server, with
+all the X specific parts removed. It is used by pangoft2 to locate
+fonts and to handle font aliases in exactly the same way as Xft does.
+
+In order to not have symbols collide, the following sed scripts were run
+on the code:
+
+for file in xftgram.y xftlex.l xftdir.c xftcache.c xftdpy.c xftfs.c xftname.c xftcfg.c xftfont.c xftinit.c xftlist.c xftpat.c xftdbg.c xftfreetype.c xftmatrix.c xftmatch.c xftstr.c xftgram.h xftint.h ; do
+ sed s#Xft#MiniXft#g $file | sed s#/X11/MiniXftConfig#/X11/XftConfig#g | sed s/xftint.h/minixftint.h/g | sed s/xftgram.h/minixftgram.h/g> mini-xft/mini$file;
+done
+
+for file in XftFreetype.h Xft.h; do
+ sed s/Xft/MiniXft/g $file > mini-xft/Mini$file;
+done
diff --git a/pango/mini-xft/Xemu.h b/pango/mini-xft/Xemu.h
new file mode 100644
index 00000000..17d0fd67
--- /dev/null
+++ b/pango/mini-xft/Xemu.h
@@ -0,0 +1,15 @@
+#ifndef XEMU_H
+#define XEMU_H
+
+#include <glib.h>
+
+#define _XFUNCPROTOBEGIN G_BEGIN_DECLS
+#define _XFUNCPROTOEND G_END_DECLS
+
+typedef gboolean Bool;
+typedef int Display;
+
+#define False FALSE
+#define True TRUE
+
+#endif /* XEMU_H */
diff --git a/pango/mini-xft/minixftcache.c b/pango/mini-xft/minixftcache.c
new file mode 100644
index 00000000..54ec1fd5
--- /dev/null
+++ b/pango/mini-xft/minixftcache.c
@@ -0,0 +1,608 @@
+/*
+ * $XFree86: xc/lib/MiniXft/xftcache.c,v 1.2 2001/06/11 22:53:30 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "minixftint.h"
+
+typedef struct _MiniXftFileCacheEnt {
+ struct _MiniXftFileCacheEnt *next;
+ unsigned int hash;
+ char *file;
+ int id;
+ time_t time;
+ char *name;
+ Bool referenced;
+} MiniXftFileCacheEnt;
+
+#define HASH_SIZE 509
+
+typedef struct _MiniXftFileCache {
+ MiniXftFileCacheEnt *ents[HASH_SIZE];
+ Bool updated;
+ int entries;
+ int referenced;
+} MiniXftFileCache;
+
+static MiniXftFileCache _MiniXftFileCache;
+
+static unsigned int
+_MiniXftFileCacheHash (char *string)
+{
+ unsigned int h = 0;
+ char c;
+
+ while ((c = *string++))
+ h = (h << 1) ^ c;
+ return h;
+}
+
+char *
+MiniXftFileCacheFind (char *file, int id, int *count)
+{
+ MiniXftFileCache *cache;
+ unsigned int hash;
+ char *match;
+ MiniXftFileCacheEnt *c, *name;
+ int maxid;
+ struct stat statb;
+
+ cache = &_MiniXftFileCache;
+ match = file;
+
+ hash = _MiniXftFileCacheHash (match);
+ name = 0;
+ maxid = -1;
+ for (c = cache->ents[hash % HASH_SIZE]; c; c = c->next)
+ {
+ if (c->hash == hash && !strcmp (match, c->file))
+ {
+ if (c->id > maxid)
+ maxid = c->id;
+ if (c->id == id)
+ {
+ if (stat (file, &statb) < 0)
+ {
+ if (_MiniXftFontDebug () & XFT_DBG_CACHE)
+ printf (" file missing\n");
+ return 0;
+ }
+ if (statb.st_mtime != c->time)
+ {
+ if (_MiniXftFontDebug () & XFT_DBG_CACHE)
+ printf (" timestamp mismatch (was %d is %d)\n",
+ (int) c->time, (int) statb.st_mtime);
+ return 0;
+ }
+ if (!c->referenced)
+ {
+ cache->referenced++;
+ c->referenced = True;
+ }
+ name = c;
+ }
+ }
+ }
+ if (!name)
+ return 0;
+ *count = maxid + 1;
+ return name->name;
+}
+
+/*
+ * Cache file syntax is quite simple:
+ *
+ * "file_name" id time "font_name" \n
+ */
+
+static Bool
+_MiniXftFileCacheReadString (FILE *f, char *dest, int len)
+{
+ int c;
+ Bool escape;
+
+ while ((c = getc (f)) != EOF)
+ if (c == '"')
+ break;
+ if (c == EOF)
+ return False;
+ if (len == 0)
+ return False;
+
+ escape = False;
+ while ((c = getc (f)) != EOF)
+ {
+ if (!escape)
+ {
+ switch (c) {
+ case '"':
+ *dest++ = '\0';
+ return True;
+ case '\\':
+ escape = True;
+ continue;
+ }
+ }
+ if (--len <= 1)
+ return False;
+ *dest++ = c;
+ escape = False;
+ }
+ return False;
+}
+
+static Bool
+_MiniXftFileCacheReadUlong (FILE *f, unsigned long *dest)
+{
+ unsigned long t;
+ int c;
+
+ while ((c = getc (f)) != EOF)
+ {
+ if (!isspace (c))
+ break;
+ }
+ if (c == EOF)
+ return False;
+ t = 0;
+ for (;;)
+ {
+ if (c == EOF || isspace (c))
+ break;
+ if (!isdigit (c))
+ return False;
+ t = t * 10 + (c - '0');
+ c = getc (f);
+ }
+ *dest = t;
+ return True;
+}
+
+static Bool
+_MiniXftFileCacheReadInt (FILE *f, int *dest)
+{
+ unsigned long t;
+ Bool ret;
+
+ ret = _MiniXftFileCacheReadUlong (f, &t);
+ if (ret)
+ *dest = (int) t;
+ return ret;
+}
+
+static Bool
+_MiniXftFileCacheReadTime (FILE *f, time_t *dest)
+{
+ unsigned long t;
+ Bool ret;
+
+ ret = _MiniXftFileCacheReadUlong (f, &t);
+ if (ret)
+ *dest = (time_t) t;
+ return ret;
+}
+
+static Bool
+_MiniXftFileCacheAdd (MiniXftFileCache *cache,
+ char *file,
+ int id,
+ time_t time,
+ char *name,
+ Bool replace)
+{
+ MiniXftFileCacheEnt *c;
+ MiniXftFileCacheEnt **prev, *old;
+ unsigned int hash;
+
+ if (_MiniXftFontDebug () & XFT_DBG_CACHE)
+ {
+ printf ("%s face %s/%d as %s\n", replace ? "Replace" : "Add",
+ file, id, name);
+ }
+ hash = _MiniXftFileCacheHash (file);
+ for (prev = &cache->ents[hash % HASH_SIZE];
+ (old = *prev);
+ prev = &(*prev)->next)
+ {
+ if (old->hash == hash && old->id == id && !strcmp (old->file, file))
+ break;
+ }
+ if (*prev)
+ {
+ if (!replace)
+ return False;
+
+ old = *prev;
+ if (old->referenced)
+ cache->referenced--;
+ *prev = old->next;
+ free (old);
+ cache->entries--;
+ }
+
+ c = malloc (sizeof (MiniXftFileCacheEnt) +
+ strlen (file) + 1 +
+ strlen (name) + 1);
+ if (!c)
+ return False;
+ c->next = *prev;
+ *prev = c;
+ c->hash = hash;
+ c->file = (char *) (c + 1);
+ c->id = id;
+ c->name = c->file + strlen (file) + 1;
+ strcpy (c->file, file);
+ c->time = time;
+ c->referenced = replace;
+ strcpy (c->name, name);
+ cache->entries++;
+ return True;
+}
+
+void
+MiniXftFileCacheDispose (void)
+{
+ MiniXftFileCache *cache;
+ MiniXftFileCacheEnt *c, *next;
+ int h;
+
+ cache = &_MiniXftFileCache;
+
+ for (h = 0; h < HASH_SIZE; h++)
+ {
+ for (c = cache->ents[h]; c; c = next)
+ {
+ next = c->next;
+ free (c);
+ }
+ cache->ents[h] = 0;
+ }
+ cache->entries = 0;
+ cache->referenced = 0;
+ cache->updated = False;
+}
+
+void
+MiniXftFileCacheLoad (char *cache_file)
+{
+ MiniXftFileCache *cache;
+ FILE *f;
+ char file[8192];
+ int id;
+ time_t time;
+ char name[8192];
+
+ f = fopen (cache_file, "r");
+ if (!f)
+ return;
+
+ cache = &_MiniXftFileCache;
+
+ cache->updated = False;
+ while (_MiniXftFileCacheReadString (f, file, sizeof (file)) &&
+ _MiniXftFileCacheReadInt (f, &id) &&
+ _MiniXftFileCacheReadTime (f, &time) &&
+ _MiniXftFileCacheReadString (f, name, sizeof (name)))
+ {
+ (void) _MiniXftFileCacheAdd (cache, file, id, time, name, False);
+ }
+ fclose (f);
+}
+
+Bool
+MiniXftFileCacheUpdate (char *file, int id, char *name)
+{
+ MiniXftFileCache *cache;
+ char *match;
+ struct stat statb;
+ Bool ret;
+
+ cache = &_MiniXftFileCache;
+ match = file;
+
+ if (stat (file, &statb) < 0)
+ return False;
+ ret = _MiniXftFileCacheAdd (cache, match, id,
+ statb.st_mtime, name, True);
+ if (ret)
+ cache->updated = True;
+ return ret;
+}
+
+static Bool
+_MiniXftFileCacheWriteString (FILE *f, char *string)
+{
+ char c;
+
+ if (putc ('"', f) == EOF)
+ return False;
+ while ((c = *string++))
+ {
+ switch (c) {
+ case '"':
+ case '\\':
+ if (putc ('\\', f) == EOF)
+ return False;
+ /* fall through */
+ default:
+ if (putc (c, f) == EOF)
+ return False;
+ }
+ }
+ if (putc ('"', f) == EOF)
+ return False;
+ return True;
+}
+
+static Bool
+_MiniXftFileCacheWriteUlong (FILE *f, unsigned long t)
+{
+ int pow;
+ unsigned long temp, digit;
+
+ temp = t;
+ pow = 1;
+ while (temp >= 10)
+ {
+ temp /= 10;
+ pow *= 10;
+ }
+ temp = t;
+ while (pow)
+ {
+ digit = temp / pow;
+ if (putc ((char) digit + '0', f) == EOF)
+ return False;
+ temp = temp - pow * digit;
+ pow = pow / 10;
+ }
+ return True;
+}
+
+static Bool
+_MiniXftFileCacheWriteInt (FILE *f, int i)
+{
+ return _MiniXftFileCacheWriteUlong (f, (unsigned long) i);
+}
+
+static Bool
+_MiniXftFileCacheWriteTime (FILE *f, time_t t)
+{
+ return _MiniXftFileCacheWriteUlong (f, (unsigned long) t);
+}
+
+Bool
+MiniXftFileCacheSave (char *cache_file)
+{
+ MiniXftFileCache *cache;
+ char *lck;
+ char *tmp;
+ FILE *f;
+ int h;
+ MiniXftFileCacheEnt *c;
+
+ cache = &_MiniXftFileCache;
+
+ if (!cache->updated && cache->referenced == cache->entries)
+ return True;
+
+ lck = malloc (strlen (cache_file)*2 + 4);
+ if (!lck)
+ goto bail0;
+ tmp = lck + strlen (cache_file) + 2;
+ strcpy (lck, cache_file);
+ strcat (lck, "L");
+ strcpy (tmp, cache_file);
+ strcat (tmp, "T");
+ if (link (lck, cache_file) < 0 && errno != ENOENT)
+ goto bail1;
+ if (access (tmp, F_OK) == 0)
+ goto bail2;
+ f = fopen (tmp, "w");
+ if (!f)
+ goto bail2;
+
+ for (h = 0; h < HASH_SIZE; h++)
+ {
+ for (c = cache->ents[h]; c; c = c->next)
+ {
+ if (!c->referenced)
+ continue;
+ if (!_MiniXftFileCacheWriteString (f, c->file))
+ goto bail4;
+ if (putc (' ', f) == EOF)
+ goto bail4;
+ if (!_MiniXftFileCacheWriteInt (f, c->id))
+ goto bail4;
+ if (putc (' ', f) == EOF)
+ goto bail4;
+ if (!_MiniXftFileCacheWriteTime (f, c->time))
+ goto bail4;
+ if (putc (' ', f) == EOF)
+ goto bail4;
+ if (!_MiniXftFileCacheWriteString (f, c->name))
+ goto bail4;
+ if (putc ('\n', f) == EOF)
+ goto bail4;
+ }
+ }
+
+ if (fclose (f) == EOF)
+ goto bail3;
+
+ if (rename (tmp, cache_file) < 0)
+ goto bail3;
+
+ unlink (lck);
+ cache->updated = False;
+ return True;
+
+bail4:
+ fclose (f);
+bail3:
+ unlink (tmp);
+bail2:
+ unlink (lck);
+bail1:
+ free (lck);
+bail0:
+ return False;
+}
+
+Bool
+MiniXftFileCacheReadDir (MiniXftFontSet *set, const char *cache_file)
+{
+ MiniXftPattern *font;
+ FILE *f;
+ char *path;
+ char *base;
+ char file[8192];
+ int id;
+ char name[8192];
+ Bool ret = False;
+
+ if (_MiniXftFontDebug () & XFT_DBG_CACHE)
+ {
+ printf ("MiniXftFileCacheReadDir cache_file \"%s\"\n", cache_file);
+ }
+
+ f = fopen (cache_file, "r");
+ if (!f)
+ {
+ if (_MiniXftFontDebug () & XFT_DBG_CACHE)
+ {
+ printf (" no cache file\n");
+ }
+ goto bail0;
+ }
+
+ base = strrchr (cache_file, '/');
+ if (!base)
+ goto bail1;
+ base++;
+ path = malloc (base - cache_file + 8192 + 1);
+ if (!path)
+ goto bail1;
+ memcpy (path, cache_file, base - cache_file);
+ base = path + (base - cache_file);
+
+ while (_MiniXftFileCacheReadString (f, file, sizeof (file)) &&
+ _MiniXftFileCacheReadInt (f, &id) &&
+ _MiniXftFileCacheReadString (f, name, sizeof (name)))
+ {
+ font = MiniXftNameParse (name);
+ if (font)
+ {
+ strcpy (base, file);
+ if (_MiniXftFontDebug () & XFT_DBG_CACHEV)
+ {
+ printf (" dir cache file \"%s\"\n", file);
+ }
+ MiniXftPatternAddString (font, XFT_FILE, path);
+ if (!MiniXftFontSetAdd (set, font))
+ goto bail2;
+ }
+ }
+ if (_MiniXftFontDebug () & XFT_DBG_CACHE)
+ {
+ printf (" cache loaded\n");
+ }
+
+ ret = True;
+bail2:
+ free (path);
+bail1:
+ fclose (f);
+bail0:
+ return ret;
+}
+
+Bool
+MiniXftFileCacheWriteDir (MiniXftFontSet *set, const char *cache_file)
+{
+ MiniXftPattern *font;
+ FILE *f;
+ char name[8192];
+ char *file, *base;
+ int n;
+ int id;
+
+ if (_MiniXftFontDebug () & XFT_DBG_CACHE)
+ printf ("MiniXftFileCacheWriteDir cache_file \"%s\"\n", cache_file);
+
+ f = fopen (cache_file, "w");
+ if (!f)
+ {
+ if (_MiniXftFontDebug () & XFT_DBG_CACHE)
+ printf (" can't create \"%s\"\n", cache_file);
+ goto bail0;
+ }
+ for (n = 0; n < set->nfont; n++)
+ {
+ font = set->fonts[n];
+ if (MiniXftPatternGetString (font, XFT_FILE, 0, &file) != MiniXftResultMatch)
+ goto bail1;
+ base = strrchr (file, '/');
+ if (base)
+ base = base + 1;
+ else
+ base = file;
+ if (MiniXftPatternGetInteger (font, XFT_INDEX, 0, &id) != MiniXftResultMatch)
+ goto bail1;
+ if (!MiniXftNameUnparse (font, name, sizeof (name)))
+ goto bail1;
+ if (_MiniXftFontDebug () & XFT_DBG_CACHEV)
+ printf (" write file \"%s\"\n", base);
+ if (!_MiniXftFileCacheWriteString (f, base))
+ goto bail1;
+ if (putc (' ', f) == EOF)
+ goto bail1;
+ if (!_MiniXftFileCacheWriteInt (f, id))
+ goto bail1;
+ if (putc (' ', f) == EOF)
+ goto bail1;
+ if (!_MiniXftFileCacheWriteString (f, name))
+ goto bail1;
+ if (putc ('\n', f) == EOF)
+ goto bail1;
+ }
+ if (fclose (f) == EOF)
+ goto bail0;
+
+ if (_MiniXftFontDebug () & XFT_DBG_CACHE)
+ printf (" cache written\n");
+ return True;
+
+bail1:
+ fclose (f);
+bail0:
+ unlink (cache_file);
+ return False;
+}
diff --git a/pango/mini-xft/minixftcfg.c b/pango/mini-xft/minixftcfg.c
new file mode 100644
index 00000000..ffc7e4e0
--- /dev/null
+++ b/pango/mini-xft/minixftcfg.c
@@ -0,0 +1,665 @@
+/*
+ * $XFree86: xc/lib/MiniXft/xftcfg.c,v 1.9 2001/03/31 01:57:20 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include "minixftint.h"
+
+static char *MiniXftConfigDefaultDirs[] = {
+ "/usr/X11R6/lib/X11/fonts/Type1",
+ 0
+};
+
+char **MiniXftConfigDirs = MiniXftConfigDefaultDirs;
+static int MiniXftConfigNdirs;
+
+char MiniXftConfigDefaultCache[] = "~/.xftcache";
+char *MiniXftConfigCache = 0;
+
+static MiniXftSubst *MiniXftSubsts;
+/* #define XFT_DEBUG_EDIT */
+
+Bool
+MiniXftConfigAddDir (char *d)
+{
+ char **dirs;
+ char *dir;
+ char *h;
+
+ if (*d == '~')
+ {
+ h = getenv ("HOME");
+ if (!h)
+ return False;
+ dir = (char *) malloc (strlen (h) + strlen (d));
+ if (!dir)
+ return False;
+ strcpy (dir, h);
+ strcat (dir, d+1);
+ }
+ else
+ {
+ dir = (char *) malloc (strlen (d) + 1);
+ if (!dir)
+ return False;
+ strcpy (dir, d);
+ }
+ dirs = (char **) malloc ((MiniXftConfigNdirs + 2) * sizeof (char *));
+ if (!dirs)
+ {
+ free (dir);
+ return False;
+ }
+ if (MiniXftConfigNdirs)
+ {
+ memcpy (dirs, MiniXftConfigDirs, MiniXftConfigNdirs * sizeof (char *));
+ }
+ dirs[MiniXftConfigNdirs] = dir;
+ MiniXftConfigNdirs++;
+ dirs[MiniXftConfigNdirs] = 0;
+ if (MiniXftConfigDirs != MiniXftConfigDefaultDirs)
+ free (MiniXftConfigDirs);
+ MiniXftConfigDirs = dirs;
+ return True;
+}
+
+Bool
+MiniXftConfigSetCache (char *c)
+{
+ char *new;
+ char *h;
+
+ if (*c == '~')
+ {
+ h = getenv ("HOME");
+ if (!h)
+ return False;
+ new = (char *) malloc (strlen (h) + strlen (c));
+ if (!new)
+ return False;
+ strcpy (new, h);
+ strcat (new, c+1);
+ }
+ else
+ {
+ new = _MiniXftSaveString (c);
+ }
+ if (MiniXftConfigCache)
+ free (MiniXftConfigCache);
+ MiniXftConfigCache = new;
+ return True;
+}
+
+char *
+MiniXftConfigGetCache (void)
+{
+ if (!MiniXftConfigCache)
+ MiniXftConfigSetCache (MiniXftConfigDefaultCache);
+ return MiniXftConfigCache;
+}
+
+static int MiniXftSubstsMaxObjects;
+
+Bool
+MiniXftConfigAddEdit (MiniXftTest *test, MiniXftEdit *edit)
+{
+ MiniXftSubst *subst, **prev;
+ MiniXftTest *t;
+ int num;
+
+ subst = (MiniXftSubst *) malloc (sizeof (MiniXftSubst));
+ if (!subst)
+ return False;
+ for (prev = &MiniXftSubsts; *prev; prev = &(*prev)->next);
+ *prev = subst;
+ subst->next = 0;
+ subst->test = test;
+ subst->edit = edit;
+#ifdef XFT_DEBUG_EDIT
+ printf ("Add Subst ");
+ MiniXftSubstPrint (subst);
+#endif
+ num = 0;
+ for (t = test; t; t = t->next)
+ num++;
+ if (MiniXftSubstsMaxObjects < num)
+ MiniXftSubstsMaxObjects = num;
+ return True;
+}
+
+typedef struct _MiniXftSubState {
+ MiniXftPatternElt *elt;
+ MiniXftValueList *value;
+} MiniXftSubState;
+
+static MiniXftMatrix MiniXftIdentityMatrix = { 1, 0, 0, 1 };
+
+static MiniXftValue
+_MiniXftConfigPromote (MiniXftValue v, MiniXftValue u)
+{
+ if (v.type == MiniXftTypeInteger)
+ {
+ v.type = MiniXftTypeDouble;
+ v.u.d = (double) v.u.i;
+ }
+ if (v.type == MiniXftTypeVoid && u.type == MiniXftTypeMatrix)
+ {
+ v.u.m = &MiniXftIdentityMatrix;
+ v.type = MiniXftTypeMatrix;
+ }
+ return v;
+}
+
+Bool
+_MiniXftConfigCompareValue (MiniXftValue m,
+ MiniXftOp op,
+ MiniXftValue v)
+{
+ Bool ret;
+
+ if (m.type == MiniXftTypeVoid)
+ return True;
+ m = _MiniXftConfigPromote (m, v);
+ v = _MiniXftConfigPromote (v, m);
+ if (m.type == v.type)
+ {
+ ret = False;
+ switch (m.type) {
+ case MiniXftTypeDouble:
+ switch (op) {
+ case MiniXftOpEqual:
+ ret = m.u.d == v.u.d;
+ break;
+ case MiniXftOpNotEqual:
+ ret = m.u.d != v.u.d;
+ break;
+ case MiniXftOpLess:
+ ret = m.u.d < v.u.d;
+ break;
+ case MiniXftOpLessEqual:
+ ret = m.u.d <= v.u.d;
+ break;
+ case MiniXftOpMore:
+ ret = m.u.d > v.u.d;
+ break;
+ case MiniXftOpMoreEqual:
+ ret = m.u.d >= v.u.d;
+ break;
+ default:
+ break;
+ }
+ break;
+ case MiniXftTypeBool:
+ switch (op) {
+ case MiniXftOpEqual:
+ ret = m.u.b == v.u.b;
+ break;
+ case MiniXftOpNotEqual:
+ ret = m.u.b != v.u.b;
+ break;
+ default:
+ break;
+ }
+ break;
+ case MiniXftTypeString:
+ switch (op) {
+ case MiniXftOpEqual:
+ ret = _MiniXftStrCmpIgnoreCase (m.u.s, v.u.s) == 0;
+ break;
+ case MiniXftOpNotEqual:
+ ret = _MiniXftStrCmpIgnoreCase (m.u.s, v.u.s) != 0;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ if (op == MiniXftOpNotEqual)
+ ret = True;
+ else
+ ret = False;
+ }
+ return ret;
+}
+
+static MiniXftValueList *
+_MiniXftConfigMatchValueList (MiniXftTest *t,
+ MiniXftValueList *v)
+{
+ MiniXftValueList *ret = 0;
+
+ for (; v; v = v->next)
+ {
+ if (_MiniXftConfigCompareValue (v->value, t->op, t->value))
+ {
+ if (!ret)
+ ret = v;
+ }
+ else
+ {
+ if (t->qual == MiniXftQualAll)
+ {
+ ret = 0;
+ break;
+ }
+ }
+ }
+ return ret;
+}
+
+static MiniXftValue
+_MiniXftConfigEvaluate (MiniXftPattern *p, MiniXftExpr *e)
+{
+ MiniXftValue v, vl, vr;
+ MiniXftResult r;
+
+ switch (e->op) {
+ case MiniXftOpInteger:
+ v.type = MiniXftTypeInteger;
+ v.u.i = e->u.ival;
+ break;
+ case MiniXftOpDouble:
+ v.type = MiniXftTypeDouble;
+ v.u.d = e->u.dval;
+ break;
+ case MiniXftOpString:
+ v.type = MiniXftTypeString;
+ v.u.s = e->u.sval;
+ break;
+ case MiniXftOpMatrix:
+ v.type = MiniXftTypeMatrix;
+ v.u.m = e->u.mval;
+ break;
+ case MiniXftOpBool:
+ v.type = MiniXftTypeBool;
+ v.u.b = e->u.bval;
+ break;
+ case MiniXftOpField:
+ r = MiniXftPatternGet (p, e->u.field, 0, &v);
+ if (r != MiniXftResultMatch)
+ v.type = MiniXftTypeVoid;
+ break;
+ case MiniXftOpQuest:
+ vl = _MiniXftConfigEvaluate (p, e->u.tree.left);
+ if (vl.type == MiniXftTypeBool)
+ {
+ if (vl.u.b)
+ v = _MiniXftConfigEvaluate (p, e->u.tree.right->u.tree.left);
+ else
+ v = _MiniXftConfigEvaluate (p, e->u.tree.right->u.tree.right);
+ }
+ else
+ v.type = MiniXftTypeVoid;
+ break;
+ case MiniXftOpOr:
+ case MiniXftOpAnd:
+ case MiniXftOpEqual:
+ case MiniXftOpNotEqual:
+ case MiniXftOpLess:
+ case MiniXftOpLessEqual:
+ case MiniXftOpMore:
+ case MiniXftOpMoreEqual:
+ case MiniXftOpPlus:
+ case MiniXftOpMinus:
+ case MiniXftOpTimes:
+ case MiniXftOpDivide:
+ vl = _MiniXftConfigEvaluate (p, e->u.tree.left);
+ vr = _MiniXftConfigEvaluate (p, e->u.tree.right);
+ vl = _MiniXftConfigPromote (vl, vr);
+ vr = _MiniXftConfigPromote (vr, vl);
+ if (vl.type == vr.type)
+ {
+ switch (vl.type) {
+ case MiniXftTypeDouble:
+ switch (e->op) {
+ case MiniXftOpPlus:
+ v.type = MiniXftTypeDouble;
+ v.u.d = vl.u.d + vr.u.d;
+ break;
+ case MiniXftOpMinus:
+ v.type = MiniXftTypeDouble;
+ v.u.d = vl.u.d - vr.u.d;
+ break;
+ case MiniXftOpTimes:
+ v.type = MiniXftTypeDouble;
+ v.u.d = vl.u.d * vr.u.d;
+ break;
+ case MiniXftOpDivide:
+ v.type = MiniXftTypeDouble;
+ v.u.d = vl.u.d / vr.u.d;
+ break;
+ case MiniXftOpEqual:
+ v.type = MiniXftTypeBool;
+ v.u.b = vl.u.d == vr.u.d;
+ break;
+ case MiniXftOpNotEqual:
+ v.type = MiniXftTypeBool;
+ v.u.b = vl.u.d != vr.u.d;
+ break;
+ case MiniXftOpLess:
+ v.type = MiniXftTypeBool;
+ v.u.b = vl.u.d < vr.u.d;
+ break;
+ case MiniXftOpLessEqual:
+ v.type = MiniXftTypeBool;
+ v.u.b = vl.u.d <= vr.u.d;
+ break;
+ case MiniXftOpMore:
+ v.type = MiniXftTypeBool;
+ v.u.b = vl.u.d > vr.u.d;
+ break;
+ case MiniXftOpMoreEqual:
+ v.type = MiniXftTypeBool;
+ v.u.b = vl.u.d >= vr.u.d;
+ break;
+ default:
+ v.type = MiniXftTypeVoid;
+ break;
+ }
+ if (v.type == MiniXftTypeDouble &&
+ v.u.d == (double) (int) v.u.d)
+ {
+ v.type = MiniXftTypeInteger;
+ v.u.i = (int) v.u.d;
+ }
+ break;
+ case MiniXftTypeBool:
+ switch (e->op) {
+ case MiniXftOpOr:
+ v.type = MiniXftTypeBool;
+ v.u.b = vl.u.b || vr.u.b;
+ break;
+ case MiniXftOpAnd:
+ v.type = MiniXftTypeBool;
+ v.u.b = vl.u.b && vr.u.b;
+ break;
+ case MiniXftOpEqual:
+ v.type = MiniXftTypeBool;
+ v.u.b = vl.u.b == vr.u.b;
+ break;
+ case MiniXftOpNotEqual:
+ v.type = MiniXftTypeBool;
+ v.u.b = vl.u.b != vr.u.b;
+ break;
+ default:
+ v.type = MiniXftTypeVoid;
+ break;
+ }
+ break;
+ case MiniXftTypeString:
+ switch (e->op) {
+ case MiniXftOpEqual:
+ v.type = MiniXftTypeBool;
+ v.u.b = _MiniXftStrCmpIgnoreCase (vl.u.s, vr.u.s) == 0;
+ break;
+ case MiniXftOpNotEqual:
+ v.type = MiniXftTypeBool;
+ v.u.b = _MiniXftStrCmpIgnoreCase (vl.u.s, vr.u.s) != 0;
+ break;
+ case MiniXftOpPlus:
+ v.type = MiniXftTypeString;
+ v.u.s = malloc (strlen (vl.u.s) + strlen (vr.u.s) + 1);
+ if (v.u.s)
+ {
+ strcpy (v.u.s, vl.u.s);
+ strcat (v.u.s, vr.u.s);
+ }
+ else
+ v.type = MiniXftTypeVoid;
+ break;
+ default:
+ v.type = MiniXftTypeVoid;
+ break;
+ }
+ case MiniXftTypeMatrix:
+ switch (e->op) {
+ case MiniXftOpEqual:
+ v.type = MiniXftTypeBool;
+ v.u.b = MiniXftMatrixEqual (vl.u.m, vr.u.m) == 0;
+ break;
+ case MiniXftOpNotEqual:
+ v.type = MiniXftTypeBool;
+ v.u.b = MiniXftMatrixEqual (vl.u.m, vr.u.m) != 0;
+ break;
+ case MiniXftOpTimes:
+ v.type = MiniXftTypeMatrix;
+ v.u.m = malloc (sizeof (MiniXftMatrix));
+ MiniXftMatrixMultiply (v.u.m, vl.u.m, vr.u.m);
+ break;
+ default:
+ v.type = MiniXftTypeVoid;
+ break;
+ }
+ break;
+ default:
+ v.type = MiniXftTypeVoid;
+ break;
+ }
+ }
+ else
+ v.type = MiniXftTypeVoid;
+ break;
+ case MiniXftOpNot:
+ vl = _MiniXftConfigEvaluate (p, e->u.tree.left);
+ switch (vl.type) {
+ case MiniXftTypeBool:
+ v.type = MiniXftTypeBool;
+ v.u.b = !vl.u.b;
+ break;
+ default:
+ v.type = MiniXftTypeVoid;
+ break;
+ }
+ break;
+ default:
+ v.type = MiniXftTypeVoid;
+ break;
+ }
+ return v;
+}
+
+static Bool
+_MiniXftConfigAdd (MiniXftValueList **head,
+ MiniXftValueList *position,
+ Bool append,
+ MiniXftValue value)
+{
+ MiniXftValueList *new, **prev;
+
+ new = (MiniXftValueList *) malloc (sizeof (MiniXftValueList));
+ if (!new)
+ goto bail0;
+
+ if (value.type == MiniXftTypeString)
+ {
+ value.u.s = _MiniXftSaveString (value.u.s);
+ if (!value.u.s)
+ goto bail1;
+
+ }
+ new->value = value;
+ new->next = 0;
+
+ if (append)
+ {
+ prev = &position->next;
+ }
+ else
+ {
+ for (prev = head; *prev; prev = &(*prev)->next)
+ {
+ if (*prev == position)
+ break;
+ }
+#ifdef XFT_DEBUG
+ if (!*prev)
+ printf ("position not on list\n");
+#endif
+ }
+
+#ifdef XFT_DEBUG_EDIT
+ printf ("%s list before ", append ? "Append" : "Prepend");
+ MiniXftValueListPrint (*head);
+ printf ("\n");
+#endif
+
+ new->next = *prev;
+ *prev = new;
+
+#ifdef XFT_DEBUG_EDIT
+ printf ("%s list after ", append ? "Append" : "Prepend");
+ MiniXftValueListPrint (*head);
+ printf ("\n");
+#endif
+
+ return True;
+
+bail1:
+ free (new);
+bail0:
+ return False;
+}
+
+static void
+_MiniXftConfigDel (MiniXftValueList **head,
+ MiniXftValueList *position)
+{
+ MiniXftValueList **prev;
+
+ for (prev = head; *prev; prev = &(*prev)->next)
+ {
+ if (*prev == position)
+ {
+ *prev = position->next;
+ position->next = 0;
+ MiniXftValueListDestroy (position);
+ break;
+ }
+ }
+}
+
+Bool
+MiniXftConfigSubstitute (MiniXftPattern *p)
+{
+ MiniXftSubst *s;
+ MiniXftSubState *st;
+ int i;
+ MiniXftTest *t;
+ MiniXftEdit *e;
+ MiniXftValue v;
+
+ st = (MiniXftSubState *) malloc (MiniXftSubstsMaxObjects * sizeof (MiniXftSubState));
+ if (!st && MiniXftSubstsMaxObjects)
+ return False;
+
+#ifdef XFT_DEBUG_EDIT
+ printf ("MiniXftConfigSubstitute ");
+ MiniXftPatternPrint (p);
+#endif
+ for (s = MiniXftSubsts; s; s = s->next)
+ {
+ for (t = s->test, i = 0; t; t = t->next, i++)
+ {
+#ifdef XFT_DEBUG_EDIT
+ printf ("MiniXftConfigSubstitute test ");
+ MiniXftTestPrint (t);
+#endif
+ st[i].elt = MiniXftPatternFind (p, t->field, False);
+ if (!st[i].elt)
+ {
+ if (t->qual == MiniXftQualAll)
+ continue;
+ else
+ break;
+ }
+ st[i].value = _MiniXftConfigMatchValueList (t, st[i].elt->values);
+ if (!st[i].value)
+ break;
+ }
+ if (t)
+ {
+#ifdef XFT_DEBUG_EDIT
+ printf ("No match\n");
+#endif
+ continue;
+ }
+#ifdef XFT_DEBUG_EDIT
+ printf ("Substitute ");
+ MiniXftSubstPrint (s);
+#endif
+ for (e = s->edit; e; e = e->next)
+ {
+ v = _MiniXftConfigEvaluate (p, e->expr);
+ if (v.type == MiniXftTypeVoid)
+ continue;
+ for (t = s->test, i = 0; t; t = t->next, i++)
+ if (!_MiniXftStrCmpIgnoreCase (t->field, e->field))
+ break;
+ switch (e->op) {
+ case MiniXftOpAssign:
+ if (t)
+ {
+ _MiniXftConfigAdd (&st[i].elt->values, st[i].value, True, v);
+ _MiniXftConfigDel (&st[i].elt->values, st[i].value);
+ }
+ else
+ {
+ MiniXftPatternDel (p, e->field);
+ MiniXftPatternAdd (p, e->field, v, True);
+ }
+ break;
+ case MiniXftOpPrepend:
+ if (t)
+ _MiniXftConfigAdd (&st[i].elt->values, st[i].value, False, v);
+ else
+ MiniXftPatternAdd (p, e->field, v, False);
+ break;
+ case MiniXftOpAppend:
+ if (t)
+ _MiniXftConfigAdd (&st[i].elt->values, st[i].value, True, v);
+ else
+ MiniXftPatternAdd (p, e->field, v, True);
+ break;
+ default:
+ break;
+ }
+ }
+#ifdef XFT_DEBUG_EDIT
+ printf ("MiniXftConfigSubstitute edit");
+ MiniXftPatternPrint (p);
+#endif
+ }
+ free (st);
+#ifdef XFT_DEBUG_EDIT
+ printf ("MiniXftConfigSubstitute done");
+ MiniXftPatternPrint (p);
+#endif
+ return True;
+}
diff --git a/pango/mini-xft/minixftdbg.c b/pango/mini-xft/minixftdbg.c
new file mode 100644
index 00000000..1912d8f5
--- /dev/null
+++ b/pango/mini-xft/minixftdbg.c
@@ -0,0 +1,230 @@
+/*
+ * $XFree86: xc/lib/MiniXft/xftdbg.c,v 1.3 2001/03/31 01:57:20 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "minixftint.h"
+#include <stdio.h>
+
+void
+MiniXftValuePrint (MiniXftValue v)
+{
+ switch (v.type) {
+ case MiniXftTypeVoid:
+ printf (" <void>");
+ break;
+ case MiniXftTypeInteger:
+ printf (" %d", v.u.i);
+ break;
+ case MiniXftTypeDouble:
+ printf (" %g", v.u.d);
+ break;
+ case MiniXftTypeString:
+ printf (" \"%s\"", v.u.s);
+ break;
+ case MiniXftTypeBool:
+ printf (" %s", v.u.b ? "True" : "False");
+ break;
+ case MiniXftTypeMatrix:
+ printf (" (%f %f; %f %f)", v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy);
+ break;
+ }
+}
+
+void
+MiniXftValueListPrint (MiniXftValueList *l)
+{
+ for (; l; l = l->next)
+ MiniXftValuePrint (l->value);
+}
+
+void
+MiniXftPatternPrint (MiniXftPattern *p)
+{
+ int i;
+ MiniXftPatternElt *e;
+
+ printf ("Pattern %d of %d\n", p->num, p->size);
+ for (i = 0; i < p->num; i++)
+ {
+ e = &p->elts[i];
+ printf ("\t%s:", e->object);
+ MiniXftValueListPrint (e->values);
+ printf ("\n");
+ }
+ printf ("\n");
+}
+
+void
+MiniXftOpPrint (MiniXftOp op)
+{
+ switch (op) {
+ case MiniXftOpInteger: printf ("Integer"); break;
+ case MiniXftOpDouble: printf ("Double"); break;
+ case MiniXftOpString: printf ("String"); break;
+ case MiniXftOpMatrix: printf ("Matrix"); break;
+ case MiniXftOpBool: printf ("Bool"); break;
+ case MiniXftOpField: printf ("Field"); break;
+ case MiniXftOpAssign: printf ("Assign"); break;
+ case MiniXftOpPrepend: printf ("Prepend"); break;
+ case MiniXftOpAppend: printf ("Append"); break;
+ case MiniXftOpQuest: printf ("Quest"); break;
+ case MiniXftOpOr: printf ("Or"); break;
+ case MiniXftOpAnd: printf ("And"); break;
+ case MiniXftOpEqual: printf ("Equal"); break;
+ case MiniXftOpNotEqual: printf ("NotEqual"); break;
+ case MiniXftOpLess: printf ("Less"); break;
+ case MiniXftOpLessEqual: printf ("LessEqual"); break;
+ case MiniXftOpMore: printf ("More"); break;
+ case MiniXftOpMoreEqual: printf ("MoreEqual"); break;
+ case MiniXftOpPlus: printf ("Plus"); break;
+ case MiniXftOpMinus: printf ("Minus"); break;
+ case MiniXftOpTimes: printf ("Times"); break;
+ case MiniXftOpDivide: printf ("Divide"); break;
+ case MiniXftOpNot: printf ("Not"); break;
+ case MiniXftOpNil: printf ("Nil"); break;
+ }
+}
+
+void
+MiniXftTestPrint (MiniXftTest *test)
+{
+ switch (test->qual) {
+ case MiniXftQualAny:
+ printf ("any ");
+ break;
+ case MiniXftQualAll:
+ printf ("all ");
+ break;
+ }
+ printf ("%s ", test->field);
+ MiniXftOpPrint (test->op);
+ printf (" ");
+ MiniXftValuePrint (test->value);
+ printf ("\n");
+}
+
+void
+MiniXftExprPrint (MiniXftExpr *expr)
+{
+ switch (expr->op) {
+ case MiniXftOpInteger: printf ("%d", expr->u.ival); break;
+ case MiniXftOpDouble: printf ("%g", expr->u.dval); break;
+ case MiniXftOpString: printf ("\"%s\"", expr->u.sval); break;
+ case MiniXftOpMatrix: printf ("[%g %g %g %g]",
+ expr->u.mval->xx,
+ expr->u.mval->xy,
+ expr->u.mval->yx,
+ expr->u.mval->yy);
+ case MiniXftOpBool: printf ("%s", expr->u.bval ? "true" : "false"); break;
+ case MiniXftOpField: printf ("%s", expr->u.field); break;
+ case MiniXftOpQuest:
+ MiniXftExprPrint (expr->u.tree.left);
+ printf (" quest ");
+ MiniXftExprPrint (expr->u.tree.right->u.tree.left);
+ printf (" colon ");
+ MiniXftExprPrint (expr->u.tree.right->u.tree.right);
+ break;
+ case MiniXftOpOr:
+ case MiniXftOpAnd:
+ case MiniXftOpEqual:
+ case MiniXftOpNotEqual:
+ case MiniXftOpLess:
+ case MiniXftOpLessEqual:
+ case MiniXftOpMore:
+ case MiniXftOpMoreEqual:
+ case MiniXftOpPlus:
+ case MiniXftOpMinus:
+ case MiniXftOpTimes:
+ case MiniXftOpDivide:
+ MiniXftExprPrint (expr->u.tree.left);
+ printf (" ");
+ switch (expr->op) {
+ case MiniXftOpOr: printf ("Or"); break;
+ case MiniXftOpAnd: printf ("And"); break;
+ case MiniXftOpEqual: printf ("Equal"); break;
+ case MiniXftOpNotEqual: printf ("NotEqual"); break;
+ case MiniXftOpLess: printf ("Less"); break;
+ case MiniXftOpLessEqual: printf ("LessEqual"); break;
+ case MiniXftOpMore: printf ("More"); break;
+ case MiniXftOpMoreEqual: printf ("MoreEqual"); break;
+ case MiniXftOpPlus: printf ("Plus"); break;
+ case MiniXftOpMinus: printf ("Minus"); break;
+ case MiniXftOpTimes: printf ("Times"); break;
+ case MiniXftOpDivide: printf ("Divide"); break;
+ default: break;
+ }
+ printf (" ");
+ MiniXftExprPrint (expr->u.tree.right);
+ break;
+ case MiniXftOpNot:
+ printf ("Not ");
+ MiniXftExprPrint (expr->u.tree.left);
+ break;
+ default:
+ break;
+ }
+}
+
+void
+MiniXftEditPrint (MiniXftEdit *edit)
+{
+ printf ("Edit %s ", edit->field);
+ MiniXftOpPrint (edit->op);
+ printf (" ");
+ MiniXftExprPrint (edit->expr);
+}
+
+void
+MiniXftSubstPrint (MiniXftSubst *subst)
+{
+ MiniXftEdit *e;
+ MiniXftTest *t;
+
+ printf ("match\n");
+ for (t = subst->test; t; t = t->next)
+ {
+ printf ("\t");
+ MiniXftTestPrint (t);
+ }
+ printf ("edit\n");
+ for (e = subst->edit; e; e = e->next)
+ {
+ printf ("\t");
+ MiniXftEditPrint (e);
+ printf (";\n");
+ }
+ printf ("\n");
+}
+
+void
+MiniXftFontSetPrint (MiniXftFontSet *s)
+{
+ int i;
+
+ printf ("FontSet %d of %d\n", s->nfont, s->sfont);
+ for (i = 0; i < s->nfont; i++)
+ {
+ printf ("Font %d ", i);
+ MiniXftPatternPrint (s->fonts[i]);
+ }
+}
diff --git a/pango/mini-xft/minixftdir.c b/pango/mini-xft/minixftdir.c
new file mode 100644
index 00000000..c6eacb10
--- /dev/null
+++ b/pango/mini-xft/minixftdir.c
@@ -0,0 +1,136 @@
+/*
+ * $XFree86: xc/lib/MiniXft/xftdir.c,v 1.3 2001/05/16 10:32:54 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <dirent.h>
+#include <stdlib.h>
+#include <string.h>
+#include "minixftint.h"
+
+Bool
+MiniXftDirScan (MiniXftFontSet *set, const char *dir, Bool force)
+{
+ DIR *d;
+ struct dirent *e;
+ char *file;
+ char *base;
+ MiniXftPattern *font;
+ char *name;
+ int count;
+ Bool ret = True;
+ int id;
+
+ file = (char *) malloc (strlen (dir) + 1 + 256 + 1);
+ if (!file)
+ return False;
+
+ strcpy (file, dir);
+ strcat (file, "/");
+ base = file + strlen (file);
+ if (!force)
+ {
+ strcpy (base, "MiniXftCache");
+
+ if (MiniXftFileCacheReadDir (set, file))
+ {
+ free (file);
+ return True;
+ }
+ }
+
+ d = opendir (dir);
+ if (!d)
+ {
+ free (file);
+ return False;
+ }
+ while (ret && (e = readdir (d)))
+ {
+ if (e->d_name[0] != '.')
+ {
+ id = 0;
+ strcpy (base, e->d_name);
+ do
+ {
+ if (!force)
+ name = MiniXftFileCacheFind (file, id, &count);
+ else
+ name = 0;
+ if (name)
+ {
+ font = MiniXftNameParse (name);
+ if (font)
+ MiniXftPatternAddString (font, XFT_FILE, file);
+ }
+ else
+ {
+ font = MiniXftFreeTypeQuery (file, id, &count);
+ if (font && !force)
+ {
+ char unparse[8192];
+
+ if (MiniXftNameUnparse (font, unparse, sizeof (unparse)))
+ {
+ (void) MiniXftFileCacheUpdate (file, id, unparse);
+ }
+ }
+ }
+ if (font)
+ {
+ if (!MiniXftFontSetAdd (set, font))
+ {
+ MiniXftPatternDestroy (font);
+ font = 0;
+ ret = False;
+ }
+ }
+ id++;
+ } while (font && ret && id < count);
+ }
+ }
+ free (file);
+ closedir (d);
+ return ret;
+}
+
+Bool
+MiniXftDirSave (MiniXftFontSet *set, const char *dir)
+{
+ char *file;
+ char *base;
+ Bool ret;
+
+ file = (char *) malloc (strlen (dir) + 1 + 256 + 1);
+ if (!file)
+ return False;
+
+ strcpy (file, dir);
+ strcat (file, "/");
+ base = file + strlen (file);
+ strcpy (base, "MiniXftCache");
+ ret = MiniXftFileCacheWriteDir (set, file);
+ free (file);
+ return ret;
+}
+
diff --git a/pango/mini-xft/minixftdpy.c b/pango/mini-xft/minixftdpy.c
new file mode 100644
index 00000000..6dbf061f
--- /dev/null
+++ b/pango/mini-xft/minixftdpy.c
@@ -0,0 +1,321 @@
+/*
+ * $XFree86: xc/lib/MiniXft/xftdpy.c,v 1.7 2001/04/29 03:21:17 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include "minixftint.h"
+
+MiniXftDisplayInfo *_MiniXftDisplayInfo;
+
+static MiniXftDisplayInfo *
+_MiniXftDisplayInfoGet (Display *dpy)
+{
+ MiniXftDisplayInfo *info, **prev;
+
+ for (prev = &_MiniXftDisplayInfo; (info = *prev); prev = &(*prev)->next)
+ {
+ if (info->display == dpy)
+ {
+ /*
+ * MRU the list
+ */
+ if (prev != &_MiniXftDisplayInfo)
+ {
+ *prev = info->next;
+ info->next = _MiniXftDisplayInfo;
+ _MiniXftDisplayInfo = info;
+ }
+ return info;
+ }
+ }
+ info = (MiniXftDisplayInfo *) malloc (sizeof (MiniXftDisplayInfo));
+ if (!info)
+ goto bail0;
+
+ info->display = dpy;
+ info->defaults = 0;
+
+ info->next = _MiniXftDisplayInfo;
+ _MiniXftDisplayInfo = info;
+ return info;
+
+bail0:
+ if (_MiniXftFontDebug () & XFT_DBG_RENDER)
+ {
+ printf ("MiniXftDisplayInfoGet failed to initialize, MiniXft unhappy\n");
+ }
+ return 0;
+}
+
+Bool
+MiniXftDefaultHasRender (Display *dpy)
+{
+ return True;
+}
+
+Bool
+MiniXftDefaultSet (Display *dpy, MiniXftPattern *defaults)
+{
+ MiniXftDisplayInfo *info = _MiniXftDisplayInfoGet (dpy);
+
+ if (!info)
+ return False;
+ if (info->defaults)
+ MiniXftPatternDestroy (info->defaults);
+ info->defaults = defaults;
+ return True;
+}
+
+int
+MiniXftDefaultParseBool (char *v)
+{
+ char c0, c1;
+
+ c0 = *v;
+ if (isupper (c0))
+ c0 = tolower (c0);
+ if (c0 == 't' || c0 == 'y' || c0 == '1')
+ return 1;
+ if (c0 == 'f' || c0 == 'n' || c0 == '0')
+ return 0;
+ if (c0 == 'o')
+ {
+ c1 = v[1];
+ if (isupper (c1))
+ c1 = tolower (c1);
+ if (c1 == 'n')
+ return 1;
+ if (c1 == 'f')
+ return 0;
+ }
+ return -1;
+}
+
+static Bool
+_MiniXftDefaultInitBool (Display *dpy, MiniXftPattern *pat, char *option)
+{
+ return True;
+}
+
+static Bool
+_MiniXftDefaultInitDouble (Display *dpy, MiniXftPattern *pat, char *option)
+{
+ return True;
+}
+
+static Bool
+_MiniXftDefaultInitInteger (Display *dpy, MiniXftPattern *pat, char *option)
+{
+ return True;
+}
+
+static MiniXftPattern *
+_MiniXftDefaultInit (Display *dpy)
+{
+ MiniXftPattern *pat;
+
+ pat = MiniXftPatternCreate ();
+ if (!pat)
+ goto bail0;
+
+ if (!_MiniXftDefaultInitBool (dpy, pat, XFT_CORE))
+ goto bail1;
+ if (!_MiniXftDefaultInitDouble (dpy, pat, XFT_SCALE))
+ goto bail1;
+ if (!_MiniXftDefaultInitDouble (dpy, pat, XFT_DPI))
+ goto bail1;
+ if (!_MiniXftDefaultInitBool (dpy, pat, XFT_RENDER))
+ goto bail1;
+ if (!_MiniXftDefaultInitInteger (dpy, pat, XFT_RGBA))
+ goto bail1;
+ if (!_MiniXftDefaultInitBool (dpy, pat, XFT_ANTIALIAS))
+ goto bail1;
+ if (!_MiniXftDefaultInitBool (dpy, pat, XFT_MINSPACE))
+ goto bail1;
+
+ return pat;
+
+bail1:
+ MiniXftPatternDestroy (pat);
+bail0:
+ return 0;
+}
+
+static MiniXftResult
+_MiniXftDefaultGet (Display *dpy, const char *object, int screen, MiniXftValue *v)
+{
+ MiniXftDisplayInfo *info = _MiniXftDisplayInfoGet (dpy);
+ MiniXftResult r;
+
+ if (!info)
+ return MiniXftResultNoMatch;
+
+ if (!info->defaults)
+ {
+ info->defaults = _MiniXftDefaultInit (dpy);
+ if (!info->defaults)
+ return MiniXftResultNoMatch;
+ }
+ r = MiniXftPatternGet (info->defaults, object, screen, v);
+ if (r == MiniXftResultNoId && screen > 0)
+ r = MiniXftPatternGet (info->defaults, object, 0, v);
+ return r;
+}
+
+Bool
+MiniXftDefaultGetBool (Display *dpy, const char *object, int screen, Bool def)
+{
+ MiniXftResult r;
+ MiniXftValue v;
+
+ r = _MiniXftDefaultGet (dpy, object, screen, &v);
+ if (r != MiniXftResultMatch || v.type != MiniXftTypeBool)
+ return def;
+ return v.u.b;
+}
+
+int
+MiniXftDefaultGetInteger (Display *dpy, const char *object, int screen, int def)
+{
+ MiniXftResult r;
+ MiniXftValue v;
+
+ r = _MiniXftDefaultGet (dpy, object, screen, &v);
+ if (r != MiniXftResultMatch || v.type != MiniXftTypeInteger)
+ return def;
+ return v.u.i;
+}
+
+double
+MiniXftDefaultGetDouble (Display *dpy, const char *object, int screen, double def)
+{
+ MiniXftResult r;
+ MiniXftValue v;
+
+ r = _MiniXftDefaultGet (dpy, object, screen, &v);
+ if (r != MiniXftResultMatch || v.type != MiniXftTypeDouble)
+ return def;
+ return v.u.d;
+}
+
+MiniXftFontSet *
+MiniXftDisplayGetFontSet (Display *dpy)
+{
+ return 0;
+}
+
+static double default_dpi = 0.0;
+
+void
+MiniXftSetDPI (double dpi)
+{
+ default_dpi = dpi;
+}
+
+void
+MiniXftDefaultSubstitute (Display *dpy, int screen, MiniXftPattern *pattern)
+{
+ MiniXftValue v;
+ double size;
+ double scale;
+
+ if (MiniXftPatternGet (pattern, XFT_STYLE, 0, &v) == MiniXftResultNoMatch)
+ {
+ if (MiniXftPatternGet (pattern, XFT_WEIGHT, 0, &v) == MiniXftResultNoMatch )
+ {
+ MiniXftPatternAddInteger (pattern, XFT_WEIGHT, XFT_WEIGHT_MEDIUM);
+ }
+ if (MiniXftPatternGet (pattern, XFT_SLANT, 0, &v) == MiniXftResultNoMatch)
+ {
+ MiniXftPatternAddInteger (pattern, XFT_SLANT, XFT_SLANT_ROMAN);
+ }
+ }
+ if (MiniXftPatternGet (pattern, XFT_ENCODING, 0, &v) == MiniXftResultNoMatch)
+ MiniXftPatternAddString (pattern, XFT_ENCODING, "iso8859-1");
+ if (MiniXftPatternGet (pattern, XFT_RENDER, 0, &v) == MiniXftResultNoMatch)
+ {
+ MiniXftPatternAddBool (pattern, XFT_RENDER,
+ MiniXftDefaultGetBool (dpy, XFT_RENDER, screen,
+ MiniXftDefaultHasRender (dpy)));
+ }
+ if (MiniXftPatternGet (pattern, XFT_CORE, 0, &v) == MiniXftResultNoMatch)
+ {
+ MiniXftPatternAddBool (pattern, XFT_CORE,
+ MiniXftDefaultGetBool (dpy, XFT_CORE, screen,
+ !MiniXftDefaultHasRender (dpy)));
+ }
+ if (MiniXftPatternGet (pattern, XFT_ANTIALIAS, 0, &v) == MiniXftResultNoMatch)
+ {
+ MiniXftPatternAddBool (pattern, XFT_ANTIALIAS,
+ MiniXftDefaultGetBool (dpy, XFT_ANTIALIAS, screen,
+ True));
+ }
+ if (MiniXftPatternGet (pattern, XFT_RGBA, 0, &v) == MiniXftResultNoMatch)
+ {
+ MiniXftPatternAddInteger (pattern, XFT_RGBA,
+ MiniXftDefaultGetInteger (dpy, XFT_RGBA, screen,
+ XFT_RGBA_NONE));
+ }
+ if (MiniXftPatternGet (pattern, XFT_MINSPACE, 0, &v) == MiniXftResultNoMatch)
+ {
+ MiniXftPatternAddBool (pattern, XFT_MINSPACE,
+ MiniXftDefaultGetBool (dpy, XFT_MINSPACE, screen,
+ False));
+ }
+ if (MiniXftPatternGet (pattern, XFT_PIXEL_SIZE, 0, &v) == MiniXftResultNoMatch)
+ {
+ double dpi;
+
+ if (MiniXftPatternGet (pattern, XFT_SIZE, 0, &v) != MiniXftResultMatch)
+ {
+ size = 12.0;
+ MiniXftPatternAddDouble (pattern, XFT_SIZE, size);
+ }
+ else
+ {
+ switch (v.type) {
+ case MiniXftTypeInteger:
+ size = (double) v.u.i;
+ break;
+ case MiniXftTypeDouble:
+ size = v.u.d;
+ break;
+ default:
+ size = 12.0;
+ break;
+ }
+ }
+ scale = MiniXftDefaultGetDouble (dpy, XFT_SCALE, screen, 1.0);
+ size *= scale;
+ if (default_dpi > 0.0)
+ dpi = default_dpi;
+ else
+ dpi = 72.0;
+ dpi = MiniXftDefaultGetDouble (dpy, XFT_DPI, screen, dpi);
+ size = size * dpi / 72.0;
+ MiniXftPatternAddDouble (pattern, XFT_PIXEL_SIZE, size);
+ }
+}
+
diff --git a/pango/mini-xft/minixftfont.c b/pango/mini-xft/minixftfont.c
new file mode 100644
index 00000000..46665c43
--- /dev/null
+++ b/pango/mini-xft/minixftfont.c
@@ -0,0 +1,111 @@
+/*
+ * $XFree86: xc/lib/MiniXft/xftfont.c,v 1.8 2000/12/20 00:20:48 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "minixftint.h"
+
+MiniXftPattern *
+MiniXftFontMatch (Display *dpy, int screen, MiniXftPattern *pattern, MiniXftResult *result)
+{
+ MiniXftPattern *new;
+ MiniXftPattern *match;
+ MiniXftFontSet *sets[2];
+ int nsets;
+ Bool render, core;
+
+ if (!MiniXftInit (0))
+ return 0;
+
+ new = MiniXftPatternDuplicate (pattern);
+ if (!new)
+ return 0;
+
+ if (_MiniXftFontDebug () & XFT_DBG_OPENV)
+ {
+ printf ("MiniXftFontMatch pattern ");
+ MiniXftPatternPrint (new);
+ }
+ MiniXftConfigSubstitute (new);
+ if (_MiniXftFontDebug () & XFT_DBG_OPENV)
+ {
+ printf ("MiniXftFontMatch after MiniXftConfig substitutions ");
+ MiniXftPatternPrint (new);
+ }
+ MiniXftDefaultSubstitute (dpy, screen, new);
+ if (_MiniXftFontDebug () & XFT_DBG_OPENV)
+ {
+ printf ("MiniXftFontMatch after X resource substitutions ");
+ MiniXftPatternPrint (new);
+ }
+ nsets = 0;
+
+ render = True;
+ core = False;
+ (void) MiniXftPatternGetBool (new, XFT_RENDER, 0, &render);
+ (void) MiniXftPatternGetBool (new, XFT_CORE, 0, &core);
+ if (_MiniXftFontDebug () & XFT_DBG_OPENV)
+ {
+ printf ("MiniXftFontMatch: use core fonts \"%s\", use render fonts \"%s\"\n",
+ core ? "True" : "False", render ? "True" : "False");
+ }
+
+ if (render)
+ {
+ if (MiniXftInitFtLibrary ())
+ {
+ sets[nsets] = _MiniXftFontSet;
+ if (sets[nsets])
+ nsets++;
+ }
+ }
+
+ match = MiniXftFontSetMatch (sets, nsets, new, result);
+ MiniXftPatternDestroy (new);
+ return match;
+}
+
+int
+_MiniXftFontDebug (void)
+{
+ static int initialized;
+ static int debug;
+
+ if (!initialized)
+ {
+ char *e;
+
+ initialized = 1;
+ e = getenv ("XFT_DEBUG");
+ if (e)
+ {
+ printf ("XFT_DEBUG=%s\n", e);
+ debug = atoi (e);
+ if (debug <= 0)
+ debug = 1;
+ }
+ }
+ return debug;
+}
+
diff --git a/pango/mini-xft/minixftfreetype.c b/pango/mini-xft/minixftfreetype.c
new file mode 100644
index 00000000..7b92abd4
--- /dev/null
+++ b/pango/mini-xft/minixftfreetype.c
@@ -0,0 +1,190 @@
+/*
+ * $XFree86: xc/lib/MiniXft/xftfreetype.c,v 1.14 2001/09/21 19:54:53 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "minixftint.h"
+
+FT_Library _MiniXftFTlibrary;
+
+typedef struct _MiniXftFtEncoding {
+ const char *name;
+ FT_Encoding encoding;
+} MiniXftFtEncoding;
+
+static MiniXftFtEncoding xftFtEncoding[] = {
+ { "iso10646-1", ft_encoding_unicode, },
+ { "iso8859-1", ft_encoding_unicode, },
+ { "apple-roman", ft_encoding_apple_roman },
+ { "adobe-fontspecific", ft_encoding_symbol, },
+ { "glyphs-fontspecific",ft_encoding_none, },
+};
+
+#define NUM_FT_ENCODINGS (sizeof xftFtEncoding / sizeof xftFtEncoding[0])
+
+#define FT_Matrix_Equal(a,b) ((a)->xx == (b)->xx && \
+ (a)->yy == (b)->yy && \
+ (a)->xy == (b)->xy && \
+ (a)->yx == (b)->yx)
+
+MiniXftPattern *
+MiniXftFreeTypeQuery (const char *file, int id, int *count)
+{
+ FT_Face face;
+ MiniXftPattern *pat;
+ int slant;
+ int weight;
+ int i, j;
+
+ if (FT_New_Face (_MiniXftFTlibrary, file, id, &face))
+ return 0;
+
+ *count = face->num_faces;
+
+ pat = MiniXftPatternCreate ();
+ if (!pat)
+ goto bail0;
+
+
+ if (!MiniXftPatternAddBool (pat, XFT_CORE, False))
+ goto bail1;
+
+ if (!MiniXftPatternAddBool (pat, XFT_OUTLINE,
+ (face->face_flags & FT_FACE_FLAG_SCALABLE) != 0))
+ goto bail1;
+
+ if (!MiniXftPatternAddBool (pat, XFT_SCALABLE,
+ (face->face_flags & FT_FACE_FLAG_SCALABLE) != 0))
+ goto bail1;
+
+
+ slant = XFT_SLANT_ROMAN;
+ if (face->style_flags & FT_STYLE_FLAG_ITALIC)
+ slant = XFT_SLANT_ITALIC;
+
+ if (!MiniXftPatternAddInteger (pat, XFT_SLANT, slant))
+ goto bail1;
+
+ weight = XFT_WEIGHT_MEDIUM;
+ if (face->style_flags & FT_STYLE_FLAG_BOLD)
+ weight = XFT_WEIGHT_BOLD;
+
+ if (!MiniXftPatternAddInteger (pat, XFT_WEIGHT, weight))
+ goto bail1;
+
+ if (!MiniXftPatternAddString (pat, XFT_FAMILY, face->family_name))
+ goto bail1;
+
+ if (!MiniXftPatternAddString (pat, XFT_STYLE, face->style_name))
+ goto bail1;
+
+ if (!MiniXftPatternAddString (pat, XFT_FILE, file))
+ goto bail1;
+
+ if (!MiniXftPatternAddInteger (pat, XFT_INDEX, id))
+ goto bail1;
+
+#if 0
+ if ((face->face_flags & FT_FACE_FLAG_FIXED_WIDTH) != 0)
+ if (!MiniXftPatternAddInteger (pat, XFT_SPACING, XFT_MONO))
+ goto bail1;
+#endif
+
+ if (!(face->face_flags & FT_FACE_FLAG_SCALABLE))
+ {
+ for (i = 0; i < face->num_fixed_sizes; i++)
+ if (!MiniXftPatternAddDouble (pat, XFT_PIXEL_SIZE,
+ (double) face->available_sizes[i].height))
+ goto bail1;
+ }
+
+ for (i = 0; i < face->num_charmaps; i++)
+ {
+#if 0
+ printf ("face %s encoding %d %c%c%c%c\n",
+ face->family_name, i,
+ face->charmaps[i]->encoding >> 24,
+ face->charmaps[i]->encoding >> 16,
+ face->charmaps[i]->encoding >> 8,
+ face->charmaps[i]->encoding >> 0);
+#endif
+ for (j = 0; j < NUM_FT_ENCODINGS; j++)
+ {
+ if (face->charmaps[i]->encoding == xftFtEncoding[j].encoding)
+ {
+ if (!MiniXftPatternAddString (pat, XFT_ENCODING,
+ xftFtEncoding[j].name))
+ goto bail1;
+ }
+ }
+ }
+
+ if (!MiniXftPatternAddString (pat, XFT_ENCODING,
+ "glyphs-fontspecific"))
+ goto bail1;
+
+
+ FT_Done_Face (face);
+ return pat;
+
+bail1:
+ MiniXftPatternDestroy (pat);
+bail0:
+ FT_Done_Face (face);
+ return 0;
+}
+
+/* #define XFT_DEBUG_FONTSET */
+Bool
+MiniXftInitFtLibrary (void)
+{
+ char **d;
+ char *cache;
+
+ if (_MiniXftFTlibrary)
+ return True;
+ if (FT_Init_FreeType (&_MiniXftFTlibrary))
+ return False;
+ _MiniXftFontSet = MiniXftFontSetCreate ();
+ if (!_MiniXftFontSet)
+ return False;
+ cache = MiniXftConfigGetCache ();
+ if (cache)
+ MiniXftFileCacheLoad (cache);
+ for (d = MiniXftConfigDirs; d && *d; d++)
+ {
+#ifdef XFT_DEBUG_FONTSET
+ printf ("scan dir %s\n", *d);
+#endif
+ MiniXftDirScan (_MiniXftFontSet, *d, False);
+ }
+#ifdef XFT_DEBUG_FONTSET
+ MiniXftFontSetPrint (_MiniXftFontSet);
+#endif
+ if (cache)
+ MiniXftFileCacheSave (cache);
+ MiniXftFileCacheDispose ();
+ return True;
+}
diff --git a/pango/mini-xft/minixftfs.c b/pango/mini-xft/minixftfs.c
new file mode 100644
index 00000000..74c1f444
--- /dev/null
+++ b/pango/mini-xft/minixftfs.c
@@ -0,0 +1,74 @@
+/*
+ * $XFree86: xc/lib/MiniXft/xftfs.c,v 1.1 2000/11/29 08:39:22 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include "minixftint.h"
+
+MiniXftFontSet *
+MiniXftFontSetCreate (void)
+{
+ MiniXftFontSet *s;
+
+ s = (MiniXftFontSet *) malloc (sizeof (MiniXftFontSet));
+ if (!s)
+ return 0;
+ s->nfont = 0;
+ s->sfont = 0;
+ s->fonts = 0;
+ return s;
+}
+
+void
+MiniXftFontSetDestroy (MiniXftFontSet *s)
+{
+ int i;
+
+ for (i = 0; i < s->nfont; i++)
+ MiniXftPatternDestroy (s->fonts[i]);
+ if (s->fonts)
+ free (s->fonts);
+ free (s);
+}
+
+Bool
+MiniXftFontSetAdd (MiniXftFontSet *s, MiniXftPattern *font)
+{
+ MiniXftPattern **f;
+ int sfont;
+
+ if (s->nfont == s->sfont)
+ {
+ sfont = s->sfont + 32;
+ if (s->fonts)
+ f = (MiniXftPattern **) realloc (s->fonts, sfont * sizeof (MiniXftPattern *));
+ else
+ f = (MiniXftPattern **) malloc (sfont * sizeof (MiniXftPattern *));
+ if (!f)
+ return False;
+ s->sfont = sfont;
+ s->fonts = f;
+ }
+ s->fonts[s->nfont++] = font;
+ return True;
+}
diff --git a/pango/mini-xft/minixftgram.c b/pango/mini-xft/minixftgram.c
new file mode 100644
index 00000000..d4798f54
--- /dev/null
+++ b/pango/mini-xft/minixftgram.c
@@ -0,0 +1,1498 @@
+
+/* A Bison parser, made from minixftgram.y
+ by GNU Bison version 1.28 */
+
+#define YYBISON 1 /* Identify Bison output. */
+
+#define INTEGER 257
+#define DOUBLE 258
+#define STRING 259
+#define NAME 260
+#define ANY 261
+#define ALL 262
+#define DIR 263
+#define CACHE 264
+#define INCLUDE 265
+#define INCLUDEIF 266
+#define MATCH 267
+#define EDIT 268
+#define TOK_TRUE 269
+#define TOK_FALSE 270
+#define TOK_NIL 271
+#define EQUAL 272
+#define SEMI 273
+#define OS 274
+#define CS 275
+#define QUEST 276
+#define COLON 277
+#define OROR 278
+#define ANDAND 279
+#define EQEQ 280
+#define NOTEQ 281
+#define LESS 282
+#define LESSEQ 283
+#define MORE 284
+#define MOREEQ 285
+#define PLUS 286
+#define MINUS 287
+#define TIMES 288
+#define DIVIDE 289
+#define NOT 290
+
+#line 25 "minixftgram.y"
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "minixftint.h"
+
+static MiniXftMatrix matrix;
+
+
+#line 35 "minixftgram.y"
+typedef union {
+ int ival;
+ double dval;
+ char *sval;
+ MiniXftExpr *eval;
+ MiniXftPattern *pval;
+ MiniXftValue vval;
+ MiniXftEdit *Eval;
+ MiniXftOp oval;
+ MiniXftQual qval;
+ MiniXftTest *tval;
+} YYSTYPE;
+#include <stdio.h>
+
+#ifndef __cplusplus
+#ifndef __STDC__
+#define const
+#endif
+#endif
+
+
+
+#define YYFINAL 95
+#define YYFLAG -32768
+#define YYNTBASE 37
+
+#define YYTRANSLATE(x) ((unsigned)(x) <= 290 ? MiniXftConfigtranslate[x] : 51)
+
+static const char MiniXftConfigtranslate[] = { 0,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 1, 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34, 35, 36
+};
+
+#if YYDEBUG != 0
+static const short MiniXftConfigprhs[] = { 0,
+ 0, 3, 4, 7, 10, 13, 16, 21, 24, 25,
+ 30, 32, 34, 35, 37, 39, 41, 43, 45, 47,
+ 49, 51, 53, 55, 57, 59, 61, 63, 65, 72,
+ 74, 76, 79, 80, 85, 87, 90, 93, 95, 97,
+ 99, 101, 103, 105, 107, 109, 113, 117, 121, 125,
+ 129, 133, 137, 141, 145, 149, 153, 157, 160
+};
+
+static const short MiniXftConfigrhs[] = { 37,
+ 38, 0, 0, 9, 5, 0, 10, 5, 0, 11,
+ 5, 0, 12, 5, 0, 13, 39, 14, 47, 0,
+ 40, 39, 0, 0, 41, 42, 43, 44, 0, 7,
+ 0, 8, 0, 0, 6, 0, 18, 0, 26, 0,
+ 27, 0, 28, 0, 29, 0, 30, 0, 31, 0,
+ 3, 0, 4, 0, 5, 0, 15, 0, 16, 0,
+ 17, 0, 45, 0, 20, 46, 46, 46, 46, 21,
+ 0, 3, 0, 4, 0, 48, 47, 0, 0, 42,
+ 49, 50, 19, 0, 18, 0, 32, 18, 0, 18,
+ 32, 0, 3, 0, 4, 0, 5, 0, 15, 0,
+ 16, 0, 17, 0, 45, 0, 6, 0, 50, 24,
+ 50, 0, 50, 25, 50, 0, 50, 26, 50, 0,
+ 50, 27, 50, 0, 50, 28, 50, 0, 50, 29,
+ 50, 0, 50, 30, 50, 0, 50, 31, 50, 0,
+ 50, 32, 50, 0, 50, 33, 50, 0, 50, 34,
+ 50, 0, 50, 35, 50, 0, 36, 50, 0, 50,
+ 22, 50, 23, 50, 0
+};
+
+#endif
+
+#if YYDEBUG != 0
+static const short MiniXftConfigrline[] = { 0,
+ 77, 78, 80, 82, 84, 86, 88, 91, 93, 96,
+ 99, 101, 103, 106, 111, 113, 115, 117, 119, 121,
+ 123, 126, 131, 136, 141, 146, 151, 155, 161, 168,
+ 170, 172, 174, 177, 180, 182, 184, 187, 189, 191,
+ 193, 195, 197, 199, 201, 203, 205, 207, 209, 211,
+ 213, 215, 217, 219, 221, 223, 225, 227, 229
+};
+#endif
+
+
+#if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
+
+static const char * const MiniXftConfigtname[] = { "$","error","$undefined.","INTEGER",
+"DOUBLE","STRING","NAME","ANY","ALL","DIR","CACHE","INCLUDE","INCLUDEIF","MATCH",
+"EDIT","TOK_TRUE","TOK_FALSE","TOK_NIL","EQUAL","SEMI","OS","CS","QUEST","COLON",
+"OROR","ANDAND","EQEQ","NOTEQ","LESS","LESSEQ","MORE","MOREEQ","PLUS","MINUS",
+"TIMES","DIVIDE","NOT","configs","config","tests","test","qual","field","compare",
+"value","matrix","number","edits","edit","eqop","expr", NULL
+};
+#endif
+
+static const short MiniXftConfigr1[] = { 0,
+ 37, 37, 38, 38, 38, 38, 38, 39, 39, 40,
+ 41, 41, 41, 42, 43, 43, 43, 43, 43, 43,
+ 43, 44, 44, 44, 44, 44, 44, 44, 45, 46,
+ 46, 47, 47, 48, 49, 49, 49, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 50, 50, 50
+};
+
+static const short MiniXftConfigr2[] = { 0,
+ 2, 0, 2, 2, 2, 2, 4, 2, 0, 4,
+ 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 6, 1,
+ 1, 2, 0, 4, 1, 2, 2, 1, 1, 1,
+ 1, 1, 1, 1, 1, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 2, 5
+};
+
+static const short MiniXftConfigdefact[] = { 2,
+ 0, 0, 0, 0, 0, 9, 1, 3, 4, 5,
+ 6, 11, 12, 0, 9, 0, 33, 8, 14, 0,
+ 0, 7, 33, 15, 16, 17, 18, 19, 20, 21,
+ 0, 35, 0, 0, 32, 22, 23, 24, 25, 26,
+ 27, 0, 10, 28, 37, 36, 38, 39, 40, 45,
+ 41, 42, 43, 0, 44, 0, 30, 31, 0, 58,
+ 34, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, 57, 0, 0,
+ 0, 59, 29, 0, 0
+};
+
+static const short MiniXftConfigdefgoto[] = { 1,
+ 7, 14, 15, 16, 21, 31, 43, 55, 59, 22,
+ 23, 34, 56
+};
+
+static const short MiniXftConfigpact[] = {-32768,
+ 39, 32, 52, 94, 95, -1,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768, 15, -1, 79, 79,-32768,-32768, 80,
+ 8,-32768, 79,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+ 27, 69, 84, 18,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768, 24,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768, 18,-32768, 34,-32768,-32768, 24,-32768,
+-32768, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 24, 48, 87, 97, 105, 105,
+ -31, -31, -31, -31, 11, 11,-32768,-32768, 24, 18,
+ 82, 62,-32768, 104,-32768
+};
+
+static const short MiniXftConfigpgoto[] = {-32768,
+-32768, 90,-32768,-32768, 125,-32768,-32768, 111, -34, 120,
+-32768,-32768, -54
+};
+
+
+#define YYLAST 143
+
+
+static const short MiniXftConfigtable[] = { 60,
+ 71, 72, 73, 74, -13, 12, 13, 76, 77, 78,
+ 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
+ 47, 48, 49, 50, 75, 32, 57, 58, 17, 36,
+ 37, 38, 51, 52, 53, 92, 8, 42, 94, 33,
+ 89, 39, 40, 41, 73, 74, 42, 2, 3, 4,
+ 5, 6, 61, 54, 91, 62, 9, 63, 64, 65,
+ 66, 67, 68, 69, 70, 71, 72, 73, 74, 62,
+ 90, 63, 64, 65, 66, 67, 68, 69, 70, 71,
+ 72, 73, 74, 62, 19, 63, 64, 65, 66, 67,
+ 68, 69, 70, 71, 72, 73, 74, 24, 10, 11,
+ 45, 46, 93, 95, 18, 25, 26, 27, 28, 29,
+ 30, 64, 65, 66, 67, 68, 69, 70, 71, 72,
+ 73, 74, 65, 66, 67, 68, 69, 70, 71, 72,
+ 73, 74, 67, 68, 69, 70, 71, 72, 73, 74,
+ 20, 44, 35
+};
+
+static const short MiniXftConfigcheck[] = { 54,
+ 32, 33, 34, 35, 6, 7, 8, 62, 63, 64,
+ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+ 3, 4, 5, 6, 59, 18, 3, 4, 14, 3,
+ 4, 5, 15, 16, 17, 90, 5, 20, 0, 32,
+ 75, 15, 16, 17, 34, 35, 20, 9, 10, 11,
+ 12, 13, 19, 36, 89, 22, 5, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34, 35, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 22, 6, 24, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 18, 5, 5,
+ 32, 18, 21, 0, 15, 26, 27, 28, 29, 30,
+ 31, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, 28, 29, 30, 31, 32, 33, 34, 35,
+ 16, 31, 23
+};
+/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
+#line 3 "/usr/lib/bison.simple"
+/* This file comes from bison-1.28. */
+
+/* Skeleton output parser for bison,
+ Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* As a special exception, when this file is copied by Bison into a
+ Bison output file, you may use that output file without restriction.
+ This special exception was added by the Free Software Foundation
+ in version 1.24 of Bison. */
+
+/* This is the parser code that is written into each bison parser
+ when the %semantic_parser declaration is not specified in the grammar.
+ It was written by Richard Stallman by simplifying the hairy parser
+ used when %semantic_parser is specified. */
+
+#ifndef YYSTACK_USE_ALLOCA
+#ifdef alloca
+#define YYSTACK_USE_ALLOCA
+#else /* alloca not defined */
+#ifdef __GNUC__
+#define YYSTACK_USE_ALLOCA
+#define alloca __builtin_alloca
+#else /* not GNU C. */
+#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386))
+#define YYSTACK_USE_ALLOCA
+#include <alloca.h>
+#else /* not sparc */
+/* We think this test detects Watcom and Microsoft C. */
+/* This used to test MSDOS, but that is a bad idea
+ since that symbol is in the user namespace. */
+#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__)
+#if 0 /* No need for malloc.h, which pollutes the namespace;
+ instead, just don't use alloca. */
+#include <malloc.h>
+#endif
+#else /* not MSDOS, or __TURBOC__ */
+#if defined(_AIX)
+/* I don't know what this was needed for, but it pollutes the namespace.
+ So I turned it off. rms, 2 May 1997. */
+/* #include <malloc.h> */
+ #pragma alloca
+#define YYSTACK_USE_ALLOCA
+#else /* not MSDOS, or __TURBOC__, or _AIX */
+#if 0
+#ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up,
+ and on HPUX 10. Eventually we can turn this on. */
+#define YYSTACK_USE_ALLOCA
+#define alloca __builtin_alloca
+#endif /* __hpux */
+#endif
+#endif /* not _AIX */
+#endif /* not MSDOS, or __TURBOC__ */
+#endif /* not sparc */
+#endif /* not GNU C */
+#endif /* alloca not defined */
+#endif /* YYSTACK_USE_ALLOCA not defined */
+
+#ifdef YYSTACK_USE_ALLOCA
+#define YYSTACK_ALLOC alloca
+#else
+#define YYSTACK_ALLOC malloc
+#endif
+
+/* Note: there must be only one dollar sign in this file.
+ It is replaced by the list of actions, each action
+ as one case of the switch. */
+
+#define MiniXftConfigerrok (MiniXftConfigerrstatus = 0)
+#define MiniXftConfigclearin (MiniXftConfigchar = YYEMPTY)
+#define YYEMPTY -2
+#define YYEOF 0
+#define YYACCEPT goto MiniXftConfigacceptlab
+#define YYABORT goto MiniXftConfigabortlab
+#define YYERROR goto MiniXftConfigerrlab1
+/* Like YYERROR except do call MiniXftConfigerror.
+ This remains here temporarily to ease the
+ transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. */
+#define YYFAIL goto MiniXftConfigerrlab
+#define YYRECOVERING() (!!MiniXftConfigerrstatus)
+#define YYBACKUP(token, value) \
+do \
+ if (MiniXftConfigchar == YYEMPTY && MiniXftConfiglen == 1) \
+ { MiniXftConfigchar = (token), MiniXftConfiglval = (value); \
+ MiniXftConfigchar1 = YYTRANSLATE (MiniXftConfigchar); \
+ YYPOPSTACK; \
+ goto MiniXftConfigbackup; \
+ } \
+ else \
+ { MiniXftConfigerror ("syntax error: cannot back up"); YYERROR; } \
+while (0)
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+#ifndef YYPURE
+#define YYLEX MiniXftConfiglex()
+#endif
+
+#ifdef YYPURE
+#ifdef YYLSP_NEEDED
+#ifdef YYLEX_PARAM
+#define YYLEX MiniXftConfiglex(&MiniXftConfiglval, &MiniXftConfiglloc, YYLEX_PARAM)
+#else
+#define YYLEX MiniXftConfiglex(&MiniXftConfiglval, &MiniXftConfiglloc)
+#endif
+#else /* not YYLSP_NEEDED */
+#ifdef YYLEX_PARAM
+#define YYLEX MiniXftConfiglex(&MiniXftConfiglval, YYLEX_PARAM)
+#else
+#define YYLEX MiniXftConfiglex(&MiniXftConfiglval)
+#endif
+#endif /* not YYLSP_NEEDED */
+#endif
+
+/* If nonreentrant, generate the variables here */
+
+#ifndef YYPURE
+
+int MiniXftConfigchar; /* the lookahead symbol */
+YYSTYPE MiniXftConfiglval; /* the semantic value of the */
+ /* lookahead symbol */
+
+#ifdef YYLSP_NEEDED
+YYLTYPE MiniXftConfiglloc; /* location data for the lookahead */
+ /* symbol */
+#endif
+
+int MiniXftConfignerrs; /* number of parse errors so far */
+#endif /* not YYPURE */
+
+#if YYDEBUG != 0
+int MiniXftConfigdebug; /* nonzero means print parse trace */
+/* Since this is uninitialized, it does not stop multiple parsers
+ from coexisting. */
+#endif
+
+/* YYINITDEPTH indicates the initial size of the parser's stacks */
+
+#ifndef YYINITDEPTH
+#define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH is the maximum size the stacks can grow to
+ (effective only if the built-in stack extension method is used). */
+
+#if YYMAXDEPTH == 0
+#undef YYMAXDEPTH
+#endif
+
+#ifndef YYMAXDEPTH
+#define YYMAXDEPTH 10000
+#endif
+
+/* Define __MiniXftConfig_memcpy. Note that the size argument
+ should be passed with type unsigned int, because that is what the non-GCC
+ definitions require. With GCC, __builtin_memcpy takes an arg
+ of type size_t, but it can handle unsigned int. */
+
+#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
+#define __MiniXftConfig_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT)
+#else /* not GNU C or C++ */
+#ifndef __cplusplus
+
+/* This is the most reliable way to avoid incompatibilities
+ in available built-in functions on various systems. */
+static void
+__MiniXftConfig_memcpy (to, from, count)
+ char *to;
+ char *from;
+ unsigned int count;
+{
+ register char *f = from;
+ register char *t = to;
+ register int i = count;
+
+ while (i-- > 0)
+ *t++ = *f++;
+}
+
+#else /* __cplusplus */
+
+/* This is the most reliable way to avoid incompatibilities
+ in available built-in functions on various systems. */
+static void
+__MiniXftConfig_memcpy (char *to, char *from, unsigned int count)
+{
+ register char *t = to;
+ register char *f = from;
+ register int i = count;
+
+ while (i-- > 0)
+ *t++ = *f++;
+}
+
+#endif
+#endif
+
+#line 217 "/usr/lib/bison.simple"
+
+/* The user can define YYPARSE_PARAM as the name of an argument to be passed
+ into MiniXftConfigparse. The argument should have type void *.
+ It should actually point to an object.
+ Grammar actions can access the variable by casting it
+ to the proper pointer type. */
+
+#ifdef YYPARSE_PARAM
+#ifdef __cplusplus
+#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
+#define YYPARSE_PARAM_DECL
+#else /* not __cplusplus */
+#define YYPARSE_PARAM_ARG YYPARSE_PARAM
+#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
+#endif /* not __cplusplus */
+#else /* not YYPARSE_PARAM */
+#define YYPARSE_PARAM_ARG
+#define YYPARSE_PARAM_DECL
+#endif /* not YYPARSE_PARAM */
+
+/* Prevent warning if -Wstrict-prototypes. */
+#ifdef __GNUC__
+#ifdef YYPARSE_PARAM
+int MiniXftConfigparse (void *);
+#else
+int MiniXftConfigparse (void);
+#endif
+#endif
+
+int
+MiniXftConfigparse(YYPARSE_PARAM_ARG)
+ YYPARSE_PARAM_DECL
+{
+ register int MiniXftConfigstate;
+ register int MiniXftConfign;
+ register short *MiniXftConfigssp;
+ register YYSTYPE *MiniXftConfigvsp;
+ int MiniXftConfigerrstatus; /* number of tokens to shift before error messages enabled */
+ int MiniXftConfigchar1 = 0; /* lookahead token as an internal (translated) token number */
+
+ short MiniXftConfigssa[YYINITDEPTH]; /* the state stack */
+ YYSTYPE MiniXftConfigvsa[YYINITDEPTH]; /* the semantic value stack */
+
+ short *MiniXftConfigss = MiniXftConfigssa; /* refer to the stacks thru separate pointers */
+ YYSTYPE *MiniXftConfigvs = MiniXftConfigvsa; /* to allow MiniXftConfigoverflow to reallocate them elsewhere */
+
+#ifdef YYLSP_NEEDED
+ YYLTYPE MiniXftConfiglsa[YYINITDEPTH]; /* the location stack */
+ YYLTYPE *MiniXftConfigls = MiniXftConfiglsa;
+ YYLTYPE *MiniXftConfiglsp;
+
+#define YYPOPSTACK (MiniXftConfigvsp--, MiniXftConfigssp--, MiniXftConfiglsp--)
+#else
+#define YYPOPSTACK (MiniXftConfigvsp--, MiniXftConfigssp--)
+#endif
+
+ int MiniXftConfigstacksize = YYINITDEPTH;
+ int MiniXftConfigfree_stacks = 0;
+
+#ifdef YYPURE
+ int MiniXftConfigchar;
+ YYSTYPE MiniXftConfiglval;
+ int MiniXftConfignerrs;
+#ifdef YYLSP_NEEDED
+ YYLTYPE MiniXftConfiglloc;
+#endif
+#endif
+
+ YYSTYPE MiniXftConfigval; /* the variable used to return */
+ /* semantic values from the action */
+ /* routines */
+
+ int MiniXftConfiglen;
+
+#if YYDEBUG != 0
+ if (MiniXftConfigdebug)
+ fprintf(stderr, "Starting parse\n");
+#endif
+
+ MiniXftConfigstate = 0;
+ MiniXftConfigerrstatus = 0;
+ MiniXftConfignerrs = 0;
+ MiniXftConfigchar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack.
+ The wasted elements are never initialized. */
+
+ MiniXftConfigssp = MiniXftConfigss - 1;
+ MiniXftConfigvsp = MiniXftConfigvs;
+#ifdef YYLSP_NEEDED
+ MiniXftConfiglsp = MiniXftConfigls;
+#endif
+
+/* Push a new state, which is found in MiniXftConfigstate . */
+/* In all cases, when you get here, the value and location stacks
+ have just been pushed. so pushing a state here evens the stacks. */
+MiniXftConfignewstate:
+
+ *++MiniXftConfigssp = MiniXftConfigstate;
+
+ if (MiniXftConfigssp >= MiniXftConfigss + MiniXftConfigstacksize - 1)
+ {
+ /* Give user a chance to reallocate the stack */
+ /* Use copies of these so that the &'s don't force the real ones into memory. */
+ YYSTYPE *MiniXftConfigvs1 = MiniXftConfigvs;
+ short *MiniXftConfigss1 = MiniXftConfigss;
+#ifdef YYLSP_NEEDED
+ YYLTYPE *MiniXftConfigls1 = MiniXftConfigls;
+#endif
+
+ /* Get the current used size of the three stacks, in elements. */
+ int size = MiniXftConfigssp - MiniXftConfigss + 1;
+
+#ifdef MiniXftConfigoverflow
+ /* Each stack pointer address is followed by the size of
+ the data in use in that stack, in bytes. */
+#ifdef YYLSP_NEEDED
+ /* This used to be a conditional around just the two extra args,
+ but that might be undefined if MiniXftConfigoverflow is a macro. */
+ MiniXftConfigoverflow("parser stack overflow",
+ &MiniXftConfigss1, size * sizeof (*MiniXftConfigssp),
+ &MiniXftConfigvs1, size * sizeof (*MiniXftConfigvsp),
+ &MiniXftConfigls1, size * sizeof (*MiniXftConfiglsp),
+ &MiniXftConfigstacksize);
+#else
+ MiniXftConfigoverflow("parser stack overflow",
+ &MiniXftConfigss1, size * sizeof (*MiniXftConfigssp),
+ &MiniXftConfigvs1, size * sizeof (*MiniXftConfigvsp),
+ &MiniXftConfigstacksize);
+#endif
+
+ MiniXftConfigss = MiniXftConfigss1; MiniXftConfigvs = MiniXftConfigvs1;
+#ifdef YYLSP_NEEDED
+ MiniXftConfigls = MiniXftConfigls1;
+#endif
+#else /* no MiniXftConfigoverflow */
+ /* Extend the stack our own way. */
+ if (MiniXftConfigstacksize >= YYMAXDEPTH)
+ {
+ MiniXftConfigerror("parser stack overflow");
+ if (MiniXftConfigfree_stacks)
+ {
+ free (MiniXftConfigss);
+ free (MiniXftConfigvs);
+#ifdef YYLSP_NEEDED
+ free (MiniXftConfigls);
+#endif
+ }
+ return 2;
+ }
+ MiniXftConfigstacksize *= 2;
+ if (MiniXftConfigstacksize > YYMAXDEPTH)
+ MiniXftConfigstacksize = YYMAXDEPTH;
+#ifndef YYSTACK_USE_ALLOCA
+ MiniXftConfigfree_stacks = 1;
+#endif
+ MiniXftConfigss = (short *) YYSTACK_ALLOC (MiniXftConfigstacksize * sizeof (*MiniXftConfigssp));
+ __MiniXftConfig_memcpy ((char *)MiniXftConfigss, (char *)MiniXftConfigss1,
+ size * (unsigned int) sizeof (*MiniXftConfigssp));
+ MiniXftConfigvs = (YYSTYPE *) YYSTACK_ALLOC (MiniXftConfigstacksize * sizeof (*MiniXftConfigvsp));
+ __MiniXftConfig_memcpy ((char *)MiniXftConfigvs, (char *)MiniXftConfigvs1,
+ size * (unsigned int) sizeof (*MiniXftConfigvsp));
+#ifdef YYLSP_NEEDED
+ MiniXftConfigls = (YYLTYPE *) YYSTACK_ALLOC (MiniXftConfigstacksize * sizeof (*MiniXftConfiglsp));
+ __MiniXftConfig_memcpy ((char *)MiniXftConfigls, (char *)MiniXftConfigls1,
+ size * (unsigned int) sizeof (*MiniXftConfiglsp));
+#endif
+#endif /* no MiniXftConfigoverflow */
+
+ MiniXftConfigssp = MiniXftConfigss + size - 1;
+ MiniXftConfigvsp = MiniXftConfigvs + size - 1;
+#ifdef YYLSP_NEEDED
+ MiniXftConfiglsp = MiniXftConfigls + size - 1;
+#endif
+
+#if YYDEBUG != 0
+ if (MiniXftConfigdebug)
+ fprintf(stderr, "Stack size increased to %d\n", MiniXftConfigstacksize);
+#endif
+
+ if (MiniXftConfigssp >= MiniXftConfigss + MiniXftConfigstacksize - 1)
+ YYABORT;
+ }
+
+#if YYDEBUG != 0
+ if (MiniXftConfigdebug)
+ fprintf(stderr, "Entering state %d\n", MiniXftConfigstate);
+#endif
+
+ goto MiniXftConfigbackup;
+ MiniXftConfigbackup:
+
+/* Do appropriate processing given the current state. */
+/* Read a lookahead token if we need one and don't already have one. */
+/* MiniXftConfigresume: */
+
+ /* First try to decide what to do without reference to lookahead token. */
+
+ MiniXftConfign = MiniXftConfigpact[MiniXftConfigstate];
+ if (MiniXftConfign == YYFLAG)
+ goto MiniXftConfigdefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* MiniXftConfigchar is either YYEMPTY or YYEOF
+ or a valid token in external form. */
+
+ if (MiniXftConfigchar == YYEMPTY)
+ {
+#if YYDEBUG != 0
+ if (MiniXftConfigdebug)
+ fprintf(stderr, "Reading a token: ");
+#endif
+ MiniXftConfigchar = YYLEX;
+ }
+
+ /* Convert token to internal form (in MiniXftConfigchar1) for indexing tables with */
+
+ if (MiniXftConfigchar <= 0) /* This means end of input. */
+ {
+ MiniXftConfigchar1 = 0;
+ MiniXftConfigchar = YYEOF; /* Don't call YYLEX any more */
+
+#if YYDEBUG != 0
+ if (MiniXftConfigdebug)
+ fprintf(stderr, "Now at end of input.\n");
+#endif
+ }
+ else
+ {
+ MiniXftConfigchar1 = YYTRANSLATE(MiniXftConfigchar);
+
+#if YYDEBUG != 0
+ if (MiniXftConfigdebug)
+ {
+ fprintf (stderr, "Next token is %d (%s", MiniXftConfigchar, MiniXftConfigtname[MiniXftConfigchar1]);
+ /* Give the individual parser a way to print the precise meaning
+ of a token, for further debugging info. */
+#ifdef YYPRINT
+ YYPRINT (stderr, MiniXftConfigchar, MiniXftConfiglval);
+#endif
+ fprintf (stderr, ")\n");
+ }
+#endif
+ }
+
+ MiniXftConfign += MiniXftConfigchar1;
+ if (MiniXftConfign < 0 || MiniXftConfign > YYLAST || MiniXftConfigcheck[MiniXftConfign] != MiniXftConfigchar1)
+ goto MiniXftConfigdefault;
+
+ MiniXftConfign = MiniXftConfigtable[MiniXftConfign];
+
+ /* MiniXftConfign is what to do for this token type in this state.
+ Negative => reduce, -MiniXftConfign is rule number.
+ Positive => shift, MiniXftConfign is new state.
+ New state is final state => don't bother to shift,
+ just return success.
+ 0, or most negative number => error. */
+
+ if (MiniXftConfign < 0)
+ {
+ if (MiniXftConfign == YYFLAG)
+ goto MiniXftConfigerrlab;
+ MiniXftConfign = -MiniXftConfign;
+ goto MiniXftConfigreduce;
+ }
+ else if (MiniXftConfign == 0)
+ goto MiniXftConfigerrlab;
+
+ if (MiniXftConfign == YYFINAL)
+ YYACCEPT;
+
+ /* Shift the lookahead token. */
+
+#if YYDEBUG != 0
+ if (MiniXftConfigdebug)
+ fprintf(stderr, "Shifting token %d (%s), ", MiniXftConfigchar, MiniXftConfigtname[MiniXftConfigchar1]);
+#endif
+
+ /* Discard the token being shifted unless it is eof. */
+ if (MiniXftConfigchar != YYEOF)
+ MiniXftConfigchar = YYEMPTY;
+
+ *++MiniXftConfigvsp = MiniXftConfiglval;
+#ifdef YYLSP_NEEDED
+ *++MiniXftConfiglsp = MiniXftConfiglloc;
+#endif
+
+ /* count tokens shifted since error; after three, turn off error status. */
+ if (MiniXftConfigerrstatus) MiniXftConfigerrstatus--;
+
+ MiniXftConfigstate = MiniXftConfign;
+ goto MiniXftConfignewstate;
+
+/* Do the default action for the current state. */
+MiniXftConfigdefault:
+
+ MiniXftConfign = MiniXftConfigdefact[MiniXftConfigstate];
+ if (MiniXftConfign == 0)
+ goto MiniXftConfigerrlab;
+
+/* Do a reduction. MiniXftConfign is the number of a rule to reduce with. */
+MiniXftConfigreduce:
+ MiniXftConfiglen = MiniXftConfigr2[MiniXftConfign];
+ if (MiniXftConfiglen > 0)
+ MiniXftConfigval = MiniXftConfigvsp[1-MiniXftConfiglen]; /* implement default value of the action */
+
+#if YYDEBUG != 0
+ if (MiniXftConfigdebug)
+ {
+ int i;
+
+ fprintf (stderr, "Reducing via rule %d (line %d), ",
+ MiniXftConfign, MiniXftConfigrline[MiniXftConfign]);
+
+ /* Print the symbols being reduced, and their result. */
+ for (i = MiniXftConfigprhs[MiniXftConfign]; MiniXftConfigrhs[i] > 0; i++)
+ fprintf (stderr, "%s ", MiniXftConfigtname[MiniXftConfigrhs[i]]);
+ fprintf (stderr, " -> %s\n", MiniXftConfigtname[MiniXftConfigr1[MiniXftConfign]]);
+ }
+#endif
+
+
+ switch (MiniXftConfign) {
+
+case 3:
+#line 81 "minixftgram.y"
+{ MiniXftConfigAddDir (MiniXftConfigvsp[0].sval); ;
+ break;}
+case 4:
+#line 83 "minixftgram.y"
+{ MiniXftConfigSetCache (MiniXftConfigvsp[0].sval); ;
+ break;}
+case 5:
+#line 85 "minixftgram.y"
+{ MiniXftConfigPushInput (MiniXftConfigvsp[0].sval, True); ;
+ break;}
+case 6:
+#line 87 "minixftgram.y"
+{ MiniXftConfigPushInput (MiniXftConfigvsp[0].sval, False); ;
+ break;}
+case 7:
+#line 89 "minixftgram.y"
+{ MiniXftConfigAddEdit (MiniXftConfigvsp[-2].tval, MiniXftConfigvsp[0].Eval); ;
+ break;}
+case 8:
+#line 92 "minixftgram.y"
+{ MiniXftConfigvsp[-1].tval->next = MiniXftConfigvsp[0].tval; MiniXftConfigval.tval = MiniXftConfigvsp[-1].tval; ;
+ break;}
+case 9:
+#line 94 "minixftgram.y"
+{ MiniXftConfigval.tval = 0; ;
+ break;}
+case 10:
+#line 97 "minixftgram.y"
+{ MiniXftConfigval.tval = MiniXftTestCreate (MiniXftConfigvsp[-3].qval, MiniXftConfigvsp[-2].sval, MiniXftConfigvsp[-1].oval, MiniXftConfigvsp[0].vval); ;
+ break;}
+case 11:
+#line 100 "minixftgram.y"
+{ MiniXftConfigval.qval = MiniXftQualAny; ;
+ break;}
+case 12:
+#line 102 "minixftgram.y"
+{ MiniXftConfigval.qval = MiniXftQualAll; ;
+ break;}
+case 13:
+#line 104 "minixftgram.y"
+{ MiniXftConfigval.qval = MiniXftQualAny; ;
+ break;}
+case 14:
+#line 107 "minixftgram.y"
+{
+ MiniXftConfigval.sval = MiniXftConfigSaveField (MiniXftConfigvsp[0].sval);
+ ;
+ break;}
+case 15:
+#line 112 "minixftgram.y"
+{ MiniXftConfigval.oval = MiniXftOpEqual; ;
+ break;}
+case 16:
+#line 114 "minixftgram.y"
+{ MiniXftConfigval.oval = MiniXftOpEqual; ;
+ break;}
+case 17:
+#line 116 "minixftgram.y"
+{ MiniXftConfigval.oval = MiniXftOpNotEqual; ;
+ break;}
+case 18:
+#line 118 "minixftgram.y"
+{ MiniXftConfigval.oval = MiniXftOpLess; ;
+ break;}
+case 19:
+#line 120 "minixftgram.y"
+{ MiniXftConfigval.oval = MiniXftOpLessEqual; ;
+ break;}
+case 20:
+#line 122 "minixftgram.y"
+{ MiniXftConfigval.oval = MiniXftOpMore; ;
+ break;}
+case 21:
+#line 124 "minixftgram.y"
+{ MiniXftConfigval.oval = MiniXftOpMoreEqual; ;
+ break;}
+case 22:
+#line 127 "minixftgram.y"
+{
+ MiniXftConfigval.vval.type = MiniXftTypeInteger;
+ MiniXftConfigval.vval.u.i = MiniXftConfigvsp[0].ival;
+ ;
+ break;}
+case 23:
+#line 132 "minixftgram.y"
+{
+ MiniXftConfigval.vval.type = MiniXftTypeDouble;
+ MiniXftConfigval.vval.u.d = MiniXftConfigvsp[0].dval;
+ ;
+ break;}
+case 24:
+#line 137 "minixftgram.y"
+{
+ MiniXftConfigval.vval.type = MiniXftTypeString;
+ MiniXftConfigval.vval.u.s = MiniXftConfigvsp[0].sval;
+ ;
+ break;}
+case 25:
+#line 142 "minixftgram.y"
+{
+ MiniXftConfigval.vval.type = MiniXftTypeBool;
+ MiniXftConfigval.vval.u.b = True;
+ ;
+ break;}
+case 26:
+#line 147 "minixftgram.y"
+{
+ MiniXftConfigval.vval.type = MiniXftTypeBool;
+ MiniXftConfigval.vval.u.b = False;
+ ;
+ break;}
+case 27:
+#line 152 "minixftgram.y"
+{
+ MiniXftConfigval.vval.type = MiniXftTypeVoid;
+ ;
+ break;}
+case 28:
+#line 156 "minixftgram.y"
+{
+ MiniXftConfigval.vval.type = MiniXftTypeMatrix;
+ MiniXftConfigval.vval.u.m = &matrix;
+ ;
+ break;}
+case 29:
+#line 162 "minixftgram.y"
+{
+ matrix.xx = MiniXftConfigvsp[-4].dval;
+ matrix.xy = MiniXftConfigvsp[-3].dval;
+ matrix.yx = MiniXftConfigvsp[-2].dval;
+ matrix.yy = MiniXftConfigvsp[-1].dval;
+ ;
+ break;}
+case 30:
+#line 169 "minixftgram.y"
+{ MiniXftConfigval.dval = (double) MiniXftConfigvsp[0].ival; ;
+ break;}
+case 32:
+#line 173 "minixftgram.y"
+{ MiniXftConfigvsp[-1].Eval->next = MiniXftConfigvsp[0].Eval; MiniXftConfigval.Eval = MiniXftConfigvsp[-1].Eval; ;
+ break;}
+case 33:
+#line 175 "minixftgram.y"
+{ MiniXftConfigval.Eval = 0; ;
+ break;}
+case 34:
+#line 178 "minixftgram.y"
+{ MiniXftConfigval.Eval = MiniXftEditCreate (MiniXftConfigvsp[-3].sval, MiniXftConfigvsp[-2].oval, MiniXftConfigvsp[-1].eval); ;
+ break;}
+case 35:
+#line 181 "minixftgram.y"
+{ MiniXftConfigval.oval = MiniXftOpAssign; ;
+ break;}
+case 36:
+#line 183 "minixftgram.y"
+{ MiniXftConfigval.oval = MiniXftOpPrepend; ;
+ break;}
+case 37:
+#line 185 "minixftgram.y"
+{ MiniXftConfigval.oval = MiniXftOpAppend; ;
+ break;}
+case 38:
+#line 188 "minixftgram.y"
+{ MiniXftConfigval.eval = MiniXftExprCreateInteger (MiniXftConfigvsp[0].ival); ;
+ break;}
+case 39:
+#line 190 "minixftgram.y"
+{ MiniXftConfigval.eval = MiniXftExprCreateDouble (MiniXftConfigvsp[0].dval); ;
+ break;}
+case 40:
+#line 192 "minixftgram.y"
+{ MiniXftConfigval.eval = MiniXftExprCreateString (MiniXftConfigvsp[0].sval); ;
+ break;}
+case 41:
+#line 194 "minixftgram.y"
+{ MiniXftConfigval.eval = MiniXftExprCreateBool (True); ;
+ break;}
+case 42:
+#line 196 "minixftgram.y"
+{ MiniXftConfigval.eval = MiniXftExprCreateBool (False); ;
+ break;}
+case 43:
+#line 198 "minixftgram.y"
+{ MiniXftConfigval.eval = MiniXftExprCreateNil (); ;
+ break;}
+case 44:
+#line 200 "minixftgram.y"
+{ MiniXftConfigval.eval = MiniXftExprCreateMatrix (&matrix); ;
+ break;}
+case 45:
+#line 202 "minixftgram.y"
+{ MiniXftConfigval.eval = MiniXftExprCreateField (MiniXftConfigvsp[0].sval); ;
+ break;}
+case 46:
+#line 204 "minixftgram.y"
+{ MiniXftConfigval.eval = MiniXftExprCreateOp (MiniXftConfigvsp[-2].eval, MiniXftOpOr, MiniXftConfigvsp[0].eval); ;
+ break;}
+case 47:
+#line 206 "minixftgram.y"
+{ MiniXftConfigval.eval = MiniXftExprCreateOp (MiniXftConfigvsp[-2].eval, MiniXftOpAnd, MiniXftConfigvsp[0].eval); ;
+ break;}
+case 48:
+#line 208 "minixftgram.y"
+{ MiniXftConfigval.eval = MiniXftExprCreateOp (MiniXftConfigvsp[-2].eval, MiniXftOpEqual, MiniXftConfigvsp[0].eval); ;
+ break;}
+case 49:
+#line 210 "minixftgram.y"
+{ MiniXftConfigval.eval = MiniXftExprCreateOp (MiniXftConfigvsp[-2].eval, MiniXftOpNotEqual, MiniXftConfigvsp[0].eval); ;
+ break;}
+case 50:
+#line 212 "minixftgram.y"
+{ MiniXftConfigval.eval = MiniXftExprCreateOp (MiniXftConfigvsp[-2].eval, MiniXftOpLess, MiniXftConfigvsp[0].eval); ;
+ break;}
+case 51:
+#line 214 "minixftgram.y"
+{ MiniXftConfigval.eval = MiniXftExprCreateOp (MiniXftConfigvsp[-2].eval, MiniXftOpLessEqual, MiniXftConfigvsp[0].eval); ;
+ break;}
+case 52:
+#line 216 "minixftgram.y"
+{ MiniXftConfigval.eval = MiniXftExprCreateOp (MiniXftConfigvsp[-2].eval, MiniXftOpMore, MiniXftConfigvsp[0].eval); ;
+ break;}
+case 53:
+#line 218 "minixftgram.y"
+{ MiniXftConfigval.eval = MiniXftExprCreateOp (MiniXftConfigvsp[-2].eval, MiniXftOpMoreEqual, MiniXftConfigvsp[0].eval); ;
+ break;}
+case 54:
+#line 220 "minixftgram.y"
+{ MiniXftConfigval.eval = MiniXftExprCreateOp (MiniXftConfigvsp[-2].eval, MiniXftOpPlus, MiniXftConfigvsp[0].eval); ;
+ break;}
+case 55:
+#line 222 "minixftgram.y"
+{ MiniXftConfigval.eval = MiniXftExprCreateOp (MiniXftConfigvsp[-2].eval, MiniXftOpMinus, MiniXftConfigvsp[0].eval); ;
+ break;}
+case 56:
+#line 224 "minixftgram.y"
+{ MiniXftConfigval.eval = MiniXftExprCreateOp (MiniXftConfigvsp[-2].eval, MiniXftOpTimes, MiniXftConfigvsp[0].eval); ;
+ break;}
+case 57:
+#line 226 "minixftgram.y"
+{ MiniXftConfigval.eval = MiniXftExprCreateOp (MiniXftConfigvsp[-2].eval, MiniXftOpDivide, MiniXftConfigvsp[0].eval); ;
+ break;}
+case 58:
+#line 228 "minixftgram.y"
+{ MiniXftConfigval.eval = MiniXftExprCreateOp (MiniXftConfigvsp[0].eval, MiniXftOpNot, (MiniXftExpr *) 0); ;
+ break;}
+case 59:
+#line 230 "minixftgram.y"
+{ MiniXftConfigval.eval = MiniXftExprCreateOp (MiniXftConfigvsp[-4].eval, MiniXftOpQuest, MiniXftExprCreateOp (MiniXftConfigvsp[-2].eval, MiniXftOpQuest, MiniXftConfigvsp[0].eval)); ;
+ break;}
+}
+ /* the action file gets copied in in place of this dollarsign */
+#line 543 "/usr/lib/bison.simple"
+
+ MiniXftConfigvsp -= MiniXftConfiglen;
+ MiniXftConfigssp -= MiniXftConfiglen;
+#ifdef YYLSP_NEEDED
+ MiniXftConfiglsp -= MiniXftConfiglen;
+#endif
+
+#if YYDEBUG != 0
+ if (MiniXftConfigdebug)
+ {
+ short *ssp1 = MiniXftConfigss - 1;
+ fprintf (stderr, "state stack now");
+ while (ssp1 != MiniXftConfigssp)
+ fprintf (stderr, " %d", *++ssp1);
+ fprintf (stderr, "\n");
+ }
+#endif
+
+ *++MiniXftConfigvsp = MiniXftConfigval;
+
+#ifdef YYLSP_NEEDED
+ MiniXftConfiglsp++;
+ if (MiniXftConfiglen == 0)
+ {
+ MiniXftConfiglsp->first_line = MiniXftConfiglloc.first_line;
+ MiniXftConfiglsp->first_column = MiniXftConfiglloc.first_column;
+ MiniXftConfiglsp->last_line = (MiniXftConfiglsp-1)->last_line;
+ MiniXftConfiglsp->last_column = (MiniXftConfiglsp-1)->last_column;
+ MiniXftConfiglsp->text = 0;
+ }
+ else
+ {
+ MiniXftConfiglsp->last_line = (MiniXftConfiglsp+MiniXftConfiglen-1)->last_line;
+ MiniXftConfiglsp->last_column = (MiniXftConfiglsp+MiniXftConfiglen-1)->last_column;
+ }
+#endif
+
+ /* Now "shift" the result of the reduction.
+ Determine what state that goes to,
+ based on the state we popped back to
+ and the rule number reduced by. */
+
+ MiniXftConfign = MiniXftConfigr1[MiniXftConfign];
+
+ MiniXftConfigstate = MiniXftConfigpgoto[MiniXftConfign - YYNTBASE] + *MiniXftConfigssp;
+ if (MiniXftConfigstate >= 0 && MiniXftConfigstate <= YYLAST && MiniXftConfigcheck[MiniXftConfigstate] == *MiniXftConfigssp)
+ MiniXftConfigstate = MiniXftConfigtable[MiniXftConfigstate];
+ else
+ MiniXftConfigstate = MiniXftConfigdefgoto[MiniXftConfign - YYNTBASE];
+
+ goto MiniXftConfignewstate;
+
+MiniXftConfigerrlab: /* here on detecting error */
+
+ if (! MiniXftConfigerrstatus)
+ /* If not already recovering from an error, report this error. */
+ {
+ ++MiniXftConfignerrs;
+
+#ifdef YYERROR_VERBOSE
+ MiniXftConfign = MiniXftConfigpact[MiniXftConfigstate];
+
+ if (MiniXftConfign > YYFLAG && MiniXftConfign < YYLAST)
+ {
+ int size = 0;
+ char *msg;
+ int x, count;
+
+ count = 0;
+ /* Start X at -MiniXftConfign if nec to avoid negative indexes in MiniXftConfigcheck. */
+ for (x = (MiniXftConfign < 0 ? -MiniXftConfign : 0);
+ x < (sizeof(MiniXftConfigtname) / sizeof(char *)); x++)
+ if (MiniXftConfigcheck[x + MiniXftConfign] == x)
+ size += strlen(MiniXftConfigtname[x]) + 15, count++;
+ msg = (char *) malloc(size + 15);
+ if (msg != 0)
+ {
+ strcpy(msg, "parse error");
+
+ if (count < 5)
+ {
+ count = 0;
+ for (x = (MiniXftConfign < 0 ? -MiniXftConfign : 0);
+ x < (sizeof(MiniXftConfigtname) / sizeof(char *)); x++)
+ if (MiniXftConfigcheck[x + MiniXftConfign] == x)
+ {
+ strcat(msg, count == 0 ? ", expecting `" : " or `");
+ strcat(msg, MiniXftConfigtname[x]);
+ strcat(msg, "'");
+ count++;
+ }
+ }
+ MiniXftConfigerror(msg);
+ free(msg);
+ }
+ else
+ MiniXftConfigerror ("parse error; also virtual memory exceeded");
+ }
+ else
+#endif /* YYERROR_VERBOSE */
+ MiniXftConfigerror("parse error");
+ }
+
+ goto MiniXftConfigerrlab1;
+MiniXftConfigerrlab1: /* here on error raised explicitly by an action */
+
+ if (MiniXftConfigerrstatus == 3)
+ {
+ /* if just tried and failed to reuse lookahead token after an error, discard it. */
+
+ /* return failure if at end of input */
+ if (MiniXftConfigchar == YYEOF)
+ YYABORT;
+
+#if YYDEBUG != 0
+ if (MiniXftConfigdebug)
+ fprintf(stderr, "Discarding token %d (%s).\n", MiniXftConfigchar, MiniXftConfigtname[MiniXftConfigchar1]);
+#endif
+
+ MiniXftConfigchar = YYEMPTY;
+ }
+
+ /* Else will try to reuse lookahead token
+ after shifting the error token. */
+
+ MiniXftConfigerrstatus = 3; /* Each real token shifted decrements this */
+
+ goto MiniXftConfigerrhandle;
+
+MiniXftConfigerrdefault: /* current state does not do anything special for the error token. */
+
+#if 0
+ /* This is wrong; only states that explicitly want error tokens
+ should shift them. */
+ MiniXftConfign = MiniXftConfigdefact[MiniXftConfigstate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
+ if (MiniXftConfign) goto MiniXftConfigdefault;
+#endif
+
+MiniXftConfigerrpop: /* pop the current state because it cannot handle the error token */
+
+ if (MiniXftConfigssp == MiniXftConfigss) YYABORT;
+ MiniXftConfigvsp--;
+ MiniXftConfigstate = *--MiniXftConfigssp;
+#ifdef YYLSP_NEEDED
+ MiniXftConfiglsp--;
+#endif
+
+#if YYDEBUG != 0
+ if (MiniXftConfigdebug)
+ {
+ short *ssp1 = MiniXftConfigss - 1;
+ fprintf (stderr, "Error: state stack now");
+ while (ssp1 != MiniXftConfigssp)
+ fprintf (stderr, " %d", *++ssp1);
+ fprintf (stderr, "\n");
+ }
+#endif
+
+MiniXftConfigerrhandle:
+
+ MiniXftConfign = MiniXftConfigpact[MiniXftConfigstate];
+ if (MiniXftConfign == YYFLAG)
+ goto MiniXftConfigerrdefault;
+
+ MiniXftConfign += YYTERROR;
+ if (MiniXftConfign < 0 || MiniXftConfign > YYLAST || MiniXftConfigcheck[MiniXftConfign] != YYTERROR)
+ goto MiniXftConfigerrdefault;
+
+ MiniXftConfign = MiniXftConfigtable[MiniXftConfign];
+ if (MiniXftConfign < 0)
+ {
+ if (MiniXftConfign == YYFLAG)
+ goto MiniXftConfigerrpop;
+ MiniXftConfign = -MiniXftConfign;
+ goto MiniXftConfigreduce;
+ }
+ else if (MiniXftConfign == 0)
+ goto MiniXftConfigerrpop;
+
+ if (MiniXftConfign == YYFINAL)
+ YYACCEPT;
+
+#if YYDEBUG != 0
+ if (MiniXftConfigdebug)
+ fprintf(stderr, "Shifting error token, ");
+#endif
+
+ *++MiniXftConfigvsp = MiniXftConfiglval;
+#ifdef YYLSP_NEEDED
+ *++MiniXftConfiglsp = MiniXftConfiglloc;
+#endif
+
+ MiniXftConfigstate = MiniXftConfign;
+ goto MiniXftConfignewstate;
+
+ MiniXftConfigacceptlab:
+ /* YYACCEPT comes here. */
+ if (MiniXftConfigfree_stacks)
+ {
+ free (MiniXftConfigss);
+ free (MiniXftConfigvs);
+#ifdef YYLSP_NEEDED
+ free (MiniXftConfigls);
+#endif
+ }
+ return 0;
+
+ MiniXftConfigabortlab:
+ /* YYABORT comes here. */
+ if (MiniXftConfigfree_stacks)
+ {
+ free (MiniXftConfigss);
+ free (MiniXftConfigvs);
+#ifdef YYLSP_NEEDED
+ free (MiniXftConfigls);
+#endif
+ }
+ return 1;
+}
+#line 232 "minixftgram.y"
+
+
+int
+MiniXftConfigwrap (void)
+{
+ return 1;
+}
+
+void
+MiniXftConfigerror (char *fmt, ...)
+{
+ va_list args;
+
+ fprintf (stderr, "\"%s\": line %d, ", MiniXftConfigFile, MiniXftConfigLineno);
+ va_start (args, fmt);
+ vfprintf (stderr, fmt, args);
+ va_end (args);
+ fprintf (stderr, "\n");
+}
+
+MiniXftTest *
+MiniXftTestCreate (MiniXftQual qual, const char *field, MiniXftOp compare, MiniXftValue value)
+{
+ MiniXftTest *test = (MiniXftTest *) malloc (sizeof (MiniXftTest));;
+
+ if (test)
+ {
+ test->next = 0;
+ test->qual = qual;
+ test->field = field; /* already saved in grammar */
+ test->op = compare;
+ if (value.type == MiniXftTypeString)
+ value.u.s = _MiniXftSaveString (value.u.s);
+ else if (value.type == MiniXftTypeMatrix)
+ value.u.m = _MiniXftSaveMatrix (value.u.m);
+ test->value = value;
+ }
+ return test;
+}
+
+MiniXftExpr *
+MiniXftExprCreateInteger (int i)
+{
+ MiniXftExpr *e = (MiniXftExpr *) malloc (sizeof (MiniXftExpr));
+
+ if (e)
+ {
+ e->op = MiniXftOpInteger;
+ e->u.ival = i;
+ }
+ return e;
+}
+
+MiniXftExpr *
+MiniXftExprCreateDouble (double d)
+{
+ MiniXftExpr *e = (MiniXftExpr *) malloc (sizeof (MiniXftExpr));
+
+ if (e)
+ {
+ e->op = MiniXftOpDouble;
+ e->u.dval = d;
+ }
+ return e;
+}
+
+MiniXftExpr *
+MiniXftExprCreateString (const char *s)
+{
+ MiniXftExpr *e = (MiniXftExpr *) malloc (sizeof (MiniXftExpr));
+
+ if (e)
+ {
+ e->op = MiniXftOpString;
+ e->u.sval = _MiniXftSaveString (s);
+ }
+ return e;
+}
+
+MiniXftExpr *
+MiniXftExprCreateMatrix (const MiniXftMatrix *m)
+{
+ MiniXftExpr *e = (MiniXftExpr *) malloc (sizeof (MiniXftExpr));
+
+ if (e)
+ {
+ e->op = MiniXftOpMatrix;
+ e->u.mval = _MiniXftSaveMatrix (m);
+ }
+ return e;
+}
+
+MiniXftExpr *
+MiniXftExprCreateBool (Bool b)
+{
+ MiniXftExpr *e = (MiniXftExpr *) malloc (sizeof (MiniXftExpr));
+
+ if (e)
+ {
+ e->op = MiniXftOpBool;
+ e->u.bval = b;
+ }
+ return e;
+}
+
+MiniXftExpr *
+MiniXftExprCreateNil (void)
+{
+ MiniXftExpr *e = (MiniXftExpr *) malloc (sizeof (MiniXftExpr));
+
+ if (e)
+ {
+ e->op = MiniXftOpNil;
+ }
+ return e;
+}
+
+MiniXftExpr *
+MiniXftExprCreateField (const char *field)
+{
+ MiniXftExpr *e = (MiniXftExpr *) malloc (sizeof (MiniXftExpr));
+
+ if (e)
+ {
+ e->op = MiniXftOpField;
+ e->u.field = _MiniXftSaveString (field);
+ }
+ return e;
+}
+
+MiniXftExpr *
+MiniXftExprCreateOp (MiniXftExpr *left, MiniXftOp op, MiniXftExpr *right)
+{
+ MiniXftExpr *e = (MiniXftExpr *) malloc (sizeof (MiniXftExpr));
+
+ if (e)
+ {
+ e->op = op;
+ e->u.tree.left = left;
+ e->u.tree.right = right;
+ }
+ return e;
+}
+
+void
+MiniXftExprDestroy (MiniXftExpr *e)
+{
+ switch (e->op) {
+ case MiniXftOpInteger:
+ break;
+ case MiniXftOpDouble:
+ break;
+ case MiniXftOpString:
+ free (e->u.sval);
+ break;
+ case MiniXftOpMatrix:
+ free (e->u.mval);
+ break;
+ case MiniXftOpBool:
+ break;
+ case MiniXftOpField:
+ free (e->u.field);
+ break;
+ case MiniXftOpAssign:
+ case MiniXftOpPrepend:
+ case MiniXftOpAppend:
+ break;
+ case MiniXftOpOr:
+ case MiniXftOpAnd:
+ case MiniXftOpEqual:
+ case MiniXftOpNotEqual:
+ case MiniXftOpLess:
+ case MiniXftOpLessEqual:
+ case MiniXftOpMore:
+ case MiniXftOpMoreEqual:
+ case MiniXftOpPlus:
+ case MiniXftOpMinus:
+ case MiniXftOpTimes:
+ case MiniXftOpDivide:
+ case MiniXftOpQuest:
+ MiniXftExprDestroy (e->u.tree.right);
+ /* fall through */
+ case MiniXftOpNot:
+ MiniXftExprDestroy (e->u.tree.left);
+ break;
+ case MiniXftOpNil:
+ break;
+ }
+ free (e);
+}
+
+MiniXftEdit *
+MiniXftEditCreate (const char *field, MiniXftOp op, MiniXftExpr *expr)
+{
+ MiniXftEdit *e = (MiniXftEdit *) malloc (sizeof (MiniXftEdit));
+
+ if (e)
+ {
+ e->next = 0;
+ e->field = field; /* already saved in grammar */
+ e->op = op;
+ e->expr = expr;
+ }
+ return e;
+}
+
+void
+MiniXftEditDestroy (MiniXftEdit *e)
+{
+ if (e->next)
+ MiniXftEditDestroy (e->next);
+ free ((void *) e->field);
+ if (e->expr)
+ MiniXftExprDestroy (e->expr);
+}
+
+char *
+MiniXftConfigSaveField (const char *field)
+{
+ return _MiniXftSaveString (field);
+}
diff --git a/pango/mini-xft/minixftgram.h b/pango/mini-xft/minixftgram.h
new file mode 100644
index 00000000..8207b436
--- /dev/null
+++ b/pango/mini-xft/minixftgram.h
@@ -0,0 +1,49 @@
+typedef union {
+ int ival;
+ double dval;
+ char *sval;
+ MiniXftExpr *eval;
+ MiniXftPattern *pval;
+ MiniXftValue vval;
+ MiniXftEdit *Eval;
+ MiniXftOp oval;
+ MiniXftQual qval;
+ MiniXftTest *tval;
+} YYSTYPE;
+#define INTEGER 257
+#define DOUBLE 258
+#define STRING 259
+#define NAME 260
+#define ANY 261
+#define ALL 262
+#define DIR 263
+#define CACHE 264
+#define INCLUDE 265
+#define INCLUDEIF 266
+#define MATCH 267
+#define EDIT 268
+#define TOK_TRUE 269
+#define TOK_FALSE 270
+#define TOK_NIL 271
+#define EQUAL 272
+#define SEMI 273
+#define OS 274
+#define CS 275
+#define QUEST 276
+#define COLON 277
+#define OROR 278
+#define ANDAND 279
+#define EQEQ 280
+#define NOTEQ 281
+#define LESS 282
+#define LESSEQ 283
+#define MORE 284
+#define MOREEQ 285
+#define PLUS 286
+#define MINUS 287
+#define TIMES 288
+#define DIVIDE 289
+#define NOT 290
+
+
+extern YYSTYPE MiniXftConfiglval;
diff --git a/pango/mini-xft/minixftgram.y b/pango/mini-xft/minixftgram.y
new file mode 100644
index 00000000..e2daaa33
--- /dev/null
+++ b/pango/mini-xft/minixftgram.y
@@ -0,0 +1,452 @@
+/*
+ * $XFree86: xc/lib/MiniXft/xftgram.y,v 1.5 2001/05/16 10:32:54 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+%{
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "minixftint.h"
+
+static MiniXftMatrix matrix;
+
+%}
+
+%union {
+ int ival;
+ double dval;
+ char *sval;
+ MiniXftExpr *eval;
+ MiniXftPattern *pval;
+ MiniXftValue vval;
+ MiniXftEdit *Eval;
+ MiniXftOp oval;
+ MiniXftQual qval;
+ MiniXftTest *tval;
+}
+
+%token <ival> INTEGER
+%token <dval> DOUBLE
+%token <sval> STRING NAME
+%token <ival> ANY ALL
+%token <ival> DIR CACHE INCLUDE INCLUDEIF MATCH EDIT
+%token <ival> TOK_TRUE TOK_FALSE TOK_NIL
+%token <ival> EQUAL SEMI OS CS
+
+%type <eval> expr
+%type <vval> value
+%type <sval> field
+%type <Eval> edit
+%type <Eval> edits
+%type <oval> eqop
+%type <qval> qual
+%type <oval> compare
+%type <tval> tests test
+%type <dval> number
+
+%right <ival> QUEST COLON
+%left <ival> OROR
+%left <ival> ANDAND
+%left <ival> EQEQ NOTEQ
+%left <ival> LESS LESSEQ MORE MOREEQ
+%left <ival> PLUS MINUS
+%left <ival> TIMES DIVIDE
+%right <ival> NOT
+
+%%
+configs : configs config
+ |
+ ;
+config : DIR STRING
+ { MiniXftConfigAddDir ($2); }
+ | CACHE STRING
+ { MiniXftConfigSetCache ($2); }
+ | INCLUDE STRING
+ { MiniXftConfigPushInput ($2, True); }
+ | INCLUDEIF STRING
+ { MiniXftConfigPushInput ($2, False); }
+ | MATCH tests EDIT edits
+ { MiniXftConfigAddEdit ($2, $4); }
+ ;
+tests : test tests
+ { $1->next = $2; $$ = $1; }
+ |
+ { $$ = 0; }
+ ;
+test : qual field compare value
+ { $$ = MiniXftTestCreate ($1, $2, $3, $4); }
+ ;
+qual : ANY
+ { $$ = MiniXftQualAny; }
+ | ALL
+ { $$ = MiniXftQualAll; }
+ |
+ { $$ = MiniXftQualAny; }
+ ;
+field : NAME
+ {
+ $$ = MiniXftConfigSaveField ($1);
+ }
+ ;
+compare : EQUAL
+ { $$ = MiniXftOpEqual; }
+ | EQEQ
+ { $$ = MiniXftOpEqual; }
+ | NOTEQ
+ { $$ = MiniXftOpNotEqual; }
+ | LESS
+ { $$ = MiniXftOpLess; }
+ | LESSEQ
+ { $$ = MiniXftOpLessEqual; }
+ | MORE
+ { $$ = MiniXftOpMore; }
+ | MOREEQ
+ { $$ = MiniXftOpMoreEqual; }
+ ;
+value : INTEGER
+ {
+ $$.type = MiniXftTypeInteger;
+ $$.u.i = $1;
+ }
+ | DOUBLE
+ {
+ $$.type = MiniXftTypeDouble;
+ $$.u.d = $1;
+ }
+ | STRING
+ {
+ $$.type = MiniXftTypeString;
+ $$.u.s = $1;
+ }
+ | TOK_TRUE
+ {
+ $$.type = MiniXftTypeBool;
+ $$.u.b = True;
+ }
+ | TOK_FALSE
+ {
+ $$.type = MiniXftTypeBool;
+ $$.u.b = False;
+ }
+ | TOK_NIL
+ {
+ $$.type = MiniXftTypeVoid;
+ }
+ | matrix
+ {
+ $$.type = MiniXftTypeMatrix;
+ $$.u.m = &matrix;
+ }
+ ;
+matrix : OS number number number number CS
+ {
+ matrix.xx = $2;
+ matrix.xy = $3;
+ matrix.yx = $4;
+ matrix.__REALLY_YY__ = $5;
+ }
+number : INTEGER
+ { $$ = (double) $1; }
+ | DOUBLE
+ ;
+edits : edit edits
+ { $1->next = $2; $$ = $1; }
+ |
+ { $$ = 0; }
+ ;
+edit : field eqop expr SEMI
+ { $$ = MiniXftEditCreate ($1, $2, $3); }
+ ;
+eqop : EQUAL
+ { $$ = MiniXftOpAssign; }
+ | PLUS EQUAL
+ { $$ = MiniXftOpPrepend; }
+ | EQUAL PLUS
+ { $$ = MiniXftOpAppend; }
+ ;
+expr : INTEGER
+ { $$ = MiniXftExprCreateInteger ($1); }
+ | DOUBLE
+ { $$ = MiniXftExprCreateDouble ($1); }
+ | STRING
+ { $$ = MiniXftExprCreateString ($1); }
+ | TOK_TRUE
+ { $$ = MiniXftExprCreateBool (True); }
+ | TOK_FALSE
+ { $$ = MiniXftExprCreateBool (False); }
+ | TOK_NIL
+ { $$ = MiniXftExprCreateNil (); }
+ | matrix
+ { $$ = MiniXftExprCreateMatrix (&matrix); }
+ | NAME
+ { $$ = MiniXftExprCreateField ($1); }
+ | expr OROR expr
+ { $$ = MiniXftExprCreateOp ($1, MiniXftOpOr, $3); }
+ | expr ANDAND expr
+ { $$ = MiniXftExprCreateOp ($1, MiniXftOpAnd, $3); }
+ | expr EQEQ expr
+ { $$ = MiniXftExprCreateOp ($1, MiniXftOpEqual, $3); }
+ | expr NOTEQ expr
+ { $$ = MiniXftExprCreateOp ($1, MiniXftOpNotEqual, $3); }
+ | expr LESS expr
+ { $$ = MiniXftExprCreateOp ($1, MiniXftOpLess, $3); }
+ | expr LESSEQ expr
+ { $$ = MiniXftExprCreateOp ($1, MiniXftOpLessEqual, $3); }
+ | expr MORE expr
+ { $$ = MiniXftExprCreateOp ($1, MiniXftOpMore, $3); }
+ | expr MOREEQ expr
+ { $$ = MiniXftExprCreateOp ($1, MiniXftOpMoreEqual, $3); }
+ | expr PLUS expr
+ { $$ = MiniXftExprCreateOp ($1, MiniXftOpPlus, $3); }
+ | expr MINUS expr
+ { $$ = MiniXftExprCreateOp ($1, MiniXftOpMinus, $3); }
+ | expr TIMES expr
+ { $$ = MiniXftExprCreateOp ($1, MiniXftOpTimes, $3); }
+ | expr DIVIDE expr
+ { $$ = MiniXftExprCreateOp ($1, MiniXftOpDivide, $3); }
+ | NOT expr
+ { $$ = MiniXftExprCreateOp ($2, MiniXftOpNot, (MiniXftExpr *) 0); }
+ | expr QUEST expr COLON expr
+ { $$ = MiniXftExprCreateOp ($1, MiniXftOpQuest, MiniXftExprCreateOp ($3, MiniXftOpQuest, $5)); }
+ ;
+%%
+
+int
+MiniXftConfigwrap (void)
+{
+ return 1;
+}
+
+void
+MiniXftConfigerror (char *fmt, ...)
+{
+ va_list args;
+
+ fprintf (stderr, "\"%s\": line %d, ", MiniXftConfigFile, MiniXftConfigLineno);
+ va_start (args, fmt);
+ vfprintf (stderr, fmt, args);
+ va_end (args);
+ fprintf (stderr, "\n");
+}
+
+MiniXftTest *
+MiniXftTestCreate (MiniXftQual qual, const char *field, MiniXftOp compare, MiniXftValue value)
+{
+ MiniXftTest *test = (MiniXftTest *) malloc (sizeof (MiniXftTest));;
+
+ if (test)
+ {
+ test->next = 0;
+ test->qual = qual;
+ test->field = field; /* already saved in grammar */
+ test->op = compare;
+ if (value.type == MiniXftTypeString)
+ value.u.s = _MiniXftSaveString (value.u.s);
+ else if (value.type == MiniXftTypeMatrix)
+ value.u.m = _MiniXftSaveMatrix (value.u.m);
+ test->value = value;
+ }
+ return test;
+}
+
+MiniXftExpr *
+MiniXftExprCreateInteger (int i)
+{
+ MiniXftExpr *e = (MiniXftExpr *) malloc (sizeof (MiniXftExpr));
+
+ if (e)
+ {
+ e->op = MiniXftOpInteger;
+ e->u.ival = i;
+ }
+ return e;
+}
+
+MiniXftExpr *
+MiniXftExprCreateDouble (double d)
+{
+ MiniXftExpr *e = (MiniXftExpr *) malloc (sizeof (MiniXftExpr));
+
+ if (e)
+ {
+ e->op = MiniXftOpDouble;
+ e->u.dval = d;
+ }
+ return e;
+}
+
+MiniXftExpr *
+MiniXftExprCreateString (const char *s)
+{
+ MiniXftExpr *e = (MiniXftExpr *) malloc (sizeof (MiniXftExpr));
+
+ if (e)
+ {
+ e->op = MiniXftOpString;
+ e->u.sval = _MiniXftSaveString (s);
+ }
+ return e;
+}
+
+MiniXftExpr *
+MiniXftExprCreateMatrix (const MiniXftMatrix *m)
+{
+ MiniXftExpr *e = (MiniXftExpr *) malloc (sizeof (MiniXftExpr));
+
+ if (e)
+ {
+ e->op = MiniXftOpMatrix;
+ e->u.mval = _MiniXftSaveMatrix (m);
+ }
+ return e;
+}
+
+MiniXftExpr *
+MiniXftExprCreateBool (Bool b)
+{
+ MiniXftExpr *e = (MiniXftExpr *) malloc (sizeof (MiniXftExpr));
+
+ if (e)
+ {
+ e->op = MiniXftOpBool;
+ e->u.bval = b;
+ }
+ return e;
+}
+
+MiniXftExpr *
+MiniXftExprCreateNil (void)
+{
+ MiniXftExpr *e = (MiniXftExpr *) malloc (sizeof (MiniXftExpr));
+
+ if (e)
+ {
+ e->op = MiniXftOpNil;
+ }
+ return e;
+}
+
+MiniXftExpr *
+MiniXftExprCreateField (const char *field)
+{
+ MiniXftExpr *e = (MiniXftExpr *) malloc (sizeof (MiniXftExpr));
+
+ if (e)
+ {
+ e->op = MiniXftOpField;
+ e->u.field = _MiniXftSaveString (field);
+ }
+ return e;
+}
+
+MiniXftExpr *
+MiniXftExprCreateOp (MiniXftExpr *left, MiniXftOp op, MiniXftExpr *right)
+{
+ MiniXftExpr *e = (MiniXftExpr *) malloc (sizeof (MiniXftExpr));
+
+ if (e)
+ {
+ e->op = op;
+ e->u.tree.left = left;
+ e->u.tree.right = right;
+ }
+ return e;
+}
+
+void
+MiniXftExprDestroy (MiniXftExpr *e)
+{
+ switch (e->op) {
+ case MiniXftOpInteger:
+ break;
+ case MiniXftOpDouble:
+ break;
+ case MiniXftOpString:
+ free (e->u.sval);
+ break;
+ case MiniXftOpMatrix:
+ free (e->u.mval);
+ break;
+ case MiniXftOpBool:
+ break;
+ case MiniXftOpField:
+ free (e->u.field);
+ break;
+ case MiniXftOpAssign:
+ case MiniXftOpPrepend:
+ case MiniXftOpAppend:
+ break;
+ case MiniXftOpOr:
+ case MiniXftOpAnd:
+ case MiniXftOpEqual:
+ case MiniXftOpNotEqual:
+ case MiniXftOpLess:
+ case MiniXftOpLessEqual:
+ case MiniXftOpMore:
+ case MiniXftOpMoreEqual:
+ case MiniXftOpPlus:
+ case MiniXftOpMinus:
+ case MiniXftOpTimes:
+ case MiniXftOpDivide:
+ case MiniXftOpQuest:
+ MiniXftExprDestroy (e->u.tree.right);
+ /* fall through */
+ case MiniXftOpNot:
+ MiniXftExprDestroy (e->u.tree.left);
+ break;
+ case MiniXftOpNil:
+ break;
+ }
+ free (e);
+}
+
+MiniXftEdit *
+MiniXftEditCreate (const char *field, MiniXftOp op, MiniXftExpr *expr)
+{
+ MiniXftEdit *e = (MiniXftEdit *) malloc (sizeof (MiniXftEdit));
+
+ if (e)
+ {
+ e->next = 0;
+ e->field = field; /* already saved in grammar */
+ e->op = op;
+ e->expr = expr;
+ }
+ return e;
+}
+
+void
+MiniXftEditDestroy (MiniXftEdit *e)
+{
+ if (e->next)
+ MiniXftEditDestroy (e->next);
+ free ((void *) e->field);
+ if (e->expr)
+ MiniXftExprDestroy (e->expr);
+}
+
+char *
+MiniXftConfigSaveField (const char *field)
+{
+ return _MiniXftSaveString (field);
+}
diff --git a/pango/mini-xft/minixftinit.c b/pango/mini-xft/minixftinit.c
new file mode 100644
index 00000000..9a995044
--- /dev/null
+++ b/pango/mini-xft/minixftinit.c
@@ -0,0 +1,48 @@
+/*
+ * $XFree86: xc/lib/MiniXft/xftinit.c,v 1.2 2000/12/15 17:12:53 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include "minixftint.h"
+
+MiniXftFontSet *_MiniXftFontSet;
+Bool _MiniXftConfigInitialized;
+
+Bool
+MiniXftInit (char *config)
+{
+ if (_MiniXftConfigInitialized)
+ return True;
+ _MiniXftConfigInitialized = True;
+ if (!config)
+ {
+ config = getenv ("XFT_CONFIG");
+ if (!config)
+ config = XFT_DEFAULT_PATH;
+ }
+ if (MiniXftConfigLexFile (config))
+ {
+ MiniXftConfigparse ();
+ }
+ return True;
+}
diff --git a/pango/mini-xft/minixftint.h b/pango/mini-xft/minixftint.h
new file mode 100644
index 00000000..22f937a9
--- /dev/null
+++ b/pango/mini-xft/minixftint.h
@@ -0,0 +1,395 @@
+/*
+ * $XFree86: xc/lib/MiniXft/minixftint.h,v 1.26 2001/07/13 18:16:10 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _XFTINT_H_
+#define _XFTINT_H_
+
+#include "MiniXftFreetype.h"
+
+typedef struct _MiniXftMatcher {
+ char *object;
+ double (*compare) (char *object, MiniXftValue value1, MiniXftValue value2);
+} MiniXftMatcher;
+
+typedef struct _MiniXftSymbolic {
+ const char *name;
+ int value;
+} MiniXftSymbolic;
+
+#define XFT_DRAW_N_SRC 2
+
+#define XFT_DRAW_SRC_TEXT 0
+#define XFT_DRAW_SRC_RECT 1
+
+typedef struct _MiniXftDisplayInfo {
+ struct _MiniXftDisplayInfo *next;
+ Display *display;
+ // XExtCodes *codes;
+ MiniXftPattern *defaults;
+ // MiniXftFontSet *coreFonts;
+ Bool hasRender;
+} MiniXftDisplayInfo;
+
+extern MiniXftDisplayInfo *_MiniXftDisplayInfo;
+extern MiniXftFontSet *_MiniXftGlobalFontSet;
+extern char **MiniXftConfigDirs;
+extern MiniXftFontSet *_MiniXftFontSet;
+
+#define XFT_NMISSING 256
+
+#ifndef XFT_DEFAULT_PATH
+#define XFT_DEFAULT_PATH "/usr/X11R6/lib/X11/XftConfig"
+#endif
+
+#define XFT_DBG_OPEN 1
+#define XFT_DBG_OPENV 2
+#define XFT_DBG_RENDER 4
+#define XFT_DBG_DRAW 8
+#define XFT_DBG_REF 16
+#define XFT_DBG_GLYPH 32
+#define XFT_DBG_GLYPHV 64
+#define XFT_DBG_CACHE 128
+#define XFT_DBG_CACHEV 256
+#define XFT_DBG_MATCH 512
+#define XFT_DBG_MATCHV 1024
+
+typedef enum _MiniXftOp {
+ MiniXftOpInteger, MiniXftOpDouble, MiniXftOpString, MiniXftOpMatrix, MiniXftOpBool, MiniXftOpNil,
+ MiniXftOpField,
+ MiniXftOpAssign, MiniXftOpPrepend, MiniXftOpAppend,
+ MiniXftOpQuest,
+ MiniXftOpOr, MiniXftOpAnd, MiniXftOpEqual, MiniXftOpNotEqual,
+ MiniXftOpLess, MiniXftOpLessEqual, MiniXftOpMore, MiniXftOpMoreEqual,
+ MiniXftOpPlus, MiniXftOpMinus, MiniXftOpTimes, MiniXftOpDivide,
+ MiniXftOpNot
+} MiniXftOp;
+
+typedef struct _MiniXftExpr {
+ MiniXftOp op;
+ union {
+ int ival;
+ double dval;
+ char *sval;
+ MiniXftMatrix *mval;
+ Bool bval;
+ char *field;
+ struct {
+ struct _MiniXftExpr *left, *right;
+ } tree;
+ } u;
+} MiniXftExpr;
+
+typedef enum _MiniXftQual {
+ MiniXftQualAny, MiniXftQualAll
+} MiniXftQual;
+
+typedef struct _MiniXftTest {
+ struct _MiniXftTest *next;
+ MiniXftQual qual;
+ const char *field;
+ MiniXftOp op;
+ MiniXftValue value;
+} MiniXftTest;
+
+typedef struct _MiniXftEdit {
+ struct _MiniXftEdit *next;
+ const char *field;
+ MiniXftOp op;
+ MiniXftExpr *expr;
+} MiniXftEdit;
+
+typedef struct _MiniXftSubst {
+ struct _MiniXftSubst *next;
+ MiniXftTest *test;
+ MiniXftEdit *edit;
+} MiniXftSubst;
+
+/*
+ * I tried this with functions that took va_list* arguments
+ * but portability concerns made me change these functions
+ * into macros (sigh).
+ */
+
+#define _MiniXftPatternVapBuild(result, orig, va) \
+{ \
+ MiniXftPattern *__p__ = (orig); \
+ const char *__o__; \
+ MiniXftValue __v__; \
+ \
+ if (!__p__) \
+ { \
+ __p__ = MiniXftPatternCreate (); \
+ if (!__p__) \
+ goto _MiniXftPatternVapBuild_bail0; \
+ } \
+ for (;;) \
+ { \
+ __o__ = va_arg (va, const char *); \
+ if (!__o__) \
+ break; \
+ __v__.type = va_arg (va, MiniXftType); \
+ switch (__v__.type) { \
+ case MiniXftTypeVoid: \
+ goto _MiniXftPatternVapBuild_bail1; \
+ case MiniXftTypeInteger: \
+ __v__.u.i = va_arg (va, int); \
+ break; \
+ case MiniXftTypeDouble: \
+ __v__.u.d = va_arg (va, double); \
+ break; \
+ case MiniXftTypeString: \
+ __v__.u.s = va_arg (va, char *); \
+ break; \
+ case MiniXftTypeBool: \
+ __v__.u.b = va_arg (va, Bool); \
+ break; \
+ case MiniXftTypeMatrix: \
+ __v__.u.m = va_arg (va, MiniXftMatrix *); \
+ break; \
+ } \
+ if (!MiniXftPatternAdd (__p__, __o__, __v__, True)) \
+ goto _MiniXftPatternVapBuild_bail1; \
+ } \
+ result = __p__; \
+ goto _MiniXftPatternVapBuild_return; \
+ \
+_MiniXftPatternVapBuild_bail1: \
+ if (!orig) \
+ MiniXftPatternDestroy (__p__); \
+_MiniXftPatternVapBuild_bail0: \
+ result = 0; \
+ \
+_MiniXftPatternVapBuild_return: \
+ ; \
+}
+
+
+/* xftcache.c */
+
+char *
+MiniXftFileCacheFind (char *file, int id, int *count);
+
+void
+MiniXftFileCacheDispose (void);
+
+void
+MiniXftFileCacheLoad (char *cache);
+
+Bool
+MiniXftFileCacheUpdate (char *file, int id, char *name);
+
+Bool
+MiniXftFileCacheSave (char *cache);
+
+Bool
+MiniXftFileCacheReadDir (MiniXftFontSet *set, const char *cache_file);
+
+Bool
+MiniXftFileCacheWriteDir (MiniXftFontSet *set, const char *cache_file);
+
+/* xftcfg.c */
+Bool
+MiniXftConfigAddDir (char *d);
+
+Bool
+MiniXftConfigSetCache (char *c);
+
+char *
+MiniXftConfigGetCache (void);
+
+Bool
+MiniXftConfigAddEdit (MiniXftTest *test, MiniXftEdit *edit);
+
+Bool
+_MiniXftConfigCompareValue (MiniXftValue m,
+ MiniXftOp op,
+ MiniXftValue v);
+
+/* xftdbg.c */
+void
+MiniXftOpPrint (MiniXftOp op);
+
+void
+MiniXftTestPrint (MiniXftTest *test);
+
+void
+MiniXftExprPrint (MiniXftExpr *expr);
+
+void
+MiniXftEditPrint (MiniXftEdit *edit);
+
+void
+MiniXftSubstPrint (MiniXftSubst *subst);
+
+/* xftdpy.c */
+int
+MiniXftDefaultParseBool (char *v);
+
+Bool
+MiniXftDefaultGetBool (Display *dpy, const char *object, int screen, Bool def);
+
+int
+MiniXftDefaultGetInteger (Display *dpy, const char *object, int screen, int def);
+
+double
+MiniXftDefaultGetDouble (Display *dpy, const char *object, int screen, double def);
+
+MiniXftFontSet *
+MiniXftDisplayGetFontSet (Display *dpy);
+
+/* xftextent.c */
+/* xftfont.c */
+int
+_MiniXftFontDebug (void);
+
+/* xftfs.c */
+/* xftgram.y */
+int
+MiniXftConfigparse (void);
+
+int
+MiniXftConfigwrap (void);
+
+void
+MiniXftConfigerror (char *fmt, ...);
+
+char *
+MiniXftConfigSaveField (const char *field);
+
+MiniXftTest *
+MiniXftTestCreate (MiniXftQual qual, const char *field, MiniXftOp compare, MiniXftValue value);
+
+MiniXftExpr *
+MiniXftExprCreateInteger (int i);
+
+MiniXftExpr *
+MiniXftExprCreateDouble (double d);
+
+MiniXftExpr *
+MiniXftExprCreateString (const char *s);
+
+MiniXftExpr *
+MiniXftExprCreateMatrix (const MiniXftMatrix *m);
+
+MiniXftExpr *
+MiniXftExprCreateBool (Bool b);
+
+MiniXftExpr *
+MiniXftExprCreateNil (void);
+
+MiniXftExpr *
+MiniXftExprCreateField (const char *field);
+
+MiniXftExpr *
+MiniXftExprCreateOp (MiniXftExpr *left, MiniXftOp op, MiniXftExpr *right);
+
+void
+MiniXftExprDestroy (MiniXftExpr *e);
+
+MiniXftEdit *
+MiniXftEditCreate (const char *field, MiniXftOp op, MiniXftExpr *expr);
+
+void
+MiniXftEditDestroy (MiniXftEdit *e);
+
+/* xftinit.c */
+
+/* xftlex.l */
+extern int MiniXftConfigLineno;
+extern char *MiniXftConfigFile;
+
+int
+MiniXftConfiglex (void);
+
+Bool
+MiniXftConfigLexFile(char *s);
+
+Bool
+MiniXftConfigPushInput (char *s, Bool complain);
+
+/* xftlist.c */
+Bool
+MiniXftListValueCompare (MiniXftValue v1,
+ MiniXftValue v2);
+
+Bool
+MiniXftListValueListCompare (MiniXftValueList *v1orig,
+ MiniXftValueList *v2orig,
+ MiniXftQual qual);
+
+Bool
+MiniXftListMatch (MiniXftPattern *p,
+ MiniXftPattern *font,
+ MiniXftQual qual);
+
+Bool
+MiniXftListAppend (MiniXftFontSet *s,
+ MiniXftPattern *font,
+ MiniXftObjectSet *os);
+
+
+/* xftmatch.c */
+
+/* xftname.c */
+Bool
+MiniXftNameConstant (char *string, int *result);
+
+/* xftpat.c */
+
+/* xftrender.c */
+
+/* xftmatrix.c */
+MiniXftMatrix *
+_MiniXftSaveMatrix (const MiniXftMatrix *mat);
+
+/* xftstr.c */
+char *
+_MiniXftSaveString (const char *s);
+
+const char *
+_MiniXftGetInt(const char *ptr, int *val);
+
+char *
+_MiniXftSplitStr (const char *field, char *save);
+
+char *
+_MiniXftDownStr (const char *field, char *save);
+
+const char *
+_MiniXftSplitField (const char *field, char *save);
+
+const char *
+_MiniXftSplitValue (const char *field, char *save);
+
+int
+_MiniXftMatchSymbolic (MiniXftSymbolic *s, int n, const char *name, int def);
+
+int
+_MiniXftStrCmpIgnoreCase (const char *s1, const char *s2);
+
+/* xftxlfd.c */
+Bool
+MiniXftCoreAddFonts (MiniXftFontSet *set, Display *dpy, Bool ignore_scalable);
+
+#endif /* _XFT_INT_H_ */
diff --git a/pango/mini-xft/minixftlex.c b/pango/mini-xft/minixftlex.c
new file mode 100644
index 00000000..4e901a6d
--- /dev/null
+++ b/pango/mini-xft/minixftlex.c
@@ -0,0 +1,1985 @@
+/* A lexical scanner generated by flex */
+
+/* Scanner skeleton version:
+ * $Header$
+ */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+
+#include <stdio.h>
+#include <unistd.h>
+
+
+/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+#endif
+
+
+#ifdef __cplusplus
+
+#include <stdlib.h>
+
+/* Use prototypes in function declarations. */
+#define YY_USE_PROTOS
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_PROTOS
+#define YY_USE_CONST
+
+#endif /* __STDC__ */
+#endif /* ! __cplusplus */
+
+#ifdef __TURBOC__
+ #pragma warn -rch
+ #pragma warn -use
+#include <io.h>
+#include <stdlib.h>
+#define YY_USE_CONST
+#define YY_USE_PROTOS
+#endif
+
+#ifdef YY_USE_CONST
+#define MiniXftConfigconst const
+#else
+#define MiniXftConfigconst
+#endif
+
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN MiniXftConfig_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((MiniXftConfig_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE MiniXftConfigrestart( MiniXftConfigin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#define YY_BUF_SIZE 16384
+
+typedef struct MiniXftConfig_buffer_state *YY_BUFFER_STATE;
+
+extern int MiniXftConfigleng;
+extern FILE *MiniXftConfigin, *MiniXftConfigout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+/* The funky do-while in the following #define is used to turn the definition
+ * int a single C statement (which needs a semi-colon terminator). This
+ * avoids problems with code like:
+ *
+ * if ( condition_holds )
+ * MiniXftConfigless( 5 );
+ * else
+ * do_something_else();
+ *
+ * Prior to using the do-while the compiler would get upset at the
+ * "else" because it interpreted the "if" statement as being all
+ * done when it reached the ';' after the MiniXftConfigless() call.
+ */
+
+/* Return all but the first 'n' matched characters back to the input stream. */
+
+#define MiniXftConfigless(n) \
+ do \
+ { \
+ /* Undo effects of setting up MiniXftConfigtext. */ \
+ *MiniXftConfig_cp = MiniXftConfig_hold_char; \
+ YY_RESTORE_YY_MORE_OFFSET \
+ MiniXftConfig_c_buf_p = MiniXftConfig_cp = MiniXftConfig_bp + n - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up MiniXftConfigtext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) MiniXftConfigunput( c, MiniXftConfigtext_ptr )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+typedef unsigned int MiniXftConfig_size_t;
+
+
+struct MiniXftConfig_buffer_state
+ {
+ FILE *MiniXftConfig_input_file;
+
+ char *MiniXftConfig_ch_buf; /* input buffer */
+ char *MiniXftConfig_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ MiniXftConfig_size_t MiniXftConfig_buf_size;
+
+ /* Number of characters read into MiniXftConfig_ch_buf, not including EOB
+ * characters.
+ */
+ int MiniXftConfig_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int MiniXftConfig_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int MiniXftConfig_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int MiniXftConfig_at_bol;
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int MiniXftConfig_fill_buffer;
+
+ int MiniXftConfig_buffer_status;
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via MiniXftConfigrestart()), so that the user can continue scanning by
+ * just pointing MiniXftConfigin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+ };
+
+static YY_BUFFER_STATE MiniXftConfig_current_buffer = 0;
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ */
+#define YY_CURRENT_BUFFER MiniXftConfig_current_buffer
+
+
+/* MiniXftConfig_hold_char holds the character lost when MiniXftConfigtext is formed. */
+static char MiniXftConfig_hold_char;
+
+static int MiniXftConfig_n_chars; /* number of characters read into MiniXftConfig_ch_buf */
+
+
+int MiniXftConfigleng;
+
+/* Points to current character in buffer. */
+static char *MiniXftConfig_c_buf_p = (char *) 0;
+static int MiniXftConfig_init = 1; /* whether we need to initialize */
+static int MiniXftConfig_start = 0; /* start state number */
+
+/* Flag which is used to allow MiniXftConfigwrap()'s to do buffer switches
+ * instead of setting up a fresh MiniXftConfigin. A bit of a hack ...
+ */
+static int MiniXftConfig_did_buffer_switch_on_eof;
+
+void MiniXftConfigrestart YY_PROTO(( FILE *input_file ));
+
+void MiniXftConfig_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
+void MiniXftConfig_load_buffer_state YY_PROTO(( void ));
+YY_BUFFER_STATE MiniXftConfig_create_buffer YY_PROTO(( FILE *file, int size ));
+void MiniXftConfig_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+void MiniXftConfig_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
+void MiniXftConfig_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+#define YY_FLUSH_BUFFER MiniXftConfig_flush_buffer( MiniXftConfig_current_buffer )
+
+YY_BUFFER_STATE MiniXftConfig_scan_buffer YY_PROTO(( char *base, MiniXftConfig_size_t size ));
+YY_BUFFER_STATE MiniXftConfig_scan_string YY_PROTO(( MiniXftConfigconst char *MiniXftConfig_str ));
+YY_BUFFER_STATE MiniXftConfig_scan_bytes YY_PROTO(( MiniXftConfigconst char *bytes, int len ));
+
+static void *MiniXftConfig_flex_alloc YY_PROTO(( MiniXftConfig_size_t ));
+static void *MiniXftConfig_flex_realloc YY_PROTO(( void *, MiniXftConfig_size_t ));
+static void MiniXftConfig_flex_free YY_PROTO(( void * ));
+
+#define MiniXftConfig_new_buffer MiniXftConfig_create_buffer
+
+#define MiniXftConfig_set_interactive(is_interactive) \
+ { \
+ if ( ! MiniXftConfig_current_buffer ) \
+ MiniXftConfig_current_buffer = MiniXftConfig_create_buffer( MiniXftConfigin, YY_BUF_SIZE ); \
+ MiniXftConfig_current_buffer->MiniXftConfig_is_interactive = is_interactive; \
+ }
+
+#define MiniXftConfig_set_bol(at_bol) \
+ { \
+ if ( ! MiniXftConfig_current_buffer ) \
+ MiniXftConfig_current_buffer = MiniXftConfig_create_buffer( MiniXftConfigin, YY_BUF_SIZE ); \
+ MiniXftConfig_current_buffer->MiniXftConfig_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (MiniXftConfig_current_buffer->MiniXftConfig_at_bol)
+
+typedef unsigned char YY_CHAR;
+FILE *MiniXftConfigin = (FILE *) 0, *MiniXftConfigout = (FILE *) 0;
+typedef int MiniXftConfig_state_type;
+extern char *MiniXftConfigtext;
+#define MiniXftConfigtext_ptr MiniXftConfigtext
+
+static MiniXftConfig_state_type MiniXftConfig_get_previous_state YY_PROTO(( void ));
+static MiniXftConfig_state_type MiniXftConfig_try_NUL_trans YY_PROTO(( MiniXftConfig_state_type current_state ));
+static int MiniXftConfig_get_next_buffer YY_PROTO(( void ));
+static void MiniXftConfig_fatal_error YY_PROTO(( MiniXftConfigconst char msg[] ));
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up MiniXftConfigtext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ MiniXftConfigtext_ptr = MiniXftConfig_bp; \
+ MiniXftConfigleng = (int) (MiniXftConfig_cp - MiniXftConfig_bp); \
+ MiniXftConfig_hold_char = *MiniXftConfig_cp; \
+ *MiniXftConfig_cp = '\0'; \
+ MiniXftConfig_c_buf_p = MiniXftConfig_cp;
+
+#define YY_NUM_RULES 39
+#define YY_END_OF_BUFFER 40
+static MiniXftConfigconst short int MiniXftConfig_accept[94] =
+ { 0,
+ 0, 0, 40, 37, 38, 21, 37, 37, 19, 17,
+ 18, 37, 20, 34, 15, 16, 24, 14, 28, 30,
+ 36, 31, 32, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 37, 2, 29, 0, 33, 0, 22, 35,
+ 0, 1, 35, 34, 0, 25, 26, 27, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36, 36, 23,
+ 33, 0, 35, 0, 0, 35, 13, 12, 36, 3,
+ 36, 36, 36, 36, 11, 36, 35, 0, 36, 8,
+ 36, 36, 36, 9, 4, 10, 36, 7, 36, 5,
+ 36, 6, 0
+
+ } ;
+
+static MiniXftConfigconst int MiniXftConfig_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 3, 4, 5, 1, 1, 6, 1, 1,
+ 1, 7, 8, 1, 9, 10, 11, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 13, 14, 15,
+ 16, 17, 18, 1, 19, 19, 19, 19, 20, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 21, 22, 23, 1, 24, 1, 25, 19, 26, 27,
+
+ 28, 29, 19, 30, 31, 19, 19, 32, 33, 34,
+ 19, 19, 19, 35, 36, 37, 38, 19, 19, 19,
+ 39, 19, 40, 41, 42, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static MiniXftConfigconst int MiniXftConfig_meta[43] =
+ { 0,
+ 1, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 3, 1, 1, 1, 1, 1, 1, 3, 3,
+ 1, 1, 1, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 1,
+ 1, 1
+ } ;
+
+static MiniXftConfigconst short int MiniXftConfig_base[96] =
+ { 0,
+ 0, 126, 130, 132, 132, 113, 39, 122, 132, 132,
+ 132, 32, 120, 35, 132, 132, 110, 109, 108, 132,
+ 0, 132, 132, 14, 98, 91, 94, 95, 85, 93,
+ 86, 81, 74, 132, 132, 45, 132, 46, 132, 42,
+ 102, 132, 45, 46, 67, 132, 132, 132, 0, 81,
+ 73, 85, 75, 77, 73, 78, 66, 70, 63, 132,
+ 47, 41, 66, 88, 87, 86, 0, 0, 67, 0,
+ 59, 59, 61, 66, 0, 63, 32, 47, 62, 0,
+ 60, 49, 54, 0, 0, 0, 54, 0, 52, 46,
+ 42, 0, 132, 106, 61
+
+ } ;
+
+static MiniXftConfigconst short int MiniXftConfig_def[96] =
+ { 0,
+ 93, 1, 93, 93, 93, 93, 94, 93, 93, 93,
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
+ 95, 93, 93, 95, 95, 95, 95, 95, 95, 95,
+ 95, 95, 93, 93, 93, 94, 93, 94, 93, 93,
+ 93, 93, 93, 93, 93, 93, 93, 93, 95, 95,
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 93,
+ 94, 93, 93, 93, 93, 93, 95, 95, 95, 95,
+ 95, 95, 95, 95, 95, 95, 93, 93, 95, 95,
+ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
+ 95, 95, 0, 93, 93
+
+ } ;
+
+static MiniXftConfigconst short int MiniXftConfig_nxt[175] =
+ { 0,
+ 4, 5, 6, 7, 4, 8, 9, 10, 11, 12,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 21,
+ 22, 4, 23, 4, 24, 25, 26, 27, 28, 21,
+ 29, 21, 30, 31, 21, 21, 32, 21, 21, 4,
+ 33, 4, 37, 40, 43, 50, 44, 51, 37, 61,
+ 37, 45, 62, 40, 45, 43, 63, 44, 78, 45,
+ 38, 45, 45, 49, 45, 45, 38, 38, 38, 45,
+ 92, 41, 45, 45, 65, 65, 91, 63, 66, 90,
+ 89, 41, 77, 88, 64, 45, 87, 86, 77, 85,
+ 84, 83, 82, 45, 81, 80, 79, 66, 66, 78,
+
+ 76, 75, 74, 73, 72, 64, 36, 71, 36, 70,
+ 69, 68, 67, 62, 60, 59, 58, 57, 56, 55,
+ 54, 53, 52, 48, 47, 46, 42, 39, 35, 93,
+ 34, 3, 93, 93, 93, 93, 93, 93, 93, 93,
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
+ 93, 93, 93, 93
+ } ;
+
+static MiniXftConfigconst short int MiniXftConfig_chk[175] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 7, 12, 14, 24, 14, 24, 36, 38,
+ 61, 77, 62, 40, 14, 44, 43, 44, 78, 77,
+ 7, 40, 14, 95, 43, 44, 36, 38, 61, 40,
+ 91, 12, 43, 44, 45, 45, 90, 63, 45, 89,
+ 87, 40, 62, 83, 43, 63, 82, 81, 78, 79,
+ 76, 74, 73, 63, 72, 71, 69, 66, 65, 64,
+
+ 59, 58, 57, 56, 55, 63, 94, 54, 94, 53,
+ 52, 51, 50, 41, 33, 32, 31, 30, 29, 28,
+ 27, 26, 25, 19, 18, 17, 13, 8, 6, 3,
+ 2, 93, 93, 93, 93, 93, 93, 93, 93, 93,
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
+ 93, 93, 93, 93
+ } ;
+
+static MiniXftConfig_state_type MiniXftConfig_last_accepting_state;
+static char *MiniXftConfig_last_accepting_cpos;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define MiniXftConfigmore() MiniXftConfigmore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *MiniXftConfigtext;
+#line 1 "minixftlex.l"
+#define INITIAL 0
+#line 2 "minixftlex.l"
+/*
+ * $XFree86: xc/lib/MiniXft/xftlex.l,v 1.7 2001/05/18 16:03:06 tsi Exp $
+ *
+ * Copyright (c) 2000 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <string.h>
+#include "minixftint.h"
+
+#include "minixftgram.h"
+
+int MiniXftConfigLineno;
+
+static void _MiniXftConfigSkipComment (void);
+
+static void _MiniXftConfigSkipLine (void);
+
+static int _MiniXftConfigPopInput (void);
+
+
+#define XFT_CONFIG_IN_DEEP 20
+FILE *MiniXftConfigInStack[XFT_CONFIG_IN_DEEP];
+FILE **MiniXftConfigInpt = MiniXftConfigInStack + XFT_CONFIG_IN_DEEP;
+FILE *MiniXftConfigInput;
+int MiniXftConfigLinenos[XFT_CONFIG_IN_DEEP];
+int *MiniXftConfigLinenopt = MiniXftConfigLinenos + XFT_CONFIG_IN_DEEP;
+char *MiniXftConfigFile = "";
+char *MiniXftConfigFileNames[XFT_CONFIG_IN_DEEP];
+char **MiniXftConfigFileNamePt = MiniXftConfigFileNames + XFT_CONFIG_IN_DEEP;
+int MiniXftConfigFiledeep = 0;
+
+#undef YY_INPUT
+
+#define YY_INPUT(buf,result,max_size) \
+{ \
+ int c; \
+ result = 0; \
+ while (result < max_size) { \
+ c = getc (MiniXftConfigInput); \
+ if (c < 0) { \
+ c = _MiniXftConfigPopInput (); \
+ if (c < 0) \
+ break; \
+ } \
+ buf[result++] = c; \
+ if (c == '\n') \
+ { \
+ MiniXftConfigLineno++; \
+ break; \
+ } \
+ } \
+}
+
+#ifndef FLEX_SCANNER
+#undef input
+#undef unput
+static int input (void)
+{
+ char buf[1];
+ static int r = EOF;
+
+ if (r == 0)
+ return 0;
+ YY_INPUT(buf, r, 1);
+ if (r == 0)
+ return EOF;
+ return buf[0];
+}
+
+static void unput (char c)
+{
+ if (!c || c == EOF)
+ return;
+ if (c == '\n')
+ MiniXftConfigLineno--;
+ ungetc (c, MiniXftConfigInput);
+}
+#endif
+
+#line 531 "lex.MiniXftConfig.c"
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int MiniXftConfigwrap YY_PROTO(( void ));
+#else
+extern int MiniXftConfigwrap YY_PROTO(( void ));
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+static void MiniXftConfigunput YY_PROTO(( int c, char *buf_ptr ));
+#endif
+
+#ifndef MiniXftConfigtext_ptr
+static void MiniXftConfig_flex_strncpy YY_PROTO(( char *, MiniXftConfigconst char *, int ));
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int MiniXftConfig_flex_strlen YY_PROTO(( MiniXftConfigconst char * ));
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int MiniXftConfiginput YY_PROTO(( void ));
+#else
+static int input YY_PROTO(( void ));
+#endif
+#endif
+
+#if YY_STACK_USED
+static int MiniXftConfig_start_stack_ptr = 0;
+static int MiniXftConfig_start_stack_depth = 0;
+static int *MiniXftConfig_start_stack = 0;
+#ifndef YY_NO_PUSH_STATE
+static void MiniXftConfig_push_state YY_PROTO(( int new_state ));
+#endif
+#ifndef YY_NO_POP_STATE
+static void MiniXftConfig_pop_state YY_PROTO(( void ));
+#endif
+#ifndef YY_NO_TOP_STATE
+static int MiniXftConfig_top_state YY_PROTO(( void ));
+#endif
+
+#else
+#define YY_NO_PUSH_STATE 1
+#define YY_NO_POP_STATE 1
+#define YY_NO_TOP_STATE 1
+#endif
+
+#ifdef YY_MALLOC_DECL
+YY_MALLOC_DECL
+#else
+#if __STDC__
+#ifndef __cplusplus
+#include <stdlib.h>
+#endif
+#else
+/* Just try to get by without declaring the routines. This will fail
+ * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
+ * or sizeof(void*) != sizeof(int).
+ */
+#endif
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( MiniXftConfigtext, MiniXftConfigleng, 1, MiniXftConfigout )
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( MiniXftConfig_current_buffer->MiniXftConfig_is_interactive ) \
+ { \
+ int c = '*', n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( MiniXftConfigin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( MiniXftConfigin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else if ( ((result = fread( buf, 1, max_size, MiniXftConfigin )) == 0) \
+ && ferror( MiniXftConfigin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" );
+#endif
+
+/* No semi-colon after return; correct usage is to write "MiniXftConfigterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef MiniXftConfigterminate
+#define MiniXftConfigterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) MiniXftConfig_fatal_error( msg )
+#endif
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL int MiniXftConfiglex YY_PROTO(( void ))
+#endif
+
+/* Code executed at the beginning of each rule, after MiniXftConfigtext and MiniXftConfigleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ if ( MiniXftConfigleng > 0 ) \
+ MiniXftConfig_current_buffer->MiniXftConfig_at_bol = \
+ (MiniXftConfigtext[MiniXftConfigleng - 1] == '\n'); \
+ YY_USER_ACTION
+
+YY_DECL
+ {
+ register MiniXftConfig_state_type MiniXftConfig_current_state;
+ register char *MiniXftConfig_cp = NULL, *MiniXftConfig_bp = NULL;
+ register int MiniXftConfig_act;
+
+#line 100 "minixftlex.l"
+
+#line 687 "lex.MiniXftConfig.c"
+
+ if ( MiniXftConfig_init )
+ {
+ MiniXftConfig_init = 0;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! MiniXftConfig_start )
+ MiniXftConfig_start = 1; /* first start state */
+
+ if ( ! MiniXftConfigin )
+ MiniXftConfigin = stdin;
+
+ if ( ! MiniXftConfigout )
+ MiniXftConfigout = stdout;
+
+ if ( ! MiniXftConfig_current_buffer )
+ MiniXftConfig_current_buffer =
+ MiniXftConfig_create_buffer( MiniXftConfigin, YY_BUF_SIZE );
+
+ MiniXftConfig_load_buffer_state();
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ MiniXftConfig_cp = MiniXftConfig_c_buf_p;
+
+ /* Support of MiniXftConfigtext. */
+ *MiniXftConfig_cp = MiniXftConfig_hold_char;
+
+ /* MiniXftConfig_bp points to the position in MiniXftConfig_ch_buf of the start of
+ * the current run.
+ */
+ MiniXftConfig_bp = MiniXftConfig_cp;
+
+ MiniXftConfig_current_state = MiniXftConfig_start;
+ MiniXftConfig_current_state += YY_AT_BOL();
+MiniXftConfig_match:
+ do
+ {
+ register YY_CHAR MiniXftConfig_c = MiniXftConfig_ec[YY_SC_TO_UI(*MiniXftConfig_cp)];
+ if ( MiniXftConfig_accept[MiniXftConfig_current_state] )
+ {
+ MiniXftConfig_last_accepting_state = MiniXftConfig_current_state;
+ MiniXftConfig_last_accepting_cpos = MiniXftConfig_cp;
+ }
+ while ( MiniXftConfig_chk[MiniXftConfig_base[MiniXftConfig_current_state] + MiniXftConfig_c] != MiniXftConfig_current_state )
+ {
+ MiniXftConfig_current_state = (int) MiniXftConfig_def[MiniXftConfig_current_state];
+ if ( MiniXftConfig_current_state >= 94 )
+ MiniXftConfig_c = MiniXftConfig_meta[(unsigned int) MiniXftConfig_c];
+ }
+ MiniXftConfig_current_state = MiniXftConfig_nxt[MiniXftConfig_base[MiniXftConfig_current_state] + (unsigned int) MiniXftConfig_c];
+ ++MiniXftConfig_cp;
+ }
+ while ( MiniXftConfig_base[MiniXftConfig_current_state] != 132 );
+
+MiniXftConfig_find_action:
+ MiniXftConfig_act = MiniXftConfig_accept[MiniXftConfig_current_state];
+ if ( MiniXftConfig_act == 0 )
+ { /* have to back up */
+ MiniXftConfig_cp = MiniXftConfig_last_accepting_cpos;
+ MiniXftConfig_current_state = MiniXftConfig_last_accepting_state;
+ MiniXftConfig_act = MiniXftConfig_accept[MiniXftConfig_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+
+do_action: /* This label is used only to access EOF actions. */
+
+
+ switch ( MiniXftConfig_act )
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *MiniXftConfig_cp = MiniXftConfig_hold_char;
+ MiniXftConfig_cp = MiniXftConfig_last_accepting_cpos;
+ MiniXftConfig_current_state = MiniXftConfig_last_accepting_state;
+ goto MiniXftConfig_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 101 "minixftlex.l"
+_MiniXftConfigSkipComment();
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 102 "minixftlex.l"
+_MiniXftConfigSkipLine();
+ YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 103 "minixftlex.l"
+return DIR;
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 104 "minixftlex.l"
+return CACHE;
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 105 "minixftlex.l"
+return INCLUDE;
+ YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 106 "minixftlex.l"
+return INCLUDEIF;
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 107 "minixftlex.l"
+return MATCH;
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 108 "minixftlex.l"
+return EDIT;
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 109 "minixftlex.l"
+return TOK_TRUE;
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 110 "minixftlex.l"
+return TOK_FALSE;
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 111 "minixftlex.l"
+return TOK_NIL;
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 112 "minixftlex.l"
+return ANY;
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 113 "minixftlex.l"
+return ALL;
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 114 "minixftlex.l"
+return EQUAL;
+ YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 115 "minixftlex.l"
+return COLON;
+ YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 116 "minixftlex.l"
+return SEMI;
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 117 "minixftlex.l"
+return PLUS;
+ YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 118 "minixftlex.l"
+return MINUS;
+ YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 119 "minixftlex.l"
+return TIMES;
+ YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 120 "minixftlex.l"
+return DIVIDE;
+ YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 121 "minixftlex.l"
+return NOT;
+ YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 122 "minixftlex.l"
+return ANDAND;
+ YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 123 "minixftlex.l"
+return OROR;
+ YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 124 "minixftlex.l"
+return LESS;
+ YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 125 "minixftlex.l"
+return LESSEQ;
+ YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 126 "minixftlex.l"
+return EQEQ;
+ YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 127 "minixftlex.l"
+return MOREEQ;
+ YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 128 "minixftlex.l"
+return MORE;
+ YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 129 "minixftlex.l"
+return NOTEQ;
+ YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 130 "minixftlex.l"
+return QUEST;
+ YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 131 "minixftlex.l"
+return OS;
+ YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 132 "minixftlex.l"
+return CS;
+ YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 133 "minixftlex.l"
+{
+ MiniXftConfigtext[MiniXftConfigleng - 1] = '\0';
+ MiniXftConfiglval.sval = MiniXftConfigtext+1;
+ return STRING;
+ }
+ YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 138 "minixftlex.l"
+{
+ MiniXftConfiglval.ival = strtol (MiniXftConfigtext, 0, 10);
+ return INTEGER;
+ }
+ YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 142 "minixftlex.l"
+{
+ MiniXftConfiglval.dval = strtod (MiniXftConfigtext, 0);
+ return DOUBLE;
+ }
+ YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 146 "minixftlex.l"
+{
+ if (MiniXftNameConstant (MiniXftConfigtext, &MiniXftConfiglval.ival))
+ return INTEGER;
+ MiniXftConfiglval.sval = MiniXftConfigtext;
+ return NAME;
+ }
+ YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 152 "minixftlex.l"
+;
+ YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 153 "minixftlex.l"
+;
+ YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 154 "minixftlex.l"
+ECHO;
+ YY_BREAK
+#line 981 "lex.MiniXftConfig.c"
+case YY_STATE_EOF(INITIAL):
+ MiniXftConfigterminate();
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int MiniXftConfig_amount_of_matched_text = (int) (MiniXftConfig_cp - MiniXftConfigtext_ptr) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *MiniXftConfig_cp = MiniXftConfig_hold_char;
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( MiniXftConfig_current_buffer->MiniXftConfig_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed MiniXftConfigin at a new source and called
+ * MiniXftConfiglex(). If so, then we have to assure
+ * consistency between MiniXftConfig_current_buffer and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ MiniXftConfig_n_chars = MiniXftConfig_current_buffer->MiniXftConfig_n_chars;
+ MiniXftConfig_current_buffer->MiniXftConfig_input_file = MiniXftConfigin;
+ MiniXftConfig_current_buffer->MiniXftConfig_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for MiniXftConfig_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since MiniXftConfig_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( MiniXftConfig_c_buf_p <= &MiniXftConfig_current_buffer->MiniXftConfig_ch_buf[MiniXftConfig_n_chars] )
+ { /* This was really a NUL. */
+ MiniXftConfig_state_type MiniXftConfig_next_state;
+
+ MiniXftConfig_c_buf_p = MiniXftConfigtext_ptr + MiniXftConfig_amount_of_matched_text;
+
+ MiniXftConfig_current_state = MiniXftConfig_get_previous_state();
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * MiniXftConfig_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ MiniXftConfig_next_state = MiniXftConfig_try_NUL_trans( MiniXftConfig_current_state );
+
+ MiniXftConfig_bp = MiniXftConfigtext_ptr + YY_MORE_ADJ;
+
+ if ( MiniXftConfig_next_state )
+ {
+ /* Consume the NUL. */
+ MiniXftConfig_cp = ++MiniXftConfig_c_buf_p;
+ MiniXftConfig_current_state = MiniXftConfig_next_state;
+ goto MiniXftConfig_match;
+ }
+
+ else
+ {
+ MiniXftConfig_cp = MiniXftConfig_c_buf_p;
+ goto MiniXftConfig_find_action;
+ }
+ }
+
+ else switch ( MiniXftConfig_get_next_buffer() )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ MiniXftConfig_did_buffer_switch_on_eof = 0;
+
+ if ( MiniXftConfigwrap() )
+ {
+ /* Note: because we've taken care in
+ * MiniXftConfig_get_next_buffer() to have set up
+ * MiniXftConfigtext, we can now set up
+ * MiniXftConfig_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ MiniXftConfig_c_buf_p = MiniXftConfigtext_ptr + YY_MORE_ADJ;
+
+ MiniXftConfig_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! MiniXftConfig_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ MiniXftConfig_c_buf_p =
+ MiniXftConfigtext_ptr + MiniXftConfig_amount_of_matched_text;
+
+ MiniXftConfig_current_state = MiniXftConfig_get_previous_state();
+
+ MiniXftConfig_cp = MiniXftConfig_c_buf_p;
+ MiniXftConfig_bp = MiniXftConfigtext_ptr + YY_MORE_ADJ;
+ goto MiniXftConfig_match;
+
+ case EOB_ACT_LAST_MATCH:
+ MiniXftConfig_c_buf_p =
+ &MiniXftConfig_current_buffer->MiniXftConfig_ch_buf[MiniXftConfig_n_chars];
+
+ MiniXftConfig_current_state = MiniXftConfig_get_previous_state();
+
+ MiniXftConfig_cp = MiniXftConfig_c_buf_p;
+ MiniXftConfig_bp = MiniXftConfigtext_ptr + YY_MORE_ADJ;
+ goto MiniXftConfig_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+ } /* end of MiniXftConfiglex */
+
+
+/* MiniXftConfig_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+
+static int MiniXftConfig_get_next_buffer()
+ {
+ register char *dest = MiniXftConfig_current_buffer->MiniXftConfig_ch_buf;
+ register char *source = MiniXftConfigtext_ptr;
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( MiniXftConfig_c_buf_p > &MiniXftConfig_current_buffer->MiniXftConfig_ch_buf[MiniXftConfig_n_chars + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( MiniXftConfig_current_buffer->MiniXftConfig_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( MiniXftConfig_c_buf_p - MiniXftConfigtext_ptr - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) (MiniXftConfig_c_buf_p - MiniXftConfigtext_ptr) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( MiniXftConfig_current_buffer->MiniXftConfig_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ MiniXftConfig_current_buffer->MiniXftConfig_n_chars = MiniXftConfig_n_chars = 0;
+
+ else
+ {
+ int num_to_read =
+ MiniXftConfig_current_buffer->MiniXftConfig_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+#ifdef YY_USES_REJECT
+ YY_FATAL_ERROR(
+"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
+#else
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = MiniXftConfig_current_buffer;
+
+ int MiniXftConfig_c_buf_p_offset =
+ (int) (MiniXftConfig_c_buf_p - b->MiniXftConfig_ch_buf);
+
+ if ( b->MiniXftConfig_is_our_buffer )
+ {
+ int new_size = b->MiniXftConfig_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->MiniXftConfig_buf_size += b->MiniXftConfig_buf_size / 8;
+ else
+ b->MiniXftConfig_buf_size *= 2;
+
+ b->MiniXftConfig_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ MiniXftConfig_flex_realloc( (void *) b->MiniXftConfig_ch_buf,
+ b->MiniXftConfig_buf_size + 2 );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->MiniXftConfig_ch_buf = 0;
+
+ if ( ! b->MiniXftConfig_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ MiniXftConfig_c_buf_p = &b->MiniXftConfig_ch_buf[MiniXftConfig_c_buf_p_offset];
+
+ num_to_read = MiniXftConfig_current_buffer->MiniXftConfig_buf_size -
+ number_to_move - 1;
+#endif
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&MiniXftConfig_current_buffer->MiniXftConfig_ch_buf[number_to_move]),
+ MiniXftConfig_n_chars, num_to_read );
+
+ MiniXftConfig_current_buffer->MiniXftConfig_n_chars = MiniXftConfig_n_chars;
+ }
+
+ if ( MiniXftConfig_n_chars == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ MiniXftConfigrestart( MiniXftConfigin );
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ MiniXftConfig_current_buffer->MiniXftConfig_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ MiniXftConfig_n_chars += number_to_move;
+ MiniXftConfig_current_buffer->MiniXftConfig_ch_buf[MiniXftConfig_n_chars] = YY_END_OF_BUFFER_CHAR;
+ MiniXftConfig_current_buffer->MiniXftConfig_ch_buf[MiniXftConfig_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+ MiniXftConfigtext_ptr = &MiniXftConfig_current_buffer->MiniXftConfig_ch_buf[0];
+
+ return ret_val;
+ }
+
+
+/* MiniXftConfig_get_previous_state - get the state just before the EOB char was reached */
+
+static MiniXftConfig_state_type MiniXftConfig_get_previous_state()
+ {
+ register MiniXftConfig_state_type MiniXftConfig_current_state;
+ register char *MiniXftConfig_cp;
+
+ MiniXftConfig_current_state = MiniXftConfig_start;
+ MiniXftConfig_current_state += YY_AT_BOL();
+
+ for ( MiniXftConfig_cp = MiniXftConfigtext_ptr + YY_MORE_ADJ; MiniXftConfig_cp < MiniXftConfig_c_buf_p; ++MiniXftConfig_cp )
+ {
+ register YY_CHAR MiniXftConfig_c = (*MiniXftConfig_cp ? MiniXftConfig_ec[YY_SC_TO_UI(*MiniXftConfig_cp)] : 1);
+ if ( MiniXftConfig_accept[MiniXftConfig_current_state] )
+ {
+ MiniXftConfig_last_accepting_state = MiniXftConfig_current_state;
+ MiniXftConfig_last_accepting_cpos = MiniXftConfig_cp;
+ }
+ while ( MiniXftConfig_chk[MiniXftConfig_base[MiniXftConfig_current_state] + MiniXftConfig_c] != MiniXftConfig_current_state )
+ {
+ MiniXftConfig_current_state = (int) MiniXftConfig_def[MiniXftConfig_current_state];
+ if ( MiniXftConfig_current_state >= 94 )
+ MiniXftConfig_c = MiniXftConfig_meta[(unsigned int) MiniXftConfig_c];
+ }
+ MiniXftConfig_current_state = MiniXftConfig_nxt[MiniXftConfig_base[MiniXftConfig_current_state] + (unsigned int) MiniXftConfig_c];
+ }
+
+ return MiniXftConfig_current_state;
+ }
+
+
+/* MiniXftConfig_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = MiniXftConfig_try_NUL_trans( current_state );
+ */
+
+#ifdef YY_USE_PROTOS
+static MiniXftConfig_state_type MiniXftConfig_try_NUL_trans( MiniXftConfig_state_type MiniXftConfig_current_state )
+#else
+static MiniXftConfig_state_type MiniXftConfig_try_NUL_trans( MiniXftConfig_current_state )
+MiniXftConfig_state_type MiniXftConfig_current_state;
+#endif
+ {
+ register int MiniXftConfig_is_jam;
+ register char *MiniXftConfig_cp = MiniXftConfig_c_buf_p;
+
+ register YY_CHAR MiniXftConfig_c = 1;
+ if ( MiniXftConfig_accept[MiniXftConfig_current_state] )
+ {
+ MiniXftConfig_last_accepting_state = MiniXftConfig_current_state;
+ MiniXftConfig_last_accepting_cpos = MiniXftConfig_cp;
+ }
+ while ( MiniXftConfig_chk[MiniXftConfig_base[MiniXftConfig_current_state] + MiniXftConfig_c] != MiniXftConfig_current_state )
+ {
+ MiniXftConfig_current_state = (int) MiniXftConfig_def[MiniXftConfig_current_state];
+ if ( MiniXftConfig_current_state >= 94 )
+ MiniXftConfig_c = MiniXftConfig_meta[(unsigned int) MiniXftConfig_c];
+ }
+ MiniXftConfig_current_state = MiniXftConfig_nxt[MiniXftConfig_base[MiniXftConfig_current_state] + (unsigned int) MiniXftConfig_c];
+ MiniXftConfig_is_jam = (MiniXftConfig_current_state == 93);
+
+ return MiniXftConfig_is_jam ? 0 : MiniXftConfig_current_state;
+ }
+
+
+#ifndef YY_NO_UNPUT
+#ifdef YY_USE_PROTOS
+static void MiniXftConfigunput( int c, register char *MiniXftConfig_bp )
+#else
+static void MiniXftConfigunput( c, MiniXftConfig_bp )
+int c;
+register char *MiniXftConfig_bp;
+#endif
+ {
+ register char *MiniXftConfig_cp = MiniXftConfig_c_buf_p;
+
+ /* undo effects of setting up MiniXftConfigtext */
+ *MiniXftConfig_cp = MiniXftConfig_hold_char;
+
+ if ( MiniXftConfig_cp < MiniXftConfig_current_buffer->MiniXftConfig_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ register int number_to_move = MiniXftConfig_n_chars + 2;
+ register char *dest = &MiniXftConfig_current_buffer->MiniXftConfig_ch_buf[
+ MiniXftConfig_current_buffer->MiniXftConfig_buf_size + 2];
+ register char *source =
+ &MiniXftConfig_current_buffer->MiniXftConfig_ch_buf[number_to_move];
+
+ while ( source > MiniXftConfig_current_buffer->MiniXftConfig_ch_buf )
+ *--dest = *--source;
+
+ MiniXftConfig_cp += (int) (dest - source);
+ MiniXftConfig_bp += (int) (dest - source);
+ MiniXftConfig_current_buffer->MiniXftConfig_n_chars =
+ MiniXftConfig_n_chars = MiniXftConfig_current_buffer->MiniXftConfig_buf_size;
+
+ if ( MiniXftConfig_cp < MiniXftConfig_current_buffer->MiniXftConfig_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--MiniXftConfig_cp = (char) c;
+
+
+ MiniXftConfigtext_ptr = MiniXftConfig_bp;
+ MiniXftConfig_hold_char = *MiniXftConfig_cp;
+ MiniXftConfig_c_buf_p = MiniXftConfig_cp;
+ }
+#endif /* ifndef YY_NO_UNPUT */
+
+
+#ifdef __cplusplus
+static int MiniXftConfiginput()
+#else
+static int input()
+#endif
+ {
+ int c;
+
+ *MiniXftConfig_c_buf_p = MiniXftConfig_hold_char;
+
+ if ( *MiniXftConfig_c_buf_p == YY_END_OF_BUFFER_CHAR )
+ {
+ /* MiniXftConfig_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( MiniXftConfig_c_buf_p < &MiniXftConfig_current_buffer->MiniXftConfig_ch_buf[MiniXftConfig_n_chars] )
+ /* This was really a NUL. */
+ *MiniXftConfig_c_buf_p = '\0';
+
+ else
+ { /* need more input */
+ int offset = MiniXftConfig_c_buf_p - MiniXftConfigtext_ptr;
+ ++MiniXftConfig_c_buf_p;
+
+ switch ( MiniXftConfig_get_next_buffer() )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because MiniXftConfig_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ MiniXftConfigrestart( MiniXftConfigin );
+
+ /* fall through */
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( MiniXftConfigwrap() )
+ return EOF;
+
+ if ( ! MiniXftConfig_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return MiniXftConfiginput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ MiniXftConfig_c_buf_p = MiniXftConfigtext_ptr + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) MiniXftConfig_c_buf_p; /* cast for 8-bit char's */
+ *MiniXftConfig_c_buf_p = '\0'; /* preserve MiniXftConfigtext */
+ MiniXftConfig_hold_char = *++MiniXftConfig_c_buf_p;
+
+ MiniXftConfig_current_buffer->MiniXftConfig_at_bol = (c == '\n');
+
+ return c;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void MiniXftConfigrestart( FILE *input_file )
+#else
+void MiniXftConfigrestart( input_file )
+FILE *input_file;
+#endif
+ {
+ if ( ! MiniXftConfig_current_buffer )
+ MiniXftConfig_current_buffer = MiniXftConfig_create_buffer( MiniXftConfigin, YY_BUF_SIZE );
+
+ MiniXftConfig_init_buffer( MiniXftConfig_current_buffer, input_file );
+ MiniXftConfig_load_buffer_state();
+ }
+
+
+#ifdef YY_USE_PROTOS
+void MiniXftConfig_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+#else
+void MiniXftConfig_switch_to_buffer( new_buffer )
+YY_BUFFER_STATE new_buffer;
+#endif
+ {
+ if ( MiniXftConfig_current_buffer == new_buffer )
+ return;
+
+ if ( MiniXftConfig_current_buffer )
+ {
+ /* Flush out information for old buffer. */
+ *MiniXftConfig_c_buf_p = MiniXftConfig_hold_char;
+ MiniXftConfig_current_buffer->MiniXftConfig_buf_pos = MiniXftConfig_c_buf_p;
+ MiniXftConfig_current_buffer->MiniXftConfig_n_chars = MiniXftConfig_n_chars;
+ }
+
+ MiniXftConfig_current_buffer = new_buffer;
+ MiniXftConfig_load_buffer_state();
+
+ /* We don't actually know whether we did this switch during
+ * EOF (MiniXftConfigwrap()) processing, but the only time this flag
+ * is looked at is after MiniXftConfigwrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ MiniXftConfig_did_buffer_switch_on_eof = 1;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void MiniXftConfig_load_buffer_state( void )
+#else
+void MiniXftConfig_load_buffer_state()
+#endif
+ {
+ MiniXftConfig_n_chars = MiniXftConfig_current_buffer->MiniXftConfig_n_chars;
+ MiniXftConfigtext_ptr = MiniXftConfig_c_buf_p = MiniXftConfig_current_buffer->MiniXftConfig_buf_pos;
+ MiniXftConfigin = MiniXftConfig_current_buffer->MiniXftConfig_input_file;
+ MiniXftConfig_hold_char = *MiniXftConfig_c_buf_p;
+ }
+
+
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE MiniXftConfig_create_buffer( FILE *file, int size )
+#else
+YY_BUFFER_STATE MiniXftConfig_create_buffer( file, size )
+FILE *file;
+int size;
+#endif
+ {
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) MiniXftConfig_flex_alloc( sizeof( struct MiniXftConfig_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in MiniXftConfig_create_buffer()" );
+
+ b->MiniXftConfig_buf_size = size;
+
+ /* MiniXftConfig_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->MiniXftConfig_ch_buf = (char *) MiniXftConfig_flex_alloc( b->MiniXftConfig_buf_size + 2 );
+ if ( ! b->MiniXftConfig_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in MiniXftConfig_create_buffer()" );
+
+ b->MiniXftConfig_is_our_buffer = 1;
+
+ MiniXftConfig_init_buffer( b, file );
+
+ return b;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void MiniXftConfig_delete_buffer( YY_BUFFER_STATE b )
+#else
+void MiniXftConfig_delete_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+ {
+ if ( ! b )
+ return;
+
+ if ( b == MiniXftConfig_current_buffer )
+ MiniXftConfig_current_buffer = (YY_BUFFER_STATE) 0;
+
+ if ( b->MiniXftConfig_is_our_buffer )
+ MiniXftConfig_flex_free( (void *) b->MiniXftConfig_ch_buf );
+
+ MiniXftConfig_flex_free( (void *) b );
+ }
+
+
+
+#ifdef YY_USE_PROTOS
+void MiniXftConfig_init_buffer( YY_BUFFER_STATE b, FILE *file )
+#else
+void MiniXftConfig_init_buffer( b, file )
+YY_BUFFER_STATE b;
+FILE *file;
+#endif
+
+
+ {
+ MiniXftConfig_flush_buffer( b );
+
+ b->MiniXftConfig_input_file = file;
+ b->MiniXftConfig_fill_buffer = 1;
+
+#if YY_ALWAYS_INTERACTIVE
+ b->MiniXftConfig_is_interactive = 1;
+#else
+#if YY_NEVER_INTERACTIVE
+ b->MiniXftConfig_is_interactive = 0;
+#else
+ b->MiniXftConfig_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+#endif
+#endif
+ }
+
+
+#ifdef YY_USE_PROTOS
+void MiniXftConfig_flush_buffer( YY_BUFFER_STATE b )
+#else
+void MiniXftConfig_flush_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+
+ {
+ if ( ! b )
+ return;
+
+ b->MiniXftConfig_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->MiniXftConfig_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->MiniXftConfig_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->MiniXftConfig_buf_pos = &b->MiniXftConfig_ch_buf[0];
+
+ b->MiniXftConfig_at_bol = 1;
+ b->MiniXftConfig_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == MiniXftConfig_current_buffer )
+ MiniXftConfig_load_buffer_state();
+ }
+
+
+#ifndef YY_NO_SCAN_BUFFER
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE MiniXftConfig_scan_buffer( char *base, MiniXftConfig_size_t size )
+#else
+YY_BUFFER_STATE MiniXftConfig_scan_buffer( base, size )
+char *base;
+MiniXftConfig_size_t size;
+#endif
+ {
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) MiniXftConfig_flex_alloc( sizeof( struct MiniXftConfig_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in MiniXftConfig_scan_buffer()" );
+
+ b->MiniXftConfig_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->MiniXftConfig_buf_pos = b->MiniXftConfig_ch_buf = base;
+ b->MiniXftConfig_is_our_buffer = 0;
+ b->MiniXftConfig_input_file = 0;
+ b->MiniXftConfig_n_chars = b->MiniXftConfig_buf_size;
+ b->MiniXftConfig_is_interactive = 0;
+ b->MiniXftConfig_at_bol = 1;
+ b->MiniXftConfig_fill_buffer = 0;
+ b->MiniXftConfig_buffer_status = YY_BUFFER_NEW;
+
+ MiniXftConfig_switch_to_buffer( b );
+
+ return b;
+ }
+#endif
+
+
+#ifndef YY_NO_SCAN_STRING
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE MiniXftConfig_scan_string( MiniXftConfigconst char *MiniXftConfig_str )
+#else
+YY_BUFFER_STATE MiniXftConfig_scan_string( MiniXftConfig_str )
+MiniXftConfigconst char *MiniXftConfig_str;
+#endif
+ {
+ int len;
+ for ( len = 0; MiniXftConfig_str[len]; ++len )
+ ;
+
+ return MiniXftConfig_scan_bytes( MiniXftConfig_str, len );
+ }
+#endif
+
+
+#ifndef YY_NO_SCAN_BYTES
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE MiniXftConfig_scan_bytes( MiniXftConfigconst char *bytes, int len )
+#else
+YY_BUFFER_STATE MiniXftConfig_scan_bytes( bytes, len )
+MiniXftConfigconst char *bytes;
+int len;
+#endif
+ {
+ YY_BUFFER_STATE b;
+ char *buf;
+ MiniXftConfig_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = len + 2;
+ buf = (char *) MiniXftConfig_flex_alloc( n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in MiniXftConfig_scan_bytes()" );
+
+ for ( i = 0; i < len; ++i )
+ buf[i] = bytes[i];
+
+ buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = MiniXftConfig_scan_buffer( buf, n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in MiniXftConfig_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->MiniXftConfig_is_our_buffer = 1;
+
+ return b;
+ }
+#endif
+
+
+#ifndef YY_NO_PUSH_STATE
+#ifdef YY_USE_PROTOS
+static void MiniXftConfig_push_state( int new_state )
+#else
+static void MiniXftConfig_push_state( new_state )
+int new_state;
+#endif
+ {
+ if ( MiniXftConfig_start_stack_ptr >= MiniXftConfig_start_stack_depth )
+ {
+ MiniXftConfig_size_t new_size;
+
+ MiniXftConfig_start_stack_depth += YY_START_STACK_INCR;
+ new_size = MiniXftConfig_start_stack_depth * sizeof( int );
+
+ if ( ! MiniXftConfig_start_stack )
+ MiniXftConfig_start_stack = (int *) MiniXftConfig_flex_alloc( new_size );
+
+ else
+ MiniXftConfig_start_stack = (int *) MiniXftConfig_flex_realloc(
+ (void *) MiniXftConfig_start_stack, new_size );
+
+ if ( ! MiniXftConfig_start_stack )
+ YY_FATAL_ERROR(
+ "out of memory expanding start-condition stack" );
+ }
+
+ MiniXftConfig_start_stack[MiniXftConfig_start_stack_ptr++] = YY_START;
+
+ BEGIN(new_state);
+ }
+#endif
+
+
+#ifndef YY_NO_POP_STATE
+static void MiniXftConfig_pop_state()
+ {
+ if ( --MiniXftConfig_start_stack_ptr < 0 )
+ YY_FATAL_ERROR( "start-condition stack underflow" );
+
+ BEGIN(MiniXftConfig_start_stack[MiniXftConfig_start_stack_ptr]);
+ }
+#endif
+
+
+#ifndef YY_NO_TOP_STATE
+static int MiniXftConfig_top_state()
+ {
+ return MiniXftConfig_start_stack[MiniXftConfig_start_stack_ptr - 1];
+ }
+#endif
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+#ifdef YY_USE_PROTOS
+static void MiniXftConfig_fatal_error( MiniXftConfigconst char msg[] )
+#else
+static void MiniXftConfig_fatal_error( msg )
+char msg[];
+#endif
+ {
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+ }
+
+
+
+/* Redefine MiniXftConfigless() so it works in section 3 code. */
+
+#undef MiniXftConfigless
+#define MiniXftConfigless(n) \
+ do \
+ { \
+ /* Undo effects of setting up MiniXftConfigtext. */ \
+ MiniXftConfigtext[MiniXftConfigleng] = MiniXftConfig_hold_char; \
+ MiniXftConfig_c_buf_p = MiniXftConfigtext + n; \
+ MiniXftConfig_hold_char = *MiniXftConfig_c_buf_p; \
+ *MiniXftConfig_c_buf_p = '\0'; \
+ MiniXftConfigleng = n; \
+ } \
+ while ( 0 )
+
+
+/* Internal utility routines. */
+
+#ifndef MiniXftConfigtext_ptr
+#ifdef YY_USE_PROTOS
+static void MiniXftConfig_flex_strncpy( char *s1, MiniXftConfigconst char *s2, int n )
+#else
+static void MiniXftConfig_flex_strncpy( s1, s2, n )
+char *s1;
+MiniXftConfigconst char *s2;
+int n;
+#endif
+ {
+ register int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+ }
+#endif
+
+#ifdef YY_NEED_STRLEN
+#ifdef YY_USE_PROTOS
+static int MiniXftConfig_flex_strlen( MiniXftConfigconst char *s )
+#else
+static int MiniXftConfig_flex_strlen( s )
+MiniXftConfigconst char *s;
+#endif
+ {
+ register int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+ }
+#endif
+
+
+#ifdef YY_USE_PROTOS
+static void *MiniXftConfig_flex_alloc( MiniXftConfig_size_t size )
+#else
+static void *MiniXftConfig_flex_alloc( size )
+MiniXftConfig_size_t size;
+#endif
+ {
+ return (void *) malloc( size );
+ }
+
+#ifdef YY_USE_PROTOS
+static void *MiniXftConfig_flex_realloc( void *ptr, MiniXftConfig_size_t size )
+#else
+static void *MiniXftConfig_flex_realloc( ptr, size )
+void *ptr;
+MiniXftConfig_size_t size;
+#endif
+ {
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+ }
+
+#ifdef YY_USE_PROTOS
+static void MiniXftConfig_flex_free( void *ptr )
+#else
+static void MiniXftConfig_flex_free( ptr )
+void *ptr;
+#endif
+ {
+ free( ptr );
+ }
+
+#if YY_MAIN
+int main()
+ {
+ MiniXftConfiglex();
+ return 0;
+ }
+#endif
+#line 154 "minixftlex.l"
+
+static void
+_MiniXftConfigSkipComment (void)
+{
+ int c;
+
+ c = input();
+ for (;;) {
+ while (c != EOF && c != '*')
+ c = input();
+ if (c == EOF)
+ return;
+ c = input();
+ if (c == EOF || c == '/')
+ return;
+ }
+}
+
+static void
+_MiniXftConfigSkipLine (void)
+{
+ int c;
+
+ do {
+ c = input();
+ } while (c != EOF && c != '\n');
+ if (c == '\n') unput('\n');
+}
+
+Bool
+MiniXftConfigLexFile(char *s)
+{
+ FILE *f;
+
+ f = fopen (s, "r");
+ if (f == 0)
+ {
+ fprintf (stderr, "cannot open file \"%s\"\n", s);
+ return False;
+ }
+ ++MiniXftConfigFiledeep;
+ MiniXftConfigInput = f;
+ MiniXftConfigFile = s;
+ return True;
+}
+
+Bool
+MiniXftConfigPushInput (char *s, Bool complain)
+{
+ FILE *f;
+ char *t;
+ char *h;
+
+ if (MiniXftConfigInpt == MiniXftConfigInStack)
+ {
+ (void) fprintf (stderr, "files nested too deeply\n");
+ return False;
+ }
+ t = s;
+ if (*s == '~')
+ {
+ h = getenv ("HOME");
+ if (h)
+ {
+ t = (char *) malloc (strlen (h) + strlen (s));
+ if (t)
+ {
+ strcpy (t, h);
+ strcat (t, s+1);
+ }
+ else
+ t = s;
+ }
+ }
+ f = fopen (t, "r");
+ if (t != s)
+ free (t);
+ if (f == 0)
+ {
+ if (complain)
+ (void) fprintf (stderr, "cannot open file %s\n", s);
+ return False;
+ }
+ ++MiniXftConfigFiledeep;
+ *--MiniXftConfigInpt = MiniXftConfigInput;
+ *--MiniXftConfigLinenopt = MiniXftConfigLineno;
+ *--MiniXftConfigFileNamePt = MiniXftConfigFile;
+ MiniXftConfigInput = f;
+ MiniXftConfigLineno = 1;
+ MiniXftConfigFile = _MiniXftSaveString (s);
+ return True;
+}
+
+static int
+_MiniXftConfigPopInput (void)
+{
+ int c;
+
+ for (;;)
+ {
+ c = getc (MiniXftConfigInput);
+ if (c >= 0)
+ return c;
+ fclose (MiniXftConfigInput);
+ MiniXftConfigInput = 0;
+ if (MiniXftConfigInpt == MiniXftConfigInStack + XFT_CONFIG_IN_DEEP)
+ return EOF;
+ MiniXftConfigInput = *MiniXftConfigInpt++;
+ MiniXftConfigLineno = *MiniXftConfigLinenopt++;
+ free (MiniXftConfigFile);
+ MiniXftConfigFile = *MiniXftConfigFileNamePt++;
+ --MiniXftConfigFiledeep;
+ }
+}
+
+void
+MiniXftConfigLexDone (void)
+{
+#ifdef FLEX_SCANNER
+ MiniXftConfig_delete_buffer (MiniXftConfig_current_buffer);
+#endif
+}
diff --git a/pango/mini-xft/minixftlex.l b/pango/mini-xft/minixftlex.l
new file mode 100644
index 00000000..9ddb7920
--- /dev/null
+++ b/pango/mini-xft/minixftlex.l
@@ -0,0 +1,275 @@
+%{
+/*
+ * $XFree86: xc/lib/MiniXft/xftlex.l,v 1.7 2001/05/18 16:03:06 tsi Exp $
+ *
+ * Copyright (c) 2000 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <string.h>
+#include "minixftint.h"
+
+#include "minixftgram.h"
+
+int MiniXftConfigLineno;
+
+static void _MiniXftConfigSkipComment (void);
+
+static void _MiniXftConfigSkipLine (void);
+
+static int _MiniXftConfigPopInput (void);
+
+
+#define XFT_CONFIG_IN_DEEP 20
+FILE *MiniXftConfigInStack[XFT_CONFIG_IN_DEEP];
+FILE **MiniXftConfigInpt = MiniXftConfigInStack + XFT_CONFIG_IN_DEEP;
+FILE *MiniXftConfigInput;
+int MiniXftConfigLinenos[XFT_CONFIG_IN_DEEP];
+int *MiniXftConfigLinenopt = MiniXftConfigLinenos + XFT_CONFIG_IN_DEEP;
+char *MiniXftConfigFile = "";
+char *MiniXftConfigFileNames[XFT_CONFIG_IN_DEEP];
+char **MiniXftConfigFileNamePt = MiniXftConfigFileNames + XFT_CONFIG_IN_DEEP;
+int MiniXftConfigFiledeep = 0;
+
+#undef YY_INPUT
+
+#define YY_INPUT(buf,result,max_size) \
+{ \
+ int c; \
+ result = 0; \
+ while (result < max_size) { \
+ c = getc (MiniXftConfigInput); \
+ if (c < 0) { \
+ c = _MiniXftConfigPopInput (); \
+ if (c < 0) \
+ break; \
+ } \
+ buf[result++] = c; \
+ if (c == '\n') \
+ { \
+ MiniXftConfigLineno++; \
+ break; \
+ } \
+ } \
+}
+
+#ifndef FLEX_SCANNER
+#undef input
+#undef unput
+static int input (void)
+{
+ char buf[1];
+ static int r = EOF;
+
+ if (r == 0)
+ return 0;
+ YY_INPUT(buf, r, 1);
+ if (r == 0)
+ return EOF;
+ return buf[0];
+}
+
+static void unput (char c)
+{
+ if (!c || c == EOF)
+ return;
+ if (c == '\n')
+ MiniXftConfigLineno--;
+ ungetc (c, MiniXftConfigInput);
+}
+#endif
+
+%}
+%%
+"/\052" _MiniXftConfigSkipComment();
+^# _MiniXftConfigSkipLine();
+dir return DIR;
+cache return CACHE;
+include return INCLUDE;
+includeif return INCLUDEIF;
+match return MATCH;
+edit return EDIT;
+true return TOK_TRUE;
+false return TOK_FALSE;
+nil return TOK_NIL;
+any return ANY;
+all return ALL;
+"=" return EQUAL;
+":" return COLON;
+";" return SEMI;
+"+" return PLUS;
+"-" return MINUS;
+"*" return TIMES;
+"/" return DIVIDE;
+"!" return NOT;
+"&&" return ANDAND;
+"||" return OROR;
+"<" return LESS;
+"<=" return LESSEQ;
+"==" return EQEQ;
+">=" return MOREEQ;
+">" return MORE;
+"!=" return NOTEQ;
+"?" return QUEST;
+"[" return OS;
+"]" return CS;
+\"([^\n\"]|\\\")*\" {
+ yytext[yyleng - 1] = '\0';
+ yylval.sval = yytext+1;
+ return STRING;
+ }
+[0-9]+ {
+ yylval.ival = strtol (yytext, 0, 10);
+ return INTEGER;
+ }
+(([0-9]+((\.[0-9]*(\{[0-9]+\})?)?))|(\.[0-9]+)|(\.[0-9]*\{[0-9]+\}))(([Ee][-+]?[0-9]+)?) {
+ yylval.dval = strtod (yytext, 0);
+ return DOUBLE;
+ }
+[a-zA-Z][0-9a-zA-Z_]* {
+ if (MiniXftNameConstant (yytext, &yylval.ival))
+ return INTEGER;
+ yylval.sval = yytext;
+ return NAME;
+ }
+. ;
+"\n" ;
+%%
+static void
+_MiniXftConfigSkipComment (void)
+{
+ int c;
+
+ c = input();
+ for (;;) {
+ while (c != EOF && c != '*')
+ c = input();
+ if (c == EOF)
+ return;
+ c = input();
+ if (c == EOF || c == '/')
+ return;
+ }
+}
+
+static void
+_MiniXftConfigSkipLine (void)
+{
+ int c;
+
+ do {
+ c = input();
+ } while (c != EOF && c != '\n');
+ if (c == '\n') unput('\n');
+}
+
+Bool
+MiniXftConfigLexFile(char *s)
+{
+ FILE *f;
+
+ f = fopen (s, "r");
+ if (f == 0)
+ {
+ fprintf (stderr, "cannot open file \"%s\"\n", s);
+ return False;
+ }
+ ++MiniXftConfigFiledeep;
+ MiniXftConfigInput = f;
+ MiniXftConfigFile = s;
+ return True;
+}
+
+Bool
+MiniXftConfigPushInput (char *s, Bool complain)
+{
+ FILE *f;
+ char *t;
+ char *h;
+
+ if (MiniXftConfigInpt == MiniXftConfigInStack)
+ {
+ (void) fprintf (stderr, "files nested too deeply\n");
+ return False;
+ }
+ t = s;
+ if (*s == '~')
+ {
+ h = getenv ("HOME");
+ if (h)
+ {
+ t = (char *) malloc (strlen (h) + strlen (s));
+ if (t)
+ {
+ strcpy (t, h);
+ strcat (t, s+1);
+ }
+ else
+ t = s;
+ }
+ }
+ f = fopen (t, "r");
+ if (t != s)
+ free (t);
+ if (f == 0)
+ {
+ if (complain)
+ (void) fprintf (stderr, "cannot open file %s\n", s);
+ return False;
+ }
+ ++MiniXftConfigFiledeep;
+ *--MiniXftConfigInpt = MiniXftConfigInput;
+ *--MiniXftConfigLinenopt = MiniXftConfigLineno;
+ *--MiniXftConfigFileNamePt = MiniXftConfigFile;
+ MiniXftConfigInput = f;
+ MiniXftConfigLineno = 1;
+ MiniXftConfigFile = _MiniXftSaveString (s);
+ return True;
+}
+
+static int
+_MiniXftConfigPopInput (void)
+{
+ int c;
+
+ for (;;)
+ {
+ c = getc (MiniXftConfigInput);
+ if (c >= 0)
+ return c;
+ fclose (MiniXftConfigInput);
+ MiniXftConfigInput = 0;
+ if (MiniXftConfigInpt == MiniXftConfigInStack + XFT_CONFIG_IN_DEEP)
+ return EOF;
+ MiniXftConfigInput = *MiniXftConfigInpt++;
+ MiniXftConfigLineno = *MiniXftConfigLinenopt++;
+ free (MiniXftConfigFile);
+ MiniXftConfigFile = *MiniXftConfigFileNamePt++;
+ --MiniXftConfigFiledeep;
+ }
+}
+
+void
+MiniXftConfigLexDone (void)
+{
+#ifdef FLEX_SCANNER
+ MiniXftConfig_delete_buffer (MiniXftConfig_current_buffer);
+#endif
+}
diff --git a/pango/mini-xft/minixftlist.c b/pango/mini-xft/minixftlist.c
new file mode 100644
index 00000000..230ab858
--- /dev/null
+++ b/pango/mini-xft/minixftlist.c
@@ -0,0 +1,303 @@
+/*
+ * $XFree86: xc/lib/MiniXft/xftlist.c,v 1.2 2000/12/07 23:57:28 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include "minixftint.h"
+
+MiniXftObjectSet *
+MiniXftObjectSetCreate (void)
+{
+ MiniXftObjectSet *os;
+
+ os = (MiniXftObjectSet *) malloc (sizeof (MiniXftObjectSet));
+ if (!os)
+ return 0;
+ os->nobject = 0;
+ os->sobject = 0;
+ os->objects = 0;
+ return os;
+}
+
+Bool
+MiniXftObjectSetAdd (MiniXftObjectSet *os, const char *object)
+{
+ int s;
+ const char **objects;
+
+ if (os->nobject == os->sobject)
+ {
+ s = os->sobject + 4;
+ if (os->objects)
+ objects = (const char **) realloc ((void *) os->objects,
+ s * sizeof (const char **));
+ else
+ objects = (const char **) malloc (s * sizeof (const char **));
+ if (!objects)
+ return False;
+ os->objects = objects;
+ os->sobject = s;
+ }
+ os->objects[os->nobject++] = object;
+ return True;
+}
+
+void
+MiniXftObjectSetDestroy (MiniXftObjectSet *os)
+{
+ if (os->objects)
+ free ((void *) os->objects);
+ free (os);
+}
+
+#define _MiniXftObjectSetVapBuild(__ret__, __first__, __va__) \
+{ \
+ MiniXftObjectSet *__os__; \
+ const char *__ob__; \
+ \
+ __ret__ = 0; \
+ __os__ = MiniXftObjectSetCreate (); \
+ if (!__os__) \
+ goto _MiniXftObjectSetVapBuild_bail0; \
+ __ob__ = __first__; \
+ while (__ob__) \
+ { \
+ if (!MiniXftObjectSetAdd (__os__, __ob__)) \
+ goto _MiniXftObjectSetVapBuild_bail1; \
+ __ob__ = va_arg (__va__, const char *); \
+ } \
+ __ret__ = __os__; \
+ \
+_MiniXftObjectSetVapBuild_bail1: \
+ if (!__ret__ && __os__) \
+ MiniXftObjectSetDestroy (__os__); \
+_MiniXftObjectSetVapBuild_bail0: \
+ ; \
+}
+
+MiniXftObjectSet *
+MiniXftObjectSetVaBuild (const char *first, va_list va)
+{
+ MiniXftObjectSet *ret;
+
+ _MiniXftObjectSetVapBuild (ret, first, va);
+ return ret;
+}
+
+MiniXftObjectSet *
+MiniXftObjectSetBuild (const char *first, ...)
+{
+ va_list va;
+ MiniXftObjectSet *os;
+
+ va_start (va, first);
+ _MiniXftObjectSetVapBuild (os, first, va);
+ va_end (va);
+ return os;
+}
+
+Bool
+MiniXftListValueCompare (MiniXftValue v1,
+ MiniXftValue v2)
+{
+ return _MiniXftConfigCompareValue (v1, MiniXftOpEqual, v2);
+}
+
+Bool
+MiniXftListValueListCompare (MiniXftValueList *v1orig,
+ MiniXftValueList *v2orig,
+ MiniXftQual qual)
+{
+ MiniXftValueList *v1, *v2;
+
+ for (v1 = v1orig; v1; v1 = v1->next)
+ {
+ for (v2 = v2orig; v2; v2 = v2->next)
+ {
+ if (_MiniXftConfigCompareValue (v1->value, MiniXftOpEqual, v2->value))
+ {
+ if (qual == MiniXftQualAny)
+ return True;
+ else
+ break;
+ }
+ }
+ if (qual == MiniXftQualAll)
+ {
+ if (!v2)
+ return False;
+ }
+ }
+ if (qual == MiniXftQualAll)
+ return True;
+ else
+ return False;
+}
+
+/*
+ * True iff all objects in "p" match "font"
+ */
+Bool
+MiniXftListMatch (MiniXftPattern *p,
+ MiniXftPattern *font,
+ MiniXftQual qual)
+{
+ int i;
+ MiniXftPatternElt *e;
+
+ for (i = 0; i < p->num; i++)
+ {
+ e = MiniXftPatternFind (font, p->elts[i].object, False);
+ if (!e)
+ {
+ if (qual == MiniXftQualAll)
+ continue;
+ else
+ return False;
+ }
+ if (!MiniXftListValueListCompare (p->elts[i].values, e->values, qual))
+ return False;
+ }
+ return True;
+}
+
+Bool
+MiniXftListAppend (MiniXftFontSet *s,
+ MiniXftPattern *font,
+ MiniXftObjectSet *os)
+{
+ int f;
+ int o;
+ MiniXftPattern *l;
+ MiniXftPatternElt *e;
+ MiniXftValueList *v;
+
+ for (f = 0; f < s->nfont; f++)
+ {
+ l = s->fonts[f];
+ if (MiniXftListMatch (l, font, MiniXftQualAll))
+ return True;
+ }
+ l = MiniXftPatternCreate ();
+ if (!l)
+ goto bail0;
+ for (o = 0; o < os->nobject; o++)
+ {
+ e = MiniXftPatternFind (font, os->objects[o], False);
+ if (e)
+ {
+ for (v = e->values; v; v = v->next)
+ {
+ if (!MiniXftPatternAdd (l, os->objects[o], v->value, True))
+ goto bail1;
+ }
+ }
+ }
+ if (!MiniXftFontSetAdd (s, l))
+ goto bail1;
+ return True;
+bail1:
+ MiniXftPatternDestroy (l);
+bail0:
+ return False;
+}
+
+MiniXftFontSet *
+MiniXftListFontSets (MiniXftFontSet **sets,
+ int nsets,
+ MiniXftPattern *p,
+ MiniXftObjectSet *os)
+{
+ MiniXftFontSet *ret;
+ MiniXftFontSet *s;
+ int f;
+ int set;
+
+ ret = MiniXftFontSetCreate ();
+ if (!ret)
+ goto bail0;
+ for (set = 0; set < nsets; set++)
+ {
+ s = sets[set];
+ for (f = 0; f < s->nfont; f++)
+ {
+ if (MiniXftListMatch (p, s->fonts[f], MiniXftQualAny))
+ {
+ if (!MiniXftListAppend (ret, s->fonts[f], os))
+ goto bail1;
+ }
+ }
+ }
+ return ret;
+bail1:
+ MiniXftFontSetDestroy (ret);
+bail0:
+ return 0;
+}
+
+MiniXftFontSet *
+MiniXftListFontsPatternObjects (Display *dpy,
+ int screen,
+ MiniXftPattern *pattern,
+ MiniXftObjectSet *os)
+{
+ MiniXftFontSet *sets[2];
+ int nsets = 0;
+
+ if (!MiniXftInit (0))
+ return 0;
+
+ if (MiniXftInitFtLibrary ())
+ {
+ sets[nsets] = _MiniXftFontSet;
+ if (sets[nsets])
+ nsets++;
+ }
+ return MiniXftListFontSets (sets, nsets, pattern, os);
+}
+
+MiniXftFontSet *
+MiniXftListFonts (Display *dpy,
+ int screen,
+ ...)
+{
+ va_list va;
+ MiniXftFontSet *fs;
+ MiniXftObjectSet *os;
+ MiniXftPattern *pattern;
+ const char *first;
+
+ va_start (va, screen);
+
+ _MiniXftPatternVapBuild (pattern, 0, va);
+
+ first = va_arg (va, const char *);
+ _MiniXftObjectSetVapBuild (os, first, va);
+
+ va_end (va);
+
+ fs = MiniXftListFontsPatternObjects (dpy, screen, pattern, os);
+ MiniXftPatternDestroy (pattern);
+ MiniXftObjectSetDestroy (os);
+ return fs;
+}
diff --git a/pango/mini-xft/minixftmatch.c b/pango/mini-xft/minixftmatch.c
new file mode 100644
index 00000000..3b68f70b
--- /dev/null
+++ b/pango/mini-xft/minixftmatch.c
@@ -0,0 +1,330 @@
+/*
+ * $XFree86: xc/lib/MiniXft/xftmatch.c,v 1.6 2001/09/21 19:54:53 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <string.h>
+#include <ctype.h>
+#include "minixftint.h"
+#include <stdio.h>
+
+static double
+_MiniXftCompareInteger (char *object, MiniXftValue value1, MiniXftValue value2)
+{
+ int v;
+
+ if (value2.type != MiniXftTypeInteger || value1.type != MiniXftTypeInteger)
+ return -1.0;
+ v = value2.u.i - value1.u.i;
+ if (v < 0)
+ v = -v;
+ return (double) v;
+}
+
+static double
+_MiniXftCompareString (char *object, MiniXftValue value1, MiniXftValue value2)
+{
+ if (value2.type != MiniXftTypeString || value1.type != MiniXftTypeString)
+ return -1.0;
+ return (double) _MiniXftStrCmpIgnoreCase (value1.u.s, value2.u.s) != 0;
+}
+
+static double
+_MiniXftCompareBool (char *object, MiniXftValue value1, MiniXftValue value2)
+{
+ if (value2.type != MiniXftTypeBool || value1.type != MiniXftTypeBool)
+ return -1.0;
+ return (double) value2.u.b != value1.u.b;
+}
+
+static double
+_MiniXftCompareSize (char *object, MiniXftValue value1, MiniXftValue value2)
+{
+ double v1, v2, v;
+
+ switch (value1.type) {
+ case MiniXftTypeInteger:
+ v1 = value1.u.i;
+ break;
+ case MiniXftTypeDouble:
+ v1 = value1.u.d;
+ break;
+ default:
+ return -1;
+ }
+ switch (value2.type) {
+ case MiniXftTypeInteger:
+ v2 = value2.u.i;
+ break;
+ case MiniXftTypeDouble:
+ v2 = value2.u.d;
+ break;
+ default:
+ return -1;
+ }
+ if (v2 == 0)
+ return 0;
+ v = v2 - v1;
+ if (v < 0)
+ v = -v;
+ return v;
+}
+
+/*
+ * Order is significant, it defines the precedence of
+ * each value, earlier values are more significant than
+ * later values
+ */
+static MiniXftMatcher _MiniXftMatchers [] = {
+ { XFT_FOUNDRY, _MiniXftCompareString, },
+ { XFT_ENCODING, _MiniXftCompareString, },
+ { XFT_FAMILY, _MiniXftCompareString, },
+ { XFT_SPACING, _MiniXftCompareInteger, },
+ { XFT_PIXEL_SIZE, _MiniXftCompareSize, },
+ { XFT_STYLE, _MiniXftCompareString, },
+ { XFT_SLANT, _MiniXftCompareInteger, },
+ { XFT_WEIGHT, _MiniXftCompareInteger, },
+ { XFT_RASTERIZER, _MiniXftCompareString, },
+ { XFT_ANTIALIAS, _MiniXftCompareBool, },
+ { XFT_OUTLINE, _MiniXftCompareBool, },
+};
+
+#define NUM_MATCHER (sizeof _MiniXftMatchers / sizeof _MiniXftMatchers[0])
+
+static Bool
+_MiniXftCompareValueList (const char *object,
+ MiniXftValueList *v1orig, /* pattern */
+ MiniXftValueList *v2orig, /* target */
+ MiniXftValue *bestValue,
+ double *value,
+ MiniXftResult *result)
+{
+ MiniXftValueList *v1, *v2;
+ double v, best;
+ int j;
+ int i;
+
+ for (i = 0; i < NUM_MATCHER; i++)
+ {
+ if (!_MiniXftStrCmpIgnoreCase (_MiniXftMatchers[i].object, object))
+ break;
+ }
+ if (i == NUM_MATCHER)
+ {
+ if (bestValue)
+ *bestValue = v2orig->value;
+ return True;
+ }
+
+ best = 1e99;
+ j = 0;
+ for (v1 = v1orig; v1; v1 = v1->next)
+ {
+ for (v2 = v2orig; v2; v2 = v2->next)
+ {
+ v = (*_MiniXftMatchers[i].compare) (_MiniXftMatchers[i].object,
+ v1->value,
+ v2->value);
+ if (v < 0)
+ {
+ *result = MiniXftResultTypeMismatch;
+ return False;
+ }
+ if (_MiniXftFontDebug () & XFT_DBG_MATCHV)
+ printf (" v %g j %d ", v, j);
+ v = v * 100 + j;
+ if (v < best)
+ {
+ if (bestValue)
+ *bestValue = v2->value;
+ best = v;
+ }
+ }
+ j++;
+ }
+ if (_MiniXftFontDebug () & XFT_DBG_MATCHV)
+ {
+ printf (" %s: %g ", object, best);
+ MiniXftValueListPrint (v1orig);
+ printf (", ");
+ MiniXftValueListPrint (v2orig);
+ printf ("\n");
+ }
+ value[i] += best;
+ return True;
+}
+
+/*
+ * Return a value indicating the distance between the two lists of
+ * values
+ */
+
+static Bool
+_MiniXftCompare (MiniXftPattern *pat,
+ MiniXftPattern *fnt,
+ double *value,
+ MiniXftResult *result)
+{
+ int i, i1, i2;
+
+ for (i = 0; i < NUM_MATCHER; i++)
+ value[i] = 0.0;
+
+ for (i1 = 0; i1 < pat->num; i1++)
+ {
+ for (i2 = 0; i2 < fnt->num; i2++)
+ {
+ if (!_MiniXftStrCmpIgnoreCase (pat->elts[i1].object,
+ fnt->elts[i2].object))
+ {
+ if (!_MiniXftCompareValueList (pat->elts[i1].object,
+ pat->elts[i1].values,
+ fnt->elts[i2].values,
+ 0,
+ value,
+ result))
+ return False;
+ break;
+ }
+ }
+#if 0
+ /*
+ * Overspecified patterns are slightly penalized in
+ * case some other font includes the requested field
+ */
+ if (i2 == fnt->num)
+ {
+ for (i2 = 0; i2 < NUM_MATCHER; i2++)
+ {
+ if (!_MiniXftStrCmpIgnoreCase (_MiniXftMatchers[i2].object,
+ pat->elts[i1].object))
+ {
+ value[i2] = 1.0;
+ break;
+ }
+ }
+ }
+#endif
+ }
+ return True;
+}
+
+MiniXftPattern *
+MiniXftFontSetMatch (MiniXftFontSet **sets,
+ int nsets,
+ MiniXftPattern *p,
+ MiniXftResult *result)
+{
+ double score[NUM_MATCHER], bestscore[NUM_MATCHER];
+ int f;
+ MiniXftFontSet *s;
+ MiniXftPattern *best;
+ MiniXftPattern *new;
+ MiniXftPatternElt *fe, *pe;
+ MiniXftValue v;
+ int i;
+ int set;
+
+ for (i = 0; i < NUM_MATCHER; i++)
+ bestscore[i] = 0;
+ best = 0;
+ if (_MiniXftFontDebug () & XFT_DBG_MATCH)
+ {
+ printf ("Match ");
+ MiniXftPatternPrint (p);
+ }
+ for (set = 0; set < nsets; set++)
+ {
+ s = sets[set];
+ for (f = 0; f < s->nfont; f++)
+ {
+ if (_MiniXftFontDebug () & XFT_DBG_MATCH)
+ {
+ printf ("Font %d ", f);
+ MiniXftPatternPrint (s->fonts[f]);
+ }
+ if (!_MiniXftCompare (p, s->fonts[f], score, result))
+ return 0;
+ if (_MiniXftFontDebug () & XFT_DBG_MATCH)
+ {
+ printf ("Score");
+ for (i = 0; i < NUM_MATCHER; i++)
+ {
+ printf (" %g", score[i]);
+ }
+ printf ("\n");
+ }
+ for (i = 0; i < NUM_MATCHER; i++)
+ {
+ if (best && bestscore[i] < score[i])
+ break;
+ if (!best || score[i] < bestscore[i])
+ {
+ for (i = 0; i < NUM_MATCHER; i++)
+ bestscore[i] = score[i];
+ best = s->fonts[f];
+ break;
+ }
+ }
+ }
+ }
+ if (_MiniXftFontDebug () & XFT_DBG_MATCH)
+ {
+ printf ("Best score");
+ for (i = 0; i < NUM_MATCHER; i++)
+ printf (" %g", bestscore[i]);
+ MiniXftPatternPrint (best);
+ }
+ if (!best)
+ {
+ *result = MiniXftResultNoMatch;
+ return 0;
+ }
+ new = MiniXftPatternCreate ();
+ if (!new)
+ return 0;
+ for (i = 0; i < best->num; i++)
+ {
+ fe = &best->elts[i];
+ pe = MiniXftPatternFind (p, fe->object, False);
+ if (pe)
+ {
+ if (!_MiniXftCompareValueList (pe->object, pe->values,
+ fe->values, &v, score, result))
+ {
+ MiniXftPatternDestroy (new);
+ return 0;
+ }
+ }
+ else
+ v = fe->values->value;
+ MiniXftPatternAdd (new, fe->object, v, True);
+ }
+ for (i = 0; i < p->num; i++)
+ {
+ pe = &p->elts[i];
+ fe = MiniXftPatternFind (best, pe->object, False);
+ if (!fe)
+ MiniXftPatternAdd (new, pe->object, pe->values->value, True);
+ }
+ return new;
+}
diff --git a/pango/mini-xft/minixftmatrix.c b/pango/mini-xft/minixftmatrix.c
new file mode 100644
index 00000000..b7decb69
--- /dev/null
+++ b/pango/mini-xft/minixftmatrix.c
@@ -0,0 +1,104 @@
+/*
+ * $XFree86: xc/lib/MiniXft/xftmatrix.c,v 1.1 2001/03/30 18:50:18 keithp Exp $
+ *
+ * Copyright © 2000 Tuomas J. Lukka
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Tuomas Lukka not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Tuomas Lukka makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * TUOMAS LUKKA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL TUOMAS LUKKA BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <math.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include "minixftint.h"
+
+MiniXftMatrix *
+_MiniXftSaveMatrix (const MiniXftMatrix *mat)
+{
+ MiniXftMatrix *r;
+ if(!mat)
+ return 0;
+ r = (MiniXftMatrix *) malloc (sizeof (*r) );
+ if (!r)
+ return 0;
+ *r = *mat;
+ return r;
+}
+
+int
+MiniXftMatrixEqual (const MiniXftMatrix *mat1, const MiniXftMatrix *mat2)
+{
+ if(mat1 == mat2) return True;
+ if(mat1 == 0 || mat2 == 0) return False;
+ return mat1->xx == mat2->xx &&
+ mat1->xy == mat2->xy &&
+ mat1->yx == mat2->yx &&
+ mat1->yy == mat2->yy;
+}
+
+void
+MiniXftMatrixMultiply (MiniXftMatrix *result, MiniXftMatrix *a, MiniXftMatrix *b)
+{
+ MiniXftMatrix r;
+
+ r.xx = a->xx * b->xx + a->xy * b->yx;
+ r.xy = a->xx * b->xy + a->xy * b->yy;
+ r.yx = a->yx * b->xx + a->yy * b->yx;
+ r.yy = a->yx * b->xy + a->yy * b->yy;
+ *result = r;
+}
+
+void
+MiniXftMatrixRotate (MiniXftMatrix *m, double c, double s)
+{
+ MiniXftMatrix r;
+
+ /*
+ * X Coordinate system is upside down, swap to make
+ * rotations counterclockwise
+ */
+ r.xx = c;
+ r.xy = -s;
+ r.yx = s;
+ r.yy = c;
+ MiniXftMatrixMultiply (m, &r, m);
+}
+
+void
+MiniXftMatrixScale (MiniXftMatrix *m, double sx, double sy)
+{
+ MiniXftMatrix r;
+
+ r.xx = sx;
+ r.xy = 0;
+ r.yx = 0;
+ r.yy = sy;
+ MiniXftMatrixMultiply (m, &r, m);
+}
+
+void
+MiniXftMatrixShear (MiniXftMatrix *m, double sh, double sv)
+{
+ MiniXftMatrix r;
+
+ r.xx = 1;
+ r.xy = sh;
+ r.yx = sv;
+ r.yy = 1;
+ MiniXftMatrixMultiply (m, &r, m);
+}
diff --git a/pango/mini-xft/minixftname.c b/pango/mini-xft/minixftname.c
new file mode 100644
index 00000000..3452f39a
--- /dev/null
+++ b/pango/mini-xft/minixftname.c
@@ -0,0 +1,391 @@
+/*
+ * $XFree86: xc/lib/MiniXft/xftname.c,v 1.10 2001/03/30 18:50:18 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "minixftint.h"
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+typedef struct _MiniXftObjectType {
+ const char *object;
+ MiniXftType type;
+} MiniXftObjectType;
+
+static const MiniXftObjectType _MiniXftObjectTypes[] = {
+ { XFT_FAMILY, MiniXftTypeString, },
+ { XFT_STYLE, MiniXftTypeString, },
+ { XFT_SLANT, MiniXftTypeInteger, },
+ { XFT_WEIGHT, MiniXftTypeInteger, },
+ { XFT_SIZE, MiniXftTypeDouble, },
+ { XFT_PIXEL_SIZE, MiniXftTypeDouble, },
+ { XFT_ENCODING, MiniXftTypeString, },
+ { XFT_SPACING, MiniXftTypeInteger, },
+ { XFT_FOUNDRY, MiniXftTypeString, },
+ { XFT_CORE, MiniXftTypeBool, },
+ { XFT_ANTIALIAS, MiniXftTypeBool, },
+ { XFT_XLFD, MiniXftTypeString, },
+ { XFT_FILE, MiniXftTypeString, },
+ { XFT_INDEX, MiniXftTypeInteger, },
+ { XFT_RASTERIZER, MiniXftTypeString, },
+ { XFT_OUTLINE, MiniXftTypeBool, },
+ { XFT_SCALABLE, MiniXftTypeBool, },
+ { XFT_RGBA, MiniXftTypeInteger, },
+ { XFT_SCALE, MiniXftTypeDouble, },
+ { XFT_RENDER, MiniXftTypeBool, },
+ { XFT_MINSPACE, MiniXftTypeBool, },
+ { XFT_CHAR_WIDTH, MiniXftTypeInteger },
+ { XFT_CHAR_HEIGHT, MiniXftTypeInteger },
+ { XFT_MATRIX, MiniXftTypeMatrix },
+};
+
+#define NUM_OBJECT_TYPES (sizeof _MiniXftObjectTypes / sizeof _MiniXftObjectTypes[0])
+
+static const MiniXftObjectType *
+MiniXftNameGetType (const char *object)
+{
+ int i;
+
+ for (i = 0; i < NUM_OBJECT_TYPES; i++)
+ {
+ if (!_MiniXftStrCmpIgnoreCase (object, _MiniXftObjectTypes[i].object))
+ return &_MiniXftObjectTypes[i];
+ }
+ return 0;
+}
+
+typedef struct _MiniXftConstant {
+ const char *name;
+ const char *object;
+ int value;
+} MiniXftConstant;
+
+static MiniXftConstant MiniXftConstants[] = {
+ { "light", "weight", XFT_WEIGHT_LIGHT, },
+ { "medium", "weight", XFT_WEIGHT_MEDIUM, },
+ { "demibold", "weight", XFT_WEIGHT_DEMIBOLD, },
+ { "bold", "weight", XFT_WEIGHT_BOLD, },
+ { "black", "weight", XFT_WEIGHT_BLACK, },
+
+ { "roman", "slant", XFT_SLANT_ROMAN, },
+ { "italic", "slant", XFT_SLANT_ITALIC, },
+ { "oblique", "slant", XFT_SLANT_OBLIQUE, },
+
+ { "proportional", "spacing", XFT_PROPORTIONAL, },
+ { "mono", "spacing", XFT_MONO, },
+ { "charcell", "spacing", XFT_CHARCELL, },
+
+ { "rgb", "rgba", XFT_RGBA_RGB, },
+ { "bgr", "rgba", XFT_RGBA_BGR, },
+ { "vrgb", "rgba", XFT_RGBA_VRGB },
+ { "vbgr", "rgba", XFT_RGBA_VBGR },
+};
+
+#define NUM_XFT_CONSTANTS (sizeof MiniXftConstants/sizeof MiniXftConstants[0])
+
+static MiniXftConstant *
+_MiniXftNameConstantLookup (char *string)
+{
+ int i;
+
+ for (i = 0; i < NUM_XFT_CONSTANTS; i++)
+ if (!_MiniXftStrCmpIgnoreCase (string, MiniXftConstants[i].name))
+ return &MiniXftConstants[i];
+ return 0;
+}
+
+Bool
+MiniXftNameConstant (char *string, int *result)
+{
+ MiniXftConstant *c;
+
+ if ((c = _MiniXftNameConstantLookup(string)))
+ {
+ *result = c->value;
+ return True;
+ }
+ return False;
+}
+
+static MiniXftValue
+_MiniXftNameConvert (MiniXftType type, char *string, MiniXftMatrix *m)
+{
+ MiniXftValue v;
+
+ v.type = type;
+ switch (v.type) {
+ case MiniXftTypeInteger:
+ if (!MiniXftNameConstant (string, &v.u.i))
+ v.u.i = atoi (string);
+ break;
+ case MiniXftTypeString:
+ v.u.s = string;
+ break;
+ case MiniXftTypeBool:
+ v.u.b = MiniXftDefaultParseBool (string);
+ break;
+ case MiniXftTypeDouble:
+ v.u.d = strtod (string, 0);
+ break;
+ case MiniXftTypeMatrix:
+ v.u.m = m;
+ sscanf (string, "%lg %lg %lg %lg", &m->xx, &m->xy, &m->yx, &m->yy);
+ break;
+ default:
+ break;
+ }
+ return v;
+}
+
+static const char *
+_MiniXftNameFindNext (const char *cur, const char *delim, char *save, char *last)
+{
+ char c;
+
+ while ((c = *cur))
+ {
+ if (c == '\\')
+ {
+ ++cur;
+ if (!(c = *cur))
+ break;
+ }
+ else if (strchr (delim, c))
+ break;
+ ++cur;
+ *save++ = c;
+ }
+ *save = 0;
+ *last = *cur;
+ if (*cur)
+ cur++;
+ return cur;
+}
+
+MiniXftPattern *
+MiniXftNameParse (const char *name)
+{
+ char *save;
+ MiniXftPattern *pat;
+ double d;
+ char *e;
+ char delim;
+ MiniXftValue v;
+ MiniXftMatrix m;
+ const MiniXftObjectType *t;
+ MiniXftConstant *c;
+
+ save = malloc (strlen (name) + 1);
+ if (!save)
+ goto bail0;
+ pat = MiniXftPatternCreate ();
+ if (!pat)
+ goto bail1;
+
+ for (;;)
+ {
+ name = _MiniXftNameFindNext (name, "-,:", save, &delim);
+ if (save[0])
+ {
+ if (!MiniXftPatternAddString (pat, XFT_FAMILY, save))
+ goto bail2;
+ }
+ if (delim != ',')
+ break;
+ }
+ if (delim == '-')
+ {
+ for (;;)
+ {
+ name = _MiniXftNameFindNext (name, "-,:", save, &delim);
+ d = strtod (save, &e);
+ if (e != save)
+ {
+ if (!MiniXftPatternAddDouble (pat, XFT_SIZE, d))
+ goto bail2;
+ }
+ if (delim != ',')
+ break;
+ }
+ }
+ while (delim == ':')
+ {
+ name = _MiniXftNameFindNext (name, "=_:", save, &delim);
+ if (save[0])
+ {
+ if (delim == '=' || delim == '_')
+ {
+ t = MiniXftNameGetType (save);
+ for (;;)
+ {
+ name = _MiniXftNameFindNext (name, ":,", save, &delim);
+ if (save[0] && t)
+ {
+ v = _MiniXftNameConvert (t->type, save, &m);
+ if (!MiniXftPatternAdd (pat, t->object, v, True))
+ goto bail2;
+ }
+ if (delim != ',')
+ break;
+ }
+ }
+ else
+ {
+ if ((c = _MiniXftNameConstantLookup (save)))
+ {
+ if (!MiniXftPatternAddInteger (pat, c->object, c->value))
+ goto bail2;
+ }
+ }
+ }
+ }
+
+ free (save);
+ return pat;
+
+bail2:
+ MiniXftPatternDestroy (pat);
+bail1:
+ free (save);
+bail0:
+ return 0;
+}
+
+static Bool
+_MiniXftNameUnparseString (const char *string, char *escape, char **destp, int *lenp)
+{
+ int len = *lenp;
+ char *dest = *destp;
+ char c;
+
+ while ((c = *string++))
+ {
+ if (escape && strchr (escape, c))
+ {
+ if (len-- == 0)
+ return False;
+ *dest++ = escape[0];
+ }
+ if (len-- == 0)
+ return False;
+ *dest++ = c;
+ }
+ *destp = dest;
+ *lenp = len;
+ return True;
+}
+
+static Bool
+_MiniXftNameUnparseValue (MiniXftValue v, char *escape, char **destp, int *lenp)
+{
+ char temp[1024];
+
+ switch (v.type) {
+ case MiniXftTypeVoid:
+ return True;
+ case MiniXftTypeInteger:
+ sprintf (temp, "%d", v.u.i);
+ return _MiniXftNameUnparseString (temp, 0, destp, lenp);
+ case MiniXftTypeDouble:
+ sprintf (temp, "%g", v.u.d);
+ return _MiniXftNameUnparseString (temp, 0, destp, lenp);
+ case MiniXftTypeString:
+ return _MiniXftNameUnparseString (v.u.s, escape, destp, lenp);
+ case MiniXftTypeBool:
+ return _MiniXftNameUnparseString (v.u.b ? "True" : "False", 0, destp, lenp);
+ case MiniXftTypeMatrix:
+ sprintf (temp, "%g %g %g %g",
+ v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy);
+ return _MiniXftNameUnparseString (temp, 0, destp, lenp);
+ }
+ return False;
+}
+
+static Bool
+_MiniXftNameUnparseValueList (MiniXftValueList *v, char *escape, char **destp, int *lenp)
+{
+ while (v)
+ {
+ if (!_MiniXftNameUnparseValue (v->value, escape, destp, lenp))
+ return False;
+ if ((v = v->next))
+ if (!_MiniXftNameUnparseString (",", 0, destp, lenp))
+ return False;
+ }
+ return True;
+}
+
+#define XFT_ESCAPE_FIXED "\\-:,"
+#define XFT_ESCAPE_VARIABLE "\\=_:,"
+
+Bool
+MiniXftNameUnparse (MiniXftPattern *pat, char *dest, int len)
+{
+ int i;
+ MiniXftPatternElt *e;
+ const MiniXftObjectType *o;
+
+ e = MiniXftPatternFind (pat, XFT_FAMILY, False);
+ if (e)
+ {
+ if (!_MiniXftNameUnparseValueList (e->values, XFT_ESCAPE_FIXED,
+ &dest, &len))
+ return False;
+ }
+ e = MiniXftPatternFind (pat, XFT_SIZE, False);
+ if (e)
+ {
+ if (!_MiniXftNameUnparseString ("-", 0, &dest, &len))
+ return False;
+ if (!_MiniXftNameUnparseValueList (e->values, XFT_ESCAPE_FIXED, &dest, &len))
+ return False;
+ }
+ for (i = 0; i < NUM_OBJECT_TYPES; i++)
+ {
+ o = &_MiniXftObjectTypes[i];
+ if (!strcmp (o->object, XFT_FAMILY) ||
+ !strcmp (o->object, XFT_SIZE) ||
+ !strcmp (o->object, XFT_FILE))
+ continue;
+
+ e = MiniXftPatternFind (pat, o->object, False);
+ if (e)
+ {
+ if (!_MiniXftNameUnparseString (":", 0, &dest, &len))
+ return False;
+ if (!_MiniXftNameUnparseString (o->object, XFT_ESCAPE_VARIABLE,
+ &dest, &len))
+ return False;
+ if (!_MiniXftNameUnparseString ("=", 0, &dest, &len))
+ return False;
+ if (!_MiniXftNameUnparseValueList (e->values, XFT_ESCAPE_VARIABLE,
+ &dest, &len))
+ return False;
+ }
+ }
+ if (len == 0)
+ return False;
+ *dest = '\0';
+ return True;
+}
diff --git a/pango/mini-xft/minixftpat.c b/pango/mini-xft/minixftpat.c
new file mode 100644
index 00000000..223966b3
--- /dev/null
+++ b/pango/mini-xft/minixftpat.c
@@ -0,0 +1,411 @@
+/*
+ * $XFree86: xc/lib/MiniXft/xftpat.c,v 1.6 2001/03/30 18:50:18 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "minixftint.h"
+
+MiniXftPattern *
+MiniXftPatternCreate (void)
+{
+ MiniXftPattern *p;
+
+ p = (MiniXftPattern *) malloc (sizeof (MiniXftPattern));
+ if (!p)
+ return 0;
+ p->num = 0;
+ p->size = 0;
+ p->elts = 0;
+ return p;
+}
+
+void
+MiniXftValueDestroy (MiniXftValue v)
+{
+ if (v.type == MiniXftTypeString)
+ free (v.u.s);
+ if( v.type == MiniXftTypeMatrix)
+ free (v.u.m);
+}
+
+void
+MiniXftValueListDestroy (MiniXftValueList *l)
+{
+ MiniXftValueList *next;
+ for (; l; l = next)
+ {
+ if (l->value.type == MiniXftTypeString)
+ free (l->value.u.s);
+ if (l->value.type == MiniXftTypeMatrix)
+ free (l->value.u.m);
+ next = l->next;
+ free (l);
+ }
+}
+
+void
+MiniXftPatternDestroy (MiniXftPattern *p)
+{
+ int i;
+
+ for (i = 0; i < p->num; i++)
+ MiniXftValueListDestroy (p->elts[i].values);
+
+ if (p->elts)
+ {
+ free (p->elts);
+ p->elts = 0;
+ }
+ p->num = p->size = 0;
+ free (p);
+}
+
+MiniXftPatternElt *
+MiniXftPatternFind (MiniXftPattern *p, const char *object, Bool insert)
+{
+ int i;
+ int s;
+ MiniXftPatternElt *e;
+
+ /* match existing */
+ for (i = 0; i < p->num; i++)
+ {
+ if (!_MiniXftStrCmpIgnoreCase (object, p->elts[i].object))
+ return &p->elts[i];
+ }
+
+ if (!insert)
+ return 0;
+
+ /* grow array */
+ if (i == p->size)
+ {
+ s = p->size + 16;
+ if (p->elts)
+ e = (MiniXftPatternElt *) realloc (p->elts, s * sizeof (MiniXftPatternElt));
+ else
+ e = (MiniXftPatternElt *) malloc (s * sizeof (MiniXftPatternElt));
+ if (!e)
+ return False;
+ p->elts = e;
+ while (p->size < s)
+ {
+ p->elts[p->size].object = 0;
+ p->elts[p->size].values = 0;
+ p->size++;
+ }
+ }
+
+ /* bump count */
+ p->num++;
+
+ return &p->elts[i];
+}
+
+Bool
+MiniXftPatternAdd (MiniXftPattern *p, const char *object, MiniXftValue value, Bool append)
+{
+ MiniXftPatternElt *e;
+ MiniXftValueList *new, **prev;
+
+ new = (MiniXftValueList *) malloc (sizeof (MiniXftValueList));
+ if (!new)
+ goto bail0;
+
+ /* dup string */
+ if (value.type == MiniXftTypeString)
+ {
+ value.u.s = _MiniXftSaveString (value.u.s);
+ if (!value.u.s)
+ goto bail1;
+ }
+ else if (value.type == MiniXftTypeMatrix)
+ {
+ value.u.m = _MiniXftSaveMatrix (value.u.m);
+ if (!value.u.m)
+ goto bail1;
+ }
+ new->value = value;
+ new->next = 0;
+
+ e = MiniXftPatternFind (p, object, True);
+ if (!e)
+ goto bail2;
+
+ e->object = object;
+ if (append)
+ {
+ for (prev = &e->values; *prev; prev = &(*prev)->next);
+ *prev = new;
+ }
+ else
+ {
+ new->next = e->values;
+ e->values = new;
+ }
+
+ return True;
+
+bail2:
+ if (value.type == MiniXftTypeString)
+ free (value.u.s);
+ else if (value.type == MiniXftTypeMatrix)
+ free (value.u.m);
+bail1:
+ free (new);
+bail0:
+ return False;
+}
+
+Bool
+MiniXftPatternDel (MiniXftPattern *p, const char *object)
+{
+ MiniXftPatternElt *e;
+ int i;
+
+ e = MiniXftPatternFind (p, object, False);
+ if (!e)
+ return False;
+
+ i = e - p->elts;
+
+ /* destroy value */
+ MiniXftValueListDestroy (e->values);
+
+ /* shuffle existing ones down */
+ memmove (e, e+1, (p->elts + p->num - (e + 1)) * sizeof (MiniXftPatternElt));
+ p->num--;
+ p->elts[p->num].object = 0;
+ p->elts[p->num].values = 0;
+ return True;
+}
+
+Bool
+MiniXftPatternAddInteger (MiniXftPattern *p, const char *object, int i)
+{
+ MiniXftValue v;
+
+ v.type = MiniXftTypeInteger;
+ v.u.i = i;
+ return MiniXftPatternAdd (p, object, v, True);
+}
+
+Bool
+MiniXftPatternAddDouble (MiniXftPattern *p, const char *object, double d)
+{
+ MiniXftValue v;
+
+ v.type = MiniXftTypeDouble;
+ v.u.d = d;
+ return MiniXftPatternAdd (p, object, v, True);
+}
+
+
+Bool
+MiniXftPatternAddString (MiniXftPattern *p, const char *object, const char *s)
+{
+ MiniXftValue v;
+
+ v.type = MiniXftTypeString;
+ v.u.s = (char *) s;
+ return MiniXftPatternAdd (p, object, v, True);
+}
+
+Bool
+MiniXftPatternAddMatrix (MiniXftPattern *p, const char *object, const MiniXftMatrix *s)
+{
+ MiniXftValue v;
+
+ v.type = MiniXftTypeMatrix;
+ v.u.m = (MiniXftMatrix *) s;
+ return MiniXftPatternAdd (p, object, v, True);
+}
+
+
+Bool
+MiniXftPatternAddBool (MiniXftPattern *p, const char *object, Bool b)
+{
+ MiniXftValue v;
+
+ v.type = MiniXftTypeBool;
+ v.u.b = b;
+ return MiniXftPatternAdd (p, object, v, True);
+}
+
+MiniXftResult
+MiniXftPatternGet (MiniXftPattern *p, const char *object, int id, MiniXftValue *v)
+{
+ MiniXftPatternElt *e;
+ MiniXftValueList *l;
+
+ e = MiniXftPatternFind (p, object, False);
+ if (!e)
+ return MiniXftResultNoMatch;
+ for (l = e->values; l; l = l->next)
+ {
+ if (!id)
+ {
+ *v = l->value;
+ return MiniXftResultMatch;
+ }
+ id--;
+ }
+ return MiniXftResultNoId;
+}
+
+MiniXftResult
+MiniXftPatternGetInteger (MiniXftPattern *p, const char *object, int id, int *i)
+{
+ MiniXftValue v;
+ MiniXftResult r;
+
+ r = MiniXftPatternGet (p, object, id, &v);
+ if (r != MiniXftResultMatch)
+ return r;
+ switch (v.type) {
+ case MiniXftTypeDouble:
+ *i = (int) v.u.d;
+ break;
+ case MiniXftTypeInteger:
+ *i = v.u.i;
+ break;
+ default:
+ return MiniXftResultTypeMismatch;
+ }
+ return MiniXftResultMatch;
+}
+
+MiniXftResult
+MiniXftPatternGetDouble (MiniXftPattern *p, const char *object, int id, double *d)
+{
+ MiniXftValue v;
+ MiniXftResult r;
+
+ r = MiniXftPatternGet (p, object, id, &v);
+ if (r != MiniXftResultMatch)
+ return r;
+ switch (v.type) {
+ case MiniXftTypeDouble:
+ *d = v.u.d;
+ break;
+ case MiniXftTypeInteger:
+ *d = (double) v.u.i;
+ break;
+ default:
+ return MiniXftResultTypeMismatch;
+ }
+ return MiniXftResultMatch;
+}
+
+MiniXftResult
+MiniXftPatternGetString (MiniXftPattern *p, const char *object, int id, char **s)
+{
+ MiniXftValue v;
+ MiniXftResult r;
+
+ r = MiniXftPatternGet (p, object, id, &v);
+ if (r != MiniXftResultMatch)
+ return r;
+ if (v.type != MiniXftTypeString)
+ return MiniXftResultTypeMismatch;
+ *s = v.u.s;
+ return MiniXftResultMatch;
+}
+
+MiniXftResult
+MiniXftPatternGetMatrix (MiniXftPattern *p, const char *object, int id, MiniXftMatrix **m)
+{
+ MiniXftValue v;
+ MiniXftResult r;
+
+ r = MiniXftPatternGet (p, object, id, &v);
+ if (r != MiniXftResultMatch)
+ return r;
+ if (v.type != MiniXftTypeMatrix)
+ return MiniXftResultTypeMismatch;
+ *m = v.u.m;
+ return MiniXftResultMatch;
+}
+
+
+MiniXftResult
+MiniXftPatternGetBool (MiniXftPattern *p, const char *object, int id, Bool *b)
+{
+ MiniXftValue v;
+ MiniXftResult r;
+
+ r = MiniXftPatternGet (p, object, id, &v);
+ if (r != MiniXftResultMatch)
+ return r;
+ if (v.type != MiniXftTypeBool)
+ return MiniXftResultTypeMismatch;
+ *b = v.u.b;
+ return MiniXftResultMatch;
+}
+
+MiniXftPattern *
+MiniXftPatternDuplicate (MiniXftPattern *orig)
+{
+ MiniXftPattern *new;
+ int i;
+ MiniXftValueList *l;
+
+ new = MiniXftPatternCreate ();
+ if (!new)
+ goto bail0;
+
+ for (i = 0; i < orig->num; i++)
+ {
+ for (l = orig->elts[i].values; l; l = l->next)
+ if (!MiniXftPatternAdd (new, orig->elts[i].object, l->value, True))
+ goto bail1;
+ }
+
+ return new;
+
+bail1:
+ MiniXftPatternDestroy (new);
+bail0:
+ return 0;
+}
+
+MiniXftPattern *
+MiniXftPatternVaBuild (MiniXftPattern *orig, va_list va)
+{
+ MiniXftPattern *ret;
+
+ _MiniXftPatternVapBuild (ret, orig, va);
+ return ret;
+}
+
+MiniXftPattern *
+MiniXftPatternBuild (MiniXftPattern *orig, ...)
+{
+ va_list va;
+
+ va_start (va, orig);
+ _MiniXftPatternVapBuild (orig, orig, va);
+ va_end (va);
+ return orig;
+}
diff --git a/pango/mini-xft/minixftstr.c b/pango/mini-xft/minixftstr.c
new file mode 100644
index 00000000..afa22338
--- /dev/null
+++ b/pango/mini-xft/minixftstr.c
@@ -0,0 +1,156 @@
+/*
+ * $XFree86: xc/lib/MiniXft/xftstr.c,v 1.6 2001/04/01 14:00:01 tsi Exp $
+ *
+ * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include "minixftint.h"
+
+char *
+_MiniXftSaveString (const char *s)
+{
+ char *r;
+
+ if (!s)
+ return 0;
+ r = (char *) malloc (strlen (s) + 1);
+ if (!r)
+ return 0;
+ strcpy (r, s);
+ return r;
+}
+
+const char *
+_MiniXftGetInt(const char *ptr, int *val)
+{
+ if (*ptr == '*') {
+ *val = -1;
+ ptr++;
+ } else
+ for (*val = 0; *ptr >= '0' && *ptr <= '9';)
+ *val = *val * 10 + *ptr++ - '0';
+ if (*ptr == '-')
+ return ptr;
+ return (char *) 0;
+}
+
+char *
+_MiniXftSplitStr (const char *field, char *save)
+{
+ char *s = save;
+ char c;
+
+ while (*field)
+ {
+ if (*field == '-')
+ break;
+ c = *field++;
+ *save++ = c;
+ }
+ *save = 0;
+ return s;
+}
+
+char *
+_MiniXftDownStr (const char *field, char *save)
+{
+ char *s = save;
+ char c;
+
+ while (*field)
+ {
+ c = *field++;
+ *save++ = c;
+ }
+ *save = 0;
+ return s;
+}
+
+const char *
+_MiniXftSplitField (const char *field, char *save)
+{
+ char c;
+
+ while (*field)
+ {
+ if (*field == '-' || *field == '=')
+ break;
+ c = *field++;
+ *save++ = c;
+ }
+ *save = 0;
+ return field;
+}
+
+const char *
+_MiniXftSplitValue (const char *field, char *save)
+{
+ char c;
+
+ while (*field)
+ {
+ if (*field == '-' || *field == ',')
+ break;
+ c = *field++;
+ *save++ = c;
+ }
+ *save = 0;
+ if (*field)
+ field++;
+ return field;
+}
+
+int
+_MiniXftMatchSymbolic (MiniXftSymbolic *s, int n, const char *name, int def)
+{
+ while (n--)
+ {
+ if (!_MiniXftStrCmpIgnoreCase (s->name, name))
+ return s->value;
+ s++;
+ }
+ return def;
+}
+
+int
+_MiniXftStrCmpIgnoreCase (const char *s1, const char *s2)
+{
+ char c1, c2;
+
+ for (;;)
+ {
+ c1 = *s1++;
+ c2 = *s2++;
+ if (!c1 || !c2)
+ break;
+ if (isupper (c1))
+ c1 = tolower (c1);
+ if (isupper (c2))
+ c2 = tolower (c2);
+ if (c1 != c2)
+ break;
+ }
+ return (int) c2 - (int) c1;
+}
+
diff --git a/pango/pango-context.c b/pango/pango-context.c
index 5a9824a6..19ca1af4 100644
--- a/pango/pango-context.c
+++ b/pango/pango-context.c
@@ -35,7 +35,7 @@ struct _PangoContext
PangoDirection base_dir;
PangoFontDescription *font_desc;
- GSList *font_maps;
+ PangoFontMap *font_map;
};
struct _PangoContextClass
@@ -92,7 +92,7 @@ pango_context_init (PangoContext *context)
{
context->base_dir = PANGO_DIRECTION_LTR;
context->language = NULL;
- context->font_maps = NULL;
+ context->font_map = NULL;
context->font_desc = pango_font_description_new ();
pango_font_description_set_family (context->font_desc, "serif");
@@ -120,8 +120,8 @@ pango_context_finalize (GObject *object)
context = PANGO_CONTEXT (object);
- g_slist_foreach (context->font_maps, (GFunc)g_object_unref, NULL);
- g_slist_free (context->font_maps);
+ if (context->font_map)
+ g_object_unref (G_OBJECT(context->font_map));
pango_font_description_free (context->font_desc);
@@ -147,39 +147,24 @@ pango_context_new (void)
}
/**
- * pango_context_add_font_map:
+ * pango_context_set_font_map:
* @context: a #PangoContext
- * @font_map: the #PangoFontMap to add.
+ * @font_map: the #PangoFontMap to set.
*
- * Add a font map to the list of font maps that are searched for fonts
- * when fonts are looked-up in this context.
+ * Sets the font map to be searched when fonts are looked-up in this context.
**/
void
-pango_context_add_font_map (PangoContext *context,
+pango_context_set_font_map (PangoContext *context,
PangoFontMap *font_map)
{
g_return_if_fail (context != NULL);
g_return_if_fail (font_map != NULL);
-
- g_object_ref (G_OBJECT (font_map));
- context->font_maps = g_slist_append (context->font_maps, font_map);
-}
-typedef struct
-{
- int n_found;
- PangoFontFamily **families;
-} ListFamiliesInfo;
+ if (context->font_map)
+ g_object_unref (G_OBJECT (context->font_map));
-static void
-list_families_foreach (gpointer key, gpointer value, gpointer user_data)
-{
- ListFamiliesInfo *info = user_data;
-
- if (info->families)
- info->families[info->n_found++] = value;
-
- g_free (value);
+ g_object_ref (G_OBJECT (font_map));
+ context->font_map = font_map;
}
/**
@@ -196,17 +181,13 @@ pango_context_list_families (PangoContext *context,
PangoFontFamily ***families,
int *n_families)
{
- int n_maps;
-
g_return_if_fail (context != NULL);
g_return_if_fail (families == NULL || n_families != NULL);
if (n_families == NULL)
return;
- n_maps = g_slist_length (context->font_maps);
-
- if (n_maps == 0)
+ if (context->font_map == NULL)
{
*n_families = 0;
if (families)
@@ -214,57 +195,8 @@ pango_context_list_families (PangoContext *context,
return;
}
- else if (n_maps == 1)
-
- pango_font_map_list_families (context->font_maps->data, families, n_families);
- else
- {
- GHashTable *family_hash;
- GSList *tmp_list;
- ListFamiliesInfo info;
-
- *n_families = 0;
-
- family_hash = g_hash_table_new (g_str_hash, g_str_equal);
-
- tmp_list = context->font_maps;
- while (tmp_list)
- {
- PangoFontFamily **tmp_families;
- int tmp_n_families;
- int i;
-
- pango_font_map_list_families (tmp_list->data, &tmp_families, &tmp_n_families);
-
- for (i=0; i<*n_families; i++)
- {
- const char *family = pango_font_family_get_name (tmp_families[i]);
-
- if (!g_hash_table_lookup (family_hash, tmp_families[i]))
- {
- g_hash_table_insert (family_hash, (char *)family, tmp_families[i]);
- (*n_families)++;
- }
- }
-
- g_free (tmp_families);
-
- tmp_list = tmp_list->next;
- }
-
- info.n_found = 0;
-
- if (families)
- {
- *families = g_new (PangoFontFamily *, *n_families);
- info.families = *families;
- }
- else
- info.families = NULL;
-
- g_hash_table_foreach (family_hash, list_families_foreach, &info);
- g_hash_table_destroy (family_hash);
- }
+ else
+ pango_font_map_list_families (context->font_map, families, n_families);
}
/**
@@ -281,23 +213,9 @@ PangoFont *
pango_context_load_font (PangoContext *context,
const PangoFontDescription *desc)
{
- GSList *tmp_list;
-
g_return_val_if_fail (context != NULL, NULL);
- tmp_list = context->font_maps;
- while (tmp_list)
- {
- PangoFont *font;
-
- font = pango_font_map_load_font (tmp_list->data, desc);
- if (font)
- return font;
-
- tmp_list = tmp_list->next;
- }
-
- return NULL;
+ return pango_font_map_load_font (context->font_map, desc);
}
/**
@@ -610,152 +528,6 @@ static PangoEngineShape fallback_shaper = {
fallback_engine_get_coverage
};
-/* FIXME: Remove this artificial limit */
-#define MAX_FAMILIES 16
-
-typedef struct _FontSet FontSet;
-
-struct _FontSet
-{
- int n_families;
- PangoFont *fonts[MAX_FAMILIES];
- PangoCoverage *coverages[MAX_FAMILIES];
-};
-
-#define FONT_SET_INITIALIZER { 0, }
-
-static gint
-font_set_get_font (FontSet *font_set,
- gunichar wc)
-{
- PangoCoverageLevel best_level = PANGO_COVERAGE_NONE;
-
- int result = -1;
- int i;
-
- for (i=0; i < font_set->n_families; i++)
- {
- if (font_set->fonts[i])
- {
- PangoCoverageLevel level = pango_coverage_get (font_set->coverages[i], wc);
-
- if (result == -1 || level > best_level)
- {
- result = i;
- best_level = level;
- }
- }
- }
-
- return result;
-}
-
-static void
-font_set_free (FontSet *font_set)
-{
- int j;
-
- for (j=0; j < font_set->n_families; j++)
- {
- if (font_set->fonts[j])
- {
- g_object_unref (font_set->fonts[j]);
- pango_coverage_unref (font_set->coverages[j]);
- }
- }
-
- font_set->n_families = 0;
-}
-
-static void
-font_set_load (FontSet *font_set,
- PangoContext *context,
- PangoLanguage *language,
- const PangoFontDescription *desc)
-{
- PangoFontDescription *tmp_desc = pango_font_description_copy_static (desc);
- char **families;
- int j;
-
- font_set_free (font_set);
-
- families = g_strsplit (pango_font_description_get_family (desc), ",", -1);
-
- font_set->n_families = 0;
- for (j=0; families[j] && font_set->n_families < MAX_FAMILIES; j++)
- {
- pango_font_description_set_family_static (tmp_desc, families[j]);
- font_set->fonts[font_set->n_families] = pango_context_load_font (context, tmp_desc);
-
- if (font_set->fonts[font_set->n_families])
- {
- font_set->coverages[font_set->n_families] = pango_font_get_coverage (font_set->fonts[font_set->n_families], language);
- (font_set->n_families)++;
- }
- }
-
- g_strfreev (families);
- pango_font_description_set_family_static (tmp_desc, pango_font_description_get_family (desc));
-
- /* The font description was completely unloadable, try with
- * family == "Sans"
- */
- if (font_set->n_families == 0)
- {
- char *ctmp1, *ctmp2;
-
- ctmp1 = pango_font_description_to_string (desc);
- pango_font_description_set_family_static (tmp_desc, "Sans");
- ctmp2 = pango_font_description_to_string (tmp_desc);
-
- g_warning ("Couldn't load font \"%s\" falling back to \"%s\"", ctmp1, ctmp2);
- g_free (ctmp1);
- g_free (ctmp2);
-
- font_set->fonts[0] = pango_context_load_font (context, tmp_desc);
- if (font_set->fonts[0])
- {
- font_set->coverages[0] = pango_font_get_coverage (font_set->fonts[0], language);
- font_set->n_families = 1;
- }
- }
-
- /* We couldn't try with Sans and the specified style. Try Sans Normal
- */
- if (font_set->n_families == 0)
- {
- char *ctmp1, *ctmp2;
-
- ctmp1 = pango_font_description_to_string (tmp_desc);
- pango_font_description_set_style (tmp_desc, PANGO_STYLE_NORMAL);
- pango_font_description_set_weight (tmp_desc, PANGO_WEIGHT_NORMAL);
- pango_font_description_set_variant (tmp_desc, PANGO_VARIANT_NORMAL);
- pango_font_description_set_stretch (tmp_desc, PANGO_STRETCH_NORMAL);
- ctmp2 = pango_font_description_to_string (tmp_desc);
-
- g_warning ("Couldn't load font \"%s\" falling back to \"%s\"", ctmp1, ctmp2);
- g_free (ctmp1);
- g_free (ctmp2);
-
- font_set->fonts[0] = pango_context_load_font (context, tmp_desc);
- if (font_set->fonts[0])
- {
- font_set->coverages[0] = pango_font_get_coverage (font_set->fonts[0], language);
- font_set->n_families = 1;
- }
- }
-
- /* Everything failed, we are screwed, there is no way to continue
- */
- if (font_set->n_families == 0)
- {
- g_warning ("All font failbacks failed!!!!");
- exit (1);
- }
-
- pango_font_description_free (tmp_desc);
-}
-
static gboolean
advance_iterator_to (PangoAttrIterator *iterator,
int start_index)
@@ -794,12 +566,11 @@ add_engines (PangoContext *context,
GSList *extra_attrs = NULL;
PangoMap *lang_map = NULL;
PangoFontDescription *current_desc = NULL;
- FontSet current_fonts = FONT_SET_INITIALIZER;
+ PangoFontset *current_fonts = NULL;
PangoAttrIterator *iterator;
gboolean first_iteration = TRUE;
gunichar wc;
int i = 0;
- int font_index;
if (cached_iter)
iterator = cached_iter;
@@ -858,7 +629,12 @@ add_engines (PangoContext *context,
pango_font_description_free (current_desc);
current_desc = next_desc;
- font_set_load (&current_fonts, context, language, current_desc);
+ if (current_fonts)
+ g_object_unref (current_fonts);
+
+ current_fonts = pango_font_map_load_fontset (context->font_map,
+ current_desc,
+ language);
}
else
pango_font_description_free (next_desc);
@@ -868,14 +644,7 @@ add_engines (PangoContext *context,
pos = g_utf8_next_char (pos);
analysis->lang_engine = (PangoEngineLang *)pango_map_get_engine (lang_map, wc);
- font_index = font_set_get_font (&current_fonts, wc);
- if (font_index != -1)
- {
- analysis->font = current_fonts.fonts[font_index];
- g_object_ref (analysis->font);
- }
- else
- analysis->font = NULL;
+ analysis->font = pango_fontset_get_font (current_fonts, wc);
analysis->language = language;
/* FIXME: handle reference counting properly on the shapers */
@@ -894,7 +663,8 @@ add_engines (PangoContext *context,
if (current_desc)
pango_font_description_free (current_desc);
- font_set_free (&current_fonts);
+ if (current_fonts)
+ g_object_unref (current_fonts);
if (iterator != cached_iter)
pango_attr_iterator_destroy (iterator);
@@ -929,62 +699,17 @@ pango_context_get_metrics (PangoContext *context,
const PangoFontDescription *desc,
PangoLanguage *language)
{
- FontSet current_fonts = FONT_SET_INITIALIZER;
- PangoFontMetrics *raw_metrics[MAX_FAMILIES];
+ PangoFontset *current_fonts = NULL;
PangoFontMetrics *metrics;
- const char *sample_str;
- const char *p;
- int i;
g_return_val_if_fail (PANGO_IS_CONTEXT (context), NULL);
g_return_val_if_fail (desc != NULL, NULL);
- sample_str = pango_language_get_sample_string (language);
+ current_fonts = pango_font_map_load_fontset (context->font_map, desc, language);
- font_set_load (&current_fonts, context, language, desc);
-
- if (current_fonts.n_families == 1)
- metrics = pango_font_get_metrics (current_fonts.fonts[0], language);
- else
- {
- int count = 0;
-
- metrics = pango_font_metrics_new ();
-
- for (i=0; i < MAX_FAMILIES; i++)
- raw_metrics[i] = NULL;
+ metrics = pango_fontset_get_metrics (current_fonts);
- p = sample_str;
- while (*p)
- {
- gunichar wc = g_utf8_get_char (p);
- int index = font_set_get_font (&current_fonts, wc);
- if (!raw_metrics[index])
- raw_metrics[index] = pango_font_get_metrics (current_fonts.fonts[index], language);
-
- if (count == 0)
- *metrics = *raw_metrics[index];
- else
- {
- metrics->ascent = MAX (metrics->ascent, raw_metrics[index]->ascent);
- metrics->descent = MAX (metrics->descent, raw_metrics[index]->descent);
- metrics->approximate_char_width += raw_metrics[index]->approximate_char_width;
- metrics->approximate_digit_width += raw_metrics[index]->approximate_digit_width;
- }
-
- p = g_utf8_next_char (p);
- count++;
- }
-
- for (i=0; i < MAX_FAMILIES; i++)
- if (raw_metrics[i])
- pango_font_metrics_unref (raw_metrics[i]);
-
- metrics->approximate_char_width /= count;
- metrics->approximate_digit_width /= count;
- }
-
- font_set_free (&current_fonts);
+ g_object_unref (current_fonts);
return metrics;
}
diff --git a/pango/pango-context.h b/pango/pango-context.h
index b9b6be24..c72cf992 100644
--- a/pango/pango-context.h
+++ b/pango/pango-context.h
@@ -50,7 +50,7 @@ GType pango_context_get_type (void) G_GNUC_CONST;
#ifdef PANGO_ENABLE_BACKEND
PangoContext *pango_context_new (void);
-void pango_context_add_font_map (PangoContext *context,
+void pango_context_set_font_map (PangoContext *context,
PangoFontMap *font_map);
#endif /* PANGO_ENABLE_BACKEND */
diff --git a/pango/pango-fontmap.c b/pango/pango-fontmap.c
index 7cb27ba3..5f678979 100644
--- a/pango/pango-fontmap.c
+++ b/pango/pango-fontmap.c
@@ -20,6 +20,14 @@
*/
#include "pango-fontmap.h"
+#include "pango-utils.h"
+#include <stdlib.h>
+
+static void pango_font_map_class_init (PangoFontMapClass *class);
+static PangoFontset *pango_font_map_real_load_fontset (PangoFontMap *fontmap,
+ const PangoFontDescription *desc,
+ PangoLanguage *language);
+
GType
pango_font_map_get_type (void)
@@ -33,7 +41,7 @@ pango_font_map_get_type (void)
sizeof (PangoFontMapClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
- NULL, /* class_init */
+ (GClassInitFunc) pango_font_map_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (PangoFontMap),
@@ -49,6 +57,13 @@ pango_font_map_get_type (void)
return object_type;
}
+
+static void
+pango_font_map_class_init (PangoFontMapClass *class)
+{
+ class->load_fontset = pango_font_map_real_load_fontset;
+}
+
/**
* pango_font_map_load_font:
* @fontmap: a #PangoFontMap
@@ -85,3 +100,139 @@ pango_font_map_list_families (PangoFontMap *fontmap,
PANGO_FONT_MAP_GET_CLASS (fontmap)->list_families (fontmap, families, n_families);
}
+
+/**
+ * pango_font_map_load_fontset:
+ * @fontmap: a #PangoFontMap
+ * @desc: a #PangoFontDescription describing the font to load
+ * @language: a #PangoLanguage the fonts will be used for
+ *
+ * Load a set of fonts in the fontmap that can be used to render
+ * a font matching @desc.
+ *
+ * Returns the fontset, or %NULL if no font matched.
+ **/
+PangoFontset *
+pango_font_map_load_fontset (PangoFontMap *fontmap,
+ const PangoFontDescription *desc,
+ PangoLanguage *language)
+{
+ g_return_val_if_fail (fontmap != NULL, 0);
+
+ return PANGO_FONT_MAP_GET_CLASS (fontmap)->load_fontset (fontmap, desc, language);
+}
+
+static void
+pango_font_map_fontset_add_fonts (PangoFontMap *fontmap,
+ PangoFontsetSimple *fonts,
+ PangoFontDescription *desc,
+ char *family)
+{
+ char **aliases;
+ int n_aliases;
+ int j;
+ PangoFont *font;
+
+ pango_lookup_aliases (family,
+ &aliases,
+ &n_aliases);
+
+ if (n_aliases)
+ {
+ for (j = 0; j < n_aliases; j++)
+ {
+ pango_font_description_set_family_static (desc, aliases[j]);
+ font = pango_font_map_load_font (fontmap, desc);
+ if (font)
+ pango_fontset_simple_append (fonts, font);
+ }
+ }
+ else
+ {
+ pango_font_description_set_family_static (desc, family);
+ font = pango_font_map_load_font (fontmap, desc);
+ if (font)
+ pango_fontset_simple_append (fonts, font);
+ }
+}
+
+static PangoFontset *
+pango_font_map_real_load_fontset (PangoFontMap *fontmap,
+ const PangoFontDescription *desc,
+ PangoLanguage *language)
+{
+ PangoFontDescription *tmp_desc = pango_font_description_copy_static (desc);
+ char **families;
+ int i;
+ PangoFontsetSimple *fonts;
+
+ families = g_strsplit (pango_font_description_get_family (desc), ",", -1);
+
+ fonts = pango_fontset_simple_new (language);
+
+ for (i = 0; families[i]; i++)
+ pango_font_map_fontset_add_fonts (fontmap,
+ fonts,
+ tmp_desc,
+ families[i]);
+
+ g_strfreev (families);
+
+ /* The font description was completely unloadable, try with
+ * family == "Sans"
+ */
+ if (pango_fontset_simple_size (fonts) == 0)
+ {
+ char *ctmp1, *ctmp2;
+
+ pango_font_description_set_family_static (tmp_desc,
+ pango_font_description_get_family (desc));
+
+ ctmp1 = pango_font_description_to_string (desc);
+ pango_font_description_set_family_static (tmp_desc, "Sans");
+ ctmp2 = pango_font_description_to_string (tmp_desc);
+
+ g_warning ("Couldn't load font \"%s\" falling back to \"%s\"", ctmp1, ctmp2);
+ g_free (ctmp1);
+ g_free (ctmp2);
+
+ pango_font_map_fontset_add_fonts (fontmap,
+ fonts,
+ tmp_desc,
+ "Sans");
+ }
+
+ /* We couldn't try with Sans and the specified style. Try Sans Normal
+ */
+ if (pango_fontset_simple_size (fonts) == 0)
+ {
+ char *ctmp1, *ctmp2;
+
+ pango_font_description_set_family_static (tmp_desc, "Sans");
+ ctmp1 = pango_font_description_to_string (tmp_desc);
+ pango_font_description_set_style (tmp_desc, PANGO_STYLE_NORMAL);
+ pango_font_description_set_weight (tmp_desc, PANGO_WEIGHT_NORMAL);
+ pango_font_description_set_variant (tmp_desc, PANGO_VARIANT_NORMAL);
+ pango_font_description_set_stretch (tmp_desc, PANGO_STRETCH_NORMAL);
+ ctmp2 = pango_font_description_to_string (tmp_desc);
+
+ g_warning ("Couldn't load font \"%s\" falling back to \"%s\"", ctmp1, ctmp2);
+ g_free (ctmp1);
+ g_free (ctmp2);
+
+ pango_font_map_fontset_add_fonts (fontmap,
+ fonts,
+ tmp_desc,
+ "Sans");
+ }
+
+ /* Everything failed, we are screwed, there is no way to continue
+ */
+ if (pango_fontset_simple_size (fonts) == 0)
+ {
+ g_warning ("All font failbacks failed!!!!");
+ exit (1);
+ }
+
+ return PANGO_FONTSET (fonts);
+}
diff --git a/pango/pango-fontmap.h b/pango/pango-fontmap.h
index eaf960f5..adc4920a 100644
--- a/pango/pango-fontmap.h
+++ b/pango/pango-fontmap.h
@@ -23,6 +23,7 @@
#define __PANGO_FONTMAP_H__
#include <pango/pango-font.h>
+#include <pango/pango-fontset.h>
G_BEGIN_DECLS
@@ -32,12 +33,16 @@ G_BEGIN_DECLS
typedef struct _PangoFontMap PangoFontMap;
-GType pango_font_map_get_type (void) G_GNUC_CONST;
-PangoFont *pango_font_map_load_font (PangoFontMap *fontmap,
- const PangoFontDescription *desc);
-void pango_font_map_list_families (PangoFontMap *fontmap,
- PangoFontFamily ***families,
- int *n_families);
+GType pango_font_map_get_type (void) G_GNUC_CONST;
+PangoFont * pango_font_map_load_font (PangoFontMap *fontmap,
+ const PangoFontDescription *desc);
+PangoFontset *pango_font_map_load_fontset (PangoFontMap *fontmap,
+ const PangoFontDescription *desc,
+ PangoLanguage *language);
+void pango_font_map_list_families (PangoFontMap *fontmap,
+ PangoFontFamily ***families,
+ int *n_families);
+
#ifdef PANGO_ENABLE_BACKEND
@@ -56,11 +61,14 @@ struct _PangoFontMapClass
{
GObjectClass parent_class;
- PangoFont *(*load_font) (PangoFontMap *fontmap,
- const PangoFontDescription *desc);
- void (*list_families) (PangoFontMap *fontmap,
- PangoFontFamily ***families,
- int *n_families);
+ PangoFont * (*load_font) (PangoFontMap *fontmap,
+ const PangoFontDescription *desc);
+ void (*list_families) (PangoFontMap *fontmap,
+ PangoFontFamily ***families,
+ int *n_families);
+ PangoFontset *(*load_fontset) (PangoFontMap *fontmap,
+ const PangoFontDescription *desc,
+ PangoLanguage *language);
};
#endif /* PANGO_ENABLE_BACKEND */
diff --git a/pango/pango-utils.c b/pango/pango-utils.c
index 866acd7b..1d81ee7f 100644
--- a/pango/pango-utils.c
+++ b/pango/pango-utils.c
@@ -48,6 +48,16 @@
#endif
+struct PangoAlias
+{
+ char *alias;
+ int n_families;
+ char **families;
+ gboolean visible; /* Do we want/need this? */
+};
+
+GHashTable *pango_aliases_ht = NULL;
+
/**
* pango_trim_string:
* @str: a string
@@ -557,7 +567,7 @@ read_config_file (const char *filename, gboolean enoent_error)
}
if (ferror (file))
- errstring = g_strdup ("g_strerror(errno)");
+ errstring = g_strdup (g_strerror(errno));
error:
@@ -1250,3 +1260,235 @@ pango_get_mirror_char (gunichar ch,
}
#endif /* HAVE_FRIBIDI */
+
+
+guint
+alias_hash (struct PangoAlias *alias)
+{
+ return g_str_hash (alias->alias);
+}
+
+gboolean
+alias_equal (struct PangoAlias *alias1,
+ struct PangoAlias *alias2)
+{
+ return g_str_equal (alias1->alias,
+ alias2->alias);
+}
+
+
+void
+alias_free (struct PangoAlias *alias)
+{
+ int i;
+ g_free (alias->alias);
+
+ for (i = 0; i < alias->n_families; i++)
+ g_free (alias->families[i]);
+
+ g_free (alias->families);
+
+ g_free (alias);
+}
+
+static void
+read_alias_file (const char *filename)
+{
+ FILE *file;
+
+ GString *line_buffer;
+ GString *tmp_buffer1;
+ GString *tmp_buffer2;
+ char *errstring = NULL;
+ const char *pos;
+ int line = 0;
+ struct PangoAlias alias_key;
+ struct PangoAlias *alias;
+ char **new_families;
+ int n_new;
+ int i;
+
+ file = fopen (filename, "r");
+ if (!file)
+ return;
+
+ line_buffer = g_string_new (NULL);
+ tmp_buffer1 = g_string_new (NULL);
+ tmp_buffer2 = g_string_new (NULL);
+
+ while (pango_read_line (file, line_buffer))
+ {
+ gboolean empty = FALSE;
+ gboolean append = FALSE;
+ line++;
+
+ pos = line_buffer->str;
+ if (!pango_skip_space (&pos))
+ continue;
+
+ if (!pango_scan_word (&pos, tmp_buffer1) ||
+ !pango_skip_space (&pos))
+ {
+ errstring = g_strdup ("Line is not of the form KEY=VALUE or KEY+=VALUE");
+ goto error;
+ }
+
+ if (*pos == '+')
+ {
+ append = TRUE;
+ pos++;
+ }
+
+ if (*(pos++) != '=')
+ {
+ errstring = g_strdup ("Line is not of the form KEY=VALUE or KEY+=VALUE");
+ goto error;
+ }
+
+ if (!pango_skip_space (&pos))
+ {
+ empty = TRUE;
+ }
+ else
+ {
+ if (!pango_scan_string (&pos, tmp_buffer2))
+ {
+ errstring = g_strdup ("Error parsing value string");
+ goto error;
+ }
+ if (pango_skip_space (&pos))
+ {
+ errstring = g_strdup ("Junk after value string");
+ goto error;
+ }
+ }
+
+ alias_key.alias = g_ascii_strdown (tmp_buffer1->str, -1);
+
+ /* Remove any existing values */
+ alias = g_hash_table_lookup (pango_aliases_ht, &alias_key);
+
+ if (!alias)
+ {
+ alias = g_new0 (struct PangoAlias, 1);
+ alias->alias = alias_key.alias;
+
+ g_hash_table_insert (pango_aliases_ht,
+ alias, alias);
+ }
+ else
+ g_free (alias_key.alias);
+
+ new_families = g_strsplit (tmp_buffer2->str, ",", -1);
+
+ n_new = 0;
+ while (new_families[n_new])
+ n_new++;
+
+ if (alias->families && append)
+ {
+ alias->families = g_realloc (alias->families,
+ sizeof (char *) *(n_new + alias->n_families));
+ for (i = 0; i < n_new; i++)
+ alias->families[alias->n_families + i] = new_families[i];
+ g_free (new_families);
+ alias->n_families += n_new;
+ }
+ else
+ {
+ for (i = 0; i < alias->n_families; i++)
+ g_free (alias->families[i]);
+ g_free (alias->families);
+
+ alias->families = new_families;
+ alias->n_families = n_new;
+ }
+ }
+
+ if (ferror (file))
+ errstring = g_strdup (g_strerror(errno));
+
+ error:
+
+ if (errstring)
+ {
+ fprintf (stderr, "Pango:%s:%d: %s\n", filename, line, errstring);
+ g_free (errstring);
+ }
+
+ g_string_free (line_buffer, TRUE);
+ g_string_free (tmp_buffer1, TRUE);
+ g_string_free (tmp_buffer2, TRUE);
+
+ fclose (file);
+}
+
+void
+pango_load_aliases (void)
+{
+ char *filename;
+ const char *home;
+
+ pango_aliases_ht = g_hash_table_new_full ((GHashFunc)alias_hash,
+ (GEqualFunc)alias_equal,
+ (GDestroyNotify)alias_free,
+ NULL);
+
+
+ filename = g_strconcat (pango_get_sysconf_subdirectory (),
+ G_DIR_SEPARATOR_S "pango.aliases",
+ NULL);
+ read_alias_file (filename);
+ g_free (filename);
+
+ home = g_get_home_dir ();
+ if (home && *home)
+ {
+ filename = g_strconcat (home,
+ G_DIR_SEPARATOR_S ".pango.aliases",
+ NULL);
+ read_alias_file (filename);
+ g_free (filename);
+ }
+}
+
+
+/**
+ * pango_lookup_aliases:
+ * @fontname: an ascii string
+ * @families: will be set to an array of font family names.
+ * this array is owned by pango and should not be freed.
+ *
+ * Look up all user defined aliases for the alias #fontname.
+ * The resulting font family names will be stored in #families,
+ * and the number of families will be returned.
+ *
+ * Return value: the number of font famillies stored in the #families argument.
+ * This value is owned by Pango and must not be freed.
+ **/
+void
+pango_lookup_aliases (const char *fontname,
+ char ***families,
+ int *n_families)
+{
+ struct PangoAlias alias_key;
+ struct PangoAlias *alias;
+
+ if (pango_aliases_ht == NULL)
+ pango_load_aliases ();
+
+ alias_key.alias = g_ascii_strdown (fontname, -1);
+ alias = g_hash_table_lookup (pango_aliases_ht, &alias_key);
+ g_free (alias_key.alias);
+
+ if (alias)
+ {
+ *families = alias->families;
+ *n_families = alias->n_families;
+ }
+ else
+ {
+ *families = NULL;
+ *n_families = 0;
+ }
+}
diff --git a/pango/pango-utils.h b/pango/pango-utils.h
index 7cb1df16..64b96eea 100644
--- a/pango/pango-utils.h
+++ b/pango/pango-utils.h
@@ -38,6 +38,9 @@ gboolean pango_scan_int (const char **pos,
#ifdef PANGO_ENABLE_BACKEND
char * pango_config_key_get (const char *key);
+void pango_lookup_aliases (const char *fontname,
+ char ***families,
+ int *n_families);
#endif /* PANGO_ENABLE_BACKEND */
/* Functions for parsing textual representations
diff --git a/pango/pangoft2-fontcache.c b/pango/pangoft2-fontcache.c
deleted file mode 100644
index 4ae5958c..00000000
--- a/pango/pangoft2-fontcache.c
+++ /dev/null
@@ -1,310 +0,0 @@
-/* Pango
- * pangoft2-fontcache.c: Cache of FreeType2 faces (FT_Face)
- *
- * Copyright (C) 2000 Red Hat Software
- * Copyright (C) 2000 Tor Lillqvist
- *
- * 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 "pangoft2-private.h"
-
-#include <string.h>
-
-/* Font cache
- */
-
-/* Number of fonts to retain after they are not otherwise referenced.
- */
-#define CACHE_SIZE 10
-
-typedef struct _CacheEntry CacheEntry;
-
-struct _PangoFT2FontCache
-{
- FT_Library library;
-
- GHashTable *forward;
- GHashTable *back;
-
- GList *mru;
- GList *mru_tail;
- int mru_count;
-};
-
-struct _CacheEntry
-{
- PangoFT2OA oa;
- FT_Face face;
-
- gint ref_count;
- GList *mru;
-};
-
-static void
-free_cache_entry (PangoFT2OA *oa,
- CacheEntry *entry,
- PangoFT2FontCache *cache)
-{
- FT_Error error;
-
- PING (("FT_Done_Face (%p)", entry->face));
-
- error = FT_Done_Face (entry->face);
- if (error != FT_Err_Ok)
- g_warning ("Error from FT_Done_Face: %s",
- pango_ft2_ft_strerror (error));
-
- g_free (entry);
-}
-
-/**
- * pango_ft2_font_cache_free:
- * @cache: a #PangoFT2FontCache
- *
- * Free a #PangoFT2FontCache and all associated memory. All fonts loaded
- * through this font cache will be freed along with the cache.
- **/
-void
-pango_ft2_font_cache_free (PangoFT2FontCache *cache)
-{
- g_return_if_fail (cache != NULL);
-
- g_hash_table_foreach (cache->forward, (GHFunc)free_cache_entry, cache);
-
- g_hash_table_destroy (cache->forward);
- g_hash_table_destroy (cache->back);
-
- g_list_free (cache->mru);
-}
-
-static guint
-oa_hash (gconstpointer v)
-{
- PangoFT2OA *oa = (PangoFT2OA *) v;
-
- if (oa->open_args->flags & ft_open_memory)
- return (guint) oa->open_args->memory_base;
- else if (oa->open_args->flags == ft_open_pathname)
- return g_str_hash (oa->open_args->pathname);
- else if (oa->open_args->flags & ft_open_stream)
- return (guint) oa->open_args->stream;
- else
- return 0;
-}
-
-static gint
-oa_equal (gconstpointer v1,
- gconstpointer v2)
-{
- PangoFT2OA *oa1 = (PangoFT2OA *) v1;
- PangoFT2OA *oa2 = (PangoFT2OA *) v2;
-
- if (oa1->open_args->flags != oa2->open_args->flags)
- return 0;
- else if (oa1->open_args->flags & ft_open_memory)
- return (oa1->open_args->memory_base == oa2->open_args->memory_base &&
- oa1->face_index == oa2->face_index);
- else if (oa1->open_args->flags == ft_open_pathname)
- return (strcmp (oa1->open_args->pathname,
- oa2->open_args->pathname) == 0 &&
- oa1->face_index == oa2->face_index);
- else if (oa1->open_args->flags & ft_open_stream)
- return (oa1->open_args->stream == oa2->open_args->stream &&
- oa1->face_index == oa2->face_index);
- else
- return 0;
-}
-
-/**
- * pango_ft2_font_cache_new:
- * @library:
- *
- * Create a font cache.
- *
- * Return value: The new font cache. This must be freed with
- * pango_ft2_font_cache_free().
- **/
-PangoFT2FontCache *
-pango_ft2_font_cache_new (FT_Library library)
-{
- PangoFT2FontCache *cache;
-
- cache = g_new (PangoFT2FontCache, 1);
-
- cache->library = library;
-
- cache->forward = g_hash_table_new (oa_hash, oa_equal);
- cache->back = g_hash_table_new (g_direct_hash, g_direct_equal);
-
- cache->mru = NULL;
- cache->mru_tail = NULL;
- cache->mru_count = 0;
-
- return cache;
-}
-
-static void
-cache_entry_unref (PangoFT2FontCache *cache,
- CacheEntry *entry)
-{
- entry->ref_count--;
- PING (("face:%p ref_count:%d", entry->face, entry->ref_count));
- if (entry->ref_count == 0)
- {
- g_hash_table_remove (cache->forward, &entry->oa);
- g_hash_table_remove (cache->back, entry->face);
-
- free_cache_entry (NULL, entry, cache);
- }
-}
-
-/**
- * pango_ft2_font_cache_load:
- * @cache: a #PangoFT2FontCache
- * @args:
- * @face_index:
- *
- * Load a #FT_Face from #FT_Open_Args and a face index. The
- * result may be newly loaded, or it may have been previously
- * stored
- *
- * Return value: The #FT_Face, or %NULL if the font could
- * not be loaded. In order to free this structure, you must call
- * pango_ft2_font_cache_unload().
- **/
-FT_Face
-pango_ft2_font_cache_load (PangoFT2FontCache *cache,
- FT_Open_Args *args,
- FT_Long face_index)
-{
- CacheEntry *entry;
- PangoFT2OA oa;
-
- g_return_val_if_fail (cache != NULL, NULL);
- g_return_val_if_fail (args != NULL, NULL);
-
- oa.open_args = args;
- oa.face_index = face_index;
-
- entry = g_hash_table_lookup (cache->forward, &oa);
-
- if (entry)
- entry->ref_count++;
- else
- {
- FT_Face face;
- FT_Error error;
-
- PING (("FT_Open_Face (%s,%ld)", args->pathname, face_index));
-
- error = FT_Open_Face (cache->library, args, face_index, &face);
- if (error != FT_Err_Ok)
- {
- g_warning ("Error from FT_Open_Face: %s",
- pango_ft2_ft_strerror (error));
- return NULL;
- }
-
- face->generic.data = 0;
- PING ((" = %p", face));
-
- entry = g_new (CacheEntry, 1);
-
- entry->oa = oa;
- entry->face = face;
-
- entry->ref_count = 1;
- entry->mru = NULL;
-
- g_hash_table_insert (cache->forward, &entry->oa, entry);
- g_hash_table_insert (cache->back, entry->face, entry);
- }
-
- if (entry->mru)
- {
- if (cache->mru_count > 1 && entry->mru->prev)
- {
- /* Move to the head of the mru list */
-
- if (entry->mru == cache->mru_tail)
- {
- cache->mru_tail = cache->mru_tail->prev;
- cache->mru_tail->next = NULL;
- }
- else
- {
- entry->mru->prev->next = entry->mru->next;
- entry->mru->next->prev = entry->mru->prev;
- }
-
- entry->mru->next = cache->mru;
- entry->mru->prev = NULL;
- cache->mru->prev = entry->mru;
- cache->mru = entry->mru;
- }
- }
- else
- {
- entry->ref_count++;
-
- /* Insert into the mru list */
-
- if (cache->mru_count == CACHE_SIZE)
- {
- CacheEntry *old_entry = cache->mru_tail->data;
-
- cache->mru_tail = cache->mru_tail->prev;
- cache->mru_tail->next = NULL;
-
- g_list_free_1 (old_entry->mru);
- old_entry->mru = NULL;
- cache_entry_unref (cache, old_entry);
- }
- else
- cache->mru_count++;
-
- cache->mru = g_list_prepend (cache->mru, entry);
- if (!cache->mru_tail)
- cache->mru_tail = cache->mru;
- entry->mru = cache->mru;
- }
-
- return entry->face;
-}
-
-/**
- * pango_ft2_font_cache_unload:
- * @cache: a #PangoFT2FontCache
- * @face: the face to unload
- *
- * Free a font structure previously loaded with pango_ft2_font_cache_load()
- **/
-void
-pango_ft2_font_cache_unload (PangoFT2FontCache *cache,
- FT_Face face)
-{
- CacheEntry *entry;
-
- g_return_if_fail (cache != NULL);
- g_return_if_fail (face != NULL);
-
- entry = g_hash_table_lookup (cache->back, face);
- g_return_if_fail (entry != NULL);
-
- PING (("pango_ft2_font_cache_unload"));
- cache_entry_unref (cache, entry);
-}
diff --git a/pango/pangoft2-fontmap.c b/pango/pangoft2-fontmap.c
index 6690da38..51039df5 100644
--- a/pango/pangoft2-fontmap.c
+++ b/pango/pangoft2-fontmap.c
@@ -36,6 +36,8 @@
#include "pango-utils.h"
#include "pangoft2-private.h"
+#include "mini-xft/MiniXftFreetype.h"
+
#ifdef G_OS_WIN32
#define STRICT
#include <windows.h>
@@ -45,41 +47,46 @@
#define PANGO_FT2_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_FT2_FONT_MAP, PangoFT2FontMap))
#define PANGO_FT2_IS_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_FT2_FONT_MAP))
-typedef struct _PangoFT2Family PangoFT2Family;
typedef struct _PangoFT2FontMap PangoFT2FontMap;
typedef struct _PangoFT2SizeInfo PangoFT2SizeInfo;
+typedef struct _PangoFT2PatternSet PangoFT2PatternSet;
/* Number of freed fonts */
#define MAX_FREED_FONTS 16
+struct _PangoFT2Family
+{
+ PangoFontFamily parent_instance;
+
+ PangoFT2FontMap *fontmap;
+ char *family_name;
+
+ PangoFT2Face **faces;
+ int n_faces; /* -1 == uninitialized */
+};
+
+
struct _PangoFT2FontMap
{
PangoFontMap parent_instance;
FT_Library library;
- PangoFT2FontCache *font_cache;
- GQueue *freed_fonts;
-
- /* Maps Pango family names to PangoFT2FamilyEntry structs */
- GHashTable *families;
-
- /* Maps the family and style of a face to a PangoFT2OA struct */
- GHashTable *faces;
+ GHashTable *fontset_hash; /* Maps PangoFontDescription -> PangoXftFontSet */
+ GHashTable *coverage_hash; /* Maps font file name -> PangoCoverage */
- int n_fonts;
+ GHashTable *fonts; /* Maps XftPattern -> PangoFT2Font */
+ GQueue *freed_fonts; /* Fonts in fonts that has been freed */
- double resolution; /* (points / pixel) * PANGO_SCALE */
+ /* List of all families availible */
+ PangoFT2Family **families;
+ int n_families; /* -1 == uninitialized */
};
-struct _PangoFT2Family
+struct _PangoFT2PatternSet
{
- PangoFontFamily parent_instance;
-
- char *family_name;
-
- /* List of PangoFT2FontEntry structs */
- GSList *font_entries;
+ int n_patterns;
+ MiniXftPattern **patterns;
};
#define PANGO_FT2_TYPE_FAMILY (pango_ft2_family_get_type ())
@@ -94,32 +101,27 @@ static GType pango_ft2_font_map_get_type (void);
GType pango_ft2_family_get_type (void);
GType pango_ft2_face_get_type (void);
-static void pango_ft2_font_map_init (PangoFT2FontMap *fontmap);
-
-static void pango_ft2_font_map_class_init (PangoFontMapClass *class);
+static void pango_ft2_font_map_init (PangoFT2FontMap *fontmap);
+static void pango_ft2_font_map_class_init (PangoFontMapClass *class);
+static void pango_ft2_font_map_finalize (GObject *object);
+static PangoFont * pango_ft2_font_map_load_font (PangoFontMap *fontmap,
+ const PangoFontDescription *description);
+static PangoFontset *pango_ft2_font_map_load_fontset (PangoFontMap *fontmap,
+ const PangoFontDescription *desc,
+ PangoLanguage *language);
+static void pango_ft2_font_set_free (PangoFT2PatternSet *font_set);
+static void pango_ft2_font_map_list_families (PangoFontMap *fontmap,
+ PangoFontFamily ***families,
+ int *n_families);
+static void pango_ft2_font_map_cache_remove (PangoFontMap *fontmap,
+ PangoFT2Font *ft2font);
+static void pango_ft2_font_map_cache_clear (PangoFT2FontMap *ft2fontmap);
-static void pango_ft2_font_map_finalize (GObject *object);
-static PangoFont *pango_ft2_font_map_load_font (PangoFontMap *fontmap,
- const PangoFontDescription *description);
-
-static void pango_ft2_font_map_list_families (PangoFontMap *fontmap,
- PangoFontFamily ***families,
- int *n_families);
-
-static void pango_ft2_fontmap_cache_clear (PangoFT2FontMap *ft2fontmap);
-
-static void pango_ft2_font_map_read_aliases (PangoFT2FontMap *ft2fontmap);
-
-static void pango_ft2_insert_face (PangoFT2FontMap *fontmap,
- FT_Face face,
- const char *path,
- int face_index);
static PangoFontClass *parent_class; /* Parent class structure for PangoFT2FontMap */
static PangoFT2FontMap *pango_ft2_global_fontmap = NULL;
-static char **pango_ft2_font_directories = NULL;
static GType
pango_ft2_font_map_get_type (void)
@@ -149,131 +151,135 @@ pango_ft2_font_map_get_type (void)
return object_type;
}
-static void
-pango_ft2_font_map_init (PangoFT2FontMap *ft2fontmap)
+static void
+pango_ft2_font_set_free (PangoFT2PatternSet *font_set)
{
- ft2fontmap->families = g_hash_table_new (g_str_hash, g_str_equal);
- ft2fontmap->faces = g_hash_table_new ((GHashFunc)pango_font_description_hash,
- (GEqualFunc)pango_font_description_equal);
- ft2fontmap->n_fonts = 0;
+ int i;
+
+ for (i = 0; i < font_set->n_patterns; i++)
+ MiniXftPatternDestroy (font_set->patterns[i]);
+
+ g_free (font_set);
}
-static void
-pango_ft2_font_map_class_init (PangoFontMapClass *class)
+static guint
+pango_ft2_pattern_hash (MiniXftPattern *pattern)
{
- GObjectClass *object_class = G_OBJECT_CLASS (class);
- char *font_path;
-
- parent_class = g_type_class_peek_parent (class);
+ char *str;
+ int i;
+ double d;
+ guint hash = 0;
- object_class->finalize = pango_ft2_font_map_finalize;
- class->load_font = pango_ft2_font_map_load_font;
- class->list_families = pango_ft2_font_map_list_families;
+ MiniXftPatternGetString (pattern, XFT_FILE, 0, &str);
+ if (str)
+ hash = g_str_hash (str);
- font_path = pango_config_key_get ("PangoFT2/FontPath");
+ if (MiniXftPatternGetInteger (pattern, XFT_INDEX, 0, &i) == MiniXftResultMatch)
+ hash ^= i;
- if (!font_path)
- {
- font_path = g_build_filename (pango_get_lib_subdirectory (),
- "ft2fonts",
- NULL);
+ if (MiniXftPatternGetDouble (pattern, XFT_PIXEL_SIZE, 0, &d) == MiniXftResultMatch)
+ hash ^= (guint) (d*1000.0);
-#ifdef G_OS_WIN32
- {
- char win_dir[100];
- char *tmp_str;
-
- GetWindowsDirectory (win_dir, sizeof (win_dir));
- tmp_str = g_build_filename (font_path,
- win_dir,
- "fonts",
- NULL);
- g_free (font_path);
- font_path = tmp_str;
- }
-#endif
- }
-
- pango_ft2_font_directories = pango_split_file_list (font_path);
- g_free (font_path);
+ return hash;
}
static gboolean
-pango_ft2_is_font_file (const char *name)
-{
- int len;
+pango_ft2_pattern_equal (MiniXftPattern *pattern1,
+ MiniXftPattern *pattern2)
+{
+ char *file1, *file2;
+ int index1, index2;
+ double size1, size2;
+ MiniXftResult res1, res2;
+ int int1, int2;
+ Bool bool1, bool2;
+
+ MiniXftPatternGetString (pattern1, XFT_FILE, 0, &file1);
+ MiniXftPatternGetString (pattern2, XFT_FILE, 0, &file2);
- len = strlen (name);
- if (len > 4 &&
- (g_ascii_strncasecmp (&name[len-4], ".pfa", 4) == 0 ||
- g_ascii_strncasecmp (&name[len-4], ".pfb", 4) == 0 ||
- g_ascii_strncasecmp (&name[len-4], ".ttf", 4) == 0 ||
- g_ascii_strncasecmp (&name[len-4], ".ttc", 4) == 0))
- return TRUE;
+ g_assert (file1 != NULL && file2 != NULL);
- return FALSE;
+ if (strcmp (file1, file2) != 0)
+ return FALSE;
+
+ if (MiniXftPatternGetInteger (pattern1, XFT_INDEX, 0, &index1) != MiniXftResultMatch)
+ return FALSE;
+
+ if (MiniXftPatternGetInteger (pattern2, XFT_INDEX, 0, &index2) != MiniXftResultMatch)
+ return FALSE;
+
+ if (index1 != index2)
+ return FALSE;
+
+ if (MiniXftPatternGetDouble (pattern1, XFT_PIXEL_SIZE, 0, &size1) != MiniXftResultMatch)
+ return FALSE;
+
+ if (MiniXftPatternGetDouble (pattern2, XFT_PIXEL_SIZE, 0, &size2) != MiniXftResultMatch)
+ return FALSE;
+
+ if (size1 != size2)
+ return FALSE;
+
+ res1 = MiniXftPatternGetInteger (pattern1, XFT_RGBA, 0, &int1);
+ res2 = MiniXftPatternGetInteger (pattern2, XFT_RGBA, 0, &int2);
+ if (res1 != res2 || (res1 == MiniXftResultMatch && int1 != int2))
+ return FALSE;
+
+ res1 = MiniXftPatternGetBool (pattern1, XFT_ANTIALIAS, 0, &bool1);
+ res2 = MiniXftPatternGetBool (pattern2, XFT_ANTIALIAS, 0, &bool2);
+ if (res1 != res2 || (res1 == MiniXftResultMatch && bool1 != bool2))
+ return FALSE;
+
+ res1 = MiniXftPatternGetBool (pattern1, XFT_MINSPACE, 0, &bool1);
+ res2 = MiniXftPatternGetBool (pattern2, XFT_MINSPACE, 0, &bool2);
+ if (res1 != res2 || (res1 == MiniXftResultMatch && bool1 != bool2))
+ return FALSE;
+
+ res1 = MiniXftPatternGetInteger (pattern1, XFT_SPACING, 0, &int1);
+ res2 = MiniXftPatternGetInteger (pattern2, XFT_SPACING, 0, &int2);
+ if (res1 != res2 || (res1 == MiniXftResultMatch && int1 != int2))
+ return FALSE;
+
+ res1 = MiniXftPatternGetInteger (pattern1, XFT_CHAR_WIDTH, 0, &int1);
+ res2 = MiniXftPatternGetInteger (pattern2, XFT_CHAR_WIDTH, 0, &int2);
+ if (res1 != res2 || (res1 == MiniXftResultMatch && int1 != int2))
+ return FALSE;
+
+ return TRUE;
}
-static gboolean
-pango_ft2_scan_directory (const char *path,
- PangoFT2FontMap *ft2fontmap)
+
+static void
+pango_ft2_font_map_init (PangoFT2FontMap *ft2fontmap)
{
- DIR *dir;
- struct dirent *entry;
- char *fullname;
- FT_Face face;
- FT_Error error;
- int i;
- gboolean found_font = FALSE;
- dir = opendir (path);
- if (!dir)
- /* Don't warn; it's OK to have nonexistent entries in the font path */
- return FALSE;
+ ft2fontmap->fonts =
+ g_hash_table_new ((GHashFunc)pango_ft2_pattern_hash,
+ (GEqualFunc)pango_ft2_pattern_equal);
+ ft2fontmap->fontset_hash =
+ g_hash_table_new_full ((GHashFunc)pango_font_description_hash,
+ (GEqualFunc)pango_font_description_equal,
+ (GDestroyNotify)pango_font_description_free,
+ (GDestroyNotify)pango_ft2_font_set_free);
+
+ ft2fontmap->coverage_hash =
+ g_hash_table_new_full (g_str_hash, g_str_equal,
+ (GDestroyNotify)g_free,
+ (GDestroyNotify)pango_coverage_unref);
+ ft2fontmap->freed_fonts = g_queue_new ();
+}
- while ((entry = readdir (dir)) != NULL)
- {
- fullname = g_build_filename (path, entry->d_name, NULL);
- if (pango_ft2_is_font_file (fullname))
- {
- error = FT_New_Face (ft2fontmap->library, fullname, 0, &face);
- if (error != FT_Err_Ok)
- g_warning ("Error loading font from '%s': %s",
- fullname, pango_ft2_ft_strerror (error));
- else
- {
- if (face->face_flags & FT_FACE_FLAG_SCALABLE)
- {
- pango_ft2_insert_face (ft2fontmap, face, fullname, 0);
- found_font = TRUE;
- }
-
- for (i = 1; i < face->num_faces; i++)
- {
- error = FT_Done_Face (face);
- if (error != FT_Err_Ok)
- g_warning ("Error from FT_Done_Face: %s",
- pango_ft2_ft_strerror (error));
- error = FT_New_Face (ft2fontmap->library, fullname, i, &face);
- if (error != FT_Err_Ok)
- g_warning ("Error loading font %d from '%s': %s",
- i, fullname, pango_ft2_ft_strerror (error));
- else if (face->face_flags & FT_FACE_FLAG_SCALABLE)
- {
- pango_ft2_insert_face (ft2fontmap, face, fullname, i);
- found_font = TRUE;
- }
- }
- error = FT_Done_Face (face);
- if (error != FT_Err_Ok)
- g_warning ("Error from FT_Done_Face: %s",
- pango_ft2_ft_strerror (error));
- }
- }
- g_free (fullname);
- }
- closedir (dir);
- return found_font;
+static void
+pango_ft2_font_map_class_init (PangoFontMapClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ parent_class = g_type_class_peek_parent (class);
+
+ object_class->finalize = pango_ft2_font_map_finalize;
+ class->load_font = pango_ft2_font_map_load_font;
+ class->load_fontset = pango_ft2_font_map_load_fontset;
+ class->list_families = pango_ft2_font_map_list_families;
}
/**
@@ -288,9 +294,7 @@ pango_ft2_scan_directory (const char *path,
PangoFontMap *
pango_ft2_font_map_for_display (void)
{
- char **tmp_list;
FT_Error error;
- gboolean read_font;
/* Make sure that the type system is initialized */
g_type_init ();
@@ -304,27 +308,10 @@ pango_ft2_font_map_for_display (void)
if (error != FT_Err_Ok)
{
g_warning ("Error from FT_Init_FreeType: %s",
- pango_ft2_ft_strerror (error));
+ _pango_ft2_ft_strerror (error));
return NULL;
}
- pango_ft2_global_fontmap->font_cache = pango_ft2_font_cache_new (pango_ft2_global_fontmap->library);
- pango_ft2_global_fontmap->freed_fonts = g_queue_new ();
-
- tmp_list = pango_ft2_font_directories;
-
- read_font = FALSE;
- while (*tmp_list)
- {
- read_font |= pango_ft2_scan_directory ((const char *) *tmp_list, pango_ft2_global_fontmap);
- tmp_list++;
- }
-
- if (!read_font)
- g_warning ("No fonts found by pangoft2. Things will probably not work");
-
- pango_ft2_font_map_read_aliases (pango_ft2_global_fontmap);
-
return PANGO_FONT_MAP (pango_ft2_global_fontmap);
}
@@ -336,34 +323,49 @@ pango_ft2_font_map_for_display (void)
void
pango_ft2_shutdown_display (void)
{
- pango_ft2_fontmap_cache_clear (pango_ft2_global_fontmap);
+ pango_ft2_font_map_cache_clear (pango_ft2_global_fontmap);
g_object_unref (G_OBJECT (pango_ft2_global_fontmap));
pango_ft2_global_fontmap = NULL;
}
+
static void
pango_ft2_font_map_finalize (GObject *object)
{
PangoFT2FontMap *ft2fontmap = PANGO_FT2_FONT_MAP (object);
- g_list_foreach (ft2fontmap->freed_fonts->head, (GFunc)g_object_unref, NULL);
g_queue_free (ft2fontmap->freed_fonts);
+ g_hash_table_destroy (ft2fontmap->fontset_hash);
+ g_hash_table_destroy (ft2fontmap->coverage_hash);
- pango_ft2_font_cache_free (ft2fontmap->font_cache);
-
FT_Done_FreeType (ft2fontmap->library);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
-static void
-list_families_foreach (gpointer key, gpointer value, gpointer user_data)
+/* Add a mapping from xfont->font_pattern to xfont */
+void
+_pango_ft2_font_map_add (PangoFontMap *fontmap,
+ PangoFT2Font *ft2font)
{
- GSList **list = user_data;
+ PangoFT2FontMap *ft2fontmap = (PangoFT2FontMap *) fontmap;
- *list = g_slist_prepend (*list, value);
+ g_hash_table_insert (ft2fontmap->fonts,
+ ft2font->font_pattern,
+ ft2font);
+}
+
+/* Remove mapping from xfont->font_pattern to xfont */
+void
+_pango_ft2_font_map_remove (PangoFontMap *fontmap,
+ PangoFT2Font *ft2font)
+{
+ PangoFT2FontMap *ft2fontmap = (PangoFT2FontMap *) fontmap;
+
+ g_hash_table_remove (ft2fontmap->fonts,
+ ft2font->font_pattern);
}
static void
@@ -371,525 +373,232 @@ pango_ft2_font_map_list_families (PangoFontMap *fontmap,
PangoFontFamily ***families,
int *n_families)
{
- GSList *family_list = NULL;
- GSList *tmp_list;
PangoFT2FontMap *ft2fontmap = (PangoFT2FontMap *)fontmap;
+ MiniXftFontSet *fontset;
+ int i;
- if (!n_families)
- return;
-
- g_hash_table_foreach (ft2fontmap->families, list_families_foreach, &family_list);
-
- *n_families = g_slist_length (family_list);
-
- if (families)
+ if (ft2fontmap->n_families < 0)
{
- int i = 0;
-
- *families = g_new (PangoFontFamily *, *n_families);
+ fontset = MiniXftListFonts ((Display *)1, 0,
+ XFT_CORE, MiniXftTypeBool, False,
+ XFT_ENCODING, MiniXftTypeString, "iso10646-1",
+ NULL,
+ XFT_FAMILY,
+ NULL);
+
+ ft2fontmap->n_families = fontset->nfont;
+ ft2fontmap->families = g_new (PangoFT2Family *, ft2fontmap->n_families);
- tmp_list = family_list;
- while (tmp_list)
+ for (i = 0; i < fontset->nfont; i++)
{
- (*families)[i] = tmp_list->data;
- i++;
- tmp_list = tmp_list->next;
+ char *s;
+ MiniXftResult res;
+
+ res = MiniXftPatternGetString (fontset->fonts[i], XFT_FAMILY, 0, &s);
+ g_assert (res == MiniXftResultMatch);
+
+ ft2fontmap->families[i] = g_object_new (PANGO_FT2_TYPE_FAMILY, NULL);
+ ft2fontmap->families[i]->family_name = g_strdup (s);
+ ft2fontmap->families[i]->fontmap = ft2fontmap;
}
+
+ MiniXftFontSetDestroy (fontset);
}
- g_slist_free (family_list);
+ if (n_families)
+ *n_families = ft2fontmap->n_families;
+
+ if (families)
+ *families = g_memdup (ft2fontmap->families, ft2fontmap->n_families * sizeof (PangoFontFamily *));
}
-static PangoFT2Family *
-pango_ft2_get_family (PangoFT2FontMap *ft2fontmap,
- const char *family_name)
+static int
+pango_ft2_convert_weight (PangoWeight pango_weight)
{
- PangoFT2Family *ft2family = g_hash_table_lookup (ft2fontmap->families, family_name);
- if (!ft2family)
- {
- ft2family = g_object_new (PANGO_FT2_TYPE_FAMILY, NULL);
- ft2family->family_name = g_strdup (family_name);
- ft2family->font_entries = NULL;
-
- g_hash_table_insert (ft2fontmap->families, ft2family->family_name, ft2family);
- }
-
- return ft2family;
+ int weight;
+
+ if (pango_weight < (PANGO_WEIGHT_NORMAL + PANGO_WEIGHT_LIGHT) / 2)
+ weight = XFT_WEIGHT_LIGHT;
+ else if (pango_weight < (PANGO_WEIGHT_NORMAL + 600) / 2)
+ weight = XFT_WEIGHT_MEDIUM;
+ else if (pango_weight < (600 + PANGO_WEIGHT_BOLD) / 2)
+ weight = XFT_WEIGHT_DEMIBOLD;
+ else if (pango_weight < (PANGO_WEIGHT_BOLD + PANGO_WEIGHT_ULTRABOLD) / 2)
+ weight = XFT_WEIGHT_BOLD;
+ else
+ weight = XFT_WEIGHT_BLACK;
+
+ return weight;
}
-static PangoFont *
-pango_ft2_font_map_load_font (PangoFontMap *fontmap,
- const PangoFontDescription *description)
+static int
+pango_ft2_convert_slant (PangoStyle pango_style)
{
- PangoFT2FontMap *ft2fontmap = (PangoFT2FontMap *)fontmap;
- PangoFT2Family *family_entry;
- PangoFont *result = NULL;
- GSList *tmp_list;
- gchar *name;
-
- g_return_val_if_fail (description != NULL, NULL);
+ int slant;
- name = g_ascii_strdown (pango_font_description_get_family (description), -1);
-
- family_entry = g_hash_table_lookup (ft2fontmap->families, name);
- g_free (name);
+ if (pango_style == PANGO_STYLE_ITALIC)
+ slant = XFT_SLANT_ITALIC;
+ else if (pango_style == PANGO_STYLE_OBLIQUE)
+ slant = XFT_SLANT_OBLIQUE;
+ else
+ slant = XFT_SLANT_ROMAN;
- if (family_entry)
- {
- PangoFT2Face *best_match = NULL;
-
- tmp_list = family_entry->font_entries;
- while (tmp_list)
- {
- PangoFT2Face *face = tmp_list->data;
-
- if (pango_font_description_better_match (description,
- best_match ? best_match->description : NULL,
- face->description))
- best_match = face;
-
- tmp_list = tmp_list->next;
- }
-
- if (best_match)
- {
- GSList *tmp_list = best_match->cached_fonts;
-
- gint size = pango_font_description_get_size (description);
-
- while (tmp_list)
- {
- PangoFT2Font *ft2font = tmp_list->data;
-
- if (ft2font->size == size)
- {
- result = (PangoFont *)ft2font;
-
- g_object_ref (G_OBJECT (result));
- if (ft2font->in_cache)
- pango_ft2_fontmap_cache_remove (fontmap, ft2font);
- break;
- }
- tmp_list = tmp_list->next;
- }
-
- if (!result)
- {
- PangoFT2Font *ft2font =
- (PangoFT2Font *) pango_ft2_load_font (fontmap,
- best_match->open_args,
- best_match->face_indices,
- best_match->n_fonts,
- size);
-
- ft2font->fontmap = fontmap;
- ft2font->entry = best_match;
- best_match->cached_fonts = g_slist_prepend (best_match->cached_fonts, ft2font);
-
- result = (PangoFont *)ft2font;
- }
- }
- }
-
- return result;
+ return slant;
}
-static gboolean
-pango_ft2_font_map_read_alias_file (PangoFT2FontMap *ft2fontmap,
- const char *filename)
-{
- FILE *infile;
- int lineno = 0;
- int nfaces;
- int i;
- PangoFT2Face *face = NULL;
- gchar **faces;
- gboolean ret_val = FALSE;
-
- infile = fopen (filename, "r");
- if (infile)
- {
- GString *line_buf = g_string_new (NULL);
- GString *tmp_buf = g_string_new (NULL);
-
- while (pango_read_line (infile, line_buf))
- {
- PangoFT2Family *family_entry;
- PangoStyle style;
- PangoVariant variant;
- PangoWeight weight;
- PangoStretch stretch;
-
- const char *p = line_buf->str;
-
- lineno++;
-
- if (!pango_skip_space (&p))
- continue;
-
- if (!pango_scan_string (&p, tmp_buf))
- goto error;
-
- face = g_object_new (PANGO_FT2_TYPE_FACE, NULL);
- face->n_fonts = 0;
- face->open_args = NULL;
- face->face_indices = NULL;
-
- face->description = pango_font_description_new ();
-
- g_string_ascii_down (tmp_buf);
- pango_font_description_set_family (face->description, tmp_buf->str);
-
- if (!pango_scan_string (&p, tmp_buf))
- goto error;
-
- if (!pango_parse_style (tmp_buf->str, &style, TRUE))
- goto error;
- pango_font_description_set_style (face->description, style);
-
- if (!pango_scan_string (&p, tmp_buf))
- goto error;
-
- if (!pango_parse_variant (tmp_buf->str, &variant, TRUE))
- goto error;
- pango_font_description_set_variant (face->description, variant);
-
- if (!pango_scan_string (&p, tmp_buf))
- goto error;
-
- if (!pango_parse_weight (tmp_buf->str, &weight, TRUE))
- goto error;
- pango_font_description_set_weight (face->description, weight);
-
- if (!pango_scan_string (&p, tmp_buf))
- goto error;
-
- if (!pango_parse_stretch (tmp_buf->str, &stretch, TRUE))
- goto error;
- pango_font_description_set_stretch (face->description, stretch);
-
- if (!pango_scan_string (&p, tmp_buf))
- goto error;
-
- /* Remove excess whitespace and check for complete fields */
- faces = g_strsplit (tmp_buf->str, ",", -1);
- nfaces = 0;
- for (i = 0; faces[i]; i++)
- {
- char *trimmed = pango_trim_string (faces[i]);
- g_free (faces[i]);
- faces[i] = trimmed;
- nfaces++;
- }
-
- face->open_args = g_new (FT_Open_Args *, nfaces);
- face->face_indices = g_new (FT_Long, nfaces);
-
- for (i = 0; i < nfaces; i++)
- {
- PangoFontDescription *desc = pango_font_description_copy_static (face->description);
- PangoFT2OA *oa;
-
- pango_font_description_set_family_static (desc, faces[i]);
- oa = g_hash_table_lookup (ft2fontmap->faces, desc);
- if (!oa)
- g_warning ("Face '%s' on line %d of '%s' not found", faces[i], lineno, filename);
- else
- {
- face->open_args[face->n_fonts] = oa->open_args;
- face->face_indices[face->n_fonts] = oa->face_index;
- face->n_fonts++;
- }
-
- pango_font_description_free (desc);
- }
-
- g_strfreev (faces);
-
- /* Insert the font entry into our structures */
-
- family_entry = pango_ft2_get_family (ft2fontmap, pango_font_description_get_family (face->description));
- family_entry->font_entries = g_slist_prepend (family_entry->font_entries, face);
- ft2fontmap->n_fonts++;
-
- /* Save space by consolidating duplicated string */
- pango_font_description_set_family_static (face->description, family_entry->family_name);
- face->cached_fonts = NULL;
- face->coverage = NULL;
- }
-
- if (ferror (infile))
- g_warning ("Error reading file '%s': %s", filename, g_strerror(errno));
-
- ret_val = TRUE;
- goto out;
-
- error:
- if (face)
- {
- if (face->open_args)
- g_free (face->open_args);
- if (face->face_indices)
- g_free (face->face_indices);
- if (face->description)
- pango_font_description_free (face->description);
- g_free (face);
- }
-
- g_warning ("Error parsing line %d of alias file '%s'", lineno, filename);
-
- out:
- g_string_free (tmp_buf, TRUE);
- g_string_free (line_buf, TRUE);
+static MiniXftPattern *
+pango_ft2_make_pattern (const PangoFontDescription *description)
+{
+ MiniXftPattern *pattern;
+ PangoStyle pango_style;
+ int slant;
+ int weight;
+
+ pango_style = pango_font_description_get_style (description);
- fclose (infile);
- }
+ slant = pango_ft2_convert_slant (pango_style);
+ weight = pango_ft2_convert_weight (pango_font_description_get_weight (description));
+
+ /* To fool Xft into not munging glyph indices, we open it as glyphs-fontspecific
+ * then set the encoding ourself
+ */
+ pattern = MiniXftPatternBuild (0,
+ XFT_ENCODING, MiniXftTypeString, "glyphs-fontspecific",
+ XFT_CORE, MiniXftTypeBool, False,
+ XFT_FAMILY, MiniXftTypeString, pango_font_description_get_family (description),
+ XFT_WEIGHT, MiniXftTypeInteger, weight,
+ XFT_SLANT, MiniXftTypeInteger, slant,
+ XFT_SIZE, MiniXftTypeDouble, (double)pango_font_description_get_size (description)/PANGO_SCALE,
+ NULL);
- return ret_val;
+ return pattern;
}
-static void
-pango_ft2_font_map_read_aliases (PangoFT2FontMap *ft2fontmap)
+static PangoFont *
+pango_ft2_font_map_new_font (PangoFontMap *fontmap,
+ MiniXftPattern *match)
{
- char **files;
- char *files_str = pango_config_key_get ("PangoFT2/AliasFiles");
- int n;
- gboolean read_aliasfile;
-
- if (!files_str)
+ PangoFT2FontMap *ft2fontmap = (PangoFT2FontMap *)fontmap;
+ PangoFT2Font *font;
+
+ /* Look up cache */
+ font = g_hash_table_lookup (ft2fontmap->fonts, match);
+
+ if (font)
{
- const char *home = g_get_home_dir ();
- char *file1 = NULL;
- char *file2;
-
- if (home && *home)
- file1 = g_build_filename (home, ".pangoft2_aliases", NULL);
+ /* Revive fonts from cache */
+ if (font->in_cache)
+ pango_ft2_font_map_cache_remove (fontmap, font);
- file2 = g_build_filename (pango_get_sysconf_subdirectory (),
- "pangoft2.aliases",
- NULL);
-
- files_str = g_build_path (G_SEARCHPATH_SEPARATOR_S,
- file1 ? file1 : file2,
- file1 ? file2 : NULL,
- NULL);
-
- g_free (file1);
- g_free (file2);
+ return (PangoFont *)g_object_ref (G_OBJECT(font));
}
-
- files = pango_split_file_list (files_str);
-
- n = 0;
- while (files[n])
- n++;
-
-
- read_aliasfile = FALSE;
- while (n-- > 0)
- read_aliasfile |= pango_ft2_font_map_read_alias_file (ft2fontmap, files[n]);
-
- if (!read_aliasfile)
- g_warning ("Didn't read any pango ft2 fontalias file. Things will probably not work.");
-
- g_strfreev (files);
- g_free (files_str);
+ return (PangoFont *)_pango_ft2_font_new (fontmap, MiniXftPatternDuplicate (match));
}
-#if DEBUGGING
-static void
-pango_print_desc (PangoFontDescription *desc)
+static PangoFont *
+pango_ft2_font_map_load_font (PangoFontMap *fontmap,
+ const PangoFontDescription *description)
{
- PangoStyle style = pango_font_description_get_style (desc);
- PangoVariant variant = pango_font_description_get_variant (desc);
- PangoWeight weight = pango_font_description_get_weight (desc);
- PangoStretch stretch = pango_font_description_get_stretch (desc);
+ MiniXftPattern *pattern, *match;
+ MiniXftResult res;
+
+ pattern = pango_ft2_make_pattern (description);
+
+ match = MiniXftFontMatch ((Display *)1, 0, pattern, &res);
+
+ MiniXftPatternDestroy (pattern);
- g_print ("%s%s%s%s%s",
- pango_font_description_get_family (desc),
- (style == PANGO_STYLE_NORMAL ? "" :
- (style == PANGO_STYLE_OBLIQUE ? " OBLIQUE" :
- (style == PANGO_STYLE_ITALIC ? " ITALIC" : " ???"))),
- (variant == PANGO_VARIANT_NORMAL ? "" :
- (variant == PANGO_VARIANT_SMALL_CAPS ? " SMALL CAPS" : "???")),
- (weight >= (PANGO_WEIGHT_LIGHT + PANGO_WEIGHT_NORMAL) / 2 &&
- weight < (PANGO_WEIGHT_NORMAL + PANGO_WEIGHT_BOLD) / 2 ? "" :
- (weight < (PANGO_WEIGHT_ULTRALIGHT + PANGO_WEIGHT_LIGHT) / 2 ? " ULTRALIGHT" :
- (weight >= (PANGO_WEIGHT_ULTRALIGHT + PANGO_WEIGHT_LIGHT) / 2 &&
- weight < (PANGO_WEIGHT_LIGHT + PANGO_WEIGHT_NORMAL) / 2 ? " LIGHT" :
- (weight >= (PANGO_WEIGHT_NORMAL + PANGO_WEIGHT_BOLD) / 2 &&
- weight < (PANGO_WEIGHT_BOLD + PANGO_WEIGHT_ULTRABOLD) / 2 ? " BOLD" :
- (weight >= (PANGO_WEIGHT_BOLD + PANGO_WEIGHT_ULTRABOLD) / 2 &&
- weight < (PANGO_WEIGHT_ULTRABOLD + PANGO_WEIGHT_HEAVY) / 2 ? " ULTRABOLD" :
- " HEAVY"))))),
- (stretch == PANGO_STRETCH_ULTRA_CONDENSED ? " ULTRA CONDENSED" :
- (stretch == PANGO_STRETCH_EXTRA_CONDENSED ? " EXTRA CONDENSED" :
- (stretch == PANGO_STRETCH_CONDENSED ? " CONDENSED" :
- (stretch == PANGO_STRETCH_SEMI_CONDENSED ? " SEMI CONDENSED" :
- (stretch == PANGO_STRETCH_NORMAL ? "" :
- (stretch == PANGO_STRETCH_SEMI_EXPANDED ? " SEMI EXPANDED" :
- (stretch == PANGO_STRETCH_EXPANDED ? " EXPANDED" :
- (stretch == PANGO_STRETCH_EXTRA_EXPANDED ? " EXTRA EXPANDED" :
- (stretch == PANGO_STRETCH_ULTRA_EXPANDED ? " ULTRA EXPANDED" : " ???"))))))))));
-}
+ if (match)
+ return pango_ft2_font_map_new_font (fontmap, match);
-static void
-pango_ft2_print_oa (PangoFT2OA *oa)
-{
- g_print ("%s:%ld", oa->open_args->pathname, oa->face_index);
+ return NULL;
}
-#endif
-
-static void
-pango_ft2_insert_face (PangoFT2FontMap *ft2fontmap,
- FT_Face face,
- const char *path,
- int face_index)
+static PangoFontset *
+pango_ft2_font_map_load_fontset (PangoFontMap *fontmap,
+ const PangoFontDescription *desc,
+ PangoLanguage *language)
{
- PangoFontDescription *description;
- char *family_name;
- PangoStyle style;
- PangoVariant variant;
- PangoWeight weight;
- PangoStretch stretch;
- GSList *tmp_list;
- PangoFT2Family *family_entry;
- PangoFT2Face *face_entry;
- PangoFT2OA *oa;
- FT_Open_Args *open_args;
-
- family_name = g_ascii_strdown (face->family_name, -1);
-
- if (face->style_flags & FT_STYLE_FLAG_ITALIC)
- style = PANGO_STYLE_ITALIC;
- else
- style = PANGO_STYLE_NORMAL;
-
- variant = PANGO_VARIANT_NORMAL;
-
- if (face->style_flags & FT_STYLE_FLAG_BOLD)
- weight = PANGO_WEIGHT_BOLD;
- else
- weight = PANGO_WEIGHT_NORMAL;
+ PangoFT2FontMap *ft2fontmap = (PangoFT2FontMap *)fontmap;
+ MiniXftPattern *pattern, *pattern_copy;
+ MiniXftPattern *match;
+ int i;
+ char *family, *family_res;
+ MiniXftResult res;
+ GPtrArray *array;
+ int id;
+ PangoFT2PatternSet *patterns;
+ PangoFontsetSimple *simple;
- stretch = PANGO_STRETCH_NORMAL;
+ patterns = g_hash_table_lookup (ft2fontmap->fontset_hash, desc);
- if (face->style_name)
+ if (patterns == NULL)
{
- gchar **styles = g_strsplit (face->style_name, " ", 0);
- gint i = 0;
+ pattern = pango_ft2_make_pattern (desc);
- while (styles[i])
- {
- (void) (pango_parse_style (styles[i], &style, FALSE) ||
- pango_parse_variant (styles[i], &variant, FALSE) ||
- pango_parse_weight (styles[i], &weight, FALSE) ||
- pango_parse_stretch (styles[i], &stretch, FALSE));
- i++;
- }
- g_strfreev (styles);
- }
+ MiniXftConfigSubstitute (pattern);
+ MiniXftDefaultSubstitute ((Display *)1, 0, pattern);
-#if 0
- PING ((""));
- pango_print_desc (description);
-#endif
+ pattern_copy = MiniXftPatternDuplicate (pattern);
- family_entry = pango_ft2_get_family (ft2fontmap, family_name);
- g_free (family_name);
+ array = g_ptr_array_new ();
+ patterns = g_new (PangoFT2PatternSet, 1);
- tmp_list = family_entry->font_entries;
- while (tmp_list)
- {
- face_entry = tmp_list->data;
+ MiniXftInit (0);
+ MiniXftInitFtLibrary ();
+
+ match = NULL;
+ id = 0;
+ while (MiniXftPatternGetString (pattern, XFT_FAMILY, id++, &family) == MiniXftResultMatch)
+ {
+ MiniXftPatternDel (pattern_copy, XFT_FAMILY);
+ MiniXftPatternAddString (pattern_copy, XFT_FAMILY, family);
- if (pango_font_description_get_style (face_entry->description) == style &&
- pango_font_description_get_weight (face_entry->description) == weight &&
- pango_font_description_get_stretch (face_entry->description) == stretch &&
- pango_font_description_get_variant (face_entry->description) == variant)
+ match = MiniXftFontSetMatch (&_MiniXftFontSet, 1, pattern_copy, &res);
+
+ if (match &&
+ MiniXftPatternGetString (match, XFT_FAMILY, 0, &family_res) == MiniXftResultMatch &&
+ g_ascii_strcasecmp (family, family_res) == 0)
+ {
+ patterns->patterns[patterns->n_patterns++] = match;
+ match = NULL;
+ }
+ if (match)
+ MiniXftPatternDestroy (match);
+ }
+
+ if (array->len == 0)
{
-#if 0
- PING ((" family and description matched (!)"));
-#endif
- return;
+ match = MiniXftFontSetMatch (&_MiniXftFontSet, 1, pattern, &res);
+ patterns->patterns[patterns->n_patterns++] = match;
}
- tmp_list = tmp_list->next;
- }
+ MiniXftPatternDestroy (pattern);
+ MiniXftPatternDestroy (pattern_copy);
- description = pango_font_description_new ();
- pango_font_description_set_family_static (description, family_entry->family_name);
- pango_font_description_set_style (description, style);
- pango_font_description_set_weight (description, weight);
- pango_font_description_set_stretch (description, stretch);
- pango_font_description_set_variant (description, variant);
-
- oa = g_hash_table_lookup (ft2fontmap->faces, description);
- if (!oa)
- {
- oa = g_new (PangoFT2OA, 1);
- open_args = g_new (FT_Open_Args, 1);
- open_args->flags = ft_open_pathname;
- open_args->pathname = g_strdup (path);
- open_args->driver = NULL;
- open_args->num_params = 0;
- oa->open_args = open_args;
- oa->face_index = face_index;
-#if 0
- PING (("adding mapping: "));
- pango_ft2_print_oa (oa);
-#endif
- g_hash_table_insert (ft2fontmap->faces, description, oa);
+ patterns->n_patterns = array->len;
+ patterns->patterns = (MiniXftPattern **)g_ptr_array_free (array, FALSE);
+
+ g_hash_table_insert (ft2fontmap->fontset_hash,
+ pango_font_description_copy (desc),
+ patterns);
}
-#if 0
- g_print ("\n");
-#endif
- face_entry = g_object_new (PANGO_FT2_TYPE_FACE, NULL);
- face_entry->description = description;
- face_entry->cached_fonts = NULL;
- face_entry->coverage = NULL;
- face_entry->open_args = g_new (FT_Open_Args *, 1);
- face_entry->open_args[0] = oa->open_args;
- face_entry->face_indices = g_new (FT_Long, 1);
- face_entry->face_indices[0] = oa->face_index;
- face_entry->n_fonts = 1;
- family_entry->font_entries = g_slist_append (family_entry->font_entries, face_entry);
- ft2fontmap->n_fonts++;
-}
-
-static void
-free_coverages_foreach (gpointer key,
- gpointer value,
- gpointer data)
-{
- pango_coverage_unref (value);
-}
-
-/**
- * pango_ft2_font_map_get_font_cache:
- * @font_map: a #PangoFT2FontMap.
- *
- * Obtains the font cache associated with the given font map.
- *
- * Returns: the #PangoFT2FontCache of @font_map.
- **/
-PangoFT2FontCache *
-pango_ft2_font_map_get_font_cache (PangoFontMap *font_map)
-{
- g_return_val_if_fail (font_map != NULL, NULL);
- g_return_val_if_fail (PANGO_FT2_IS_FONT_MAP (font_map), NULL);
+ simple = pango_fontset_simple_new (language);
- return PANGO_FT2_FONT_MAP (font_map)->font_cache;
+ for (i = 0; i < patterns->n_patterns; i++)
+ pango_fontset_simple_append (simple,
+ pango_ft2_font_map_new_font (fontmap, patterns->patterns[i]));
+
+ return PANGO_FONTSET (simple);
}
void
-pango_ft2_fontmap_cache_add (PangoFontMap *fontmap,
- PangoFT2Font *ft2font)
+_pango_ft2_font_map_cache_add (PangoFontMap *fontmap,
+ PangoFT2Font *ft2font)
{
PangoFT2FontMap *ft2fontmap = PANGO_FT2_FONT_MAP (fontmap);
@@ -904,9 +613,9 @@ pango_ft2_fontmap_cache_add (PangoFontMap *fontmap,
ft2font->in_cache = TRUE;
}
-void
-pango_ft2_fontmap_cache_remove (PangoFontMap *fontmap,
- PangoFT2Font *ft2font)
+static void
+pango_ft2_font_map_cache_remove (PangoFontMap *fontmap,
+ PangoFT2Font *ft2font)
{
PangoFT2FontMap *ft2fontmap = PANGO_FT2_FONT_MAP (fontmap);
@@ -926,7 +635,7 @@ pango_ft2_fontmap_cache_remove (PangoFontMap *fontmap,
}
static void
-pango_ft2_fontmap_cache_clear (PangoFT2FontMap *ft2fontmap)
+pango_ft2_font_map_cache_clear (PangoFT2FontMap *ft2fontmap)
{
g_list_foreach (ft2fontmap->freed_fonts->head, (GFunc)g_object_unref, NULL);
g_list_free (ft2fontmap->freed_fonts->head);
@@ -935,98 +644,95 @@ pango_ft2_fontmap_cache_clear (PangoFT2FontMap *ft2fontmap)
ft2fontmap->freed_fonts->length = 0;
}
-static void
-pango_ft2_face_dump (int indent,
- PangoFT2Face *face)
+/*
+ * PangoFT2Face
+ */
+
+PangoFontDescription *
+_pango_ft2_font_desc_from_pattern (MiniXftPattern *pattern)
{
+ PangoFontDescription *desc;
+ PangoStyle style;
+ PangoWeight weight;
+
+ char *s;
int i;
- printf ("%*sPangoFT2Face@%p:\n"
- "%*s lfp:\n",
- indent, "", face,
- indent, "");
-
- for (i = 0; i < face->n_fonts; i++)
- printf ("%*s PangoFT2OpenArgs:%s:%ld\n",
- indent, "", face->open_args[i]->pathname, face->face_indices[i]);
-
- printf ("%*s description:\n"
- "%*s family_name: %s\n"
- "%*s style: %d\n"
- "%*s variant: %d\n"
- "%*s weight: %d\n"
- "%*s stretch: %d\n"
- "%*s coverage: %p\n",
- indent, "",
- indent, "", pango_font_description_get_family (face->description),
- indent, "", pango_font_description_get_style (face->description),
- indent, "", pango_font_description_get_variant (face->description),
- indent, "", pango_font_description_get_weight (face->description),
- indent, "", pango_font_description_get_stretch (face->description),
- indent, "", face->coverage);
-}
+ desc = pango_font_description_new ();
-static void
-pango_ft2_family_entry_dump (int indent,
- PangoFT2Family *entry)
-{
- GSList *tmp_list = entry->font_entries;
+ g_assert (MiniXftPatternGetString (pattern, XFT_FAMILY, 0, &s) == MiniXftResultMatch);
+
+ pango_font_description_set_family (desc, s);
- printf ("%*sPangoFT2Family@%p:\n"
- "%*s family_name: %s\n"
- "%*s font_entries:\n",
- indent, "", entry,
- indent, "", entry->family_name,
- indent, "");
-
- while (tmp_list)
+ if (MiniXftPatternGetInteger (pattern, XFT_SLANT, 0, &i) == MiniXftResultMatch)
{
- PangoFT2Face *face = tmp_list->data;
-
- pango_ft2_face_dump (indent + 2, face);
- tmp_list = tmp_list->next;
+ if (i == XFT_SLANT_ROMAN)
+ style = PANGO_STYLE_NORMAL;
+ else if (i == XFT_SLANT_OBLIQUE)
+ style = PANGO_STYLE_OBLIQUE;
+ else
+ style = PANGO_STYLE_ITALIC;
}
-}
-
-static void
-dump_family (gpointer key,
- gpointer value,
- gpointer user_data)
-{
- PangoFT2Family *entry = value;
- int indent = (int) user_data;
+ else
+ style = PANGO_STYLE_NORMAL;
- pango_ft2_family_entry_dump (indent, entry);
-}
+ pango_font_description_set_style (desc, style);
+
+ if (MiniXftPatternGetInteger (pattern, XFT_WEIGHT, 0, &i) == MiniXftResultMatch)
+ {
+ if (i < XFT_WEIGHT_LIGHT)
+ weight = PANGO_WEIGHT_ULTRALIGHT;
+ else if (i < (XFT_WEIGHT_LIGHT + XFT_WEIGHT_MEDIUM) / 2)
+ weight = PANGO_WEIGHT_LIGHT;
+ else if (i < (XFT_WEIGHT_MEDIUM + XFT_WEIGHT_DEMIBOLD) / 2)
+ weight = PANGO_WEIGHT_NORMAL;
+ else if (i < (XFT_WEIGHT_DEMIBOLD + XFT_WEIGHT_BOLD) / 2)
+ weight = 600;
+ else if (i < (XFT_WEIGHT_BOLD + XFT_WEIGHT_BLACK) / 2)
+ weight = PANGO_WEIGHT_BOLD;
+ else
+ weight = PANGO_WEIGHT_ULTRABOLD;
+ }
+ else
+ weight = PANGO_WEIGHT_NORMAL;
-/**
- * pango_ft2_fontmap_dump:
- * @indent: the indent to use.
- * @fontmap: a #PangoFT2FontMap.
- *
- * Writes a description of the given font map to stdout.
- **/
-void
-pango_ft2_fontmap_dump (int indent,
- PangoFontMap *fontmap)
-{
- PangoFT2FontMap *ft2fontmap = PANGO_FT2_FONT_MAP (fontmap);
+ pango_font_description_set_weight (desc, weight);
+
+ pango_font_description_set_variant (desc, PANGO_VARIANT_NORMAL);
+ pango_font_description_set_stretch (desc, PANGO_STRETCH_NORMAL);
- printf ("%*sPangoFT2FontMap@%p:\n",
- indent, "", ft2fontmap);
- g_hash_table_foreach (ft2fontmap->families, dump_family, (gpointer) (indent + 2));
+ return desc;
}
-/*
- * PangoFT2Face
- */
static PangoFontDescription *
pango_ft2_face_describe (PangoFontFace *face)
{
- PangoFT2Face *ft2face = PANGO_FT2_FACE (face);
+ PangoFT2Face *ft2face = (PangoFT2Face *) face;
+ PangoFT2Family *ft2family = ft2face->family;
+ PangoFontDescription *desc = NULL;
+ MiniXftResult res;
+ MiniXftPattern *match_pattern;
+ MiniXftPattern *result_pattern;
+
+ match_pattern = MiniXftPatternBuild (NULL,
+ XFT_ENCODING, MiniXftTypeString, "iso10646-1",
+ XFT_FAMILY, MiniXftTypeString, ft2family->family_name,
+ XFT_CORE, MiniXftTypeBool, False,
+ XFT_STYLE, MiniXftTypeString, ft2face->style,
+ NULL);
+ g_assert (match_pattern);
+
+ result_pattern = MiniXftFontMatch ((Display *)1, 0, match_pattern, &res);
+ if (result_pattern)
+ {
+ desc = _pango_ft2_font_desc_from_pattern (result_pattern);
+ MiniXftPatternDestroy (result_pattern);
+ }
- return pango_font_description_copy (ft2face->description);
+ MiniXftPatternDestroy (match_pattern);
+
+ return desc;
}
static const char *
@@ -1034,18 +740,7 @@ pango_ft2_face_get_face_name (PangoFontFace *face)
{
PangoFT2Face *ft2face = PANGO_FT2_FACE (face);
- if (!ft2face->face_name)
- {
- PangoFontDescription *desc = pango_font_face_describe (face);
-
- pango_font_description_unset_fields (desc,
- PANGO_FONT_MASK_FAMILY | PANGO_FONT_MASK_SIZE);
-
- ft2face->face_name = pango_font_description_to_string (desc);
- pango_font_description_free (desc);
- }
-
- return ft2face->face_name;
+ return ft2face->style;
}
static void
@@ -1083,112 +778,32 @@ pango_ft2_face_get_type (void)
return object_type;
}
-PangoCoverage *
-pango_ft2_face_get_coverage (PangoFT2Face *face,
- PangoFont *font,
- PangoLanguage *language)
+void
+_pango_ft2_font_map_set_coverage (PangoFontMap *fontmap,
+ const char *name,
+ PangoCoverage *coverage)
{
- guint32 ch;
- PangoMap *shape_map;
- PangoCoverage *coverage;
- PangoCoverage *result;
- PangoCoverageLevel font_level;
- PangoMapEntry *map_entry;
- GHashTable *coverage_hash;
- PangoFontDescription *description;
- FILE *cache_file;
- char *file_name;
- char *cache_file_name;
- char *font_as_filename;
- guchar *buf;
- size_t buflen;
-
- if (face)
- if (face->coverage)
- {
- pango_coverage_ref (face->coverage);
- return face->coverage;
- }
-
- description = pango_font_describe (font);
- font_as_filename = pango_font_description_to_filename (description);
- file_name = g_strconcat (font_as_filename, ".",
- language ? pango_language_to_string (language) : "",
- NULL);
- g_free (font_as_filename);
- cache_file_name = g_build_filename (pango_get_sysconf_subdirectory (),
- "cache.ft2", file_name, NULL);
- g_free (file_name);
- pango_font_description_free (description);
-
- PING (("trying to load %s", cache_file_name));
- result = NULL;
- if (g_file_get_contents (cache_file_name, (char **)&buf, &buflen, NULL))
- {
- result = pango_coverage_from_bytes (buf, buflen);
- g_free (buf);
- }
-
- if (!result)
- {
- result = pango_coverage_new ();
-
- coverage_hash = g_hash_table_new (g_str_hash, g_str_equal);
-
- shape_map = pango_ft2_get_shaper_map (language);
-
- for (ch = 0; ch < 65536; ch++)
- {
- map_entry = pango_map_get_entry (shape_map, ch);
- if (map_entry->info)
- {
- coverage = g_hash_table_lookup (coverage_hash, map_entry->info->id);
- if (!coverage)
- {
- PangoEngineShape *engine = (PangoEngineShape *)pango_map_get_engine (shape_map, ch);
- coverage = engine->get_coverage (font, language);
- g_hash_table_insert (coverage_hash, map_entry->info->id, coverage);
- }
-
- font_level = pango_coverage_get (coverage, ch);
- if (font_level == PANGO_COVERAGE_EXACT && !map_entry->is_exact)
- font_level = PANGO_COVERAGE_APPROXIMATE;
-
- if (font_level != PANGO_COVERAGE_NONE)
- pango_coverage_set (result, ch, font_level);
- }
- }
-
- g_hash_table_foreach (coverage_hash, free_coverages_foreach, NULL);
- g_hash_table_destroy (coverage_hash);
-
- cache_file = fopen (cache_file_name, "wb");
- if (cache_file)
- {
- pango_coverage_to_bytes (result, &buf, &buflen);
- PING (("saving %d bytes to %s", buflen, cache_file_name));
- fwrite (buf, buflen, 1, cache_file);
- fclose (cache_file);
- g_free (buf);
- }
- }
+ PangoFT2FontMap *ft2fontmap = (PangoFT2FontMap *)fontmap;
- if (face)
- {
- face->coverage = result;
- pango_coverage_ref (result);
- }
+ g_hash_table_insert (ft2fontmap->coverage_hash, g_strdup (name),
+ pango_coverage_ref (coverage));
+}
- g_free (cache_file_name);
+PangoCoverage *
+_pango_ft2_font_map_get_coverage (PangoFontMap *fontmap,
+ const char *name)
+{
+ PangoFT2FontMap *ft2fontmap = (PangoFT2FontMap *)fontmap;
- return result;
+ return g_hash_table_lookup (ft2fontmap->coverage_hash, name);
}
-void
-pango_ft2_face_remove (PangoFT2Face *face,
- PangoFont *font)
+FT_Library
+_pango_ft2_font_map_get_library (PangoFontMap *fontmap)
{
- face->cached_fonts = g_slist_remove (face->cached_fonts, font);
+ PangoFT2FontMap *ft2fontmap = (PangoFT2FontMap *)fontmap;
+
+ return ft2fontmap->library;
}
/*
@@ -1197,26 +812,48 @@ pango_ft2_face_remove (PangoFT2Face *face,
static void
pango_ft2_family_list_faces (PangoFontFamily *family,
- PangoFontFace ***faces,
- int *n_faces)
+ PangoFontFace ***faces,
+ int *n_faces)
{
PangoFT2Family *ft2family = PANGO_FT2_FAMILY (family);
- *n_faces = g_slist_length (ft2family->font_entries);
- if (faces)
+ if (ft2family->n_faces < 0)
{
- GSList *tmp_list;
- int i = 0;
+ MiniXftFontSet *fontset;
+ int i;
+
+ fontset = MiniXftListFonts ((Display *)1, 0,
+ XFT_ENCODING, MiniXftTypeString, "iso10646-1",
+ XFT_FAMILY, MiniXftTypeString, ft2family->family_name,
+ XFT_CORE, MiniXftTypeBool, False,
+ NULL,
+ XFT_STYLE,
+ NULL);
- *faces = g_new (PangoFontFace *, *n_faces);
+ ft2family->n_faces = fontset->nfont;
+ ft2family->faces = g_new (PangoFT2Face *, ft2family->n_faces);
- tmp_list = ft2family->font_entries;
- while (tmp_list)
+ for (i = 0; i < fontset->nfont; i++)
{
- (*faces)[i++] = tmp_list->data;
- tmp_list = tmp_list->next;
+ char *s;
+ MiniXftResult res;
+
+ res = MiniXftPatternGetString (fontset->fonts[i], XFT_STYLE, 0, &s);
+ g_assert (res == MiniXftResultMatch);
+
+ ft2family->faces[i] = g_object_new (PANGO_FT2_TYPE_FACE, NULL);
+ ft2family->faces[i]->style = g_strdup (s);
+ ft2family->faces[i]->family = ft2family;
}
+
+ MiniXftFontSetDestroy (fontset);
}
+
+ if (n_faces)
+ *n_faces = ft2family->n_faces;
+
+ if (faces)
+ *faces = g_memdup (ft2family->faces, ft2family->n_faces * sizeof (PangoFontFace *));
}
const char *
diff --git a/pango/pangoft2-private.h b/pango/pangoft2-private.h
index cc12206e..5dd5b3d5 100644
--- a/pango/pangoft2-private.h
+++ b/pango/pangoft2-private.h
@@ -25,6 +25,7 @@
#include "pango-modules.h"
#include "pangoft2.h"
+#include "mini-xft/MiniXft.h"
/* Debugging... */
/*#define DEBUGGING 1*/
@@ -52,43 +53,27 @@
((d) - PANGO_SCALE_26_6 / 2) / PANGO_SCALE_26_6)
#define PANGO_UNITS_26_6(d) (PANGO_SCALE_26_6 * (d))
-typedef struct _PangoFT2OA PangoFT2OA;
-typedef struct _PangoFT2Font PangoFT2Font;
+typedef struct _PangoFT2Font PangoFT2Font;
typedef struct _PangoFT2GlyphInfo PangoFT2GlyphInfo;
-typedef struct _PangoFT2Face PangoFT2Face;
-typedef struct _PangoFT2SubfontInfo PangoFT2SubfontInfo;
+typedef struct _PangoFT2Face PangoFT2Face;
+typedef struct _PangoFT2Family PangoFT2Family;
-struct _PangoFT2OA
-{
- FT_Open_Args *open_args;
- FT_Long face_index;
-};
struct _PangoFT2Font
{
PangoFont font;
- /* A PangoFT2Font consists of one or several FT2 fonts (faces) that
- * are assumed to blend visually well, and cover separate parts of
- * the Unicode characters. The FT2 faces are not kept unnecessarily
- * open, thus also we keep both the FT_Open_Args (and face index),
- * and FT_Face.
- */
- PangoFT2OA **oa;
- FT_Face *faces;
- int n_fonts;
+ MiniXftPattern *font_pattern;
+ FT_Face face;
int size;
- GSList *metrics_by_lang;
-
PangoFontMap *fontmap;
+ PangoFontDescription *description;
+
/* If TRUE, font is in cache of recently unused fonts and not otherwise
- * in use.
- */
+ * in use. */
gboolean in_cache;
-
- PangoFT2Face *entry;
GHashTable *glyph_info;
};
@@ -103,27 +88,30 @@ struct _PangoFT2Face
{
PangoFontFace parent_instance;
- FT_Open_Args **open_args;
- FT_Long *face_indices;
- int n_fonts;
- PangoFontDescription *description;
- PangoCoverage *coverage;
- char *face_name;
-
- GSList *cached_fonts;
+ PangoFT2Family *family;
+ char *style;
};
-PangoMap *pango_ft2_get_shaper_map (PangoLanguage *language);
-PangoCoverage *pango_ft2_face_get_coverage (PangoFT2Face *face,
- PangoFont *font,
- PangoLanguage *language);
-void pango_ft2_face_remove (PangoFT2Face *face,
- PangoFont *font);
-FT_Library *pango_ft2_fontmap_get_library (PangoFontMap *fontmap);
-void pango_ft2_fontmap_cache_add (PangoFontMap *fontmap,
- PangoFT2Font *ft2font);
-void pango_ft2_fontmap_cache_remove (PangoFontMap *fontmap,
- PangoFT2Font *ft2font);
-const char *pango_ft2_ft_strerror (FT_Error error);
+PangoFT2Font * _pango_ft2_font_new (PangoFontMap *font,
+ MiniXftPattern *pattern);
+PangoMap *_pango_ft2_get_shaper_map (PangoLanguage *language);
+void _pango_ft2_font_map_set_coverage (PangoFontMap *fontmap,
+ const char *name,
+ PangoCoverage *coverage);
+PangoCoverage *_pango_ft2_font_map_get_coverage (PangoFontMap *fontmap,
+ const char *name);
+void _pango_ft2_face_remove (PangoFT2Face *face,
+ PangoFont *font);
+FT_Library _pango_ft2_font_map_get_library (PangoFontMap *fontmap);
+void _pango_ft2_font_map_cache_add (PangoFontMap *fontmap,
+ PangoFT2Font *ft2font);
+void _pango_ft2_font_map_cache_remove (PangoFontMap *fontmap,
+ PangoFT2Font *ft2font);
+void _pango_ft2_font_map_add (PangoFontMap *fontmap,
+ PangoFT2Font *ft2font);
+void _pango_ft2_font_map_remove (PangoFontMap *fontmap,
+ PangoFT2Font *ft2font);
+const char *_pango_ft2_ft_strerror (FT_Error error);
+PangoFontDescription *_pango_ft2_font_desc_from_pattern (MiniXftPattern *pattern);
#endif /* __PANGOFT2_PRIVATE_H__ */
diff --git a/pango/pangoft2.c b/pango/pangoft2.c
index ea1653ad..93f1b18b 100644
--- a/pango/pangoft2.c
+++ b/pango/pangoft2.c
@@ -46,12 +46,6 @@ typedef struct _PangoFT2FontClass PangoFT2FontClass;
typedef struct _PangoFT2MetricsInfo PangoFT2MetricsInfo;
typedef struct _PangoFT2ContextInfo PangoFT2ContextInfo;
-struct _PangoFT2MetricsInfo
-{
- const char *sample_str;
- PangoFontMetrics *metrics;
-};
-
struct _PangoFT2FontClass
{
PangoFontClass parent_class;
@@ -66,9 +60,6 @@ static void pango_ft2_font_finalize (GObject *object);
static PangoFontDescription *pango_ft2_font_describe (PangoFont *font);
-static PangoCoverage * pango_ft2_font_get_coverage (PangoFont *font,
- PangoLanguage *language);
-
static PangoEngineShape * pango_ft2_font_find_shaper (PangoFont *font,
PangoLanguage *language,
guint32 ch);
@@ -88,66 +79,87 @@ static void pango_ft2_get_item_properties (PangoItem
PangoAttrColor *bg_color,
gboolean *bg_set);
-static char *
-pango_ft2_open_args_describe (PangoFT2OA *oa)
+static GType pango_ft2_font_get_type (void);
+
+PangoFT2Font *
+_pango_ft2_font_new (PangoFontMap *fontmap,
+ MiniXftPattern *pattern)
{
- if (oa->open_args->flags & ft_open_memory)
- return g_strdup_printf ("memory at %p", oa->open_args->memory_base);
- else if (oa->open_args->flags == ft_open_pathname)
- return g_strdup_printf ("file '%s'", oa->open_args->pathname);
- else if (oa->open_args->flags & ft_open_stream)
- return g_strdup_printf ("FT_Stream at %p", oa->open_args->stream);
- else
- return g_strdup_printf ("open_args at %p, face_index %ld", oa->open_args, oa->face_index);
+ PangoFT2Font *ft2font;
+ double d;
+
+ g_return_val_if_fail (fontmap != NULL, NULL);
+ g_return_val_if_fail (pattern != NULL, NULL);
+
+ ft2font = (PangoFT2Font *)g_object_new (PANGO_TYPE_FT2_FONT, NULL);
+
+ ft2font->fontmap = fontmap;
+ ft2font->font_pattern = pattern;
+
+ g_object_ref (G_OBJECT (fontmap));
+ ft2font->description = _pango_ft2_font_desc_from_pattern (pattern);
+ ft2font->face = NULL;
+
+ if (MiniXftPatternGetDouble (pattern, XFT_PIXEL_SIZE, 0, &d) == MiniXftResultMatch)
+ ft2font->size = d*PANGO_SCALE;
+
+ _pango_ft2_font_map_add (ft2font->fontmap, ft2font);
+
+ return ft2font;
}
+
/**
- * pango_ft2_get_face:
+ * pango_ft2_font_get_face:
* @font: a #PangoFont
- * @subfont_index: the index of a subfont
*
- * Looks up a subfont in a #PangoFT2Font and returns a pointer to the
- * native FreeType2 FT_Face structure. This may be useful if you want
- * to use FreeType2 functions directly.
+ * Returns the native FreeType2 FT_Face structure used for this PangoFont.
+ * This may be useful if you want to use FreeType2 functions directly.
*
- * Return value: a pointer to a #FT_Face structure.
+ * Return value: a pointer to a #FT_Face structure, with the size set correctly
**/
FT_Face
-pango_ft2_get_face (PangoFont *font,
- PangoFT2Subfont subfont_index)
+pango_ft2_font_get_face (PangoFont *font)
{
PangoFT2Font *ft2font = (PangoFT2Font *)font;
- PangoFT2FontCache *cache;
FT_Face face;
FT_Error error;
+ MiniXftPattern *pattern;
+ char *filename;
+ int id;
+
+ pattern = ft2font->font_pattern;
- if (subfont_index < 1 || subfont_index > ft2font->n_fonts)
+ if (!ft2font->face)
{
- g_warning ("Invalid subfont %d", subfont_index);
- return NULL;
+ if (MiniXftPatternGetString (pattern, XFT_FILE, 0, &filename) != MiniXftResultMatch)
+ goto bail0;
+
+ if (MiniXftPatternGetInteger (pattern, XFT_INDEX, 0, &id) != MiniXftResultMatch)
+ goto bail0;
+
+ error = FT_New_Face (_pango_ft2_font_map_get_library (ft2font->fontmap),
+ filename, id, &ft2font->face);
+ ft2font->face->generic.data = 0;
}
+ bail0:
- if (!ft2font->faces[subfont_index-1])
+ if (!ft2font->face)
{
- cache = pango_ft2_font_map_get_font_cache (ft2font->fontmap);
-
- ft2font->faces[subfont_index-1] =
- pango_ft2_font_cache_load (cache,
- ft2font->oa[subfont_index-1]->open_args,
- ft2font->oa[subfont_index-1]->face_index);
-
- if (!ft2font->faces[subfont_index-1])
- g_warning ("Cannot load font for %s",
- pango_ft2_open_args_describe (ft2font->oa[subfont_index-1]));
+ g_warning ("Cannot load font\n");
+ return NULL;
}
- face = ft2font->faces[subfont_index-1];
+ face = ft2font->face;
if (ft2font->size != GPOINTER_TO_UINT (face->generic.data))
{
face->generic.data = GUINT_TO_POINTER (ft2font->size);
- error = FT_Set_Char_Size (face, 0, PANGO_PIXELS_26_6 (ft2font->size), 72, 72);
+ error = FT_Set_Char_Size (face,
+ PANGO_PIXELS_26_6 (ft2font->size),
+ PANGO_PIXELS_26_6 (ft2font->size),
+ 0, 0);
if (error)
g_warning ("Error in FT_Set_Char_Size: %d", error);
}
@@ -157,6 +169,7 @@ pango_ft2_get_face (PangoFont *font,
/**
* pango_ft2_get_context:
+ * @dpi: the dpi of the target device
*
* Retrieves a #PangoContext appropriate for rendering with the PangoFT2
* backend.
@@ -164,7 +177,7 @@ pango_ft2_get_face (PangoFont *font,
* Return value: the new #PangoContext
**/
PangoContext *
-pango_ft2_get_context (void)
+pango_ft2_get_context (double dpi)
{
PangoContext *result;
static gboolean registered_modules = FALSE;
@@ -177,9 +190,11 @@ pango_ft2_get_context (void)
for (i = 0; _pango_included_ft2_modules[i].list; i++)
pango_module_register (&_pango_included_ft2_modules[i]);
}
+
+ MiniXftSetDPI (dpi);
result = pango_context_new ();
- pango_context_add_font_map (result, pango_ft2_font_map_for_display ());
+ pango_context_set_font_map (result, pango_ft2_font_map_for_display ());
return result;
}
@@ -215,14 +230,10 @@ pango_ft2_font_get_type (void)
static void
pango_ft2_font_init (PangoFT2Font *ft2font)
{
- ft2font->oa = NULL;
- ft2font->faces = NULL;
-
- ft2font->n_fonts = 0;
+ ft2font->face = NULL;
- ft2font->metrics_by_lang = NULL;
+ ft2font->size = 0;
- ft2font->entry = NULL;
ft2font->glyph_info = g_hash_table_new (NULL, NULL);
}
@@ -245,54 +256,6 @@ pango_ft2_font_class_init (PangoFT2FontClass *class)
}
/**
- * pango_ft2_load_font:
- * @fontmap: a #PangoFontmap
- * @open_args: parameters that control loading
- * @face_indices:
- * @n_fonts:
- * @size:
- *
- * Loads a logical font based on XXX
- *
- * Return value: a new #PangoFont
- **/
-PangoFont *
-pango_ft2_load_font (PangoFontMap *fontmap,
- FT_Open_Args **open_args,
- FT_Long *face_indices,
- int n_fonts,
- int size)
-{
- PangoFT2Font *result;
- int i;
-
- g_return_val_if_fail (fontmap != NULL, NULL);
- g_return_val_if_fail (open_args != NULL, NULL);
- g_return_val_if_fail (face_indices != NULL, NULL);
- g_return_val_if_fail (n_fonts > 0, NULL);
-
- result = (PangoFT2Font *)g_object_new (PANGO_TYPE_FT2_FONT, NULL);
-
- result->fontmap = fontmap;
- g_object_ref (G_OBJECT (result->fontmap));
-
- result->oa = g_new (PangoFT2OA *, n_fonts);
- result->faces = g_new (FT_Face, n_fonts);
- result->n_fonts = n_fonts;
- result->size = size;
-
- for (i = 0; i < n_fonts; i++)
- {
- result->oa[i] = g_new (PangoFT2OA, 1);
- result->oa[i]->open_args = open_args[i];
- result->oa[i]->face_index = face_indices[i];
- result->faces[i] = NULL;
- }
-
- return &result->font;
-}
-
-/**
* pango_ft2_render:
* @bitmap: the FreeType2 bitmap onto which to draw the string
* @font: the font in which to draw the string
@@ -315,7 +278,6 @@ pango_ft2_render (FT_Bitmap *bitmap,
int i;
int x_position = 0;
int ix, iy, ixoff, iyoff, y_start, y_limit, x_start, x_limit;
- PangoFT2Subfont subfont_index;
PangoGlyphInfo *gi;
guchar *p, *q;
@@ -329,9 +291,8 @@ pango_ft2_render (FT_Bitmap *bitmap,
{
if (gi->glyph)
{
- glyph_index = PANGO_FT2_GLYPH_INDEX (gi->glyph);
- subfont_index = PANGO_FT2_GLYPH_SUBFONT (gi->glyph);
- face = pango_ft2_get_face (font, subfont_index);
+ glyph_index = gi->glyph;
+ face = pango_ft2_font_get_face (font);
if (face)
{
@@ -418,15 +379,9 @@ pango_ft2_render (FT_Bitmap *bitmap,
}
static FT_Glyph_Metrics *
-pango_ft2_get_per_char (PangoFont *font,
- PangoFT2Subfont subfont_index,
- guint32 glyph_index)
+pango_ft2_get_per_char (FT_Face face,
+ guint32 glyph_index)
{
- FT_Face face;
-
- if (!(face = pango_ft2_get_face (font, subfont_index)))
- return NULL;
-
FT_Load_Glyph (face, glyph_index, FT_LOAD_DEFAULT);
return &face->glyph->metrics;
}
@@ -439,22 +394,17 @@ pango_ft2_font_get_glyph_extents (PangoFont *font,
{
PangoFT2Font *ft2font = (PangoFT2Font *)font;
PangoFT2GlyphInfo *info;
- PangoFT2Subfont subfont_index;
- FT_UInt glyph_index;
FT_Glyph_Metrics *gm;
info = g_hash_table_lookup (ft2font->glyph_info, GUINT_TO_POINTER (glyph));
if (!info)
{
+ FT_Face face = pango_ft2_font_get_face (font);
info = g_new (PangoFT2GlyphInfo, 1);
- glyph_index = PANGO_FT2_GLYPH_INDEX (glyph);
- subfont_index = PANGO_FT2_GLYPH_SUBFONT (glyph);
- if (glyph && (gm = pango_ft2_get_per_char (font, subfont_index, glyph_index)))
+ if (glyph && (gm = pango_ft2_get_per_char (face, glyph)))
{
- FT_Face face = pango_ft2_get_face (font, subfont_index);
-
info->ink_rect.x = PANGO_UNITS_26_6 (gm->horiBearingX);
info->ink_rect.width = PANGO_UNITS_26_6 (gm->width);
info->ink_rect.y = -PANGO_UNITS_26_6 (gm->horiBearingY);
@@ -481,7 +431,7 @@ pango_ft2_font_get_glyph_extents (PangoFont *font,
g_hash_table_insert (ft2font->glyph_info, GUINT_TO_POINTER(glyph), info);
}
-
+
if (ink_rect)
*ink_rect = info->ink_rect;
if (logical_rect)
@@ -504,280 +454,67 @@ pango_ft2_font_get_kerning (PangoFont *font,
PangoGlyph left,
PangoGlyph right)
{
- PangoFT2Subfont subfont_index;
FT_Face face;
- FT_UInt left_glyph_index, right_glyph_index;
FT_Error error;
FT_Vector kerning;
- subfont_index = PANGO_FT2_GLYPH_SUBFONT (left);
- if (PANGO_FT2_GLYPH_SUBFONT (right) != subfont_index)
- return 0;
-
- face = pango_ft2_get_face (font, subfont_index);
+ face = pango_ft2_font_get_face (font);
if (!face)
return 0;
if (!FT_HAS_KERNING (face))
return 0;
- left_glyph_index = PANGO_FT2_GLYPH_INDEX (left);
- right_glyph_index = PANGO_FT2_GLYPH_INDEX (right);
-
- if (!left_glyph_index || !right_glyph_index)
+ if (!left || !right)
return 0;
- error = FT_Get_Kerning (face, left_glyph_index, right_glyph_index,
+ error = FT_Get_Kerning (face, left, right,
ft_kerning_default, &kerning);
if (error != FT_Err_Ok)
g_warning ("FT_Get_Kerning returns error: %s",
- pango_ft2_ft_strerror (error));
+ _pango_ft2_ft_strerror (error));
return PANGO_UNITS_26_6 (kerning.x);
}
-/* Get composite font metrics for all subfonts in list
- */
-static void
-get_font_metrics_from_subfonts (PangoFont *font,
- GSList *subfonts,
- PangoFontMetrics *metrics)
-{
- GSList *tmp_list = subfonts;
- gboolean first = TRUE;
-
- metrics->ascent = 0;
- metrics->descent = 0;
-
- while (tmp_list)
- {
- FT_Face face = pango_ft2_get_face (font, GPOINTER_TO_UINT (tmp_list->data));
-
- g_assert (face != NULL);
-
- if (first)
- {
- metrics->ascent = PANGO_UNITS_26_6 (face->size->metrics.ascender);
- metrics->descent = PANGO_UNITS_26_6 (-face->size->metrics.descender);
- metrics->approximate_digit_width = PANGO_UNITS_26_6 (face->size->metrics.max_advance);
- metrics->approximate_char_width = PANGO_UNITS_26_6 (face->size->metrics.max_advance);
- first = FALSE;
- }
- else
- {
- metrics->ascent = MAX (PANGO_UNITS_26_6 (face->size->metrics.ascender), metrics->ascent);
- metrics->descent = MAX (PANGO_UNITS_26_6 (-face->size->metrics.descender), metrics->descent);
- metrics->approximate_digit_width =
- MAX (PANGO_UNITS_26_6 (face->size->metrics.max_advance), metrics->approximate_digit_width);
- metrics->approximate_char_width =
- MAX (PANGO_UNITS_26_6 (face->size->metrics.max_advance), metrics->approximate_char_width);
- }
-
- tmp_list = tmp_list->next;
- }
-}
-
-/* Get composite font metrics for all subfonts resulting from shaping
- * string str with the given font
- *
- * This duplicates quite a bit of code from pango_itemize. This function
- * should die and we should simply add the ability to specify particular
- * fonts when itemizing.
- */
-static void
-get_font_metrics_from_string (PangoFont *font,
- PangoLanguage *language,
- const char *str,
- PangoFontMetrics *metrics)
-{
- const char *start, *p;
- PangoGlyphString *glyph_str = pango_glyph_string_new ();
- PangoEngineShape *shaper, *last_shaper;
- int last_level;
- gunichar *text_ucs4;
- long n_chars, i;
- guint8 *embedding_levels;
- PangoDirection base_dir = PANGO_DIRECTION_LTR;
- GSList *subfonts = NULL;
-
- text_ucs4 = g_utf8_to_ucs4_fast (str, -1, &n_chars);
- if (!text_ucs4)
- return;
-
- embedding_levels = g_new (guint8, n_chars);
- pango_log2vis_get_embedding_levels (text_ucs4, n_chars, &base_dir,
- embedding_levels);
- g_free (text_ucs4);
-
- last_shaper = NULL;
- last_level = 0;
-
- i = 0;
- p = start = str;
- while (*p)
- {
- gunichar wc = g_utf8_get_char (p);
- p = g_utf8_next_char (p);
-
- shaper = pango_font_find_shaper (font, language, wc);
- if (p > start &&
- (shaper != last_shaper || last_level != embedding_levels[i]))
- {
- PangoAnalysis analysis;
- int j;
-
- analysis.shape_engine = shaper;
- analysis.lang_engine = NULL;
- analysis.font = font;
- analysis.level = last_level;
-
- pango_shape (start, p - start, &analysis, glyph_str);
-
- for (j = 0; j < glyph_str->num_glyphs; j++)
- {
- PangoFT2Subfont subfont_index = PANGO_FT2_GLYPH_SUBFONT (glyph_str->glyphs[j].glyph);
- if (!g_slist_find (subfonts, GUINT_TO_POINTER ((guint)subfont_index)))
- subfonts = g_slist_prepend (subfonts, GUINT_TO_POINTER ((guint)subfont_index));
- }
-
- start = p;
- }
-
- last_shaper = shaper;
- last_level = embedding_levels[i];
- i++;
- }
-
- get_font_metrics_from_subfonts (font, subfonts, metrics);
- g_slist_free (subfonts);
-
- pango_glyph_string_free (glyph_str);
- g_free (embedding_levels);
-
- return;
-}
-
static PangoFontMetrics *
pango_ft2_font_get_metrics (PangoFont *font,
PangoLanguage *language)
{
- PangoFT2MetricsInfo *info = NULL; /* Quiet GCC */
- PangoFT2Font *ft2font = (PangoFT2Font *)font;
- GSList *tmp_list;
-
- const char *sample_str = pango_language_get_sample_string (language);
+ PangoFontMetrics *metrics;
+ FT_Face face;
- tmp_list = ft2font->metrics_by_lang;
- while (tmp_list)
- {
- info = tmp_list->data;
-
- if (info->sample_str == sample_str) /* We _don't_ need strcmp */
- break;
+ face = pango_ft2_font_get_face (font);
- tmp_list = tmp_list->next;
- }
-
- if (!tmp_list)
- {
- info = g_new (PangoFT2MetricsInfo, 1);
- info->sample_str = sample_str;
- info->metrics = pango_font_metrics_new ();
- get_font_metrics_from_string (font, language, sample_str, info->metrics);
-
- ft2font->metrics_by_lang = g_slist_prepend (ft2font->metrics_by_lang, info);
- }
-
- return pango_font_metrics_ref (info->metrics);
-}
-
-/**
- * pango_ft2_n_subfonts:
- * @font: a #PangoFont
- *
- * Returns the number of subfonts in a #PangoFT2Font.
- *
- * Return value: the number of subfonts in @font
- **/
-int
-pango_ft2_n_subfonts (PangoFont *font)
-{
- PangoFT2Font *ft2font = (PangoFT2Font *)font;
-
- g_return_val_if_fail (font != NULL, 0);
+ metrics = pango_font_metrics_new ();
+
+ metrics->ascent = PANGO_UNITS_26_6 (face->size->metrics.ascender);
+ metrics->descent = PANGO_UNITS_26_6 (-face->size->metrics.descender);
+ metrics->approximate_digit_width = PANGO_UNITS_26_6 (face->size->metrics.max_advance);
+ metrics->approximate_char_width = PANGO_UNITS_26_6 (face->size->metrics.max_advance);
- return ft2font->n_fonts;
+ return pango_font_metrics_ref (metrics);
}
-/**
- * pango_ft2_get_coverage:
- * @font: a #PangoFT2Font.
- * @language: the language to compute the coverage for.
- *
- * Computes the coverage of @language by @font.
- *
- * Returns: a newly-allocated #PangoCoverage.
- **/
-PangoCoverage *
-pango_ft2_get_coverage (PangoFont *font,
- PangoLanguage *language)
+static PangoCoverage *
+pango_ft2_calc_coverage (PangoFont *font,
+ PangoLanguage *language)
{
- PangoFT2Font *ft2font = (PangoFT2Font *)font;
- PangoCoverage *result = pango_coverage_new ();
- PangoCoverage *tmp;
- PangoGlyph glyph;
+ PangoCoverage *result;
FT_Face face;
gunichar wc;
- int i;
- for (i = 1; i <= ft2font->n_fonts; i++)
+ result = pango_coverage_new ();
+ face = pango_ft2_font_get_face (font);
+ for (wc = 0; wc < 65536; wc++)
{
- tmp = pango_coverage_new ();
- face = pango_ft2_get_face (font, i);
- for (wc = 0; wc < 65536; wc++)
- {
- glyph = PANGO_FT2_MAKE_GLYPH (i, wc);
- if (FT_Get_Char_Index (face, wc))
- pango_coverage_set (tmp, wc, PANGO_COVERAGE_EXACT);
- }
- pango_coverage_max (result, tmp);
- pango_coverage_unref (tmp);
+ if (FT_Get_Char_Index (face, wc))
+ pango_coverage_set (result, wc, PANGO_COVERAGE_EXACT);
}
return result;
}
-/**
- * pango_ft2_font_subfont_open_args:
- * @font: a #PangoFont which must be from the FT2 backend
- * @subfont_id: the id of a subfont within the @font
- * @open_args: pointer where to store the #FT_Open_Args for this subfont
- * @face_index: pointer where to store the face index for this subfont
- *
- * Determine the FT_Open_Args and face index for the specified subfont.
- **/
-void
-pango_ft2_font_subfont_open_args (PangoFont *font,
- PangoFT2Subfont subfont_id,
- FT_Open_Args **open_args,
- FT_Long *face_index)
-{
- PangoFT2Font *ft2font = (PangoFT2Font *)font;
- *open_args = NULL;
- *face_index = 0;
-
- g_return_if_fail (font != NULL);
- g_return_if_fail (PANGO_FT2_IS_FONT (font));
-
- if (subfont_id < 1 || subfont_id > ft2font->n_fonts)
- g_warning ("pango_ft2_font_subfont_open_args: Invalid subfont_id specified");
- else
- {
- *open_args = ft2font->oa[subfont_id-1]->open_args;
- *face_index = ft2font->oa[subfont_id-1]->face_index;
- }
-}
-
static void
pango_ft2_font_dispose (GObject *object)
{
@@ -788,7 +525,7 @@ pango_ft2_font_dispose (GObject *object)
* freed.
*/
if (!ft2font->in_cache && ft2font->fontmap)
- pango_ft2_fontmap_cache_add (ft2font->fontmap, ft2font);
+ _pango_ft2_font_map_cache_add (ft2font->fontmap, ft2font);
G_OBJECT_CLASS (parent_class)->dispose (object);
}
@@ -802,39 +539,25 @@ pango_ft2_free_glyph_info_callback (gpointer key, gpointer value, gpointer data)
}
static void
-free_metrics_info (PangoFT2MetricsInfo *info)
-{
- pango_font_metrics_unref (info->metrics);
- g_free (info);
-}
-
-static void
pango_ft2_font_finalize (GObject *object)
{
PangoFT2Font *ft2font = (PangoFT2Font *)object;
- PangoFT2FontCache *cache = pango_ft2_font_map_get_font_cache (ft2font->fontmap);
- int i;
- PING ((" "));
+ _pango_ft2_font_map_remove (ft2font->fontmap, ft2font);
- for (i = 0; i < ft2font->n_fonts; i++)
+ if (ft2font->face)
{
- if (ft2font->faces[i])
- pango_ft2_font_cache_unload (cache, ft2font->faces[i]);
+ FT_Done_Face (ft2font->face);
+ ft2font->face = NULL;
}
- g_free (ft2font->oa);
- g_free (ft2font->faces);
-
- g_slist_foreach (ft2font->metrics_by_lang, (GFunc)free_metrics_info, NULL);
- g_slist_free (ft2font->metrics_by_lang);
+ pango_font_description_free (ft2font->description);
+ MiniXftPatternDestroy (ft2font->font_pattern);
- if (ft2font->entry)
- pango_ft2_face_remove (ft2font->entry, (PangoFont *)ft2font);
-
g_object_unref (G_OBJECT (ft2font->fontmap));
- g_hash_table_foreach_remove (ft2font->glyph_info, pango_ft2_free_glyph_info_callback, NULL);
+ g_hash_table_foreach_remove (ft2font->glyph_info,
+ pango_ft2_free_glyph_info_callback, NULL);
g_hash_table_destroy (ft2font->glyph_info);
G_OBJECT_CLASS (parent_class)->finalize (object);
@@ -848,7 +571,7 @@ pango_ft2_font_describe (PangoFont *font)
ft2font = PANGO_FT2_FONT (font);
- desc = pango_font_description_copy (ft2font->entry->description);
+ desc = pango_font_description_copy (ft2font->description);
pango_font_description_set_size (desc, ft2font->size);
return desc;
@@ -869,13 +592,31 @@ pango_ft2_get_shaper_map (PangoLanguage *language)
return pango_find_map (language, engine_type_id, render_type_id);
}
-static PangoCoverage *
+PangoCoverage *
pango_ft2_font_get_coverage (PangoFont *font,
PangoLanguage *language)
{
PangoFT2Font *ft2font = (PangoFT2Font *)font;
+ char *filename = NULL;
+ FT_Face face;
+ PangoCoverage *coverage;
+
+ MiniXftPatternGetString (ft2font->font_pattern, XFT_FILE, 0, &filename);
+
+ coverage = _pango_ft2_font_map_get_coverage (ft2font->fontmap, filename);
+
+ if (coverage)
+ return pango_coverage_ref (coverage);
- return pango_ft2_face_get_coverage (ft2font->entry, font, language);
+ /* Ugh, this is going to be SLOW */
+
+ face = pango_ft2_font_get_face (font);
+
+ coverage = pango_ft2_calc_coverage (font, language);
+
+ _pango_ft2_font_map_set_coverage (ft2font->fontmap, filename, coverage);
+
+ return coverage;
}
static PangoEngineShape *
@@ -902,7 +643,7 @@ pango_ft2_font_find_shaper (PangoFont *font,
PangoGlyph
pango_ft2_get_unknown_glyph (PangoFont *font)
{
- return PANGO_FT2_MAKE_GLYPH (1, 0);
+ return 0;
}
/**
@@ -1140,7 +881,7 @@ ft_error_compare (const void *pkey,
}
const char *
-pango_ft2_ft_strerror (FT_Error error)
+_pango_ft2_ft_strerror (FT_Error error)
{
#undef __FTERRORS_H__
#define FT_ERRORDEF( e, v, s ) { e, s },
diff --git a/pango/pangoft2.h b/pango/pangoft2.h
index f2148d10..c792d797 100644
--- a/pango/pangoft2.h
+++ b/pango/pangoft2.h
@@ -31,15 +31,9 @@ G_BEGIN_DECLS
#define PANGO_RENDER_TYPE_FT2 "PangoRenderFT2"
-/* Calls for applications
- */
-PangoContext *pango_ft2_get_context (void);
+/* Calls for applications */
+PangoContext *pango_ft2_get_context (double dpi);
-PangoFont *pango_ft2_load_font (PangoFontMap *fontmap,
- FT_Open_Args **open_args,
- FT_Long *face_indices,
- int n_fonts,
- int size);
void pango_ft2_render (FT_Bitmap *bitmap,
PangoFont *font,
PangoGlyphString *glyphs,
@@ -54,50 +48,18 @@ void pango_ft2_render_layout (FT_Bitmap *bitmap,
int x,
int y);
+PangoFontMap *pango_ft2_font_map_for_display (void);
+void pango_ft2_shutdown_display (void);
/* API for rendering modules
*/
-typedef guint16 PangoFT2Subfont;
-
-#define PANGO_FT2_MAKE_GLYPH(subfont,index) ((subfont)<<16 | (index))
-#define PANGO_FT2_GLYPH_SUBFONT(glyph) ((glyph)>>16)
-#define PANGO_FT2_GLYPH_INDEX(glyph) ((glyph) & 0xFFFF)
-
-int pango_ft2_n_subfonts (PangoFont *font);
PangoGlyph pango_ft2_get_unknown_glyph (PangoFont *font);
int pango_ft2_font_get_kerning (PangoFont *font,
PangoGlyph left,
PangoGlyph right);
-PangoCoverage *pango_ft2_get_coverage (PangoFont *font,
+FT_Face pango_ft2_font_get_face (PangoFont *font);
+PangoCoverage *pango_ft2_font_get_coverage (PangoFont *font,
PangoLanguage *language);
-FT_Face pango_ft2_get_face (PangoFont *font,
- PangoFT2Subfont subfont_index);
-
-/* API for libraries that want to use PangoFT2 mixed with classic
- * FT2 fonts.
- */
-typedef struct _PangoFT2FontCache PangoFT2FontCache;
-
-PangoFT2FontCache *pango_ft2_font_cache_new (FT_Library library);
-void pango_ft2_font_cache_free (PangoFT2FontCache *cache);
-FT_Face pango_ft2_font_cache_load (PangoFT2FontCache *cache,
- FT_Open_Args *args,
- FT_Long face_index);
-void pango_ft2_font_cache_unload (PangoFT2FontCache *cache,
- FT_Face face);
-PangoFontMap *pango_ft2_font_map_for_display (void);
-void pango_ft2_shutdown_display (void);
-PangoFT2FontCache *pango_ft2_font_map_get_font_cache (PangoFontMap *font_map);
-void pango_ft2_font_subfont_open_args (PangoFont *font,
- PangoFT2Subfont subfont_id,
- FT_Open_Args **open_args,
- FT_Long *face_index);
-
-
-/* Debugging.
- */
-void pango_ft2_fontmap_dump (int indent,
- PangoFontMap *fontmap);
G_END_DECLS
diff --git a/pango/pangowin32.c b/pango/pangowin32.c
index d184728e..a6d5052d 100644
--- a/pango/pangowin32.c
+++ b/pango/pangowin32.c
@@ -129,7 +129,7 @@ pango_win32_get_context (void)
}
result = pango_context_new ();
- pango_context_add_font_map (result, pango_win32_font_map_for_display ());
+ pango_context_set_font_map (result, pango_win32_font_map_for_display ());
return result;
}
diff --git a/pango/pangox.c b/pango/pangox.c
index e6bb7a01..dd16ae19 100644
--- a/pango/pangox.c
+++ b/pango/pangox.c
@@ -275,7 +275,7 @@ pango_x_get_context (Display *display)
g_quark_from_static_string ("pango-x-info"),
info, (GDestroyNotify)g_free);
- pango_context_add_font_map (result, pango_x_font_map_for_display (display));
+ pango_context_set_font_map (result, pango_x_font_map_for_display (display));
return result;
}
diff --git a/pango/pangoxft-font.c b/pango/pangoxft-font.c
index 87d9cbec..c398f86d 100644
--- a/pango/pangoxft-font.c
+++ b/pango/pangoxft-font.c
@@ -112,22 +112,21 @@ pango_xft_font_class_init (PangoXftFontClass *class)
PangoXftFont *
_pango_xft_font_new (PangoFontMap *fontmap,
- const PangoFontDescription *description,
- XftFont *xft_font)
+ XftPattern *pattern)
{
PangoXftFont *xfont;
g_return_val_if_fail (fontmap != NULL, NULL);
- g_return_val_if_fail (description != NULL, NULL);
- g_return_val_if_fail (xft_font != NULL, NULL);
+ g_return_val_if_fail (pattern != NULL, NULL);
xfont = (PangoXftFont *)g_object_new (PANGO_TYPE_XFT_FONT, NULL);
xfont->fontmap = fontmap;
+ xfont->font_pattern = pattern;
g_object_ref (G_OBJECT (fontmap));
- xfont->description = pango_font_description_copy (description);
- xfont->xft_font = xft_font;
+ xfont->description = _pango_xft_font_desc_from_pattern (pattern);
+ xfont->xft_font = NULL;
_pango_xft_font_map_add (xfont->fontmap, xfont);
@@ -158,7 +157,7 @@ get_mini_font (PangoFont *font)
xfont->mini_font = pango_font_map_load_font (xfont->fontmap, desc);
pango_font_description_free (desc);
- mini_xft = ((PangoXftFont *)xfont->mini_font)->xft_font;
+ mini_xft = pango_xft_font_get_font (xfont->mini_font);
face = pango_xft_font_get_face (xfont->mini_font);
for (i = 0 ; i < 16 ; i++)
@@ -247,6 +246,7 @@ pango_xft_real_render (Display *display,
gint y)
{
PangoXftFont *xfont = PANGO_XFT_FONT (font);
+ XftFont *xft_font = pango_xft_font_get_font (font);
int i;
int x_off = 0;
@@ -271,12 +271,12 @@ pango_xft_real_render (Display *display,
int j, k;
PangoFont *mini_font = get_mini_font (font);
- XftFont *mini_xft = ((PangoXftFont *)mini_font)->xft_font;
+ XftFont *mini_xft = pango_xft_font_get_font (mini_font);
FT_Face face = pango_xft_font_get_face (xfont->mini_font);
glyph &= ~PANGO_XFT_UNKNOWN_FLAG;
- ys[0] = y + PANGO_PIXELS (glyphs->glyphs[i].geometry.y_offset) - xfont->xft_font->ascent + (xfont->xft_font->ascent + xfont->xft_font->descent - xfont->mini_height * 2 - xfont->mini_pad * 5) / 2;
+ ys[0] = y + PANGO_PIXELS (glyphs->glyphs[i].geometry.y_offset) - xft_font->ascent + (xft_font->ascent + xft_font->descent - xfont->mini_height * 2 - xfont->mini_pad * 5) / 2;
ys[1] = ys[0] + 2 * xfont->mini_pad + xfont->mini_height;
ys[2] = ys[1] + xfont->mini_height + xfont->mini_pad;
@@ -307,12 +307,12 @@ pango_xft_real_render (Display *display,
else
{
if (draw)
- XftDrawString32 (draw, color, xfont->xft_font,
+ XftDrawString32 (draw, color, xft_font,
x + PANGO_PIXELS (x_off + glyphs->glyphs[i].geometry.x_offset),
y + PANGO_PIXELS (glyphs->glyphs[i].geometry.y_offset),
&glyph, 1);
else
- XftRenderString32 (display, src_picture, xfont->xft_font->u.ft.font, dest_picture, 0, 0,
+ XftRenderString32 (display, src_picture, xft_font->u.ft.font, dest_picture, 0, 0,
x + PANGO_PIXELS (x_off + glyphs->glyphs[i].geometry.x_offset),
y + PANGO_PIXELS (glyphs->glyphs[i].geometry.y_offset),
&glyph, 1);
@@ -385,13 +385,13 @@ static PangoFontMetrics *
pango_xft_font_get_metrics (PangoFont *font,
PangoLanguage *language)
{
- PangoXftFont *xfont = (PangoXftFont *)font;
PangoFontMetrics *metrics = pango_font_metrics_new ();
+ XftFont *xft_font = pango_xft_font_get_font (font);
- metrics->ascent = PANGO_SCALE * xfont->xft_font->ascent;
- metrics->descent = PANGO_SCALE * xfont->xft_font->descent;
- metrics->approximate_digit_width = PANGO_SCALE * xfont->xft_font->max_advance_width;
- metrics->approximate_char_width = PANGO_SCALE * xfont->xft_font->max_advance_width;
+ metrics->ascent = PANGO_SCALE * xft_font->ascent;
+ metrics->descent = PANGO_SCALE * xft_font->descent;
+ metrics->approximate_digit_width = PANGO_SCALE * xft_font->max_advance_width;
+ metrics->approximate_char_width = PANGO_SCALE * xft_font->max_advance_width;
return metrics;
}
@@ -428,8 +428,10 @@ pango_xft_font_finalize (GObject *object)
g_object_unref (xfont->ot_info);
pango_font_description_free (xfont->description);
-
- XftFontClose (display, xfont->xft_font);
+ XftPatternDestroy (xfont->font_pattern);
+
+ if (xfont->xft_font)
+ XftFontClose (display, xfont->xft_font);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -447,15 +449,17 @@ pango_xft_font_get_coverage (PangoFont *font,
PangoLanguage *language)
{
PangoXftFont *xfont = (PangoXftFont *)font;
- const gchar *family = pango_font_description_get_family (xfont->description);
+ char *filename = NULL;
FT_Face face;
PangoCoverage *coverage;
Display *display;
int i;
_pango_xft_font_map_get_info (xfont->fontmap, &display, NULL);
+
+ XftPatternGetString (xfont->font_pattern, XFT_FILE, 0, &filename);
- coverage = _pango_xft_font_map_get_coverage (xfont->fontmap, family);
+ coverage = _pango_xft_font_map_get_coverage (xfont->fontmap, filename);
if (coverage)
return pango_coverage_ref (coverage);
@@ -473,7 +477,7 @@ pango_xft_font_get_coverage (PangoFont *font,
pango_coverage_set (coverage, i, PANGO_COVERAGE_EXACT);
}
- _pango_xft_font_map_set_coverage (xfont->fontmap, family, coverage);
+ _pango_xft_font_map_set_coverage (xfont->fontmap, g_strdup (filename), coverage);
return coverage;
}
@@ -485,6 +489,7 @@ pango_xft_font_get_glyph_extents (PangoFont *font,
PangoRectangle *logical_rect)
{
PangoXftFont *xfont = (PangoXftFont *)font;
+ XftFont *xft_font = pango_xft_font_get_font (font);
XGlyphInfo extents;
Display *display;
@@ -500,7 +505,7 @@ pango_xft_font_get_glyph_extents (PangoFont *font,
if (ink_rect)
{
ink_rect->x = 0;
- ink_rect->y = PANGO_SCALE * (- xfont->xft_font->ascent + (xfont->xft_font->ascent + xfont->xft_font->descent - xfont->mini_height * 2 - xfont->mini_pad * 5) / 2);
+ ink_rect->y = PANGO_SCALE * (- xft_font->ascent + (xft_font->ascent + xft_font->descent - xfont->mini_height * 2 - xfont->mini_pad * 5) / 2);
ink_rect->width = PANGO_SCALE * (xfont->mini_width * 2 + xfont->mini_pad * 5);
ink_rect->height = PANGO_SCALE * (xfont->mini_height * 2 + xfont->mini_pad * 5);
}
@@ -508,14 +513,14 @@ pango_xft_font_get_glyph_extents (PangoFont *font,
if (logical_rect)
{
logical_rect->x = 0;
- logical_rect->y = - PANGO_SCALE * xfont->xft_font->ascent;
+ logical_rect->y = - PANGO_SCALE * xft_font->ascent;
logical_rect->width = PANGO_SCALE * (xfont->mini_width * 2 + xfont->mini_pad * 6);
- logical_rect->height = (xfont->xft_font->ascent + xfont->xft_font->descent) * PANGO_SCALE;
+ logical_rect->height = (xft_font->ascent + xft_font->descent) * PANGO_SCALE;
}
}
else
{
- XftTextExtents32 (display, xfont->xft_font, &glyph, 1, &extents);
+ XftTextExtents32 (display, xft_font, &glyph, 1, &extents);
if (ink_rect)
{
@@ -528,9 +533,9 @@ pango_xft_font_get_glyph_extents (PangoFont *font,
if (logical_rect)
{
logical_rect->x = 0;
- logical_rect->y = - xfont->xft_font->ascent * PANGO_SCALE;
+ logical_rect->y = - xft_font->ascent * PANGO_SCALE;
logical_rect->width = extents.xOff * PANGO_SCALE;
- logical_rect->height = (xfont->xft_font->ascent + xfont->xft_font->descent) * PANGO_SCALE;
+ logical_rect->height = (xft_font->ascent + xft_font->descent) * PANGO_SCALE;
}
}
}
@@ -573,11 +578,34 @@ XftFont *
pango_xft_font_get_font (PangoFont *font)
{
PangoXftFont *xfont;
+ Display *display;
+ int screen;
+ FT_Face face;
+ FT_Error error;
+ int charmap;
g_return_val_if_fail (PANGO_XFT_IS_FONT (font), NULL);
xfont = PANGO_XFT_FONT (font);
+ if (xfont->xft_font == NULL)
+ {
+ _pango_xft_font_map_get_info (xfont->fontmap, &display, &screen);
+
+ xfont->xft_font = XftFontOpenPattern (display, xfont->font_pattern);
+
+ face = xfont->xft_font->u.ft.font->face;
+
+ /* There should be a unicode encoding, since we queried for it */
+ for (charmap = 0; charmap < face->num_charmaps; charmap++)
+ if (face->charmaps[charmap]->encoding == ft_encoding_unicode)
+ break;
+
+ g_assert (charmap != face->num_charmaps);
+
+ error = FT_Set_Charmap(face, face->charmaps[charmap]);
+ }
+
return xfont->xft_font;
}
@@ -633,16 +661,16 @@ pango_xft_font_get_unknown_glyph (PangoFont *font,
FT_Face
pango_xft_font_get_face (PangoFont *font)
{
- PangoXftFont *xfont;
+ XftFont *xft_font;
g_return_val_if_fail (PANGO_XFT_IS_FONT (font), NULL);
- xfont = PANGO_XFT_FONT (font);
+ xft_font = pango_xft_font_get_font (font);
- if (xfont->xft_font->core)
+ if (xft_font->core)
return NULL;
else
- return xfont->xft_font->u.ft.font->face;
+ return xft_font->u.ft.font->face;
}
/**
diff --git a/pango/pangoxft-fontmap.c b/pango/pangoxft-fontmap.c
index f6d0f261..6715ebb4 100644
--- a/pango/pangoxft-fontmap.c
+++ b/pango/pangoxft-fontmap.c
@@ -19,11 +19,14 @@
* Boston, MA 02111-1307, USA.
*/
+#include <string.h>
+
#include "pango-fontmap.h"
#include "pangoxft.h"
#include "pangoxft-private.h"
#include "modules.h"
+#include "X11/Xft/Xft.h"
#include "X11/Xft/XftFreetype.h"
/* Number of freed fonts */
@@ -32,6 +35,7 @@
typedef struct _PangoXftFontMap PangoXftFontMap;
typedef struct _PangoXftFamily PangoXftFamily;
typedef struct _PangoXftFace PangoXftFace;
+typedef struct _PangoXftPatternSet PangoXftPatternSet;
#define PANGO_TYPE_XFT_FONT_MAP (pango_xft_font_map_get_type ())
#define PANGO_XFT_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_XFT_FONT_MAP, PangoXftFontMap))
@@ -41,13 +45,19 @@ struct _PangoXftFontMap
{
PangoFontMap parent_instance;
- GHashTable *font_hash;
- GHashTable *coverage_hash;
- GQueue *freed_fonts;
+ GHashTable *fontset_hash; /* Maps PangoFontDescription -> PangoXftPatternSet */
+ GHashTable *coverage_hash; /* Maps font file name -> PangoCoverage */
+
+ GHashTable *fonts; /* Maps XftPattern -> PangoXftFont */
+ GQueue *freed_fonts; /* Fonts in fonts that has been freed */
+ /* List of all families availible */
PangoXftFamily **families;
int n_families; /* -1 == uninitialized */
+ /* List of all fonts (XftPatterns) availible */
+ XftFontSet *font_set;
+
Display *display;
int screen;
};
@@ -67,6 +77,12 @@ struct _PangoXftFamily
int n_faces; /* -1 == uninitialized */
};
+struct _PangoXftPatternSet
+{
+ int n_patterns;
+ XftPattern **patterns;
+};
+
#define PANGO_XFT_TYPE_FACE (pango_xft_face_get_type ())
#define PANGO_XFT_FACE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_XFT_TYPE_FACE, PangoXftFace))
#define PANGO_XFT_IS_FACE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_XFT_TYPE_FACE))
@@ -83,18 +99,24 @@ static GType pango_xft_font_map_get_type (void);
GType pango_xft_family_get_type (void);
GType pango_xft_face_get_type (void);
-static void pango_xft_font_map_init (PangoXftFontMap *fontmap);
-static void pango_xft_font_map_class_init (PangoFontMapClass *class);
-static void pango_xft_font_map_finalize (GObject *object);
-static PangoFont *pango_xft_font_map_load_font (PangoFontMap *fontmap,
- const PangoFontDescription *description);
-static void pango_xft_font_map_list_families (PangoFontMap *fontmap,
- PangoFontFamily ***families,
- int *n_families);
+static void pango_xft_font_map_init (PangoXftFontMap *fontmap);
+static void pango_xft_font_map_class_init (PangoFontMapClass *class);
+static void pango_xft_font_map_finalize (GObject *object);
+static PangoFont * pango_xft_font_map_load_font (PangoFontMap *fontmap,
+ const PangoFontDescription *description);
+static PangoFontset *pango_xft_font_map_load_fontset (PangoFontMap *fontmap,
+ const PangoFontDescription *desc,
+ PangoLanguage *language);
+static void pango_xft_font_map_list_families (PangoFontMap *fontmap,
+ PangoFontFamily ***families,
+ int *n_families);
+
+
+static void pango_xft_font_set_free (PangoXftPatternSet *font_set);
-static void pango_xft_font_map_cache_clear (PangoXftFontMap *xfontmap);
-static void pango_xft_font_map_cache_remove (PangoFontMap *fontmap,
- PangoXftFont *xfont);
+static void pango_xft_font_map_cache_clear (PangoXftFontMap *xfontmap);
+static void pango_xft_font_map_cache_remove (PangoFontMap *fontmap,
+ PangoXftFont *xfont);
static PangoFontClass *parent_class; /* Parent class structure for PangoXftFontMap */
@@ -141,11 +163,98 @@ pango_xft_font_map_class_init (PangoFontMapClass *class)
object_class->finalize = pango_xft_font_map_finalize;
class->load_font = pango_xft_font_map_load_font;
+ class->load_fontset = pango_xft_font_map_load_fontset;
class->list_families = pango_xft_font_map_list_families;
}
static GSList *fontmaps = NULL;
+guint
+pango_xft_pattern_hash (XftPattern *pattern)
+{
+ char *str;
+ int i;
+ double d;
+ guint hash = 0;
+
+ XftPatternGetString (pattern, XFT_FILE, 0, &str);
+ if (str)
+ hash = g_str_hash (str);
+
+ if (XftPatternGetInteger (pattern, XFT_INDEX, 0, &i) == XftResultMatch)
+ hash ^= i;
+
+ if (XftPatternGetDouble (pattern, XFT_PIXEL_SIZE, 0, &d) == XftResultMatch)
+ hash ^= (guint) (d*1000.0);
+
+ return hash;
+}
+
+gboolean
+pango_xft_pattern_equal (XftPattern *pattern1,
+ XftPattern *pattern2)
+{
+ char *file1, *file2;
+ int index1, index2;
+ double size1, size2;
+ XftResult res1, res2;
+ int int1, int2;
+ Bool bool1, bool2;
+
+ XftPatternGetString (pattern1, XFT_FILE, 0, &file1);
+ XftPatternGetString (pattern2, XFT_FILE, 0, &file2);
+
+ g_assert (file1 != NULL && file2 != NULL);
+
+ if (strcmp (file1, file2) != 0)
+ return FALSE;
+
+ if (XftPatternGetInteger (pattern1, XFT_INDEX, 0, &index1) != XftResultMatch)
+ return FALSE;
+
+ if (XftPatternGetInteger (pattern2, XFT_INDEX, 0, &index2) != XftResultMatch)
+ return FALSE;
+
+ if (index1 != index2)
+ return FALSE;
+
+ if (XftPatternGetDouble (pattern1, XFT_PIXEL_SIZE, 0, &size1) != XftResultMatch)
+ return FALSE;
+
+ if (XftPatternGetDouble (pattern2, XFT_PIXEL_SIZE, 0, &size2) != XftResultMatch)
+ return FALSE;
+
+ if (size1 != size2)
+ return FALSE;
+
+ res1 = XftPatternGetInteger (pattern1, XFT_RGBA, 0, &int1);
+ res2 = XftPatternGetInteger (pattern2, XFT_RGBA, 0, &int2);
+ if (res1 != res2 || (res1 == XftResultMatch && int1 != int2))
+ return FALSE;
+
+ res1 = XftPatternGetBool (pattern1, XFT_ANTIALIAS, 0, &bool1);
+ res2 = XftPatternGetBool (pattern2, XFT_ANTIALIAS, 0, &bool2);
+ if (res1 != res2 || (res1 == XftResultMatch && bool1 != bool2))
+ return FALSE;
+
+ res1 = XftPatternGetBool (pattern1, XFT_MINSPACE, 0, &bool1);
+ res2 = XftPatternGetBool (pattern2, XFT_MINSPACE, 0, &bool2);
+ if (res1 != res2 || (res1 == XftResultMatch && bool1 != bool2))
+ return FALSE;
+
+ res1 = XftPatternGetInteger (pattern1, XFT_SPACING, 0, &int1);
+ res2 = XftPatternGetInteger (pattern2, XFT_SPACING, 0, &int2);
+ if (res1 != res2 || (res1 == XftResultMatch && int1 != int2))
+ return FALSE;
+
+ res1 = XftPatternGetInteger (pattern1, XFT_CHAR_WIDTH, 0, &int1);
+ res2 = XftPatternGetInteger (pattern2, XFT_CHAR_WIDTH, 0, &int2);
+ if (res1 != res2 || (res1 == XftResultMatch && int1 != int2))
+ return FALSE;
+
+ return TRUE;
+}
+
static PangoFontMap *
pango_xft_get_font_map (Display *display,
int screen)
@@ -172,9 +281,15 @@ pango_xft_get_font_map (Display *display,
xfontmap->display = display;
xfontmap->screen = screen;
- xfontmap->font_hash = g_hash_table_new ((GHashFunc)pango_font_description_hash,
- (GEqualFunc)pango_font_description_equal);
- xfontmap->coverage_hash = g_hash_table_new (g_str_hash, g_str_equal);
+ xfontmap->fonts = g_hash_table_new ((GHashFunc)pango_xft_pattern_hash,
+ (GEqualFunc)pango_xft_pattern_equal);
+ xfontmap->fontset_hash = g_hash_table_new_full ((GHashFunc)pango_font_description_hash,
+ (GEqualFunc)pango_font_description_equal,
+ (GDestroyNotify)pango_font_description_free,
+ (GDestroyNotify)pango_xft_font_set_free);
+ xfontmap->coverage_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
+ (GDestroyNotify)g_free,
+ (GDestroyNotify)pango_coverage_unref);
xfontmap->freed_fonts = g_queue_new ();
fontmaps = g_slist_prepend (fontmaps, xfontmap);
@@ -211,21 +326,12 @@ pango_xft_get_context (Display *display,
}
result = pango_context_new ();
- pango_context_add_font_map (result, pango_xft_get_font_map (display, screen));
+ pango_context_set_font_map (result, pango_xft_get_font_map (display, screen));
return result;
}
static void
-coverage_foreach (gpointer key, gpointer value, gpointer data)
-{
- PangoCoverage *coverage = value;
-
- g_free (key);
- pango_coverage_unref (coverage);
-}
-
-static void
pango_xft_font_map_finalize (GObject *object)
{
PangoXftFontMap *xfontmap = PANGO_XFT_FONT_MAP (object);
@@ -233,30 +339,34 @@ pango_xft_font_map_finalize (GObject *object)
fontmaps = g_slist_remove (fontmaps, object);
g_queue_free (xfontmap->freed_fonts);
- g_hash_table_destroy (xfontmap->font_hash);
-
- g_hash_table_foreach (xfontmap->coverage_hash, coverage_foreach, NULL);
+ g_hash_table_destroy (xfontmap->fontset_hash);
g_hash_table_destroy (xfontmap->coverage_hash);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
+
+/* Add a mapping from xfont->font_pattern to xfont */
void
_pango_xft_font_map_add (PangoFontMap *fontmap,
- PangoXftFont *xfont)
+ PangoXftFont *xfont)
{
PangoXftFontMap *xfontmap = PANGO_XFT_FONT_MAP (fontmap);
- g_hash_table_insert (xfontmap->font_hash, xfont->description, xfont);
+ g_hash_table_insert (xfontmap->fonts,
+ xfont->font_pattern,
+ xfont);
}
+/* Remove mapping from xfont->font_pattern to xfont */
void
_pango_xft_font_map_remove (PangoFontMap *fontmap,
PangoXftFont *xfont)
{
PangoXftFontMap *xfontmap = PANGO_XFT_FONT_MAP (fontmap);
- g_hash_table_remove (xfontmap->font_hash, xfont->description);
+ g_hash_table_remove (xfontmap->fonts,
+ xfont->font_pattern);
}
static void
@@ -303,38 +413,10 @@ pango_xft_font_map_list_families (PangoFontMap *fontmap,
*families = g_memdup (xfontmap->families, xfontmap->n_families * sizeof (PangoFontFamily *));
}
-static PangoFont *
-pango_xft_font_map_load_font (PangoFontMap *fontmap,
- const PangoFontDescription *description)
+static int
+pango_xft_convert_weight (PangoWeight pango_weight)
{
- PangoXftFontMap *xfontmap = (PangoXftFontMap *)fontmap;
- PangoXftFont *font;
- PangoStyle pango_style;
- int slant;
- PangoWeight pango_weight;
int weight;
- XftFont *xft_font;
-
- font = g_hash_table_lookup (xfontmap->font_hash, description);
-
- if (font)
- {
- if (font->in_cache)
- pango_xft_font_map_cache_remove (fontmap, font);
-
- return (PangoFont *)g_object_ref (G_OBJECT (font));
- }
-
- pango_style = pango_font_description_get_style (description);
-
- if (pango_style == PANGO_STYLE_ITALIC)
- slant = XFT_SLANT_ITALIC;
- else if (pango_style == PANGO_STYLE_OBLIQUE)
- slant = XFT_SLANT_OBLIQUE;
- else
- slant = XFT_SLANT_ROMAN;
-
- pango_weight = pango_font_description_get_weight (description);
if (pango_weight < (PANGO_WEIGHT_NORMAL + PANGO_WEIGHT_LIGHT) / 2)
weight = XFT_WEIGHT_LIGHT;
@@ -346,55 +428,198 @@ pango_xft_font_map_load_font (PangoFontMap *fontmap,
weight = XFT_WEIGHT_BOLD;
else
weight = XFT_WEIGHT_BLACK;
+
+ return weight;
+}
+
+static int
+pango_xft_convert_slant (PangoStyle pango_style)
+{
+ int slant;
+
+ if (pango_style == PANGO_STYLE_ITALIC)
+ slant = XFT_SLANT_ITALIC;
+ else if (pango_style == PANGO_STYLE_OBLIQUE)
+ slant = XFT_SLANT_OBLIQUE;
+ else
+ slant = XFT_SLANT_ROMAN;
+
+ return slant;
+}
+
+static XftPattern *
+pango_xft_make_pattern (const PangoFontDescription *description)
+{
+ XftPattern *pattern;
+ PangoStyle pango_style;
+ int slant;
+ int weight;
+
+ pango_style = pango_font_description_get_style (description);
+
+ slant = pango_xft_convert_slant (pango_style);
+ weight = pango_xft_convert_weight (pango_font_description_get_weight (description));
+
/* To fool Xft into not munging glyph indices, we open it as glyphs-fontspecific
* then set the encoding ourself
*/
- xft_font = XftFontOpen (xfontmap->display, xfontmap->screen,
- XFT_ENCODING, XftTypeString, "glyphs-fontspecific",
- XFT_CORE, XftTypeBool, False,
- XFT_FAMILY, XftTypeString, pango_font_description_get_family (description),
- XFT_WEIGHT, XftTypeInteger, weight,
- XFT_SLANT, XftTypeInteger, slant,
- XFT_SIZE, XftTypeDouble, (double)pango_font_description_get_size (description)/PANGO_SCALE,
- NULL);
-
- if (xft_font)
+ pattern = XftPatternBuild (0,
+ XFT_ENCODING, XftTypeString, "glyphs-fontspecific",
+ XFT_CORE, XftTypeBool, False,
+ XFT_FAMILY, XftTypeString, pango_font_description_get_family (description),
+ XFT_WEIGHT, XftTypeInteger, weight,
+ XFT_SLANT, XftTypeInteger, slant,
+ XFT_SIZE, XftTypeDouble, (double)pango_font_description_get_size (description)/PANGO_SCALE,
+ NULL);
+
+ return pattern;
+}
+
+static PangoFont *
+pango_xft_font_map_new_font (PangoFontMap *fontmap,
+ XftPattern *match)
+{
+ PangoXftFontMap *xfontmap = (PangoXftFontMap *)fontmap;
+ PangoXftFont *font;
+
+ /* Look up cache */
+ font = g_hash_table_lookup (xfontmap->fonts, match);
+
+ if (font)
{
- FT_Face face;
- FT_Error error;
+ /* Revive fonts from cache */
+ if (font->in_cache)
+ pango_xft_font_map_cache_remove (fontmap, font);
- int charmap;
+ return (PangoFont *)g_object_ref (G_OBJECT(font));
+ }
+
+ return (PangoFont *)_pango_xft_font_new (fontmap, XftPatternDuplicate (match));
+}
- g_assert (!xft_font->core);
+static PangoFont *
+pango_xft_font_map_load_font (PangoFontMap *fontmap,
+ const PangoFontDescription *description)
+{
+ PangoXftFontMap *xfontmap = (PangoXftFontMap *)fontmap;
+ XftPattern *pattern, *match;
+ XftResult res;
+
+ pattern = pango_xft_make_pattern (description);
- face = xft_font->u.ft.font->face;
+ match = XftFontMatch (xfontmap->display, xfontmap->screen, pattern, &res);
+ XftPatternDestroy (pattern);
+
+ if (match)
+ return pango_xft_font_map_new_font (fontmap, match);
- for (charmap = 0; charmap < face->num_charmaps; charmap++)
- if (face->charmaps[charmap]->encoding == ft_encoding_unicode)
- break;
+ return NULL;
+}
+
+
+static void
+pango_xft_font_set_free (PangoXftPatternSet *font_set)
+{
+ int i;
+
+ for (i = 0; i < font_set->n_patterns; i++)
+ XftPatternDestroy (font_set->patterns[i]);
+
+ g_free (font_set);
+}
+
+static PangoFontset *
+pango_xft_font_map_load_fontset (PangoFontMap *fontmap,
+ const PangoFontDescription *desc,
+ PangoLanguage *language)
+{
+ PangoXftFontMap *xfontmap = (PangoXftFontMap *)fontmap;
+ XftPattern *pattern, *pattern_copy;
+ XftPattern *match;
+ int i;
+ char *family, *family_res;
+ XftResult res;
+ int id;
+ GPtrArray *array;
+ PangoXftPatternSet *patterns;
+ PangoFontsetSimple *simple;
+
+ patterns = g_hash_table_lookup (xfontmap->fontset_hash, desc);
+
+ if (patterns == NULL)
+ {
+ if (xfontmap->font_set == NULL)
+ xfontmap->font_set = XftListFonts (xfontmap->display, xfontmap->screen,
+ XFT_CORE, XftTypeBool, False,
+ XFT_ENCODING, XftTypeString, "iso10646-1",
+ NULL,
+ XFT_FOUNDRY, XFT_STYLE, XFT_FAMILY,
+ XFT_ENCODING, XFT_FILE, XFT_INDEX,
+ XFT_CORE, XFT_FAMILY, XFT_WEIGHT,
+ XFT_SLANT, XFT_CHAR_WIDTH, XFT_MATRIX,
+ XFT_RGBA, XFT_ANTIALIAS, XFT_MINSPACE,
+ XFT_SPACING, XFT_SIZE,
+ NULL);
+
+ pattern = pango_xft_make_pattern (desc);
- if (charmap == face->num_charmaps)
- goto error;
+ XftConfigSubstitute (pattern);
+ XftDefaultSubstitute (xfontmap->display, xfontmap->screen, pattern);
- error = FT_Set_Charmap(face, face->charmaps[charmap]);
+ pattern_copy = XftPatternDuplicate (pattern);
+
+ array = g_ptr_array_new ();
+ patterns = g_new (PangoXftPatternSet, 1);
+
+ match = NULL;
+ id = 0;
+ while (XftPatternGetString (pattern, XFT_FAMILY, id++, &family) == XftResultMatch)
+ {
+ XftPatternDel (pattern_copy, XFT_FAMILY);
+ XftPatternAddString (pattern_copy, XFT_FAMILY, family);
+
+ match = XftFontSetMatch (&xfontmap->font_set, 1, pattern_copy, &res);
+
+ if (match &&
+ XftPatternGetString (match, XFT_FAMILY, 0, &family_res) == XftResultMatch &&
+ g_ascii_strcasecmp (family, family_res) == 0)
+ {
+ g_ptr_array_add (array, match);
+ match = NULL;
+ }
+ if (match)
+ XftPatternDestroy (match);
+ }
- if (error)
- goto error;
+ if (array->len == 0)
+ {
+ match = XftFontSetMatch (&xfontmap->font_set, 1, pattern, &res);
+ g_ptr_array_add (array, match);
+ }
+
+ XftPatternDestroy (pattern);
+ XftPatternDestroy (pattern_copy);
+
+ patterns->n_patterns = array->len;
+ patterns->patterns = (XftPattern **)g_ptr_array_free (array, FALSE);
- font = _pango_xft_font_new (fontmap, description, xft_font);
+ g_hash_table_insert (xfontmap->fontset_hash,
+ pango_font_description_copy (desc),
+ patterns);
}
- else
- return NULL;
-
- return (PangoFont *)font;
- error:
+
+ simple = pango_fontset_simple_new (language);
- XftFontClose (xfontmap->display, xft_font);
- return NULL;
+ for (i = 0; i < patterns->n_patterns; i++)
+ pango_fontset_simple_append (simple,
+ pango_xft_font_map_new_font (fontmap, patterns->patterns[i]));
+
+ return PANGO_FONTSET (simple);
}
+
void
_pango_xft_font_map_cache_add (PangoFontMap *fontmap,
PangoXftFont *xfont)
@@ -482,8 +707,8 @@ _pango_xft_font_map_get_info (PangoFontMap *fontmap,
* PangoXftFace
*/
-static PangoFontDescription *
-font_desc_from_pattern (XftPattern *pattern)
+PangoFontDescription *
+_pango_xft_font_desc_from_pattern (XftPattern *pattern)
{
PangoFontDescription *desc;
PangoStyle style;
@@ -560,7 +785,7 @@ pango_xft_face_describe (PangoFontFace *face)
result_pattern = XftFontMatch (xfontmap->display, xfontmap->screen, match_pattern, &res);
if (result_pattern)
{
- desc = font_desc_from_pattern (result_pattern);
+ desc = _pango_xft_font_desc_from_pattern (result_pattern);
XftPatternDestroy (result_pattern);
}
@@ -645,7 +870,8 @@ pango_xft_family_list_faces (PangoFontFamily *family,
XftResult res;
res = XftPatternGetString (fontset->fonts[i], XFT_STYLE, 0, &s);
- g_assert (res == XftResultMatch);
+ if (res != XftResultMatch)
+ s = "Regular";
xfamily->faces[i] = g_object_new (PANGO_XFT_TYPE_FACE, NULL);
xfamily->faces[i]->style = g_strdup (s);
diff --git a/pango/pangoxft-private.h b/pango/pangoxft-private.h
index f7e54382..65ca2c85 100644
--- a/pango/pangoxft-private.h
+++ b/pango/pangoxft-private.h
@@ -32,7 +32,8 @@ typedef struct _PangoXftFont PangoXftFont;
struct _PangoXftFont
{
PangoFont parent_instance;
-
+
+ XftPattern *font_pattern;
XftFont *xft_font;
PangoFont *mini_font;
PangoFontMap *fontmap;
@@ -47,8 +48,7 @@ struct _PangoXftFont
};
PangoXftFont * _pango_xft_font_new (PangoFontMap *font,
- const PangoFontDescription *description,
- XftFont *xft_font);
+ XftPattern *pattern);
void _pango_xft_font_map_cache_add (PangoFontMap *fontmap,
PangoXftFont *xfont);
void _pango_xft_font_map_add (PangoFontMap *fontmap,
@@ -64,6 +64,8 @@ void _pango_xft_font_map_get_info (PangoFontMap *fo
Display **display,
int *screen);
+PangoFontDescription * _pango_xft_font_desc_from_pattern (XftPattern *pattern);
+
G_END_DECLS
#endif /* __PANGOXFT_PRIVATE_H__ */