diff options
author | Alexander Larsson <alla@lysator.liu.se> | 2001-11-18 16:06:02 +0000 |
---|---|---|
committer | Alexander Larsson <alexl@src.gnome.org> | 2001-11-18 16:06:02 +0000 |
commit | 0766534429b5830716e782418179ea63f8f1f65d (patch) | |
tree | 1ab6b8c50e572af8320c8f3623b8135276c010f6 /pango | |
parent | b12c0fb6263fd542bb03f8bb10076a0653694f12 (diff) | |
download | pango-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')
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 (¤t_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 (¤t_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 (¤t_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 (¤t_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 (¤t_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 (¤t_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__ */ |