diff options
52 files changed, 11068 insertions, 2105 deletions
@@ -1,3 +1,55 @@ +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. + 2001-11-14 Matthias Clasen <matthiasc@poet.de> * docs/Makefile.am (MKDB_OPTIONS): Add --sgml-mode. diff --git a/ChangeLog.pre-1-0 b/ChangeLog.pre-1-0 index 01311568..10f16b3d 100644 --- a/ChangeLog.pre-1-0 +++ b/ChangeLog.pre-1-0 @@ -1,3 +1,55 @@ +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. + 2001-11-14 Matthias Clasen <matthiasc@poet.de> * docs/Makefile.am (MKDB_OPTIONS): Add --sgml-mode. diff --git a/ChangeLog.pre-1-10 b/ChangeLog.pre-1-10 index 01311568..10f16b3d 100644 --- a/ChangeLog.pre-1-10 +++ b/ChangeLog.pre-1-10 @@ -1,3 +1,55 @@ +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. + 2001-11-14 Matthias Clasen <matthiasc@poet.de> * docs/Makefile.am (MKDB_OPTIONS): Add --sgml-mode. diff --git a/ChangeLog.pre-1-2 b/ChangeLog.pre-1-2 index 01311568..10f16b3d 100644 --- a/ChangeLog.pre-1-2 +++ b/ChangeLog.pre-1-2 @@ -1,3 +1,55 @@ +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. + 2001-11-14 Matthias Clasen <matthiasc@poet.de> * docs/Makefile.am (MKDB_OPTIONS): Add --sgml-mode. diff --git a/ChangeLog.pre-1-4 b/ChangeLog.pre-1-4 index 01311568..10f16b3d 100644 --- a/ChangeLog.pre-1-4 +++ b/ChangeLog.pre-1-4 @@ -1,3 +1,55 @@ +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. + 2001-11-14 Matthias Clasen <matthiasc@poet.de> * docs/Makefile.am (MKDB_OPTIONS): Add --sgml-mode. diff --git a/ChangeLog.pre-1-6 b/ChangeLog.pre-1-6 index 01311568..10f16b3d 100644 --- a/ChangeLog.pre-1-6 +++ b/ChangeLog.pre-1-6 @@ -1,3 +1,55 @@ +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. + 2001-11-14 Matthias Clasen <matthiasc@poet.de> * docs/Makefile.am (MKDB_OPTIONS): Add --sgml-mode. diff --git a/ChangeLog.pre-1-8 b/ChangeLog.pre-1-8 index 01311568..10f16b3d 100644 --- a/ChangeLog.pre-1-8 +++ b/ChangeLog.pre-1-8 @@ -1,3 +1,55 @@ +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. + 2001-11-14 Matthias Clasen <matthiasc@poet.de> * docs/Makefile.am (MKDB_OPTIONS): Add --sgml-mode. diff --git a/configure.in b/configure.in index 2b0ac3a2..7b0036f2 100644 --- a/configure.in +++ b/configure.in @@ -15,7 +15,9 @@ AM_CONFIG_HEADER(config.h) AC_PROG_CC AC_LIBTOOL_WIN32_DLL AM_PROG_LIBTOOL - +AM_PROG_LEX +AC_PROG_YACC + AC_MSG_CHECKING([for some Win32 platform]) case "$host" in *-*-mingw*|*-*-cygwin*) @@ -553,6 +555,7 @@ AC_OUTPUT([ Makefile pango/Makefile pango/mini-fribidi/Makefile +pango/mini-xft/Makefile pango/opentype/Makefile pango/makefile.mingw pango/pango.rc diff --git a/modules/basic/basic-ft2.c b/modules/basic/basic-ft2.c index 9c5dac66..15779904 100644 --- a/modules/basic/basic-ft2.c +++ b/modules/basic/basic-ft2.c @@ -119,21 +119,13 @@ static PangoGlyph find_char (PangoFont *font, gunichar wc) { - int i; - int n_subfonts; - - n_subfonts = pango_ft2_n_subfonts (font); + FT_Face face; + FT_UInt index; - for (i = 0; i < n_subfonts; i++) - { - FT_Face face; - FT_UInt index; - - face = pango_ft2_get_face (font, i+1); - index = FT_Get_Char_Index (face, wc); - if (index && index <= face->num_glyphs) - return PANGO_FT2_MAKE_GLYPH (i+1, index); - } + face = pango_ft2_font_get_face (font); + index = FT_Get_Char_Index (face, wc); + if (index && index <= face->num_glyphs) + return index; return 0; } @@ -285,19 +277,7 @@ static PangoCoverage * basic_engine_get_coverage (PangoFont *font, PangoLanguage *lang) { - PangoCoverage *result; -#if 0 - gunichar wc; - - result = pango_coverage_new (); - - for (wc = 0; wc < 65536; wc++) - if (find_char (font, wc)) - pango_coverage_set (result, wc, PANGO_COVERAGE_EXACT); -#else - result = pango_ft2_get_coverage (font, lang); -#endif - return result; + return pango_ft2_font_get_coverage (font, lang); } static PangoEngine * @@ -346,3 +326,4 @@ void MODULE_ENTRY(script_engine_unload) (PangoEngine *engine) { } + 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__ */ |