Git init
authorKibum Kim <kb0929.kim@samsung.com>
Fri, 6 Jan 2012 15:49:18 +0000 (00:49 +0900)
committerKibum Kim <kb0929.kim@samsung.com>
Fri, 6 Jan 2012 15:49:18 +0000 (00:49 +0900)
124 files changed:
AUTHORS [new file with mode: 0644]
COPYING [new file with mode: 0644]
ChangeLog [new file with mode: 0755]
Makefile.am [new file with mode: 0755]
README [new file with mode: 0644]
autogen.sh [new file with mode: 0644]
configure.ac [new file with mode: 0755]
debian/README.source [new file with mode: 0644]
debian/changelog [new file with mode: 0755]
debian/compat [new file with mode: 0644]
debian/control [new file with mode: 0755]
debian/copyright [new file with mode: 0644]
debian/libxfont-dev.install [new file with mode: 0755]
debian/libxfont1-udeb.install [new file with mode: 0644]
debian/libxfont1.install [new file with mode: 0644]
debian/rules [new file with mode: 0755]
debian/watch [new file with mode: 0644]
debian/xsfbs/repack.sh [new file with mode: 0644]
debian/xsfbs/xsfbs.mk [new file with mode: 0644]
debian/xsfbs/xsfbs.sh [new file with mode: 0644]
doc/Makefile.am [new file with mode: 0755]
doc/fontlib.css [new file with mode: 0644]
doc/fontlib.xml [new file with mode: 0755]
doc/fontlib.xsl [new file with mode: 0644]
include/X11/fonts/bdfint.h [new file with mode: 0755]
include/X11/fonts/bitmap.h [new file with mode: 0755]
include/X11/fonts/bufio.h [new file with mode: 0755]
include/X11/fonts/fntfil.h [new file with mode: 0755]
include/X11/fonts/fntfilio.h [new file with mode: 0755]
include/X11/fonts/fntfilst.h [new file with mode: 0755]
include/X11/fonts/fontconf.h.in [new file with mode: 0755]
include/X11/fonts/fontencc.h [new file with mode: 0755]
include/X11/fonts/fontmisc.h [new file with mode: 0755]
include/X11/fonts/fontshow.h [new file with mode: 0755]
include/X11/fonts/fontutil.h [new file with mode: 0755]
include/X11/fonts/fontxlfd.h [new file with mode: 0755]
include/X11/fonts/pcf.h [new file with mode: 0755]
packaging/libXfont.spec [new file with mode: 0644]
src/FreeType/Makefile.am [new file with mode: 0644]
src/FreeType/ft.h [new file with mode: 0755]
src/FreeType/ftenc.c [new file with mode: 0755]
src/FreeType/ftfuncs.c [new file with mode: 0755]
src/FreeType/ftfuncs.h [new file with mode: 0755]
src/FreeType/fttools.c [new file with mode: 0755]
src/FreeType/xttcap.c [new file with mode: 0755]
src/FreeType/xttcap.h [new file with mode: 0755]
src/Makefile.am [new file with mode: 0755]
src/bitmap/Makefile.am [new file with mode: 0755]
src/bitmap/bdfread.c [new file with mode: 0755]
src/bitmap/bdfutils.c [new file with mode: 0755]
src/bitmap/bitmap.c [new file with mode: 0755]
src/bitmap/bitmapfunc.c [new file with mode: 0755]
src/bitmap/bitmaputil.c [new file with mode: 0755]
src/bitmap/bitscale.c [new file with mode: 0755]
src/bitmap/fontink.c [new file with mode: 0755]
src/bitmap/pcfread.c [new file with mode: 0755]
src/bitmap/pcfwrite.c [new file with mode: 0755]
src/bitmap/snfread.c [new file with mode: 0755]
src/bitmap/snfstr.h [new file with mode: 0755]
src/builtins/Makefile.am [new file with mode: 0644]
src/builtins/buildfont [new file with mode: 0644]
src/builtins/builtin.h [new file with mode: 0755]
src/builtins/dir.c [new file with mode: 0644]
src/builtins/file.c [new file with mode: 0755]
src/builtins/fonts.c [new file with mode: 0755]
src/builtins/fpe.c [new file with mode: 0755]
src/builtins/render.c [new file with mode: 0755]
src/dummy.c [new file with mode: 0644]
src/fc/Makefile.am [new file with mode: 0644]
src/fc/fsconvert.c [new file with mode: 0755]
src/fc/fserve.c [new file with mode: 0755]
src/fc/fserve.h [new file with mode: 0755]
src/fc/fservestr.h [new file with mode: 0755]
src/fc/fsio.c [new file with mode: 0755]
src/fc/fsio.h [new file with mode: 0755]
src/fc/fslibos.h [new file with mode: 0755]
src/fc/fstrans.c [new file with mode: 0644]
src/fontfile/Makefile.am [new file with mode: 0644]
src/fontfile/bitsource.c [new file with mode: 0755]
src/fontfile/bufio.c [new file with mode: 0755]
src/fontfile/bunzip2.c [new file with mode: 0755]
src/fontfile/catalogue.c [new file with mode: 0755]
src/fontfile/decompress.c [new file with mode: 0755]
src/fontfile/defaults.c [new file with mode: 0755]
src/fontfile/dirfile.c [new file with mode: 0755]
src/fontfile/fileio.c [new file with mode: 0755]
src/fontfile/filewr.c [new file with mode: 0755]
src/fontfile/fontdir.c [new file with mode: 0755]
src/fontfile/fontencc.c [new file with mode: 0755]
src/fontfile/fontfile.c [new file with mode: 0755]
src/fontfile/fontscale.c [new file with mode: 0755]
src/fontfile/gunzip.c [new file with mode: 0755]
src/fontfile/register.c [new file with mode: 0644]
src/fontfile/renderers.c [new file with mode: 0755]
src/stubs/Makefile.am [new file with mode: 0644]
src/stubs/cauthgen.c [new file with mode: 0644]
src/stubs/csignal.c [new file with mode: 0644]
src/stubs/delfntcid.c [new file with mode: 0644]
src/stubs/errorf.c [new file with mode: 0644]
src/stubs/fatalerror.c [new file with mode: 0644]
src/stubs/findoldfnt.c [new file with mode: 0644]
src/stubs/getcres.c [new file with mode: 0644]
src/stubs/getdefptsize.c [new file with mode: 0644]
src/stubs/getnewfntcid.c [new file with mode: 0644]
src/stubs/gettime.c [new file with mode: 0644]
src/stubs/initfshdl.c [new file with mode: 0644]
src/stubs/regfpefunc.c [new file with mode: 0644]
src/stubs/rmfshdl.c [new file with mode: 0644]
src/stubs/servclient.c [new file with mode: 0644]
src/stubs/setfntauth.c [new file with mode: 0644]
src/stubs/stfntcfnt.c [new file with mode: 0644]
src/stubs/stubs.h [new file with mode: 0755]
src/util/Makefile.am [new file with mode: 0644]
src/util/atom.c [new file with mode: 0755]
src/util/fontaccel.c [new file with mode: 0755]
src/util/fontnames.c [new file with mode: 0755]
src/util/fontutil.c [new file with mode: 0755]
src/util/fontxlfd.c [new file with mode: 0755]
src/util/format.c [new file with mode: 0755]
src/util/miscutil.c [new file with mode: 0755]
src/util/patcache.c [new file with mode: 0755]
src/util/private.c [new file with mode: 0755]
src/util/utilbitmap.c [new file with mode: 0755]
xfont.pc.in [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..05edf1e
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,7 @@
+Keith Packard, MIT X Consortium and SuSE, Inc.
+Dave Lemke, Network Computing Devices (font server)
+Mark Leisher, Juliusz Chroboczek, (Freetype)
+Digital Equipment Corporation (bitmap) (Phil Karlton or Susan Angebrandt???)
+Shunsuke Akiyama (TrueType)
+
+Our apologies if anyone has been missed.
diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..b271bf3
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,262 @@
+Copyright Â© 2007 Red Hat, Inc
+Copyright Â© 2008,2009 Sun Microsystems, Inc.  All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+Copyright (c) 1997 by Mark Leisher
+Copyright (c) 1998-2003 by Juliusz Chroboczek
+Copyright (c) 1998 Go Watanabe, All rights reserved.
+Copyright (c) 1998 Kazushi (Jam) Marukawa, All rights reserved.
+Copyright (c) 1998 Takuya SHIOZAKI, All rights reserved.
+Copyright (c) 1998 X-TrueType Server Project, All rights reserved.
+Copyright (c) 2003-2004 After X-TT Project, All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+
+Copyright 1990, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+
+Copyright 1999 SuSE, 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 SuSE not be used in advertising or
+publicity pertaining to distribution of the software without specific,
+written prior permission.  SuSE makes no representations about the
+suitability of this software for any purpose.  It is provided "as is"
+without express or implied warranty.
+
+SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+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.
+
+
+Copyright 1990 Network Computing Devices
+
+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 Network Computing Devices not be used
+in advertising or publicity pertaining to distribution of the software
+without specific, written prior permission.  Network Computing Devices
+makes no representations about the suitability of this software for any
+purpose.  It is provided "as is" without express or implied warranty.
+
+NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+IN NO EVENT SHALL NETWORK COMPUTING DEVICES 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.
+
+
+Copyright 1990 Network Computing Devices
+
+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 names of Network Computing Devices, or Digital
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+NETWORK COMPUTING DEVICES, AND DIGITAL AND DISCLAIM ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES,
+OR DIGITAL 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.
+
+
+[Note: clause 3 in the following license, the "advertising clause", was
+rescinded by Berkeley in 1999.  See
+<ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change>]
+
+Copyright (c) 1991, 1993
+     The Regents of the University of California.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. All advertising materials mentioning features or use of this software
+   must display the following acknowledgement:
+     This product includes software developed by the University of
+     California, Berkeley and its contributors.
+4. Neither the name of the University nor the names of its contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+
+Copyright (c) 1998-1999 Shunsuke Akiyama <akiyama@jp.FreeBSD.org>.
+All rights reserved.
+Copyright (c) 1998-1999 X-TrueType Server Project, All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+
+Copyright Â© 2004 Keith Packard
+
+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.
+
+
+/* lib/font/fontfile/gunzip.c
+   written by Mark Eichin <eichin@kitten.gen.ma.us> September 1996.
+   intended for inclusion in X11 public releases. */
+
+
+Copyright (c) 1999  The XFree86 Project Inc.
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The XFree86 Project
+Inc. shall not be used in advertising or otherwise to promote the
+sale, use or other dealings in this Software without prior written
+authorization from The XFree86 Project Inc..
diff --git a/ChangeLog b/ChangeLog
new file mode 100755 (executable)
index 0000000..b734a4a
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,1768 @@
+commit 12157fbebc35c2d039df2df4fc5ac2b299eeec03
+Author: Alan Coopersmith <alan.coopersmith@oracle.com>
+Date:   Thu Oct 28 20:43:27 2010 -0700
+
+    libXfont 1.4.3
+    
+    Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
+
+commit f29f1d68d7eca96e45ba3758686be07993d82e03
+Author: Jesse Adkins <jesserayadkins@gmail.com>
+Date:   Tue Sep 28 13:30:02 2010 -0700
+
+    Purge cvs tags.
+    
+    Signed-off-by: Jesse Adkins <jesserayadkins@gmail.com>
+    Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
+
+commit 6628b4d82426cf9ac240da363cd8a8252e6f71ef
+Author: Jeremy Huddleston <jeremyhu@apple.com>
+Date:   Mon Sep 27 12:31:50 2010 -0700
+
+    FreeType: Cleanup MUMBLE and fix printing of XLFD in debug spew.
+    
+    Signed-off-by: Jeremy Huddleston <jeremyhu@apple.com>
+
+commit c482a2c104aa5cd1a265c2ca310a308dcc418fe7
+Author: Yaakov Selkowitz <yselkowitz@users.sourceforge.net>
+Date:   Wed Apr 14 05:58:28 2010 -0500
+
+    Revert "Bug #6247: Fix build on Cygwin"
+    
+    libtool requires the '-no-undefined' flag in order to create shared
+    libraries on PE/COFF platforms (Cygwin/MinGW); on other platforms this
+    flag has no effect.
+    
+    The problem with libXfont is that PE weak symbols do not behave exactly
+    as they do on ELF platforms.  Since PE binaries (both executables and
+    libraries) must have all symbols resolved at link time, there is no way
+    for the real symbols in xserver to "displace" those in libXfont at
+    runtime, so the result is that libXfont uses its stubs, which do
+    nothing, and xserver ends up unable to find its fonts.
+    
+    Solving this will require either significant changes to libXfont or some
+    major improvement to the toolchain to handle this case.  Until that
+    happens, removing '-no-undefined' will result in a static-only library
+    on these platforms, which is the only currently working solution.
+    
+    http://sourceware.org/bugzilla/show_bug.cgi?id=11306
+    http://cygwin.com/ml/cygwin/2010-04/msg00281.html
+    
+    This reverts commit 69c4ae1e3e14a58bc2eb9b9b8820dc7183b82a67.
+    
+    Conflicts:
+    
+       ChangeLog
+    
+    Signed-off-by: Yaakov Selkowitz <yselkowitz@users.sourceforge.net>
+
+commit 455ec66e82e3c4bedd9e789d2ab33030b8e64ffa
+Author: Alan Coopersmith <alan.coopersmith@oracle.com>
+Date:   Sun Aug 8 00:19:36 2010 -0700
+
+    Fix builds with Sun compilers
+    
+    Sun compilers use #pragma weak in the *.c files to declare weak symbols,
+    so should have weak defined to empty, but not define NO_WEAK_SYMBOLS
+    
+    Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
+
+commit 0386fa77367a305deea3cc27f8a3865cc3c467c0
+Author: Jeremy Huddleston <jeremyhu@apple.com>
+Date:   Sat Jul 10 10:08:21 2010 -0700
+
+    darwin: Fix build regression introduced by previous patch
+    
+    Signed-off-by: Jeremy Huddleston <jeremyhu@apple.com>
+
+commit 8f75706901da0141590d46f0f898e5678feac953
+Author: Jon TURNEY <jon.turney@dronecode.org.uk>
+Date:   Mon Jun 28 17:56:07 2010 +0100
+
+    Build fix for platforms which don't have weak linkage
+    
+    Since we fix this by removing the serverGeneration symbol, assuming
+    an external definition will be provided, this means on Windows libXfont
+    can only be built as a static library (since PE shared libraries cannot
+    contain undefined symbols).  This produces a libXfont which might only
+    be useful to the xserver, but the only other users we might care about
+    are xfs, which is obsolete, and bdftopcf, which fortunately doesn't
+    pull in any objects which reference serverGeneration from libXfont.
+    
+    Signed-off-by: Jon TURNEY <jon.turney@dronecode.org.uk>
+    Reviewed-by: Colin Harrison <colin.harrison@virgin.net>
+
+commit 5c49c956e9c85d89f6b2e719eb9b6fbde62c2f72
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Mon Jun 28 13:18:22 2010 -0400
+
+    doc: use xorg-docs xorg.css stylesheet
+    
+    Use latest DocBook XML util-macros infrastructure
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit 27270de56f7da5e047784434f3b29fa672f97ffd
+Author: Tiago Vignatti <tiago.vignatti@nokia.com>
+Date:   Thu Jun 10 16:29:37 2010 +0300
+
+    libXfont 1.4.2
+    
+    Signed-off-by: Tiago Vignatti <tiago.vignatti@nokia.com>
+    Reviewed-by: Mikhail Gusarov <dottedmag@dottedmag.net>
+    Reviewed-by: Alex Deucher <alexdeucher@gmail.com>
+    Reviewed-by: Daniel Stone <daniel@fooishbar.org>
+
+commit a85f4fc6142349517aaa4cf6bc8049e2d85c1006
+Author: Tiago Vignatti <tiago.vignatti@nokia.com>
+Date:   Thu Jun 10 16:18:05 2010 +0300
+
+    Use one single function to register fpe functions
+    
+    X server doesn't need to understand fpe internals, so let it transparent
+    turning all registration functions in a single one. For that, fill the already
+    existent register_fpe_functions().
+    
+    Some X servers don't want font server support, so this patch also sets font
+    server support to be configured in build time.
+    
+    In my machine, I see 20kB of RSS being saved in libXfont mapped in Xorg
+    process when I disabled font server support and other kind of fonts in the
+    library (--disable-pcfformat --disable-bdfformat --disable-snfformat
+    --disable-freetype --disable-fc).
+    
+    The default library built was taking:
+       text    data     bss     dec     hex filename
+     261847    4484    1536  267867   4165b ./lib/libXfont.so
+    
+    and with these flags, it jumps to:
+       text    data     bss     dec     hex filename
+     157764    2428    1188  161380   27664 ./lib/libXfont.so
+    
+    Signed-off-by: Tiago Vignatti <tiago.vignatti@nokia.com>
+    Reviewed-by: Mikhail Gusarov <dottedmag@dottedmag.net>
+    Reviewed-by: Alex Deucher <alexdeucher@gmail.com>
+    Reviewed-by: Daniel Stone <daniel@fooishbar.org>
+
+commit d137c81b83e0a6f68989c37035d0c950bb43fcc5
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Thu Apr 1 14:12:47 2010 -0400
+
+    config: fontconf.h.in is redundant in EXTRA_DIST
+    
+    Output files listed in AC_CONFIG_HEADERS or AC_OUTPUT have
+    their input files (typically .in) included in the tarball.
+    
+    Reviewed-by: Dan Nicholson <dbn.lists@gmail.com>
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit d8d901323776599c8392f9b973ba129c3af45a4b
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Tue Mar 30 09:26:13 2010 -0400
+
+    config: replace obsolete AM_CONFIG_HEADER with AC_CONFIG_HEADERS
+    
+    There are 2 headers to generate. The first one (config.h)
+    is picked up by autoheader to generate the familiar config.h.in
+    input file. The others in the list (or in subsequent AC_CONFIG_HEADERS
+    macro calls) are generated from their existing matching template,
+    e.g. fontconf.h.in.
+    
+    When multiple headers are listed in the same macro call,
+    they cannot be separated by a new line like we do in AC_OUTPUT.
+    
+    Reviewed-by: Dan Nicholson <dbn.lists@gmail.com>
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit df94cb141f02f123a64b0ef7abf5f593c1b27e13
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Wed Mar 31 20:21:47 2010 -0400
+
+    Revert "config: replace obsolete AM_CONFIG_HEADER with AC_CONFIG_HEADERS"
+    
+    This reverts commit 8e84687b26be6e8f5da4fce173c0a134eb07f4f3.
+    
+    Until the issue is resolved on MAC O/S
+    http://tinderbox.x.org/builds/2010-03-31-0030/logs/libXfont/
+
+commit 8e84687b26be6e8f5da4fce173c0a134eb07f4f3
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Tue Mar 30 09:26:13 2010 -0400
+
+    config: replace obsolete AM_CONFIG_HEADER with AC_CONFIG_HEADERS
+    
+    Both headers end up created by the same macro.
+    
+    Reviewed-by: Dan Nicholson <dbn.lists@gmail.com>
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit a7b7bc72b9ad061ed164601d2d18dbffd6ec1f4f
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Mon Mar 29 14:53:48 2010 -0400
+
+    config: remove the pkgconfig pc.in file from EXTRA_DIST
+    
+    Automake always includes it in the tarball.
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit f77258d0b286c2fd2a2fee36e42280016e310b10
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Sat Mar 27 17:06:34 2010 -0400
+
+    config: remove protection for AS_HELP_STRING for old autoconf
+    
+    No longer needed as modules will not configure with 2.57.
+    AS_HELP_STRING was introduced in 2.58. The minimum level
+    is now 2.60.
+    
+    Reviewed-by: Jeremy Huddleston <jeremyhu@apple.com>
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit a79a22bfcb344c47f2659e4178fd79f8555fbcfd
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Thu Mar 11 10:11:23 2010 -0500
+
+    doc: specify 0.0.20 as the minimum version for xmlto
+    
+    Older versions do not have fop backend.
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit a76488f75f23b8e08763e28b2fa56352e7b04e19
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Sat Jan 30 13:13:33 2010 -0500
+
+    doc: use new macros to control doc generation
+    
+    Namely XORG_WITH_FOP for the fop backend (pdf) and
+    XORG_ENABLE_DEVEL_DOCS for the generation of all docs
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit 360f10333ac19f033ea64a8360c4886fbb657890
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Wed Jan 20 11:46:21 2010 -0500
+
+    config: replace custom code with reusable macro XORG_WITH_XMLTO
+    
+    XORG_WITH_XMLTO provides additional functions like a configure
+    option which allow platform builders to control the usage of
+    the xmlto program.
+    
+    This is a requirement from platforms that do not have such doc tool.
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit 24a257ca5b70e168564f0c6527e60bb06b61be8c
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Thu Jan 14 21:39:11 2010 -0800
+
+    Update Sun license notices to current X.Org standard form
+    
+    Signed-off-by: Alan Coopersmith <alan.coopersmith@sun.com>
+
+commit d1c9028a410a10ef1b27c990f55de836eb948887
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Fri Nov 27 20:56:04 2009 -0500
+
+    Makefile.am: add ChangeLog and INSTALL on MAINTAINERCLEANFILES
+    
+    Now that the INSTALL file is generated.
+    Allows running make maintainer-clean.
+
+commit 72353a449e8dbf82a53a1d7958755198e989d892
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Wed Oct 28 15:28:32 2009 -0400
+
+    configure.ac: AM_MAINTAINER_MODE missing #24238
+    
+    This turns off maintainer mode build rules in tarballs.
+    Works in conjunction with autogen.sh --enable-maintainer-mode
+    For all X.Org components.
+
+commit 489e7b2cb3371042552489385902a98dc1cd976a
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Wed Oct 28 14:09:10 2009 -0400
+
+    INSTALL, NEWS, README or AUTHORS files are missing/incorrect #24206
+    
+    Add missing INSTALL file. Use standard GNU file on building tarball
+    README may have been updated
+    Remove AUTHORS file as it is empty and no content available yet.
+    Remove NEWS file as it is empty and no content available yet.
+
+commit c22d67cc78c27d19bb6eaba5bf71b66444ed4a40
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Tue Oct 27 15:07:25 2009 -0400
+
+    Deploy the new XORG_DEFAULT_OPTIONS #24242
+    
+    This macro aggregate a number of existing macros that sets commmon
+    X.Org components configuration options. It shields the configuration file from
+    future changes.
+
+commit 271382b01995469eb60035d38880f9d3665d4c4c
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Mon Oct 26 22:08:43 2009 -0400
+
+    Makefile.am: ChangeLog not required: EXTRA_DIST or *CLEANFILES #24432
+    
+    ChangeLog filename is known to Automake and requires no further
+    coding in the makefile.
+
+commit 9be83ae94cd82b447ed59ba0869f9e94ed9018f7
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Thu Oct 22 15:34:34 2009 -0400
+
+    .gitignore: use common defaults with custom section # 24239
+    
+    Using common defaults will reduce errors and maintenance.
+    Only the very small or inexistent custom section need periodic maintenance
+    when the structure of the component changes. Do not edit defaults.
+
+commit 489924bfb693a844f8f8ad6023fc78e4a212bef6
+Author: Yaakov Selkowitz <yselkowitz@users.sourceforge.net>
+Date:   Wed Oct 14 11:31:59 2009 -0500
+
+    Add -lbz2 to Libs.private if bzip2 is enabled
+    
+    This is required on Cygwin, which must link the xservers with a static
+    libXfont due to poor weak-symbol support.  Z_LIBS includes -lz and, if
+    bzip2 support is enabled, -lbz2.
+    
+    Signed-off-by: Yaakov Selkowitz <yselkowitz@users.sourceforge.net>
+    Acked-by: Julien Cristau <jcristau@debian.org>
+
+commit 64f21944c5f374b0da63657f01e289b34d00904c
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Fri Oct 9 17:38:33 2009 -0700
+
+    libXfont 1.4.1
+    
+    Signed-off-by: Alan Coopersmith <alan.coopersmith@sun.com>
+
+commit 947d3162f5edaaa05bbbfcfe2303d0c8b796f9ca
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Wed Oct 7 13:05:26 2009 -0700
+
+    Remove unused setting of ENCODINGSDIR
+    
+    Seems to have been a leftover from before the encoding code was split
+    out into libfontenc by XFree86
+    
+    Signed-off-by: Alan Coopersmith <alan.coopersmith@sun.com>
+
+commit 18053ffbf92473ffce23a3c5182de92b608b9cdf
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Wed Oct 7 10:44:27 2009 -0700
+
+    Convert documentation from troff to DocBook/XML
+    
+    Signed-off-by: Alan Coopersmith <alan.coopersmith@sun.com>
+
+commit 96a4daad7097ce94d4340a4e9ce779e378f9b83c
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Wed Oct 7 08:31:54 2009 -0700
+
+    Move fontlib.ms from xorg-docs
+    
+    Signed-off-by: Alan Coopersmith <alan.coopersmith@sun.com>
+
+commit b7be4a976a59f3149590cf62a2ea8144aa729c2a
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Tue Oct 6 13:03:25 2009 -0700
+
+    Migrate to xorg macros 1.3 & XORG_DEFAULT_OPTIONS
+    
+    Signed-off-by: Alan Coopersmith <alan.coopersmith@sun.com>
+
+commit 18c5e2ff1097880e8dea951079ae49a93ec315b0
+Author: Bob Ham <rah@bash.sh>
+Date:   Tue Sep 15 14:28:12 2009 +1000
+
+     Fixed int(*)()->double cast warning
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 0045b2555b288099c90b65f97bd4b4a5ebc8c688
+Author: Adam Jackson <ajax@redhat.com>
+Date:   Wed Feb 18 13:53:14 2009 -0500
+
+    libXfont 1.4.0
+
+commit 04ced93e997b185b5d9124cacc96fa39a77b2ab7
+Author: Peter Astrand <astrand@maggie.lkpg.cendio.se>
+Date:   Wed Feb 4 22:09:25 2009 +0100
+
+    Avoid sending uninitialized padding data over the network.
+    
+    Besides cluttering Valgrind output, this might also be an information leak.
+    
+    Signed-off-by: Peter Astrand <astrand@cendio.se>
+    Signed-off-by: Alan Coopersmith <alan.coopersmith@sun.com>
+
+commit e15dca77fa76252dd8499f8585d8ce922ac3b869
+Author: Paulo Cesar Pereira de Andrade <pcpa@mandriva.com.br>
+Date:   Thu Jan 29 18:02:34 2009 -0200
+
+    Janitor: make distcheck and .gitignore
+    
+      Distribute ChangeLog but not autogen.sh.
+      Use a single toplevel .gitignore file, instead of one per subdirectory.
+
+commit 38bac54519a67ab1a276b66dbaa84a3327ccf827
+Author: Adam Jackson <ajax@redhat.com>
+Date:   Sat Sep 27 02:06:27 2008 -0400
+
+    Remove some strcasecmp silliness
+
+commit f431b4eb4dc743ccdf94b1b2ed858cc21f63c091
+Author: Adam Jackson <ajax@redhat.com>
+Date:   Tue Jan 20 23:23:40 2009 -0500
+
+    Allow case insensitive filename matching in fontfile.
+    
+    Simplify the freetype renderer list to match.
+
+commit 903d39aeea73a973fb8b05ca1ac147c2cca146cb
+Author: Adam Jackson <ajax@redhat.com>
+Date:   Tue Jan 20 23:21:29 2009 -0500
+
+    Delete some dead ifdefs
+
+commit daa7af2bb2326de363aa5ea51c29616e3634343a
+Author: Adam Jackson <ajax@redhat.com>
+Date:   Tue Jan 20 23:20:20 2009 -0500
+
+    Move the copy of CopyISOLatin1Lowered near its user, and un-weak it.
+
+commit 6c29007756301f513c0151e2b63af073f310af66
+Author: Adam Jackson <ajax@redhat.com>
+Date:   Tue Jan 20 23:17:55 2009 -0500
+
+    Drop OS/2 support
+
+commit 0cdc9b8f850342d50b72a57507db3413eacc6fb8
+Author: Adam Jackson <ajax@redhat.com>
+Date:   Tue Jan 20 23:16:35 2009 -0500
+
+    xalloc -> malloc, etc.
+
+commit 632a2e90a4b209facc84d7a18873f19a720ea7df
+Author: Adam Jackson <ajax@redhat.com>
+Date:   Sat Sep 27 01:30:13 2008 -0400
+
+    Remove PMF support.
+    
+    .pmf files are printer font metrics; they have no glyphs, just boxes for
+    layout.  They can't possibly be useful in a post-Xprint world.
+
+commit e1927f80deabe0268dc18b4a9f3ceda1325171f5
+Author: Adam Jackson <ajax@redhat.com>
+Date:   Tue Jan 20 22:57:35 2009 -0500
+
+    Remove printer font support.
+    
+    Xprint is just insidious, isn't it.
+
+commit 732191d5d6ad58caab25e24df16fb89efaea2e9a
+Author: Adam Jackson <ajax@redhat.com>
+Date:   Tue Jan 20 22:42:22 2009 -0500
+
+    Remove loadable renderer support.
+
+commit 423d0a2c1dfad969f4a238618811937bc5f49776
+Author: Adam Jackson <ajax@redhat.com>
+Date:   Sat Sep 27 01:55:47 2008 -0400
+
+    Remove useless #define
+
+commit 50bca6dd881c2d787b3afa4d98a2c2667f767614
+Author: Adam Jackson <ajax@redhat.com>
+Date:   Tue Jan 20 22:33:06 2009 -0500
+
+    Get rid of a useless array
+
+commit 6ba0565362ba9c8d1037c0e4725cb31faa141656
+Author: Adam Jackson <ajax@redhat.com>
+Date:   Tue Jan 20 22:29:10 2009 -0500
+
+    const cleanup
+
+commit 1247f01ee36f80222e30c1678f940329aadb8335
+Author: Adam Jackson <ajax@redhat.com>
+Date:   Tue Jan 20 01:13:08 2009 -0500
+
+    Delete Type1
+    
+    Yes, these are still real fonts, but freetype can handle them just fine.
+
+commit 85b66b8a7f3095f10437c8ecb3dcbfe68c9cfced
+Author: Adam Jackson <ajax@redhat.com>
+Date:   Tue Jan 20 01:03:16 2009 -0500
+
+    Delete speedo
+    
+    OUT OUT OUT
+
+commit 1559d8086e8063c692aae008006578b88e1368fe
+Author: Jeremy Huddleston <jeremyhu@freedesktop.org>
+Date:   Sun Dec 28 12:35:37 2008 -0800
+
+    Added missing AM_CFLAGS for -Wl,-flat_namespace
+    
+    Fixes commit f859a76b0f325b07952ad1c5c818318307c589b0
+
+commit 99bad52b592f4f11887bf9033590b61880c3c976
+Author: Paulo Cesar Pereira de Andrade <pcpa@mandriva.com.br>
+Date:   Sat Mar 1 16:45:55 2008 -0300
+
+    Disable some fun stdio wrapping.
+    
+      The code is still there but no magic with macros is attempted anymore
+    to handle files.
+      This should really be changed to just use stdio, and properly adapt
+     functions like T1Decript, T1eexec, etc.
+
+commit 95760fbe45a700ea4cc118daa536604393721a59
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Fri Dec 19 16:24:39 2008 -0800
+
+    Restore comment deleted by b6f793d7d5
+
+commit b6f793d7d5c7f7c55911e6524dede41b92dcbc22
+Author: Paulo Cesar Pereira de Andrade <pcpa@mandriva.com.br>
+Date:   Fri Mar 14 01:30:24 2008 -0300
+
+    libXfont ansification and removal of xf86_ansic.h dependency
+    
+      Basically the code is now compiled as if FONTMODULE was never defined,
+    but also removed some "magic" defining _XOPEN_SOURCE before including
+    math.h.
+      Also removed some #if 0'ed code instead of fixing prototypes inside
+    the "dead code".
+      Changes to spdo_prv.h were due to defines like:
+      <hash>define foo() sp_foo()
+      that would not compile with the ansification in the format:
+      type foo(void)
+      due to the macro receiving "void" as an argument.
+
+commit 282ac4226195d58e3818e7ac97093e396aa78086
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Fri Dec 19 15:07:21 2008 -0800
+
+    Version bump: 1.3.4
+
+commit 5c631ad798fcdea4f2b7d0b012ac94182fad4184
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Fri Dec 19 14:01:28 2008 -0800
+
+    miscutil.c:108: warning: old-style parameter declaration
+
+commit d21d6c5b23a23f120f32b483ec6b86cf88cb3a98
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Fri Dec 19 13:47:48 2008 -0800
+
+    Add simple README with pointers to bugzilla/git/mailing list
+
+commit d3be1261d29b7d8eda124add3497a93ebe34712c
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Fri Dec 19 13:47:27 2008 -0800
+
+    Update COPYING file with additional copyrights/licenses
+
+commit b5cc4a10c0fe365b40be19613777f192a1ada0db
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Fri Dec 19 13:05:32 2008 -0800
+
+    Use XORG_CWARNFLAGS & XORG_CHANGELOG macros from xorg-macros 1.2
+
+commit 377584bb71ccb2cc380c3a8f71f0acd7e755ad33
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Thu Dec 18 21:22:31 2008 -0800
+
+    Always scan catalogue dirs at startup, even if their mtime < 0
+    
+    Works around bug in VMWare that caused the Solaris kernel to fail to read
+    the time-of-day chip on boot, and start with a time < 0 (i.e. back to the
+    1960's) - when the system was then installed from this mode, Xorg wouldn't
+    start after reboot, since the mtime would be < 0 and the catalogue dir was
+    then skipped as not changed since reading at the 0 initially set in the
+    cat->mtime.
+    
+    Fixes OpenSolaris bug #4780
+       <http://defect.opensolaris.org/bz/show_bug.cgi?id=4780>
+
+commit 9ad7f24fafe876851b89190732034da6fb640788
+Author: Benjamin Close <Benjamin.Close@clearchain.com>
+Date:   Thu Dec 11 15:26:13 2008 +1030
+
+    Make sure font names/font alias names are null terminated
+    
+    This fixes a crash upon server restart where the saved fonts were
+    being restored however strlen(font_name) was incorrect hence memory
+    was being clobbered.
+
+commit d93cc906d4a2f42d11629e245fb13a2d08cf2a61
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Thu Dec 4 16:56:56 2008 -0800
+
+    Pad CreateAC packets with 0 auths to workaround xfs bug
+    
+    Versions of xfs before commit 3fe28a31a2974287acc182c7c9bfd68d94ea6292
+    will reject CreateAC packets with 0 auths unless they claim to have at
+    least 4 bytes of authentication data that isn't actually read.
+
+commit f859a76b0f325b07952ad1c5c818318307c589b0
+Author: Julien Cristau <jcristau@debian.org>
+Date:   Tue Nov 4 19:24:29 2008 +0100
+
+    Don't clobber CFLAGS in configure
+    
+    This lets the user set CFLAGS when running make.
+
+commit 6bf52de1fb84d61b227daf7a7077af9ea3ec27a3
+Author: Peter Breitenlohner <peb@mppmu.mpg.de>
+Date:   Mon Oct 20 19:32:23 2008 -0700
+
+    X.Org Bug 17945: avoid gcc warnings for libXfont
+    
+    <http://bugs.freedesktop.org/show_bug.cgi?id=17945>
+    
+    Avoid two gcc warnings
+    src/fontfile/ffcheck.c:150: warning: initialization discards qualifiers from pointer target type
+    src/fontfile/register.c:98: warning: initialization discards qualifiers from pointer target type
+
+commit b012dcf65b1f0e41def2f595f1b1e7b06a49d275
+Author: Adam Jackson <ajax@redhat.com>
+Date:   Thu Aug 28 15:36:06 2008 -0400
+
+    Retry font server connections faster.
+
+commit 8a6df69750a2d350074715fb31d9d20195d00b4c
+Author: Adam Jackson <ajax@redhat.com>
+Date:   Thu Aug 28 15:35:16 2008 -0400
+
+    Nuke fontcache.
+    
+    Hasn't been relevant since the X-TT merge ages ago.
+
+commit 5d5587a36453d731e9a7353a98fa391dbb51b57d
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Thu Aug 21 19:58:06 2008 -0700
+
+    Add support for bzip2 bitmap font compression
+    
+    Code originally written for Solaris Xsun in 2003, ported now to current Xorg
+    <http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=4819077>
+
+commit 624b7a507cdea25cec0728b4679610df3fb3097c
+Author: Derek Wang <derek.wang@sun.com>
+Date:   Thu Aug 21 16:06:51 2008 -0700
+
+    Sun bug 4510977: dtremote fails to start session
+    
+    <http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=4510977>
+
+commit 684c000e57f30344777cf763f2f1b540ef008b38
+Author: Adam Jackson <ajax@redhat.com>
+Date:   Wed Jul 2 15:30:03 2008 -0400
+
+    libXfont 1.3.3
+
+commit 11edbc3a818e15ea2b622b31e6f87159ee68ae4a
+Author: Maarten ter Huurne <maarten.ter.huurne@philips.com>
+Date:   Sat Jun 28 15:34:50 2008 -0400
+
+    Do not call FT_Get_BDF_Charset_ID() if configured with --disable-bdfformat
+    
+    When I configure libXfont-1.3.2 with --disable-bdfformat and link it against
+    FreeType that is built without BDF support, I get the following link error:
+    
+    libXfont.so: undefined reference to â€˜FT_Get_BDF_Charset_ID’
+    
+    I fixed it by checking XFONT_BDFFORMAT and if BDF support is disabled, the call
+    to FT_Get_BDF_Charset_ID() is omitted and the result code is set as if the call
+    had failed.
+    
+    Signed-off-by: James Cloos <cloos@jhcloos.com>
+
+commit 1ab07ce0eec4f6c7ed66c7aba3edf8c4315dd907
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Tue May 13 17:26:57 2008 -0700
+
+    FontFileDirectoryChanged: check length of "fonts.alias" as well as "fonts.dir"
+
+commit 0f9db4aa7de6e0644ac9c5811b949e5f936c9d61
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Fri May 9 12:36:30 2008 -0700
+
+    Don't allow a font alias to point to itself and create a loop
+    
+    Part of fix for Sun bug 4258475
+    <http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=4258475>
+
+commit 67311922a2e02d8a763831831b65bb4833db58b5
+Author: Colin Harrison <colin.harrison-at-virgin.net>
+Date:   Mon May 5 22:17:55 2008 +0100
+
+    Fix build for WIN32
+
+commit 6ba408c956ca8e241d10d463c45b4e987b757333
+Author: Matthieu Herrb <matthieu.herrb@laas.fr>
+Date:   Sun Mar 9 08:21:34 2008 +0100
+
+    nuke RCS Ids
+
+commit 754cabe62e91b9ad50c3027c063f4269775f7add
+Author: Julien Cristau <jcristau@debian.org>
+Date:   Fri Mar 7 12:19:22 2008 +0100
+
+    Add missing include in src/FreeType/ftfuncs.c
+    
+    Fixes compiler warning:
+    ../../../src/FreeType/ftfuncs.c: In function 'restrict_code_range_by_str':
+    ../../../src/FreeType/ftfuncs.c:2081: warning: implicit declaration of function 'isspace'
+
+commit 0fd2a1428df56d8b29e148b08dcec2dfed9302fa
+Author: Adam Jackson <ajax@redhat.com>
+Date:   Wed Mar 5 22:04:06 2008 -0500
+
+    libXfont 1.3.2
+
+commit b76df66d2c507898472bba0f9986ef5700029a36
+Author: Matthieu Herrb <matthieu@bluenote.herrb.com>
+Date:   Thu Jan 17 15:30:37 2008 +0100
+
+    Fix for CVE-2008-0006 - PCF Font parser buffer overflow.
+
+commit 2297c6390a1609fe810c2cd5b3443f3722610944
+Author: Matthieu Herrb <matthieu@bluenote.herrb.com>
+Date:   Thu Oct 18 21:46:49 2007 +0200
+
+    ftsystem.c is not needed anymore.
+
+commit 5bf703700ee4a5d6eae20da07cb7a29369667aef
+Author: Matthieu Herrb <matthieu@bluenote.herrb.com>
+Date:   Fri Sep 28 08:17:57 2007 +0200
+
+    catalogue.c: prevent a one character overflow
+    
+    this occurs if readlink writes a result that's exactly the
+    size of the buffer that's passed to it. Reported by
+    Joerg Sonnenberger.
+    
+    Re
+
+commit fd8a03fbbd74f5cbaa740e5d50fccdf5c1f78b5b
+Author: Jens Granseuer <jensgr@gmx.net>
+Date:   Thu Sep 27 23:12:00 2007 +0200
+
+    fix build with gcc 2.95.
+    
+    In addition to fixing the C89 issue, the patch also flags a few functions as
+    static to avoid "no previous prototype" warnings.
+
+commit 268f1bb1859e97944e8b63a5bb12677e874ed144
+Author: Tilman Sauerbeck <tilman@code-monkey.de>
+Date:   Thu Sep 13 20:40:26 2007 +0200
+
+    Replaced one instance of bcopy() with memcpy().
+    
+    f->buffer cannot overlap with io->file->bits, so it's safe to
+    use memcpy() rather than memmove().
+    Compile-tested only.
+
+commit f2725a5c9da771fb610d503ebfda3b4d1553bac4
+Author: Eric Anholt <eric@anholt.net>
+Date:   Wed Sep 5 13:10:43 2007 -0700
+
+    Bump version to 1.3.1.
+
+commit aca95d12a8b35de7ae914632fc9e8a723d58a860
+Author: Matthieu Herrb <matthieu@bluenote.herrb.com>
+Date:   Sat Aug 25 23:32:54 2007 +0200
+
+    Kill unused macro definition.
+
+commit 3c3b47bf6f080ddb700886de3e5bfa42c2f0774e
+Merge: 9f86614 32d2d33
+Author: Dodji Seketeli <dodji@openedhand.com>
+Date:   Sat Aug 11 23:09:50 2007 +0200
+
+    Merge branch 'master' of ssh://dodji@git.freedesktop.org/git/xorg/lib/libXfont
+
+commit 9f86614394af81bc484cf00f3e9996510d3718cb
+Author: Ademar de Souza Reis Jr <ademar@mandriva.com.br>
+Date:   Mon Jul 30 14:36:21 2007 -0400
+
+    Fix dirfd leak on CatalogueRescan().
+
+commit 87f50267181887ed9214536608bd2035d2dd70f7
+Author: Ademar de Souza Reis Jr <ademar@mandriva.com.br>
+Date:   Mon Jul 30 14:35:01 2007 -0400
+
+    Support relative paths in catalogue:<dir> symlinks.
+    
+    Relative symlinks are common inside the catalogue directory and
+    should be supported as well.
+
+commit 32d2d335eacd1b55980323a71ef35cdf7c22366d
+Author: Ademar de Souza Reis Jr <ademar@mandriva.com.br>
+Date:   Mon Jul 30 14:36:21 2007 -0400
+
+    Fix dirfd leak on CatalogueRescan().
+
+commit 0a5b31a40c4933f4c69157c61d4d4890af2205b1
+Author: Ademar de Souza Reis Jr <ademar@mandriva.com.br>
+Date:   Mon Jul 30 14:35:01 2007 -0400
+
+    Support relative paths in catalogue:<dir> symlinks.
+    
+    Relative symlinks are common inside the catalogue directory and
+    should be supported as well.
+
+commit 7670d4a2720c61fbc7b989fed14c676f04ac3ad1
+Author: Dodji Seketeli <dodji@seketeli.org>
+Date:   Mon Jul 16 12:24:34 2007 +0200
+
+    Remove side effects from BuiltinReadDirectory()
+    
+    The first time BuiltinReadDirectory() is called,
+    save the content of builtin_dir and builtin_alias,
+    before calling FontFileAddFontFile(), because that fonction
+    will modify those.
+    
+    Then, in subsequent calls to BuiltinReadDirectory(), restore
+    builtin_dir and builtin_alias so that the side effect incurred
+    by the first call disappears.
+
+commit e3642d9b2c0819a607d4cce413b9f0541285545b
+Author: Kristian Høgsberg <krh@redhat.com>
+Date:   Mon Jul 2 15:01:05 2007 -0400
+
+    Bump version to 1.3.0.
+
+commit f33f9361086db3cf1d09cec067f38fe751ed22eb
+Author: Kristian Høgsberg <krh@redhat.com>
+Date:   Mon Jul 2 14:59:11 2007 -0400
+
+    Fix crash when no attributes are present for symlink.
+
+commit 8d47483711be6076e7bfefab14aa890c5f37e1aa
+Author: Kristian Høgsberg <krh@redhat.com>
+Date:   Thu Jun 21 21:44:02 2007 -0400
+
+    Bump version to 1.2.9.
+
+commit c5ab59762c4ad5def68436d55937a2bd558d5c99
+Author: Kristian Høgsberg <krh@redhat.com>
+Date:   Tue Jun 19 10:38:02 2007 -0400
+
+    Add a new 'catalogue' FPE, which takes font paths from symlinks in a dir.
+    
+    This patch adds a new FPE type, which will match font path elements of the
+    form
+    
+       catalogue:<dir>
+    
+    The dir specified after the catalogue: prefix will be scanned for symlinks
+    and each symlink destination will be added as a local fontfile FPE.
+    The symlink can be suffixed by attributes, such as 'unscaled', which
+    will be passed through to the underlying fontfile FPE.  Except the new
+    attribute 'pri' which will be used for ordering the fontfile FPEs.
+    
+    An example configuration:
+    
+       75dpi:unscaled:pri=20 -> /usr/share/X11/fonts/75dpi
+       ghostscript:pri=60 -> /usr/share/fonts/default/ghostscript
+       misc:unscaled:pri=10 -> /usr/share/X11/fonts/misc
+       type1:pri=40 -> /usr/share/X11/fonts/Type1
+       type1:pri=50 -> /usr/share/fonts/default/Type1
+    
+    will add /usr/share/X11/fonts/misc as the first FPE with the attribute
+    'unscaled', second FPE will be /usr/share/X11/fonts/75dpi, also with
+    the attribute unscaled etc.  This is functionally equivalent to setting
+    the following font path:
+    
+       /usr/share/X11/fonts/misc:unscaled,
+       /usr/share/X11/fonts/75dpi:unscaled,
+       /usr/share/X11/fonts/Type1,
+       /usr/share/fonts/default/Type1,
+       /usr/share/fonts/default/ghostscript
+    
+    The motivation is to let font packages add a symlink to the new font
+    directory they provide instead of rewriting either the Xorg config file
+    or the xfs config file.
+
+commit 1a690feaf7c416da9b01861af381d15a661e5f52
+Author: Adam Jackson <ajax@benzedrine.nwnk.net>
+Date:   Thu Jun 7 16:01:03 2007 -0400
+
+    Minor fontfile cleanup.
+
+commit 3b1bcd7676fe810ce60d6a4758067b571796cceb
+Author: Adam Jackson <ajax@benzedrine.nwnk.net>
+Date:   Thu Jun 7 15:54:51 2007 -0400
+
+    Dead code cull from fontserver code.
+
+commit 6257af0e547095483331b8c8ed588e5467852671
+Author: Adam Jackson <ajax@benzedrine.nwnk.net>
+Date:   Thu Jun 7 15:41:19 2007 -0400
+
+    Static markup over bitmap and builtins.
+
+commit 8c31fadabd706af63381007d666e685a66b58fd9
+Author: Adam Jackson <ajax@benzedrine.nwnk.net>
+Date:   Thu Jun 7 15:28:09 2007 -0400
+
+    Dead code cull from FreeType.
+
+commit fabf5458f1acbfc967bdaea3b89d707c22b97364
+Author: Adam Jackson <ajax@benzedrine.nwnk.net>
+Date:   Thu Jun 7 15:17:16 2007 -0400
+
+    Death to open-coded strcasecmp.
+    
+    Seriously, if you don't already have this, you've already lost.
+
+commit d50de26430c1a114a22597de40a3e5ac3c8e1ab7
+Author: Adam Jackson <ajax@benzedrine.nwnk.net>
+Date:   Thu Jun 7 15:13:44 2007 -0400
+
+    Dead code cull from Speedo.
+
+commit 3fd7a510b5467479d6e2559819b96b222c7328e8
+Author: Adam Jackson <ajax@benzedrine.nwnk.net>
+Date:   Thu Jun 7 14:39:03 2007 -0400
+
+    One more missed static in Type1
+
+commit 440166a027b78eb53d7686937148b755ad51f7f9
+Author: Adam Jackson <ajax@benzedrine.nwnk.net>
+Date:   Thu Jun 7 14:24:46 2007 -0400
+
+    Dead code removal and static markup for Type1.
+
+commit 9739e750a7ca4b86ddb89674b104e9b9a8b61014
+Author: Adam Jackson <ajax@benzedrine.nwnk.net>
+Date:   Thu Jun 7 14:20:27 2007 -0400
+
+    Warning cleanup.
+
+commit 87db45f5eb7880395735f7bf3a8ee2d89b7e0122
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Wed Apr 4 17:05:13 2007 -0700
+
+    Version bump: 1.2.8
+
+commit 224fb6403a328e70b370540cc5cefd74421fafac
+Merge: e7a59cf 0fbb37c
+Author: Matthieu Herrb <matthieu@roadrock.(none)>
+Date:   Tue Apr 3 16:05:48 2007 +0200
+
+    Merge branch 'master' of git+ssh://herrb@git.freedesktop.org/git/xorg/lib/libXfont
+
+commit e7a59cfb5d442d2965cfcffeff405a4b05591190
+Author: Matthieu Herrb <matthieu@roadrock.(none)>
+Date:   Tue Apr 3 15:45:21 2007 +0200
+
+    Integer overflow vulnerabilities
+    
+    CVE-2007-1351: BDFFont Parsing Integer Overflow
+    CVE-2007-1352: fonts.dir File Parsing Integer Overflow
+
+commit 0fbb37ccc630ced42d6a973c81d947870cca7637
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Mon Apr 2 17:40:19 2007 -0700
+
+    Add #pragma weak for Sun cc where needed
+
+commit cc824e4f2c9a53a00b36a6f83bf065c363027087
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Fri Mar 23 15:57:29 2007 -0700
+
+    Actually use loadable font modules
+    
+    Loadable font modules were not being initialized, and all font renderers
+    known at build time were always being initialized, regardless of Xorg
+    module configuration.
+
+commit fc6e22f238d34918156ded34148730075b7b9cc2
+Author: Ben Byer <bbyer@bbyer.(none)>
+Date:   Tue Feb 20 00:20:23 2007 -0800
+
+    added -flat_namespace to CFLAGS for Darwin
+
+commit 9509d5c7ee5d5e78c6eef54e8faceede5ca5f24e
+Author: Kristian Høgsberg <krh@redhat.com>
+Date:   Mon Jan 22 18:24:19 2007 -0500
+
+    Bump to 1.2.7.
+
+commit 63af35b908b51690a6c12fd42b54cf4ee08c762a
+Author: Simon Law <sfllaw@debian.org>
+Date:   Fri Jan 19 08:50:39 2007 +1100
+
+    fontfile: accept empty (but valid) font paths (bug #3091)
+    If a path has a valid fonts.dir or fonts.alias, but does not contain any
+    fonts (either fonts.dir specifies zero fonts, or fonts could not be
+    loaded), load it as a valid font path anyway.
+
+commit 931b777108526dd0761f948dcd9f1603ac02efc8
+Author: Kristian Høgsberg <krh@redhat.com>
+Date:   Wed Jan 17 17:19:53 2007 -0500
+
+    Add stubs for the scalable renderer callbacks.
+    
+    Trying to scale a bitmap font provided by the built-in backend will
+    crash the X server as it calls into a NULL pointer.  This patch
+    adds "return BadFont;" stubs to prevent the crash.
+
+commit 2e4ae1b524a0149479c46f3f12a9ce2413092442
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Sat Dec 16 00:53:43 2006 +0200
+
+    bump to 1.2.6
+
+commit facc7ce4892eab4353fff0f45d2d3fd6be7d3e3d
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Sat Dec 16 00:53:32 2006 +0200
+
+    build Type1 by default
+    Build Type1 by default, instead of needing to explicitly enable it.
+
+commit 257db35656d5bf9385080e1d173260f0076f849c
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Sat Dec 16 00:53:07 2006 +0200
+
+    don't distribute fontconf.h
+    Since fontconf.h is a generated file, don't distribute it.
+
+commit ab0f05dcfb5537ba5aec7e48ddb713d4fdba7e75
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Wed Dec 6 18:53:54 2006 +0200
+
+    Makefile.am: make ChangeLog hook safer
+    Make ChangeLog hook as safe as possible.
+
+commit da20e256b786eaa6357e3d55baa9e90e38f14614
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Fri Dec 1 01:05:59 2006 +0200
+
+    bump to 1.2.5
+
+commit 16a0c282a673136c0bbb116f35e6e89d8b43a877
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Fri Dec 1 01:05:40 2006 +0200
+
+    post-CID fixes
+    Curiously, make distcheck succeeded ... go figure.
+
+commit e47fb944a8f485c4ad6be9c2cf6a4866eff7a07f
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Fri Dec 1 00:35:48 2006 +0200
+
+    bump to 1.2.4
+
+commit 47084ba39920068030c3e59523701d1205161a9f
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Fri Dec 1 00:35:04 2006 +0200
+
+    remove CID font support (bug #5553)
+    Remove non-free CID font support, which was unused anyway.
+
+commit c4741cdd83bcdedcc6f7a072a73b16668fc905eb
+Author: Adam Jackson <ajax@benzedrine.nwnk.net>
+Date:   Fri Oct 13 16:17:26 2006 -0400
+
+    Bump to 1.2.3
+
+commit 5dfff0eb0f532edb1f4a25daa5529e08dd832ecb
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Thu Oct 5 18:12:50 2006 -0700
+
+    --disable-builtins should not force off all bitmap support
+
+commit 264df52d24f585915e0d9823d5f087cf23e3fc75
+Merge: 0fb55cb d896c3e
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Fri Sep 22 11:36:43 2006 -0700
+
+    Merge branch 'master' of git+ssh://git.freedesktop.org/git/xorg/lib/libXfont
+
+commit d896c3eaeafdb8831ed0833af46250c36f82502f
+Author: Adam Jackson <ajax@benzedrine.nwnk.net>
+Date:   Tue Sep 12 11:11:12 2006 -0400
+
+    Fix distcheck.
+
+commit 1bb49c77c321fab1f5c268404ea0ec622fa083ed
+Author: Adam Jackson <ajax@benzedrine.nwnk.net>
+Date:   Tue Sep 12 11:01:13 2006 -0400
+
+    Bump to 1.2.2.
+
+commit 8c8203ca2760105aca4e0b6ec5909355a061f0b3
+Author: Matthieu Herrb <matthieu@blues.laas.fr>
+Date:   Tue Sep 12 13:50:31 2006 +0200
+
+    Fixes for integer overflows in CID encoded fonts parsing reported by iDefense
+    CVE-ID 2006-3739, 2006-3740, bugzilla #8000, #8001.
+
+commit 0fb55cb86e2ec5dbfbf27a01ceafb77c72fe9f40
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Wed Aug 30 15:53:14 2006 -0700
+
+    Fix typo in comment (alreadt -> already)
+
+commit aa7f3107d5aad41cb3f7b1bb3a4723014314289c
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Fri Aug 25 17:51:46 2006 -0700
+
+    Add *~ to .gitignore to skip emacs droppings
+
+commit cd09f4d54045b957d728d853398d62543d687d03
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Fri Aug 25 17:51:04 2006 -0700
+
+    Replace static ChangeLog with dist-hook to generate from git log
+
+commit 8d171fe61e564d8ed8f75034d4191062cecf190b
+Author: Matthieu Herrb <matthieu.herrb@laas.fr>
+Date:   Sun Jul 23 22:42:43 2006 +0200
+
+    More check on PCF file reading. Bugzilla #7535
+
+commit fead0fa3bae0ba5a4744d6a2aee1caa08019f344
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Wed Jul 19 18:03:58 2006 -0400
+
+    use OpenBitmap when available
+    Don't just use OpenScalable unconditionally.  Fixes builtin fonts.
+
+commit 13422d0e0468f2ddf7cb74cbf925e5bcf4551ae7
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Wed Jul 19 18:03:26 2006 -0400
+
+    move builtin fonts to gzip
+    Use gzip, rather than compress, for builtin fonts.
+
+commit 47ca9941396a375f5e22c220327b6bd513350996
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Thu Jul 13 14:58:56 2006 -0700
+
+    renamed: .cvsignore -> .gitignore
+
+commit 1bf657186d19887a0916340b544b5534e29da081
+Author: Matthieu Herrb <matthieu.herrb@laas.fr>
+Date:   Thu Jul 13 10:18:38 2006 -0400
+
+    Bug #7397: Fix a buffer overflow in Freetype font support.
+
+commit 5d39f5fd3048fc413cb07afeffec0c4daa0cc5a4
+Author: Adam Jackson <ajax@benzedrine.nwnk.net>
+Date:   Thu Jul 6 16:13:14 2006 -0400
+
+    Bump to 1.2.0
+
+commit d9e83ea0ab1cc3bafcdca04812dcbfe541ce1473
+Author: Jie Luo <clotho67@gmail.com>
+Date:   Thu Jul 6 15:59:31 2006 -0400
+
+    Bug #6918: remove dependencies on Freetype internal headers.  As of 2.2
+    Freetype no longer installs them.
+
+commit 2a564715e6d01bafdf4b701e125e45a77c2c404b
+Author: Alan Coopersmith <Alan.Coopersmith@sun.com>
+Date:   Sat Jun 3 06:25:05 2006 +0000
+
+    Coverity #1541: Double free of pointer "ranges" in call to "Xfree"
+
+commit ddd281e6b9408c786cdc759cf7d1ec8972048658
+Author: Adam Jackson <ajax@nwnk.net>
+Date:   Thu Jun 1 21:49:51 2006 +0000
+
+    For the 20-odd symbols defined both in libXfont and the X server, emit them
+        as weak symbols so that the linker will prefer the server's definition
+        when present.
+
+commit e9357d6670fc2e8ccf8d8770bac4c31994d6cc2f
+Author: Adam Jackson <ajax@nwnk.net>
+Date:   Sat Apr 1 23:05:40 2006 +0000
+
+    Add ft.h and ftfuncs.h to the install set for Xprint's benefit. Bump to 1.1
+        for new header files and bugfixes.
+
+commit 7ecd09a15c30770ed6e70d80fb67f88819471c20
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Fri Mar 31 07:17:16 2006 +0000
+
+    Change BUILD_* to XFONT_* (Drew Parsons). Remove random #ifndef CRAY.
+
+commit 69c4ae1e3e14a58bc2eb9b9b8820dc7183b82a67
+Author: Adam Jackson <ajax@nwnk.net>
+Date:   Mon Mar 20 19:44:26 2006 +0000
+
+    Bug #6247: Fix build on Cygwin. (Yaakov Selkowitz)
+
+commit bfb8a71f4f7e5c5ed4278cb3ee271bf9990d276d
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Tue Feb 21 21:35:32 2006 +0000
+
+    Don't crash when we receive an FS_Error from the font server (Guillem
+        Jover).
+
+commit 784838e88ea205c4457f41335b4ce7876833dffc
+Author: Kevin E Martin <kem@kem.org>
+Date:   Thu Dec 15 00:24:29 2005 +0000
+
+    Update package version number for final X11R7 release candidate.
+
+commit e2e5839417ac4d635781508e48ab1838218f4a77
+Author: Kevin E Martin <kem@kem.org>
+Date:   Fri Dec 9 06:55:27 2005 +0000
+
+    Bug #5175: Make encodingsdir configurable.
+
+commit 9a7909e80a8b436aa7aad84c8aceba7df2ffc95c
+Author: Kevin E Martin <kem@kem.org>
+Date:   Sat Dec 3 05:49:43 2005 +0000
+
+    Update package version number for X11R7 RC3 release.
+
+commit ad001bd8823594fed860e070b278748fe2b7c3aa
+Author: Eric Anholt <anholt@freebsd.org>
+Date:   Sun Nov 20 23:17:40 2005 +0000
+
+    Add/improve libs .cvsignores.
+
+commit d48bfbaf52598d89b4b1d97b230924874175e068
+Author: Kevin E Martin <kem@kem.org>
+Date:   Sat Nov 19 07:15:41 2005 +0000
+
+    Update pkgconfig files to separate library build-time dependencies from
+        application build-time dependencies, and update package deps to work
+        with separate build roots.
+
+commit 70a8aeb19223cc6db9ff6fc1335e3ef94bbb9253
+Author: Adam Jackson <ajax@nwnk.net>
+Date:   Mon Nov 14 20:40:42 2005 +0000
+
+    Bug #5047: Make font directory attribs work in modular.
+
+commit 659b2a75a690838dc37ae488d0295c4c594978ce
+Author: Kevin E Martin <kem@kem.org>
+Date:   Wed Nov 9 21:19:13 2005 +0000
+
+    Update package version number for X11R7 RC2 release.
+
+commit fc82a56858e26674e83cc9429fa0eae24d97a530
+Author: Kean Johnson <kean@armory.com>
+Date:   Tue Nov 8 06:33:26 2005 +0000
+
+    See ChangeLog entry 2005-11-07 for details.
+
+commit fb3d726bbff1fad62a3d6dbbcf1c397872aadef3
+Author: Adam Jackson <ajax@nwnk.net>
+Date:   Sun Oct 23 18:32:05 2005 +0000
+
+    Bug #4721: Fix crash when using Freetype 2.1.10. (Michael Gor)
+
+commit 0f006d82f8edd15e0125800fa3166a147e79b9f5
+Author: Kevin E Martin <kem@kem.org>
+Date:   Wed Oct 19 02:48:10 2005 +0000
+
+    Update package version number for RC1 release.
+
+commit 70dfb55c0390cd8698a77baad5e9fbb07aab272d
+Author: Kevin E Martin <kem@kem.org>
+Date:   Wed Oct 5 19:39:06 2005 +0000
+
+    Include missing files
+
+commit 01f5840009b23cc504359219a6fbab3c150d4656
+Author: Adam Jackson <ajax@nwnk.net>
+Date:   Tue Oct 4 00:24:47 2005 +0000
+
+    Bug #4677: Don't install libfontcache.so
+
+commit 30f912cd14e8b7272a95586dc0af429a0fa4c84f
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Fri Sep 9 05:32:58 2005 +0000
+
+    AC_DEFINE FONTCACHE rather than XFONT_FONTCACHE, as the former is used in
+        the code, and the latter in Makefile.ams for an AM_CONDITIONAL.
+
+commit 4a2f7ae2f3317e53d99daf15ad362230388949d4
+Author: Alan Coopersmith <Alan.Coopersmith@sun.com>
+Date:   Thu Aug 4 16:15:46 2005 +0000
+
+    If --with-freetype-config is not specified, try pkgconfig freetype2, then
+        fall back to freetype-config if pkgconfig fails.
+
+commit 0c52dd6f8816a72d8309f0b059afb0c3393f17cf
+Author: Alan Coopersmith <Alan.Coopersmith@sun.com>
+Date:   Sat Jul 30 18:56:32 2005 +0000
+
+    Clear compiler warnings. (Stefan Dirsch)
+
+commit 8520fa13d35e42da7352772b499beef258723d43
+Author: Kevin E Martin <kem@kem.org>
+Date:   Fri Jul 29 21:22:51 2005 +0000
+
+    Various changes preparing packages for RC0:
+    - Verify and update package version numbers as needed
+    - Implement versioning scheme
+    - Change bug address to point to bugzilla bug entry form
+    - Disable loadable i18n in libX11 by default (use --enable-loadable-i18n to
+        reenable it)
+    - Fix makedepend to use pkgconfig and pass distcheck
+    - Update build script to build macros first
+    - Update modular Xorg version
+
+commit d0c5d54d2c7f0bb9364414620df869e3c7615cd5
+Author: Kevin E Martin <kem@kem.org>
+Date:   Sat Jul 23 05:27:00 2005 +0000
+
+    Fix distchecks
+
+commit 561a45751e4c553f1e0887b73abcc724828f03b0
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Sat Jul 16 07:55:12 2005 +0000
+
+    Set soversion to 1.0.0 using -version-number.
+
+commit 054dd01fd5793cff89f7c536c04fd8d904aca4a3
+Author: Adam Jackson <ajax@nwnk.net>
+Date:   Thu Jul 14 14:56:13 2005 +0000
+
+    Add a dummy source file to avoid link failures.
+
+commit 740cfa83024ce5d3f131cdc2f52dd5bf26f945b3
+Author: Kevin E Martin <kem@kem.org>
+Date:   Sun Jul 10 21:35:08 2005 +0000
+
+    Change include dir now that public headers are referenced by
+        <X11/fonts/*.h>
+
+commit cd24fcabc449bbc701a25e3cad279009dec69032
+Author: Keith Packard <keithp@keithp.com>
+Date:   Sat Jul 9 23:31:40 2005 +0000
+
+    Switch from monolithic configuration symbols to modular ones, add backward
+        compatibility for monolithic symbols
+
+commit 428dd333c1c1a96d205d8236c6ecee32dbf7cac9
+Author: Keith Packard <keithp@keithp.com>
+Date:   Sat Jul 9 23:30:07 2005 +0000
+
+    Switch from monolithic configuration symbols to modular ones, add backward
+        compatibility for monolithic symbols
+
+commit 99cde389c331616f22dd6aab395c488f3a798e2e
+Author: Keith Packard <keithp@keithp.com>
+Date:   Sat Jul 9 23:15:37 2005 +0000
+
+    Rearrange configuration options so that individual font file formats drive
+        combined options, and so that the default matches the monolithic
+        defaults
+    Extent fontconf.h to cover all formats
+    Typo in src/Makefile.am failed to link in Type1 library
+    Missing xttcap.c from FreeType shim library.
+
+commit 3c4ac0b9f5b7aced60a763bcaca7b32cd53a7fec
+Author: Keith Packard <keithp@keithp.com>
+Date:   Sat Jul 9 06:36:13 2005 +0000
+
+    Include config.h in every source file to make sure necessary options are
+        found when building in the modular tree
+
+commit 712140dadd20c7d2024d7b75f7033fff407e57e6
+Author: Keith Packard <keithp@keithp.com>
+Date:   Sat Jul 9 06:20:37 2005 +0000
+
+    Add .cvsignore files Switch _la_CFLAGS for AM_CFLAGS to clean up directory
+
+commit ef504c5311dfd441dcb73be64e90f6e7a530b61c
+Author: Adam Jackson <ajax@nwnk.net>
+Date:   Fri Jul 8 20:47:12 2005 +0000
+
+    add -D_XOPEN_SOURCE for linux builds; others might need it too
+
+commit 3ff8db61b901a4d6236a0e4fa40fe5f1b7afcf78
+Author: Adam Jackson <ajax@nwnk.net>
+Date:   Fri Jul 8 20:16:12 2005 +0000
+
+    disable the poll detection momentarily, it's not correct
+
+commit 830d29e5cb0a8c46cd366adefbf3a291c65bd3ac
+Author: Adam Jackson <ajax@nwnk.net>
+Date:   Fri Jul 8 20:08:12 2005 +0000
+
+    silence a warning
+
+commit 75bbb2d461957902258223a9f8f7f8490132e75d
+Author: Adam Jackson <ajax@nwnk.net>
+Date:   Fri Jul 8 19:53:05 2005 +0000
+
+    config.h includes to fix modular build.
+
+commit f068c478d0966be93f9e984c1e9ce2600819a6a1
+Author: Adam Jackson <ajax@nwnk.net>
+Date:   Fri Jul 8 18:29:58 2005 +0000
+
+    Properly test for the existance of poll(3). Default to using it if it
+        exists; add a flag to disable it if you like going slow.
+    Also s/BULITIN/BUILTIN/.
+
+commit e5f35e324548994f2d6df89d6bd0a4eb913f7414
+Author: Alan Coopersmith <Alan.Coopersmith@sun.com>
+Date:   Thu Jul 7 14:59:47 2005 +0000
+
+    Bug #2901 <https://bugs.freedesktop.org/show_bug.cgi?id=2901> Patch #2332
+        <https://bugs.freedesktop.org/attachment.cgi?id=2332> This patch avoids
+        79 gcc-3.4.3 warnings 'xxx' declared `static' but never defined mostly
+        due to including "ftfuncs.h" with the declaration of static functions
+        defined in "ftfuncs.c". (Peter Breitenlohner)
+
+commit c073ce34164a9872688ce619cc0b3fedbdc76f83
+Author: Alexander Gottwald <alexander.gottwald@s1999.tu-chemnitz.de>
+Date:   Mon Jul 4 22:26:15 2005 +0000
+
+    Test for xtrans connection flags
+
+commit a0dc7d02bfcaea8c8a60dcbd00795999bd7f8e0a
+Author: Kevin E Martin <kem@kem.org>
+Date:   Sun Jul 3 21:43:32 2005 +0000
+
+    Undo previous change to add ${includedir}/X11/fonts to CFLAGS. Instead,
+        require all apps to include font headers explicitly -- i.e., from
+        <X11/fonts/*.h> instead of "*.h" or <*.h>.
+
+commit b15a03de6b1897d7c8292e154d0e927f43e3cde0
+Author: Kevin E Martin <kem@kem.org>
+Date:   Sun Jul 3 21:38:42 2005 +0000
+
+    Install publicly used headers in X11/fonts.
+    Change source files that use these headers to get them via <X11/fonts/*.h>.
+
+commit bf4070d02196cab1de62d5fe19be9a1aa74a87c7
+Author: Kevin E Martin <kem@kem.org>
+Date:   Sun Jul 3 16:10:05 2005 +0000
+
+    Change include dir now that public headers are referenced by
+        <X11/fonts/*.h>
+
+commit 932edb23b47440397447265bf72ad7932fd80070
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Sun Jul 3 07:01:01 2005 +0000
+
+    Add Xtrans definitions (FONT_t, TRANS_CLIENT) to clean up warnings.
+    Add XSERV_t, TRANS_SERVER, TRANS_REOPEN to quash warnings.
+    Add #include <dix-config.h> or <xorg-config.h>, as appropriate, to all
+        source files in the xserver/xorg tree, predicated on defines of
+        HAVE_{DIX,XORG}_CONFIG_H. Change all Xfont includes to
+        <X11/fonts/foo.h>.
+
+commit b03d67fd1612a0df5132b10dd0bd9b2cec053a39
+Author: Keith Packard <keithp@keithp.com>
+Date:   Sat Jul 2 23:03:05 2005 +0000
+
+    Add suitable .cvsignore files
+
+commit 69ee19fc4131ce168c9bad2602ff2da176a86715
+Author: Kevin E Martin <kem@kem.org>
+Date:   Sat Jul 2 21:39:23 2005 +0000
+
+    Make headers needed by bdftopcf public
+    Set CFLAGS to make public interface actually public
+    Fix distcheck problem
+
+commit 0ea9f882abb9ad56de2bb8b569e21728e13a1ea7
+Author: Keith Packard <keithp@keithp.com>
+Date:   Sat Jul 2 21:22:31 2005 +0000
+
+    Build libXfont.la in the 'src' directory as my version of automake really
+        didn't like sub-subdirs in SUBDIRS.
+
+commit 6abcfa406de44d726f550fe7e9b04e4168fce265
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Sat Jul 2 18:02:19 2005 +0000
+
+    Remove -I${includedir}/X11/fonts from CFLAGS.
+
+commit 58edcd0de115e23030955493e88afb25b57668e9
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Fri Jul 1 22:21:43 2005 +0000
+
+    Add Xtrans definitions (FONT_t, TRANS_CLIENT) to clean up warnings.
+
+commit 12cca25eea410bfd536ada44e252d79e0896ffa2
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Fri Jul 1 21:24:31 2005 +0000
+
+    Default --enable-fc to yes; minor formatting changes.
+
+commit 4534fa0c8adb77b7db47101318e0e863edb186ce
+Author: Søren Sandmann Pedersen <sandmann@daimi.au.dk>
+Date:   Mon Jun 27 16:09:14 2005 +0000
+
+    - Remove fontenc from Xfont
+    - Add a dependency from Xfont on libfontenc
+    - Add build system for lib/fontenc
+    - xc/lib/font: Change #include "fontenc.h" to #include
+        <X11/fonts/fontenc.h> in some places.
+    - Remove dpsinfo and dpsexec from the app section of symlink.sh
+    - Fix xp.pc.in to add XPRINT_LIBS/CFLAGS instead of X_LIBS/CFLAGS
+
+commit fda7215c0783ad170eb14f7dda078fac3f134470
+Author: Søren Sandmann Pedersen <sandmann@daimi.au.dk>
+Date:   Tue Jun 21 21:29:40 2005 +0000
+
+    Add fontenc directory, update buildsystem
+
+commit db8fd7e670cbd901116344212217bee8001ab460
+Author: Søren Sandmann Pedersen <sandmann@daimi.au.dk>
+Date:   Fri Jun 17 20:33:33 2005 +0000
+
+    Add lbxutil to symlink.sh Add back accidentally removed include in Type1
+        directory Disable Speedo by default
+
+commit e5525d268c6165318894f326be445b22a2523558
+Author: Søren Sandmann Pedersen <sandmann@daimi.au.dk>
+Date:   Thu Jun 16 21:35:26 2005 +0000
+
+    Add Speedo directory to Xfont
+
+commit b96f539005da57273dc7e2bee13651de4eedf087
+Author: Søren Sandmann Pedersen <sandmann@daimi.au.dk>
+Date:   Thu Jun 16 20:50:12 2005 +0000
+
+    Add Type1 subdirectory to lib/Xfonts, update build system accordingly.
+
+commit 01c8cee1736be252348306412ab56b2e03bf2678
+Author: Alexander Gottwald <alexander.gottwald@s1999.tu-chemnitz.de>
+Date:   Thu Jun 9 15:56:05 2005 +0000
+
+    Replace <X11/transport.c> with <X11/Xtrans/transport.c>
+
+commit 3a46316e5f21e28402babdc95871317bd7013809
+Author: Alexander Gottwald <alexander.gottwald@s1999.tu-chemnitz.de>
+Date:   Thu Jun 9 15:52:03 2005 +0000
+
+    Replace <X11/Xtrans.h> with <X11/Xtrans/Xtrans.h>
+    Copy Xtrans.h to exports/include/X11/Xtrans only
+
+commit 175bbc2e58f7dbe5c1f097ef36eadc3f6fe4b5e6
+Author: Josh Triplett <josh@speakeasy.net>
+Date:   Fri May 27 17:44:08 2005 +0000
+
+    Reference X11/fonts header files using X11/fonts/ prefix.
+
+commit fd884a4dbe3f1be8919426da3ebd177fa474a59e
+Author: Josh Triplett <josh@speakeasy.net>
+Date:   Fri May 27 05:17:52 2005 +0000
+
+    Add Xfont.
+
+commit 73c3c1850bc5ba1b0d42b2a9d4f3f5593bfbfd02
+Author: Adam Jackson <ajax@nwnk.net>
+Date:   Fri Apr 22 20:49:49 2005 +0000
+
+    Bug #3069: Drop the BuildLowMem hack, it doesn't compile and isn't useful.
+
+commit dd695cb666d6912f615b264eaabbad63592588c1
+Author: Alexander Gottwald <alexander.gottwald@s1999.tu-chemnitz.de>
+Date:   Mon Nov 15 15:06:56 2004 +0000
+
+    Bufzilla #1802, http://freedesktop.org/bugzilla/show_bug.cgi?id=1802 Added
+        mingw (Win32) port
+
+commit 8cb3bec3667fa6ee57277956d3be71671915a73b
+Author: Roland Mainz <roland.mainz@nrubsig.org>
+Date:   Wed Nov 10 07:46:26 2004 +0000
+
+    xc/lib/font/util/Imakefile
+    //freedesktop.org/bugzilla/show_bug.cgi?id=1804): Fix build failure (caused
+        by missing symbols such as |TwoByteSwap|) when linking the FreeType
+        module and the FreeType library both statically info the Xserver.
+
+commit 69e87288b14a9f28caf0ed5e4ccf5a52767b22eb
+Author: Roland Mainz <roland.mainz@nrubsig.org>
+Date:   Wed Nov 3 19:43:57 2004 +0000
+
+    //freedesktop.org/bugzilla/show_bug.cgi?id=1767): Fixing build bustage in
+        xc/programs/bdftopcf/ due missing `FT_STREAM_SEEK'/`FT_STREAM_POS'
+        symbols.
+
+commit 29b00ebfebf9811d0940c164a4fcff1b2fc5f2a0
+Author: Egbert Eich <eich@suse.de>
+Date:   Tue Nov 2 08:54:52 2004 +0000
+
+    Removing unneeded private FreeType2 symbol.
+    Updating to EDID 1.3. (Bugzilla# 1490, Jay Cotton, Egbert Eich).
+    Removing unneeded code.
+    Fixed KGA handling for i810. KGA handling for chips derived from C&T chips
+        is slightly different. The changes make the code consistent with the
+        C&T (chips) and i740 drivers.
+
+commit e521b8425894ae62ebe225af80e8b6f820df6ff8
+Author: Egbert Eich <eich@suse.de>
+Date:   Wed Aug 4 12:21:48 2004 +0000
+
+    Optimization of CJK rendering when using versions of freetype prior to
+        2.1.8 (Chisato Yamauchi).
+    A small backward compatibility fix to make the freetype module build with
+        freetype version < 2.1.7.
+    Fixed/added some debugging code.
+
+commit 0cbe4e38042a21ee193b2fda42fa647e23f61758
+Author: Egbert Eich <eich@suse.de>
+Date:   Tue Aug 3 16:12:53 2004 +0000
+
+    fixed typo
+
+commit 3ebaa297368aaf4c49caf179d2032c1678066663
+Author: Egbert Eich <eich@suse.de>
+Date:   Tue Aug 3 09:02:17 2004 +0000
+
+    Bugzilla #925: Simpler version of backward compatibility fix (Chisato
+        Yamauchi). Fix to support older versions of gcc (Matthieu Herrb).
+
+commit 96a97b8f86982ece612aa72865b737820d88105b
+Author: Egbert Eich <eich@suse.de>
+Date:   Mon Aug 2 19:35:07 2004 +0000
+
+    Removed distro specific stuff.
+    Fixed FreeType module to build with FreeType versions older than 2.1.7.
+    Fixed typo.
+    Added vtSema to protect call of driver DPMS function.
+    removed unneeded variable
+    Modified RandR driver hook to reduce the number of function calls to one.
+        Function is sufficiently generic to be extended in the future.
+
+commit d1054db0eec3af6a7c322b262cfc1bf5a3992805
+Author: Egbert Eich <eich@suse.de>
+Date:   Mon May 24 19:06:59 2004 +0000
+
+    Fix build glitches when building modules independently using Imake.
+
+commit 2a7109894f4dcfaba70135e19fb6d595332522c7
+Author: Egbert Eich <eich@suse.de>
+Date:   Wed May 5 17:24:40 2004 +0000
+
+    BugZilla #601: fixed missing symbols in Xserver freetype module due to
+        using isdigit instead of ft_isdigit, missing or faulty defines for
+        digit and string functions in ftstdlib.h (now myftstdlib.h). Reverted
+        freetype2 to upstream version, fixed CHAR_BIT in myftstdlib.h and made
+        the use of a copy of ftconfig.h in lib/font/FreeType obsolete (Egbert
+        Eich).
+
+commit b096ed91beaa09eb06b07ef948eeb6207bd3c5e4
+Author: Roland Mainz <roland.mainz@nrubsig.org>
+Date:   Tue May 4 22:59:15 2004 +0000
+
+    Fix for http://pdx.freedesktop.org/cgi-bin/bugzilla/show_bug.cgi?id=595 -
+        RFE: Retire XTT font module and FreeType1 from xorg tree. The
+        functionality of XTT has been integrated into the FreeType font module
+        and the old XTT1.x code (incl. FreeType1 in xc/extras/) is no longer
+        needed anymore.
+
+commit ca5602cde91fc78f54ebe9f08c11a44a9372a652
+Author: Roland Mainz <roland.mainz@nrubsig.org>
+Date:   Tue May 4 18:47:31 2004 +0000
+
+    Fix for http://pdx.freedesktop.org/cgi-bin/bugzilla/show_bug.cgi?id=307 -
+        Restore optimization heuristics on CJK fonts in the FreeType font
+        module which were broken in X11R6.7. Patch by Chisato Yamauchi
+        <cyamauch@a.phys.nagoya-u.ac.jp>.
+
+commit 3d75ea33ecf80c3539b38a993092cd16325a9525
+Author: Egbert Eich <eich@suse.de>
+Date:   Fri Apr 23 18:44:23 2004 +0000
+
+    Merging XORG-CURRENT into trunk
+
+commit 8ee2a19ff0295d625baf0b42e0a8bb7f4ad575fd
+Author: Egbert Eich <eich@suse.de>
+Date:   Sun Mar 14 08:32:37 2004 +0000
+
+    Importing vendor version xf86-4_4_99_1 on Sun Mar 14 00:26:39 PST 2004
+
+commit 4986cabb22d133aeb37b53514471ff7d5bf999fe
+Author: Egbert Eich <eich@suse.de>
+Date:   Wed Mar 3 12:11:44 2004 +0000
+
+    Importing vendor version xf86-4_4_0 on Wed Mar 3 04:09:24 PST 2004
+
+commit f827ecf1e0c4289b5020256f9bf5b8d563b202c7
+Author: Egbert Eich <eich@suse.de>
+Date:   Thu Feb 26 13:35:35 2004 +0000
+
+    readding XFree86's cvs IDs
+
+commit 90614769a00fbdaf6ef2e313b480e1f0857425f3
+Author: Egbert Eich <eich@suse.de>
+Date:   Thu Feb 26 09:22:53 2004 +0000
+
+    Importing vendor version xf86-4_3_99_903 on Wed Feb 26 01:21:00 PST 2004
+
+commit 45fc57ae316da51b2f9abab2aee303456730ab54
+Author: Kaleb Keithley <kaleb@freedesktop.org>
+Date:   Mon Feb 23 20:34:43 2004 +0000
+
+    Import most of XFree86 4.4RC3. This import excludes files which have the
+        new license. If we want to, later we can import 4.4RC3 again and pick
+        up the files that have the new license, but for now the vendor branch
+        is "pure."
+
+commit d7467b679ccff6fb2025f963b9bcea5dbe72fa15
+Author: Egbert Eich <eich@suse.de>
+Date:   Thu Jan 29 08:08:15 2004 +0000
+
+    Importing vendor version xf86-012804-2330 on Thu Jan 29 00:06:33 PST 2004
+
+commit a0e93cace89c3da8df33d8626a486afe6840d530
+Author: Kaleb Keithley <kaleb@freedesktop.org>
+Date:   Fri Dec 19 20:54:40 2003 +0000
+
+    XFree86 4.3.99.902 (RC 2)
+
+commit d82accff22e36919479b3ac1de72de6115688138
+Author: Kaleb Keithley <kaleb@freedesktop.org>
+Date:   Thu Dec 4 22:03:04 2003 +0000
+
+    XFree86 4.3.99.901 (RC 1)
+
+commit fb0cbe6e7287d635a5f368e055cc0aae6ed50125
+Author: Kaleb Keithley <kaleb@freedesktop.org>
+Date:   Tue Nov 25 19:28:20 2003 +0000
+
+    XFree86 4.3.99.16 Bring the tree up to date for the Cygwin folks
+
+commit ca219ad2fc4f392505d378dfa5a2b34d33de6d61
+Author: Kaleb Keithley <kaleb@freedesktop.org>
+Date:   Tue Nov 25 19:28:16 2003 +0000
+
+    Initial revision
+
+commit 4349bf0fa125e2a1c32b0b49c974ff5fa588cdbe
+Author: Kaleb Keithley <kaleb@freedesktop.org>
+Date:   Fri Nov 14 16:48:50 2003 +0000
+
+    XFree86 4.3.0.1
+
+commit 3795e9702b3b3a6fe0594d09cdd110adeb5e42f9
+Author: Kaleb Keithley <kaleb@freedesktop.org>
+Date:   Fri Nov 14 16:48:50 2003 +0000
+
+    Initial revision
+
+commit 153e8da44452905ae04a0e20ad0d85f40399b4ca
+Author: Kaleb Keithley <kaleb@freedesktop.org>
+Date:   Fri Nov 14 15:54:40 2003 +0000
+
+    R6.6 is the Xorg base-line
diff --git a/Makefile.am b/Makefile.am
new file mode 100755 (executable)
index 0000000..9153e98
--- /dev/null
@@ -0,0 +1,56 @@
+# 
+#  Copyright Â© 2003 Keith Packard, Noah Levitt
+# 
+#  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.
+
+SUBDIRS=doc src
+
+libXfontincludedir = $(includedir)/X11/fonts
+libXfontinclude_HEADERS = \
+       include/X11/fonts/bdfint.h   \
+       include/X11/fonts/bitmap.h   \
+       include/X11/fonts/bufio.h    \
+       include/X11/fonts/fntfil.h   \
+       include/X11/fonts/fntfilio.h \
+       include/X11/fonts/fntfilst.h \
+       include/X11/fonts/fontencc.h \
+       include/X11/fonts/fontmisc.h \
+       include/X11/fonts/fontshow.h \
+       include/X11/fonts/fontutil.h \
+       include/X11/fonts/fontxlfd.h \
+       include/X11/fonts/pcf.h      \
+       src/FreeType/ft.h            \
+       src/FreeType/ftfuncs.h
+nodist_libXfontinclude_HEADERS = \
+       include/X11/fonts/fontconf.h
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = xfont.pc
+
+MAINTAINERCLEANFILES = ChangeLog INSTALL
+
+.PHONY: ChangeLog INSTALL
+
+INSTALL:
+       $(INSTALL_CMD)
+
+ChangeLog:
+       $(CHANGELOG_CMD)
+
+dist-hook: ChangeLog INSTALL
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..97a9e8a
--- /dev/null
+++ b/README
@@ -0,0 +1,25 @@
+libXfont provides the core of the legacy X11 font system, handling the
+index files (fonts.dir, fonts.alias, fonts.scale), the various font file
+formats, and rasterizing them.   It is used by the X servers, the
+X Font Server (xfs), and some font utilities (bdftopcf for instance),
+but should not be used by normal X11 clients.  X11 clients access fonts
+via either the new API's in libXft, or the legacy API's in libX11.
+
+Please submit bugs & patches to the Xorg bugzilla:
+
+       https://bugs.freedesktop.org/enter_bug.cgi?product=xorg
+
+All questions regarding this software should be directed at the
+Xorg mailing list:
+
+       http://lists.freedesktop.org/mailman/listinfo/xorg
+
+The master development code repository can be found at:
+
+       git://anongit.freedesktop.org/git/xorg/lib/libXfont
+
+       http://cgit.freedesktop.org/xorg/lib/libXfont
+
+For more information on the git code manager, see:
+
+       http://wiki.x.org/wiki/GitPage
diff --git a/autogen.sh b/autogen.sh
new file mode 100644 (file)
index 0000000..904cd67
--- /dev/null
@@ -0,0 +1,12 @@
+#! /bin/sh
+
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+
+ORIGDIR=`pwd`
+cd $srcdir
+
+autoreconf -v --install || exit 1
+cd $ORIGDIR || exit $?
+
+$srcdir/configure --enable-maintainer-mode "$@"
diff --git a/configure.ac b/configure.ac
new file mode 100755 (executable)
index 0000000..8389dfc
--- /dev/null
@@ -0,0 +1,213 @@
+dnl  Copyright Â© 2003 Keith Packard
+dnl 
+dnl  Permission to use, copy, modify, distribute, and sell this software and its
+dnl  documentation for any purpose is hereby granted without fee, provided that
+dnl  the above copyright notice appear in all copies and that both that
+dnl  copyright notice and this permission notice appear in supporting
+dnl  documentation, and that the name of Keith Packard not be used in
+dnl  advertising or publicity pertaining to distribution of the software without
+dnl  specific, written prior permission.  Keith Packard makes no
+dnl  representations about the suitability of this software for any purpose.  It
+dnl  is provided "as is" without express or implied warranty.
+dnl 
+dnl  KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+dnl  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+dnl  EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+dnl  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+dnl  DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+dnl  TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+dnl  PERFORMANCE OF THIS SOFTWARE.
+dnl
+dnl Process this file with autoconf to create configure.
+
+AC_PREREQ([2.60])
+
+AC_INIT([libXfont],
+       [1.4.3],
+       [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
+       libXfont)
+# Autoheader generates config.h.in. No new lines allowed in the list.
+AC_CONFIG_HEADERS([config.h include/X11/fonts/fontconf.h])
+dnl
+dnl This is the package version number, not the shared library
+dnl version.  This same version number must appear in Xfont.h
+dnl Yes, it is a pain to synchronize version numbers.  Unfortunately, it's
+dnl not possible to extract the version number here from Xfont.h
+dnl
+AM_INIT_AUTOMAKE([foreign dist-bzip2])
+AM_MAINTAINER_MODE
+
+# Require xorg-macros minimum of 1.10 for DocBook XML documentation
+m4_ifndef([XORG_MACROS_VERSION],
+          [m4_fatal([must install xorg-macros 1.10 or later before running autoconf/autogen])])
+XORG_MACROS_VERSION(1.10)
+XORG_DEFAULT_OPTIONS
+XORG_ENABLE_DEVEL_DOCS
+XORG_WITH_XMLTO(0.0.20)
+XORG_WITH_FOP
+XORG_CHECK_SGML_DOCTOOLS(1.5)
+
+# Check for progs
+AC_PROG_CC
+AC_PROG_LIBTOOL
+dnl If the first PKG_CHECK_MODULES appears inside a conditional, pkg-config
+dnl must first be located explicitly.
+PKG_PROG_PKG_CONFIG
+
+# Look for headers
+AC_CHECK_HEADERS([endian.h poll.h sys/poll.h])
+AC_CHECK_FUNCS([poll])
+
+#
+# select libraries to include
+#
+
+XFONT_FONTFILE=no
+
+#
+# Scalable fonts in files:
+#      FreeType
+#      Bitstream Speedo rasterizer
+#
+AC_ARG_ENABLE(freetype, [ --disable-freetype],[XFONT_FREETYPE=$enableval],[XFONT_FREETYPE=yes])
+AM_CONDITIONAL(XFONT_FREETYPE, [test x$XFONT_FREETYPE = xyes])
+if test x$XFONT_FREETYPE = xyes; then
+       AC_DEFINE(XFONT_FREETYPE,1,[Support FreeType rasterizer for nearly all font file formats])
+       AC_ARG_WITH(freetype-config, [  --with-freetype-config=PROG   Use FreeType configuration program PROG], freetype_config=$withval, freetype_config=auto)
+       
+       if test "$freetype_config" = "auto" ; then
+               PKG_CHECK_MODULES(FREETYPE, freetype2, 
+                       freetype_config=no, freetype_config=yes)
+       fi
+
+       if test "$freetype_config" = "yes"; then 
+               AC_PATH_PROG(ft_config,freetype-config,no)
+               if test "$ft_config" = "no"; then
+                       AC_MSG_ERROR([You must have freetype installed; see http://www.freetype.org/])
+               fi
+       else
+               ft_config="$freetype_config"
+       fi
+
+       if test "$freetype_config" != "no"; then        
+               FREETYPE_CFLAGS="`$ft_config --cflags`"
+               FREETYPE_LIBS="`$ft_config --libs`"
+       fi
+       FREETYPE_REQUIRES="freetype2"
+       XFONT_FONTFILE=yes
+else
+       FREETYPE_CFLAGS=""
+       FREETYPE_LIBS=""
+       FREETYPE_REQUIRES=""
+fi
+AC_SUBST(FREETYPE_LIBS)
+AC_SUBST(FREETYPE_CFLAGS)
+AC_SUBST(FREETYPE_REQUIRES)
+
+#
+# Bitmap fonts in files:
+#      Builtins (gzipped pcf format in .text segment)
+#      PCF
+#      BDF
+#      SNF
+#
+
+AC_DEFINE(X_GZIP_FONT_COMPRESSION,1,[Support gzip for bitmap fonts])
+X_GZIP_FONT_COMPRESSION=1
+AC_SUBST(X_GZIP_FONT_COMPRESSION)
+AC_CHECK_LIB(z, gzopen, [Z_LIBS=-lz], AC_MSG_ERROR([*** zlib is required]))
+
+AC_ARG_WITH(bzip2, 
+       AS_HELP_STRING([--with-bzip2], 
+                       [Support bzip2 compressed bitmap fonts]),
+       [], [with_bzip2=no])
+if test "x$with_bzip2" = xyes; then
+       AC_CHECK_LIB(bz2, BZ2_bzopen, [Z_LIBS="$Z_LIBS -lbz2"],
+               AC_MSG_ERROR([*** libbz2 is required for bzip2 support]))
+       AC_DEFINE(X_BZIP2_FONT_COMPRESSION,1,[Support bzip2 for bitmap fonts])
+fi
+AM_CONDITIONAL(X_BZIP2_FONT_COMPRESSION, [test "x$with_bzip2" = xyes ])
+AC_SUBST(Z_LIBS)
+
+AC_ARG_ENABLE(builtins, [ --disable-builtins ], [XFONT_BUILTINS=$enableval], [XFONT_BUILTINS=yes])
+AM_CONDITIONAL(XFONT_BUILTINS, [test "x$XFONT_BUILTINS" = xyes ])
+if test "x$XFONT_BUILTINS" = xyes; then
+       AC_DEFINE(XFONT_BUILTINS,1,[Support built-in fonts])
+       XFONT_BITMAP=yes
+fi
+
+AC_ARG_ENABLE(pcfformat, [ --disable-pcfformat ], [XFONT_PCFFORMAT=$enableval], [XFONT_PCFFORMAT=yes])
+AM_CONDITIONAL(XFONT_PCFFORMAT, [test "x$XFONT_PCFFORMAT" = xyes])
+if test "x$XFONT_PCFFORMAT" = xyes; then
+       AC_DEFINE(XFONT_PCFFORMAT,1,[Support pcf format bitmap font files])
+       XFONT_BITMAP=yes
+fi
+
+AC_ARG_ENABLE(bdfformat, [ --disable-bdfformat ], [XFONT_BDFFORMAT=$enableval], [XFONT_BDFFORMAT=yes])
+AM_CONDITIONAL(XFONT_BDFFORMAT, [test "x$XFONT_BDFFORMAT" = xyes])
+if test "x$XFONT_BDFFORMAT" = xyes; then
+       AC_DEFINE(XFONT_BDFFORMAT,1,[Support bdf format bitmap font files])
+       XFONT_BITMAP=yes
+fi
+
+AC_ARG_ENABLE(snfformat, [ --disable-snfformat ], [XFONT_SNFFORMAT=$enableval], [XFONT_SNFFORMAT=yes])
+AM_CONDITIONAL(XFONT_SNFFORMAT, [test "x$XFONT_SNFFORMAT" = xyes])
+if test "x$XFONT_SNFFORMAT" = xyes; then
+       AC_DEFINE(XFONT_SNFFORMAT,1,[Support snf format bitmap font files])
+       XFONT_BITMAP=yes
+fi
+
+AM_CONDITIONAL(XFONT_BITMAP, [test "x$XFONT_BITMAP" = xyes ])
+if test "x$XFONT_BITMAP" = xyes; then
+       AC_DEFINE(XFONT_BITMAP,1,[Support bitmap font files])
+       XFONT_FONTFILE=yes
+fi
+
+AM_CONDITIONAL(XFONT_FONTFILE, [test "x$XFONT_FONTFILE" = xyes])
+if test "x$XFONT_FONTFILE" = xyes; then
+       AC_DEFINE(XFONT_FONTFILE,1,[Support fonts in files])
+fi
+
+#
+# Support connection to font servers?
+#
+
+AC_ARG_ENABLE(fc, [ --disable-fc ],[XFONT_FC=$enableval],[XFONT_FC=yes])
+AM_CONDITIONAL(XFONT_FC, [test "x$XFONT_FC" = xyes])
+if test "x$XFONT_FC" = xyes; then
+       AC_DEFINE(XFONT_FC,1,[Support the X Font Services Protocol])
+fi
+
+
+AC_CHECK_LIB(m, hypot, [MATH_LIBS=-lm
+AC_SUBST(MATH_LIBS)], AC_MSG_ERROR([*** libm is required]))
+
+PKG_CHECK_MODULES(XFONT, xproto xtrans fontsproto fontenc)
+
+# Transport selection macro from xtrans.m4
+XTRANS_CONNECTION_FLAGS
+
+case $host_os in
+    linux*)
+        OS_CFLAGS="-D_XOPEN_SOURCE"
+        ;;
+    darwin*)
+        OS_CFLAGS="-Wl,-flat_namespace"
+       ;;
+    *)
+        OS_CFLAGS=
+        ;;
+esac
+AC_SUBST([OS_CFLAGS])
+
+AC_OUTPUT([Makefile
+          doc/Makefile
+          src/Makefile
+          src/fontfile/Makefile
+          src/FreeType/Makefile
+          src/builtins/Makefile
+          src/bitmap/Makefile
+          src/fc/Makefile
+          src/util/Makefile
+          src/stubs/Makefile
+           xfont.pc])
diff --git a/debian/README.source b/debian/README.source
new file mode 100644 (file)
index 0000000..34ab4bf
--- /dev/null
@@ -0,0 +1,73 @@
+------------------------------------------------------
+Quick Guide To Patching This Package For The Impatient
+------------------------------------------------------
+
+1. Make sure you have quilt installed
+2. Unpack the package as usual with "dpkg-source -x"
+3. Run the "patch" target in debian/rules
+4. Create a new patch with "quilt new" (see quilt(1))
+5. Edit all the files you want to include in the patch with "quilt edit" 
+   (see quilt(1)).
+6. Write the patch with "quilt refresh" (see quilt(1))
+7. Run the "clean" target in debian/rules
+
+Alternatively, instead of using quilt directly, you can drop the patch in to 
+debian/patches and add the name of the patch to debian/patches/series.
+
+------------------------------------
+Guide To The X Strike Force Packages
+------------------------------------
+
+The X Strike Force team maintains X packages in git repositories on
+git.debian.org in the pkg-xorg subdirectory. Most upstream packages
+are actually maintained in git repositories as well, so they often
+just need to be pulled into git.debian.org in a "upstream-*" branch.
+Otherwise, the upstream sources are manually installed in the Debian
+git repository.
+
+The .orig.tar.gz upstream source file could be generated this
+"upstream-*" branch in the Debian git repository but it is actually
+copied from upstream tarballs directly.
+
+Due to X.org being highly modular, packaging all X.org applications
+as their own independent packages would have created too many Debian
+packages. For this reason, some X.org applications have been grouped
+into larger packages: xutils, xutils-dev, x11-apps, x11-session-utils,
+x11-utils, x11-xfs-utils, x11-xkb-utils, x11-xserver-utils.
+Most packages, including the X.org server itself and all libraries
+and drivers are, however maintained independently.
+
+The Debian packaging is added by creating the "debian-*" git branch
+which contains the aforementioned "upstream-*" branch plus the debian/
+repository files.
+When a patch has to be applied to the Debian package, two solutions
+are involved:
+* If the patch is available in one of the upstream branches, it
+  may be git'cherry-picked into the Debian repository. In this
+  case, it appears directly in the .diff.gz.
+* Otherwise, the patch is added to debian/patches/ which is managed
+  with quilt as documented in /usr/share/doc/quilt/README.source.
+
+quilt is actually invoked by the Debian X packaging through a larger
+set of scripts called XSFBS. XSFBS brings some other X specific
+features such as managing dependencies and conflicts due to the video
+and input driver ABIs.
+XSFBS itself is maintained in a separate repository at
+  git://git.debian.org/pkg-xorg/xsfbs.git
+and it is pulled inside the other Debian X repositories when needed.
+
+The XSFBS patching system requires a build dependency on quilt. Also
+a dependency on $(STAMP_DIR)/patch has to be added to debian/rules
+so that the XSFBS patching occurs before the actual build. So the
+very first target of the build (likely the one running autoreconf)
+should depend on $(STAMP_DIR)/patch. It should also not depend on
+anything so that parallel builds are correctly supported (nothing
+should probably run while patching is being done). And finally, the
+clean target should depend on the xsfclean target so that patches
+are unapplied on clean.
+
+When the upstream sources contain some DFSG-nonfree files, they are
+listed in text files in debian/prune/ in the "debian-*" branch of
+the Debian repository. XSFBS' scripts then take care of removing
+these listed files during the build so as to generate a modified
+DFSG-free .orig.tar.gz tarball.
diff --git a/debian/changelog b/debian/changelog
new file mode 100755 (executable)
index 0000000..d9c56c7
--- /dev/null
@@ -0,0 +1,300 @@
+libxfont (1:1.4.3-2slp2) unstable; urgency=low
+
+  * upgrade version due to the change of fontconfig
+  * Git: 165.213.180.234:slp/pkgs/xorg/lib/libxfont
+  * Tag: libxfont_1.4.3-2slp2
+
+ -- SooChan Lim <sc1.lim@samsung.com>  Mon, 11 Apr 2011 11:02:33 +0900
+
+libxfont (1:1.4.3-1slp2) unstable; urgency=low
+
+  * [X11R7.6] upgrade pacakge 
+  * Git: 165.213.180.234:slp/pkgs/xorg/lib/libxfont
+  * Tag: libxfont_1.4.3-1slp2
+
+ -- SooChan Lim <sc1.lim@samsung.com>  Thu, 06 Jan 2011 11:39:02 +0900
+
+libxfont (1:1.4.2-1) experimental; urgency=low
+
+  * New upstream release.
+  * Bump xutils-dev build-dep for new xorg-macros.
+  * Bump shlibs for register_fpe_functions().
+  * Update debian/copyright.
+  * Bump Standards-Version to 3.9.0, no changes.
+
+ -- Julien Cristau <jcristau@debian.org>  Wed, 07 Jul 2010 18:25:15 +0100
+
+libxfont (1:1.4.1-2) unstable; urgency=low
+
+  [ Julien Cristau ]
+  * Rename the build directory to not include DEB_BUILD_GNU_TYPE for no
+    good reason.  Thanks, Colin Watson!
+  * Remove myself from Uploaders
+
+  [ Cyril Brulebois ]
+  * Use dh_makeshlibs?\99s -V argument instead of debian/libxfont1.shlibs
+  * Add udeb needed for the graphical installer: libxfont1-udeb.
+  * Version the B-D on libfontenc-dev to ensure libxfont1-udeb gets a
+    dependency on libfontenc1-udeb.
+  * Use a bzip2-less flavour for the udeb.
+  * Bump Standards-Version from 3.8.3 to 3.8.4 (no changes needed).
+  * Fix obsolete-relation-form-in-source by using ??<??instead of ????for
+    xprint in Conflicts, thanks to lintian.
+  * Add myself to Uploaders.
+
+ -- Cyril Brulebois <kibi@debian.org>  Wed, 10 Mar 2010 20:05:31 +0100
+
+libxfont (1:1.4.1-1) unstable; urgency=low
+
+  * New upstream release.
+  * Bump xutils-dev build-dep for new util-macros.
+  * Build documentation, install it in libxfont-dev.
+  * Enable support for bzip2 compressed bitmap fonts.
+  * Don't use LDFLAGS from the environment.  Ubuntu sets that to
+    -Bsymbolic-functions, which breaks libXfont's weak symbols usage.
+
+ -- Julien Cristau <jcristau@debian.org>  Wed, 02 Dec 2009 11:12:13 +0100
+
+libxfont (1:1.4.0-8slp2) unstable; urgency=low
+
+  * To sync git and dpkg
+  * Git: 165.213.180.234:/git/slp/pkgs/xorg/lib/libxfont
+  * Tag: libxfont_1.4.0-8slp2
+
+ -- YoungHoon Jung <yhoon.jung@samsung.com>  Thu, 02 Dec 2010 15:45:37 +0900
+
+libxfont (1:1.4.0-7slp2) unstable; urgency=low
+
+  * Update maintainer
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/X11
+  * Tag: libxfont_1.4.0-7slp2
+
+ -- Sung-Jin Park <sj76.park@samsung.com>  Wed, 21 Apr 2010 13:46:42 +0900
+
+libxfont (1:1.4.0-6slp2) unstable; urgency=low
+
+  * modify the package name
+
+ -- SooChan Lim <sc1.lim@samsung.com>  Thu, 25 Mar 2010 17:51:04 +0900
+
+libxfont (1:1.4.0-5) unstable; urgency=low
+
+  * Fix debian/rules to install .la files properly
+
+ -- Sung-Jin Park <sj76.park@samsung.com>  Mon, 07 Dec 2009 14:51:41 +0900
+
+libxfont (1:1.4.0-4) unstable; urgency=low
+
+  * Import debian package
+  * Install .la files
+
+ -- Sung-Jin Park <sj76.park@samsung.com>  Mon, 07 Dec 2009 10:30:58 +0900
+
+libxfont (1:1.4.0-3) unstable; urgency=low
+
+  * libxfont1 Conflicts: xprint (< 2:1.6.0-1). 
+    The requiem release of xprint (1.6) will not conflict with
+    libxfont1. I am assured the garlic wreaths should prove most
+    efficacious at protecting the general public from the undead. 
+  * Standards version 3.8.3.
+
+ -- Drew Parsons <dparsons@debian.org>  Sat, 31 Oct 2009 11:29:34 +1100
+
+libxfont (1:1.4.0-2) unstable; urgency=high
+
+  * libxfont1 Conflicts with xprint, printer font support was removed upstream
+    in 1.4.0 (closes: #535952).
+  * Add README.source from xsfbs.  Bump Standards-Version to 3.8.2.
+
+ -- Julien Cristau <jcristau@debian.org>  Sun, 02 Aug 2009 13:36:46 +0200
+
+libxfont (1:1.4.0-1) unstable; urgency=low
+
+  * New upstream release.
+  * Move libxfont1-dbg to new section 'debug'.
+
+ -- Julien Cristau <jcristau@debian.org>  Mon, 13 Apr 2009 12:11:23 +0100
+
+libxfont (1:1.3.4-2) unstable; urgency=low
+
+  * Update debian/copyright from upstream COPYING.
+  * Upload to unstable.
+
+ -- Julien Cristau <jcristau@debian.org>  Mon, 16 Feb 2009 19:31:59 +0100
+
+libxfont (1:1.3.4-1) experimental; urgency=low
+
+  * Wrap build-deps in debian/control.
+  * Run autoreconf on build; build-dep on xutils-dev, autoconf, automake and
+    libtool.
+  * Handle parallel builds.
+  * New upstream release.
+  * Drop obsolete x11proto-fontcache-dev build-dependency.
+
+ -- Julien Cristau <jcristau@debian.org>  Tue, 23 Dec 2008 15:06:37 +0100
+
+libxfont (1:1.3.3-1) unstable; urgency=high
+
+  [ Julien Cristau ]
+  * Drop dependency on x11-common from libxfont1{,-dbg}.
+  * New upstream bugfix release.
+  * Disable the type1 rasterizer and support for speedo font files.  The
+    former is a security hazard, and Speedo fonts are disabled in the X server
+    since before etch anyway.
+  * Urgency high so the above gets in lenny.
+
+  [ Brice Goglin ]
+  * Add upstream URL to debian/copyright.
+  * Add a link to www.X.org and a reference to the upstream module
+    in the long description.
+
+ -- Julien Cristau <jcristau@debian.org>  Thu, 17 Jul 2008 22:50:03 +0200
+
+libxfont (1:1.3.2-1) unstable; urgency=low
+
+  * New upstream release
+  * Drop CVE-2008-0006.diff, included upstream.
+
+ -- Julien Cristau <jcristau@debian.org>  Fri, 07 Mar 2008 13:32:43 +0100
+
+libxfont (1:1.3.1-2) unstable; urgency=high
+
+  * High urgency upload for security fix.
+  * Fix a buffer overflow in the PCF font parser (CVE-2008-0006).
+  * debian/control updates
+    + add myself to Uploaders, and remove Branden and Fabio with their
+      permission
+    + s/^XS-Vcs/Vcs/
+    + bump Standards-Version to 3.7.3 (no changes)
+    + libxfont1 is Section: libs
+    + libxfont-dev and libxfont1-dbg are Section: libdevel
+
+ -- Julien Cristau <jcristau@debian.org>  Thu, 17 Jan 2008 00:09:38 +0100
+
+libxfont (1:1.3.1-1) unstable; urgency=low
+
+  * New upstream release.
+  * Add libxfont1.shlibs, bump shlibs to >= 1:1.2.9.
+
+ -- Julien Cristau <jcristau@debian.org>  Wed, 05 Sep 2007 22:45:57 +0200
+
+libxfont (1:1.2.9-1) unstable; urgency=low
+
+  * New upstream version.
+    - Add a new 'catalogue' FPE (font path element), which takes font
+      paths from symlinks in a dir.
+  * Use libxfont1 (= ${binary:Version}) instead of ${Source-Version}
+    in debian/control.
+
+ -- Drew Parsons <dparsons@debian.org>  Sat, 23 Jun 2007 09:40:45 +1000
+
+libxfont (1:1.2.8-1) unstable; urgency=low
+
+  * Add XS-Vcs-Browser to debian/control.
+  * New upstream release.
+    + drop patch from 1:1.2.2-2, applied upstream.
+  * Upload to unstable.
+
+ -- Julien Cristau <jcristau@debian.org>  Wed, 11 Apr 2007 15:52:11 +0200
+
+libxfont (1:1.2.7-1) experimental; urgency=low
+
+  * New upstream release.
+  * Add XS-Vcs-Git header to debian/control, and drop obsolete CVS information.
+  * Install the upstream ChangeLog.
+
+ -- Julien Cristau <jcristau@debian.org>  Fri, 16 Feb 2007 14:32:57 +0100
+
+libxfont (1:1.2.2-2) unstable; urgency=high
+
+  * Grab patch from upstream git to fix security issues:
+    + CVE-2007-1351: BDFFont Parsing Integer Overflow
+    + CVE-2007-1352: fonts.dir File Parsing Integer Overflow
+
+ -- Julien Cristau <jcristau@debian.org>  Tue, 03 Apr 2007 19:31:24 +0200
+
+libxfont (1:1.2.2-1) unstable; urgency=high
+
+  * New upstream version.
+    - closes security bug in CID encoded fonts (iDefense CVE-ID
+      2006-3739, 2006-3740)
+    - applies patches 10_freetype_buffer_overflow.patch, 10_pcf_font.patch
+  * dbg package has priority extra.
+
+ -- Drew Parsons <dparsons@debian.org>  Wed, 13 Sep 2006 17:50:06 +1000
+
+libxfont (1:1.2.0-2) unstable; urgency=high
+
+  * Apply upstream patch 10_pcf_font.patch (security vulnerability
+    CVE-2006-3467).  Closes: #383353.
+  * Upload to unstable to ensure patch is propagated quickly.
+  * Apply patch 10_freetype_buffer_overflow.patch while we're at it
+    (no known exploits).
+
+ -- Drew Parsons <dparsons@debian.org>  Thu, 17 Aug 2006 07:45:40 +1000
+
+libxfont (1:1.2.0-1) experimental; urgency=low
+
+  * New upstream version. Closes: #364854.
+    - builds and works with Freetype 2.2. Closes: #362920, #370149.
+  * Standards version 3.7.2.
+  * libxfont-dev doesn't need both Depends: and Pre-Depends: x11-common.
+  * Use debhelper 5, tidy up debian/rules to match.
+  * libxfont does not provide libfontcache.so!
+
+ -- Drew Parsons <dparsons@debian.org>  Thu, 27 Jul 2006 15:08:14 +1000
+
+libxfont (1:1.1.0-1) UNRELEASED; urgency=low
+
+  [ David Nusinow ]
+  * New upstream release
+  * Remove obsolete patch 01_fontserver_fix_SEGV.diff
+
+  [ Andres Salomon ]
+  * Test for obj-$(DEB_BUILD_GNU_TYPE) before creating it during build;
+    idempotency fix.
+  * Run dh_install w/ --list-missing.
+
+ -- Andres Salomon <dilinger@debian.org>  Mon, 17 Jul 2006 01:20:57 -0400
+
+libxfont (1:1.0.0-4) unstable; urgency=low
+
+  * Reorder makeshlib command in rules file so that ldconfig is run
+    properly. Thanks Drew Parsons and Steve Langasek.
+  * Add quilt to build-depends
+
+ -- David Nusinow <dnusinow@debian.org>  Wed, 19 Apr 2006 00:10:33 -0400
+
+libxfont (1:1.0.0-3) unstable; urgency=low
+
+  * Upload to unstable
+
+ -- David Nusinow <dnusinow@debian.org>  Thu, 23 Mar 2006 22:44:39 -0500
+
+libxfont (1:1.0.0-2) experimental; urgency=low
+
+  * Have libxfont-dev depend on libfreetype6-dev and libfontenc-dev. Thanks
+    Eugene Konev.
+  * Port patches from trunk
+    + general/099v_fontserver_fix_SEGV.diff
+
+ -- David Nusinow <dnusinow@debian.org>  Sun, 26 Feb 2006 18:35:44 -0500
+
+libxfont (1:1.0.0-1) experimental; urgency=low
+
+  * First upload to Debian
+
+ -- David Nusinow <dnusinow@debian.org>  Thu, 29 Dec 2005 20:51:40 -0500
+
+libxfont (1:0.99.0+cvs.20050909-1) breezy; urgency=low
+
+  * Fix the XFONT_FONTCACHE/FONTCACHE define in configure.ac (close:
+    Ubuntu#14319).
+
+ -- Daniel Stone <daniel.stone@ubuntu.com>  Fri,  9 Sep 2005 15:39:57 +1000
+
+libxfont (1:0.99.0-1) breezy; urgency=low
+
+  * First libxfont release.
+
+ -- Daniel Stone <daniel.stone@ubuntu.com>  Mon, 16 May 2005 22:10:17 +1000
diff --git a/debian/compat b/debian/compat
new file mode 100644 (file)
index 0000000..7ed6ff8
--- /dev/null
@@ -0,0 +1 @@
+5
diff --git a/debian/control b/debian/control
new file mode 100755 (executable)
index 0000000..69d42b6
--- /dev/null
@@ -0,0 +1,69 @@
+Source: libxfont
+Section: x11
+Priority: optional
+Maintainer: YoungHoon Jung <yhoon.jung@samsung.com>, SangJin Lee <lsj119@samsung.com>, Debian X Strike Force <debian-x@lists.debian.org>
+Uploaders: SooChan Lim <sc1.lim@samsung.com>, David Nusinow <dnusinow@debian.org>, Drew Parsons <dparsons@debian.org>, Cyril Brulebois <kibi@debian.org>
+Build-Depends: debhelper (>= 5), pkg-config, libfontenc-dev (>= 1:1.0.5-2), x11proto-core-dev, xtrans-dev, x11proto-fonts-dev, libfreetype6-dev, zlib1g-dev, libbz2-dev, quilt, xutils-dev (>= 1:7.5-1slp2), autoconf, automake, libtool, xmlto, 
+Standards-Version: 3.9.0
+Vcs-Git: git://git.debian.org/git/pkg-xorg/lib/libxfont
+Vcs-Browser:  http://git.debian.org/?p=pkg-xorg/lib/libxfont.git
+
+Package: libxfont1
+Section: libs
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Conflicts: xprint (<< 2:1.6.0-1)
+Description: X11 font rasterisation library
+ libXfont provides various services for X servers, most notably font
+ selection and rasterisation (through external libraries).
+ .
+ More information about X.Org can be found at:
+ <URL:http://www.X.org>
+ .
+ This module can be found at
+ git://anongit.freedesktop.org/git/xorg/lib/libXfont
+
+#Package: libxfont1-udeb
+#XC-Package-Type: udeb
+#Section: debian-installer
+#Architecture: any
+#Depends: ${shlibs:Depends}, ${misc:Depends}
+#Description: X11 font rasterisation library
+# This is a udeb, or a microdeb, for the debian-installer.
+
+Package: libxfont1-dbg
+Section: debug
+Architecture: any
+Priority: extra
+Depends: ${shlibs:Depends}, ${misc:Depends}, libxfont1 (= ${binary:Version})
+Description: X11 font rasterisation library (debug package)
+ libXfont provides various services for X servers, most notably font
+ selection and rasterisation (through external libraries).
+ .
+ This package contains the debug versions of the library found in libxfont1.
+ Non-developers likely have little use for this package.
+ .
+ More information about X.Org can be found at:
+ <URL:http://www.X.org>
+ .
+ This module can be found at
+ git://anongit.freedesktop.org/git/xorg/lib/libXfont
+
+Package: libxfont-dev
+Section: libdevel
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}, libxfont1 (= ${binary:Version}), libx11-dev, x11proto-core-dev, x11proto-fonts-dev, libfreetype6-dev, libfontenc-dev (>= 1:1.0.1-1)
+Pre-Depends: x11-common (>= 1:7.0.0)
+Replaces: xlibs-static-dev (<< 6.8.2-51)
+Description: X11 font rasterisation library (development headers)
+ libXfont provides various services for X servers, most notably font
+ selection and rasterisation (through external libraries).
+ .
+ This package contains the development headers for the library found in
+ libxfont1.  Non-developers likely have little use for this package.
+ .
+ More information about X.Org can be found at:
+ <URL:http://www.X.org>
+ .
+ This module can be found at
+ git://anongit.freedesktop.org/git/xorg/lib/libXfont
diff --git a/debian/copyright b/debian/copyright
new file mode 100644 (file)
index 0000000..ec711a1
--- /dev/null
@@ -0,0 +1,265 @@
+This package was downloaded from
+http://xorg.freedesktop.org/releases/individual/lib/
+
+Copyright Â© 2007 Red Hat, Inc
+Copyright Â© 2008,2009 Sun Microsystems, Inc.  All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+Copyright (c) 1997 by Mark Leisher
+Copyright (c) 1998-2003 by Juliusz Chroboczek
+Copyright (c) 1998 Go Watanabe, All rights reserved.
+Copyright (c) 1998 Kazushi (Jam) Marukawa, All rights reserved.
+Copyright (c) 1998 Takuya SHIOZAKI, All rights reserved.
+Copyright (c) 1998 X-TrueType Server Project, All rights reserved.
+Copyright (c) 2003-2004 After X-TT Project, All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+
+Copyright 1990, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+
+Copyright 1999 SuSE, 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 SuSE not be used in advertising or
+publicity pertaining to distribution of the software without specific,
+written prior permission.  SuSE makes no representations about the
+suitability of this software for any purpose.  It is provided "as is"
+without express or implied warranty.
+
+SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+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.
+
+
+Copyright 1990 Network Computing Devices
+
+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 Network Computing Devices not be used
+in advertising or publicity pertaining to distribution of the software
+without specific, written prior permission.  Network Computing Devices
+makes no representations about the suitability of this software for any
+purpose.  It is provided "as is" without express or implied warranty.
+
+NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+IN NO EVENT SHALL NETWORK COMPUTING DEVICES 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.
+
+
+Copyright 1990 Network Computing Devices
+
+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 names of Network Computing Devices, or Digital
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+NETWORK COMPUTING DEVICES, AND DIGITAL AND DISCLAIM ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES,
+OR DIGITAL 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.
+
+
+[Note: clause 3 in the following license, the "advertising clause", was
+rescinded by Berkeley in 1999.  See
+<ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change>]
+
+Copyright (c) 1991, 1993
+     The Regents of the University of California.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. All advertising materials mentioning features or use of this software
+   must display the following acknowledgement:
+     This product includes software developed by the University of
+     California, Berkeley and its contributors.
+4. Neither the name of the University nor the names of its contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+
+Copyright (c) 1998-1999 Shunsuke Akiyama <akiyama@jp.FreeBSD.org>.
+All rights reserved.
+Copyright (c) 1998-1999 X-TrueType Server Project, All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+
+Copyright Â© 2004 Keith Packard
+
+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.
+
+
+/* lib/font/fontfile/gunzip.c
+   written by Mark Eichin <eichin@kitten.gen.ma.us> September 1996.
+   intended for inclusion in X11 public releases. */
+
+
+Copyright (c) 1999  The XFree86 Project Inc.
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The XFree86 Project
+Inc. shall not be used in advertising or otherwise to promote the
+sale, use or other dealings in this Software without prior written
+authorization from The XFree86 Project Inc..
diff --git a/debian/libxfont-dev.install b/debian/libxfont-dev.install
new file mode 100755 (executable)
index 0000000..b0cfdd5
--- /dev/null
@@ -0,0 +1,5 @@
+usr/include/X11/*
+usr/lib/libXfont.a
+usr/lib/libXfont.so
+usr/lib/libXfont.la
+usr/lib/pkgconfig/xfont.pc
diff --git a/debian/libxfont1-udeb.install b/debian/libxfont1-udeb.install
new file mode 100644 (file)
index 0000000..e73e376
--- /dev/null
@@ -0,0 +1,2 @@
+usr/lib/libXfont.so.1*
+
diff --git a/debian/libxfont1.install b/debian/libxfont1.install
new file mode 100644 (file)
index 0000000..e73e376
--- /dev/null
@@ -0,0 +1,2 @@
+usr/lib/libXfont.so.1*
+
diff --git a/debian/rules b/debian/rules
new file mode 100755 (executable)
index 0000000..58a8919
--- /dev/null
@@ -0,0 +1,104 @@
+#!/usr/bin/make -f
+# debian/rules for the Debian libxfont package.
+# Copyright Â© 2004 Scott James Remnant <scott@netsplit.com>
+# Copyright Â© 2005 Daniel Stone <daniel@fooishbar.org>
+# Copyright Â© 2005 David Nusinow <dnusinow@debian.org>
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+PACKAGE = libxfont1
+
+include debian/xsfbs/xsfbs.mk
+
+CFLAGS = -Wall -g
+ifneq (,$(filter noopt,$(DEB_BUILD_OPTIONS)))
+       CFLAGS += -O0
+else
+       CFLAGS += -O2
+endif
+ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
+       NUMJOBS = $(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
+       MAKEFLAGS += -j$(NUMJOBS)
+endif
+
+DEB_HOST_ARCH      ?= $(shell dpkg-architecture -qDEB_HOST_ARCH)
+DEB_HOST_GNU_TYPE  ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
+DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
+ifeq ($(DEB_BUILD_GNU_TYPE), $(DEB_HOST_GNU_TYPE))
+       confflags += --build=$(DEB_HOST_GNU_TYPE)
+else
+       confflags += --build=$(DEB_HOST_GNU_TYPE) --host=$(DEB_HOST_GNU_TYPE)
+#      confflags += --build=$(DEB_BUILD_GNU_TYPE) --host=$(DEB_HOST_GNU_TYPE)
+endif
+
+confflags += --enable-fc --enable-builtins --enable-pcfformat --enable-bdfformat
+
+configure: $(STAMP_DIR)/patch
+       autoreconf -vfi
+
+obj-$(DEB_BUILD_GNU_TYPE)/config.status: configure
+       mkdir -p obj-$(DEB_BUILD_GNU_TYPE)
+       cd obj-$(DEB_BUILD_GNU_TYPE) && \
+       ../configure --prefix=/usr --mandir=\$${prefix}/share/man \
+                    --infodir=\$${prefix}/share/info $(confflags) \
+                    --without-bzip2 \
+                    CFLAGS="$(CFLAGS)" 
+
+build: build-stamp
+build-stamp: obj-$(DEB_BUILD_GNU_TYPE)/config.status
+       dh_testdir
+
+       cd obj-$(DEB_BUILD_GNU_TYPE) && $(MAKE)
+       >$@
+
+clean: xsfclean
+       dh_testdir
+       dh_testroot
+       rm -f build-stamp
+
+       rm -f config.cache config.log config.status
+       rm -f */config.cache */config.log */config.status
+       rm -f conftest* */conftest*
+       rm -rf autom4te.cache */autom4te.cache
+       rm -rf obj-*
+       rm -f $$(find -name Makefile.in)
+       rm -f aclocal.m4 config.guess config.h.in config.sub configure
+       rm -f depcomp install-sh ltmain.sh missing mkinstalldirs
+
+       dh_clean
+
+install: build
+       dh_testdir
+       dh_testroot
+       dh_clean -k
+       dh_installdirs
+
+       cd obj-$(DEB_BUILD_GNU_TYPE) && $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install
+
+# Build architecture-dependent files here.
+binary-arch: build install
+       dh_testdir
+       dh_testroot
+
+       dh_installdocs
+       dh_install --sourcedir=debian/tmp --list-missing
+       #dh_install --sourcedir=debian/tmp --list-missing -XlibXfont.la
+       dh_installchangelogs ChangeLog
+       dh_link
+       dh_strip --dbg-package=$(PACKAGE)-dbg
+       dh_compress
+       dh_fixperms
+       dh_makeshlibs -V'libxfont1 (>= 1:1.4.2)'
+       dh_shlibdeps
+       dh_installdeb
+       dh_gencontrol
+       dh_md5sums
+       dh_builddeb
+
+# Build architecture-independent files here.
+binary-indep: build install
+# Nothing to do
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install
diff --git a/debian/watch b/debian/watch
new file mode 100644 (file)
index 0000000..a241b87
--- /dev/null
@@ -0,0 +1,2 @@
+version=3
+http://xorg.freedesktop.org/releases/individual/lib/ libXfont-(.*)\.tar\.gz
diff --git a/debian/xsfbs/repack.sh b/debian/xsfbs/repack.sh
new file mode 100644 (file)
index 0000000..5935cc9
--- /dev/null
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+set -e
+
+if ! [ -d debian/prune ]; then
+       exit 0
+fi
+
+if [ "x$1" != x--upstream-version ]; then
+       exit 1
+fi
+
+version="$2"
+filename="$3"
+
+if [ -z "$version" ] || ! [ -f "$filename" ]; then
+       exit 1
+fi
+
+dir="$(pwd)"
+tempdir="$(mktemp -d)"
+
+cd "$tempdir"
+tar xf "$dir/$filename"
+cat "$dir"/debian/prune/* | while read file; do rm -f */$file; done
+
+tar czf "$dir/$filename" *
+cd "$dir"
+rm -rf "$tempdir"
+echo "Done pruning upstream tarball"
+
+exit 0
diff --git a/debian/xsfbs/xsfbs.mk b/debian/xsfbs/xsfbs.mk
new file mode 100644 (file)
index 0000000..5e16b10
--- /dev/null
@@ -0,0 +1,276 @@
+#!/usr/bin/make -f
+
+# Debian X Strike Force Build System (XSFBS): Make portion
+
+# Copyright 1996 Stephen Early
+# Copyright 1997 Mark Eichin
+# Copyright 1998-2005, 2007 Branden Robinson
+# Copyright 2005 David Nusinow
+#
+# Licensed under the GNU General Public License, version 2.  See the file
+# /usr/share/common-licenses/GPL or <http://www.gnu.org/copyleft/gpl.txt>.
+
+# Originally by Stephen Early <sde1000@debian.org>
+# Modified by Mark W. Eichin <eichin@kitten.gen.ma.us>
+# Modified by Adam Heath <doogie@debian.org>
+# Modified by Branden Robinson <branden@debian.org>
+# Modified by Fabio Massimo Di Nitto <fabbione@fabbione.net>
+# Modified by David Nusinow <dnusinow@debian.org>
+# Acknowledgements to Manoj Srivastava.
+
+# Pass $(DH_OPTIONS) into the environment for debhelper's benefit.
+export DH_OPTIONS
+
+# force quilt to not use ~/.quiltrc and to use debian/patches
+QUILT = QUILT_PATCHES=debian/patches quilt --quiltrc /dev/null
+
+# Set up parameters for the upstream build environment.
+
+# Determine (source) package name from Debian changelog.
+SOURCE_NAME:=$(shell dpkg-parsechangelog -ldebian/changelog \
+                        | grep '^Source:' | awk '{print $$2}')
+
+# Determine package version from Debian changelog.
+SOURCE_VERSION:=$(shell dpkg-parsechangelog -ldebian/changelog \
+                        | grep '^Version:' | awk '{print $$2}')
+
+# Determine upstream version number.
+UPSTREAM_VERSION:=$(shell echo $(SOURCE_VERSION) | sed 's/-.*//')
+
+# Determine the source version without the epoch for make-orig-tar-gz
+NO_EPOCH_VER:=$(shell echo $(UPSTREAM_VERSION) | sed 's/^.://')
+
+# Figure out who's building this package.
+BUILDER:=$(shell echo $${DEBEMAIL:-$${EMAIL:-$$(echo $$LOGNAME@$$(cat /etc/mailname 2>/dev/null))}})
+
+# Find out if this is an official build; an official build has nothing but
+# digits, dots, and/or the codename of a release in the Debian part of the
+# version number.  Anything else indicates an unofficial build.
+OFFICIAL_BUILD:=$(shell VERSION=$(SOURCE_VERSION); if ! expr "$$(echo $${VERSION\#\#*-} | sed 's/\(woody\|sarge\|etch\|lenny\)//g')" : ".*[^0-9.].*" >/dev/null 2>&1; then echo yes; fi)
+
+# Set up parameters for the Debian build environment.
+
+# Determine our architecture.
+BUILD_ARCH:=$(shell dpkg-architecture -qDEB_BUILD_ARCH)
+# Work around some old-time dpkg braindamage.
+BUILD_ARCH:=$(subst i486,i386,$(BUILD_ARCH))
+# The DEB_HOST_ARCH variable may be set per the Debian cross-compilation policy.
+ifdef DEB_HOST_ARCH
+ ARCH:=$(DEB_HOST_ARCH)
+else
+ # dpkg-cross sets the ARCH environment variable; if set, use it.
+ ifdef ARCH
+  ARCH:=$(ARCH)
+ else
+  ARCH:=$(BUILD_ARCH)
+ endif
+endif
+
+# $(STAMP_DIR) houses stamp files for complex targets.
+STAMP_DIR:=stampdir
+
+# $(DEBTREEDIR) is where all install rules are told (via $(DESTDIR)) to place
+# their files.
+DEBTREEDIR:=$(CURDIR)/debian/tmp
+
+# All "important" targets have four lines:
+#   1) A target name that is invoked by a package-building tool or the user.
+#      This consists of a dependency on a "$(STAMP_DIR)/"-prefixed counterpart.
+#   2) A line delcaring 1) as a phony target (".PHONY:").
+#   3) A "$(STAMP_DIR)/"-prefixed target which does the actual work, and may
+#   depend on other targets.
+#   4) A line declaring 3) as a member of the $(stampdir_targets) variable; the
+#   "$(STAMP_DIR)/" prefix is omitted.
+#
+# This indirection is needed so that the "stamp" files that signify when a rule
+# is done can be located in a separate "stampdir".  Recall that make has no way
+# to know when a goal has been met for a phony target (like "build" or
+# "install").
+#
+# At the end of each "$(STAMP_DIR)/" target, be sure to run the command ">$@"
+# so that the target will not be run again.  Removing the file will make Make
+# run the target over.
+
+# All phony targets should be declared as dependencies of .PHONY, even if they
+# do not have "($STAMP_DIR)/"-prefixed counterparts.
+
+# Define a harmless default rule to keep things from going nuts by accident.
+.PHONY: default
+default:
+
+# Set up the $(STAMP_DIR) directory.
+.PHONY: stampdir
+stampdir_targets+=stampdir
+stampdir: $(STAMP_DIR)/stampdir
+$(STAMP_DIR)/stampdir:
+       mkdir $(STAMP_DIR)
+       >$@
+
+# Set up the package build directory as quilt expects to find it.
+.PHONY: prepare
+stampdir_targets+=prepare
+prepare: $(STAMP_DIR)/prepare
+$(STAMP_DIR)/prepare: $(STAMP_DIR)/log $(STAMP_DIR)/genscripts
+       >$@
+
+.PHONY: log
+stampdir_targets+=log
+log: $(STAMP_DIR)/log
+$(STAMP_DIR)/log: $(STAMP_DIR)/stampdir
+       mkdir -p $(STAMP_DIR)/log
+
+# Apply all patches to the upstream source.
+.PHONY: patch
+stampdir_targets+=patch
+patch: $(STAMP_DIR)/patch
+$(STAMP_DIR)/patch: $(STAMP_DIR)/prepare
+       if ! [ `which quilt` ]; then \
+               echo "Couldn't find quilt. Please install it or add it to the build-depends for this package."; \
+               exit 1; \
+       fi; \
+       if $(QUILT) next >/dev/null 2>&1; then \
+         echo -n "Applying patches..."; \
+         if $(QUILT) push -a -v >$(STAMP_DIR)/log/patch 2>&1; then \
+           cat $(STAMP_DIR)/log/patch; \
+           echo "successful."; \
+         else \
+           cat $(STAMP_DIR)/log/patch; \
+           echo "failed! (check $(STAMP_DIR)/log/patch for details)"; \
+           exit 1; \
+         fi; \
+       else \
+         echo "No patches to apply"; \
+       fi; \
+       >$@
+
+# Revert all patches to the upstream source.
+.PHONY: unpatch
+unpatch: $(STAMP_DIR)/log
+       rm -f $(STAMP_DIR)/patch
+       @echo -n "Unapplying patches..."; \
+       if $(QUILT) applied >/dev/null 2>/dev/null; then \
+         if $(QUILT) pop -a -v >$(STAMP_DIR)/log/unpatch 2>&1; then \
+           cat $(STAMP_DIR)/log/unpatch; \
+           echo "successful."; \
+         else \
+           cat $(STAMP_DIR)/log/unpatch; \
+           echo "failed! (check $(STAMP_DIR)/log/unpatch for details)"; \
+           exit 1; \
+         fi; \
+       else \
+         echo "nothing to do."; \
+       fi
+
+# Clean the generated maintainer scripts.
+.PHONY: cleanscripts
+cleanscripts:
+       rm -f $(STAMP_DIR)/genscripts
+       rm -f debian/*.config \
+             debian/*.postinst \
+             debian/*.postrm \
+             debian/*.preinst \
+             debian/*.prerm
+
+# Clean the package build tree.
+.PHONY: xsfclean
+xsfclean: cleanscripts unpatch
+       dh_testdir
+       rm -rf .pc
+       rm -rf $(STAMP_DIR)
+       dh_clean
+
+# Remove files from the upstream source tree that we don't need, or which have
+# licensing problems.  It must be run before creating the .orig.tar.gz.
+#
+# Note: This rule is for Debian package maintainers' convenience, and is not
+# needed for conventional build scenarios.
+.PHONY: prune-upstream-tree
+prune-upstream-tree:
+       # Ensure we're in the correct directory.
+       dh_testdir
+       grep -rvh '^#' debian/prune/ | xargs --no-run-if-empty rm -rf
+
+# Verify that there are no offsets or fuzz in the patches we apply.
+#
+# Note: This rule is for Debian package maintainers' convenience, and is not
+# needed for conventional build scenarios.
+.PHONY: patch-audit
+patch-audit: prepare unpatch
+       @echo -n "Auditing patches..."; \
+       >$(STAMP_DIR)/log/patch; \
+       FUZZY=; \
+       while [ -n "$$($(QUILT) next)" ]; do \
+         RESULT=$$($(QUILT) push -v | tee -a $(STAMP_DIR)/log/patch | grep ^Hunk | sed 's/^Hunk.*\(succeeded\|FAILED\).*/\1/');\
+         case "$$RESULT" in \
+           succeeded) \
+             echo "fuzzy patch: $$($(QUILT) top)" \
+               | tee -a $(STAMP_DIR)/log/$$($(QUILT) top); \
+             FUZZY=yes; \
+             ;; \
+           FAILED) \
+             echo "broken patch: $$($(QUILT) next)" \
+               | tee -a $(STAMP_DIR)/log/$$($(QUILT) next); \
+             exit 1; \
+             ;; \
+         esac; \
+       done; \
+       if [ -n "$$FUZZY" ]; then \
+         echo "there were fuzzy patches; please fix."; \
+         exit 1; \
+       else \
+         echo "done."; \
+       fi
+
+# Generate the maintainer scripts.
+.PHONY: genscripts
+stampdir_targets+=genscripts
+genscripts: $(STAMP_DIR)/genscripts
+$(STAMP_DIR)/genscripts: $(STAMP_DIR)/stampdir
+       for FILE in debian/*.config.in \
+                   debian/*.postinst.in \
+                   debian/*.postrm.in \
+                   debian/*.preinst.in \
+                   debian/*.prerm.in; do \
+         if [ -e "$$FILE" ]; then \
+           MAINTSCRIPT=$$(echo $$FILE | sed 's/.in$$//'); \
+           sed -n '1,/^#INCLUDE_SHELL_LIB#$$/p' <$$FILE \
+             | sed -e '/^#INCLUDE_SHELL_LIB#$$/d' >$$MAINTSCRIPT.tmp; \
+           cat debian/xsfbs/xsfbs.sh >>$$MAINTSCRIPT.tmp; \
+           sed -n '/^#INCLUDE_SHELL_LIB#$$/,$$p' <$$FILE \
+             | sed -e '/^#INCLUDE_SHELL_LIB#$$/d' >>$$MAINTSCRIPT.tmp; \
+           sed -e 's/@SOURCE_VERSION@/$(SOURCE_VERSION)/' \
+               -e 's/@OFFICIAL_BUILD@/$(OFFICIAL_BUILD)/' \
+             <$$MAINTSCRIPT.tmp >$$MAINTSCRIPT; \
+           rm $$MAINTSCRIPT.tmp; \
+         fi; \
+       done
+       # Validate syntax of generated shell scripts.
+       #sh debian/scripts/validate-posix-sh debian/*.config \
+       #                                    debian/*.postinst \
+       #                                    debian/*.postrm \
+       #                                    debian/*.preinst \
+       #                                    debian/*.prerm
+       >$@
+
+SERVERMINVERS = $(shell cat /usr/share/xserver-xorg/serverminver 2>/dev/null)
+VIDEOABI = $(shell cat /usr/share/xserver-xorg/videoabiver 2>/dev/null)
+INPUTABI = $(shell cat /usr/share/xserver-xorg/inputabiver 2>/dev/null)
+SERVER_DEPENDS = xserver-xorg-core (>= $(SERVERMINVERS))
+VIDDRIVER_PROVIDES = xserver-xorg-video-$(VIDEOABI)
+INPDRIVER_PROVIDES = xserver-xorg-input-$(INPUTABI)
+ifeq ($(PACKAGE),)
+PACKAGE=$(shell awk '/^Package:/ { print $$2; exit }' < debian/control)
+endif
+
+.PHONY: serverabi
+serverabi: install
+ifeq ($(SERVERMINVERS),)
+       @echo error: xserver-xorg-dev needs to be installed
+       @exit 1
+else
+       echo "xserver:Depends=$(SERVER_DEPENDS)" >> debian/$(PACKAGE).substvars
+       echo "xviddriver:Provides=$(VIDDRIVER_PROVIDES)" >> debian/$(PACKAGE).substvars
+       echo "xinpdriver:Provides=$(INPDRIVER_PROVIDES)" >> debian/$(PACKAGE).substvars
+endif
+
+# vim:set noet ai sts=8 sw=8 tw=0:
diff --git a/debian/xsfbs/xsfbs.sh b/debian/xsfbs/xsfbs.sh
new file mode 100644 (file)
index 0000000..813fd8d
--- /dev/null
@@ -0,0 +1,622 @@
+# This is the X Strike Force shell library for X Window System package
+# maintainer scripts.  It serves to define shell functions commonly used by
+# such packages, and performs some error checking necessary for proper operation
+# of those functions.  By itself, it does not "do" much; the maintainer scripts
+# invoke the functions defined here to accomplish package installation and
+# removal tasks.
+
+# If you are reading this within a Debian package maintainer script (e.g.,
+# /var/lib/dpkg/info/PACKAGE.{config,preinst,postinst,prerm,postrm}), you can
+# skip past this library by scanning forward in this file to the string
+# "GOBSTOPPER".
+
+SOURCE_VERSION=@SOURCE_VERSION@
+OFFICIAL_BUILD=@OFFICIAL_BUILD@
+
+# Use special abnormal exit codes so that problems with this library are more
+# easily tracked down.
+SHELL_LIB_INTERNAL_ERROR=86
+SHELL_LIB_THROWN_ERROR=74
+SHELL_LIB_USAGE_ERROR=99
+
+# old -> new variable names
+if [ -z "$DEBUG_XORG_PACKAGE" ] && [ -n "$DEBUG_XFREE86_PACKAGE" ]; then
+  DEBUG_XORG_PACKAGE="$DEBUG_XFREE86_PACKAGE"
+fi
+if [ -z "$DEBUG_XORG_DEBCONF" ] && [ -n "$DEBUG_XFREE86_DEBCONF" ]; then
+  DEBUG_XORG_DEBCONF="$DEBUG_XFREE86_DEBCONF"
+fi
+
+# initial sanity checks
+if [ -z "$THIS_PACKAGE" ]; then
+  cat >&2 <<EOF
+Error: package maintainer script attempted to use shell library without
+definining \$THIS_PACKAGE shell variable.  Please report the package name,
+version, and the text of this error message to the Debian Bug Tracking System.
+Visit <http://www.debian.org/Bugs/Reporting> on the World Wide Web for
+instructions, read the file /usr/share/doc/debian/bug-reporting.txt from the
+"doc-debian" package, or install the "reportbug" package and use the command of
+the same name to file a report against version $SOURCE_VERSION of this package.
+EOF
+  exit $SHELL_LIB_USAGE_ERROR
+fi
+
+if [ -z "$THIS_SCRIPT" ]; then
+  cat >&2 <<EOF
+Error: package maintainer script attempted to use shell library without
+definining \$THIS_SCRIPT shell variable.  Please report the package name,
+version, and the text of this error message to the Debian Bug Tracking System.
+Visit <http://www.debian.org/Bugs/Reporting> on the World Wide Web for
+instructions, read the file /usr/share/doc/debian/bug-reporting.txt from the
+"doc-debian" package, or install the "reportbug" package and use the command of
+the same name to file a report against version $SOURCE_VERSION of the
+"$THIS_PACKAGE" package.
+EOF
+  exit $SHELL_LIB_USAGE_ERROR
+fi
+
+if [ "$1" = "reconfigure" ] || [ -n "$DEBCONF_RECONFIGURE" ]; then
+  RECONFIGURE="true"
+else
+  RECONFIGURE=
+fi
+
+if ([ "$1" = "install" ] || [ "$1" = "configure" ]) && [ -z "$2" ]; then
+  FIRSTINST="yes"
+fi
+
+if [ -z "$RECONFIGURE" ] && [ -z "$FIRSTINST" ]; then
+  UPGRADE="yes"
+fi
+
+trap "message;\
+      message \"Received signal.  Aborting $THIS_PACKAGE package $THIS_SCRIPT script.\";\
+      message;\
+      exit 1" HUP INT QUIT TERM
+
+reject_nondigits () {
+  # syntax: reject_nondigits [ operand ... ]
+  #
+  # scan operands (typically shell variables whose values cannot be trusted) for
+  # characters other than decimal digits and barf if any are found
+  while [ -n "$1" ]; do
+    # does the operand contain anything but digits?
+    if ! expr "$1" : "[[:digit:]]\+$" > /dev/null 2>&1; then
+      # can't use die(), because it wraps message() which wraps this function
+      echo "$THIS_PACKAGE $THIS_SCRIPT error: reject_nondigits() encountered" \
+           "possibly malicious garbage \"$1\"" >&2
+      exit $SHELL_LIB_THROWN_ERROR
+    fi
+    shift
+  done
+}
+
+reject_unlikely_path_chars () {
+  # syntax: reject_unlikely_path_chars [ operand ... ]
+  #
+  # scan operands (typically shell variables whose values cannot be trusted) for
+  # characters unlikely to be seen in a path and which the shell might
+  # interpret and barf if any are found
+  while [ -n "$1" ]; do
+    # does the operand contain any funny characters?
+    if expr "$1" : '.*[!$&()*;<>?|].*' > /dev/null 2>&1; then
+      # can't use die(), because I want to avoid forward references
+      echo "$THIS_PACKAGE $THIS_SCRIPT error: reject_unlikely_path_chars()" \
+           "encountered possibly malicious garbage \"$1\"" >&2
+      exit $SHELL_LIB_THROWN_ERROR
+    fi
+    shift
+  done
+}
+
+# Query the terminal to establish a default number of columns to use for
+# displaying messages to the user.  This is used only as a fallback in the
+# event the COLUMNS variable is not set.  ($COLUMNS can react to SIGWINCH while
+# the script is running, and this cannot, only being calculated once.)
+DEFCOLUMNS=$(stty size 2> /dev/null | awk '{print $2}') || true
+if ! expr "$DEFCOLUMNS" : "[[:digit:]]\+$" > /dev/null 2>&1; then
+  DEFCOLUMNS=80
+fi
+
+message () {
+  # pretty-print messages of arbitrary length
+  reject_nondigits "$COLUMNS"
+  echo "$*" | fmt -t -w ${COLUMNS:-$DEFCOLUMNS} >&2
+}
+
+observe () {
+  # syntax: observe message ...
+  #
+  # issue observational message suitable for logging someday when support for
+  # it exists in dpkg
+  if [ -n "$DEBUG_XORG_PACKAGE" ]; then
+    message "$THIS_PACKAGE $THIS_SCRIPT note: $*"
+  fi
+}
+
+warn () {
+  # syntax: warn message ...
+  #
+  # issue warning message suitable for logging someday when support for
+  # it exists in dpkg; also send to standard error
+  message "$THIS_PACKAGE $THIS_SCRIPT warning: $*"
+}
+
+die () {
+  # syntax: die message ...
+  #
+  # exit script with error message
+  message "$THIS_PACKAGE $THIS_SCRIPT error: $*"
+  exit $SHELL_LIB_THROWN_ERROR
+}
+
+internal_error () {
+  # exit script with error; essentially a "THIS SHOULD NEVER HAPPEN" message
+  message "internal error: $*"
+  if [ -n "$OFFICIAL_BUILD" ]; then
+    message "Please report a bug in the $THIS_SCRIPT script of the" \
+            "$THIS_PACKAGE package, version $SOURCE_VERSION to the Debian Bug" \
+            "Tracking System.  Include all messages above that mention the" \
+            "$THIS_PACKAGE package.  Visit " \
+            "<http://www.debian.org/Bugs/Reporting> on the World Wide Web for" \
+            "instructions, read the file" \
+            "/usr/share/doc/debian/bug-reporting.txt from the doc-debian" \
+            "package, or install the reportbug package and use the command of" \
+            "the same name to file a report."
+  fi
+  exit $SHELL_LIB_INTERNAL_ERROR
+}
+
+usage_error () {
+  message "usage error: $*"
+  message "Please report a bug in the $THIS_SCRIPT script of the" \
+          "$THIS_PACKAGE package, version $SOURCE_VERSION to the Debian Bug" \
+          "Tracking System.  Include all messages above that mention the" \
+          "$THIS_PACKAGE package.  Visit " \
+          "<http://www.debian.org/Bugs/Reporting> on the World Wide Web for" \
+          "instructions, read the file" \
+          "/usr/share/doc/debian/bug-reporting.txt from the doc-debian" \
+          "package, or install the reportbug package and use the command of" \
+          "the same name to file a report."
+  exit $SHELL_LIB_USAGE_ERROR
+}
+
+font_update () {
+  # run $UPDATECMDS in $FONTDIRS
+
+  local dir cmd shortcmd x_font_dir_prefix
+
+  x_font_dir_prefix="/usr/share/fonts/X11"
+
+  if [ -z "$UPDATECMDS" ]; then
+    usage_error "font_update() called but \$UPDATECMDS not set"
+  fi
+  if [ -z "$FONTDIRS" ]; then
+    usage_error "font_update() called but \$FONTDIRS not set"
+  fi
+
+  reject_unlikely_path_chars "$UPDATECMDS"
+  reject_unlikely_path_chars "$FONTDIRS"
+
+  for dir in $FONTDIRS; do
+    if [ -d "$x_font_dir_prefix/$dir" ]; then
+      for cmd in $UPDATECMDS; do
+        if which "$cmd" > /dev/null 2>&1; then
+          shortcmd=${cmd##*/}
+          observe "running $shortcmd in $dir font directory"
+         cmd_opts=
+          if [ "$shortcmd" = "update-fonts-alias" ]; then
+            cmd_opts=--x11r7-layout
+          fi
+          if [ "$shortcmd" = "update-fonts-dir" ]; then
+            cmd_opts=--x11r7-layout
+          fi
+          if [ "$shortcmd" = "update-fonts-scale" ]; then
+            cmd_opts=--x11r7-layout
+          fi
+          $cmd $cmd_opts $dir || warn "$cmd $cmd_opts $dir" \
+                              "failed; font directory data may not" \
+                              "be up to date"
+        else
+          warn "$cmd not found; not updating corresponding $dir font" \
+               "directory data"
+        fi
+      done
+    else
+      warn "$dir is not a directory; not updating font directory data"
+    fi
+  done
+}
+
+remove_conffile_prepare () {
+  # syntax: remove_conffile_prepare filename official_md5sum ...
+  #
+  # Check a conffile "filename" against a list of canonical MD5 checksums.
+  # If the file's current MD5 checksum matches one of the "official_md5sum"
+  # operands provided, then prepare the conffile for removal from the system.
+  # We defer actual deletion until the package is configured so that we can
+  # roll this operation back if package installation fails.
+  #
+  # Call this function from a preinst script in the event $1 is "upgrade" or
+  # "install" and verify $2 to ensure the package is being upgraded from a
+  # version (or installed over a version removed-but-not-purged) prior to the
+  # one in which the conffile was obsoleted.
+
+  local conffile current_checksum
+
+  # validate arguments
+  if [ $# -lt 2 ]; then
+    usage_error "remove_conffile_prepare() called with wrong number of" \
+                "arguments; expected at least 2, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  conffile="$1"
+  shift
+
+  # does the conffile even exist?
+  if [ -e "$conffile" ]; then
+    # calculate its checksum
+    current_checksum=$(md5sum < "$conffile" | sed 's/[[:space:]].*//')
+    # compare it to each supplied checksum
+    while [ -n "$1" ]; do
+      if [ "$current_checksum" = "$1" ]; then
+        # we found a match; move the confffile and stop looking
+        observe "preparing obsolete conffile $conffile for removal"
+        mv "$conffile" "$conffile.$THIS_PACKAGE-tmp"
+        break
+      fi
+      shift
+    done
+  fi
+}
+
+remove_conffile_lookup () {
+  # syntax: remove_conffile_lookup package filename
+  #
+  # Lookup the md5sum of a conffile in dpkg's database, and prepare for removal
+  # if it matches the actual file's md5sum.
+  #
+  # Call this function when you would call remove_conffile_prepare but only
+  # want to check against dpkg's status database instead of known checksums.
+
+  local package conffile old_md5sum
+
+  # validate arguments
+  if [ $# -ne 2 ]; then
+    usage_error "remove_conffile_lookup() called with wrong number of" \
+                "arguments; expected 1, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  package="$1"
+  conffile="$2"
+
+  if ! [ -e "$conffile" ]; then
+    return
+  fi
+  old_md5sum="$(dpkg-query -W -f='${Conffiles}' "$package" | \
+    awk '{ if (match($0, "^ '"$conffile"' ")) print $2}')"
+  if [ -n "$old_md5sum" ]; then
+    remove_conffile_prepare "$conffile" "$old_md5sum"
+  fi
+}
+
+remove_conffile_commit () {
+  # syntax: remove_conffile_commit filename
+  #
+  # Complete the removal of a conffile "filename" that has become obsolete.
+  #
+  # Call this function from a postinst script after having used
+  # remove_conffile_prepare() in the preinst.
+
+  local conffile
+
+  # validate arguments
+  if [ $# -ne 1 ]; then
+    usage_error "remove_conffile_commit() called with wrong number of" \
+                "arguments; expected 1, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  conffile="$1"
+
+  # if the temporary file created by remove_conffile_prepare() exists, remove it
+  if [ -e "$conffile.$THIS_PACKAGE-tmp" ]; then
+    observe "committing removal of obsolete conffile $conffile"
+    rm "$conffile.$THIS_PACKAGE-tmp"
+  fi
+}
+
+remove_conffile_rollback () {
+  # syntax: remove_conffile_rollback filename
+  #
+  # Roll back the removal of a conffile "filename".
+  #
+  # Call this function from a postrm script in the event $1 is "abort-upgrade"
+  # or "abort-install" is  after having used remove_conffile_prepare() in the
+  # preinst.
+
+  local conffile
+
+  # validate arguments
+  if [ $# -ne 1 ]; then
+    usage_error "remove_conffile_rollback() called with wrong number of" \
+                "arguments; expected 1, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  conffile="$1"
+
+  # if the temporary file created by remove_conffile_prepare() exists, move it
+  # back
+  if [ -e "$conffile.$THIS_PACKAGE-tmp" ]; then
+    observe "rolling back removal of obsolete conffile $conffile"
+    mv "$conffile.$THIS_PACKAGE-tmp" "$conffile"
+  fi
+}
+
+replace_conffile_with_symlink_prepare () {
+  # syntax: replace_conffile_with_symlink_prepare oldfilename newfilename \
+  # official_md5sum ...
+  #
+  # Check a conffile "oldfilename" against a list of canonical MD5 checksums.
+  # If the file's current MD5 checksum matches one of the "official_md5sum"
+  # operands provided, then prepare the conffile for removal from the system.
+  # We defer actual deletion until the package is configured so that we can
+  # roll this operation back if package installation fails. Otherwise copy it
+  # to newfilename and let dpkg handle it through conffiles mechanism.
+  #
+  # Call this function from a preinst script in the event $1 is "upgrade" or
+  # "install" and verify $2 to ensure the package is being upgraded from a
+  # version (or installed over a version removed-but-not-purged) prior to the
+  # one in which the conffile was obsoleted.
+
+  local conffile current_checksum
+
+  # validate arguments
+  if [ $# -lt 3 ]; then
+    usage_error "replace_conffile_with_symlink_prepare() called with wrong" \
+                " number of arguments; expected at least 3, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  oldconffile="$1"
+  shift
+  newconffile="$1"
+  shift
+
+  remove_conffile_prepare "$_oldconffile" "$@"
+  # If $oldconffile still exists, then md5sums didn't match.
+  # Copy it to new one.
+  if [ -f "$oldconffile" ]; then
+    cp "$oldconffile" "$newconffile"
+  fi
+
+}
+
+replace_conffile_with_symlink_commit () {
+  # syntax: replace_conffile_with_symlink_commit oldfilename
+  #
+  # Complete the removal of a conffile "oldfilename" that has been
+  # replaced by a symlink.
+  #
+  # Call this function from a postinst script after having used
+  # replace_conffile_with_symlink_prepare() in the preinst.
+
+  local conffile
+
+  # validate arguments
+  if [ $# -ne 1 ]; then
+    usage_error "replace_conffile_with_symlink_commit() called with wrong" \
+                "number of arguments; expected 1, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  conffile="$1"
+
+  remove_conffile_commit "$conffile"
+}
+
+replace_conffile_with_symlink_rollback () {
+  # syntax: replace_conffile_with_symlink_rollback oldfilename newfilename
+  #
+  # Roll back the replacing of a conffile "oldfilename" with symlink to
+  # "newfilename".
+  #
+  # Call this function from a postrm script in the event $1 is "abort-upgrade"
+  # or "abort-install" and verify $2 to ensure the package failed to upgrade
+  # from a version (or install over a version removed-but-not-purged) prior
+  # to the one in which the conffile was obsoleted.
+  # You should have  used replace_conffile_with_symlink_prepare() in the
+  # preinst.
+
+  local conffile
+
+  # validate arguments
+  if [ $# -ne 2 ]; then
+    usage_error "replace_conffile_with_symlink_rollback() called with wrong" \
+                "number of arguments; expected 2, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  oldconffile="$1"
+  newconffile="$2"
+
+  remove_conffile_rollback "$_oldconffile"
+  if [ -f "$newconffile" ]; then
+    rm "$newconffile"
+  fi
+}
+
+run () {
+  # syntax: run command [ argument ... ]
+  #
+  # Run specified command with optional arguments and report its exit status.
+  # Useful for commands whose exit status may be nonzero, but still acceptable,
+  # or commands whose failure is not fatal to us.
+  #
+  # NOTE: Do *not* use this function with db_get or db_metaget commands; in
+  # those cases the return value of the debconf command *must* be checked
+  # before the string returned by debconf is used for anything.
+
+  local retval
+
+  # validate arguments
+  if [ $# -lt 1 ]; then
+    usage_error "run() called with wrong number of arguments; expected at" \
+                "least 1, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  "$@" || retval=$?
+
+  if [ ${retval:-0} -ne 0 ]; then
+    observe "command \"$*\" exited with status $retval"
+  fi
+}
+
+make_symlink_sane () {
+  # syntax: make_symlink_sane symlink target
+  #
+  # Ensure that the symbolic link symlink exists, and points to target.
+  #
+  # If symlink does not exist, create it and point it at target.
+  #
+  # If symlink exists but is not a symbolic link, back it up.
+  #
+  # If symlink exists, is a symbolic link, but points to the wrong location, fix
+  # it.
+  #
+  # If symlink exists, is a symbolic link, and already points to target, do
+  # nothing.
+  #
+  # This function wouldn't be needed if ln had an -I, --idempotent option.
+
+  # Validate arguments.
+  if [ $# -ne 2 ]; then
+    usage_error "make_symlink_sane() called with wrong number of arguments;" \
+      "expected 2, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  # We could just use the positional parameters as-is, but that makes things
+  # harder to follow.
+  local symlink target
+
+  symlink="$1"
+  target="$2"
+
+  if [ -L "$symlink" ] && [ "$(readlink "$symlink")" = "$target" ]; then
+      observe "link from $symlink to $target already exists"
+  else
+    observe "creating symbolic link from $symlink to $target"
+    mkdir -p "${target%/*}" "${symlink%/*}"
+    ln -s -b -S ".dpkg-old" "$target" "$symlink"
+  fi
+}
+
+migrate_dir_to_symlink () {
+  # syntax: migrate_dir_to_symlink old_location new_location
+  #
+  # Per Debian Policy section 6.5.4, "A directory will never be replaced by a
+  # symbolic link to a directory or vice versa; instead, the existing state
+  # (symlink or not) will be left alone and dpkg will follow the symlink if
+  # there is one."
+  #
+  # We have to do it ourselves.
+  #
+  # This function moves the contents of old_location, a directory, into
+  # new_location, a directory, then makes old_location a symbolic link to
+  # new_location.
+  #
+  # old_location need not exist, but if it does, it must be a directory (or a
+  # symlink to a directory).  If it is not, it is backed up.  If new_location
+  # exists already and is not a directory, it is backed up.
+  #
+  # This function should be called from a package's preinst so that other
+  # packages unpacked after this one --- but before this package's postinst runs
+  # --- are unpacked into new_location even if their payloads contain
+  # old_location filespecs.
+
+  # Validate arguments.
+  if [ $# -ne 2 ]; then
+    usage_error "migrate_dir_to_symlink() called with wrong number of"
+                "arguments; expected 2, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  # We could just use the positional parameters as-is, but that makes things
+  # harder to follow.
+  local new old
+
+  old="$1"
+  new="$2"
+
+  # Is old location a symlink?
+  if [ -L "$old" ]; then
+    # Does it already point to new location?
+    if [ "$(readlink "$old")" = "$new" ]; then
+      # Nothing to do; migration has already been done.
+      observe "migration of $old to $new already done"
+      return 0
+    else
+      # Back it up.
+      warn "backing up symbolic link $old as $old.dpkg-old"
+      mv -b "$old" "$old.dpkg-old"
+    fi
+  fi
+
+  # Does old location exist, but is not a directory?
+  if [ -e "$old" ] && ! [ -d "$old" ]; then
+      # Back it up.
+      warn "backing up non-directory $old as $old.dpkg-old"
+      mv -b "$old" "$old.dpkg-old"
+  fi
+
+  observe "migrating $old to $new"
+
+  # Is new location a symlink?
+  if [ -L "$new" ]; then
+    # Does it point the wrong way, i.e., back to where we're migrating from?
+    if [ "$(readlink "$new")" = "$old" ]; then
+      # Get rid of it.
+      observe "removing symbolic link $new which points to $old"
+      rm "$new"
+    else
+      # Back it up.
+      warn "backing up symbolic link $new as $new.dpkg-old"
+      mv -b "$new" "$new.dpkg-old"
+    fi
+  fi
+
+  # Does new location exist, but is not a directory?
+  if [ -e "$new" ] && ! [ -d "$new" ]; then
+    warn "backing up non-directory $new as $new.dpkg-old"
+    mv -b "$new" "$new.dpkg-old"
+  fi
+
+  # Create new directory if it does not yet exist.
+  if ! [ -e "$new" ]; then
+    observe "creating $new"
+    mkdir -p "$new"
+  fi
+
+  # Copy files in old location to new location.  Back up any filenames that
+  # already exist in the new location with the extension ".dpkg-old".
+  observe "copying files from $old to $new"
+  if ! (cd "$old" && cp -a -b -S ".dpkg-old" . "$new"); then
+    die "error(s) encountered while copying files from $old to $new"
+  fi
+
+  # Remove files at old location.
+  observe "removing $old"
+  rm -r "$old"
+
+  # Create symlink from old location to new location.
+  make_symlink_sane "$old" "$new"
+}
+
+# vim:set ai et sw=2 ts=2 tw=80:
+
+# GOBSTOPPER: The X Strike Force shell library ends here.
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100755 (executable)
index 0000000..dc3f0a6
--- /dev/null
@@ -0,0 +1,66 @@
+#
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+#
+
+# Developer documentation - not installed on system
+EXTRA_DIST = fontlib.xml
+
+if ENABLE_DEVEL_DOCS
+doc_sources = fontlib.xml
+
+if HAVE_XMLTO
+noinst_DATA = $(doc_sources:.xml=.html)
+
+if HAVE_FOP
+noinst_DATA += $(doc_sources:.xml=.ps) $(doc_sources:.xml=.pdf)
+endif
+
+if HAVE_XMLTO_TEXT
+noinst_DATA += $(doc_sources:.xml=.txt)
+endif
+
+if HAVE_STYLESHEETS
+XMLTO_FLAGS = -m $(XSL_STYLESHEET)
+
+noinst_DATA += xorg.css
+xorg.css: $(STYLESHEET_SRCDIR)/xorg.css
+       $(AM_V_GEN)cp -pf $(STYLESHEET_SRCDIR)/xorg.css $@
+endif
+
+CLEANFILES = $(noinst_DATA)
+
+SUFFIXES = .xml .ps .pdf .txt .html
+
+.xml.txt:
+       $(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) txt $<
+
+.xml.html:
+       $(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) xhtml-nochunks $<
+
+.xml.pdf:
+       $(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) --with-fop pdf $<
+
+.xml.ps:
+       $(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) --with-fop ps $<
+
+endif HAVE_XMLTO
+endif ENABLE_DEVEL_DOCS
diff --git a/doc/fontlib.css b/doc/fontlib.css
new file mode 100644 (file)
index 0000000..0bc70e6
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+.structname, .property, .errorname, .function, .parameter, .filename {
+  font-family: monospace;
+}
+
+h1, .author, .pubdate {
+  text-align: center;
+}
+
+.legalnotice {
+  text-align: justify;
+  font-size: small;
+  font-style: italic;
+}
+
+.warning {
+  border: 1px solid red;
+  background: yellow;
+}
diff --git a/doc/fontlib.xml b/doc/fontlib.xml
new file mode 100755 (executable)
index 0000000..f2e4811
--- /dev/null
@@ -0,0 +1,659 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
+            "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" >
+<!-- lifted from troff+ms by doclifter -->
+<!-- previous version was in xorg-docs/specs/Xserver/fontlib.ms -->
+
+  <article id='fontlibms'>
+<!-- .ps 12 -->
+<!-- .EF 'Font Library Interface'\- % \-'July 27, 1991' -->
+<!-- .OF 'Font Library Interface'\- % \-'July 27, 1991' -->
+<!-- .EH '''' -->
+<!-- .OH '''' -->
+<!-- body begins here -->
+    <articleinfo>
+      <title>
+       The X Font Library
+      </title>
+      <pubdate>July 27, 1991</pubdate>
+      <authorgroup>
+       <author>
+         <firstname>Keith</firstname>
+         <surname>Packard</surname>
+         <affiliation>
+           <orgname>MIT X Consortium</orgname>
+         </affiliation>
+       </author>
+       <author>
+         <firstname>David</firstname>
+         <surname>Lemke</surname>
+         <affiliation>
+           <orgname>Network Computing Devices</orgname>
+         </affiliation>
+       </author>
+      </authorgroup>
+      <legalnotice>
+       <para>
+         Copyright 1993 <orgname>Network Computing Devices</orgname>
+       </para>
+       <para>
+         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 Network Computing
+         Devices not be used in advertising or publicity pertaining
+         to distribution of the software without specific, written
+         prior permission.  Network Computing Devices makes no
+         representations about the suitability of this software for
+         any purpose.  It is provided &ldquo;as is&rdquo; without
+         express or implied warranty.
+       </para>
+       <para>
+         Copyright 1993, 1994 <orgname>X Consortium</orgname>
+       </para>
+       <para>
+         Permission is hereby granted, free of charge, to any person
+         obtaining a copy of this software and associated
+         documentation files (the &ldquo;Software&rdquo;), to deal in the
+         Software without restriction, including without limitation
+         the rights to use, copy, modify, merge, publish, distribute,
+         sublicense, and/or sell copies of the Software, and to
+         permit persons to whom the Software is furnished to do so,
+         subject to the following conditions:
+       </para><para>
+         The above copyright notice and this permission notice shall be
+         included in all copies or substantial portions of the Software.
+       </para><para>
+         THE SOFTWARE IS PROVIDED &ldquo;AS IS&rdquo;, WITHOUT WARRANTY
+         OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
+         THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+         PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE X
+         CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+         LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+         OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+         SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+       </para><para>
+         Except as contained in this notice, the name of the X
+         Consortium shall not be used in advertising or otherwise to
+         promote the sale, use or other dealings in this Software
+         without prior written authorization from the X Consortium.
+       </para>
+      </legalnotice>
+    </articleinfo>
+
+    <warning>
+      <para>
+       This document has not been updated since X11R6, and is likely
+       to be somewhat out of date for the current libXfont.
+      </para>
+    </warning>
+
+    <para>
+      This document describes the data structures and interfaces for
+      using the X Font library.  It is intended as a reference for
+      programmers building X and Font servers.  You may want to refer
+      to the following documents:
+    </para>
+
+    <itemizedlist>
+      <listitem>
+       <para>
+         <citetitle pubwork="article">Definition of the Porting Layer for
+           the X v11 Sample Server</citetitle> for a discussion on how this
+         library interacts with the X server
+       </para>
+      </listitem>
+      <listitem>
+       <para>
+         <citetitle pubwork="article">Font Server Implementation
+           Overview</citetitle> which discusses the design of the font
+         server.
+       </para>
+      </listitem>
+      <listitem>
+       <para>
+         <citetitle pubwork="article">Bitmap Distribution Format</citetitle>
+         which covers the contents of the bitmap font files which this
+         library reads; although the library is capable of reading other
+         formats as well, including non-bitmap fonts.
+       </para>
+      </listitem>
+      <listitem>
+       <para>
+         <citetitle pubwork="article">The X Font Service Protocol</citetitle>
+         for a description of the constraints placed  on the design by
+         including support for this font service mechanism.
+       </para>
+      </listitem>
+    </itemizedlist>
+
+    <para>
+      This document assumes the reader is familiar with the X server design,
+      the X protocol as it relates to fonts and the C programming language.
+      As with most MIT produced documentation, this relies heavily on the
+      source code, so have a listing handy.
+    </para>
+
+    <sect1 id='requirements_for_the_font_library'>
+      <title>
+       Requirements for the Font library
+      </title>
+
+      <para>
+       To avoid miles of duplicate code in the X server, the font server
+       and the various font manipulation tools, the font library should
+       provide interfaces appropriate for all of these tasks.  In
+       particular, the X server and font server should be able to both
+       use the library to access disk based fonts, and to communicate
+       with a font server.  By providing a general library, we hoped to
+       avoid duplicating code between the X server and font server.
+      </para>
+
+      <para>
+       Another requirement is that the X server (or even a font server)
+       be able to continue servicing requests from other clients while
+       awaiting a response from the font server on behalf of one client.
+       This is the strongest requirement placed on the font library, and
+       has warped the design in curious ways.  Because both the X server
+       and font server are single threaded, the font library must not
+       suspend internally, rather it returns an indication of suspension
+       to the application which continues processing other things, until
+       the font data is ready, at which time it restarts the suspended
+       request.
+      </para>
+
+      <para>
+       Because the code for reading and manipulating bitmap font data is
+       used by the font applications <command>mkfontdir</command> and
+       <command>bdftopcf</command>, the font library includes
+       bitmap-font specific interfaces which those applications use,
+       instead of the more general interfaces used by the X and font
+       servers, which are unaware of the source of the font data.
+       These routines will be refered to as the bitmap font access
+       methods.
+      </para>
+
+    </sect1>
+
+    <sect1 id='general_font_library_interface_details'>
+      <title>
+       General Font Library Interface details.
+      </title>
+
+      <para>
+       To avoid collision between the #define name space for errors, the Font
+       library defines a new set of return values:
+      </para>
+
+      <programlisting remap='.nf'>
+#define AllocError      80
+#define StillWorking    81
+#define FontNameAlias   82
+#define BadFontName     83
+#define Suspended       84
+#define Successful      85
+#define BadFontPath     86
+#define BadCharRange    87
+#define BadFontFormat   88
+#define FPEResetFailed  89
+      </programlisting> <!-- .fi -->
+
+      <para>
+       Whenever a routine returns <errorname>Suspended</errorname>,
+       the font library will notify the caller (via the ClientSignal
+       interface described below) who should then reinvoke the same routine
+       again with the same arguments.
+      </para>
+
+    </sect1>
+
+    <sect1 id='font_path_elements'>
+      <title>
+       Font Path Elements
+      </title>
+
+      <para>
+       At the center of the general font access methods used by X and
+       <command>xfs</command> is the Font Path Element data structure.
+       Like most structures in the X server, this contains a collection
+       of data and some function pointers for manipulating this data:
+      </para>
+
+      <programlisting remap='.nf'>
+/* External view of font paths */
+typedef struct _FontPathElement {
+    int         name_length;
+    char       *name;
+    int         type;
+    int         refcount;
+    pointer     private;
+} FontPathElementRec, *FontPathElementPtr;
+
+typedef struct _FPEFunctions {
+    int         (*name_check) ( /* name */ );
+    int         (*init_fpe) ( /* fpe */ );
+    int         (*reset_fpe) ( /* fpe */ );
+    int         (*free_fpe) ( /* fpe */ );
+    int         (*open_font) (  /* client, fpe, flags,
+                        name, namelen, format,
+                        fid,  ppfont, alias */ );
+    int         (*close_font) ( /* pfont */ );
+    int         (*list_fonts) ( /* client, fpe, pattern,
+                        patlen, maxnames, paths */ );
+    int         (*start_list_fonts_with_info) (
+                        /* client, fpe, name, namelen,
+                           maxnames, data */ );
+    int         (*list_next_font_with_info) (
+                        /* client, fpe, name, namelen,
+                           info, num, data */ );
+    int         (*wakeup_fpe) ( /* fpe, mask */ );
+    int         (*client_died) ( /* client, fpe */ );
+} FPEFunctionsRec, FPEFunctions;
+      </programlisting> <!-- .fi -->
+
+      <para>
+       The function pointers are split out from the data structure to
+       save memory; additionally, this avoids any complications when
+       initializing the data structure as there would not be any way
+       to discover the appropriate function to call (a chicken and
+       egg problem).
+      </para>
+
+      <para>
+       When a font path type is initialized, it passes the function
+       pointers to the server which are then stored in an
+       <structname>FPEFunctionsRec</structname>. Each function is
+       described below in turn.
+      </para>
+
+      <sect2 id='name_check'>
+       <title>
+         (*name_check)
+       </title>
+
+       <para>
+         Each new font path member is passed to this function; if
+         the return value is <errorname>Successful</errorname>, then
+         the FPE recognises the format of the string.  This does not
+         guarantee that the FPE will be able to successfully use this
+         member.  For example, the disk-based font directory file
+         <filename>fonts.dir</filename> may be corrupted, this will
+         not be detected until the font path is initialized.  This
+         routine never returns <errorname>Suspended</errorname>.
+       </para>
+      </sect2>
+
+      <sect2 id='init_fpe'>
+       <title>
+         (*init_fpe)
+       </title>
+
+       <para>
+         Initialize a new font path element.  This function prepares
+         a new font path element for other requests: the disk font
+         routine reads the <filename>fonts.dir</filename> and
+         <filename>fonts.alias</filename> files into the internal
+         format, while the font server routine connects to the
+         requested font server and prepares for using it.  This
+         routine returns <errorname>Successful</errorname> if
+         everything went OK, otherwise the return value indicates the
+         source of the problem.  This routine never returns
+         <errorname>Suspended</errorname>.
+       </para>
+      </sect2>
+
+      <sect2 id='reset_fpe'>
+       <title>
+         (*reset_fpe)
+       </title>
+
+       <para>
+         When the X font path is reset, and some of the new members
+         are also in the old font path, this function is called to
+         reinitialize those FPEs.  This routine returns
+         <errorname>Successful</errorname> if everything went OK.  It
+         returns <errorname>FPEResetFailed</errorname> if (for some
+         reason) the reset failed, and the caller should remove the
+         old FPE and simply create a new one in its place.  This is
+         used by the disk-based fonts routine as resetting the
+         internal directory structures would be more complicated than
+         simply having destroying the old and creating a new.
+       </para>
+      </sect2>
+
+      <sect2 id='free_fpe'>
+       <title>
+         (*free_fpe)
+       </title>
+
+       <para>
+         When the server is finished with an FPE, this function is
+         called to dispose of any internal state.  It should return
+         <errorname>Successful</errorname>, unless something terrible
+         happens.
+       </para>
+      </sect2>
+
+      <sect2 id='open_font'>
+       <title>
+         (*open_font)
+       </title>
+
+       <para>
+         This routine requests that a font be opened.  The <parameter
+         class='function'>client</parameter> argument is used by the
+         font library only in connection with suspending/restarting
+         the request.  The <parameter class='function'>flags</parameter>
+         argument specifies some behaviour for the library and can be
+         any of:
+       </para>
+
+       <programlisting remap='.nf'>
+/* OpenFont flags */
+#define FontLoadInfo    0x0001
+#define FontLoadProps   0x0002
+#define FontLoadMetrics 0x0004
+#define FontLoadBitmaps 0x0008
+#define FontLoadAll     0x000f
+#define FontOpenSync    0x0010
+       </programlisting> <!-- .fi -->
+
+       <para>
+         The various fields specify which portions of the font should
+         be loaded at this time.  When <constant>FontOpenSync</constant>
+         is specified, this routine will not return until all of the
+         requested portions are loaded.  Otherwise, this routine may
+         return <errorname>Suspended</errorname>.  When the presented
+         font name is actually an alias for some other font name,
+         <errorname>FontNameAlias</errorname> is returned, and the
+         actual font name is stored in the location pointed to by the
+         <parameter class='function'>alias</parameter> argument as a
+         null-terminated string.
+       </para>
+      </sect2>
+
+      <sect2 id='close_font'>
+       <title>
+         (*close_font)
+       </title>
+
+       <para>
+         When the server is finished with a font, this routine
+         disposes of any internal state and frees the font data
+         structure.
+       </para>
+      </sect2>
+
+      <sect2 id='list_fonts'>
+       <title>
+         (*list_fonts)
+       </title>
+
+       <para>
+         The <parameter class='function'>paths</parameter> argument is
+         a data structure which will be filled with all of the font names
+         from this directory which match the specified
+         <parameter class='function'>pattern</parameter>.  At
+         most <parameter class='function'>maxnames</parameter> will be added.
+         This routine may return <errorname>Suspended</errorname>.
+       </para>
+      </sect2>
+
+      <sect2 id='start_list_fonts_with_info'>
+       <title>
+         (*start_list_fonts_with_info)
+       </title>
+
+       <para>
+         This routine sets any internal state for a verbose listing of
+         all fonts matching the specified pattern.  This routine may
+         return <errorname>Suspended</errorname>.
+       </para>
+      </sect2>
+
+      <sect2 id='list_next_font_with_info'>
+       <title>
+         (*list_next_font_with_info)
+       </title>
+
+       <para>
+         To avoid storing huge amounts of data, the interface for
+         ListFontsWithInfo allows the server to get one reply at a time
+         and forward that to the client.  When the font name returned
+         is actually an alias for some other font,
+         <errorname>FontNameAlias</errorname> will be returned.  The
+         actual font name is return instead, and the font alias which
+         matched the pattern is returned in the location pointed to by
+         data as a null-terminated string.  The caller can then get the
+         information by recursively listing that font name with a
+         maxnames of 1.  When <errorname>Successful</errorname> is
+         returned, the matching font name is returned, and a
+         FontInfoPtr is stored in the location pointed to by
+         <parameter class='function'>data</parameter>.
+         <parameter class='function'>Data</parameter> must be initialized
+         with a pointer to a FontInfoRec allocated by the caller.  When the
+         pointer pointed to by <parameter class='function'>data</parameter>
+         is not left pointing at that storage, the caller mustn't free the
+         associated property data. This routine may return
+         <errorname>Suspended</errorname>.
+       </para>
+      </sect2>
+
+      <sect2 id='wakeup_fpe'>
+       <title>
+         (*wakeup_fpe)
+       </title>
+
+       <para>
+         Whenever an FPE function has returned
+         <errorname>Suspended</errorname>, this routine is called
+         whenever the application wakes up from waiting for input
+         (from <citerefentry><refentrytitle>select</refentrytitle>
+           <manvolnum>2</manvolnum></citerefentry>).  This
+           <parameter class='function'>mask</parameter> argument should be
+           the value returned from <function>select(2)</function>.
+       </para>
+      </sect2>
+
+      <sect2 id='client_died'>
+       <title>
+         (*client_died)
+       </title>
+
+       <para>
+         When an FPE function has returned <errorname>Suspended</errorname>
+         and the associated client is being destroyed, this function
+         allows the font library to dispose of any state associated
+         with that client.
+       </para>
+      </sect2>
+    </sect1>
+
+    <sect1 id='fonts'>
+      <title>
+       Fonts
+      </title>
+
+      <para>
+       The data structure which actually contains the font information has
+       changed significantly since previous releases; it now attempts to
+       hide the actual storage format for the data from the application,
+       providing accessor functions to get at the data.  This allows a
+       range of internal details for different font sources.  The structure
+       is split into two pieces, so that ListFontsWithInfo can share
+       information from the font when it has been loaded.  The
+       <structname>FontInfo</structname> structure, then, contains only
+       information germane to LFWI.
+      </para>
+
+      <programlisting remap='.nf'>
+typedef struct _FontInfo {
+    unsigned short firstCol;            /* range of glyphs for this font */
+    unsigned short lastCol;
+    unsigned short firstRow;
+    unsigned short lastRow;
+    unsigned short defaultCh;           /* default character index */
+    unsigned int noOverlap:1;           /* no combination of glyphs overlap */
+    unsigned int terminalFont:1;        /* Character cell font */
+    unsigned int constantMetrics:1;     /* all metrics are the same */
+    unsigned int constantWidth:1;       /* all character widths are the same*/
+    unsigned int inkInside:1;           /* all ink inside character cell */
+    unsigned int inkMetrics:1;          /* font has ink metrics */
+    unsigned int allExist:1;            /* no missing chars in range */
+    unsigned int drawDirection:2;       /* left-to-right/right-to-left*/
+    unsigned int cachable:1;            /* font needn't be opened each time*/
+    unsigned int anamorphic:1;          /* font is strangely scaled */
+    short       maxOverlap;             /* maximum overlap amount */
+    short       pad;                    /* unused */
+    xCharInfo   maxbounds;              /* glyph metrics maximums */
+    xCharInfo   minbounds;              /* glyph metrics minimums */
+    xCharInfo   ink_maxbounds;          /* ink metrics maximums */
+    xCharInfo   ink_minbounds;          /* ink metrics minimums */
+    short       fontAscent;             /* font ascent amount */
+    short       fontDescent;            /* font descent amount */
+    int         nprops;                 /* number of font properties */
+    FontPropPtr props;                  /* font properties */
+    char       *isStringProp;           /* boolean array */
+}           FontInfoRec, *FontInfoPtr;
+      </programlisting> <!-- .fi -->
+
+      <para>
+       The font structure, then, contains a font info record, the format of
+       the bits in each bitmap and the functions which access the font
+       records (which are stored in an opaque format hung off of
+       <structfield>fontPrivate</structfield>).
+      </para>
+
+      <programlisting remap='.nf'>
+typedef struct _Font {
+    int         refcnt;
+    FontInfoRec info;
+    char        bit;                    /* bit order: LSBFirst/MSBFirst */
+    char        byte;                   /* byte order: LSBFirst/MSBFirst */
+    char        glyph;                  /* glyph pad: 1, 2, 4 or 8 */
+    char        scan;                   /* glyph scan unit: 1, 2 or 4 */
+    fsBitmapFormat format;              /* FS-style format (packed) */
+    int         (*get_glyphs)  ( /* font, count, chars, encoding, count, glyphs */ );
+    int         (*get_metrics) ( /* font, count, chars, encoding, count, glyphs */ );
+    int         (*get_bitmaps) ( /* client, font, flags, format,
+                                    flags, nranges, ranges, data_sizep,
+                                    num_glyphsp, offsetsp, glyph_datap,
+                                    free_datap */ );
+    int         (*get_extents) ( /* client, font, flags, nranges,
+                                    ranges, nextentsp, extentsp */);
+    void        (*unload_font) ( /* font */ );
+    FontPathElementPtr fpe;             /* FPE associated with this font */
+    pointer     svrPrivate;             /* X/FS private data */
+    pointer     fontPrivate;            /* private to font */
+    pointer     fpePrivate;             /* private to FPE */
+    int         maxPrivate;             /* devPrivates (see below) */
+    pointer     *devPrivates;           /*  ... */
+}           FontRec, *FontPtr;
+      </programlisting> <!-- .fi -->
+
+      <para>
+       Yes, there are several different private pointers in the
+       <structfield>Font</structfield> structure; they were added
+       haphazardly until the devPrivate pointers were added.  Future
+       releases may remove some (or all) of the specific pointers,
+       leaving only the <structfield>devPrivates</structfield>mechanism.
+      </para>
+
+      <para>
+       There are two similar interfaces implemented -
+       <structfield>get_glyphs</structfield>/<structfield>get_metrics</structfield>
+       and
+       <structfield>get_bitmaps</structfield>/<structfield>get_extents</structfield>.
+       Too little time caused the font-server specific interfaces to
+       be placed in the font library (and portions duplicated in each
+       renderer) instead of having them integrated into the font server
+       itself.  This may change.  The X server uses only
+       <structfield>get_glyphs</structfield>/<structfield>get_metrics</structfield>,
+       and those will not change dramatically.  Each of the routines
+       is described below.
+      </para>
+
+      <sect2 id='get_glyphs'>
+       <title>
+         (*get_glyphs)
+       </title>
+
+       <para>
+         This routine returns <structname>CharInfoPtrs</structname>
+         for each of the requested characters in the font.  If the
+         character does not exist in the font, the default character
+         will be returned, unless no default character exists in
+         which case that character is skipped.  Thus, the number of
+         glyphs returned will not always be the same as the number of
+         characters passed in.
+       </para>
+      </sect2>
+
+      <sect2 id='get_metrics'>
+       <title>
+         (*get_metrics)
+       </title>
+
+       <para>
+         This is similar to <structfield>(*get_glyphs)</structfield>
+         except that pointers to <structname>xCharInfo</structname>
+         structures are returned, and, if the font has ink metrics,
+         those are returned instead of the bitmap metrics.
+       </para>
+      </sect2>
+
+      <sect2 id='getbitmaps'>
+       <title>
+         (*get_bitmaps)
+       </title>
+
+       <para>
+         This packs the glyph image data in the requested
+         <parameter class='function'>format</parameter> and returns it.  The
+         <parameter class='function'>ranges</parameter>/<parameter class='function'>nranges</parameter>
+         argument specify the set of glyphs from the font to pack together.
+       </para>
+      </sect2>
+
+      <sect2 id='get_extents'>
+       <title>
+         (*get_extents)
+       </title>
+
+       <para>
+         This returns the metrics for the specified font from the
+         specified <parameter class='function'>ranges</parameter>.
+       </para>
+
+      </sect2>
+
+      <sect2 id='unload_font'>
+       <title>
+         (*unload_font)
+       </title>
+
+       <para>
+         This is called from the FPE routine
+         <function>(*close_font)</function>, and so should not ever be
+         called from the application.
+       </para>
+      </sect2>
+
+      <sect2 id='maxprivate'>
+       <title>
+         maxPrivate
+       </title>
+
+       <para>
+         When initializing a new font structure,
+         <structfield>maxPrivate</structfield> should be set to -1 so
+         that the <function>FontSetPrivate()</function> macro works
+         properly with an index of 0.  Initializing
+         <structfield>maxPrivate</structfield> to 0 can cause
+         problems if the server tries to set something at index 0.
+       </para>
+      </sect2>
+    </sect1>
+  </article>
diff --git a/doc/fontlib.xsl b/doc/fontlib.xsl
new file mode 100644 (file)
index 0000000..5de4a28
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version="1.0">
+  <!--
+Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+   -->
+
+  <xsl:param name="html.stylesheet" select="'fontlib.css'"/>
+  <xsl:param name="chunker.output.indent">yes</xsl:param>
+  <xsl:param name="html.extra.head.links" select="1"></xsl:param>
+  <xsl:param name="saxon.character.representation" select="'entity;decimal'"></xsl:param>
+  <xsl:param name="function.parens" select="0"></xsl:param>
+</xsl:stylesheet>
diff --git a/include/X11/fonts/bdfint.h b/include/X11/fonts/bdfint.h
new file mode 100755 (executable)
index 0000000..913f660
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+
+Copyright 1990, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+#ifndef BDFINT_H
+#define BDFINT_H
+
+#define bdfIsPrefix(buf,str)   (!strncmp((char *)buf,str,strlen(str)))
+#define        bdfStrEqual(s1,s2)      (!strcmp(s1,s2))
+
+#define        BDF_GENPROPS    6
+#define NullProperty   ((FontPropPtr)0)
+
+/*
+ * This structure holds some properties we need to generate if they aren't
+ * specified in the BDF file and some other values read from the file
+ * that we'll need to calculate them.  We need to keep track of whether
+ * or not we've read them.
+ */
+typedef struct BDFSTAT {
+    int         linenum;
+    char       *fileName;
+    char        fontName[MAXFONTNAMELEN];
+    float       pointSize;
+    int         resolution_x;
+    int         resolution_y;
+    int         digitCount;
+    int         digitWidths;
+    int         exHeight;
+
+    FontPropPtr fontProp;
+    FontPropPtr pointSizeProp;
+    FontPropPtr resolutionXProp;
+    FontPropPtr resolutionYProp;
+    FontPropPtr resolutionProp;
+    FontPropPtr xHeightProp;
+    FontPropPtr weightProp;
+    FontPropPtr quadWidthProp;
+    BOOL        haveFontAscent;
+    BOOL        haveFontDescent;
+    BOOL        haveDefaultCh;
+}           bdfFileState;
+
+extern void bdfError ( char * message, ... );
+extern void bdfWarning ( char *message, ... );
+extern unsigned char * bdfGetLine ( FontFilePtr file, unsigned char *buf, 
+                                   int len );
+extern Atom bdfForceMakeAtom ( char *str, int *size );
+extern Atom bdfGetPropertyValue ( char *s );
+extern int bdfIsInteger ( char *str );
+extern unsigned char bdfHexByte ( unsigned char *s );
+extern Bool bdfSpecialProperty ( FontPtr pFont, FontPropPtr prop, 
+                                char isString, bdfFileState *bdfState );
+extern int bdfReadFont( FontPtr pFont, FontFilePtr file, 
+                       int bit, int byte, int glyph, int scan );
+extern int bdfReadFontInfo( FontInfoPtr pFontInfo, FontFilePtr file );
+
+extern void FontCharInkMetrics ( FontPtr pFont, CharInfoPtr pCI, 
+                                xCharInfo *pInk );
+extern void FontCharReshape ( FontPtr pFont, CharInfoPtr pSrc, 
+                             CharInfoPtr pDst );
+
+#endif                         /* BDFINT_H */
diff --git a/include/X11/fonts/bitmap.h b/include/X11/fonts/bitmap.h
new file mode 100755 (executable)
index 0000000..c023427
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+
+Copyright 1990, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+/*
+ * Author:  Keith Packard, MIT X Consortium
+ */
+
+#ifndef _BITMAP_H_
+#define _BITMAP_H_
+
+#include <X11/fonts/fntfilio.h>
+#include <stdio.h>  /* just for NULL */
+
+/*
+ * Internal format used to store bitmap fonts
+ */
+
+/* number of encoding entries in one segment */
+#define BITMAP_FONT_SEGMENT_SIZE 128
+
+typedef struct _BitmapExtra {
+    Atom       *glyphNames;
+    int        *sWidths;
+    CARD32      bitmapsSizes[GLYPHPADOPTIONS];
+    FontInfoRec info;
+}           BitmapExtraRec, *BitmapExtraPtr;
+
+typedef struct _BitmapFont {
+    unsigned    version_num;
+    int         num_chars;
+    int         num_tables;
+    CharInfoPtr metrics;       /* font metrics, including glyph pointers */
+    xCharInfo  *ink_metrics;   /* ink metrics */
+    char       *bitmaps;       /* base of bitmaps, useful only to free */
+    CharInfoPtr **encoding;    /* array of arrays of char info pointers */
+    CharInfoPtr pDefault;      /* default character */
+    BitmapExtraPtr bitmapExtra;        /* stuff not used by X server */
+}           BitmapFontRec, *BitmapFontPtr;
+
+#define ACCESSENCODING(enc,i) \
+(enc[(i)/BITMAP_FONT_SEGMENT_SIZE]?\
+(enc[(i)/BITMAP_FONT_SEGMENT_SIZE][(i)%BITMAP_FONT_SEGMENT_SIZE]):\
+0)
+#define ACCESSENCODINGL(enc,i) \
+(enc[(i)/BITMAP_FONT_SEGMENT_SIZE][(i)%BITMAP_FONT_SEGMENT_SIZE])
+
+#define SEGMENT_MAJOR(n) ((n)/BITMAP_FONT_SEGMENT_SIZE)
+#define SEGMENT_MINOR(n) ((n)%BITMAP_FONT_SEGMENT_SIZE)
+#define NUM_SEGMENTS(n) \
+  (((n)+BITMAP_FONT_SEGMENT_SIZE-1)/BITMAP_FONT_SEGMENT_SIZE)
+
+extern int bitmapGetGlyphs ( FontPtr pFont, unsigned long count, 
+                            unsigned char *chars, FontEncoding charEncoding, 
+                            unsigned long *glyphCount, CharInfoPtr *glyphs );
+extern int bitmapGetMetrics ( FontPtr pFont, unsigned long count, 
+                             unsigned char *chars, FontEncoding charEncoding,
+                             unsigned long *glyphCount, xCharInfo **glyphs );
+
+extern void bitmapComputeFontBounds ( FontPtr pFont );
+extern void bitmapComputeFontInkBounds ( FontPtr pFont );
+extern Bool bitmapAddInkMetrics ( FontPtr pFont );
+extern int bitmapComputeWeight ( FontPtr pFont );
+
+extern void BitmapRegisterFontFileFunctions ( void );
+
+extern int BitmapOpenScalable ( FontPathElementPtr fpe, FontPtr *pFont, 
+                               int flags, FontEntryPtr entry, char *fileName,
+                               FontScalablePtr vals, fsBitmapFormat format, 
+                               fsBitmapFormatMask fmask, 
+                               FontPtr non_cachable_font );
+extern int BitmapGetInfoScalable ( FontPathElementPtr fpe, 
+                                  FontInfoPtr pFontInfo, FontEntryPtr entry, 
+                                  FontNamePtr fontName, char *fileName, 
+                                  FontScalablePtr vals );
+
+#endif                         /* _BITMAP_H_ */
diff --git a/include/X11/fonts/bufio.h b/include/X11/fonts/bufio.h
new file mode 100755 (executable)
index 0000000..e7a9f4a
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+
+Copyright 1993, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+#ifndef ___BUFIO_H___
+#define ___BUFIO_H___ 1
+
+#include <X11/Xfuncproto.h>
+
+#define BUFFILESIZE    8192
+#define BUFFILEEOF     -1
+
+typedef unsigned char BufChar;
+typedef struct _buffile *BufFilePtr;
+
+typedef struct _buffile {
+    BufChar *bufp;
+    int            left;
+    int     eof;
+    BufChar buffer[BUFFILESIZE];
+    int            (*input)( BufFilePtr /* f */);
+    int     (*output)( int /* c */, BufFilePtr /* f */);
+    int            (*skip)( BufFilePtr /* f */, int /* count */);
+    int            (*close)( BufFilePtr /* f */, int /* doClose */);
+    char    *private;
+} BufFileRec;
+
+extern BufFilePtr BufFileCreate (
+    char*,
+    int (*)(BufFilePtr),
+    int (*)(int, BufFilePtr),
+    int (*)(BufFilePtr, int),
+    int (*)(BufFilePtr, int));
+extern BufFilePtr BufFileOpenRead ( int );
+extern BufFilePtr BufFileOpenWrite ( int );
+extern BufFilePtr BufFilePushCompressed ( BufFilePtr );
+#ifdef X_GZIP_FONT_COMPRESSION
+extern BufFilePtr BufFilePushZIP ( BufFilePtr );
+#endif
+#ifdef X_BZIP2_FONT_COMPRESSION
+extern BufFilePtr BufFilePushBZIP2 ( BufFilePtr );
+#endif
+extern int BufFileClose ( BufFilePtr, int );
+extern int BufFileRead ( BufFilePtr, char*, int );
+extern int BufFileWrite ( BufFilePtr, char*, int );
+
+#define BufFileGet(f)  ((f)->left-- ? *(f)->bufp++ : ((f)->eof = (*(f)->input) (f)))
+#define BufFilePut(c,f)        (--(f)->left ? *(f)->bufp++ = ((unsigned char)(c)) : (*(f)->output) ((unsigned char)(c),f))
+#define BufFileSkip(f,c)    ((f)->eof = (*(f)->skip) (f, c))
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#endif /* ___BUFIO_H___ */
+
diff --git a/include/X11/fonts/fntfil.h b/include/X11/fonts/fntfil.h
new file mode 100755 (executable)
index 0000000..25d1f30
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+
+Copyright 1991, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+/*
+ * Author:  Keith Packard, MIT X Consortium
+ */
+
+#ifndef _FONTFILE_H_
+#define _FONTFILE_H_
+
+#include <X11/fonts/fontxlfd.h>
+
+typedef struct _FontEntry          *FontEntryPtr;
+typedef struct _FontTable          *FontTablePtr;
+typedef struct _FontName           *FontNamePtr;
+typedef struct _FontScaled         *FontScaledPtr;
+typedef struct _FontScalableExtra   *FontScalableExtraPtr;
+typedef struct _FontScalableEntry   *FontScalableEntryPtr;
+typedef struct _FontScaleAliasEntry *FontScaleAliasEntryPtr;
+typedef struct _FontBitmapEntry            *FontBitmapEntryPtr;
+typedef struct _FontAliasEntry     *FontAliasEntryPtr;
+typedef struct _FontBCEntry        *FontBCEntryPtr;
+typedef struct _FontDirectory      *FontDirectoryPtr;
+typedef struct _FontRenderer       *FontRendererPtr;
+
+#define NullFontEntry              ((FontEntryPtr) 0)
+#define NullFontTable              ((FontTablePtr) 0)
+#define NullFontName               ((FontNamePtr) 0)
+#define NullFontScaled             ((FontScaled) 0)
+#define NullFontScalableExtra      ((FontScalableExtra) 0)
+#define NullFontscalableEntry      ((FontScalableEntry) 0)
+#define NullFontScaleAliasEntry            ((FontScaleAliasEntry) 0)
+#define NullFontBitmapEntry        ((FontBitmapEntry) 0)
+#define NullFontAliasEntry         ((FontAliasEntry) 0)
+#define NullFontBCEntry                    ((FontBCEntry) 0)
+#define NullFontDirectory          ((FontDirectoryPtr) 0)
+#define NullFontRenderer           ((FontRendererPtr) 0)
+
+#define FONT_ENTRY_SCALABLE    0
+#define FONT_ENTRY_SCALE_ALIAS 1
+#define FONT_ENTRY_BITMAP      2
+#define FONT_ENTRY_ALIAS       3
+#define FONT_ENTRY_BC          4
+
+#define MAXFONTNAMELEN     1024
+#define MAXFONTFILENAMELEN  1024
+
+#define FontDirFile        "fonts.dir"
+#define FontAliasFile      "fonts.alias"
+#define FontScalableFile    "fonts.scale"
+
+extern int FontFileNameCheck ( char *name );
+extern int FontFileInitFPE ( FontPathElementPtr fpe );
+extern int FontFileResetFPE ( FontPathElementPtr fpe );
+extern int FontFileFreeFPE ( FontPathElementPtr fpe );
+extern int FontFileOpenFont ( pointer client, FontPathElementPtr fpe, 
+                             Mask flags, char *name, int namelen, 
+                             fsBitmapFormat format, fsBitmapFormatMask fmask, 
+                             XID id, FontPtr *pFont, char **aliasName, 
+                             FontPtr non_cachable_font );
+extern void FontFileCloseFont ( FontPathElementPtr fpe, FontPtr pFont );
+extern int FontFileOpenBitmap ( FontPathElementPtr fpe, FontPtr *pFont, 
+                               int flags, FontEntryPtr entry, 
+                               fsBitmapFormat format, 
+                               fsBitmapFormatMask fmask );
+extern int FontFileListFonts ( pointer client, FontPathElementPtr fpe, 
+                              char *pat, int len, int max, 
+                              FontNamesPtr names );
+extern int FontFileStartListFonts ( pointer client, FontPathElementPtr fpe, 
+                                   char *pat, int len, int max, 
+                                   pointer *privatep, int mark_aliases );
+extern int FontFileStartListFontsWithInfo ( pointer client, 
+                                           FontPathElementPtr fpe, 
+                                           char *pat, int len, int max, 
+                                           pointer *privatep );
+extern int FontFileListNextFontWithInfo ( pointer client, 
+                                         FontPathElementPtr fpe, 
+                                         char **namep, int *namelenp, 
+                                         FontInfoPtr *pFontInfo, 
+                                         int *numFonts, pointer private );
+extern int FontFileStartListFontsAndAliases ( pointer client, 
+                                             FontPathElementPtr fpe, 
+                                             char *pat, int len, int max, 
+                                             pointer *privatep );
+extern int FontFileListNextFontOrAlias ( pointer client, 
+                                        FontPathElementPtr fpe, 
+                                        char **namep, int *namelenp, 
+                                        char **resolvedp, int *resolvedlenp, 
+                                        pointer private );
+extern void FontFileRegisterLocalFpeFunctions ( void );
+extern void CatalogueRegisterLocalFpeFunctions ( void );
+
+
+extern FontEntryPtr FontFileAddEntry ( FontTablePtr table, 
+                                      FontEntryPtr prototype );
+extern Bool FontFileAddFontAlias ( FontDirectoryPtr dir, char *aliasName, 
+                                  char *fontName );
+extern Bool FontFileAddFontFile ( FontDirectoryPtr dir, char *fontName, 
+                                 char *fileName );
+extern int FontFileCountDashes ( char *name, int namelen );
+extern FontEntryPtr FontFileFindNameInDir ( FontTablePtr table, 
+                                           FontNamePtr pat );
+extern FontEntryPtr FontFileFindNameInScalableDir ( FontTablePtr table,
+                                                   FontNamePtr pat, 
+                                                   FontScalablePtr vals );
+extern int FontFileFindNamesInDir ( FontTablePtr table, FontNamePtr pat, 
+                                   int max, FontNamesPtr names );
+extern int FontFileFindNamesInScalableDir ( FontTablePtr table, 
+                                           FontNamePtr pat, int max, 
+                                           FontNamesPtr names, 
+                                           FontScalablePtr vals, 
+                                           int alias_behavior, int *newmax );
+
+extern void FontFileFreeDir ( FontDirectoryPtr dir );
+extern void FontFileFreeEntry ( FontEntryPtr entry );
+extern void FontFileFreeTable ( FontTablePtr table );
+extern Bool FontFileInitTable ( FontTablePtr table, int size );
+extern FontDirectoryPtr FontFileMakeDir ( char *dirName, int size );
+extern Bool FontFileMatchName ( char *name, int length, FontNamePtr pat );
+extern char * FontFileSaveString ( char *s );
+extern void FontFileSortDir ( FontDirectoryPtr dir );
+extern void FontFileSortTable ( FontTablePtr table );
+
+extern void FontDefaultFormat ( int *bit, int *byte, int *glyph, int *scan );
+
+extern Bool FontFileRegisterRenderer ( FontRendererPtr renderer );
+extern Bool FontFilePriorityRegisterRenderer ( FontRendererPtr renderer,
+                                               int priority );
+extern FontRendererPtr FontFileMatchRenderer ( char *fileName );
+
+extern Bool FontFileAddScaledInstance ( FontEntryPtr entry, 
+                                       FontScalablePtr vals, FontPtr pFont, 
+                                       char *bitmapName );
+extern void FontFileSwitchStringsToBitmapPointers ( FontDirectoryPtr dir );
+extern void FontFileRemoveScaledInstance ( FontEntryPtr entry, FontPtr pFont );
+extern Bool FontFileCompleteXLFD ( FontScalablePtr vals, FontScalablePtr def );
+extern FontScaledPtr FontFileFindScaledInstance ( FontEntryPtr entry, 
+                                                 FontScalablePtr vals, 
+                                                 int noSpecificSize );
+
+extern Bool FontFileRegisterBitmapSource ( FontPathElementPtr fpe );
+extern void FontFileUnregisterBitmapSource ( FontPathElementPtr fpe );
+extern void FontFileEmptyBitmapSource ( void );
+extern int FontFileMatchBitmapSource ( FontPathElementPtr fpe, 
+                                      FontPtr *pFont, int flags, 
+                                      FontEntryPtr entry, 
+                                      FontNamePtr zeroPat, 
+                                      FontScalablePtr vals, 
+                                      fsBitmapFormat format, 
+                                      fsBitmapFormatMask fmask, 
+                                      Bool noSpecificSize );
+
+extern int FontFileReadDirectory ( char *directory, FontDirectoryPtr *pdir );
+extern Bool FontFileDirectoryChanged ( FontDirectoryPtr dir );
+
+#endif /* _FONTFILE_H_ */
diff --git a/include/X11/fonts/fntfilio.h b/include/X11/fonts/fntfilio.h
new file mode 100755 (executable)
index 0000000..3a8f4ca
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+
+Copyright 1991, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+/*
+ * Author:  Keith Packard, MIT X Consortium
+ */
+
+#ifndef _FNTFILIO_H_
+#define _FNTFILIO_H_
+
+#include <X11/fonts/bufio.h>
+
+typedef BufFilePtr  FontFilePtr;
+
+#define FontFileGetc(f)            BufFileGet(f)
+#define FontFilePutc(c,f)   BufFilePut(c,f)
+#define FontFileRead(f,b,n) BufFileRead(f,b,n)
+#define FontFileWrite(f,b,n)   BufFileWrite(f,b,n)
+#define FontFileSkip(f,n)   (BufFileSkip (f, n) != BUFFILEEOF)
+#define FontFileSeek(f,n)   (BufFileSeek (f,n,0) != BUFFILEEOF)
+
+#define FontFileEOF    BUFFILEEOF
+
+extern FontFilePtr FontFileOpen ( const char *name );
+extern int FontFileClose ( FontFilePtr f );
+extern FontFilePtr FontFileOpenWrite ( const char *name );
+extern FontFilePtr FontFileOpenWriteFd ( int fd );
+extern FontFilePtr FontFileOpenFd ( int fd );
+
+#endif /* _FNTFILIO_H_ */
diff --git a/include/X11/fonts/fntfilst.h b/include/X11/fonts/fntfilst.h
new file mode 100755 (executable)
index 0000000..29e0a56
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+
+Copyright 1991, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+/*
+ * Author:  Keith Packard, MIT X Consortium
+ */
+
+#ifndef _FONTFILEST_H_
+#define _FONTFILEST_H_
+
+#include <X11/Xos.h>
+#ifndef XP_PSTEXT
+#include <X11/fonts/fontmisc.h>
+#endif
+#include <X11/fonts/fontstruct.h>
+#include <X11/fonts/fontxlfd.h>
+#include <X11/fonts/fntfil.h>
+
+typedef struct _FontName {
+    char       *name;
+    short      length;
+    short      ndashes;
+} FontNameRec;
+
+typedef struct _FontScaled {
+    FontScalableRec    vals;
+    FontEntryPtr       bitmap;
+    FontPtr            pFont;
+} FontScaledRec;
+
+typedef struct _FontScalableExtra {
+    FontScalableRec    defaults;
+    int                        numScaled;
+    int                        sizeScaled;
+    FontScaledPtr      scaled;
+    pointer            private;
+} FontScalableExtraRec;
+
+typedef struct _FontScalableEntry {
+    FontRendererPtr        renderer;
+    char                   *fileName;
+    FontScalableExtraPtr   extra;
+} FontScalableEntryRec;
+
+/*
+ * This "can't" work yet - the returned alias string must be permanent,
+ * but this layer would need to generate the appropriate name from the
+ * resolved scalable + the XLFD values passed in.  XXX
+ */
+
+typedef struct _FontScaleAliasEntry {
+    char               *resolved;
+} FontScaleAliasEntryRec;
+
+typedef struct _FontBitmapEntry {
+    FontRendererPtr    renderer;
+    char               *fileName;
+    FontPtr            pFont;
+} FontBitmapEntryRec;
+
+typedef struct _FontAliasEntry {
+    char       *resolved;
+} FontAliasEntryRec;
+
+typedef struct _FontBCEntry {
+    FontScalableRec        vals;
+    FontEntryPtr           entry;
+} FontBCEntryRec;
+
+typedef struct _FontEntry {
+    FontNameRec        name;
+    int                type;
+    union _FontEntryParts {
+       FontScalableEntryRec    scalable;
+       FontBitmapEntryRec      bitmap;
+       FontAliasEntryRec       alias;
+       FontBCEntryRec          bc;
+    } u;
+} FontEntryRec;
+
+typedef struct _FontTable {
+    int                    used;
+    int                    size;
+    FontEntryPtr    entries;
+    Bool           sorted;
+} FontTableRec;
+
+typedef struct _FontDirectory {
+    char           *directory;
+    unsigned long   dir_mtime;
+    unsigned long   alias_mtime;
+    FontTableRec    scalable;
+    FontTableRec    nonScalable;
+    char           *attributes;
+} FontDirectoryRec;
+
+/* Capability bits: for definition of capabilities bitmap in the
+   FontRendererRec to indicate support of XLFD enhancements */
+
+#define CAP_MATRIX             0x1
+#define CAP_CHARSUBSETTING     0x2
+
+typedef struct _FontRenderer {
+    char    *fileSuffix;
+    int            fileSuffixLen;
+    int            (*OpenBitmap)(FontPathElementPtr /* fpe */, 
+                         FontPtr * /* pFont */,
+                         int /* flags */, 
+                         FontEntryPtr /* entry */, 
+                         char * /* fileName */, 
+                         fsBitmapFormat /* format */, 
+                         fsBitmapFormatMask /* mask */,
+                         FontPtr /* non_cachable_font */);
+    int            (*OpenScalable)(FontPathElementPtr /* fpe */, 
+                           FontPtr * /* pFont */, 
+                           int /* flags */, 
+                           FontEntryPtr /* entry */, 
+                           char * /* fileName */, 
+                           FontScalablePtr /* vals */, 
+                           fsBitmapFormat /* format */, 
+                           fsBitmapFormatMask /* fmask */,
+                           FontPtr /* non_cachable_font */);
+    int            (*GetInfoBitmap)(FontPathElementPtr /* fpe */, 
+                            FontInfoPtr /* pFontInfo */, 
+                            FontEntryPtr /* entry */, 
+                            char * /*fileName */);
+    int            (*GetInfoScalable)(FontPathElementPtr /* fpe */, 
+                              FontInfoPtr /* pFontInfo */, 
+                              FontEntryPtr /* entry */, 
+                              FontNamePtr /* fontName */,
+                              char * /* fileName */, 
+                              FontScalablePtr /* vals */);
+    int            number;
+    int     capabilities;      /* Bitmap components defined above */
+} FontRendererRec;
+
+typedef struct _FontRenders {
+    int                    number;
+    struct _FontRenderersElement {
+        /* In order to preserve backward compatibility, the
+           priority field is made invisible to renderers */
+        FontRendererPtr renderer;
+        int priority;
+    } *renderers;
+} FontRenderersRec, *FontRenderersPtr;
+
+typedef struct _BitmapInstance {
+    FontScalableRec    vals;
+    FontBitmapEntryPtr bitmap;
+} BitmapInstanceRec, *BitmapInstancePtr;
+
+typedef struct _BitmapScalablePrivate {
+    int                        numInstances;
+    BitmapInstancePtr  instances;
+} BitmapScalablePrivateRec, *BitmapScalablePrivatePtr;
+
+typedef struct _BitmapSources {
+    FontPathElementPtr *fpe;
+    int                        size;
+    int                        count;
+} BitmapSourcesRec, *BitmapSourcesPtr;
+
+extern BitmapSourcesRec        FontFileBitmapSources;
+
+/* Defines for FontFileFindNamesInScalableDir() behavior */
+#define NORMAL_ALIAS_BEHAVIOR          0
+#define LIST_ALIASES_AND_TARGET_NAMES   (1<<0)
+#define IGNORE_SCALABLE_ALIASES                (1<<1)
+
+#endif /* _FONTFILEST_H_ */
diff --git a/include/X11/fonts/fontconf.h.in b/include/X11/fonts/fontconf.h.in
new file mode 100755 (executable)
index 0000000..67783d3
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright Â© 2005 Keith Packard
+ *
+ * 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.
+ */
+
+/* Define as 1 if you have FreeType support in Xfont */
+#undef XFONT_FREETYPE
+
+/* Define as 1 if you have builtin font support in Xfont */
+#undef XFONT_BUILTINS
+
+/* Define as 1 if you have pcf font support in Xfont */
+#undef XFONT_PCFFORMAT
+
+/* Define as 1 if you have bdf font support in Xfont */
+#undef XFONT_BDFFORMAT
+
+/* Define as 1 if you have snf font support in Xfont */
+#undef XFONT_SNFFORMAT
+
+/* Define as 1 if you have bitmap font support in Xfont */
+#undef XFONT_BITMAP
+
+/* Define as 1 if you have fontfile support in Xfont */
+#undef XFONT_FONTFILE
+
+/* Define as 1 if you have font cache support in Xfont */
+#undef XFONT_FONTCACHE
+
+/* Define as 1 if you have X Font Services Protocol support in Xfont */
+#undef XFONT_FC
+
diff --git a/include/X11/fonts/fontencc.h b/include/X11/fonts/fontencc.h
new file mode 100755 (executable)
index 0000000..987cbfb
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+Copyright (c) 1998-2001 by Juliusz Chroboczek
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+/* Binary compatibility entry points. */
+
+/* This file includes code to make modules compiled for earlier
+   versions of the fontenc interfaces link with this one.  It does
+   *not* provide source compatibility, as many of the data structures
+   now have different names. */
+
+extern char *font_encoding_from_xlfd(const char*, int);
+extern unsigned font_encoding_recode(unsigned, FontEncPtr, FontMapPtr);
+extern FontEncPtr font_encoding_find(const char*, const char*);
+extern char *font_encoding_name(unsigned, FontEncPtr, FontMapPtr);
+extern char **identifyEncodingFile(const char *fileName);
+
diff --git a/include/X11/fonts/fontmisc.h b/include/X11/fonts/fontmisc.h
new file mode 100755 (executable)
index 0000000..cd9d52a
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+
+Copyright 1991, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+/*
+ * Author:  Keith Packard, MIT X Consortium
+ */
+
+#ifndef _FONTMISC_H_
+#define _FONTMISC_H_
+
+#include <X11/Xfuncs.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <X11/Xdefs.h>
+
+
+#ifndef LSBFirst
+#define LSBFirst       0
+#define MSBFirst       1
+#endif
+
+#ifndef None
+#define None   0l
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif
+
+extern Atom MakeAtom ( char *string, unsigned len, int makeit );
+extern int ValidAtom ( Atom atom );
+extern char *NameForAtom (Atom atom);
+
+#define lowbit(x) ((x) & (~(x) + 1))
+
+#undef assert
+#define assert(x)      ((void)0)
+
+extern void
+BitOrderInvert(
+    register unsigned char *,
+    register int
+);
+
+extern void
+TwoByteSwap(
+    register unsigned char *,
+    register int
+);
+
+extern void
+FourByteSwap(
+    register unsigned char *,
+    register int
+);
+
+extern int
+RepadBitmap (
+    char*, 
+    char*,
+    unsigned, 
+    unsigned,
+    int, 
+    int
+);
+
+extern void CopyISOLatin1Lowered(
+    char * /*dest*/,
+    char * /*source*/,
+    int /*length*/
+);
+
+extern void register_fpe_functions(void);
+
+#endif /* _FONTMISC_H_ */
diff --git a/include/X11/fonts/fontshow.h b/include/X11/fonts/fontshow.h
new file mode 100755 (executable)
index 0000000..126cab6
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+
+Copyright 1990, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+/*
+ * Author:  Keith Packard, MIT X Consortium
+ */
+
+#define FONT_SHOW_INFO     (1<<0)
+#define FONT_SHOW_PROPS            (1<<1)
+#define FONT_SHOW_METRICS   (1<<2)
+#define FONT_SHOW_GLYPHS    (1<<3)
+#define FONT_SHOW_ALL      (FONT_SHOW_INFO|FONT_SHOW_PROPS|FONT_SHOW_GLYPHS)
diff --git a/include/X11/fonts/fontutil.h b/include/X11/fonts/fontutil.h
new file mode 100755 (executable)
index 0000000..71d507b
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef _FONTUTIL_H_
+#define _FONTUTIL_H_
+
+#include <X11/fonts/FSproto.h>
+
+extern int FontCouldBeTerminal(FontInfoPtr);
+extern int CheckFSFormat(fsBitmapFormat, fsBitmapFormatMask, int *, int *,
+                        int *, int *, int *);
+extern void FontComputeInfoAccelerators(FontInfoPtr);
+
+extern void GetGlyphs ( FontPtr font, unsigned long count, 
+                       unsigned char *chars, FontEncoding fontEncoding, 
+                       unsigned long *glyphcount, CharInfoPtr *glyphs );
+extern void QueryGlyphExtents ( FontPtr pFont, CharInfoPtr *charinfo, 
+                               unsigned long count, ExtentInfoRec *info );
+extern Bool QueryTextExtents ( FontPtr pFont, unsigned long count, 
+                              unsigned char *chars, ExtentInfoRec *info );
+extern Bool ParseGlyphCachingMode ( char *str );
+extern void InitGlyphCaching ( void );
+extern void SetGlyphCachingMode ( int newmode );
+extern int add_range ( fsRange *newrange, int *nranges, fsRange **range, 
+                      Bool charset_subset );
+
+#endif /* _FONTUTIL_H_ */
diff --git a/include/X11/fonts/fontxlfd.h b/include/X11/fonts/fontxlfd.h
new file mode 100755 (executable)
index 0000000..3555706
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+
+Copyright 1990, 1994, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+/*
+ * Author:  Keith Packard, MIT X Consortium
+ */
+
+#ifndef _FONTXLFD_H_
+#define _FONTXLFD_H_
+
+#include <X11/fonts/FSproto.h>
+
+/* Constants for values_supplied bitmap */
+
+#define SIZE_SPECIFY_MASK              0xf
+
+#define PIXELSIZE_MASK                 0x3
+#define PIXELSIZE_UNDEFINED            0
+#define PIXELSIZE_SCALAR               0x1
+#define PIXELSIZE_ARRAY                        0x2
+#define PIXELSIZE_SCALAR_NORMALIZED    0x3     /* Adjusted for resolution */
+
+#define POINTSIZE_MASK                 0xc
+#define POINTSIZE_UNDEFINED            0
+#define POINTSIZE_SCALAR               0x4
+#define POINTSIZE_ARRAY                        0x8
+
+#define PIXELSIZE_WILDCARD             0x10
+#define POINTSIZE_WILDCARD             0x20
+
+#define ENHANCEMENT_SPECIFY_MASK       0x40
+
+#define CHARSUBSET_SPECIFIED           0x40
+
+#define EPS            1.0e-20
+#define XLFD_NDIGITS   3               /* Round numbers in pixel and
+                                          point arrays to this many
+                                          digits for repeatability */
+
+typedef struct _FontScalable {
+    int                values_supplied;        /* Bitmap identifying what advanced
+                                          capabilities or enhancements
+                                          were specified in the font name */
+    double     pixel_matrix[4];
+    double     point_matrix[4];
+
+    /* Pixel and point fields are deprecated in favor of the
+       transformation matrices.  They are provided and filled in for the
+       benefit of rasterizers that do not handle the matrices.  */
+
+    int                pixel,
+               point;
+
+    int         x,
+                y,
+                width;
+    char       *xlfdName;
+    int                nranges;
+    fsRange    *ranges;
+}           FontScalableRec, *FontScalablePtr;
+
+
+extern double xlfd_round_double ( double x );
+extern Bool FontParseXLFDName ( char *fname, FontScalablePtr vals, int subst );
+extern fsRange *FontParseRanges ( char *name, int *nranges );
+
+#define FONT_XLFD_REPLACE_NONE 0
+#define FONT_XLFD_REPLACE_STAR 1
+#define FONT_XLFD_REPLACE_ZERO 2
+#define FONT_XLFD_REPLACE_VALUE        3
+
+#endif                         /* _FONTXLFD_H_ */
diff --git a/include/X11/fonts/pcf.h b/include/X11/fonts/pcf.h
new file mode 100755 (executable)
index 0000000..a5fdbcd
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+
+Copyright 1991, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+/*
+ * Author:  Keith Packard, MIT X Consortium
+ */
+
+#ifndef _PCF_H_
+#define _PCF_H_
+
+#include <X11/fonts/fntfilio.h>
+
+/*
+ * Information used to read/write PCF fonts
+ */
+
+typedef struct _PCFTable {
+    CARD32      type;
+    CARD32      format;
+    CARD32      size;
+    CARD32      offset;
+}           PCFTableRec, *PCFTablePtr;
+
+#define PCF_FILE_VERSION       (('p'<<24)|('c'<<16)|('f'<<8)|1)
+#define        PCF_FORMAT_MASK         0xffffff00
+
+#define PCF_DEFAULT_FORMAT     0x00000000
+#define PCF_INKBOUNDS          0x00000200
+#define PCF_ACCEL_W_INKBOUNDS  0x00000100
+#define PCF_COMPRESSED_METRICS 0x00000100
+
+#define PCF_FORMAT_MATCH(a,b) (((a)&PCF_FORMAT_MASK) == ((b)&PCF_FORMAT_MASK))
+
+#define PCF_GLYPH_PAD_MASK     (3<<0)
+#define PCF_BYTE_MASK          (1<<2)
+#define PCF_BIT_MASK           (1<<3)
+#define PCF_SCAN_UNIT_MASK     (3<<4)
+
+#define PCF_BYTE_ORDER(f)      (((f) & PCF_BYTE_MASK)?MSBFirst:LSBFirst)
+#define PCF_BIT_ORDER(f)       (((f) & PCF_BIT_MASK)?MSBFirst:LSBFirst)
+#define PCF_GLYPH_PAD_INDEX(f) ((f) & PCF_GLYPH_PAD_MASK)
+#define PCF_GLYPH_PAD(f)       (1<<PCF_GLYPH_PAD_INDEX(f))
+#define PCF_SCAN_UNIT_INDEX(f) (((f) & PCF_SCAN_UNIT_MASK) >> 4)
+#define PCF_SCAN_UNIT(f)       (1<<PCF_SCAN_UNIT_INDEX(f))
+#define PCF_FORMAT_BITS(f)     ((f) & (PCF_GLYPH_PAD_MASK|PCF_BYTE_MASK|PCF_BIT_MASK|PCF_SCAN_UNIT_MASK))
+
+#define PCF_SIZE_TO_INDEX(s)   ((s) == 4 ? 2 : (s) == 2 ? 1 : 0)
+#define PCF_INDEX_TO_SIZE(b)   (1<<b)
+
+#define PCF_FORMAT(bit,byte,glyph,scan) (\
+    (PCF_SIZE_TO_INDEX(scan) << 4) | \
+    (((bit) == MSBFirst ? 1 : 0) << 3) | \
+    (((byte) == MSBFirst ? 1 : 0) << 2) | \
+    (PCF_SIZE_TO_INDEX(glyph) << 0))
+
+#define PCF_PROPERTIES             (1<<0)
+#define PCF_ACCELERATORS           (1<<1)
+#define PCF_METRICS                (1<<2)
+#define PCF_BITMAPS                (1<<3)
+#define PCF_INK_METRICS                    (1<<4)
+#define        PCF_BDF_ENCODINGS           (1<<5)
+#define PCF_SWIDTHS                (1<<6)
+#define PCF_GLYPH_NAMES                    (1<<7)
+#define PCF_BDF_ACCELERATORS       (1<<8)
+
+extern int pcfReadFont ( FontPtr pFont, FontFilePtr file, 
+                        int bit, int byte, int glyph, int scan );
+extern int pcfReadFontInfo ( FontInfoPtr pFontInfo, FontFilePtr file );
+extern int pcfWriteFont ( FontPtr pFont, FontFilePtr file );
+extern void pcfError ( const char *, ... );
+
+#endif                         /* _PCF_H_ */
diff --git a/packaging/libXfont.spec b/packaging/libXfont.spec
new file mode 100644 (file)
index 0000000..720cffb
--- /dev/null
@@ -0,0 +1,93 @@
+
+Name:       libXfont
+Summary:    X.Org X11 libXfont runtime library
+Version:    1.4.3
+Release:    1
+Group:      System/Libraries
+License:    MIT
+URL:        http://www.x.org
+Source0:    http://xorg.freedesktop.org/releases/individual/lib/%{name}-%{version}.tar.gz
+Requires(post): /sbin/ldconfig
+Requires(postun): /sbin/ldconfig
+BuildRequires:  pkgconfig(xorg-macros)
+BuildRequires:  pkgconfig(xproto)
+BuildRequires:  pkgconfig(xtrans)
+BuildRequires:  pkgconfig(fontsproto)
+BuildRequires:  pkgconfig(fontenc)
+BuildRequires:  pkgconfig(freetype2)
+BuildRequires:  pkgconfig(fontcacheproto)
+
+
+%description
+libXfont provides the core of the legacy X11 font system, handling the
+index files (fonts.dir, fonts.alias, fonts.scale), the various font file
+formats, and rasterizing them
+
+
+
+%package devel
+Summary:    X.Org X11 libXfont development package
+Group:      Development/Libraries
+Requires:   %{name} = %{version}-%{release}
+Requires:   xorg-x11-filesystem
+
+%description devel
+the legacy X11 font system development files
+
+
+%prep
+%setup -q -n %{name}-%{version}
+
+
+%build
+
+%reconfigure --disable-static \
+    --enable-fc --enable-builtins --enable-pcfformat --enable-bdfformat --without-bzip2
+
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+%make_install
+
+
+
+
+%post -p /sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+
+
+
+
+%files
+%defattr(-,root,root,-)
+# FIXME:  Missing README/INSTALL - should file bug upstream.
+#%doc AUTHORS COPYING README INSTALL ChangeLog NEWS
+%doc AUTHORS COPYING ChangeLog
+%{_libdir}/libXfont.so.1
+%{_libdir}/libXfont.so.1.4.1
+
+
+%files devel
+%defattr(-,root,root,-)
+%dir %{_includedir}/X11/fonts
+%{_includedir}/X11/fonts/bdfint.h
+%{_includedir}/X11/fonts/bitmap.h
+%{_includedir}/X11/fonts/bufio.h
+%{_includedir}/X11/fonts/fntfil.h
+%{_includedir}/X11/fonts/fntfilio.h
+%{_includedir}/X11/fonts/fntfilst.h
+%{_includedir}/X11/fonts/fontconf.h
+%{_includedir}/X11/fonts/fontencc.h
+%{_includedir}/X11/fonts/fontmisc.h
+%{_includedir}/X11/fonts/fontshow.h
+%{_includedir}/X11/fonts/fontutil.h
+%{_includedir}/X11/fonts/fontxlfd.h
+%{_includedir}/X11/fonts/pcf.h
+%{_includedir}/X11/fonts/ft.h
+%{_includedir}/X11/fonts/ftfuncs.h
+%{_libdir}/libXfont.so
+%{_libdir}/pkgconfig/xfont.pc
+
diff --git a/src/FreeType/Makefile.am b/src/FreeType/Makefile.am
new file mode 100644 (file)
index 0000000..fa45da1
--- /dev/null
@@ -0,0 +1,15 @@
+INCLUDES =                                \
+       -I${top_srcdir}/include
+
+noinst_LTLIBRARIES = libft.la
+
+AM_CFLAGS = $(FREETYPE_CFLAGS) $(XFONT_CFLAGS) $(OS_CFLAGS) $(CWARNFLAGS)
+
+libft_la_SOURCES =             \
+       ft.h                    \
+       ftfuncs.h               \
+       xttcap.h                \
+       ftenc.c                 \
+       ftfuncs.c               \
+       fttools.c               \
+       xttcap.c
diff --git a/src/FreeType/ft.h b/src/FreeType/ft.h
new file mode 100755 (executable)
index 0000000..8cf31d4
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+Copyright (c) 1997 by Mark Leisher
+Copyright (c) 1998-2002 by Juliusz Chroboczek
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifndef _FT_H_
+#define _FT_H_
+
+#include <X11/Xfuncproto.h>
+
+#define FREETYPE_VERSION (FREETYPE_MAJOR * 1000000 + FREETYPE_MINOR * 1000 + FREETYPE_PATCH)
+
+#undef DEBUG_TRUETYPE
+
+#ifdef DEBUG_TRUETYPE
+#define MUMBLE ErrorF
+#else
+#define MUMBLE(...)
+#endif
+
+#undef MAX
+#define MAX(h,i) ((h) > (i) ? (h) : (i))
+#define ADJUSTMAX(m,v) if((v)>(m)) (m)=(v)
+#undef MIN
+#define MIN(l,o) ((l) < (o) ? (l) : (o))
+#define ADJUSTMIN(m,v) if ((v)<(m)) (m)=(v)
+
+/* When comparing floating point values, we want to ignore small errors. */
+#define NEGLIGIBLE ((double)0.001)
+/* Are x and y significantly different? */
+#define DIFFER(x,y) (fabs((x)-(y))>=NEGLIGIBLE*fabs(x))
+/* Is x significantly different from 0 w.r.t. y? */
+#define DIFFER0(x,y) (fabs(x)>=NEGLIGIBLE*fabs(y))
+
+#ifndef ABS
+#define ABS(x) ((x) >= 0 ? (x) : -(x))
+#endif
+
+/* Two to the sixteenth power, as a double. */
+#define TWO_SIXTEENTH ((double)(1<<16))
+#define TWO_SIXTH ((double)(1<<6))
+
+/* Data structures used across files */
+
+typedef struct _FTMapping
+{
+    int named;
+    FT_CharMap cmap;
+    int base;
+    struct _FontMap *mapping;     /* allow inclusion without fontenc.h */
+} FTMappingRec, *FTMappingPtr;
+
+/* Prototypes */
+
+/* ftfuncs.c */
+
+/* ftenc.c */
+
+int FTPickMapping(char*, int, char*, FT_Face, FTMappingPtr);
+unsigned FTRemap(FT_Face face, FTMappingPtr, unsigned code);
+
+/* fttools.c */
+
+int FTtoXReturnCode(int);
+int FTGetEnglishName(FT_Face, int, char *, int);
+
+extern void ErrorF(const char*, ...);
+
+#endif /* _FT_H_ */
diff --git a/src/FreeType/ftenc.c b/src/FreeType/ftenc.c
new file mode 100755 (executable)
index 0000000..99defbe
--- /dev/null
@@ -0,0 +1,239 @@
+/* 
+Copyright (c) 1998-2003 by Juliusz Chroboczek
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions: 
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software. 
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <string.h>
+
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/fontutil.h>
+#include <X11/fonts/FSproto.h>
+
+#include <X11/fonts/fontmisc.h>
+#include <X11/fonts/fontenc.h>
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_TRUETYPE_IDS_H
+#include FT_TRUETYPE_TABLES_H
+#include FT_TYPE1_TABLES_H
+#include FT_BDF_H
+#include FT_XFREE86_H
+#include "ft.h"
+
+static int find_cmap(int, int, int, FT_Face, FT_CharMap *);
+
+static int
+FTEncFontSpecific(char *encoding)
+{
+    char *p = encoding;
+
+    if(strcasecmp(encoding, "microsoft-symbol") == 0)
+        return 1;
+       
+    while(*p != '-') {
+        if(*p == '\0')
+            return 0;
+        p++;
+    }
+    p++;
+    return (strcasecmp(p, "fontspecific") == 0);
+}
+
+int
+FTPickMapping(char *xlfd, int length, char *filename, FT_Face face,
+              FTMappingPtr tm)
+{
+    FontEncPtr encoding;
+    FontMapPtr mapping;
+    FT_CharMap cmap;
+    int ftrc;
+    int symbol = 0;
+    const char *enc, *reg;
+    char *encoding_name = 0;
+    char buf[20];
+
+    if(xlfd)
+      encoding_name = FontEncFromXLFD(xlfd, length);
+    if(!encoding_name)
+        encoding_name = "iso8859-1";
+
+    symbol = FTEncFontSpecific(encoding_name);
+
+#if XFONT_BDFFORMAT
+    ftrc = FT_Get_BDF_Charset_ID(face, &enc, &reg);
+#else
+    ftrc = -1;
+#endif
+    if(ftrc == 0) {
+        /* Disable reencoding for non-Unicode fonts.  This will
+           currently only work for BDFs. */
+        if(strlen(enc) + strlen(reg) > 18)
+            goto native;
+        strcpy(buf, enc);
+        strcat(buf, "-");
+        strcat(buf, reg);
+        ErrorF("%s %s\n", buf, encoding_name);
+        if(strcasecmp(buf, "iso10646-1") != 0) {
+            if(strcasecmp(buf, encoding_name) == 0)
+                goto native;
+            return BadFontFormat;
+        }
+    } else if(symbol) {
+        ftrc = FT_Select_Charmap(face, ft_encoding_adobe_custom);
+        if(ftrc == 0)
+            goto native;
+    }
+
+    encoding = FontEncFind(encoding_name, filename);
+    if(symbol && encoding == NULL)
+        encoding = FontEncFind("microsoft-symbol", filename);
+    if(encoding == NULL) {
+        ErrorF("FreeType: couldn't find encoding '%s' for '%s'\n",
+               encoding_name, filename);
+        return BadFontName;
+    }
+
+    if(FT_Has_PS_Glyph_Names(face)) {
+        for(mapping = encoding->mappings; mapping; mapping = mapping->next) {
+            if(mapping->type == FONT_ENCODING_POSTSCRIPT) {
+                tm->named = 1;
+                tm->base = 0;
+                tm->mapping = mapping;
+                return Successful;
+            }
+        }
+    }
+    
+    for(mapping = encoding->mappings; mapping; mapping = mapping->next) {
+        if(find_cmap(mapping->type, mapping->pid, mapping->eid, face, 
+                     &cmap)) {
+            tm->named = 0;
+            tm->cmap = cmap;
+            if(symbol) {
+                /* deal with an undocumented ``feature'' of the
+                   Microsft-Symbol cmap */
+                TT_OS2 *os2;
+                os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2);
+                if(os2)
+                    tm->base = os2->usFirstCharIndex - 0x20;
+                else
+                    tm->base = 0;
+            } else
+                tm->base = 0;
+            tm->mapping = mapping;
+            return Successful;
+        }
+    }
+    
+    return BadFontFormat;
+
+  native:
+    tm->named = 0;
+    tm->cmap = face->charmap;
+    tm->base = 0;
+    tm->mapping = NULL;
+    return Successful;
+}
+
+static int 
+find_cmap(int type, int pid, int eid, FT_Face face, FT_CharMap *cmap_return)
+{
+    int i, n;
+    FT_CharMap cmap = NULL;
+
+    n = face->num_charmaps;
+
+    switch(type) {
+    case FONT_ENCODING_TRUETYPE:  /* specific cmap */
+        for(i=0; i<n; i++) {
+            cmap = face->charmaps[i];
+            if(cmap->platform_id == pid && cmap->encoding_id == eid) {
+                *cmap_return = cmap;
+                return 1;
+            }
+        }
+        break;
+    case FONT_ENCODING_UNICODE:   /* any Unicode cmap */
+        /* prefer Microsoft Unicode */
+        for(i=0; i<n; i++) {
+            cmap = face->charmaps[i];
+            if(cmap->platform_id == TT_PLATFORM_MICROSOFT && 
+               cmap->encoding_id == TT_MS_ID_UNICODE_CS) {
+                *cmap_return = cmap;
+                return 1;
+            }
+        }
+        break;
+        /* Try Apple Unicode */
+        for(i=0; i<n; i++) {
+            cmap = face->charmaps[i];
+            if(cmap->platform_id == TT_PLATFORM_APPLE_UNICODE) {
+                *cmap_return = cmap;
+                return 1;
+            }
+        }
+        /* ISO Unicode? */
+        for(i=0; i<n; i++) {
+            cmap = face->charmaps[i];
+            if(cmap->platform_id == TT_PLATFORM_ISO) {
+                *cmap_return = cmap;
+                return 1;
+            }
+        }
+        break;
+    default:
+        return 0;
+    }
+    return 0;
+}
+
+unsigned 
+FTRemap(FT_Face face, FTMappingPtr tm, unsigned code)
+{
+    unsigned index;
+    char *name;
+    unsigned glyph_index;
+
+    if(tm->mapping) {
+        if(tm->named) {
+            name = FontEncName(code, tm->mapping);
+            if(!name)
+                return 0;
+            glyph_index = FT_Get_Name_Index(face, name);
+            return glyph_index;
+        } else {
+            index = FontEncRecode(code, tm->mapping) + tm->base;
+            FT_Set_Charmap(face, tm->cmap);
+            glyph_index = FT_Get_Char_Index(face, index);
+            return glyph_index;
+        }
+    } else {
+        if(code < 0x100) {
+            index = code;
+            FT_Set_Charmap(face, tm->cmap);
+            glyph_index = FT_Get_Char_Index(face, index);
+            return glyph_index;
+        } else
+            return 0;
+    }
+}
diff --git a/src/FreeType/ftfuncs.c b/src/FreeType/ftfuncs.c
new file mode 100755 (executable)
index 0000000..fd8e53e
--- /dev/null
@@ -0,0 +1,3924 @@
+/*
+Copyright (c) 1997 by Mark Leisher
+Copyright (c) 1998-2003 by Juliusz Chroboczek
+Copyright (c) 1998 Go Watanabe, All rights reserved.
+Copyright (c) 1998 Kazushi (Jam) Marukawa, All rights reserved.
+Copyright (c) 1998 Takuya SHIOZAKI, All rights reserved.
+Copyright (c) 1998 X-TrueType Server Project, All rights reserved.
+Copyright (c) 2003-2004 After X-TT Project, All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fontmisc.h>
+
+#include <string.h>
+#include <math.h>
+#include <ctype.h>
+
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/fontutil.h>
+#include <X11/fonts/FSproto.h>
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_SIZES_H
+#include FT_TRUETYPE_IDS_H
+#include FT_TRUETYPE_TABLES_H
+#include FT_TYPE1_TABLES_H
+#include FT_XFREE86_H
+#include FT_BBOX_H
+#include FT_TRUETYPE_TAGS_H
+/*
+ *  If you want to use FT_Outline_Get_CBox instead of 
+ *  FT_Outline_Get_BBox, define here.
+ */
+/* #define USE_GET_CBOX */
+#ifdef USE_GET_CBOX
+#include FT_OUTLINE_H
+#endif
+
+#include <X11/fonts/fontenc.h>
+#include "ft.h"
+#include "ftfuncs.h"
+#include "xttcap.h"
+
+/* Work around FreeType bug */
+#define WORK_AROUND_UPM 2048
+
+#ifndef True
+#define True (-1)
+#endif /* True */
+#ifndef False
+#define False (0)
+#endif /* False */
+
+#define FLOOR64(x) ((x) & -64)
+#define CEIL64(x) (((x) + 64 - 1) & -64)
+
+/*
+ *  If you want very lazy method(vl=y) AS DEFAULT when
+ *  handling large charset, define here.
+ */
+/* #define DEFAULT_VERY_LAZY 1 */      /* Always */
+#define DEFAULT_VERY_LAZY 2            /* Multi-byte only */
+/* #define DEFAULT_VERY_LAZY 256 */    /* Unicode only */
+
+/* Does the X accept noSuchChar? */
+#define X_ACCEPTS_NO_SUCH_CHAR
+/* Does the XAA accept NULL noSuchChar.bits?(dangerous) */
+/* #define XAA_ACCEPTS_NULL_BITS */
+
+#ifdef X_ACCEPTS_NO_SUCH_CHAR
+static CharInfoRec noSuchChar = { /* metrics */{0,0,0,0,0,0},
+                                 /* bits */   NULL };
+#endif
+
+/* The propery names for all the XLFD properties. */
+
+static char *xlfd_props[] = {
+    "FOUNDRY",
+    "FAMILY_NAME",
+    "WEIGHT_NAME",
+    "SLANT",
+    "SETWIDTH_NAME",
+    "ADD_STYLE_NAME",
+    "PIXEL_SIZE",
+    "POINT_SIZE",
+    "RESOLUTION_X",
+    "RESOLUTION_Y",
+    "SPACING",
+    "AVERAGE_WIDTH",
+    "CHARSET_REGISTRY",
+    "CHARSET_ENCODING",
+};
+
+
+/* read 2-byte value from a SFNT table */
+static FT_UShort
+sfnt_get_ushort( FT_Face     face,
+                 FT_ULong    table_tag,
+                 FT_ULong    table_offset )
+{
+  FT_Byte    buff[2];
+  FT_ULong   len = sizeof(buff);
+  FT_UShort  result = 0;
+
+  if ( !FT_Load_Sfnt_Table( face, table_tag, table_offset, buff, &len ) );
+    result = (FT_UShort)( (buff[0] << 8) | buff[1] );
+
+  return result;
+}
+
+#define  sfnt_get_short(f,t,o)  ((FT_Short)sfnt_get_ushort((f),(t),(o)))
+
+
+static int ftypeInitP = 0;      /* is the engine initialised? */
+FT_Library ftypeLibrary;
+
+static FTFacePtr faceTable[NUMFACEBUCKETS];
+
+static unsigned
+hash(char *string)
+{
+    int i;
+    unsigned u = 0;
+    for(i = 0; string[i] != '\0'; i++)
+        u = (u<<5) + (u >> (NUMFACEBUCKETS - 5)) + (unsigned char)string[i];
+    return u;
+}
+
+static int
+ifloor(int x, int y)
+{
+    if(x >= 0)
+        return x/y;
+    else
+        return x/y - 1;
+}
+
+static int
+iceil(int x, int y)
+{
+    return ifloor(x + y - 1, y);
+}
+  
+static int
+FreeTypeOpenFace(FTFacePtr *facep, char *FTFileName, char *realFileName, int faceNumber)
+{
+    FT_Error ftrc;
+    int bucket;
+    FTFacePtr face, otherFace;
+
+    if (!ftypeInitP) {
+        ftrc = FT_Init_FreeType(&ftypeLibrary);
+        if (ftrc != 0) {
+            ErrorF("FreeType: error initializing ftypeEngine: %d\n", ftrc);
+            return AllocError;
+        }
+        ftypeInitP = 1;
+    }
+
+    /* Try to find a matching face in the hashtable */
+    bucket = hash(FTFileName)%NUMFACEBUCKETS;
+    otherFace = faceTable[bucket];
+    while(otherFace) {
+        if( strcmp(otherFace->filename, FTFileName) == 0 ) break;
+        otherFace = otherFace->next;
+    }
+    if(otherFace) {
+        MUMBLE("Returning cached face: %s\n", otherFace->filename);
+        *facep = otherFace;
+        return Successful;
+    }
+
+    /* No cached match; need to make a new one */
+    face = calloc(1, sizeof(FTFaceRec));
+    if (face == NULL) {
+        return AllocError;
+    }
+
+    face->filename = strdup(FTFileName);
+    if (face->filename == NULL) {
+        free(face);
+        return AllocError;
+    }
+
+    ftrc = FT_New_Face(ftypeLibrary, realFileName, faceNumber, &face->face);
+    if(ftrc != 0) {
+        ErrorF("FreeType: couldn't open face %s: %d\n", FTFileName, ftrc);
+        free(face->filename);
+        free(face);
+        return BadFontName;
+    }
+
+    face->bitmap = ((face->face->face_flags & FT_FACE_FLAG_SCALABLE) == 0);
+    if(!face->bitmap) {
+        TT_MaxProfile *maxp;
+        maxp = FT_Get_Sfnt_Table(face->face, ft_sfnt_maxp);
+        if(maxp && maxp->maxContours == 0)
+            face->bitmap = 1;
+    }
+
+    face->num_hmetrics = (FT_UInt) sfnt_get_ushort( face->face,
+                                                    TTAG_hhea, 34 );
+
+    /* Insert face in hashtable and return it */
+    face->next = faceTable[bucket];
+    faceTable[bucket] = face;
+    *facep = face;
+    return Successful;
+}
+
+static void
+FreeTypeFreeFace(FTFacePtr face)
+{
+    int bucket;
+    FTFacePtr otherFace;
+
+    if(!face->instances) {
+        bucket = hash(face->filename) % NUMFACEBUCKETS;
+        if(faceTable[bucket] == face)
+            faceTable[bucket] = face->next;
+        else {
+            otherFace = faceTable[bucket];
+            while(otherFace) {
+                if(otherFace->next == face)
+                    break;
+                otherFace = otherFace->next;
+            }
+            if(otherFace && otherFace->next)
+                otherFace->next = otherFace->next->next;
+            else
+                ErrorF("FreeType: freeing unknown face\n");
+        }
+        MUMBLE("Closing face: %s\n", face->filename);
+        FT_Done_Face(face->face);
+        free(face->filename);
+        free(face);
+    }
+}
+
+static int
+TransEqual(FTNormalisedTransformationPtr t1, FTNormalisedTransformationPtr t2)
+{
+    if(t1->scale != t2->scale)
+        return 0;
+    else if(t1->xres != t2->xres || t1->yres != t2->yres)
+        return 0;
+    else if(t1->nonIdentity != t2->nonIdentity)
+        return 0;
+    else if(t1->nonIdentity && t2->nonIdentity) {
+        return 
+            t1->matrix.xx == t2->matrix.xx &&
+            t1->matrix.yx == t2->matrix.yx &&
+            t1->matrix.yy == t2->matrix.yy &&
+            t1->matrix.xy == t2->matrix.xy;
+    } else
+        return 1;
+}
+
+static int
+BitmapFormatEqual(FontBitmapFormatPtr f1, FontBitmapFormatPtr f2)
+{
+    return
+        f1->bit == f2->bit &&
+        f1->byte == f2->byte &&
+        f1->glyph == f2->glyph;
+}
+
+static int
+TTCapEqual(struct TTCapInfo *t1, struct TTCapInfo *t2)
+{
+    return
+       t1->autoItalic == t2->autoItalic &&
+       t1->scaleWidth == t2->scaleWidth &&
+       t1->scaleBBoxWidth == t2->scaleBBoxWidth &&
+       t1->scaleBBoxHeight == t2->scaleBBoxHeight &&
+       t1->doubleStrikeShift == t2->doubleStrikeShift &&
+       t1->adjustBBoxWidthByPixel == t2->adjustBBoxWidthByPixel &&
+       t1->adjustLeftSideBearingByPixel == t2->adjustLeftSideBearingByPixel &&
+       t1->adjustRightSideBearingByPixel == t2->adjustRightSideBearingByPixel &&
+       t1->flags == t2->flags &&
+       t1->scaleBitmap == t2->scaleBitmap &&
+       /*
+         If we use forceConstantSpacing, 
+         we *MUST* allocate new instance.
+       */
+       t1->forceConstantSpacingEnd < 0 &&
+       t2->forceConstantSpacingEnd < 0;
+}
+
+static int
+FTInstanceMatch(FTInstancePtr instance,
+               char *FTFileName, FTNormalisedTransformationPtr trans,
+               int spacing, FontBitmapFormatPtr bmfmt,
+               struct TTCapInfo *tmp_ttcap, FT_Int32 load_flags) 
+{
+    if(strcmp(instance->face->filename, FTFileName) != 0) {
+        return 0;
+    } else if(!TransEqual(&instance->transformation, trans)) {
+        return 0;
+    } else if( spacing != instance->spacing ) {
+        return 0;
+    } else if( load_flags != instance->load_flags ) {
+        return 0;
+    } else if(!BitmapFormatEqual(&instance->bmfmt, bmfmt)) {
+        return 0;
+    } else if(!TTCapEqual(&instance->ttcap, tmp_ttcap)) {
+        return 0;
+    } else {
+        return 1;
+    }
+}
+
+static int
+FreeTypeActivateInstance(FTInstancePtr instance)
+{
+    FT_Error ftrc;
+    if(instance->face->active_instance == instance)
+        return Successful;
+
+    ftrc = FT_Activate_Size(instance->size);
+    if(ftrc != 0) {
+        instance->face->active_instance = NULL;
+        ErrorF("FreeType: couldn't activate instance: %d\n", ftrc);
+        return FTtoXReturnCode(ftrc);
+    }
+    FT_Set_Transform(instance->face->face,
+                     instance->transformation.nonIdentity ?
+                     &instance->transformation.matrix : 0,
+                     0);
+                            
+    instance->face->active_instance = instance;
+    return Successful;
+}
+
+static int
+FTFindSize(FT_Face face, FTNormalisedTransformationPtr trans,
+           int *x_return, int *y_return)
+{
+    int tx, ty, x, y;
+    int i, j;
+    int d, dd;
+
+    if(trans->nonIdentity)
+        return BadFontName;
+
+    tx = (int)(trans->scale * trans->xres / 72.0 + 0.5);
+    ty = (int)(trans->scale * trans->yres / 72.0 + 0.5);
+
+    d = 100;
+    j = -1;
+    for(i = 0; i < face->num_fixed_sizes; i++) {
+        x = face->available_sizes[i].width;
+        y = face->available_sizes[i].height;
+        if(ABS(x - tx) <= 1 && ABS(y - ty) <= 1) {
+            dd = ABS(x - tx) * ABS(x - tx) + ABS(y - ty) * ABS(y - ty);
+            if(dd < d) {
+                j = i;
+                d = dd;
+            }
+        }            
+    }
+    if(j < 0)
+        return BadFontName;
+
+    *x_return = face->available_sizes[j].width;
+    *y_return = face->available_sizes[j].height;
+    return Successful;
+}
+
+static int
+FreeTypeOpenInstance(FTInstancePtr *instance_return, FTFacePtr face,
+                     char *FTFileName, FTNormalisedTransformationPtr trans,
+                     int spacing, FontBitmapFormatPtr bmfmt,
+                    struct TTCapInfo *tmp_ttcap, FT_Int32 load_flags)
+{
+    FT_Error ftrc;
+    int xrc;
+    FTInstancePtr instance, otherInstance;
+
+    /* Search for a matching instance */
+    for(otherInstance = face->instances;
+        otherInstance;
+        otherInstance = otherInstance->next) {
+        if(FTInstanceMatch(otherInstance, FTFileName, trans, spacing, bmfmt,
+                          tmp_ttcap, load_flags)) break;
+    }
+    if(otherInstance) {
+        MUMBLE("Returning cached instance\n");
+        otherInstance->refcount++;
+        *instance_return = otherInstance;
+        return Successful;
+    }
+
+    /* None matching found */
+    instance = malloc(sizeof(FTInstanceRec));
+    if(instance == NULL) {
+        return AllocError;
+    }
+
+    instance->refcount = 1;
+    instance->face = face;
+
+    instance->load_flags = load_flags;
+    instance->spacing    = spacing;            /* Actual spacing */
+    instance->pixel_size =0;
+    instance->pixel_width_unit_x =0;
+    instance->pixel_width_unit_y =0;
+    instance->charcellMetrics = NULL;
+    instance->averageWidth = 0;
+    instance->rawAverageWidth = 0;
+    instance->forceConstantMetrics = NULL;
+
+    instance->transformation = *trans;
+    instance->bmfmt = *bmfmt;
+    instance->glyphs = NULL;
+    instance->available = NULL;
+
+    if( 0 <= tmp_ttcap->forceConstantSpacingEnd )
+       instance->nglyphs = 2 * instance->face->face->num_glyphs;
+    else
+       instance->nglyphs = instance->face->face->num_glyphs;
+
+    /* Store the TTCap info. */
+    memcpy((char*)&instance->ttcap, (char*)tmp_ttcap,
+          sizeof(struct TTCapInfo));
+
+    ftrc = FT_New_Size(instance->face->face, &instance->size);
+    if(ftrc != 0) {
+        ErrorF("FreeType: couldn't create size object: %d\n", ftrc);
+        free(instance);
+        return FTtoXReturnCode(ftrc);
+    }
+    FreeTypeActivateInstance(instance);
+    if(!face->bitmap) {
+        ftrc = FT_Set_Char_Size(instance->face->face,
+                                (int)(trans->scale*(1<<6) + 0.5),
+                                (int)(trans->scale*(1<<6) + 0.5),
+                                trans->xres, trans->yres);
+    } else {
+        int xsize, ysize;
+        xrc = FTFindSize(face->face, trans, &xsize, &ysize);
+        if(xrc != Successful) {
+            free(instance);
+            return xrc;
+        }
+        ftrc = FT_Set_Pixel_Sizes(instance->face->face, xsize, ysize);
+    }
+    if(ftrc != 0) {
+        FT_Done_Size(instance->size);
+        free(instance);
+        return FTtoXReturnCode(ftrc);
+    }
+
+    if( FT_IS_SFNT( face->face ) ) {
+#if 1
+        FT_F26Dot6  tt_char_width, tt_char_height, tt_dim_x, tt_dim_y;
+        FT_UInt     nn;
+
+        instance->strike_index=0xFFFFU;
+
+        tt_char_width  = (FT_F26Dot6)(trans->scale*(1<<6) + 0.5);
+        tt_char_height = (FT_F26Dot6)(trans->scale*(1<<6) + 0.5);
+
+        tt_dim_x = FLOOR64( ( tt_char_width  * trans->xres + 36 ) / 72 + 32 );
+        tt_dim_y = FLOOR64( ( tt_char_height * trans->yres + 36 ) / 72 + 32 );
+
+       if ( tt_dim_x && !tt_dim_y )
+           tt_dim_y = tt_dim_x;
+       else if ( !tt_dim_x && tt_dim_y )
+           tt_dim_x = tt_dim_y;
+
+        for ( nn = 0; nn < face->face->num_fixed_sizes; nn++ )
+        {
+          FT_Bitmap_Size*  sz = &face->face->available_sizes[nn];
+
+          if ( tt_dim_x == FLOOR64(sz->x_ppem + 32) && tt_dim_y == FLOOR64(sz->y_ppem + 32) )
+          {
+            instance->strike_index = nn;
+            break;
+          }
+        }
+#else
+       /* See Set_Char_Sizes() in ttdriver.c */
+       FT_Error err;
+       TT_Face tt_face;
+       FT_Long tt_dim_x, tt_dim_y;
+       FT_UShort tt_x_ppem, tt_y_ppem;
+       FT_F26Dot6  tt_char_width, tt_char_height;
+       SFNT_Service sfnt;
+       tt_face=(TT_Face)face->face;
+       tt_char_width  = (int)(trans->scale*(1<<6) + 0.5);
+       tt_char_height = (int)(trans->scale*(1<<6) + 0.5);
+       if ( ( tt_face->header.Flags & 8 ) != 0 ) {
+           tt_dim_x = ( ( tt_char_width  * trans->xres + (36+32*72) ) / 72 ) & -64;
+           tt_dim_y = ( ( tt_char_height * trans->yres + (36+32*72) ) / 72 ) & -64;
+       }
+       else{
+           tt_dim_x = ( ( tt_char_width  * trans->xres + 36 ) / 72 );
+           tt_dim_y = ( ( tt_char_height * trans->yres + 36 ) / 72 );
+       }
+       tt_x_ppem  = (FT_UShort)( tt_dim_x >> 6 );
+       tt_y_ppem  = (FT_UShort)( tt_dim_y >> 6 );
+       /* See Reset_SBit_Size() in ttobjs.c */
+       sfnt   = (SFNT_Service)tt_face->sfnt;
+       err = sfnt->set_sbit_strike(tt_face,tt_x_ppem,tt_y_ppem,&instance->strike_index);
+       if ( err ) instance->strike_index=0xFFFFU;
+#endif
+    }
+
+    /* maintain a linked list of instances */
+    instance->next = instance->face->instances;
+    instance->face->instances = instance;
+    
+    *instance_return = instance;
+    return Successful;
+}
+
+static void
+FreeTypeFreeInstance(FTInstancePtr instance)
+{
+    FTInstancePtr otherInstance;
+
+    if( instance == NULL ) return;
+
+    if(instance->face->active_instance == instance)
+        instance->face->active_instance = NULL;
+    instance->refcount--;
+    if(instance->refcount <= 0) {
+        int i,j;
+        
+        if(instance->face->instances == instance)
+            instance->face->instances = instance->next;
+        else {
+            for(otherInstance = instance->face->instances;
+                otherInstance;
+                otherInstance = otherInstance->next)
+                if(otherInstance->next == instance) {
+                    otherInstance->next = instance->next;
+                    break;
+                }
+        }
+
+        FT_Done_Size(instance->size);
+        FreeTypeFreeFace(instance->face);
+
+        if(instance->charcellMetrics) {
+            free(instance->charcellMetrics);
+        }
+        if(instance->forceConstantMetrics) {
+            free(instance->forceConstantMetrics);
+        }
+        if(instance->glyphs) {
+            for(i = 0; i < iceil(instance->nglyphs, FONTSEGMENTSIZE); i++) {
+                if(instance->glyphs[i]) {
+                    for(j = 0; j < FONTSEGMENTSIZE; j++) {
+                        if(instance->available[i][j] == 
+                           FT_AVAILABLE_RASTERISED)
+                            free(instance->glyphs[i][j].bits);
+                    }
+                    free(instance->glyphs[i]);
+                }
+            }
+            free(instance->glyphs);
+        }
+        if(instance->available) {
+            for(i = 0; i < iceil(instance->nglyphs, FONTSEGMENTSIZE); i++) {
+                if(instance->available[i])
+                    free(instance->available[i]);
+            }
+            free(instance->available);
+        }
+        free(instance);
+    }
+}
+
+static int
+FreeTypeInstanceFindGlyph(unsigned idx_in, int flags, FTInstancePtr instance,
+                          CharInfoPtr **glyphs, int ***available,
+                          int *found, int *segmentP, int *offsetP)
+{
+    int segment, offset;
+    unsigned idx = idx_in;
+
+    if( 0 <= instance->ttcap.forceConstantSpacingEnd ){
+       if( (flags & FT_FORCE_CONSTANT_SPACING) )
+           idx += instance->nglyphs / 2 ;
+    }
+
+    if(idx > instance->nglyphs) {
+        *found = 0;
+        return Successful;
+    }
+  
+    if(*available == NULL) {
+        *available = calloc(iceil(instance->nglyphs, FONTSEGMENTSIZE),
+                           sizeof(int *));
+        if(*available == NULL)
+            return AllocError;
+    }
+
+    segment = ifloor(idx, FONTSEGMENTSIZE);
+    offset = idx - segment * FONTSEGMENTSIZE;
+
+    if((*available)[segment] == NULL) {
+        (*available)[segment] = calloc(FONTSEGMENTSIZE, sizeof(int *));
+        if((*available)[segment] == NULL)
+            return AllocError;
+    }
+
+    if(*glyphs == NULL) {
+        *glyphs = calloc(iceil(instance->nglyphs, FONTSEGMENTSIZE),
+                        sizeof(CharInfoPtr));
+        if(*glyphs == NULL)
+            return AllocError;
+    }
+
+    if((*glyphs)[segment] == NULL) {
+        (*glyphs)[segment] = malloc(sizeof(CharInfoRec) * FONTSEGMENTSIZE);
+        if((*glyphs)[segment] == NULL)
+            return AllocError;
+    }
+
+    *found = 1;
+    *segmentP = segment;
+    *offsetP = offset;
+    return Successful;
+}
+
+static int
+FreeTypeInstanceGetGlyph(unsigned idx, int flags, CharInfoPtr *g, FTInstancePtr instance)
+{
+    int found, segment, offset;
+    int xrc;
+    int ***available;
+    CharInfoPtr **glyphs;
+    
+    available = &instance->available;
+    glyphs = &instance->glyphs;
+
+    xrc = FreeTypeInstanceFindGlyph(idx, flags, instance, glyphs, available,
+                                    &found, &segment, &offset);
+    if(xrc != Successful)
+        return xrc;
+
+    if(!found || (*available)[segment][offset] == FT_AVAILABLE_NO) {
+        *g = NULL;
+        return Successful;
+    } 
+
+    if((*available)[segment][offset] == FT_AVAILABLE_RASTERISED) {
+       *g = &(*glyphs)[segment][offset];
+       return Successful;
+    }
+    
+    flags |= FT_GET_GLYPH_BOTH;
+
+    xrc = FreeTypeRasteriseGlyph(idx, flags, 
+                                &(*glyphs)[segment][offset], instance, 
+                                (*available)[segment][offset] >= FT_AVAILABLE_METRICS);
+    if(xrc != Successful && (*available)[segment][offset] >= FT_AVAILABLE_METRICS) {
+       ErrorF("Warning: FreeTypeRasteriseGlyph() returns an error,\n");
+       ErrorF("\tso the backend tries to set a white space.\n");
+       xrc = FreeTypeRasteriseGlyph(idx, flags | FT_GET_DUMMY,
+                                    &(*glyphs)[segment][offset], instance,
+                                    (*available)[segment][offset] >= FT_AVAILABLE_METRICS);
+    }
+    if(xrc == Successful) {
+        (*available)[segment][offset] = FT_AVAILABLE_RASTERISED;
+       /* return the glyph */
+        *g = &(*glyphs)[segment][offset];
+    }
+    return xrc;
+}
+
+static int
+FreeTypeInstanceGetGlyphMetrics(unsigned idx, int flags,
+                               xCharInfo **metrics, FTInstancePtr instance )
+{
+    int xrc;
+    int found, segment, offset;
+    
+    /* Char cell */
+    if(instance->spacing == FT_CHARCELL) {
+       *metrics = instance->charcellMetrics;
+       return Successful;
+    }
+    /* Force constant metrics  */
+    if( flags & FT_FORCE_CONSTANT_SPACING) {
+       *metrics = instance->forceConstantMetrics;
+       return Successful;
+    }
+
+    /* Not char cell */
+
+    xrc = FreeTypeInstanceFindGlyph(idx, flags, instance, 
+                                    &instance->glyphs, &instance->available, 
+                                    &found, &segment, &offset);
+    if(xrc != Successful)
+        return xrc;
+    if(!found) {
+        *metrics = NULL;
+        return Successful;
+    }
+    if( instance->available[segment][offset] == FT_AVAILABLE_NO ) {
+        *metrics = NULL;
+        return Successful;
+    } 
+
+    if( instance->available[segment][offset] >= FT_AVAILABLE_METRICS ) {
+       *metrics = &instance->glyphs[segment][offset].metrics;
+       return Successful;
+    }
+    
+    flags |= FT_GET_GLYPH_METRICS_ONLY;
+
+    xrc = FreeTypeRasteriseGlyph(idx, flags, 
+                                &instance->glyphs[segment][offset],
+                                instance, 0);
+    if(xrc == Successful) {
+        instance->available[segment][offset] = FT_AVAILABLE_METRICS;
+        *metrics = &instance->glyphs[segment][offset].metrics;
+    }
+    return xrc;
+}
+    
+/*
+ * Pseudo enbolding similar as Microsoft Windows.
+ * It is useful but poor.
+ */
+static void
+ft_make_up_bold_bitmap( char *raster, int bpr, int ht, int ds_mode)
+{
+    int x, y;
+    unsigned char *p = (unsigned char *)raster;
+    if ( ds_mode & TTCAP_DOUBLE_STRIKE_MKBOLD_EDGE_LEFT ) {
+        for (y=0; y<ht; y++) {
+            unsigned char rev_pat=0;
+            unsigned char lsb = 0;
+            for (x=0; x<bpr; x++) {
+                unsigned char tmp = *p<<7;
+                if ( (rev_pat & 0x01) && (*p & 0x80) ) p[-1] &= 0xfe;
+                rev_pat = ~(*p);
+                *p |= (*p>>1) | lsb;
+                *p &= ~(rev_pat & (*p << 1));
+                lsb = tmp;
+                p++;
+            }
+        }
+    }
+    else {
+        for (y=0; y<ht; y++) {
+            unsigned char lsb = 0;
+            for (x=0; x<bpr; x++) {
+                unsigned char tmp = *p<<7;
+                *p |= (*p>>1) | lsb;
+                lsb = tmp;
+                p++;
+            }
+        }
+    }
+}
+
+static void
+ft_make_up_italic_bitmap( char *raster, int bpr, int ht, int shift,
+                         int h_total, int h_offset, double a_italic)
+{
+    int x, y;
+    unsigned char *p = (unsigned char *)raster;
+    if ( a_italic < 0 ) shift = -shift;
+    for (y=0; y<ht; y++) {
+        unsigned char *tmp_p = p + y*bpr;
+        int tmp_shift = shift * (h_total -1 -(y+h_offset)) / h_total;
+        int tmp_byte_shift;
+       if ( 0 <= tmp_shift ) {
+           tmp_byte_shift = tmp_shift/8;
+           tmp_shift %= 8;
+           if ( tmp_shift ) {
+               for (x=bpr-1;0<=x;x--) {
+                   if ( x != bpr-1 ) 
+                       tmp_p[x+1] |= tmp_p[x]<<(8-tmp_shift);
+                   tmp_p[x]>>=tmp_shift;
+               }
+           }
+           if ( tmp_byte_shift ) {
+               for (x=bpr-1;0<x;x--) {
+                   tmp_p[x] = tmp_p[x-1];
+               }
+               tmp_p[x]=0;
+           }
+       }
+       else {
+           tmp_shift = -tmp_shift;
+           tmp_byte_shift = tmp_shift/8;
+           tmp_shift %= 8;
+           if ( tmp_shift ) {
+               for (x=0;x<bpr;x++) {
+                   if ( x != 0 ) 
+                       tmp_p[x-1] |= tmp_p[x]>>(8-tmp_shift);
+                   tmp_p[x]<<=tmp_shift;
+               }
+           }
+           if ( tmp_byte_shift ) {
+               for (x=0;x<bpr-1;x++) {
+                   tmp_p[x] = tmp_p[x+1];
+               }
+               tmp_p[x]=0;
+           }
+       }
+    }
+}
+
+/*
+ * The very lazy method,
+ * parse the htmx field in TrueType font.
+ */
+
+static void
+tt_get_metrics( FT_Face         face,
+               FT_UInt         idx,
+               FT_UInt         num_hmetrics,
+               FT_Short*       bearing,
+               FT_UShort*      advance )
+{
+   /* read the metrics directly from the horizontal header, we
+    * parse the SFNT table directly through the standard FreeType API.
+    * this works with any version of the library and doesn't need to
+    * peek at its internals. Maybe a bit less
+    */
+    FT_UInt  count  = num_hmetrics;
+    FT_ULong length = 0;
+    FT_ULong offset = 0;
+    FT_Error error;
+
+    error = FT_Load_Sfnt_Table( face, TTAG_hmtx, 0, NULL, &length );
+
+    if ( count == 0 || error )
+    {
+      *advance = 0;
+      *bearing = 0;
+    }
+    else if ( idx < count )
+    {
+       offset = idx * 4L;
+       if ( offset + 4 > length )
+       {
+           *advance = 0;
+           *bearing = 0;
+       }
+       else
+       {
+           *advance = sfnt_get_ushort( face, TTAG_hmtx, offset );
+           *bearing = sfnt_get_short ( face, TTAG_hmtx, offset+2 );
+       }
+    }
+    else
+    {
+       offset = 4L * (count - 1);
+       if ( offset + 4 > length )
+       {
+           *advance = 0;
+           *bearing = 0;
+       }
+       else
+       {
+           *advance = sfnt_get_ushort ( face, TTAG_hmtx, offset );
+           offset += 4 + 2 * ( idx - count );
+           if ( offset + 2 > length)
+               *bearing = 0;
+           else
+               *bearing = sfnt_get_short ( face, TTAG_hmtx, offset );
+    }
+    }
+}
+
+static int                   
+ft_get_very_lazy_bbox( FT_UInt index,
+                      FT_Face face,
+                      FT_Size size,
+                      FT_UInt num_hmetrics,
+                      double slant,
+                      FT_Matrix *matrix,
+                      FT_BBox *bbox,
+                      FT_Long *horiAdvance,
+                      FT_Long *vertAdvance)
+{
+    if ( FT_IS_SFNT( face ) ) {
+       FT_Size_Metrics *smetrics = &size->metrics;
+       FT_Short  leftBearing = 0;
+       FT_UShort advance = 0;
+       FT_Vector p0, p1, p2, p3;
+
+       /* horizontal */
+       tt_get_metrics( face, index, num_hmetrics,
+                      &leftBearing, &advance );
+
+#if 0
+       fprintf(stderr,"x_scale=%f y_scale=%f\n",
+               (double)smetrics->x_scale,(double)smetrics->y_scale);
+#endif
+       bbox->xMax = *horiAdvance =
+           FT_MulFix( advance, smetrics->x_scale );
+       bbox->xMin =
+           FT_MulFix( leftBearing, smetrics->x_scale );
+       /* vertical */
+       bbox->yMin = FT_MulFix( face->bbox.yMin,
+                               smetrics->y_scale );
+       bbox->yMax = FT_MulFix( face->bbox.yMax,
+                               smetrics->y_scale );
+       /* slant */
+       if( 0 < slant ) {
+           bbox->xMax += slant * bbox->yMax;
+           bbox->xMin += slant * bbox->yMin;
+       }
+       else if( slant < 0 ) {
+           bbox->xMax += slant * bbox->yMin;
+           bbox->xMin += slant * bbox->yMax;
+       }
+
+       *vertAdvance = -1;      /* We don't support */
+
+       p0.x = p2.x = bbox->xMin;
+       p1.x = p3.x = bbox->xMax;
+       p0.y = p1.y = bbox->yMin;
+       p2.y = p3.y = bbox->yMax;
+
+       FT_Vector_Transform(&p0, matrix);
+       FT_Vector_Transform(&p1, matrix);
+       FT_Vector_Transform(&p2, matrix);
+       FT_Vector_Transform(&p3, matrix);
+
+#if 0
+       fprintf(stderr,
+               "->(%.1f %.1f) (%.1f %.1f)"
+               "  (%.1f %.1f) (%.1f %.1f)\n",
+               p0.x / 64.0, p0.y / 64.0,
+               p1.x / 64.0, p1.y / 64.0,
+               p2.x / 64.0, p2.y / 64.0,
+               p3.x / 64.0, p3.y / 64.0);
+#endif
+       bbox->xMin = MIN(p0.x, MIN(p1.x, MIN(p2.x, p3.x)));
+       bbox->xMax = MAX(p0.x, MAX(p1.x, MAX(p2.x, p3.x)));
+       bbox->yMin = MIN(p0.y, MIN(p1.y, MIN(p2.y, p3.y)));
+       bbox->yMax = MAX(p0.y, MAX(p1.y, MAX(p2.y, p3.y)));
+       return 0;       /* Successful */
+    }
+    return -1;
+}
+
+static FT_Error
+FT_Do_SBit_Metrics( FT_Face ft_face, FT_Size ft_size, FT_ULong strike_index,
+                   FT_UShort glyph_index, FT_Glyph_Metrics *metrics_return,
+                   int *sbitchk_incomplete_but_exist )
+{
+#if 1
+    if ( strike_index != 0xFFFFU && ft_face->available_sizes != NULL )
+    {
+      FT_Error         error;
+      FT_Bitmap_Size*  sz = &ft_face->available_sizes[strike_index];
+
+      error = FT_Set_Pixel_Sizes( ft_face, sz->x_ppem/64, sz->y_ppem/64 );
+      if ( !error )
+      {
+        error = FT_Load_Glyph( ft_face, glyph_index, FT_LOAD_SBITS_ONLY );
+        if ( !error )
+        {
+          if ( metrics_return != NULL )
+            *metrics_return = ft_face->glyph->metrics;
+
+          return 0;
+        }
+      }
+    }
+    return -1;
+#elif (FREETYPE_VERSION >= 2001008)
+    SFNT_Service       sfnt;
+    TT_Face            face;
+    FT_Error           error;
+    FT_Stream          stream;
+    TT_SBit_Strike     strike;
+    TT_SBit_Range      range;
+    TT_SBit_MetricsRec elem_metrics;
+    FT_ULong           ebdt_pos;
+    FT_ULong           glyph_offset;
+    ;
+
+    if ( ! FT_IS_SFNT( ft_face ) )
+    {
+        error=-1;
+        goto Exit;
+    }
+
+    face = (TT_Face)ft_face;
+    sfnt   = (SFNT_Service)face->sfnt;
+
+    if (strike_index != 0xFFFFU && sfnt && sfnt->find_sbit_image &&
+            sfnt->load_sbits) {
+        /* Check whether there is a glyph sbit for the current index */
+        error = sfnt->find_sbit_image( face, glyph_index, strike_index,
+                                       &range, &strike, &glyph_offset );
+    }
+    else error=-1;
+    if ( error ) goto Exit;
+
+    if ( metrics_return == NULL ) goto Exit;
+
+    stream = face->root.stream;
+
+    /* now, find the location of the `EBDT' table in */
+    /* the font file                                 */
+    error = face->goto_table( face, TTAG_EBDT, stream, 0 );
+    if ( error )
+      error = face->goto_table( face, TTAG_bdat, stream, 0 );
+    if (error)
+      goto Exit;
+
+    ebdt_pos = FT_STREAM_POS();
+
+    /* place stream at beginning of glyph data and read metrics */
+    if ( FT_STREAM_SEEK( ebdt_pos + glyph_offset ) )
+      goto Exit;
+
+    error = sfnt->load_sbit_metrics( stream, range, &elem_metrics );
+    if ( error )
+      goto Exit;
+
+    metrics_return->width  = (FT_Pos)elem_metrics.width  << 6;
+    metrics_return->height = (FT_Pos)elem_metrics.height << 6;
+
+    metrics_return->horiBearingX = (FT_Pos)elem_metrics.horiBearingX << 6;
+    metrics_return->horiBearingY = (FT_Pos)elem_metrics.horiBearingY << 6;
+    metrics_return->horiAdvance  = (FT_Pos)elem_metrics.horiAdvance  << 6;
+    
+    metrics_return->vertBearingX = (FT_Pos)elem_metrics.vertBearingX << 6;
+    metrics_return->vertBearingY = (FT_Pos)elem_metrics.vertBearingY << 6;
+    metrics_return->vertAdvance  = (FT_Pos)elem_metrics.vertAdvance  << 6;
+
+  Exit:
+      return error;
+#else  /* if (FREETYPE_VERSION < 2001008) */
+    TT_Face            face;
+    SFNT_Service       sfnt;
+    if ( ! FT_IS_SFNT( ft_face ) ) return -1;
+    face = (TT_Face)ft_face;
+    sfnt = (SFNT_Service)face->sfnt;
+    if ( strike_index != 0xFFFFU && sfnt->load_sbits ) {
+        if ( sbitchk_incomplete_but_exist ) *sbitchk_incomplete_but_exist=1;
+    }
+    return -1;
+#endif
+}
+
+int
+FreeTypeRasteriseGlyph(unsigned idx, int flags, CharInfoPtr tgp,
+                      FTInstancePtr instance, int hasMetrics)
+{
+    FTFacePtr face;
+    FT_BBox bbox;
+    FT_Long outline_hori_advance, outline_vert_advance;
+    FT_Glyph_Metrics sbit_metrics;
+    FT_Glyph_Metrics *bitmap_metrics=NULL, *metrics = NULL;
+    char *raster;
+    int wd, ht, bpr;            /* width, height, bytes per row */
+    int wd_actual, ht_actual;
+    int ftrc, is_outline, correct, b_shift=0;
+    int dx, dy;
+    int leftSideBearing, rightSideBearing, characterWidth, rawCharacterWidth,
+        ascent, descent;
+    int sbitchk_incomplete_but_exist;
+    double bbox_center_raw;
+
+    face = instance->face;
+
+    FreeTypeActivateInstance(instance);
+
+    if(!tgp) return AllocError;
+
+    /*
+     * PREPARE METRICS
+     */
+
+    if(!hasMetrics) {
+       if( instance->spacing == FT_CHARCELL || flags & FT_GET_DUMMY ){
+           memcpy((char*)&tgp->metrics, 
+                  (char*)instance->charcellMetrics,
+                  sizeof(xCharInfo));
+       }
+       else if( flags & FT_FORCE_CONSTANT_SPACING ) {
+           memcpy((char*)&tgp->metrics, 
+                  (char*)instance->forceConstantMetrics,
+                  sizeof(xCharInfo));
+       }
+       /* mono or prop. */
+       else{
+           int new_width;
+           double ratio;
+
+           sbitchk_incomplete_but_exist=0;
+           if( ! (instance->load_flags & FT_LOAD_NO_BITMAP) ) {
+               if( FT_Do_SBit_Metrics(face->face,instance->size,instance->strike_index,
+                                      idx,&sbit_metrics,&sbitchk_incomplete_but_exist)==0 ) {
+                   bitmap_metrics = &sbit_metrics;
+               }
+           }
+           if( bitmap_metrics == NULL ) {
+               if ( sbitchk_incomplete_but_exist==0 && (instance->ttcap.flags & TTCAP_IS_VERY_LAZY) ) {
+                   if( ft_get_very_lazy_bbox( idx, face->face, instance->size, 
+                                              face->num_hmetrics,
+                                              instance->ttcap.vl_slant,
+                                              &instance->transformation.matrix,
+                                              &bbox, &outline_hori_advance, 
+                                              &outline_vert_advance ) == 0 ) {
+                       goto bbox_ok;   /* skip exact calculation */
+                   }
+               }
+               ftrc = FT_Load_Glyph(instance->face->face, idx, 
+                                    instance->load_flags);
+               if(ftrc != 0) return FTtoXReturnCode(ftrc);
+               metrics = &face->face->glyph->metrics;
+               if( face->face->glyph->format == FT_GLYPH_FORMAT_BITMAP ) {
+                   bitmap_metrics = metrics;
+               }
+           }
+
+           if( bitmap_metrics ) {
+               FT_Pos factor;
+               
+               leftSideBearing = bitmap_metrics->horiBearingX / 64;
+               rightSideBearing = (bitmap_metrics->width + bitmap_metrics->horiBearingX) / 64;
+               bbox_center_raw = (2.0 * bitmap_metrics->horiBearingX + bitmap_metrics->width)/2.0/64.0;
+               characterWidth = (int)floor(bitmap_metrics->horiAdvance 
+                                           * instance->ttcap.scaleBBoxWidth / 64.0 + .5);
+               ascent = bitmap_metrics->horiBearingY / 64;
+               descent = (bitmap_metrics->height - bitmap_metrics->horiBearingY) / 64 ;
+               /* */
+               new_width = characterWidth;
+               if( instance->ttcap.flags & TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH )
+                   new_width += instance->ttcap.doubleStrikeShift;
+               new_width += instance->ttcap.adjustBBoxWidthByPixel;
+               ratio = (double)new_width/characterWidth;
+               characterWidth = new_width;
+               /* adjustment by pixel unit */
+               if( instance->ttcap.flags & TTCAP_DOUBLE_STRIKE )
+                   rightSideBearing += instance->ttcap.doubleStrikeShift;
+               rightSideBearing += instance->ttcap.adjustRightSideBearingByPixel;
+               leftSideBearing  += instance->ttcap.adjustLeftSideBearingByPixel;
+               rightSideBearing += instance->ttcap.rsbShiftOfBitmapAutoItalic;
+               leftSideBearing  += instance->ttcap.lsbShiftOfBitmapAutoItalic;
+               /* */
+               factor = bitmap_metrics->horiAdvance;
+               rawCharacterWidth = (unsigned short)(short)(floor(1000 * factor
+                                                 * instance->ttcap.scaleBBoxWidth * ratio / 64.
+                                                 / instance->pixel_size));
+           }
+           else {
+               /* Outline */
+#ifdef USE_GET_CBOX
+               /* Very fast?? */
+               FT_Outline_Get_CBox(&face->face->glyph->outline, &bbox);
+               ftrc=0;         /* FT_Outline_Get_CBox returns nothing. */
+#else
+               /* Calculate exact metrics */
+               ftrc=FT_Outline_Get_BBox(&face->face->glyph->outline, &bbox);
+#endif
+               if( ftrc != 0 ) return FTtoXReturnCode(ftrc);
+               outline_hori_advance = metrics->horiAdvance;
+               outline_vert_advance = metrics->vertAdvance;
+           bbox_ok:
+               descent  = CEIL64(-bbox.yMin - 32) / 64;
+               leftSideBearing  = FLOOR64(bbox.xMin + 32) / 64;
+               ascent   = FLOOR64(bbox.yMax + 32) / 64;
+               rightSideBearing = FLOOR64(bbox.xMax + 32) / 64;
+               bbox_center_raw = (double)(bbox.xMax + bbox.xMin)/2.0/64.;
+               if ( instance->pixel_width_unit_x != 0 )
+                   characterWidth =
+                       (int)floor( outline_hori_advance 
+                                   * instance->ttcap.scaleBBoxWidth
+                                   * instance->pixel_width_unit_x / 64. + .5);
+               else {
+                   characterWidth = 
+                       (int)floor( outline_vert_advance
+                                   * instance->ttcap.scaleBBoxHeight
+                                   * instance->pixel_width_unit_y / 64. + .5);
+                   if(characterWidth <= 0)
+                       characterWidth = instance->charcellMetrics->characterWidth;
+               }
+               /* */
+               new_width = characterWidth;
+               if( instance->ttcap.flags & TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH )
+                   new_width += instance->ttcap.doubleStrikeShift;
+               new_width += instance->ttcap.adjustBBoxWidthByPixel;
+               ratio = (double)new_width/characterWidth;
+               characterWidth = new_width;
+               if ( instance->pixel_width_unit_x != 0 )
+                   rawCharacterWidth =
+                       (unsigned short)(short)(floor(1000 * outline_hori_advance 
+                                                     * instance->ttcap.scaleBBoxWidth * ratio
+                                                     * instance->pixel_width_unit_x / 64.));
+               else {
+                   rawCharacterWidth =
+                       (unsigned short)(short)(floor(1000 * outline_vert_advance 
+                                                     * instance->ttcap.scaleBBoxHeight * ratio
+                                                     * instance->pixel_width_unit_y / 64.));
+                   if(rawCharacterWidth <= 0)
+                       rawCharacterWidth = instance->charcellMetrics->attributes;
+               }
+               /* adjustment by pixel unit */
+               if( instance->ttcap.flags & TTCAP_DOUBLE_STRIKE )
+                   rightSideBearing += instance->ttcap.doubleStrikeShift;
+               rightSideBearing += instance->ttcap.adjustRightSideBearingByPixel;
+               leftSideBearing  += instance->ttcap.adjustLeftSideBearingByPixel;
+           }
+
+           /* Set the glyph metrics. */
+           tgp->metrics.attributes = (unsigned short)((short)rawCharacterWidth);
+           tgp->metrics.leftSideBearing = leftSideBearing;
+           tgp->metrics.rightSideBearing = rightSideBearing;
+           tgp->metrics.characterWidth = characterWidth;
+           tgp->metrics.ascent = ascent;
+           tgp->metrics.descent = descent;
+           /* Update the width to match the width of the font */
+           if( instance->spacing != FT_PROPORTIONAL )
+               tgp->metrics.characterWidth = instance->charcellMetrics->characterWidth;
+           if(instance->ttcap.flags & TTCAP_MONO_CENTER){
+               b_shift   = (int)floor((instance->advance/2.0-bbox_center_raw) + .5);
+               tgp->metrics.leftSideBearing  += b_shift;
+               tgp->metrics.rightSideBearing += b_shift;
+           }
+       }
+    }
+
+    if( flags & FT_GET_GLYPH_METRICS_ONLY ) return Successful;
+
+    /*
+     * CHECK THE NECESSITY OF BITMAP POSITION'S CORRECTION
+     */
+
+    correct=0;
+    if( instance->spacing == FT_CHARCELL ) correct=1;
+    else if( flags & FT_FORCE_CONSTANT_SPACING ) correct=1;
+    else{
+       int sbit_available=0;
+       sbitchk_incomplete_but_exist=0;
+       if( !(instance->load_flags & FT_LOAD_NO_BITMAP) ) {
+           if( FT_Do_SBit_Metrics(face->face,instance->size,
+                                  instance->strike_index,idx,NULL,
+                                  &sbitchk_incomplete_but_exist)==0 ) {
+               sbit_available=1;
+           }
+       }
+       if( sbit_available == 0 ) {
+           if ( sbitchk_incomplete_but_exist==0 && (instance->ttcap.flags & TTCAP_IS_VERY_LAZY) ) {
+               if( FT_IS_SFNT(face->face) ) correct=1;
+           }
+       }
+    }
+
+    /*
+     * RENDER AND ALLOCATE BUFFER
+     */
+
+    if( flags & FT_GET_DUMMY ) is_outline = -1;
+    else {
+       if( !metrics ) {
+           ftrc = FT_Load_Glyph(instance->face->face, idx, 
+                                instance->load_flags);
+           metrics = &face->face->glyph->metrics;
+
+           if(ftrc != 0) return FTtoXReturnCode(ftrc);
+       }
+
+       if( face->face->glyph->format != FT_GLYPH_FORMAT_BITMAP ) {
+#ifdef USE_GET_CBOX
+           FT_Outline_Get_CBox(&face->face->glyph->outline, &bbox);
+           ftrc = 0;
+#else
+           ftrc = FT_Outline_Get_BBox(&face->face->glyph->outline, &bbox);
+#endif
+           if( ftrc != 0 ) return FTtoXReturnCode(ftrc);
+           bbox.yMin = FLOOR64( bbox.yMin );
+           bbox.yMax = CEIL64 ( bbox.yMax );
+           ht_actual = ( bbox.yMax - bbox.yMin ) >> 6;
+           /* FreeType think a glyph with 0 height control box is invalid. 
+            * So just let X to create a empty bitmap instead. */
+           if ( ht_actual == 0 )
+               is_outline = -1;
+           else
+           {
+           ftrc = FT_Render_Glyph(face->face->glyph,FT_RENDER_MODE_MONO);
+           if( ftrc != 0 ) return FTtoXReturnCode(ftrc);
+           is_outline = 1;
+       }
+       }
+       else{
+           is_outline=0;
+       }
+    }
+
+    /* Spacial case */
+    if( (instance->ttcap.flags & TTCAP_MONO_CENTER) && hasMetrics ) {
+       if( is_outline == 1 ){
+           if( correct ){
+               if( ft_get_very_lazy_bbox( idx, face->face, instance->size, 
+                                          face->num_hmetrics,
+                                          instance->ttcap.vl_slant,
+                                          &instance->transformation.matrix,
+                                          &bbox, &outline_hori_advance, 
+                                          &outline_vert_advance ) != 0 ){
+                   is_outline = -1;    /* <- error */
+               }
+           }
+           else {
+#ifdef USE_GET_CBOX
+               FT_Outline_Get_CBox(&face->face->glyph->outline, &bbox);
+               ftrc=0;
+#else
+               ftrc=FT_Outline_Get_BBox(&face->face->glyph->outline, &bbox);
+#endif
+               if( ftrc != 0 ) return FTtoXReturnCode(ftrc);
+           }
+           bbox_center_raw = (double)(bbox.xMax + bbox.xMin)/2.0/64.;
+       }
+       else if( is_outline == 0 )
+           bbox_center_raw = (2.0 * metrics->horiBearingX + metrics->width)/2.0/64.0;
+       else
+           bbox_center_raw = 0;
+       b_shift = (int)floor((instance->advance/2.0-bbox_center_raw) + .5);
+    }
+
+    wd_actual = tgp->metrics.rightSideBearing - tgp->metrics.leftSideBearing;
+    ht_actual = tgp->metrics.ascent + tgp->metrics.descent;
+
+    /* The X convention is to consider a character with an empty
+     * bounding box as undefined.  This convention is broken. */
+
+    if(wd_actual <= 0) wd = 1;
+    else wd=wd_actual;
+    if(ht_actual <= 0) ht = 1;
+    else ht=ht_actual;
+
+    bpr = (((wd + (instance->bmfmt.glyph<<3) - 1) >> 3) & 
+           -instance->bmfmt.glyph);
+    raster = calloc(1, ht * bpr);
+    if(raster == NULL) 
+       return AllocError;
+
+    tgp->bits = raster;
+
+    /* If FT_GET_DUMMY is set, we return white space. */
+    if ( is_outline == -1 ) return Successful;
+
+    if ( wd_actual <= 0 || ht_actual <= 0 ) return Successful;
+
+    /*
+     * CALCULATE OFFSET, dx AND dy.
+     */
+
+    dx = face->face->glyph->bitmap_left - tgp->metrics.leftSideBearing;
+    dy = tgp->metrics.ascent - face->face->glyph->bitmap_top;
+
+    if(instance->ttcap.flags & TTCAP_MONO_CENTER)
+       dx += b_shift;
+
+    /* To prevent chipped bitmap, we correct dx and dy if needed. */
+    if( correct && is_outline==1 ){
+       int lsb, rsb, asc, des;
+       int chip_left,chip_right,chip_top,chip_bot;
+#ifdef USE_GET_CBOX
+       FT_Outline_Get_CBox(&face->face->glyph->outline, &bbox);
+       ftrc=0;
+#else
+       ftrc=FT_Outline_Get_BBox(&face->face->glyph->outline, &bbox);
+#endif
+       if( ftrc != 0 ) return FTtoXReturnCode(ftrc);
+       des = CEIL64(-bbox.yMin - 32) / 64;
+       lsb = FLOOR64(bbox.xMin + 32) / 64;
+       asc = FLOOR64(bbox.yMax + 32) / 64;
+       rsb = FLOOR64(bbox.xMax + 32) / 64;
+       rightSideBearing = tgp->metrics.rightSideBearing;
+       leftSideBearing  = tgp->metrics.leftSideBearing;
+       if( instance->ttcap.flags & TTCAP_DOUBLE_STRIKE )
+           rightSideBearing -= instance->ttcap.doubleStrikeShift;
+       /* special case */
+       if(instance->ttcap.flags & TTCAP_MONO_CENTER){
+           leftSideBearing  -= b_shift;
+           rightSideBearing -= b_shift;
+       }
+       chip_left  = lsb - leftSideBearing;
+       chip_right = rightSideBearing - rsb;
+       if( flags & FT_FORCE_CONSTANT_SPACING ){
+           if( instance->ttcap.force_c_adjust_lsb_by_pixel != 0 ||
+               instance->ttcap.force_c_adjust_rsb_by_pixel != 0 ){
+               chip_left=0;
+               chip_right=0;
+           }
+       }
+       else{
+           if( instance->ttcap.adjustRightSideBearingByPixel != 0 ||
+               instance->ttcap.adjustLeftSideBearingByPixel != 0 ){
+               chip_left=0;
+               chip_right=0;
+           }
+       }
+       chip_top   = tgp->metrics.ascent - asc;
+       chip_bot   = tgp->metrics.descent - des;
+       if( chip_left < 0 && 0 < chip_right ) dx++;
+       else if( chip_right < 0 && 0 < chip_left ) dx--;
+       if( chip_top < 0 && 0 < chip_bot ) dy++;
+       else if( chip_bot < 0 && 0 < chip_top ) dy--;
+    }
+
+    /*
+     * COPY RASTER
+     */
+
+    {
+       FT_Bitmap *bitmap;
+       int i, j;
+       unsigned char *current_raster;
+       unsigned char *current_buffer;
+       int mod_dx0,mod_dx1;
+       int div_dx;
+       bitmap = &face->face->glyph->bitmap;
+       if( 0 <= dx ){
+           div_dx = dx / 8;
+           mod_dx0 = dx % 8;
+           mod_dx1 = 8-mod_dx0;
+       }
+       else{
+           div_dx = dx / 8 -1;
+           mod_dx1 = -dx % 8;
+           mod_dx0 = 8-mod_dx1;
+       }
+       for( i = MAX(0, dy) ; i<ht ; i++ ){
+           int prev_jj,jj;
+           if( bitmap->rows <= i-dy ) break;
+           current_buffer=(unsigned char *)(bitmap->buffer+bitmap->pitch*(i-dy));
+           current_raster=(unsigned char *)(raster+i*bpr);
+           j       = MAX(0,div_dx);
+           jj      = j-div_dx;
+           prev_jj = jj-1;
+           if( j<bpr ){
+               if( 0 <= prev_jj && prev_jj < bitmap->pitch )
+                   current_raster[j]|=current_buffer[prev_jj]<<mod_dx1;
+               if( 0 <= jj && jj < bitmap->pitch ){
+                   current_raster[j]|=current_buffer[jj]>>mod_dx0;
+                   j++; prev_jj++; jj++;
+                   for( ; j<bpr ; j++,prev_jj++,jj++ ){
+                       current_raster[j]|=current_buffer[prev_jj]<<mod_dx1;
+                       if( bitmap->pitch <= jj ) break;
+                       current_raster[j]|=current_buffer[jj]>>mod_dx0;
+                   }
+               }
+           }
+       }
+    }
+
+    /* by TTCap */
+    if ( instance->ttcap.flags & TTCAP_DOUBLE_STRIKE ) {
+       int i;
+       for( i=0 ; i < instance->ttcap.doubleStrikeShift ; i++ )
+           ft_make_up_bold_bitmap( raster, bpr, ht, instance->ttcap.flags);
+    }
+    if ( is_outline == 0 &&
+        ( instance->ttcap.lsbShiftOfBitmapAutoItalic != 0 ||
+          instance->ttcap.rsbShiftOfBitmapAutoItalic != 0 ) ) {
+       ft_make_up_italic_bitmap( raster, bpr, ht, 
+                                 - instance->ttcap.lsbShiftOfBitmapAutoItalic
+                                 + instance->ttcap.rsbShiftOfBitmapAutoItalic,
+                                 instance->charcellMetrics->ascent
+                                 + instance->charcellMetrics->descent,
+                                 instance->charcellMetrics->ascent
+                                 - tgp->metrics.ascent,
+                                 instance->ttcap.autoItalic);
+    }
+    
+    if(instance->bmfmt.bit == LSBFirst) {
+        BitOrderInvert((unsigned char*)(tgp->bits), ht*bpr);
+    }
+    
+    if(instance->bmfmt.byte != instance->bmfmt.bit) {
+        switch(instance->bmfmt.scan) {
+        case 1:
+            break;
+        case 2:
+            TwoByteSwap((unsigned char*)(tgp->bits), ht*bpr);
+            break;
+        case 4:
+            FourByteSwap((unsigned char*)(tgp->bits), ht*bpr);
+            break;
+        default:
+            ;
+        }
+    }
+
+    return Successful;
+}
+
+static void
+FreeTypeFreeFont(FTFontPtr font)
+{
+    FreeTypeFreeInstance(font->instance);
+    if(font->ranges)
+        free(font->ranges);
+    if(font->dummy_char.bits)
+       free(font->dummy_char.bits);
+    free(font);
+}
+
+/* Free a font.  If freeProps is 0, don't free the properties. */
+
+static void
+FreeTypeFreeXFont(FontPtr pFont, int freeProps)
+{
+    FTFontPtr tf;
+    
+    if(pFont) {
+        if((tf = (FTFontPtr)pFont->fontPrivate)) {
+            FreeTypeFreeFont(tf);
+        }
+        if(freeProps && pFont->info.nprops>0) {
+            free(pFont->info.isStringProp);
+            free(pFont->info.props);
+        }
+        DestroyFontRec(pFont);
+    }
+}
+
+
+/* Unload a font */
+
+static void
+FreeTypeUnloadXFont(FontPtr pFont)
+{
+    MUMBLE("Unloading\n");
+    FreeTypeFreeXFont(pFont, 1);
+}
+
+/* Add the font properties, including the Font name, the XLFD
+   properties, some strings from the font, and various typographical
+   data.  We only provide data readily available in the tables in the
+   font for now, altough FIGURE_WIDTH would be a good idea as it is
+   used by Xaw. */
+
+static int
+FreeTypeAddProperties(FTFontPtr font, FontScalablePtr vals, FontInfoPtr info, 
+                      char *fontname, int rawAverageWidth, Bool font_properties)
+{
+    int i, j, maxprops;
+    char *sp, *ep, val[MAXFONTNAMELEN], *vp;
+    FTFacePtr face;
+    FTInstancePtr instance;
+    FTNormalisedTransformationPtr trans;
+    int upm;
+    TT_OS2 *os2;
+    TT_Postscript *post;
+    PS_FontInfoRec t1info_rec, *t1info;
+    int xlfdProps = 0;
+    int ftrc;
+
+    instance = font->instance;
+    face = instance->face;
+    trans = &instance->transformation;
+    upm = face->face->units_per_EM;
+    if(upm == 0) {
+        /* Work around FreeType bug */
+        upm = WORK_AROUND_UPM;
+    }
+
+    os2 = FT_Get_Sfnt_Table(face->face, ft_sfnt_os2);
+    post = FT_Get_Sfnt_Table(face->face, ft_sfnt_post);
+    ftrc = FT_Get_PS_Font_Info(face->face, &t1info_rec);
+    if(ftrc == 0)
+        t1info = &t1info_rec;
+    else
+        t1info = NULL;
+
+    if(t1info) {
+        os2 = NULL;
+        post = NULL;
+    }
+
+    info->nprops = 0;           /* in case we abort */
+  
+    strcpy(val, fontname);
+    if(FontParseXLFDName(val, vals, FONT_XLFD_REPLACE_VALUE)) {
+        xlfdProps = 1;
+    } else {
+        MUMBLE("Couldn't parse XLFD\n");
+        xlfdProps = 0;
+    }
+
+    maxprops=
+        1 +                     /* NAME */
+        (xlfdProps ? 14 : 0) +  /* from XLFD */
+        5 +
+        ( !face->bitmap ? 3 : 0 ) +    /* raw_av,raw_asc,raw_dec */
+        ( font_properties ? 2 : 0 ) +  /* asc,dec */
+        ( (font_properties && os2) ? 6 : 0 ) +
+        ( (font_properties && (post || t1info)) ? 3 : 0 ) +
+        2;                      /* type */
+    
+    info->props = malloc(maxprops * sizeof(FontPropRec));
+    if(info->props == NULL)
+        return AllocError;
+    
+    info->isStringProp = malloc(maxprops);
+    if(info->isStringProp == NULL) {
+        free(info->props);
+        return AllocError;
+    }
+
+    memset((char *)info->isStringProp, 0, maxprops);
+
+    i = 0;
+
+    info->props[i].name = MakeAtom("FONT", 4, TRUE);
+    info->props[i].value = MakeAtom(val, strlen(val), TRUE);
+    info->isStringProp[i] = 1;
+    i++;
+
+    if(*val && *(sp = val + 1)) {
+        for (j = 0, sp = val + 1; j < 14; j++) {
+            if (j == 13)
+                /* Handle the case of the final field containing a subset
+                   specification. */
+                for (ep = sp; *ep && *ep != '['; ep++);
+            else
+                for (ep = sp; *ep && *ep != '-'; ep++);
+            
+            info->props[i].name =
+                MakeAtom(xlfd_props[j], strlen(xlfd_props[j]), TRUE);
+            
+            switch(j) {
+            case 6:                   /* pixel size */
+                info->props[i].value = 
+                    (int)(fabs(vals->pixel_matrix[3]) + 0.5);
+                i++;
+                break;
+            case 7:                   /* point size */
+                info->props[i].value = 
+                    (int)(fabs(vals->point_matrix[3])*10.0 + 0.5);
+                i++;
+                break;
+            case 8:                   /* resolution x */
+                info->props[i].value = vals->x;
+                i++;
+                break;
+            case 9:                   /* resolution y */
+                info->props[i].value = vals->y;
+                i++;
+                break;
+            case 11:                  /* average width */
+                info->props[i].value = vals->width;
+                i++;
+                break;
+            default:                  /* a string */
+                info->props[i].value = MakeAtom(sp, ep - sp, TRUE);
+                info->isStringProp[i] = 1;
+                i++;
+            }
+            sp = ++ep;
+        }
+    }
+
+    info->props[i].name = MakeAtom("RAW_PIXEL_SIZE", 14, TRUE);
+    info->props[i].value = 1000;
+    i++;
+
+    info->props[i].name = MakeAtom("RAW_POINT_SIZE", 14, TRUE);
+    info->props[i].value = (long)(72270.0 / (double)vals->y + .5);
+    i++;
+
+    if(!face->bitmap) {
+        info->props[i].name = MakeAtom("RAW_AVERAGE_WIDTH", 17, TRUE);
+        info->props[i].value = rawAverageWidth;
+        i++;
+    }
+
+    if ( font_properties ) {
+       info->props[i].name = MakeAtom("FONT_ASCENT", 11, TRUE);
+       info->props[i].value = info->fontAscent;
+       i++;
+    }
+
+    if(!face->bitmap) {
+        info->props[i].name = MakeAtom("RAW_ASCENT", 10, TRUE);
+        info->props[i].value = 
+            ((double)face->face->ascender/(double)upm*1000.0);
+        i++;
+    }
+
+    if ( font_properties ) {
+       info->props[i].name = MakeAtom("FONT_DESCENT", 12, TRUE);
+       info->props[i].value = info->fontDescent;
+       i++;
+    }
+
+    if(!face->bitmap) {
+        info->props[i].name = MakeAtom("RAW_DESCENT", 11, TRUE);
+        info->props[i].value = 
+            -((double)face->face->descender/(double)upm*1000.0);
+        i++;
+    }
+
+    j = FTGetEnglishName(face->face, TT_NAME_ID_COPYRIGHT,
+                         val, MAXFONTNAMELEN);
+    vp = val;
+    if (j < 0) {
+        if(t1info && t1info->notice) {
+            vp = t1info->notice;
+            j = strlen(vp);
+        }
+    }
+    if(j > 0) {
+        info->props[i].name = MakeAtom("COPYRIGHT", 9, TRUE);
+        info->props[i].value = MakeAtom(vp, j, TRUE);
+        info->isStringProp[i] = 1;
+        i++;
+    }
+    
+    j = FTGetEnglishName(face->face, TT_NAME_ID_FULL_NAME,
+                         val, MAXFONTNAMELEN);
+    vp = val;
+    if (j < 0) {
+        if(t1info && t1info->full_name) {
+            vp = t1info->full_name;
+            j = strlen(vp);
+        }
+    }
+    if(j > 0) {
+        info->props[i].name = MakeAtom("FACE_NAME", 9, TRUE);
+        info->props[i].value = MakeAtom(vp, j, TRUE);
+        info->isStringProp[i] = 1;
+        i++;
+    }
+
+    vp = (char *)FT_Get_Postscript_Name(face->face);
+    if (vp) {
+       j = strlen(vp);
+    } else {
+       j = -1;
+    }
+    if (j < 0) {
+       j = FTGetEnglishName(face->face, TT_NAME_ID_PS_NAME,
+                         val, MAXFONTNAMELEN);
+       vp = val;
+    }
+    if (j < 0) {
+        if(t1info && t1info->full_name) {
+            vp = t1info->full_name;
+            j = strlen(vp);
+        }
+    }
+    if(j > 0) {
+        info->props[i].name = MakeAtom("_ADOBE_POSTSCRIPT_FONTNAME", 26, TRUE);
+        info->props[i].value = MakeAtom(vp, j, TRUE);
+        info->isStringProp[i] = 1;
+        i++;
+    }
+
+  /* These macros handle the case of a diagonal matrix.  They convert
+     FUnits into pixels. */
+#define TRANSFORM_FUNITS_X(xval) \
+  ((int) \
+   floor( ((double)(xval)/(double)upm) * (double)vals->pixel_matrix[0] + 0.5 ) )
+
+#define TRANSFORM_FUNITS_Y(yval) \
+  ((int) \
+   floor( ((double)(yval)/(double)upm) * (double)vals->pixel_matrix[3] + 0.5 ) )
+
+  /* In what follows, we assume the matrix is diagonal.  In the rare
+     case when it is not, the values will be somewhat wrong. */
+  
+    if( font_properties && os2 ) {
+        info->props[i].name = MakeAtom("SUBSCRIPT_SIZE",14,TRUE);
+        info->props[i].value = 
+            TRANSFORM_FUNITS_Y(os2->ySubscriptYSize);
+        i++;
+        info->props[i].name = MakeAtom("SUBSCRIPT_X",11,TRUE);
+        info->props[i].value = 
+            TRANSFORM_FUNITS_X(os2->ySubscriptXOffset);
+        i++;
+        info->props[i].name = MakeAtom("SUBSCRIPT_Y",11,TRUE);
+        info->props[i].value = 
+            TRANSFORM_FUNITS_Y(os2->ySubscriptYOffset);
+        i++;
+        info->props[i].name = MakeAtom("SUPERSCRIPT_SIZE",16,TRUE);
+        info->props[i].value = 
+            TRANSFORM_FUNITS_Y(os2->ySuperscriptYSize);
+        i++;
+        info->props[i].name = MakeAtom("SUPERSCRIPT_X",13,TRUE);
+        info->props[i].value = 
+            TRANSFORM_FUNITS_X(os2->ySuperscriptXOffset);
+        i++;
+        info->props[i].name = MakeAtom("SUPERSCRIPT_Y",13,TRUE);
+        info->props[i].value = 
+        TRANSFORM_FUNITS_Y(os2->ySuperscriptYOffset);
+        i++;
+    }
+
+    if( font_properties && (post || t1info) ) {
+        int underlinePosition, underlineThickness;
+
+       /* Raw underlineposition counts upwards, 
+          but UNDERLINE_POSITION counts downwards. */
+        if(post) {
+            underlinePosition = TRANSFORM_FUNITS_Y(-post->underlinePosition);
+            underlineThickness = TRANSFORM_FUNITS_Y(post->underlineThickness);
+        } else {
+            underlinePosition = 
+                TRANSFORM_FUNITS_Y(-t1info->underline_position);
+            underlineThickness = 
+                TRANSFORM_FUNITS_Y(t1info->underline_thickness);
+        }
+        if(underlineThickness <= 0)
+            underlineThickness = 1;
+
+        info->props[i].name = MakeAtom("UNDERLINE_THICKNESS",19,TRUE);
+        info->props[i].value = underlineThickness;
+        i++;
+
+        info->props[i].name = MakeAtom("UNDERLINE_POSITION",18,TRUE);
+
+        info->props[i].value = underlinePosition;
+
+        i++;
+
+        /* The italic angle is often unreliable for Type 1 fonts */
+        if(post && trans->matrix.xx == trans->matrix.yy) {
+            info->props[i].name = MakeAtom("ITALIC_ANGLE",12,TRUE);
+            info->props[i].value = 
+                /* Convert from TT_Fixed to 
+                   64th of a degree counterclockwise from 3 o'clock */
+                90*64+(post->italicAngle >> 10);
+            i++;
+        }
+#undef TRANSFORM_FUNITS_X
+#undef TRANSFORM_FUNITS_Y
+    }
+
+    info->props[i].name  = MakeAtom("FONT_TYPE", 9, TRUE);
+    vp = (char *)FT_Get_X11_Font_Format(face->face);
+    info->props[i].value = MakeAtom(vp, strlen(vp), TRUE);
+    info->isStringProp[i] = 1;
+    i++;
+    
+    info->props[i].name  = MakeAtom("RASTERIZER_NAME", 15, TRUE);
+    info->props[i].value = MakeAtom("FreeType", 10, TRUE);
+    info->isStringProp[i] = 1;
+    i++;
+    
+    info->nprops = i;
+    return Successful;
+}
+
+static int
+ft_get_index(unsigned code, FTFontPtr font, unsigned *idx)
+{
+    
+    /* As a special case, we pass 0 even when it is not in the ranges;
+       this will allow for the default glyph, which should exist in any
+       TrueType font. */
+    
+    /* This is not required...
+    if(code > 0 && font->nranges) {
+        int i;
+        for(i = 0; i < font->nranges; i++)
+            if((code >= 
+                font->ranges[i].min_char_low+
+                (font->ranges[i].min_char_high<<8)) &&
+               (code <=
+                font->ranges[i].max_char_low + 
+                (font->ranges[i].max_char_high<<8)))
+                break;
+        if(i == font->nranges) {
+           *idx = font->zero_idx;
+            return -1;
+        }
+    }
+    */
+    if( font->info ) {
+       if( !( font->info->firstCol <= (code & 0x000ff) &&
+              (code & 0x000ff) <= font->info->lastCol &&
+              font->info->firstRow <= (code >> 8) &&
+              (code >> 8) <= font->info->lastRow ) ) {
+           *idx = font->zero_idx;
+           /* Error: The code has not been parsed in ft_compute_bounds()!
+              We should not return any metrics. */
+           return -1;
+       }
+    }
+
+    *idx = FTRemap(font->instance->face->face, &font->mapping, code);
+    
+    return 0;
+}
+
+static int
+FreeTypeFontGetGlyph(unsigned code, int flags, CharInfoPtr *g, FTFontPtr font)
+{
+    unsigned idx = 0;
+    int xrc;
+    
+#ifdef X_ACCEPTS_NO_SUCH_CHAR
+    if( ft_get_index(code,font,&idx) || idx == 0 || idx == font->zero_idx ) {
+       *g = NULL;
+       flags &= ~FT_FORCE_CONSTANT_SPACING;
+       /* if( font->instance->spacing != FT_CHARCELL ) */
+       return Successful;
+    }
+#else
+    if( ft_get_index(code,font,&idx) ) {
+       /* The code has not been parsed! */
+       *g = NULL;
+       flags &= ~FT_FORCE_CONSTANT_SPACING;
+    }
+#endif
+
+    xrc = FreeTypeInstanceGetGlyph(idx, flags, g, font->instance);
+    if( xrc == Successful && *g != NULL )
+       return Successful;
+    if( font->zero_idx != idx ) {
+       xrc = FreeTypeInstanceGetGlyph(font->zero_idx, flags, g, font->instance);
+       if( xrc == Successful && *g != NULL )
+           return Successful;
+    }
+    return FreeTypeInstanceGetGlyph(font->zero_idx, flags|FT_GET_DUMMY, g, font->instance);
+}
+
+static int
+FreeTypeFontGetGlyphMetrics(unsigned code, int flags, xCharInfo **metrics, FTFontPtr font)
+{
+    unsigned idx = 0;
+    int xrc;
+
+#ifdef X_ACCEPTS_NO_SUCH_CHAR
+    if ( ft_get_index(code,font,&idx) || idx == 0 || idx == font->zero_idx ) {
+       *metrics = NULL;
+       flags &= ~FT_FORCE_CONSTANT_SPACING;
+       /* if( font->instance->spacing != FT_CHARCELL ) */
+       return Successful;
+    }
+#else
+    if ( ft_get_index(code,font,&idx) || idx == 0 || idx == font->zero_idx ) {
+       /* The code has not been parsed! */
+       *metrics = NULL;
+       flags &= ~FT_FORCE_CONSTANT_SPACING;
+    }
+#endif
+
+    xrc = FreeTypeInstanceGetGlyphMetrics(idx, flags, metrics, font->instance);
+    if( xrc == Successful && *metrics != NULL )
+       return Successful;
+    if( font->zero_idx != idx ) {
+       xrc = FreeTypeInstanceGetGlyphMetrics(font->zero_idx, flags, 
+                                             metrics, font->instance);
+       if( xrc == Successful && *metrics != NULL )
+           return Successful;
+    }
+    return FreeTypeInstanceGetGlyphMetrics(font->zero_idx, flags|FT_GET_DUMMY, metrics, font->instance);
+}
+
+/*
+ * restrict code range
+ *
+ * boolean for the numeric zone:
+ *   results = results & (ranges[0] | ranges[1] | ... ranges[nranges-1])
+ */
+
+static void
+restrict_code_range(unsigned short *refFirstCol,
+                    unsigned short *refFirstRow,
+                    unsigned short *refLastCol,
+                    unsigned short *refLastRow,
+                    fsRange const *ranges, int nRanges)
+{
+    if (nRanges) {
+        int minCol = 256, minRow = 256, maxCol = -1, maxRow = -1;
+        fsRange const *r = ranges;
+        int i;
+
+        for (i=0; i<nRanges; i++) {
+            if (r->min_char_high != r->max_char_high) {
+                minCol = 0x00;
+                maxCol = 0xff;
+            } else {
+                if (minCol > r->min_char_low)
+                    minCol = r->min_char_low;
+                if (maxCol < r->max_char_low)
+                    maxCol = r->max_char_low;
+            }
+            if (minRow > r->min_char_high)
+                minRow = r->min_char_high;
+            if (maxRow < r->max_char_high)
+                maxRow = r->max_char_high;
+            r++;
+        }
+
+        if (minCol > *refLastCol)
+            *refFirstCol = *refLastCol;
+        else if (minCol > *refFirstCol)
+            *refFirstCol = minCol;
+
+        if (maxCol < *refFirstCol)
+            *refLastCol = *refFirstCol;
+        else if (maxCol < *refLastCol)
+            *refLastCol = maxCol;
+
+        if (minRow > *refLastRow) {
+            *refFirstRow = *refLastRow;
+            *refFirstCol = *refLastCol;
+        } else if (minRow > *refFirstRow)
+            *refFirstRow = minRow;
+
+        if (maxRow < *refFirstRow) {
+            *refLastRow = *refFirstRow;
+            *refLastCol = *refFirstCol;
+        } else if (maxRow < *refLastRow)
+            *refLastRow = maxRow;
+    }
+}
+
+
+static int
+restrict_code_range_by_str(int count,unsigned short *refFirstCol,
+                          unsigned short *refFirstRow,
+                          unsigned short *refLastCol,
+                          unsigned short *refLastRow,
+                          char const *str)
+{
+    int nRanges = 0;
+    int result = 0;
+    fsRange *ranges = NULL;
+    char const *p, *q;
+
+    p = q = str;
+    for (;;) {
+        int minpoint=0, maxpoint=65535;
+        long val;
+
+        /* skip comma and/or space */
+        while (',' == *p || isspace(*p))
+            p++;
+
+        /* begin point */
+        if ('-' != *p) {
+            val = strtol(p, (char **)&q, 0);
+            if (p == q)
+                /* end or illegal */
+                break;
+            if (val<0 || val>65535) {
+                /* out of zone */
+                break;
+            }
+            minpoint = val;
+            p=q;
+        }
+
+        /* skip space */
+        while (isspace(*p))
+            p++;
+
+        if (',' != *p && '\0' != *p) {
+            /* contiune */
+            if ('-' == *p)
+                /* hyphon */
+                p++;
+            else
+                /* end or illegal */
+                break;
+
+            /* skip space */
+            while (isspace(*p))
+                p++;
+
+            val = strtol(p, (char **)&q, 0);
+            if (p != q) {
+                if (val<0 || val>65535)
+                    break;
+                maxpoint = val;
+            } else if (',' != *p && '\0' != *p)
+                /* end or illegal */
+                break;
+            p=q;
+        } else
+            /* comma - single code */
+            maxpoint = minpoint;
+
+        if ( count <= 0 && minpoint>maxpoint ) {
+            int tmp;
+            tmp = minpoint;
+            minpoint = maxpoint;
+            maxpoint = tmp;
+        }
+
+        /* add range */
+#if 0
+        fprintf(stderr, "zone: 0x%04X - 0x%04X\n", minpoint, maxpoint);
+        fflush(stderr);
+#endif
+        nRanges++;
+        ranges = realloc(ranges, nRanges*sizeof(*ranges));
+        if (NULL == ranges)
+            break;
+        {
+            fsRange *r = ranges+nRanges-1;
+
+            r->min_char_low = minpoint & 0xff;
+            r->max_char_low = maxpoint & 0xff;
+            r->min_char_high = (minpoint>>8) & 0xff;
+            r->max_char_high = (maxpoint>>8) & 0xff;
+        }
+    }
+
+    if (ranges) {
+        if ( count <= 0 ) {
+            restrict_code_range(refFirstCol, refFirstRow, refLastCol, refLastRow,
+                                ranges, nRanges);
+        }
+        else {
+            int i;
+            fsRange *r;
+            for ( i=0 ; i<nRanges ; i++ ) {
+                if ( count <= i ) break;
+                r = ranges+i;
+                refFirstCol[i] = r->min_char_low;
+                refLastCol[i] = r->max_char_low;
+                refFirstRow[i] = r->min_char_high;
+                refLastRow[i] = r->max_char_high;
+            }
+            result=i;
+        }
+        free(ranges);
+    }
+    return result;
+}
+
+/* *face_number and *spacing are initialized but *load_flags is NOT. */
+static int 
+FreeTypeSetUpTTCap( char *fileName, FontScalablePtr vals,
+                   char **dynStrRealFileName, char **dynStrFTFileName,
+                   struct TTCapInfo *ret, int *face_number, FT_Int32 *load_flags,
+                   int *spacing, Bool *font_properties, char **dynStrTTCapCodeRange )
+{
+    int result = Successful;
+    SDynPropRecValList listPropRecVal;
+    SPropRecValContainer contRecValue;
+    Bool hinting=True;
+    Bool isEmbeddedBitmap = True;
+    Bool alwaysEmbeddedBitmap = False;
+    int pixel = vals->pixel;
+
+    *font_properties=True;
+    *dynStrRealFileName=NULL;
+    *dynStrFTFileName=NULL;
+    *dynStrTTCapCodeRange=NULL;
+
+    if (SPropRecValList_new(&listPropRecVal)) {
+        return AllocError;
+    }
+
+    {
+        int len = strlen(fileName);
+        char *capHead = NULL;
+        {
+            /* font cap */
+            char *p1=NULL, *p2=NULL;
+           
+           p1=strrchr(fileName, '/');
+           if ( p1 == NULL ) p1 = fileName;
+           else p1++;
+           if (NULL != (p2=strrchr(p1, ':'))) {
+               /* colon exist in the right side of slash. */
+               int dirLen = p1-fileName;
+               int baseLen = fileName+len - p2 -1;
+               
+               *dynStrRealFileName = malloc(dirLen+baseLen+1);
+               if( *dynStrRealFileName == NULL ) {
+                   result = AllocError;
+                   goto quit;
+               }
+               if ( 0 < dirLen )
+                   memcpy(*dynStrRealFileName, fileName, dirLen);
+               strcpy(*dynStrRealFileName+dirLen, p2+1);
+               capHead = p1;
+           } else {
+               *dynStrRealFileName = xstrdup(fileName);
+               if( *dynStrRealFileName == NULL ) {
+                   result = AllocError;
+                   goto quit;
+               }
+           }
+        }
+
+       /* font cap */
+       if (capHead) {
+           if (SPropRecValList_add_by_font_cap(&listPropRecVal,
+                                               capHead)) {
+               result = BadFontPath;
+               goto quit;
+           }
+       }
+    }
+
+    *face_number=0;
+    *spacing=0;
+    ret->autoItalic=0.0;
+    ret->scaleWidth=1.0;
+    ret->scaleBBoxWidth = 1.0;
+    ret->scaleBBoxHeight = 1.0;
+    ret->doubleStrikeShift = 1;
+    ret->adjustBBoxWidthByPixel = 0;
+    ret->adjustLeftSideBearingByPixel = 0;
+    ret->adjustRightSideBearingByPixel = 0;
+    ret->flags = 0;
+    ret->scaleBitmap = 0.0;
+    ret->forceConstantSpacingBegin = -1;
+    ret->forceConstantSpacingEnd = -1;
+    ret->force_c_representative_metrics_char_code = -2;
+    ret->force_c_scale_b_box_width = 1.0;
+    ret->force_c_scale_b_box_height = 1.0;
+    ret->force_c_adjust_width_by_pixel = 0;
+    ret->force_c_adjust_lsb_by_pixel = 0;
+    ret->force_c_adjust_rsb_by_pixel = 0;
+    ret->force_c_scale_lsb = 0.0;
+    ret->force_c_scale_rsb = 1.0;
+    /* */
+    ret->vl_slant=0;
+    ret->lsbShiftOfBitmapAutoItalic=0;
+    ret->rsbShiftOfBitmapAutoItalic=0;
+    /* face number */
+    {
+       char *beginptr=NULL,*endptr;
+       if ( SPropRecValList_search_record(&listPropRecVal,
+                                       &contRecValue,
+                                       "FaceNumber")) {
+           int lv;
+           beginptr = SPropContainer_value_str(contRecValue);
+           lv=strtol(beginptr, &endptr, 10);
+           if ( *beginptr != '\0' && *endptr == '\0' ) {
+               if ( 0 < lv ) *face_number = lv;
+           }
+       }
+       if( beginptr && 0 < *face_number ) {
+           char *slash;
+           *dynStrFTFileName =         /* add ->  ':'+strlen0+':'+strlen1+'\0' */
+               malloc(1+strlen(beginptr)+1+strlen(*dynStrRealFileName)+1);
+           if( *dynStrFTFileName == NULL ){
+               result = AllocError;
+               goto quit;
+           }
+           **dynStrFTFileName = '\0';
+           slash = strrchr(*dynStrRealFileName,'/');
+           if( slash ) {
+               char *p;
+               strcat(*dynStrFTFileName,*dynStrRealFileName);
+               p = strrchr(*dynStrFTFileName,'/');
+               p[1] = '\0';
+               strcat(*dynStrFTFileName,":");
+               strcat(*dynStrFTFileName,beginptr);
+               strcat(*dynStrFTFileName,":");
+               strcat(*dynStrFTFileName,slash+1);
+           }
+           else{
+               strcat(*dynStrFTFileName,":");
+               strcat(*dynStrFTFileName,beginptr);
+               strcat(*dynStrFTFileName,":");
+               strcat(*dynStrFTFileName,*dynStrRealFileName);
+           }
+       }
+       else{
+           *dynStrFTFileName = malloc(strlen(*dynStrRealFileName)+1);
+           if( *dynStrFTFileName == NULL ){
+               result = AllocError;
+               goto quit;
+           }
+           **dynStrFTFileName = '\0';
+           strcat(*dynStrFTFileName,*dynStrRealFileName);
+       }
+    }
+    /*
+    fprintf(stderr,"[Filename:%s]\n",fileName);
+    fprintf(stderr,"[RealFilename:%s]\n",*dynStrRealFileName);
+    fprintf(stderr,"[FTFilename:%s]\n",*dynStrFTFileName);
+    */    
+    /* slant control */
+    if (SPropRecValList_search_record(&listPropRecVal,
+                                      &contRecValue,
+                                      "AutoItalic"))
+        ret->autoItalic = SPropContainer_value_dbl(contRecValue);
+    /* hinting control */
+    if (SPropRecValList_search_record(&listPropRecVal,
+                                      &contRecValue,
+                                      "Hinting"))
+        hinting = SPropContainer_value_bool(contRecValue);
+    /* scaling */
+    if (SPropRecValList_search_record(&listPropRecVal,
+                                      &contRecValue,
+                                      "ScaleWidth")) {
+        ret->scaleWidth = SPropContainer_value_dbl(contRecValue);
+        if (ret->scaleWidth<=0.0) {
+            fprintf(stderr, "ScaleWitdh needs plus.\n");
+           result = BadFontName;
+           goto quit;
+       }
+    }
+    /* bbox adjustment */
+    if (SPropRecValList_search_record(&listPropRecVal,
+                                      &contRecValue,
+                                      "ScaleBBoxWidth")) {
+        /* Scaling to Bounding Box Width */
+        int lv;
+        char *endptr,*beginptr;
+        double v,scaleBBoxWidth=1.0,scaleBBoxHeight=1.0;
+        beginptr = SPropContainer_value_str(contRecValue);
+        do {
+            if ( strlen(beginptr) < 1 ) break;
+            v=strtod(beginptr, &endptr);
+            if ( endptr!=beginptr ) {
+                scaleBBoxWidth = v;
+            }
+            if ( *endptr != ';' && *endptr != ',' ) break;
+           if ( *endptr == ',' ) {
+               beginptr=endptr+1;
+               v=strtod(beginptr, &endptr);
+               if ( endptr!=beginptr ) {
+                   scaleBBoxHeight = v;
+               }
+           }
+            if ( *endptr != ';' && *endptr != ',' ) break;
+            beginptr=endptr+1;
+            lv=strtol(beginptr, &endptr, 10);
+            if ( endptr!=beginptr ) {
+                ret->adjustBBoxWidthByPixel = lv;
+            }
+            if ( *endptr != ',' ) break;
+            beginptr=endptr+1;
+            lv=strtol(beginptr, &endptr, 10);
+            if ( endptr!=beginptr ) {
+                ret->adjustLeftSideBearingByPixel = lv;
+            }
+            if ( *endptr != ',' ) break;
+            beginptr=endptr+1;
+            lv=strtol(beginptr, &endptr, 10);
+            if ( endptr!=beginptr ) {
+                ret->adjustRightSideBearingByPixel = lv;
+            }
+        } while ( 0 );
+        if (scaleBBoxWidth<=0.0) {
+            fprintf(stderr, "ScaleBBoxWitdh needs plus.\n");
+           result = BadFontName;
+           goto quit;
+        }
+        if (scaleBBoxHeight<=0.0) {
+            fprintf(stderr, "ScaleBBoxHeight needs plus.\n");
+           result = BadFontName;
+           goto quit;
+        }
+        ret->scaleBBoxWidth  = scaleBBoxWidth;
+        ret->scaleBBoxHeight = scaleBBoxHeight;
+    }
+    /* spacing */
+    if (SPropRecValList_search_record(&listPropRecVal,
+                                     &contRecValue,
+                                     "ForceSpacing")) {
+       char *strSpace = SPropContainer_value_str(contRecValue);
+       Bool err = False;
+       if (1 != strlen(strSpace))
+           err = True;
+       else
+           switch (strSpace[0]) {
+           case 'M':
+               ret->flags |= TTCAP_MONO_CENTER;
+               *spacing = 'm';
+               break;
+           case 'm':
+           case 'p':
+           case 'c':
+               *spacing = strSpace[0];
+               break;
+           default:
+               err = True;
+           }
+       if (err) {
+           result = BadFontName;
+           goto quit;
+       }
+    }
+    /* doube striking */
+    if (SPropRecValList_search_record(&listPropRecVal,
+                                      &contRecValue,
+                                      "DoubleStrike")) {
+        /* Set or Reset Auto Bold Flag */
+        char *strDoubleStrike = SPropContainer_value_str(contRecValue);
+        Bool err = False;
+        if ( 0 < strlen(strDoubleStrike) ) {
+            switch (strDoubleStrike[0]) {
+            case 'm':
+            case 'M':
+            case 'l':
+            case 'L':
+                ret->flags |= TTCAP_DOUBLE_STRIKE;
+                ret->flags |= TTCAP_DOUBLE_STRIKE_MKBOLD_EDGE_LEFT;
+                break;
+            case 'y':
+            case 'Y':
+                ret->flags |= TTCAP_DOUBLE_STRIKE;
+                break;
+            case 'n':
+            case 'N':
+                ret->flags &= ~TTCAP_DOUBLE_STRIKE;
+                ret->flags &= ~TTCAP_DOUBLE_STRIKE_MKBOLD_EDGE_LEFT;
+                ret->flags &= ~TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH;
+                break;
+            default:
+                err = True;
+            }
+            if ( err != True ) {
+                if ( strDoubleStrike[1] ) {
+                    switch (strDoubleStrike[1]) {
+                    case 'b':
+                    case 'B':
+                    case 'p':
+                    case 'P':
+                    case 'y':
+                    case 'Y':
+                        ret->flags |= TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH;
+                        break;
+                    default:
+                        break;
+                    }
+                }
+                do {
+                    char *comma_ptr=strchr(strDoubleStrike,';');
+                    if ( !comma_ptr ) comma_ptr=strchr(strDoubleStrike,',');
+                    if ( !comma_ptr ) break;
+                   if ( comma_ptr[1] ) {
+                       char *endptr;
+                       int mkboldMaxPixel;
+                       mkboldMaxPixel=strtol(comma_ptr+1, &endptr, 10);
+                       if ( endptr != comma_ptr+1 && mkboldMaxPixel <= pixel ) {
+                           ret->flags &= ~TTCAP_DOUBLE_STRIKE_MKBOLD_EDGE_LEFT;
+                       }
+                   }
+                   comma_ptr=strchr(comma_ptr+1,',');
+                   if ( !comma_ptr ) break;
+                   if ( comma_ptr[1] ) {
+                       char *endptr;
+                       int max_pixel;
+                       max_pixel=strtol(comma_ptr+1, &endptr, 10);
+                       if ( endptr != comma_ptr+1 && max_pixel <= pixel ) {
+                         if( ret->flags & TTCAP_DOUBLE_STRIKE )
+                           ret->doubleStrikeShift += pixel / max_pixel;
+                       }
+                   }
+                } while(0);
+            }
+        }
+        else
+            err = True;
+        if (err) {
+            result = BadFontName;
+            goto quit;
+        }
+    }
+    /* very lazy metrics */
+    if (SPropRecValList_search_record(&listPropRecVal,
+                                      &contRecValue,
+                                      "VeryLazyMetrics")){
+       Bool isVeryLazy = SPropContainer_value_bool(contRecValue);
+       ret->flags |= TTCAP_DISABLE_DEFAULT_VERY_LAZY;
+       if( isVeryLazy == True )
+           ret->flags |= TTCAP_IS_VERY_LAZY;
+       else
+           ret->flags &= ~TTCAP_IS_VERY_LAZY;
+    }
+    /* embedded bitmap */
+    if (SPropRecValList_search_record(&listPropRecVal,
+                                      &contRecValue,
+                                      "EmbeddedBitmap")) {
+        char *strEmbeddedBitmap = SPropContainer_value_str(contRecValue);
+        Bool err = False;
+        if ( 1 == strlen(strEmbeddedBitmap) ) {
+            switch (strEmbeddedBitmap[0]) {
+            case 'y':
+            case 'Y':
+                isEmbeddedBitmap = True;
+                alwaysEmbeddedBitmap = True;
+                break;
+            case 'u':
+            case 'U':
+                isEmbeddedBitmap = True;
+                alwaysEmbeddedBitmap = False;
+                break;
+            case 'n':
+            case 'N':
+                isEmbeddedBitmap = False;
+                break;
+            default:
+                err = True;
+            }
+        }
+        else
+            err = True;
+        if (err) {
+            result = BadFontName;
+            goto quit;
+        }
+    }
+    /* scale bitmap */
+    if((ret->flags & TTCAP_IS_VERY_LAZY) &&
+       SPropRecValList_search_record(&listPropRecVal,
+                                     &contRecValue,
+                                     "VeryLazyBitmapWidthScale")) {
+        /* Scaling to Bitmap Bounding Box Width */
+        double scaleBitmapWidth = SPropContainer_value_dbl(contRecValue);
+
+       fprintf(stderr, "Warning: `bs' option is not required in X-TT version 2.\n");
+#if 0
+        if (scaleBitmapWidth<=0.0) {
+            fprintf(stderr, "ScaleBitmapWitdh needs plus.\n");
+            result = BadFontName;
+            goto quit;
+        }
+#endif
+        ret->scaleBitmap = scaleBitmapWidth;
+    }
+    /* restriction of the code range */
+    if (SPropRecValList_search_record(&listPropRecVal,
+                                     &contRecValue,
+                                     "CodeRange")) {
+       *dynStrTTCapCodeRange = xstrdup(SPropContainer_value_str(contRecValue));
+       if( *dynStrTTCapCodeRange == NULL ) {
+           result = AllocError;
+           goto quit;
+       }
+    }
+    /* forceConstantSpacing{Begin,End} */
+    if ( 1 /* ft->spacing == 'p' */ ){
+        unsigned short first_col=0,last_col=0x00ff;
+        unsigned short first_row=0,last_row=0x00ff;
+        if (SPropRecValList_search_record(&listPropRecVal,
+                                           &contRecValue,
+                                           "ForceConstantSpacingCodeRange")) {
+            if ( restrict_code_range_by_str(1,&first_col, &first_row,
+                                            &last_col, &last_row,
+                                            SPropContainer_value_str(contRecValue)) == 1 ) {
+              ret->forceConstantSpacingBegin = (int)( first_row<<8 | first_col );
+              ret->forceConstantSpacingEnd = (int)( last_row<<8 | last_col );
+             if ( ret->forceConstantSpacingBegin <= ret->forceConstantSpacingEnd )
+                 ret->flags &= ~TTCAP_FORCE_C_OUTSIDE;
+             else ret->flags |= TTCAP_FORCE_C_OUTSIDE;
+            }
+        }
+    }
+    /* */
+    if ( 1 ){
+        unsigned short first_col=0, last_col=0x0ff;
+        unsigned short first_row=0, last_row=0x0ff;
+        if ( SPropRecValList_search_record(&listPropRecVal,
+                                           &contRecValue,
+                                           "ForceConstantSpacingMetrics")) {
+            char *strMetrics;
+            strMetrics = SPropContainer_value_str(contRecValue);
+            if ( strMetrics ) {
+                char *comma_ptr,*period_ptr,*semic_ptr;
+                semic_ptr=strchr(strMetrics,';');
+                comma_ptr=strchr(strMetrics,',');
+                period_ptr=strchr(strMetrics,'.');
+                if ( semic_ptr && comma_ptr ) 
+                    if ( semic_ptr < comma_ptr ) comma_ptr=NULL;
+                if ( semic_ptr && period_ptr ) 
+                    if ( semic_ptr < period_ptr ) period_ptr=NULL;
+                if ( !comma_ptr && !period_ptr && strMetrics != semic_ptr ) {
+                    if ( restrict_code_range_by_str(1,&first_col, &first_row,
+                                                    &last_col, &last_row,
+                                                    SPropContainer_value_str(contRecValue)) == 1 ) {
+                      ret->force_c_representative_metrics_char_code = 
+                          (int)( first_row<<8 | first_col );
+                    }
+                }
+                else {
+                    double v;
+                    char *endptr,*beginptr=strMetrics;
+                    do {
+                        v=strtod(beginptr, &endptr);
+                        if ( endptr!=beginptr ) {
+                            ret->force_c_scale_b_box_width = v;
+                        }
+                        if ( *endptr != ',' ) break;
+                        beginptr=endptr+1;
+                        v=strtod(beginptr, &endptr);
+                        if ( endptr!=beginptr ) {
+                            ret->force_c_scale_lsb = v;
+                            ret->flags |= TTCAP_FORCE_C_LSB_FLAG;
+                        }
+                        if ( *endptr != ',' ) break;
+                        beginptr=endptr+1;
+                        v=strtod(beginptr, &endptr);
+                        if ( endptr!=beginptr ) {
+                            ret->force_c_scale_rsb = v;
+                            ret->flags |= TTCAP_FORCE_C_RSB_FLAG;
+                        }
+                        if ( *endptr != ',' ) break;
+                        beginptr=endptr+1;
+                        v=strtod(beginptr, &endptr);
+                        if ( endptr!=beginptr ) {
+                            ret->force_c_scale_b_box_height = v;
+                       }
+                    } while (0);
+                }
+                if ( semic_ptr ) {
+                    int lv;
+                    char *endptr,*beginptr=semic_ptr+1;
+                    do {
+                        lv=strtol(beginptr, &endptr, 10);
+                        if ( endptr!=beginptr ) {
+                            ret->force_c_adjust_width_by_pixel=lv;
+                        }
+                        if ( *endptr != ',' ) break;
+                        beginptr=endptr+1;
+                        lv=strtol(beginptr, &endptr, 10);
+                        if ( endptr!=beginptr ) {
+                            ret->force_c_adjust_lsb_by_pixel=lv;
+                        }
+                        if ( *endptr != ',' ) break;
+                        beginptr=endptr+1;
+                        lv=strtol(beginptr, &endptr, 10);
+                        if ( endptr!=beginptr ) {
+                            ret->force_c_adjust_rsb_by_pixel=lv;
+                        }
+                    } while (0);
+                }
+            }
+        }
+    }
+
+    if (SPropRecValList_search_record(&listPropRecVal,
+                                      &contRecValue,
+                                      "FontProperties")) {
+        /* Set or Reset the Flag of FontProperties */
+        *font_properties=SPropContainer_value_bool(contRecValue);
+    }
+
+    ret->force_c_scale_b_box_width *= ret->scaleBBoxWidth;
+    ret->force_c_scale_b_box_height *= ret->scaleBBoxHeight;
+
+    ret->force_c_scale_b_box_width *= ret->scaleWidth;
+    ret->scaleBBoxWidth            *= ret->scaleWidth;
+
+    ret->force_c_adjust_rsb_by_pixel += ret->adjustRightSideBearingByPixel;
+    ret->force_c_adjust_lsb_by_pixel += ret->adjustLeftSideBearingByPixel;
+
+    /* scaleWidth, scaleBBoxWidth, force_c_scale_b_box_width, force_c_scale_b_box_width */
+
+    /* by TTCap */
+    if( hinting == False ) *load_flags |= FT_LOAD_NO_HINTING;
+    if( isEmbeddedBitmap == False ) *load_flags |= FT_LOAD_NO_BITMAP;
+    if( ret->autoItalic != 0 && alwaysEmbeddedBitmap == False )
+       *load_flags |= FT_LOAD_NO_BITMAP;
+
+ quit:
+    return result;
+}
+
+static int
+ft_get_trans_from_vals( FontScalablePtr vals, FTNormalisedTransformationPtr trans )
+{
+    /* Compute the transformation matrix.  We use floating-point
+       arithmetic for simplicity */
+    
+    trans->xres = vals->x;
+    trans->yres = vals->y;
+    
+    /* This value cannot be 0. */
+    trans->scale = hypot(vals->point_matrix[2], vals->point_matrix[3]);
+    trans->nonIdentity = 0;
+    
+    /* Try to round stuff.  We want approximate zeros to be exact zeros,
+       and if the elements on the diagonal are approximately equal, we
+       want them equal.  We do this to avoid breaking hinting. */
+    if(DIFFER(vals->point_matrix[0], vals->point_matrix[3])) {
+        trans->nonIdentity = 1;
+        trans->matrix.xx =
+            (int)((vals->point_matrix[0]*(double)TWO_SIXTEENTH)/trans->scale);
+        trans->matrix.yy =
+            (int)((vals->point_matrix[3]*(double)TWO_SIXTEENTH)/trans->scale);
+    } else {
+        trans->matrix.xx = trans->matrix.yy =
+            ((vals->point_matrix[0] + vals->point_matrix[3])/2*
+             (double)TWO_SIXTEENTH)/trans->scale;
+    }
+    
+    if(DIFFER0(vals->point_matrix[1], trans->scale)) {
+        trans->matrix.yx =
+            (int)((vals->point_matrix[1]*(double)TWO_SIXTEENTH)/trans->scale);
+        trans->nonIdentity = 1;
+    } else
+        trans->matrix.yx = 0;
+    
+    if(DIFFER0(vals->point_matrix[2], trans->scale)) {
+        trans->matrix.xy =
+            (int)((vals->point_matrix[2]*(double)TWO_SIXTEENTH)/trans->scale);
+        trans->nonIdentity = 1;
+    } else
+        trans->matrix.xy=0;
+    return 0;
+}
+
+
+static int
+is_fixed_width(FT_Face face)
+{
+    PS_FontInfoRec t1info_rec;
+    int ftrc;
+
+    if(FT_IS_FIXED_WIDTH(face)) {
+        return 1;
+    }
+
+    ftrc = FT_Get_PS_Font_Info(face, &t1info_rec);
+    if(ftrc == 0 && t1info_rec.is_fixed_pitch) {
+        return 1;
+    }
+
+    return 0;
+}
+
+static int
+FreeTypeLoadFont(FTFontPtr font, FontInfoPtr info, FTFacePtr face,
+                char *FTFileName, FontScalablePtr vals, FontEntryPtr entry,
+                 FontBitmapFormatPtr bmfmt, FT_Int32 load_flags, 
+                struct TTCapInfo *tmp_ttcap, char *dynStrTTCapCodeRange,
+                int ttcap_spacing )
+{
+    int xrc;
+    FTNormalisedTransformationRec trans;
+    int spacing, actual_spacing, zero_code;
+    long  lastCode, firstCode;
+    TT_Postscript *post;
+
+    ft_get_trans_from_vals(vals,&trans);
+
+    /* Check for charcell in XLFD */
+    spacing = FT_PROPORTIONAL;
+    if(entry->name.ndashes == 14) {
+        char *p;
+        int dashes = 0;
+        for(p = entry->name.name; 
+            p <= entry->name.name + entry->name.length - 2;
+            p++) {
+            if(*p == '-') {
+                dashes++;
+                if(dashes == 11) {
+                    if(p[1]=='c' && p[2]=='-')
+                        spacing=FT_CHARCELL;
+                   else if(p[1]=='m' && p[2]=='-')
+                        spacing=FT_MONOSPACED;
+                    break;
+                }
+            }
+        }
+    }
+    /* by TTCap  */
+    if( ttcap_spacing != 0 ) {
+       if( ttcap_spacing == 'c' ) spacing=FT_CHARCELL;
+       else if( ttcap_spacing == 'm' ) spacing=FT_MONOSPACED;
+       else spacing=FT_PROPORTIONAL;
+    }
+
+    actual_spacing = spacing;
+    if( spacing == FT_PROPORTIONAL ) {
+       if( is_fixed_width(face->face) )
+           actual_spacing = FT_MONOSPACED;
+    }
+
+    if(entry->name.ndashes == 14) {
+        xrc = FTPickMapping(entry->name.name, entry->name.length, FTFileName,
+                           face->face, &font->mapping);
+       if (xrc != Successful)
+           return xrc;
+    } else {
+        xrc = FTPickMapping(0, 0, FTFileName, 
+                           face->face, &font->mapping);
+       if (xrc != Successful)
+           return xrc;
+    }
+    
+    font->nranges = vals->nranges;
+    font->ranges = 0;
+    if(font->nranges) {
+        font->ranges = malloc(vals->nranges*sizeof(fsRange));
+        if(font->ranges == NULL) 
+            return AllocError;
+        memcpy((char*)font->ranges, (char*)vals->ranges,
+               vals->nranges*sizeof(fsRange));
+    }
+
+    zero_code=-1;
+    if(info) {
+        firstCode = 0;
+        lastCode = 0xFFFFL;
+        if(!font->mapping.mapping || 
+           font->mapping.mapping->encoding->row_size == 0) {
+            /* linear indexing */
+            lastCode=MIN(lastCode,
+                         font->mapping.mapping ?
+                         font->mapping.mapping->encoding->size-1 :
+                         0xFF);
+            if(font->mapping.mapping && font->mapping.mapping->encoding->first)
+                firstCode = font->mapping.mapping->encoding->first;
+            info->firstRow = firstCode/0x100;
+            info->lastRow = lastCode/0x100;
+            info->firstCol =
+                (info->firstRow || info->lastRow) ? 0 : (firstCode & 0xFF);
+            info->lastCol = info->lastRow ? 0xFF : (lastCode & 0xFF);
+           if ( firstCode == 0 ) zero_code=0;
+        } else {
+            /* matrix indexing */
+            info->firstRow = font->mapping.mapping->encoding->first;
+            info->lastRow = MIN(font->mapping.mapping->encoding->size-1,
+                                lastCode/0x100);
+            info->firstCol = font->mapping.mapping->encoding->first_col;
+            info->lastCol = MIN(font->mapping.mapping->encoding->row_size-1, 
+                                lastCode<0x100?lastCode:0xFF);
+           if( info->firstRow == 0 && info->firstCol == 0 ) zero_code=0;
+        }
+
+        /* firstCode and lastCode are not valid in case of a matrix
+           encoding */
+
+       if( dynStrTTCapCodeRange ) {
+           restrict_code_range_by_str(0,&info->firstCol, &info->firstRow,
+                                      &info->lastCol, &info->lastRow,
+                                      dynStrTTCapCodeRange);
+       }
+       restrict_code_range(&info->firstCol, &info->firstRow,
+                           &info->lastCol, &info->lastRow,
+                           font->ranges, font->nranges);
+    }
+    font->info = info;
+
+    /* zero code is frequently used. */
+    if ( zero_code < 0 ) {
+       /* The fontenc should have the information of DefaultCh.
+          But we do not have such a information.
+          So we cannot but set 0. */
+       font->zero_idx = 0;
+    }
+    else
+       font->zero_idx = FTRemap(face->face, 
+                                &font->mapping, zero_code);
+
+    post = FT_Get_Sfnt_Table(face->face, ft_sfnt_post);
+
+#ifdef DEFAULT_VERY_LAZY
+    if( !( tmp_ttcap->flags & TTCAP_DISABLE_DEFAULT_VERY_LAZY ) )
+       if( DEFAULT_VERY_LAZY <= 1 + info->lastRow - info->firstRow ) {
+           if( post ){
+               tmp_ttcap->flags |= TTCAP_IS_VERY_LAZY;
+           }
+       }
+#endif
+    /* We should always reset. */
+    tmp_ttcap->flags &= ~TTCAP_DISABLE_DEFAULT_VERY_LAZY;
+
+    if ( face->bitmap || actual_spacing == FT_CHARCELL )
+       tmp_ttcap->flags &= ~TTCAP_IS_VERY_LAZY;
+    /* "vl=y" is available when TrueType or OpenType only */
+    if ( !face->bitmap && !(FT_IS_SFNT( face->face )) )
+       tmp_ttcap->flags &= ~TTCAP_IS_VERY_LAZY;
+
+    if( post ) {
+       if( post->italicAngle != 0 )
+           tmp_ttcap->vl_slant = -sin( (post->italicAngle/1024./5760.)*1.57079632679489661923 );
+       /* fprintf(stderr,"angle=%g(%g)\n",tmp_ttcap->vl_slant,(post->italicAngle/1024./5760.)*90); */
+    }
+
+    xrc = FreeTypeOpenInstance(&font->instance, face,
+                               FTFileName, &trans, actual_spacing, bmfmt,
+                              tmp_ttcap, load_flags );
+    return xrc;
+}
+
+static void
+adjust_min_max(xCharInfo *minc, xCharInfo *maxc, xCharInfo *tmp)
+{
+#define MINMAX(field,ci) \
+    if (minc->field > (ci)->field) \
+    minc->field = (ci)->field; \
+    if (maxc->field < (ci)->field) \
+    maxc->field = (ci)->field;
+
+    MINMAX(ascent, tmp);
+    MINMAX(descent, tmp);
+    MINMAX(leftSideBearing, tmp);
+    MINMAX(rightSideBearing, tmp);
+    MINMAX(characterWidth, tmp);
+
+    if ((INT16)minc->attributes > (INT16)tmp->attributes)
+        minc->attributes = tmp->attributes;
+    if ((INT16)maxc->attributes < (INT16)tmp->attributes)
+        maxc->attributes = tmp->attributes;
+#undef  MINMAX
+}
+
+static void
+ft_compute_bounds(FTFontPtr font, FontInfoPtr pinfo, FontScalablePtr vals )
+{
+    FTInstancePtr instance;
+    int row, col;
+    unsigned int c;
+    xCharInfo minchar, maxchar, *tmpchar = NULL;
+    int overlap, maxOverlap;
+    long swidth      = 0;
+    long total_width = 0;
+    int num_cols, num_chars = 0;
+    int flags, skip_ok = 0;
+    int force_c_outside ;
+
+    instance = font->instance;
+    force_c_outside = instance->ttcap.flags & TTCAP_FORCE_C_OUTSIDE;
+
+    minchar.ascent = minchar.descent =
+    minchar.leftSideBearing = minchar.rightSideBearing =
+    minchar.characterWidth = minchar.attributes = 32767;
+    maxchar.ascent = maxchar.descent =
+    maxchar.leftSideBearing = maxchar.rightSideBearing =
+    maxchar.characterWidth = maxchar.attributes = -32767;
+    maxOverlap = -32767;
+
+    /* Parse all glyphs */
+    num_cols = 1 + pinfo->lastCol - pinfo->firstCol;
+    for (row = pinfo->firstRow; row <= pinfo->lastRow; row++) {
+      if ( skip_ok && tmpchar ) {
+        if ( !force_c_outside ) {
+          if ( instance->ttcap.forceConstantSpacingBegin < row<<8 
+              && row<<8 < (instance->ttcap.forceConstantSpacingEnd & 0x0ff00) ) {
+            if (tmpchar->characterWidth) {
+              num_chars += num_cols;
+              swidth += ABS(tmpchar->characterWidth)*num_cols;
+              total_width += tmpchar->characterWidth*num_cols;
+              continue;
+            }
+          }
+          else skip_ok=0;
+        }
+        else {          /* for GB18030 proportional */
+          if ( instance->ttcap.forceConstantSpacingBegin < row<<8 
+              || row<<8 < (instance->ttcap.forceConstantSpacingEnd & 0x0ff00) ) {
+            if (tmpchar->characterWidth) {
+              num_chars += num_cols;
+              swidth += ABS(tmpchar->characterWidth)*num_cols;
+              total_width += tmpchar->characterWidth*num_cols;
+              continue;
+            }
+          }
+          else skip_ok=0;
+        }
+      }
+      for (col = pinfo->firstCol; col <= pinfo->lastCol; col++) {
+          c = row<<8|col;
+          flags=0;
+          if ( !force_c_outside ) {
+              if ( c <= instance->ttcap.forceConstantSpacingEnd 
+                  && instance->ttcap.forceConstantSpacingBegin <= c )
+                  flags|=FT_FORCE_CONSTANT_SPACING;
+          }
+          else {        /* for GB18030 proportional */
+              if ( c <= instance->ttcap.forceConstantSpacingEnd 
+                  || instance->ttcap.forceConstantSpacingBegin <= c )
+                  flags|=FT_FORCE_CONSTANT_SPACING;
+          }
+#if 0
+          fprintf(stderr, "comp_bounds: %x ->", c);
+#endif
+          if ( skip_ok == 0 || flags == 0 ){
+              tmpchar=NULL;
+#if 0
+              fprintf(stderr, "%x\n", c);
+#endif
+             if( FreeTypeFontGetGlyphMetrics(c, flags, &tmpchar, font) != Successful )
+                 continue;
+          }
+          if ( !tmpchar ) continue;
+          adjust_min_max(&minchar, &maxchar, tmpchar);
+          overlap = tmpchar->rightSideBearing - tmpchar->characterWidth;
+          if (maxOverlap < overlap)
+              maxOverlap = overlap;
+          
+          if (!tmpchar->characterWidth)
+              continue;
+          num_chars++;
+          swidth += ABS(tmpchar->characterWidth);
+          total_width += tmpchar->characterWidth;
+          
+          if ( flags & FT_FORCE_CONSTANT_SPACING ) skip_ok=1;
+      }
+    }
+
+#ifndef X_ACCEPTS_NO_SUCH_CHAR
+    /* Check code 0 */
+    if( FreeTypeInstanceGetGlyphMetrics(font->zero_idx, 0, &tmpchar, font->instance) != Successful || tmpchar == NULL)
+       if( FreeTypeInstanceGetGlyphMetrics(font->zero_idx, FT_GET_DUMMY, &tmpchar, font->instance) != Successful )
+           tmpchar = NULL;
+    if ( tmpchar ) {
+       adjust_min_max(&minchar, &maxchar, tmpchar);
+       overlap = tmpchar->rightSideBearing - tmpchar->characterWidth;
+       if (maxOverlap < overlap)
+           maxOverlap = overlap;
+    }
+#endif
+
+    /* AVERAGE_WIDTH ... 1/10 pixel unit */
+    if (num_chars > 0) {
+        swidth = (swidth * 10.0 + num_chars / 2.0) / num_chars;
+        if (total_width < 0)
+            swidth = -swidth;
+        vals->width = swidth;
+    } else
+        vals->width = 0;
+
+    /*
+    if (char_width.pixel) {
+        maxchar.characterWidth = char_width.pixel;
+        minchar.characterWidth = char_width.pixel;
+    }
+    */
+
+    pinfo->maxbounds     = maxchar;
+    pinfo->minbounds     = minchar;
+    pinfo->ink_maxbounds = maxchar;
+    pinfo->ink_minbounds = minchar;
+    pinfo->maxOverlap    = maxOverlap;
+}
+
+static int
+compute_new_extents( FontScalablePtr vals, double scale, double lsb, double rsb, double desc, double asc,
+                    int *lsb_result, int *rsb_result, int *desc_result, int *asc_result )
+{
+#define TRANSFORM_POINT(matrix, x, y, dest) \
+    ((dest)[0] = (matrix)[0] * (x) + (matrix)[2] * (y), \
+     (dest)[1] = (matrix)[1] * (x) + (matrix)[3] * (y))
+
+#define CHECK_EXTENT(lsb, rsb, desc, asc, data) \
+    ((lsb) > (data)[0] ? (lsb) = (data)[0] : 0 , \
+     (rsb) < (data)[0] ? (rsb) = (data)[0] : 0, \
+     (-desc) > (data)[1] ? (desc) = -(data)[1] : 0 , \
+     (asc) < (data)[1] ? (asc) = (data)[1] : 0)
+    double newlsb, newrsb, newdesc, newasc;
+    double point[2];
+
+    /* Compute new extents for this glyph */
+    TRANSFORM_POINT(vals->pixel_matrix, lsb, -desc, point);
+    newlsb  = point[0];
+    newrsb  = newlsb;
+    newdesc = -point[1];
+    newasc  = -newdesc;
+    TRANSFORM_POINT(vals->pixel_matrix, lsb, asc, point);
+    CHECK_EXTENT(newlsb, newrsb, newdesc, newasc, point);
+    TRANSFORM_POINT(vals->pixel_matrix, rsb, -desc, point);
+    CHECK_EXTENT(newlsb, newrsb, newdesc, newasc, point);
+    TRANSFORM_POINT(vals->pixel_matrix, rsb, asc, point);
+    CHECK_EXTENT(newlsb, newrsb, newdesc, newasc, point);
+
+    /* ???: lsb = (int)floor(newlsb * scale); */
+    *lsb_result   = (int)floor(newlsb * scale + 0.5);
+    *rsb_result   = (int)floor(newrsb * scale + 0.5);
+    *desc_result  = (int)ceil(newdesc * scale - 0.5);
+    *asc_result   = (int)floor(newasc * scale + 0.5);
+
+    return 0;
+#undef CHECK_EXTENT
+#undef TRANSFORM_POINT
+}
+
+static int
+is_matrix_unit(FontScalablePtr vals)
+{
+    double base_size;
+    FT_Matrix m;
+
+    base_size = hypot(vals->point_matrix[2], vals->point_matrix[3]);
+
+    m.xx = vals->point_matrix[0] / base_size * 65536;
+    m.xy = vals->point_matrix[2] / base_size * 65536;
+    m.yx = vals->point_matrix[1] / base_size * 65536;
+    m.yy = vals->point_matrix[3] / base_size * 65536;
+
+    return (m.xx == 65536) && (m.yx == 0) && 
+          (m.xy == 0) && (m.yy == 65536);
+}
+
+/* Do all the real work for OpenFont or FontInfo */
+/* xf->info is only accessed through info, and xf might be null */
+
+static int
+FreeTypeLoadXFont(char *fileName, 
+                  FontScalablePtr vals, FontPtr xf, FontInfoPtr info,
+                  FontBitmapFormatPtr bmfmt, FontEntryPtr entry)
+{
+    FTFontPtr font = NULL;
+    FTFacePtr face = NULL;
+    FTInstancePtr instance;
+    FT_Size_Metrics *smetrics;
+    int xrc=Successful;
+    int charcell;
+    long rawWidth = 0, rawAverageWidth = 0;
+    int upm, minLsb, maxRsb, ascent, descent, width, averageWidth;
+    double scale, base_width, base_height;
+    Bool orig_is_matrix_unit, font_properties;
+    int face_number, ttcap_spacing;
+    struct TTCapInfo tmp_ttcap;
+    struct TTCapInfo *ins_ttcap;
+    FT_Int32 load_flags = FT_LOAD_DEFAULT;     /* orig: FT_LOAD_RENDER | FT_LOAD_MONOCHROME */
+    char *dynStrRealFileName   = NULL; /* foo.ttc */
+    char *dynStrFTFileName     = NULL; /* :1:foo.ttc */
+    char *dynStrTTCapCodeRange = NULL;
+
+    font = calloc(1, sizeof(FTFontRec));
+    if(font == NULL) {
+        xrc = AllocError;
+        goto quit;
+    }
+
+    xrc = FreeTypeSetUpTTCap(fileName, vals, 
+                            &dynStrRealFileName, &dynStrFTFileName,
+                            &tmp_ttcap, &face_number, 
+                            &load_flags, &ttcap_spacing,
+                            &font_properties, &dynStrTTCapCodeRange);
+    if ( xrc != Successful ) {
+       goto quit;
+    }
+
+    xrc = FreeTypeOpenFace(&face, dynStrFTFileName, dynStrRealFileName, face_number);
+    if(xrc != Successful) {
+        goto quit;
+    }
+
+    if( is_matrix_unit(vals) )
+       orig_is_matrix_unit = True;
+    else {
+       orig_is_matrix_unit = False;
+       /* Turn off EmbeddedBitmap when original matrix is not diagonal. */
+       load_flags |= FT_LOAD_NO_BITMAP;
+    }
+
+    if( face->bitmap ) load_flags &= ~FT_LOAD_NO_BITMAP;
+
+    /* Slant control by TTCap */
+    if(!face->bitmap) {
+       vals->pixel_matrix[2] +=
+           vals->pixel_matrix[0] * tmp_ttcap.autoItalic;
+       vals->point_matrix[2] +=
+           vals->point_matrix[0] * tmp_ttcap.autoItalic;
+       vals->pixel_matrix[3] +=
+           vals->pixel_matrix[1] * tmp_ttcap.autoItalic;
+       vals->point_matrix[3] +=
+           vals->point_matrix[1] * tmp_ttcap.autoItalic;
+    }
+
+    base_width=hypot(vals->pixel_matrix[0], vals->pixel_matrix[1]);
+    base_height=hypot(vals->pixel_matrix[2], vals->pixel_matrix[3]);
+    if(MAX(base_width, base_height) < 1.0 ) {
+        xrc = BadFontName;
+       goto quit;
+    }
+
+    xrc = FreeTypeLoadFont(font, info, face, dynStrFTFileName, vals, entry, bmfmt,
+                          load_flags, &tmp_ttcap, dynStrTTCapCodeRange, 
+                          ttcap_spacing );
+    if(xrc != Successful) {
+        goto quit;
+    }
+
+    instance = font->instance;
+    smetrics = &instance->size->metrics;
+    ins_ttcap = &instance->ttcap;
+
+    upm = face->face->units_per_EM;
+    if(upm == 0) {
+        /* Work around FreeType bug */
+        upm = WORK_AROUND_UPM;
+    }
+    scale = 1.0 / upm;
+
+    charcell = (instance->spacing == FT_CHARCELL);
+
+    if( instance->charcellMetrics == NULL ) {
+
+       /* New instance */
+
+       long force_c_rawWidth = 0;
+       int force_c_lsb,force_c_rsb,force_c_width;
+       double unit_x=0,unit_y=0,advance;
+       CharInfoPtr tmpglyph;
+
+       /*
+        * CALCULATE HEADER'S METRICS
+        */
+
+       /* for OUTLINE fonts */
+       if(!face->bitmap) {
+           int new_width;
+           double ratio,force_c_ratio;
+           double width_x=0,width_y=0;
+           double force_c_width_x, force_c_rsb_x, force_c_lsb_x;
+           double tmp_rsb,tmp_lsb,tmp_asc,tmp_des;
+           double max_advance_height;
+           tmp_asc = face->face->bbox.yMax;
+           tmp_des = -(face->face->bbox.yMin);
+           if ( tmp_asc < face->face->ascender ) tmp_asc = face->face->ascender;
+           if ( tmp_des < -(face->face->descender) ) tmp_des = -(face->face->descender);
+           tmp_lsb = face->face->bbox.xMin;
+           tmp_rsb = face->face->bbox.xMax;
+           if ( tmp_rsb < face->face->max_advance_width ) tmp_rsb = face->face->max_advance_width;
+           /* apply scaleBBoxWidth */
+           /* we should not ...??? */
+           tmp_lsb *= ins_ttcap->scaleBBoxWidth;
+           tmp_rsb *= ins_ttcap->scaleBBoxWidth;
+           /* transform and rescale */
+           compute_new_extents( vals, scale, tmp_lsb, tmp_rsb, tmp_des, tmp_asc,
+                                &minLsb, &maxRsb, &descent, &ascent );
+           /* */
+           /* Consider vertical layouts */
+           if( 0 < face->face->max_advance_height )
+               max_advance_height = face->face->max_advance_height;
+           else
+               max_advance_height = tmp_asc + tmp_des;
+           if( vals->pixel_matrix[1] == 0 ){
+               unit_x = fabs(vals->pixel_matrix[0]);
+               unit_y = 0;
+               width_x = face->face->max_advance_width * ins_ttcap->scaleBBoxWidth * unit_x;
+           }
+           else if( vals->pixel_matrix[3] == 0 ){
+               unit_y = fabs(vals->pixel_matrix[2]);
+               unit_x = 0;
+               width_x = max_advance_height * ins_ttcap->scaleBBoxHeight * unit_y;
+           }
+           else{
+               unit_x = fabs(vals->pixel_matrix[0] - 
+                             vals->pixel_matrix[1]*vals->pixel_matrix[2]/vals->pixel_matrix[3]);
+               unit_y = fabs(vals->pixel_matrix[2] - 
+                             vals->pixel_matrix[3]*vals->pixel_matrix[0]/vals->pixel_matrix[1]);
+               width_x = face->face->max_advance_width * ins_ttcap->scaleBBoxWidth * unit_x;
+               width_y = max_advance_height * ins_ttcap->scaleBBoxHeight * unit_y;
+               if( width_y < width_x ){
+                   width_x = width_y;
+                   unit_x = 0;
+               }
+               else{
+                   unit_y = 0;
+               }
+           }
+           /* calculate correction ratio */
+           width = (int)floor( (advance = width_x * scale) + 0.5);
+           new_width = width;
+           if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH )
+               new_width += ins_ttcap->doubleStrikeShift;
+           new_width += ins_ttcap->adjustBBoxWidthByPixel;
+           ratio = (double)new_width/width;
+           width = new_width;
+           /* force constant */
+           if( unit_x != 0 ) {
+               force_c_width_x = face->face->max_advance_width
+                   * ins_ttcap->force_c_scale_b_box_width * unit_x;
+               force_c_lsb_x = face->face->max_advance_width
+                   * ins_ttcap->force_c_scale_lsb * unit_x;
+               force_c_rsb_x = face->face->max_advance_width
+                   * ins_ttcap->force_c_scale_rsb * unit_x;
+           }
+           else {
+               force_c_width_x = max_advance_height
+                   * ins_ttcap->force_c_scale_b_box_height * unit_y;
+               force_c_lsb_x = max_advance_height
+                   * ins_ttcap->force_c_scale_lsb * unit_y;
+               force_c_rsb_x = max_advance_height
+                   * ins_ttcap->force_c_scale_rsb * unit_y;
+           }
+           /* calculate correction ratio */
+           force_c_width = (int)floor(force_c_width_x * scale + 0.5);
+           new_width = force_c_width;
+           if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH )
+               force_c_width += ins_ttcap->doubleStrikeShift;
+           new_width += ins_ttcap->force_c_adjust_width_by_pixel;
+           force_c_ratio = (double)new_width/force_c_width;
+           force_c_width = new_width;
+           /* force_c_lsb, force_c_rsb */
+           if( ins_ttcap->flags & TTCAP_FORCE_C_LSB_FLAG )
+               force_c_lsb = (int)floor( force_c_lsb_x * scale + 0.5 );
+           else
+               force_c_lsb = minLsb;
+           if( ins_ttcap->flags & TTCAP_FORCE_C_RSB_FLAG )
+               force_c_rsb = (int)floor( force_c_rsb_x * scale + 0.5 );
+           else
+               force_c_rsb = maxRsb;
+           /* calculate shift of BitmapAutoItalic
+              (when diagonal matrix only) */
+           if( orig_is_matrix_unit == True ) {
+               if( ins_ttcap->autoItalic != 0 ) {
+                   double ai;
+                   int ai_lsb,ai_rsb,ai_total;
+                   if( 0 < ins_ttcap->autoItalic ) ai=ins_ttcap->autoItalic;
+                   else ai = -ins_ttcap->autoItalic;
+                   ai_total = (int)( (ascent+descent) * ai + 0.5);
+                   ai_rsb = (int)((double)ai_total * ascent / ( ascent + descent ) + 0.5 );
+                   ai_lsb = -(ai_total - ai_rsb);
+                   if( 0 < ins_ttcap->autoItalic ) {
+                       ins_ttcap->lsbShiftOfBitmapAutoItalic = ai_lsb;
+                       ins_ttcap->rsbShiftOfBitmapAutoItalic = ai_rsb;
+                   }
+                   else {
+                       ins_ttcap->lsbShiftOfBitmapAutoItalic = -ai_rsb;
+                       ins_ttcap->rsbShiftOfBitmapAutoItalic = -ai_lsb;
+                   }
+               }
+           }
+           /* integer adjustment by TTCap */
+           if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE )
+               maxRsb += ins_ttcap->doubleStrikeShift;
+           maxRsb += ins_ttcap->adjustRightSideBearingByPixel;
+           minLsb += ins_ttcap->adjustLeftSideBearingByPixel;
+           /* */
+           if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE )
+               force_c_rsb += ins_ttcap->doubleStrikeShift;
+           force_c_rsb += ins_ttcap->force_c_adjust_rsb_by_pixel;
+           force_c_lsb += ins_ttcap->force_c_adjust_lsb_by_pixel;
+           /* apply to rawWidth */
+           averageWidth = (int)floor(10 * width_x * scale 
+                                     * ratio + 0.5);
+           rawWidth = floor(width_x * scale
+                            * ratio * 1000. / base_height + 0.5);
+           rawAverageWidth = floor(width_x * scale * ratio * 10.
+                                   * 1000. / base_height + 0.5);
+           force_c_rawWidth = floor(force_c_width_x * scale
+                                    * force_c_ratio * 1000. / base_height + 0.5);
+           /* */
+       }
+       /* for BITMAP fonts [if(face->bitmap)] */
+       else {
+           /* These values differ from actual when outline,
+              so we must use them ONLY FOR BITMAP. */
+           width = (int)floor(smetrics->max_advance * ins_ttcap->scaleBBoxWidth / 64.0 + .5);
+           descent = -smetrics->descender / 64;
+           ascent = smetrics->ascender / 64;
+           /* force constant */
+           force_c_width = (int)floor(smetrics->max_advance
+                                      * ins_ttcap->force_c_scale_b_box_width / 64.0 + .5);
+           /* Preserve average width for bitmap fonts */
+           if(vals->width != 0)
+               averageWidth = (int)floor(vals->width * ins_ttcap->scaleBBoxWidth +.5);
+           else
+               averageWidth = (int)floor(10.0 * smetrics->max_advance
+                                         * ins_ttcap->scaleBBoxWidth / 64.0 + .5);
+           rawWidth = 0;
+           rawAverageWidth = 0;
+           force_c_rawWidth = 0;
+           /* We don't consider vertical layouts */
+           advance = (int)floor(smetrics->max_advance / 64.0 +.5);
+           unit_x = vals->pixel_matrix[0];
+           unit_y = 0;
+           /* We can use 'width' only when bitmap.
+              This should not be set when outline. */
+           minLsb = 0;
+           maxRsb = width;
+           /* force constant */
+           if( ins_ttcap->flags & TTCAP_FORCE_C_LSB_FLAG )
+               force_c_lsb = (int)floor(smetrics->max_advance
+                                        * ins_ttcap->force_c_scale_lsb / 64.0 + .5);
+           else
+               force_c_lsb = minLsb;
+           if( ins_ttcap->flags & TTCAP_FORCE_C_RSB_FLAG )
+               force_c_rsb = (int)floor(smetrics->max_advance
+                                        * ins_ttcap->force_c_scale_rsb / 64.0 + .5);
+           else
+               force_c_rsb = maxRsb;
+           /* calculate shift of BitmapAutoItalic */
+           if( ins_ttcap->autoItalic != 0 ) {
+               double ai;
+               int ai_lsb,ai_rsb,ai_total;
+               if( 0 < ins_ttcap->autoItalic ) ai=ins_ttcap->autoItalic;
+               else ai = -ins_ttcap->autoItalic;
+               ai_total = (int)( (ascent+descent) * ai + 0.5);
+               ai_rsb = (int)((double)ai_total * ascent / ( ascent + descent ) + 0.5 );
+               ai_lsb = -(ai_total - ai_rsb);
+               if( 0 < ins_ttcap->autoItalic ) {
+                   ins_ttcap->lsbShiftOfBitmapAutoItalic = ai_lsb;
+                   ins_ttcap->rsbShiftOfBitmapAutoItalic = ai_rsb;
+               }
+               else {
+                   ins_ttcap->lsbShiftOfBitmapAutoItalic = -ai_rsb;
+                   ins_ttcap->rsbShiftOfBitmapAutoItalic = -ai_lsb;
+               }
+           }
+           /* integer adjustment by TTCap */
+           if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH )
+               width += ins_ttcap->doubleStrikeShift;
+           if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE )
+               maxRsb += ins_ttcap->doubleStrikeShift;
+           maxRsb += ins_ttcap->adjustRightSideBearingByPixel;
+           minLsb += ins_ttcap->adjustLeftSideBearingByPixel;
+           /* We have not carried out matrix calculation, so this is done. */
+           maxRsb += ins_ttcap->rsbShiftOfBitmapAutoItalic;
+           minLsb += ins_ttcap->lsbShiftOfBitmapAutoItalic;
+           /* force constant */
+           if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE )
+               force_c_rsb += ins_ttcap->doubleStrikeShift;
+           force_c_rsb += ins_ttcap->force_c_adjust_rsb_by_pixel;
+           force_c_lsb += ins_ttcap->force_c_adjust_lsb_by_pixel;
+           force_c_rsb += ins_ttcap->rsbShiftOfBitmapAutoItalic;
+           force_c_lsb += ins_ttcap->lsbShiftOfBitmapAutoItalic;
+       }
+
+       /* SET CALCULATED VALUES TO INSTANCE */
+
+       /* Set actual height and cosine */
+       instance->pixel_size = base_height;
+       instance->advance = advance;
+       if ( unit_x != 0 ){
+           instance->pixel_width_unit_x = unit_x/base_height;
+           instance->pixel_width_unit_y = 0;
+       }
+       else{
+           instance->pixel_width_unit_x = 0;
+           instance->pixel_width_unit_y = unit_y/base_height;
+       }
+
+       /* header's metrics */
+       instance->charcellMetrics = malloc(sizeof(xCharInfo));
+       if(instance->charcellMetrics == NULL) {
+           xrc = AllocError;
+           goto quit;
+       }
+       instance->charcellMetrics->ascent = ascent;
+       instance->charcellMetrics->descent = descent;
+       instance->charcellMetrics->attributes = rawWidth;
+       instance->charcellMetrics->rightSideBearing = maxRsb;
+       instance->charcellMetrics->leftSideBearing = minLsb;
+       instance->charcellMetrics->characterWidth = width;
+       instance->averageWidth = averageWidth;
+       instance->rawAverageWidth = rawAverageWidth;
+
+       /* Check code 0 */
+       if( FreeTypeInstanceGetGlyph(font->zero_idx, 0, &tmpglyph, font->instance) != Successful
+           || tmpglyph == NULL)
+           if( FreeTypeInstanceGetGlyph(font->zero_idx, FT_GET_DUMMY, &tmpglyph, font->instance)
+               != Successful )
+               tmpglyph = NULL;
+       if ( !tmpglyph ) {
+           xrc = AllocError;
+           goto quit;
+       }
+
+       /* FORCE CONSTANT METRICS */
+       if( 0 <= ins_ttcap->forceConstantSpacingEnd ) {
+            xCharInfo *tmpchar = NULL;
+            int c = ins_ttcap->force_c_representative_metrics_char_code;
+           /* header's metrics */
+           if( instance->forceConstantMetrics == NULL ){
+               instance->forceConstantMetrics = malloc(sizeof(xCharInfo));
+               if(instance->forceConstantMetrics == NULL) {
+                   xrc = AllocError;
+                   goto quit;
+               }
+           }
+            /* Get Representative Metrics */
+            if ( 0 <= c ) {
+               if( FreeTypeFontGetGlyphMetrics(c, 0, &tmpchar, font) != Successful )
+                   tmpchar = NULL;
+            }
+            if ( tmpchar && 0 < tmpchar->characterWidth ) {
+               instance->forceConstantMetrics->leftSideBearing  = tmpchar->leftSideBearing;
+               instance->forceConstantMetrics->rightSideBearing = tmpchar->rightSideBearing;
+               instance->forceConstantMetrics->characterWidth   = tmpchar->characterWidth;
+               instance->forceConstantMetrics->ascent           = tmpchar->ascent;
+               instance->forceConstantMetrics->descent          = tmpchar->descent;
+               instance->forceConstantMetrics->attributes       = tmpchar->attributes;
+            }
+            else {
+                instance->forceConstantMetrics->leftSideBearing  = force_c_lsb;
+                instance->forceConstantMetrics->rightSideBearing = force_c_rsb;
+                instance->forceConstantMetrics->characterWidth   = force_c_width;
+                instance->forceConstantMetrics->ascent           = ascent;
+                instance->forceConstantMetrics->descent          = descent;
+                instance->forceConstantMetrics->attributes       = force_c_rawWidth;
+            }
+           /* Check code 0 */
+           if( FreeTypeInstanceGetGlyph(font->zero_idx, FT_FORCE_CONSTANT_SPACING, 
+                                        &tmpglyph, font->instance) != Successful
+               || tmpglyph == NULL)
+               if( FreeTypeInstanceGetGlyph(font->zero_idx, FT_FORCE_CONSTANT_SPACING | FT_GET_DUMMY,
+                                            &tmpglyph, font->instance)
+                   != Successful )
+                   tmpglyph = NULL;
+           if ( !tmpglyph ) {
+               xrc = AllocError;
+               goto quit;
+           }
+        }
+    }
+    else{
+
+       /*
+        * CACHED VALUES
+        */
+
+       width = instance->charcellMetrics->characterWidth;
+       ascent = instance->charcellMetrics->ascent;
+       descent = instance->charcellMetrics->descent;
+       rawWidth = instance->charcellMetrics->attributes;
+       maxRsb = instance->charcellMetrics->rightSideBearing;
+       minLsb = instance->charcellMetrics->leftSideBearing;
+       averageWidth = instance->averageWidth;
+       rawAverageWidth = instance->rawAverageWidth;
+
+    }
+
+    /*
+     * SET maxbounds, minbounds ...
+     */
+
+    if( !charcell ) {          /* NOT CHARCELL */
+       if( info ){
+           /* 
+              Calculate all glyphs' metrics.
+              maxbounds.ascent and maxbounds.descent are quite important values
+              for XAA.  If ascent/descent of each glyph exceeds 
+              maxbounds.ascent/maxbounds.descent, XAA causes SERVER CRASH.
+              Therefore, THIS MUST BE DONE.
+           */
+           ft_compute_bounds(font,info,vals);
+       }
+    }
+    else{                      /* CHARCELL */
+
+    /*
+     * SET CALCULATED OR CACHED VARIABLES
+     */
+
+       vals->width = averageWidth;
+       
+       if( info ){
+
+           info->maxbounds.leftSideBearing = minLsb;
+           info->maxbounds.rightSideBearing = maxRsb;
+           info->maxbounds.characterWidth = width;
+           info->maxbounds.ascent = ascent;
+           info->maxbounds.descent = descent;
+           info->maxbounds.attributes =
+               (unsigned short)(short)rawWidth;
+           
+           info->minbounds = info->maxbounds;
+       }
+    }
+
+    /* set info */
+
+    if( info ){
+       /*
+       info->fontAscent = ascent;
+       info->fontDescent = descent;
+       */
+       info->fontAscent = info->maxbounds.ascent;
+       info->fontDescent = info->maxbounds.descent;
+       /* Glyph metrics are accurate */
+       info->inkMetrics=1;
+           
+       memcpy((char *)&info->ink_maxbounds,
+              (char *)&info->maxbounds, sizeof(xCharInfo));
+       memcpy((char *)&info->ink_minbounds,
+              (char *)&info->minbounds, sizeof(xCharInfo));
+       
+       /* XXX - hack */
+       info->defaultCh=0;
+
+       /* Set the pInfo flags */
+       /* Properties set by FontComputeInfoAccelerators:
+          pInfo->noOverlap;
+          pInfo->terminalFont;
+          pInfo->constantMetrics;
+          pInfo->constantWidth;
+          pInfo->inkInside;
+       */
+       /* from lib/font/util/fontaccel.c */
+       FontComputeInfoAccelerators(info);
+    }
+
+    if(xf)
+        xf->fontPrivate = (void*)font;
+  
+    if(info) {
+        xrc = FreeTypeAddProperties(font, vals, info, entry->name.name, 
+                                    rawAverageWidth, font_properties);
+        if (xrc != Successful) {
+            goto quit;
+        }
+    }
+
+ quit:
+    if ( dynStrTTCapCodeRange ) free(dynStrTTCapCodeRange);
+    if ( dynStrFTFileName ) free(dynStrFTFileName);
+    if ( dynStrRealFileName ) free(dynStrRealFileName);
+    if ( xrc != Successful ) {
+       if( font ){
+           if( face && font->instance == NULL ) FreeTypeFreeFace(face);
+           FreeTypeFreeFont(font);
+       }
+    }
+    return xrc;
+}
+
+/* Routines used by X11 to get info and glyphs from the font. */
+
+static int
+FreeTypeGetMetrics(FontPtr pFont, unsigned long count, unsigned char *chars,
+                   FontEncoding charEncoding, unsigned long *metricCount,
+                   xCharInfo **metrics)
+{
+    unsigned int code = 0;
+    int flags = 0;
+    FTFontPtr tf;
+    struct TTCapInfo *ttcap;
+    xCharInfo **mp, *m;
+
+    /*  MUMBLE("Get metrics for %ld characters\n", count);*/
+
+    tf = (FTFontPtr)pFont->fontPrivate;
+    ttcap = &tf->instance->ttcap;
+    mp = metrics;
+
+    while (count-- > 0) {
+        switch (charEncoding) {
+        case Linear8Bit: 
+        case TwoD8Bit:
+            code = *chars++;
+            break;
+        case Linear16Bit: 
+        case TwoD16Bit:
+            code = (*chars++ << 8);
+            code |= *chars++;
+           /* */
+            if ( !(ttcap->flags & TTCAP_FORCE_C_OUTSIDE) ) {
+                if ( (int)code <= ttcap->forceConstantSpacingEnd 
+                    && ttcap->forceConstantSpacingBegin <= (int)code )
+                    flags|=FT_FORCE_CONSTANT_SPACING;
+               else flags=0;
+            }
+            else {      /* for GB18030 proportional */
+                if ( (int)code <= ttcap->forceConstantSpacingEnd 
+                    || ttcap->forceConstantSpacingBegin <= (int)code )
+                    flags|=FT_FORCE_CONSTANT_SPACING;
+               else flags=0;
+            }
+            break;
+        }
+
+        if(FreeTypeFontGetGlyphMetrics(code, flags, &m, tf) == Successful && m!=NULL) {
+            *mp++ = m;
+        }
+#ifdef X_ACCEPTS_NO_SUCH_CHAR
+       else *mp++ = &noSuchChar.metrics;
+#endif
+    }
+    
+    *metricCount = mp - metrics;
+    return Successful;
+}
+
+static int
+FreeTypeGetGlyphs(FontPtr pFont, unsigned long count, unsigned char *chars,
+                  FontEncoding charEncoding, unsigned long *glyphCount,
+                  CharInfoPtr *glyphs)
+{
+    unsigned int code = 0;
+    int flags = 0;
+    FTFontPtr tf;
+    CharInfoPtr *gp;
+    CharInfoPtr g;
+    struct TTCapInfo *ttcap;
+
+    tf = (FTFontPtr)pFont->fontPrivate;
+    ttcap = &tf->instance->ttcap;
+    gp = glyphs;
+
+    while (count-- > 0) {
+        switch (charEncoding) {
+        case Linear8Bit: case TwoD8Bit:
+            code = *chars++;
+            break;
+        case Linear16Bit: case TwoD16Bit:
+            code = *chars++ << 8; 
+            code |= *chars++;
+           /* */
+            if ( !(ttcap->flags & TTCAP_FORCE_C_OUTSIDE) ) {
+                if ( (int)code <= ttcap->forceConstantSpacingEnd 
+                    && ttcap->forceConstantSpacingBegin <= (int)code )
+                    flags|=FT_FORCE_CONSTANT_SPACING;
+               else flags=0;
+            }
+            else {      /* for GB18030 proportional */
+                if ( (int)code <= ttcap->forceConstantSpacingEnd 
+                    || ttcap->forceConstantSpacingBegin <= (int)code )
+                    flags|=FT_FORCE_CONSTANT_SPACING;
+               else flags=0;
+            }
+            break;
+        }
+      
+        if(FreeTypeFontGetGlyph(code, flags, &g, tf) == Successful && g!=NULL) {
+            *gp++ = g;
+        }
+#ifdef X_ACCEPTS_NO_SUCH_CHAR
+       else {
+#ifdef XAA_ACCEPTS_NULL_BITS
+           *gp++ = &noSuchChar;
+#else
+           if ( tf->dummy_char.bits ) {
+               *gp++ = &tf->dummy_char;
+           }
+           else {
+               char *raster = NULL;
+               int wd_actual, ht_actual, wd, ht, bpr;
+               wd_actual = tf->info->maxbounds.rightSideBearing - tf->info->maxbounds.leftSideBearing;
+               ht_actual = tf->info->maxbounds.ascent + tf->info->maxbounds.descent;
+               if(wd_actual <= 0) wd = 1;
+               else wd=wd_actual;
+               if(ht_actual <= 0) ht = 1;
+               else ht=ht_actual;
+               bpr = (((wd + (tf->instance->bmfmt.glyph<<3) - 1) >> 3) & 
+                      -tf->instance->bmfmt.glyph);
+               raster = calloc(1, ht * bpr);
+               if(raster) {
+                   tf->dummy_char.bits = raster;
+                   *gp++ = &tf->dummy_char;
+               }
+           }
+#endif
+       }
+#endif
+    }
+    
+    *glyphCount = gp - glyphs;
+    return Successful;
+}
+
+static int
+FreeTypeSetUpFont(FontPathElementPtr fpe, FontPtr xf, FontInfoPtr info, 
+                  fsBitmapFormat format, fsBitmapFormatMask fmask,
+                  FontBitmapFormatPtr bmfmt)
+{
+    int xrc;
+    int image;
+
+    /* Get the default bitmap format information for this X installation.
+       Also update it for the client if running in the font server. */
+    FontDefaultFormat(&bmfmt->bit, &bmfmt->byte, &bmfmt->glyph, &bmfmt->scan);
+    if ((xrc = CheckFSFormat(format, fmask, &bmfmt->bit, &bmfmt->byte,
+                             &bmfmt->scan, &bmfmt->glyph,
+                             &image)) != Successful) {
+        MUMBLE("Aborting after checking FS format: %d\n", xrc);
+        return xrc;
+    }
+
+    if(xf) {
+        xf->refcnt = 0;
+        xf->bit = bmfmt->bit;
+        xf->byte = bmfmt->byte;
+        xf->glyph = bmfmt->glyph;
+        xf->scan = bmfmt->scan;
+        xf->format = format;
+        xf->get_glyphs = FreeTypeGetGlyphs;
+        xf->get_metrics = FreeTypeGetMetrics;
+        xf->unload_font = FreeTypeUnloadXFont;
+        xf->unload_glyphs = 0;
+        xf->fpe = fpe;
+        xf->svrPrivate = 0;
+        xf->fontPrivate = 0;        /* we'll set it later */
+        xf->fpePrivate = 0;
+    }
+
+    info->defaultCh = 0;
+    info->noOverlap = 0;          /* not updated */
+    info->terminalFont = 0;       /* not updated */
+    info->constantMetrics = 0;    /* we'll set it later */
+    info->constantWidth = 0;      /* we'll set it later */
+    info->inkInside = 1;
+    info->inkMetrics = 1;
+    info->allExist=0;             /* not updated */
+    info->drawDirection = LeftToRight; /* we'll set it later */
+    info->cachable = 1;           /* we don't do licensing */
+    info->anamorphic = 0;         /* can hinting lead to anamorphic scaling? */
+    info->maxOverlap = 0;         /* we'll set it later. */
+    info->pad = 0;                /* ??? */
+    return Successful;
+}
+
+/* Functions exported by the backend */
+
+static int
+FreeTypeOpenScalable(FontPathElementPtr fpe, FontPtr *ppFont, int flags,
+                     FontEntryPtr entry, char *fileName, FontScalablePtr vals,
+                     fsBitmapFormat format, fsBitmapFormatMask fmask,
+                     FontPtr non_cachable_font)
+{
+    int xrc;
+    FontPtr xf;
+    FontBitmapFormatRec bmfmt;
+
+    MUMBLE("Open Scalable %s, XLFD=%s\n",fileName, entry->name.length ? entry->name.name : "");
+
+    xf = CreateFontRec();
+    if (xf == NULL)
+        return AllocError;
+
+    xrc = FreeTypeSetUpFont(fpe, xf, &xf->info, format, fmask, &bmfmt);
+    if(xrc != Successful) {
+        DestroyFontRec(xf);
+        return xrc;
+    }
+    xrc = FreeTypeLoadXFont(fileName, vals, xf, &xf->info, &bmfmt, entry);
+    if(xrc != Successful) {
+        MUMBLE("Error during load: %d\n",xrc);
+        DestroyFontRec(xf);
+        return xrc;
+    }
+
+    *ppFont = xf;
+
+    return xrc;
+}
+
+/* Routine to get requested font info. */
+
+static int
+FreeTypeGetInfoScalable(FontPathElementPtr fpe, FontInfoPtr info,
+                        FontEntryPtr entry, FontNamePtr fontName,
+                        char *fileName, FontScalablePtr vals)
+{
+    int xrc;
+    FontBitmapFormatRec bmfmt;
+
+    MUMBLE("Get info, XLFD=%s\n", entry->name.length ? entry->name.name : "");
+
+    xrc = FreeTypeSetUpFont(fpe, 0, info, 0, 0, &bmfmt);
+    if(xrc != Successful) {
+        return xrc;
+    }
+
+    bmfmt.glyph <<= 3;
+
+    xrc = FreeTypeLoadXFont(fileName, vals, 0, info, &bmfmt, entry);
+    if(xrc != Successful) {
+        MUMBLE("Error during load: %d\n", xrc);
+        return xrc;
+    }
+
+    return Successful;
+}
+
+/* Renderer registration. */
+
+/* Set the capabilities of this renderer. */
+#define CAPABILITIES (CAP_CHARSUBSETTING | CAP_MATRIX)
+
+/* Set it up so file names with either upper or lower case can be
+   loaded.  We don't support compressed fonts. */
+static FontRendererRec renderers[] = {
+    {".ttf", 4, 0, FreeTypeOpenScalable, 0,
+     FreeTypeGetInfoScalable, 0, CAPABILITIES},
+    {".ttc", 4, 0, FreeTypeOpenScalable, 0,
+     FreeTypeGetInfoScalable, 0, CAPABILITIES},
+    {".otf", 4, 0, FreeTypeOpenScalable, 0,
+     FreeTypeGetInfoScalable, 0, CAPABILITIES},
+    {".otc", 4, 0, FreeTypeOpenScalable, 0,
+     FreeTypeGetInfoScalable, 0, CAPABILITIES},
+    {".pfa", 4, 0, FreeTypeOpenScalable, 0,
+     FreeTypeGetInfoScalable, 0, CAPABILITIES},
+    {".pfb", 4, 0, FreeTypeOpenScalable, 0,
+     FreeTypeGetInfoScalable, 0, CAPABILITIES},
+};
+static int num_renderers = sizeof(renderers) / sizeof(renderers[0]);
+
+static FontRendererRec alt_renderers[] = {
+    {".bdf", 4, 0, FreeTypeOpenScalable, 0,
+     FreeTypeGetInfoScalable, 0, CAPABILITIES},
+    {".pcf", 4, 0, FreeTypeOpenScalable, 0,
+     FreeTypeGetInfoScalable, 0, CAPABILITIES},
+};
+
+static int num_alt_renderers =  
+sizeof(alt_renderers) / sizeof(alt_renderers[0]);
+    
+
+void
+FreeTypeRegisterFontFileFunctions(void)
+{
+    int i;
+
+    for (i = 0; i < num_renderers; i++)
+        FontFileRegisterRenderer(&renderers[i]);
+
+    for (i = 0; i < num_alt_renderers; i++)
+        FontFilePriorityRegisterRenderer(&alt_renderers[i], -10);
+}
diff --git a/src/FreeType/ftfuncs.h b/src/FreeType/ftfuncs.h
new file mode 100755 (executable)
index 0000000..068a595
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+Copyright (c) 1998-2002 by Juliusz Chroboczek
+Copyright (c) 2003 After X-TT Project, All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+/* Number of buckets in the hashtable holding faces */
+#define NUMFACEBUCKETS 32
+
+/* Glyphs are held in segments of this size */
+#define FONTSEGMENTSIZE 16
+
+/* A structure that holds bitmap order and padding info. */
+
+typedef struct {
+    int bit;                    /* bit order */
+    int byte;                   /* byte order */
+    int glyph;                  /* glyph pad size */
+    int scan;                   /* machine word size */
+} FontBitmapFormatRec, *FontBitmapFormatPtr;
+
+struct FTSize_s;
+
+/* At the lowest level, there is face; FTFaces are in one-to-one
+   correspondence with TrueType faces.  Multiple instance may share
+   the same face. */
+
+typedef struct _FTFace {
+    char *filename;
+    FT_Face face;
+    int bitmap;
+    FT_UInt num_hmetrics;
+    struct _FTInstance *instances;
+    struct _FTInstance *active_instance;
+    struct _FTFace *next;       /* link to next face in bucket */
+} FTFaceRec, *FTFacePtr;
+
+/* A transformation matrix with resolution information */
+typedef struct _FTNormalisedTransformation {
+    double scale;
+    int nonIdentity;            /* if 0, matrix is the identity */
+    FT_Matrix matrix;
+    int xres, yres;
+} FTNormalisedTransformationRec, *FTNormalisedTransformationPtr;
+
+#define FT_PROPORTIONAL 0
+#define FT_MONOSPACED 1
+#define FT_CHARCELL 2
+
+#define FT_AVAILABLE_UNKNOWN 0
+#define FT_AVAILABLE_NO 1
+#define FT_AVAILABLE_METRICS 2
+#define FT_AVAILABLE_RASTERISED 3
+
+#define FT_GET_GLYPH_BOTH        0x01
+#define FT_GET_GLYPH_METRICS_ONLY 0x02
+#define FT_GET_DUMMY             0x04
+#define FT_FORCE_CONSTANT_SPACING 0x08
+
+#define TTCAP_DOUBLE_STRIKE                    0x0001
+#define TTCAP_DOUBLE_STRIKE_MKBOLD_EDGE_LEFT   0x0002
+#define TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH        0x0008
+#define TTCAP_IS_VERY_LAZY                     0x0010
+#define TTCAP_DISABLE_DEFAULT_VERY_LAZY                0x0020
+#define TTCAP_FORCE_C_LSB_FLAG                 0x0100
+#define TTCAP_FORCE_C_RSB_FLAG                 0x0200
+#define TTCAP_FORCE_C_OUTSIDE                  0x0400
+#define TTCAP_MONO_CENTER                      0x0800
+
+/* TTCap */
+struct TTCapInfo {
+    long flags;
+    double autoItalic;
+    double scaleWidth;
+    double scaleBBoxWidth;
+    double scaleBBoxHeight;
+    int doubleStrikeShift;
+    int adjustBBoxWidthByPixel;
+    int adjustLeftSideBearingByPixel;
+    int adjustRightSideBearingByPixel;
+    double scaleBitmap;
+    int forceConstantSpacingBegin;
+    int forceConstantSpacingEnd;
+    /* We don't compare */
+    int force_c_adjust_width_by_pixel;
+    int force_c_adjust_lsb_by_pixel;
+    int force_c_adjust_rsb_by_pixel;
+    int force_c_representative_metrics_char_code;
+    double force_c_scale_b_box_width;
+    double force_c_scale_b_box_height;
+    double force_c_scale_lsb;
+    double force_c_scale_rsb;
+    double vl_slant;
+    int lsbShiftOfBitmapAutoItalic;
+    int rsbShiftOfBitmapAutoItalic;
+};
+
+/* An instance builds on a face by specifying the transformation
+   matrix.  Multiple fonts may share the same instance. */
+
+/* This structure caches bitmap data */
+typedef struct _FTInstance {
+    FTFacePtr face;             /* the associated face */
+    FT_Size size;
+    FTNormalisedTransformationRec transformation;
+    FT_Int32 load_flags;
+    FT_ULong strike_index;
+    int spacing;               /* actual spacing */
+    double pixel_size;          /* to calc attributes (actual height) */
+    double pixel_width_unit_x;  /* to calc horiz. width (cosine) */
+    double pixel_width_unit_y;  /* to calc vert. width (cosine) */
+    xCharInfo *charcellMetrics;        /* the header's metrics */
+    int averageWidth;          /* the header's metrics */
+    long rawAverageWidth;      /* the header's metrics */
+    double advance;            /* the header's metrics */
+    xCharInfo *forceConstantMetrics;
+    FontBitmapFormatRec bmfmt;
+    unsigned nglyphs;
+    CharInfoPtr *glyphs;        /* glyphs and available are used in parallel */
+    int **available;
+    struct TTCapInfo ttcap;
+    int refcount;
+    struct _FTInstance *next;   /* link to next instance */
+} FTInstanceRec, *FTInstancePtr;
+
+/* A font is an instance with coding information; fonts are in
+   one-to-one correspondence with X fonts */
+typedef struct _FTFont{
+    FTInstancePtr instance;
+    FTMappingRec mapping;
+    unsigned zero_idx;
+    FontInfoPtr info;
+    int nranges;
+    CharInfoRec dummy_char;
+    fsRange *ranges;
+} FTFontRec, *FTFontPtr;
+
+#ifndef NOT_IN_FTFUNCS
+
+/* Prototypes for some local functions */
+
+static int FreeTypeOpenFace(FTFacePtr *facep, char *FTFileName, char *realFileName, int faceNumber);
+static void FreeTypeFreeFace(FTFacePtr face);
+static int 
+FreeTypeOpenInstance(FTInstancePtr *instancep, FTFacePtr face,
+                     char *FTFileName, FTNormalisedTransformationPtr trans,
+                     int spacing, FontBitmapFormatPtr bmfmt,
+                    struct TTCapInfo *tmp_ttcap, FT_Int32 load_flags);
+static void FreeTypeFreeInstance(FTInstancePtr instance);
+static int
+FreeTypeInstanceGetGlyph(unsigned idx, int flags, CharInfoPtr *g, FTInstancePtr instance);
+static int
+FreeTypeInstanceGetGlyphMetrics(unsigned idx, int flags,
+                               xCharInfo **metrics, FTInstancePtr instance );
+static int 
+FreeTypeRasteriseGlyph(unsigned idx, int flags, CharInfoPtr tgp, 
+                      FTInstancePtr instance, int hasMetrics );
+static void FreeTypeFreeFont(FTFontPtr font);
+static void FreeTypeFreeXFont(FontPtr pFont, int freeProps);
+static void FreeTypeUnloadXFont(FontPtr pFont);
+static int
+FreeTypeAddProperties(FTFontPtr font, FontScalablePtr vals, FontInfoPtr info, 
+                      char *fontname, int rawAverageWidth, Bool font_properties);
+static int FreeTypeFontGetGlyph(unsigned code, int flags, CharInfoPtr *g, FTFontPtr font);
+static int
+FreeTypeLoadFont(FTFontPtr font, FontInfoPtr info, FTFacePtr face,
+                char *FTFileName, FontScalablePtr vals, FontEntryPtr entry,
+                 FontBitmapFormatPtr bmfmt, FT_Int32 load_flags, 
+                struct TTCapInfo *tmp_ttcap, char *dynStrTTCapCodeRange,
+                int ttcap_spacing );
+
+#endif /* NOT_IN_FTFUNCS */
diff --git a/src/FreeType/fttools.c b/src/FreeType/fttools.c
new file mode 100755 (executable)
index 0000000..bc75b7e
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+  Copyright (c) 1997 by Mark Leisher
+  Copyright (c) 1998-2002 by Juliusz Chroboczek
+
+  Permission is hereby granted, free of charge, to any person obtaining a copy
+  of this software and associated documentation files (the "Software"), to deal
+  in the Software without restriction, including without limitation the rights
+  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+  copies of the Software, and to permit persons to whom the Software is
+  furnished to do so, subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be included in
+  all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+  THE SOFTWARE.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fontmisc.h>
+#include <ctype.h>
+#include <string.h>
+
+#include <X11/fonts/font.h>
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_SFNT_NAMES_H
+#include FT_TRUETYPE_IDS_H
+#include "ft.h"
+
+#ifndef LSBFirst
+#define LSBFirst 0
+#define MSBFirst 1
+#endif
+
+#define LOBYTE(s,byte) ((byte)==LSBFirst?*(char*)(s):*((char*)(s)+1))
+#define HIBYTE(s,byte) ((byte)==LSBFirst?*((char*)(s)+1):*(char*)(s))
+
+int FTtoXReturnCode(int rc)
+{
+    if(rc == 0x40)
+        return AllocError;
+    /* Anything else stops the font matching mechanism */
+    else return BadFontName;
+
+}
+
+/* Convert slen bytes from UCS-2 to ISO 8859-1.  Byte specifies the
+   endianness of the string, max the maximum number of bytes written into
+   to. */
+static int
+FTu2a(int slen, FT_Byte *from, char *to, int byte, int max)
+{
+    int i, n;
+
+    n = 0;
+    for (i = 0; i < slen; i += 2) {
+        if(n >= max - 1)
+            break;
+        if(HIBYTE(from+i, byte)!=0)
+            *to++='?';
+        else
+            *to++ = LOBYTE(from+i,byte);
+        n++;
+    }
+    *to = 0;
+    return n;
+}
+
+static int
+FTGetName(FT_Face face, int nid, int pid, int eid, FT_SfntName *name_return)
+{
+    FT_SfntName name;
+    int n, i;
+
+    n = FT_Get_Sfnt_Name_Count(face);
+    if(n <= 0)
+        return 0;
+
+    for(i = 0; i < n; i++) {
+        if(FT_Get_Sfnt_Name(face, i, &name))
+            continue;
+        if(name.name_id == nid &&
+           name.platform_id == pid &&
+           (eid < 0 || name.encoding_id == eid)) {
+            switch(name.platform_id) {
+            case TT_PLATFORM_APPLE_UNICODE:
+            case TT_PLATFORM_MACINTOSH:
+                if(name.language_id != TT_MAC_LANGID_ENGLISH)
+                    continue;
+                break;
+            case TT_PLATFORM_MICROSOFT:
+                if(name.language_id != TT_MS_LANGID_ENGLISH_UNITED_STATES &&
+                   name.language_id != TT_MS_LANGID_ENGLISH_UNITED_KINGDOM)
+                    break;
+                    continue;
+                break;
+            default:
+                break;
+            }
+            *name_return = name;
+            return 1;
+        }
+    }
+    return 0;
+}
+
+int 
+FTGetEnglishName(FT_Face face, int nid, char *name_return, int name_len)
+{
+    FT_SfntName name;
+    int len;
+
+    if(FTGetName(face, nid, 
+                 TT_PLATFORM_MICROSOFT, TT_MS_ID_UNICODE_CS, &name) ||
+       FTGetName(face, nid, 
+                 TT_PLATFORM_APPLE_UNICODE, -1, &name))
+        return FTu2a(name.string_len, name.string, name_return, 
+                     MSBFirst, name_len);
+
+    /* Pretend that Apple Roman is ISO 8859-1. */
+    if(FTGetName(face, nid, TT_PLATFORM_MACINTOSH, TT_MAC_ID_ROMAN, &name)) {
+        len = name.string_len;
+        if(len > name_len  - 1)
+            len = name_len - 1;
+        memcpy(name_return, name.string, len);
+        name_return[len] = '\0'; /* ensure nul terminaison */
+        return len;
+    }
+
+    /* Must be some font that can only be named in Polish or something. */
+    return -1;
+}
diff --git a/src/FreeType/xttcap.c b/src/FreeType/xttcap.c
new file mode 100755 (executable)
index 0000000..c2a4120
--- /dev/null
@@ -0,0 +1,705 @@
+/* ===EmacsMode: -*- Mode: C; tab-width:4; c-basic-offset: 4; -*- === */
+/* ===FileName: ===
+   Copyright (c) 1998 Takuya SHIOZAKI, All Rights reserved.
+   Copyright (c) 1998 X-TrueType Server Project, All rights reserved. 
+   Copyright (c) 2003 After X-TT Project, All rights reserved.
+
+===Notice
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   1. Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+   2. Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+
+   THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+   FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+   OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+   OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+   SUCH DAMAGE.
+
+   Major Release ID: X-TrueType Server Version 1.4 [Charles's Wain Release 0]
+
+Notice===
+ */
+
+/*
+#include "xttversion.h"
+
+static char const * const releaseID =
+    _XTT_RELEASE_NAME;
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fontmisc.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+
+#ifndef True
+#define True (-1)
+#endif /* True */
+#ifndef False
+#define False (0)
+#endif /* False */
+
+#include "xttcap.h"
+
+
+/**************************************************************************
+  Private Data Types
+ */
+
+/* Property Record List */
+/* List Node */
+typedef struct TagSPropRecValListNodeP
+{
+    SPropRecValContainerEntityP containerE;
+    struct TagSPropRecValListNodeP *nextNode;
+} SPropRecValListNodeP;
+
+
+/**************************************************************************
+  Tables
+ */
+
+/* valid record field */
+static SPropertyRecord const validRecords[] =
+{
+    { "FontFile",               eRecTypeString  },
+    { "FaceNumber",             eRecTypeString },
+    { "AutoItalic",             eRecTypeDouble  },
+    { "DoubleStrike",           eRecTypeString  },
+    { "FontProperties",         eRecTypeBool    },
+    { "ForceSpacing",           eRecTypeString  },
+    { "ScaleBBoxWidth",         eRecTypeString  },
+    { "ScaleWidth",             eRecTypeDouble  },
+    { "EncodingOptions",        eRecTypeString  },
+    { "Hinting",                eRecTypeBool    },
+    { "VeryLazyMetrics",        eRecTypeBool    },
+    { "CodeRange",              eRecTypeString  },
+    { "EmbeddedBitmap",         eRecTypeString  },
+    { "VeryLazyBitmapWidthScale", eRecTypeDouble  },
+    { "ForceConstantSpacingCodeRange", eRecTypeString },
+    { "ForceConstantSpacingMetrics", eRecTypeString },
+    { "Dummy",                  eRecTypeVoid    }
+};
+static int const
+numOfValidRecords = sizeof(validRecords)/sizeof(validRecords[0]);
+
+/* correspondence between record name and cap variable name */
+static struct {
+    char const * capVariable;
+    char const * recordName;
+} const correspondRelations[] = {
+    { "fn", "FaceNumber" },
+    { "ai", "AutoItalic" },
+    { "ds", "DoubleStrike" },
+    { "fp", "FontProperties" },
+    { "fs", "ForceSpacing" },
+    { "bw", "ScaleBBoxWidth" },
+    { "sw", "ScaleWidth" },
+    { "eo", "EncodingOptions" },
+    { "vl", "VeryLazyMetrics" },
+    { "bs", "VeryLazyBitmapWidthScale" },
+    { "cr", "CodeRange" },
+    { "eb", "EmbeddedBitmap" },
+    { "hi", "Hinting" },
+    { "fc", "ForceConstantSpacingCodeRange" },
+    { "fm", "ForceConstantSpacingMetrics" }
+};
+static int const
+numOfCorrespondRelations
+= sizeof(correspondRelations)/sizeof(correspondRelations[0]);
+
+/**************************************************************************
+  Functions
+ */
+
+/* get property record type by record name */
+static Bool /* True == Found, False == Not Found */
+get_record_type_by_name(SPropertyRecord const ** const refRefRecord, /*result*/
+                        char const *strName)
+{
+    Bool result = False;
+    int i;
+    
+    *refRefRecord = NULL;
+    for (i=0; i<numOfValidRecords; i++) {
+        if (!strcasecmp(validRecords[i].strRecordName, strName)) {
+            result = True;
+            *refRefRecord = &validRecords[i];
+            break;
+        }
+    }
+    
+    return result;
+}
+
+/* Add Property Record Value */
+static Bool /* True == Error, False == Success */
+SPropRecValList_add_record(SDynPropRecValList *pThisList,
+                           char const * const recordName,
+                           char const * const strValue)
+{
+    Bool result = False;
+    SPropRecValContainerEntityP tmpContainerE;
+
+    if (get_record_type_by_name(&tmpContainerE.refRecordType, recordName)) {
+        switch (tmpContainerE.refRecordType->recordType) {
+        case eRecTypeInteger:
+            {
+                int val;
+                char *endPtr;
+                    
+                val = strtol(strValue, &endPtr, 0);
+                if ('\0' != *endPtr) {
+                    fprintf(stderr,
+                            "truetype font property : "
+                            "%s record needs integer value.\n",
+                            recordName);
+                    result = True;
+                    goto quit;
+                }
+                SPropContainer_value_int(&tmpContainerE) = val;
+            }
+            break;
+        case eRecTypeDouble:
+            {
+                double val;
+                char *endPtr;
+                    
+                val = strtod(strValue, &endPtr);
+                if ('\0' != *endPtr) {
+                    fprintf(stderr,
+                            "truetype font property : "
+                            "%s record needs floating point value.\n",
+                            recordName);
+                    result = True;
+                    goto quit;
+                }
+                SPropContainer_value_dbl(&tmpContainerE) = val;
+            }
+            break;
+        case eRecTypeBool:
+            {
+                Bool val;
+                
+                if (!strcasecmp(strValue, "yes"))
+                    val = True;
+                else if (!strcasecmp(strValue, "y"))
+                    val = True;
+                else if (!strcasecmp(strValue, "on"))
+                    val = True;
+                else if (!strcasecmp(strValue, "true"))
+                    val = True;
+                else if (!strcasecmp(strValue, "t"))
+                    val = True;
+                else if (!strcasecmp(strValue, "ok"))
+                    val = True;
+                else if (!strcasecmp(strValue, "no"))
+                    val = False;
+                else if (!strcasecmp(strValue, "n"))
+                    val = False;
+                else if (!strcasecmp(strValue, "off"))
+                    val = False;
+                else if (!strcasecmp(strValue, "false"))
+                    val = False;
+                else if (!strcasecmp(strValue, "f"))
+                    val = False;
+                else if (!strcasecmp(strValue, "bad"))
+                    val = False;
+                else {
+                    fprintf(stderr,
+                            "truetype font property : "
+                            "%s record needs boolean value.\n",
+                            recordName);
+                    result = True;
+                    goto quit;
+                }
+                SPropContainer_value_bool(&tmpContainerE) = val;
+            }
+            break;
+        case eRecTypeString:
+            {
+                char *p;
+                    
+                if (NULL == (p = malloc(strlen(strValue)+1))) {
+                    fprintf(stderr,
+                            "truetype font property : "
+                            "cannot allocate memory.\n");
+                    result = True;
+                    goto quit;
+                }
+                strcpy(p, strValue);
+                SPropContainer_value_str(&tmpContainerE) = p;
+            }
+            break;
+        case eRecTypeVoid:
+            if ('\0' != *strValue) {
+                fprintf(stderr,
+                        "truetype font property : "
+                        "%s record needs void.\n", recordName);
+                result = True;
+            }
+            break;
+        }
+        {
+            /* add to list */
+            SPropRecValListNodeP *newNode;
+            
+            if (NULL == (newNode = malloc(sizeof(*newNode)))) {
+                fprintf(stderr,
+                        "truetype font property : "
+                        "cannot allocate memory.\n");
+                result = True;
+                goto quit;
+            }
+            newNode->nextNode = pThisList->headNode;
+            newNode->containerE = tmpContainerE;
+            tmpContainerE.refRecordType = NULL; /* invalidate --
+                                                   disown value handle. */
+            pThisList->headNode = newNode;
+        }
+    } else {
+        /* invalid record name */
+        fprintf(stderr,
+                "truetype font : "
+                "invalid record name \"%s.\"\n", recordName);
+        result = True;
+    }
+
+ quit:
+    return result;
+}
+
+#ifdef USE_TTP_FILE
+
+#ifndef LEN_LINEBUF
+#define LEN_LINEBUF 2048
+#endif /* !def LEN_LINEBUF */
+
+/* get one line */
+static Bool /* True == Error, False == Success */
+get_one_line(FILE *is, char *buf)
+{
+    Bool result = False;
+    int count = 0;
+    Bool flHead = True;
+    Bool flSpace = False;
+    Bool flInSingleQuote = False;
+    Bool flInDoubleQuote = False;
+    Bool flBackSlash = False;
+    Bool flFirstElement = True;
+    
+    *buf = '\0';
+    for (;;) {
+        int c = fgetc(is);
+        
+        if (ferror(is)) {
+            fprintf(stderr, "truetype font property file : read error.\n");
+            result = True;
+            break;
+        }
+
+        if (EOF == c) {
+            if (flInSingleQuote || flInDoubleQuote) {
+                fprintf(stderr,
+                        "truetype font property file : unmatched quote.\n");
+                result = True;
+            }
+            break;
+        }
+        if (flInSingleQuote) {
+            if ('\'' == c) {
+                /* end of single quoted string */
+                flInSingleQuote = False;
+                c = -1; /* NOT extract to buffer. */
+            } else
+                /* others, extract all character to buffer unconditionally. */
+                ;
+            goto trans;
+        }
+        if (flBackSlash) {
+            /* escape --- when just before character is backslash,
+               next character is escaped. */
+            flBackSlash = False;
+            if ('n' == c)
+                /* newline */
+                c = '\n';
+            if ('\n' == c)
+                /* ignore newline */
+                c = -1;
+            else
+                /* others, extract all character to buffer unconditionally. */
+                ;
+            goto trans;
+        }
+        if ('\\' == c) {
+            /* set flag to escape next character. */
+            flBackSlash = True;
+            c = -1; /* NOT extract to buffer. */
+            goto trans;
+        }
+        if (flInDoubleQuote) {
+            if ('"' == c) {
+                /* end of double quoted string */
+                flInDoubleQuote = False;
+                c = -1; /* NOT extract to buffer. */
+            } else
+                /* others, extract all character to buffer unconditionally. */
+                ;
+            goto trans;
+        }
+        if ('#' == c) {
+            /* skip comment till end of line. */
+            while ('\n' != c) {
+                c = fgetc(is);
+                if (ferror(is)) {
+                    fprintf(stderr,
+                            "truetype font property file : read error.\n");
+                    result = True;
+                    break;
+                }
+                if (EOF == c) {
+                    break;
+                }
+            }
+            break;
+        }
+        if ('\'' == c) {
+            /* into single quoted string */
+            flInSingleQuote = True;
+            c = -1; /* NOT extract to buffer. */
+            goto trans;
+        }
+        if ('"' == c) {
+            /* into double quoted string */
+            flInDoubleQuote = True;
+            c = -1; /* NOT extract to buffer. */
+            goto trans;
+        }
+        if ('\n' == c)
+            /* End of Line */
+            break;
+        if (isspace(c)) {
+            /* convine multiple spaces */
+            if (!flHead)
+                /* except space at the head of line */
+                flSpace = True;
+            continue;
+        }
+      trans:
+        /* set flHead to False, since current character is not white space
+           when reaches here. */
+        flHead = False;
+        do {
+          if (count>=LEN_LINEBUF-1) {
+              /* overflow */
+              fprintf(stderr,
+                      "truetype font property file : too long line.\n");
+              result = True;
+              goto quit;
+          }
+          if (flSpace) {
+              /* just before characters is white space, but
+                 current character is not WS. */
+              if (flFirstElement) {
+                  /* this spaces is the first cell(?) of white spaces. */
+                  flFirstElement = False;
+                  /* separate record name and record value */
+                  *buf = (char)0xff;
+              } else
+                  *buf = ' ';
+              flSpace = False;
+          } else
+              if (-1 != c) {
+                  *buf = c;
+                  c = -1; /* invalidate */
+              } else
+                  /* skip */
+                  buf--;
+          buf++;
+        } while (-1 != c); /* when 'c' is not -1, it means
+                              that 'c' contains an untreated character. */
+    }
+    *buf = '\0';
+
+  quit:
+    return result;
+}
+
+/* parse one line */
+static Bool /* True == Error, False == Success */
+parse_one_line(SDynPropRecValList *pThisList, FILE *is)
+{
+    Bool result = False;
+    char *buf = NULL;
+    char *recordHead, *valueHead = NULL;
+    
+    if (NULL == (buf = malloc(LEN_LINEBUF))) {
+        fprintf(stderr,
+                "truetype font property file : cannot allocate memory.\n");
+        result = True;
+        goto abort;
+    }
+    {
+        recordHead = buf;
+/*        refRecordValue->refRecordType = NULL;*/
+        do {
+            if (get_one_line(is, buf)) {
+                result = True;
+                goto quit;
+            }
+            if (feof(is)) {
+                if ('\0' == *buf)
+                    goto quit;
+                break;
+            }
+        } while ('\0' == *buf);
+
+        if (NULL != (valueHead = strchr(buf, 0xff))) {
+            *valueHead = '\0';
+            valueHead++;
+        } else
+            valueHead = buf+strlen(buf);
+#if 0
+        fprintf(stderr,
+                "truetype font property file : \n"
+                "recName:\"%s\"\nvalue:\"%s\"\n",
+                recordHead, valueHead);
+#endif
+        result = SPropRecValList_add_record(pThisList, recordHead, valueHead);
+    }
+  quit:
+    free(buf);
+  abort:    
+    return result;
+}
+
+/* Read Property File */
+Bool /* True == Error, False == Success */
+SPropRecValList_read_prop_file(SDynPropRecValList *pThisList,
+                               char const * const strFileName)
+{
+    Bool result = False;
+    FILE *is;
+    
+#if 1
+    if (!strcmp(strFileName, "-"))
+        is = stdin;
+    else
+#endif
+        is = fopen(strFileName, "r");
+    if (NULL == is) {
+        fprintf(stderr, "truetype font property : cannot open file %s.\n",
+                strFileName);
+        result = True;
+        goto abort;
+    }
+    {
+        for (;;) {
+            if (False != (result = parse_one_line(pThisList, is)))
+                goto quit;
+            if (feof(is))
+                break;
+        }
+    }
+  quit:
+#if 1
+    if (strcmp(strFileName, "-"))
+#endif
+        fclose(is);
+  abort:
+    return result;
+}
+#endif /* USE_TTP_FILE */
+
+/* Constructor for Container Node */
+Bool /* True == Error, False == Success */
+SPropRecValList_new(SDynPropRecValList *pThisList)
+{
+    Bool result = False;
+    
+    pThisList->headNode = NULL;
+
+    return result;
+}
+
+#ifdef DUMP
+void
+SPropRecValList_dump(SRefPropRecValList *pThisList)
+{
+    SPropRecValListNodeP *p;
+    for (p=pThisList->headNode; NULL!=p; p=p->nextNode) {
+        switch (p->containerE.refRecordType->recordType) {
+        case eRecTypeInteger:
+            fprintf(stderr, "%s = %d\n",
+                    p->containerE.refRecordType->strRecordName,
+                    p->containerE.uValue.integerValue);
+            break;
+        case eRecTypeDouble:
+            fprintf(stderr, "%s = %f\n",
+                    p->containerE.refRecordType->strRecordName,
+                    p->containerE.uValue.doubleValue);
+            break;
+        case eRecTypeBool:
+            fprintf(stderr, "%s = %s\n",
+                    p->containerE.refRecordType->strRecordName,
+                    p->containerE.uValue.boolValue
+                    ? "True":"False");
+            break;
+        case eRecTypeString:
+            fprintf(stderr, "%s = \"%s\"\n",
+                    p->containerE.refRecordType->strRecordName,
+                    p->containerE.uValue.dynStringValue);
+            break;
+        case eRecTypeVoid:
+            fprintf(stderr, "%s = void\n",
+                    p->containerE.refRecordType->strRecordName);
+            break;
+        }
+    }
+}
+#endif
+
+
+/* Search Property Record */
+Bool /* True == Hit, False == Miss */
+SPropRecValList_search_record(SRefPropRecValList *pThisList,
+                              SPropRecValContainer *refRecValue,
+                              char const * const recordName)
+{
+    Bool result = False;
+    SPropRecValListNodeP *p;
+    
+    *refRecValue = NULL;
+    for (p=pThisList->headNode; NULL!=p; p=p->nextNode) {
+        if (!strcasecmp(p->containerE.refRecordType->strRecordName,
+                          recordName)) {
+            *refRecValue = &p->containerE;
+            result = True;
+            break;
+        }
+    }
+
+    return result;
+}
+
+
+/* Parse TTCap */
+Bool /* True == Error, False == Success */
+SPropRecValList_add_by_font_cap(SDynPropRecValList *pThisList,
+                                char const *strCapHead)
+{
+    Bool result = False;
+    /*    SPropertyRecord const *refRecordType; */
+    char const *term;
+    
+    if (NULL == (term = strrchr(strCapHead, ':')))
+        goto abort;
+
+    {
+        /* for xfsft compatible */
+        char const *p;
+        for (p=term-1; p>=strCapHead; p--) {
+            if ( ':'==*p ) {
+                /*
+                 * :num:filename
+                 * ^p  ^term
+                 */
+                if ( p!=term ) {
+                    int len = term-p-1;
+                    char *value;
+
+                    len = term-p-1;
+                    value=malloc(len+1);
+                    memcpy(value, p+1, len);
+                    value[len]='\0';
+                    SPropRecValList_add_record(pThisList,
+                                               "FaceNumber",
+                                               value);
+                    free(value);
+                    term=p;
+                }
+                break;
+            }
+            if ( !isdigit(*p) )
+                break;
+        }
+    }
+
+    while (strCapHead<term) {
+        int i;
+        char const *nextColon = strchr(strCapHead, ':');
+        if (0<nextColon-strCapHead) {
+            char *duplicated = malloc((nextColon-strCapHead)+1);
+            {
+                char *value;
+            
+                memcpy(duplicated, strCapHead, nextColon-strCapHead);
+                duplicated[nextColon-strCapHead] = '\0';
+                if (NULL != (value=strchr(duplicated, '='))) {
+                    *value = '\0';
+                    value++;
+                } else
+                    value = &duplicated[nextColon-strCapHead];
+            
+                for (i=0; i<numOfCorrespondRelations; i++) {
+                    if (!strcasecmp(correspondRelations[i].capVariable,
+                                      duplicated)) {
+                        if (SPropRecValList_add_record(pThisList,
+                                                        correspondRelations[i]
+                                                       .recordName,
+                                                       value))
+                            break;
+                        goto next;
+                    }
+                }
+                fprintf(stderr, "truetype font : Illegal Font Cap.\n");
+                result = True;
+                break;
+              next:
+                ;
+            }
+            free(duplicated);
+        }
+        strCapHead = nextColon+1;
+    }
+    
+    /*  quit: */
+  abort:
+    return result;
+}
+
+
+/**************************************************************************
+  Functions (xttmisc)
+ */
+
+/* strdup clone with using the allocator of X server */
+char *
+XttXstrdup(char const *str)
+{
+    char *result;
+    
+    result = malloc(strlen(str)+1);
+
+    if (result)
+        strcpy(result, str);
+
+    return result;
+}
+
+
+/* end of file */
diff --git a/src/FreeType/xttcap.h b/src/FreeType/xttcap.h
new file mode 100755 (executable)
index 0000000..6a09cf6
--- /dev/null
@@ -0,0 +1,130 @@
+/* ===EmacsMode: -*- Mode: C; tab-width:4; c-basic-offset: 4; -*- === */
+/* ===FileName: ===
+   Copyright (c) 1998 Takuya SHIOZAKI, All Rights reserved.
+   Copyright (c) 1998 X-TrueType Server Project, All rights reserved. 
+   Copyright (c) 2003 After X-TT Project, All rights reserved. 
+
+===Notice
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   1. Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+   2. Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+
+   THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+   FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+   OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+   OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+   SUCH DAMAGE.
+
+   Major Release ID: X-TrueType Server Version 1.3 [Aoi MATSUBARA Release 3]
+
+Notice===
+ */
+
+#ifndef _XTTCAP_H_
+#define _XTTCAP_H_ (1)
+
+#include <X11/Xdefs.h>
+
+/*******************************************************************
+  Data Types
+ */
+
+/* Record Type */
+typedef enum
+{
+    eRecTypeInteger,
+    eRecTypeDouble,
+    eRecTypeBool,
+    eRecTypeString,
+    eRecTypeVoid=-1
+} ERecType;
+
+/* Record Name vs Record Type */
+typedef struct
+{
+    char const *strRecordName;
+    ERecType const recordType;
+} SPropertyRecord;
+
+/* Record Value Container */
+typedef struct
+{
+    SPropertyRecord const *refRecordType;
+    union {
+        int integerValue;
+        double doubleValue;
+        Bool boolValue;
+        char *dynStringValue;
+    } uValue;
+} SPropRecValContainerEntityP, *SPropRecValContainer;
+
+/* Record Value List */
+typedef struct TagSPropRecValListNodeP SPropRecValListNode;
+typedef struct
+{
+    SPropRecValListNode *headNode;
+} SDynPropRecValList;
+typedef SDynPropRecValList const SRefPropRecValList;
+
+
+/*******************************************************************
+  Functions
+ */
+
+/* Constructor for Rec Val List */
+extern Bool /* True == Error, False == Success */
+SPropRecValList_new(SDynPropRecValList *pThisList);
+/* Destructor for Rec Val List */
+extern Bool /* True == Error, False == Success */
+SPropRecValList_delete(SDynPropRecValList *pThisList);
+/* Read Property File */
+extern Bool /* True == Error, False == Success */
+SPropRecValList_read_prop_file(SDynPropRecValList *pThisList,
+                               char const * const strFileName);
+/* Search Property Record */
+extern Bool /* True == Hit, False == Miss */
+SPropRecValList_search_record(SRefPropRecValList *pThisList,
+                              SPropRecValContainer *refContRecVal,
+                              char const * const recordName);
+/* Add by Font Cap */
+extern Bool /* True == Error, False == Success */
+SPropRecValList_add_by_font_cap(SDynPropRecValList *pThisList,
+                                char const *strCapHead);
+
+#ifdef DUMP
+void
+SPropRecValList_dump(SRefPropRecValList *refList);
+#endif
+
+#define SPropContainer_value_int(contRecVal)\
+  ((contRecVal)->uValue.integerValue)
+#define SPropContainer_value_dbl(contRecVal)\
+  ((contRecVal)->uValue.doubleValue)
+#define SPropContainer_value_bool(contRecVal)\
+  ((contRecVal)->uValue.boolValue)
+#define SPropContainer_value_str(contRecVal)\
+  ((contRecVal)->uValue.dynStringValue)
+
+/******************************************************
+  Prototypes (xttmisc)
+ */
+
+/* strdup clone */
+char * XttXstrdup(char const *str);
+#undef xstrdup
+#define xstrdup(s) XttXstrdup((char const*)s)
+
+#endif /* !def _XTTCAP_H_ */
+
+/* end of file */
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100755 (executable)
index 0000000..26551bc
--- /dev/null
@@ -0,0 +1,68 @@
+# 
+#  Copyright Â© 2003 Keith Packard, Noah Levitt
+# 
+#  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.
+
+lib_LTLIBRARIES = libXfont.la
+
+AM_CFLAGS = $(OS_CFLAGS) $(CWARNFLAGS)
+
+if XFONT_FONTFILE
+FONTFILE_DIR = fontfile
+FONTFILE_LIB = fontfile/libfontfile.la
+endif
+
+if XFONT_FREETYPE
+FREETYPE_DIR = FreeType
+FREETYPE_LIB = FreeType/libft.la
+endif
+
+if XFONT_BITMAP
+BITMAP_DIR = bitmap
+BITMAP_LIB = bitmap/libbitmap.la
+endif
+
+if XFONT_BUILTINS
+BUILTINS_DIR = builtins
+BUILTINS_LIB = builtins/libbuiltins.la
+endif
+
+if XFONT_FC
+FC_DIR = fc
+FC_LIB = fc/libfc.la
+endif
+
+UTIL_DIR = util
+UTIL_LIB = util/libutil.la
+
+STUBS_LIB = stubs/libstubs.la
+STUBS_DIR = stubs
+
+SUBDIRS=\
+       $(FONTFILE_DIR) $(FREETYPE_DIR) $(BITMAP_DIR) \
+       $(BUILTINS_DIR) $(FC_DIR) $(UTIL_DIR) $(STUBS_DIR)
+
+libXfont_la_LIBADD = \
+       $(FONTFILE_LIB) $(FREETYPE_LIB) $(BITMAP_LIB) \
+       $(BUILTINS_LIB) $(FC_LIB) $(UTIL_LIB) $(STUBS_LIB) \
+       $(FREETYPE_LIBS) $(Z_LIBS) $(MATH_LIBS) $(XFONT_LIBS)
+
+libXfont_la_SOURCES = dummy.c
+
+libXfont_la_LDFLAGS = -version-number 1:4:1
diff --git a/src/bitmap/Makefile.am b/src/bitmap/Makefile.am
new file mode 100755 (executable)
index 0000000..b5b9674
--- /dev/null
@@ -0,0 +1,19 @@
+INCLUDES =                     \
+       -I${top_srcdir}/include
+
+AM_CFLAGS = $(XFONT_CFLAGS) $(OS_CFLAGS) $(CWARNFLAGS)
+
+noinst_LTLIBRARIES = libbitmap.la
+
+libbitmap_la_SOURCES =                 \
+       bdfread.c               \
+       bdfutils.c              \
+       bitmap.c                \
+       bitmapfunc.c            \
+       bitmaputil.c            \
+       bitscale.c              \
+       fontink.c               \
+       pcfread.c               \
+       pcfwrite.c              \
+       snfread.c               \
+       snfstr.h
diff --git a/src/bitmap/bdfread.c b/src/bitmap/bdfread.c
new file mode 100755 (executable)
index 0000000..2464c03
--- /dev/null
@@ -0,0 +1,955 @@
+/************************************************************************
+Copyright 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+************************************************************************/
+
+/*
+
+Copyright 1994, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <ctype.h>
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/fontutil.h>
+/* use bitmap structure */
+#include <X11/fonts/bitmap.h>
+#include <X11/fonts/bdfint.h>
+
+#if HAVE_STDINT_H
+#include <stdint.h>
+#elif !defined(INT32_MAX)
+#define INT32_MAX 0x7fffffff
+#endif
+
+#define INDICES 256
+#define MAXENCODING 0xFFFF
+#define BDFLINELEN  1024
+
+static Bool bdfPadToTerminal(FontPtr pFont);
+extern int  bdfFileLineNum;
+
+/***====================================================================***/
+
+static Bool
+bdfReadBitmap(CharInfoPtr pCI, FontFilePtr file, int bit, int byte, 
+             int glyph, int scan, CARD32 *sizes)
+{
+    int         widthBits,
+                widthBytes,
+                widthHexChars;
+    int         height,
+                row;
+    int         i,
+                inLineLen,
+                nextByte;
+    unsigned char *pInBits,
+               *picture,
+               *line = NULL;
+    unsigned char        lineBuf[BDFLINELEN];
+
+    widthBits = GLYPHWIDTHPIXELS(pCI);
+    height = GLYPHHEIGHTPIXELS(pCI);
+
+    widthBytes = BYTES_PER_ROW(widthBits, glyph);
+    if (widthBytes * height > 0) {
+       picture = malloc(widthBytes * height);
+       if (!picture) {
+          bdfError("Couldn't allocate picture (%d*%d)\n", widthBytes, height);        
+           goto BAILOUT;
+      }
+    } else
+       picture = NULL;
+    pCI->bits = (char *) picture;
+
+    if (sizes) {
+       for (i = 0; i < GLYPHPADOPTIONS; i++)
+           sizes[i] += BYTES_PER_ROW(widthBits, (1 << i)) * height;
+    }
+    nextByte = 0;
+    widthHexChars = BYTES_PER_ROW(widthBits, 1);
+
+/* 5/31/89 (ef) -- hack, hack, hack.  what *am* I supposed to do with */
+/*             0 width characters? */
+
+    for (row = 0; row < height; row++) {
+       line = bdfGetLine(file, lineBuf, BDFLINELEN);
+       if (!line)
+           break;
+
+       if (widthBits == 0) {
+           if ((!line) || (bdfIsPrefix(line, "ENDCHAR")))
+               break;
+           else
+               continue;
+       }
+       pInBits = line;
+       inLineLen = strlen((char *) pInBits);
+
+       if (inLineLen & 1) {
+           bdfError("odd number of characters in hex encoding\n");
+           line[inLineLen++] = '0';
+           line[inLineLen] = '\0';
+       }
+       inLineLen >>= 1;
+       i = inLineLen;
+       if (i > widthHexChars)
+           i = widthHexChars;
+       for (; i > 0; i--, pInBits += 2)
+           picture[nextByte++] = bdfHexByte(pInBits);
+
+       /* pad if line is too short */
+       if (inLineLen < widthHexChars) {
+           for (i = widthHexChars - inLineLen; i > 0; i--)
+               picture[nextByte++] = 0;
+       } else {
+           unsigned char mask;
+
+           mask = 0xff << (8 - (widthBits & 0x7));
+           if (mask && picture[nextByte - 1] & ~mask) {
+               picture[nextByte - 1] &= mask;
+           }
+       }
+
+       if (widthBytes > widthHexChars) {
+           i = widthBytes - widthHexChars;
+           while (i-- > 0)
+               picture[nextByte++] = 0;
+       }
+    }
+
+    if ((line && (!bdfIsPrefix(line, "ENDCHAR"))) || (height == 0))
+       line = bdfGetLine(file, lineBuf, BDFLINELEN);
+
+    if ((!line) || (!bdfIsPrefix(line, "ENDCHAR"))) {
+       bdfError("missing 'ENDCHAR'\n");
+       goto BAILOUT;
+    }
+    if (nextByte != height * widthBytes) {
+       bdfError("bytes != rows * bytes_per_row (%d != %d * %d)\n",
+                nextByte, height, widthBytes);
+       goto BAILOUT;
+    }
+    if (picture != NULL) {
+       if (bit == LSBFirst)
+           BitOrderInvert(picture, nextByte);
+       if (bit != byte) {
+           if (scan == 2)
+               TwoByteSwap(picture, nextByte);
+           else if (scan == 4)
+               FourByteSwap(picture, nextByte);
+       }
+    }
+    return (TRUE);
+BAILOUT:
+    if (picture)
+       free(picture);
+    pCI->bits = NULL;
+    return (FALSE);
+}
+
+/***====================================================================***/
+
+static Bool
+bdfSkipBitmap(FontFilePtr file, int height)
+{
+    unsigned char *line;
+    int         i = 0;
+    unsigned char        lineBuf[BDFLINELEN];
+
+    do {
+       line = bdfGetLine(file, lineBuf, BDFLINELEN);
+       i++;
+    } while (line && !bdfIsPrefix(line, "ENDCHAR") && i <= height);
+
+    if (i > 1 && line && !bdfIsPrefix(line, "ENDCHAR")) {
+       bdfError("Error in bitmap, missing 'ENDCHAR'\n");
+       return (FALSE);
+    }
+    return (TRUE);
+}
+
+/***====================================================================***/
+
+static void
+bdfFreeFontBits(FontPtr pFont)
+{
+    BitmapFontPtr  bitmapFont;
+    BitmapExtraPtr bitmapExtra;
+    int         i, nencoding;
+
+    bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+    bitmapExtra = (BitmapExtraPtr) bitmapFont->bitmapExtra;
+    free(bitmapFont->ink_metrics);
+    if(bitmapFont->encoding) {
+        nencoding = (pFont->info.lastCol - pFont->info.firstCol + 1) *
+           (pFont->info.lastRow - pFont->info.firstRow + 1);
+        for(i=0; i<NUM_SEGMENTS(nencoding); i++)
+            free(bitmapFont->encoding[i]);
+    }
+    free(bitmapFont->encoding);
+    for (i = 0; i < bitmapFont->num_chars; i++)
+       free(bitmapFont->metrics[i].bits);
+    free(bitmapFont->metrics);
+    if (bitmapExtra)
+    {
+       free (bitmapExtra->glyphNames);
+       free (bitmapExtra->sWidths);
+       free (bitmapExtra);
+    }
+    free(pFont->info.props);
+    free(bitmapFont);
+}
+
+
+static Bool
+bdfReadCharacters(FontFilePtr file, FontPtr pFont, bdfFileState *pState, 
+                 int bit, int byte, int glyph, int scan)
+{
+    unsigned char *line;
+    register CharInfoPtr ci;
+    int         i,
+                ndx,
+                nchars,
+                nignored;
+    unsigned int char_row, char_col;
+    int         numEncodedGlyphs = 0;
+    CharInfoPtr *bdfEncoding[256];
+    BitmapFontPtr  bitmapFont;
+    BitmapExtraPtr bitmapExtra;
+    CARD32     *bitmapsSizes;
+    unsigned char        lineBuf[BDFLINELEN];
+    int         nencoding;
+
+    bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+    bitmapExtra = (BitmapExtraPtr) bitmapFont->bitmapExtra;
+
+    if (bitmapExtra) {
+       bitmapsSizes = bitmapExtra->bitmapsSizes;
+       for (i = 0; i < GLYPHPADOPTIONS; i++)
+           bitmapsSizes[i] = 0;
+    } else
+       bitmapsSizes = NULL;
+
+    bzero(bdfEncoding, sizeof(bdfEncoding));
+    bitmapFont->metrics = NULL;
+    ndx = 0;
+
+    line = bdfGetLine(file, lineBuf, BDFLINELEN);
+
+    if ((!line) || (sscanf((char *) line, "CHARS %d", &nchars) != 1)) {
+       bdfError("bad 'CHARS' in bdf file\n");
+       return (FALSE);
+    }
+    if (nchars < 1) {
+       bdfError("invalid number of CHARS in BDF file\n");
+       return (FALSE);
+    }
+    if (nchars > INT32_MAX / sizeof(CharInfoRec)) {
+       bdfError("Couldn't allocate pCI (%d*%d)\n", nchars,
+                sizeof(CharInfoRec));
+       goto BAILOUT;
+    }
+    ci = calloc(nchars, sizeof(CharInfoRec));
+    if (!ci) {
+       bdfError("Couldn't allocate pCI (%d*%d)\n", nchars,
+                sizeof(CharInfoRec));
+       goto BAILOUT;
+    }
+    bitmapFont->metrics = ci;
+
+    if (bitmapExtra) {
+       bitmapExtra->glyphNames = malloc(nchars * sizeof(Atom));
+       if (!bitmapExtra->glyphNames) {
+           bdfError("Couldn't allocate glyphNames (%d*%d)\n",
+                    nchars, sizeof(Atom));
+           goto BAILOUT;
+       }
+    }
+    if (bitmapExtra) {
+       bitmapExtra->sWidths = malloc(nchars * sizeof(int));
+       if (!bitmapExtra->sWidths) {
+           bdfError("Couldn't allocate sWidth (%d *%d)\n",
+                    nchars, sizeof(int));
+           return FALSE;
+       }
+    }
+    line = bdfGetLine(file, lineBuf, BDFLINELEN);
+    pFont->info.firstRow = 256;
+    pFont->info.lastRow = 0;
+    pFont->info.firstCol = 256;
+    pFont->info.lastCol = 0;
+    nignored = 0;
+    for (ndx = 0; (ndx < nchars) && (line) && (bdfIsPrefix(line, "STARTCHAR"));) {
+       int         t;
+       int         wx;         /* x component of width */
+       int         wy;         /* y component of width */
+       int         bw;         /* bounding-box width */
+       int         bh;         /* bounding-box height */
+       int         bl;         /* bounding-box left */
+       int         bb;         /* bounding-box bottom */
+       int         enc,
+                   enc2;       /* encoding */
+       unsigned char *p;       /* temp pointer into line */
+       char        charName[100];
+       int         ignore;
+
+       if (sscanf((char *) line, "STARTCHAR %s", charName) != 1) {
+           bdfError("bad character name in BDF file\n");
+           goto BAILOUT;       /* bottom of function, free and return error */
+       }
+       if (bitmapExtra)
+           bitmapExtra->glyphNames[ndx] = bdfForceMakeAtom(charName, NULL);
+
+       line = bdfGetLine(file, lineBuf, BDFLINELEN);
+       if (!line || (t = sscanf((char *) line, "ENCODING %d %d", &enc, &enc2)) < 1) {
+           bdfError("bad 'ENCODING' in BDF file\n");
+           goto BAILOUT;
+       }
+       if (enc < -1 || (t == 2 && enc2 < -1)) {
+           bdfError("bad ENCODING value");
+           goto BAILOUT;
+       }
+       if (t == 2 && enc == -1)
+           enc = enc2;
+       ignore = 0;
+       if (enc == -1) {
+           if (!bitmapExtra) {
+               nignored++;
+               ignore = 1;
+           }
+       } else if (enc > MAXENCODING) {
+           bdfError("char '%s' has encoding too large (%d)\n",
+                    charName, enc);
+       } else {
+           char_row = (enc >> 8) & 0xFF;
+           char_col = enc & 0xFF;
+           if (char_row < pFont->info.firstRow)
+               pFont->info.firstRow = char_row;
+           if (char_row > pFont->info.lastRow)
+               pFont->info.lastRow = char_row;
+           if (char_col < pFont->info.firstCol)
+               pFont->info.firstCol = char_col;
+           if (char_col > pFont->info.lastCol)
+               pFont->info.lastCol = char_col;
+           if (bdfEncoding[char_row] == (CharInfoPtr *) NULL) {
+               bdfEncoding[char_row] = malloc(256 * sizeof(CharInfoPtr));
+               if (!bdfEncoding[char_row]) {
+                   bdfError("Couldn't allocate row %d of encoding (%d*%d)\n",
+                            char_row, INDICES, sizeof(CharInfoPtr));
+                   goto BAILOUT;
+               }
+               for (i = 0; i < 256; i++)
+                   bdfEncoding[char_row][i] = (CharInfoPtr) NULL;
+           }
+           if (bdfEncoding[char_row] != NULL) {
+               bdfEncoding[char_row][char_col] = ci;
+               numEncodedGlyphs++;
+           }
+       }
+
+       line = bdfGetLine(file, lineBuf, BDFLINELEN);
+       if ((!line) || (sscanf((char *) line, "SWIDTH %d %d", &wx, &wy) != 2)) {
+           bdfError("bad 'SWIDTH'\n");
+           goto BAILOUT;
+       }
+       if (wy != 0) {
+           bdfError("SWIDTH y value must be zero\n");
+           goto BAILOUT;
+       }
+       if (bitmapExtra)
+           bitmapExtra->sWidths[ndx] = wx;
+
+/* 5/31/89 (ef) -- we should be able to ditch the character and recover */
+/*             from all of these.                                      */
+
+       line = bdfGetLine(file, lineBuf, BDFLINELEN);
+       if ((!line) || (sscanf((char *) line, "DWIDTH %d %d", &wx, &wy) != 2)) {
+           bdfError("bad 'DWIDTH'\n");
+           goto BAILOUT;
+       }
+       if (wy != 0) {
+           bdfError("DWIDTH y value must be zero\n");
+           goto BAILOUT;
+       }
+       line = bdfGetLine(file, lineBuf, BDFLINELEN);
+       if ((!line) || (sscanf((char *) line, "BBX %d %d %d %d", &bw, &bh, &bl, &bb) != 4)) {
+           bdfError("bad 'BBX'\n");
+           goto BAILOUT;
+       }
+       if ((bh < 0) || (bw < 0)) {
+           bdfError("character '%s' has a negative sized bitmap, %dx%d\n",
+                    charName, bw, bh);
+           goto BAILOUT;
+       }
+       line = bdfGetLine(file, lineBuf, BDFLINELEN);
+       if ((line) && (bdfIsPrefix(line, "ATTRIBUTES"))) {
+           for (p = line + strlen("ATTRIBUTES ");
+                   (*p == ' ') || (*p == '\t');
+                   p++)
+                /* empty for loop */ ;
+           ci->metrics.attributes = (bdfHexByte(p) << 8) + bdfHexByte(p + 2);
+           line = bdfGetLine(file, lineBuf, BDFLINELEN);
+       } else
+           ci->metrics.attributes = 0;
+
+       if (!line || !bdfIsPrefix(line, "BITMAP")) {
+           bdfError("missing 'BITMAP'\n");
+           goto BAILOUT;
+       }
+       /* collect data for generated properties */
+       if ((strlen(charName) == 1)) {
+           if ((charName[0] >= '0') && (charName[0] <= '9')) {
+               pState->digitWidths += wx;
+               pState->digitCount++;
+           } else if (charName[0] == 'x') {
+               pState->exHeight = (bh + bb) <= 0 ? bh : bh + bb;
+           }
+       }
+       if (!ignore) {
+           ci->metrics.leftSideBearing = bl;
+           ci->metrics.rightSideBearing = bl + bw;
+           ci->metrics.ascent = bh + bb;
+           ci->metrics.descent = -bb;
+           ci->metrics.characterWidth = wx;
+           ci->bits = NULL;
+           bdfReadBitmap(ci, file, bit, byte, glyph, scan, bitmapsSizes);
+           ci++;
+           ndx++;
+       } else
+           bdfSkipBitmap(file, bh);
+
+       line = bdfGetLine(file, lineBuf, BDFLINELEN);   /* get STARTCHAR or
+                                                        * ENDFONT */
+    }
+
+    if (ndx + nignored != nchars) {
+       bdfError("%d too few characters\n", nchars - (ndx + nignored));
+       goto BAILOUT;
+    }
+    nchars = ndx;
+    bitmapFont->num_chars = nchars;
+    if ((line) && (bdfIsPrefix(line, "STARTCHAR"))) {
+       bdfError("more characters than specified\n");
+       goto BAILOUT;
+    }
+    if ((!line) || (!bdfIsPrefix(line, "ENDFONT"))) {
+       bdfError("missing 'ENDFONT'\n");
+       goto BAILOUT;
+    }
+    if (numEncodedGlyphs == 0)
+       bdfWarning("No characters with valid encodings\n");
+
+    nencoding = (pFont->info.lastRow - pFont->info.firstRow + 1) *
+       (pFont->info.lastCol - pFont->info.firstCol + 1);
+    bitmapFont->encoding = calloc(NUM_SEGMENTS(nencoding),sizeof(CharInfoPtr*));
+    if (!bitmapFont->encoding) {
+       bdfError("Couldn't allocate ppCI (%d,%d)\n",
+                 NUM_SEGMENTS(nencoding),
+                 sizeof(CharInfoPtr*));
+       goto BAILOUT;
+    }
+    pFont->info.allExist = TRUE;
+    i = 0;
+    for (char_row = pFont->info.firstRow;
+           char_row <= pFont->info.lastRow;
+           char_row++) {
+       if (bdfEncoding[char_row] == (CharInfoPtr *) NULL) {
+           pFont->info.allExist = FALSE;
+            i += pFont->info.lastCol - pFont->info.firstCol + 1;
+       } else {
+           for (char_col = pFont->info.firstCol;
+                   char_col <= pFont->info.lastCol;
+                   char_col++) {
+               if (!bdfEncoding[char_row][char_col])
+                   pFont->info.allExist = FALSE;
+                else {
+                    if (!bitmapFont->encoding[SEGMENT_MAJOR(i)]) {
+                        bitmapFont->encoding[SEGMENT_MAJOR(i)]=
+                            calloc(BITMAP_FONT_SEGMENT_SIZE,
+                                   sizeof(CharInfoPtr));
+                        if (!bitmapFont->encoding[SEGMENT_MAJOR(i)])
+                            goto BAILOUT;
+                    }
+                    ACCESSENCODINGL(bitmapFont->encoding,i) = 
+                        bdfEncoding[char_row][char_col];
+                }
+                i++;
+            }
+       }
+    }
+    for (i = 0; i < 256; i++)
+       if (bdfEncoding[i])
+           free(bdfEncoding[i]);
+    return (TRUE);
+BAILOUT:
+    for (i = 0; i < 256; i++)
+       if (bdfEncoding[i])
+           free(bdfEncoding[i]);
+    /* bdfFreeFontBits will clean up the rest */
+    return (FALSE);
+}
+
+/***====================================================================***/
+
+static Bool
+bdfReadHeader(FontFilePtr file, bdfFileState *pState)
+{
+    unsigned char *line;
+    char        namebuf[BDFLINELEN];
+    unsigned char        lineBuf[BDFLINELEN];
+
+    line = bdfGetLine(file, lineBuf, BDFLINELEN);
+    if (!line || sscanf((char *) line, "STARTFONT %s", namebuf) != 1 ||
+           !bdfStrEqual(namebuf, "2.1")) {
+       bdfError("bad 'STARTFONT'\n");
+       return (FALSE);
+    }
+    line = bdfGetLine(file, lineBuf, BDFLINELEN);
+    if (!line || sscanf((char *) line, "FONT %[^\n]", pState->fontName) != 1) {
+       bdfError("bad 'FONT'\n");
+       return (FALSE);
+    }
+    line = bdfGetLine(file, lineBuf, BDFLINELEN);
+    if (!line || !bdfIsPrefix(line, "SIZE")) {
+       bdfError("missing 'SIZE'\n");
+       return (FALSE);
+    }
+    if (sscanf((char *) line, "SIZE %f%d%d", &pState->pointSize,
+              &pState->resolution_x, &pState->resolution_y) != 3) {
+       bdfError("bad 'SIZE'\n");
+       return (FALSE);
+    }
+    if (pState->pointSize < 1 ||
+       pState->resolution_x < 1 || pState->resolution_y < 1) {
+       bdfError("SIZE values must be > 0\n");
+       return (FALSE);
+    }
+    line = bdfGetLine(file, lineBuf, BDFLINELEN);
+    if (!line || !bdfIsPrefix(line, "FONTBOUNDINGBOX")) {
+       bdfError("missing 'FONTBOUNDINGBOX'\n");
+       return (FALSE);
+    }
+    return (TRUE);
+}
+
+/***====================================================================***/
+
+static Bool
+bdfReadProperties(FontFilePtr file, FontPtr pFont, bdfFileState *pState)
+{
+    int         nProps, props_left,
+                nextProp;
+    char       *stringProps;
+    FontPropPtr props;
+    char        namebuf[BDFLINELEN],
+                secondbuf[BDFLINELEN],
+                thirdbuf[BDFLINELEN];
+    unsigned char *line;
+    unsigned char        lineBuf[BDFLINELEN];
+    BitmapFontPtr  bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+
+    line = bdfGetLine(file, lineBuf, BDFLINELEN);
+    if (!line || !bdfIsPrefix(line, "STARTPROPERTIES")) {
+       bdfError("missing 'STARTPROPERTIES'\n");
+       return (FALSE);
+    }
+    if (sscanf((char *) line, "STARTPROPERTIES %d", &nProps) != 1) {
+       bdfError("bad 'STARTPROPERTIES'\n");
+       return (FALSE);
+    }
+    pFont->info.isStringProp = NULL;
+    pFont->info.props = NULL;
+    pFont->info.nprops = 0;
+
+    stringProps = malloc((nProps + BDF_GENPROPS) * sizeof(char));
+    pFont->info.isStringProp = stringProps;
+    if (stringProps == NULL) {
+       bdfError("Couldn't allocate stringProps (%d*%d)\n",
+                (nProps + BDF_GENPROPS), sizeof(Bool));
+       goto BAILOUT;
+    }
+    pFont->info.props = props = calloc(nProps + BDF_GENPROPS,
+                                      sizeof(FontPropRec));
+    if (props == NULL) {
+       bdfError("Couldn't allocate props (%d*%d)\n", nProps + BDF_GENPROPS,
+                                                     sizeof(FontPropRec));
+       goto BAILOUT;
+    }
+
+    nextProp = 0;
+    props_left = nProps;
+    while (props_left-- > 0) {
+       line = bdfGetLine(file, lineBuf, BDFLINELEN);
+       if (line == NULL || bdfIsPrefix(line, "ENDPROPERTIES")) {
+           bdfError("\"STARTPROPERTIES %d\" followed by only %d properties\n",
+                    nProps, nProps - props_left - 1);
+           goto BAILOUT;
+       }
+       while (*line && isspace(*line))
+           line++;
+
+       switch (sscanf((char *) line, "%s%s%s", namebuf, secondbuf, thirdbuf)) {
+       default:
+           bdfError("missing '%s' parameter value\n", namebuf);
+           goto BAILOUT;
+
+       case 2:
+           /*
+            * Possibilites include: valid quoted string with no white space
+            * valid integer value invalid value
+            */
+           if (secondbuf[0] == '"') {
+               stringProps[nextProp] = TRUE;
+               props[nextProp].value =
+                   bdfGetPropertyValue((char *)line + strlen(namebuf) + 1);
+               if (!props[nextProp].value)
+                   goto BAILOUT;
+               break;
+           } else if (bdfIsInteger(secondbuf)) {
+               stringProps[nextProp] = FALSE;
+               props[nextProp].value = atoi(secondbuf);
+               break;
+           } else {
+               bdfError("invalid '%s' parameter value\n", namebuf);
+               goto BAILOUT;
+           }
+
+       case 3:
+           /*
+            * Possibilites include: valid quoted string with some white space
+            * invalid value (reject even if second string is integer)
+            */
+           if (secondbuf[0] == '"') {
+               stringProps[nextProp] = TRUE;
+               props[nextProp].value =
+                   bdfGetPropertyValue((char *)line + strlen(namebuf) + 1);
+               if (!props[nextProp].value)
+                   goto BAILOUT;
+               break;
+           } else {
+               bdfError("invalid '%s' parameter value\n", namebuf);
+               goto BAILOUT;
+           }
+       }
+       props[nextProp].name = bdfForceMakeAtom(namebuf, NULL);
+       if (props[nextProp].name == None) {
+           bdfError("Empty property name.\n");
+           goto BAILOUT;
+       }
+       if (!bdfSpecialProperty(pFont, &props[nextProp],
+                               stringProps[nextProp], pState))
+           nextProp++;
+    }
+
+    line = bdfGetLine(file, lineBuf, BDFLINELEN);
+    if (!line || !bdfIsPrefix(line, "ENDPROPERTIES")) {
+       bdfError("missing 'ENDPROPERTIES'\n");
+       goto BAILOUT;
+    }
+    if (!pState->haveFontAscent || !pState->haveFontDescent) {
+       bdfError("missing 'FONT_ASCENT' or 'FONT_DESCENT' properties\n");
+       goto BAILOUT;
+    }
+    if (bitmapFont->bitmapExtra) {
+       bitmapFont->bitmapExtra->info.fontAscent = pFont->info.fontAscent;
+       bitmapFont->bitmapExtra->info.fontDescent = pFont->info.fontDescent;
+    }
+    if (!pState->pointSizeProp) {
+       props[nextProp].name = bdfForceMakeAtom("POINT_SIZE", NULL);
+       props[nextProp].value = (INT32) (pState->pointSize * 10.0);
+       stringProps[nextProp] = FALSE;
+       pState->pointSizeProp = &props[nextProp];
+       nextProp++;
+    }
+    if (!pState->fontProp) {
+       props[nextProp].name = bdfForceMakeAtom("FONT", NULL);
+       props[nextProp].value = (INT32) bdfForceMakeAtom(pState->fontName, NULL);
+       stringProps[nextProp] = TRUE;
+       pState->fontProp = &props[nextProp];
+       nextProp++;
+    }
+    if (!pState->weightProp) {
+       props[nextProp].name = bdfForceMakeAtom("WEIGHT", NULL);
+       props[nextProp].value = -1;     /* computed later */
+       stringProps[nextProp] = FALSE;
+       pState->weightProp = &props[nextProp];
+       nextProp++;
+    }
+    if (!pState->resolutionProp &&
+       pState->resolution_x == pState->resolution_y) {
+       props[nextProp].name = bdfForceMakeAtom("RESOLUTION", NULL);
+       props[nextProp].value = (INT32) ((pState->resolution_x * 100.0) / 72.27);
+       stringProps[nextProp] = FALSE;
+       pState->resolutionProp = &props[nextProp];
+       nextProp++;
+    }
+    if (!pState->resolutionXProp) {
+       props[nextProp].name = bdfForceMakeAtom("RESOLUTION_X", NULL);
+       props[nextProp].value = (INT32) pState->resolution_x;
+       stringProps[nextProp] = FALSE;
+       pState->resolutionProp = &props[nextProp];
+       nextProp++;
+    }
+    if (!pState->resolutionYProp) {
+       props[nextProp].name = bdfForceMakeAtom("RESOLUTION_Y", NULL);
+       props[nextProp].value = (INT32) pState->resolution_y;
+       stringProps[nextProp] = FALSE;
+       pState->resolutionProp = &props[nextProp];
+       nextProp++;
+    }
+    if (!pState->xHeightProp) {
+       props[nextProp].name = bdfForceMakeAtom("X_HEIGHT", NULL);
+       props[nextProp].value = -1;     /* computed later */
+       stringProps[nextProp] = FALSE;
+       pState->xHeightProp = &props[nextProp];
+       nextProp++;
+    }
+    if (!pState->quadWidthProp) {
+       props[nextProp].name = bdfForceMakeAtom("QUAD_WIDTH", NULL);
+       props[nextProp].value = -1;     /* computed later */
+       stringProps[nextProp] = FALSE;
+       pState->quadWidthProp = &props[nextProp];
+       nextProp++;
+    }
+    pFont->info.nprops = nextProp;
+    return (TRUE);
+BAILOUT:
+    if (pFont->info.isStringProp) {
+       free(pFont->info.isStringProp);
+       pFont->info.isStringProp = NULL;
+    }
+    if (pFont->info.props) {
+       free(pFont->info.props);
+       pFont->info.props = NULL;
+    }
+    while (line && bdfIsPrefix(line, "ENDPROPERTIES"))
+       line = bdfGetLine(file, lineBuf, BDFLINELEN);
+    return (FALSE);
+}
+
+/***====================================================================***/
+
+static void
+bdfUnloadFont(FontPtr pFont)
+{
+    bdfFreeFontBits (pFont);
+    DestroyFontRec(pFont);
+}
+
+int
+bdfReadFont(FontPtr pFont, FontFilePtr file, 
+           int bit, int byte, int glyph, int scan)
+{
+    bdfFileState state;
+    xCharInfo  *min,
+               *max;
+    BitmapFontPtr  bitmapFont;
+
+    pFont->fontPrivate = 0;
+
+    bzero(&state, sizeof(bdfFileState));
+    bdfFileLineNum = 0;
+
+    if (!bdfReadHeader(file, &state))
+       goto BAILOUT;
+
+    bitmapFont = calloc(1, sizeof(BitmapFontRec));
+    if (!bitmapFont) {
+      bdfError("Couldn't allocate bitmapFontRec (%d)\n", sizeof(BitmapFontRec));
+       goto BAILOUT;
+    }
+
+    pFont->fontPrivate = (pointer) bitmapFont;
+    bitmapFont->metrics = 0;
+    bitmapFont->ink_metrics = 0;
+    bitmapFont->bitmaps = 0;
+    bitmapFont->encoding = 0;
+    bitmapFont->pDefault = NULL;
+
+    bitmapFont->bitmapExtra = calloc(1, sizeof(BitmapExtraRec));
+    if (!bitmapFont->bitmapExtra) {
+      bdfError("Couldn't allocate bitmapExtra (%d)\n", sizeof(BitmapExtraRec));
+        goto BAILOUT;
+    }
+    
+    bitmapFont->bitmapExtra->glyphNames = 0;
+    bitmapFont->bitmapExtra->sWidths = 0;
+
+    if (!bdfReadProperties(file, pFont, &state))
+       goto BAILOUT;
+
+    if (!bdfReadCharacters(file, pFont, &state, bit, byte, glyph, scan))
+       goto BAILOUT;
+
+    if (state.haveDefaultCh) {
+       unsigned int r, c, cols;
+
+       r = pFont->info.defaultCh >> 8;
+       c = pFont->info.defaultCh & 0xFF;
+       if (pFont->info.firstRow <= r && r <= pFont->info.lastRow &&
+               pFont->info.firstCol <= c && c <= pFont->info.lastCol) {
+           cols = pFont->info.lastCol - pFont->info.firstCol + 1;
+           r = r - pFont->info.firstRow;
+           c = c - pFont->info.firstCol;
+           bitmapFont->pDefault = ACCESSENCODING(bitmapFont->encoding, 
+                                                 r * cols + c);
+       }
+    }
+    pFont->bit = bit;
+    pFont->byte = byte;
+    pFont->glyph = glyph;
+    pFont->scan = scan;
+    pFont->info.anamorphic = FALSE;
+    pFont->info.cachable = TRUE;
+    bitmapComputeFontBounds(pFont);
+    if (FontCouldBeTerminal(&pFont->info)) {
+       bdfPadToTerminal(pFont);
+       bitmapComputeFontBounds(pFont);
+    }
+    FontComputeInfoAccelerators(&pFont->info);
+    if (bitmapFont->bitmapExtra)
+       FontComputeInfoAccelerators(&bitmapFont->bitmapExtra->info);
+    if (pFont->info.constantMetrics) {
+      if (!bitmapAddInkMetrics(pFont)) {
+        bdfError("Failed to add bitmap ink metrics\n");
+        goto BAILOUT;
+      }
+    }    
+    if (bitmapFont->bitmapExtra)
+       bitmapFont->bitmapExtra->info.inkMetrics = pFont->info.inkMetrics;
+
+    bitmapComputeFontInkBounds(pFont);
+/*    ComputeFontAccelerators (pFont); */
+
+    /* generate properties */
+    min = &pFont->info.ink_minbounds;
+    max = &pFont->info.ink_maxbounds;
+    if (state.xHeightProp && (state.xHeightProp->value == -1))
+       state.xHeightProp->value = state.exHeight ?
+           state.exHeight : min->ascent;
+
+    if (state.quadWidthProp && (state.quadWidthProp->value == -1))
+       state.quadWidthProp->value = state.digitCount ?
+           (INT32) (state.digitWidths / state.digitCount) :
+           (min->characterWidth + max->characterWidth) / 2;
+
+    if (state.weightProp && (state.weightProp->value == -1))
+       state.weightProp->value = bitmapComputeWeight(pFont);
+
+    pFont->get_glyphs = bitmapGetGlyphs;
+    pFont->get_metrics = bitmapGetMetrics;
+    pFont->unload_font = bdfUnloadFont;
+    pFont->unload_glyphs = NULL;
+    return Successful;
+BAILOUT:
+    if (pFont->fontPrivate)
+       bdfFreeFontBits (pFont);
+    return AllocError;
+}
+
+int
+bdfReadFontInfo(FontInfoPtr pFontInfo, FontFilePtr file)
+{
+    FontRec     font;
+    int         ret;
+
+    bzero(&font, sizeof (FontRec));
+
+    ret = bdfReadFont(&font, file, MSBFirst, LSBFirst, 1, 1);
+    if (ret == Successful) {
+       *pFontInfo = font.info;
+       font.info.props = 0;
+       font.info.isStringProp = 0;
+       font.info.nprops = 0;
+       bdfFreeFontBits (&font);
+    }
+    return ret;
+}
+
+static Bool
+bdfPadToTerminal(FontPtr pFont)
+{
+    BitmapFontPtr  bitmapFont;
+    BitmapExtraPtr bitmapExtra;
+    int         i;
+    int         new_size;
+    CharInfoRec new;
+    int         w,
+                h;
+
+    bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+
+    bzero(&new, sizeof(CharInfoRec)); 
+    new.metrics.ascent = pFont->info.fontAscent;
+    new.metrics.descent = pFont->info.fontDescent;
+    new.metrics.leftSideBearing = 0;
+    new.metrics.rightSideBearing = pFont->info.minbounds.characterWidth;
+    new.metrics.characterWidth = new.metrics.rightSideBearing;
+    new_size = BYTES_FOR_GLYPH(&new, pFont->glyph);
+
+    for (i = 0; i < bitmapFont->num_chars; i++) {
+       new.bits = malloc(new_size);
+       if (!new.bits) {
+          bdfError("Couldn't allocate bits (%d)\n", new_size);
+           return FALSE;
+       }
+       FontCharReshape(pFont, &bitmapFont->metrics[i], &new);
+        new.metrics.attributes = bitmapFont->metrics[i].metrics.attributes;
+       free(bitmapFont->metrics[i].bits);
+       bitmapFont->metrics[i] = new;
+    }
+    bitmapExtra = bitmapFont->bitmapExtra;
+    if (bitmapExtra) {
+       w = GLYPHWIDTHPIXELS(&new);
+       h = GLYPHHEIGHTPIXELS(&new);
+       for (i = 0; i < GLYPHPADOPTIONS; i++)
+           bitmapExtra->bitmapsSizes[i] = bitmapFont->num_chars *
+               (BYTES_PER_ROW(w, 1 << i) * h);
+    }
+    return TRUE;
+}
diff --git a/src/bitmap/bdfutils.c b/src/bitmap/bdfutils.c
new file mode 100755 (executable)
index 0000000..1d6cc72
--- /dev/null
@@ -0,0 +1,336 @@
+/************************************************************************
+Copyright 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+************************************************************************/
+
+/*
+
+Copyright 1994, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/fontstruct.h>
+/* use bitmap structure */
+#include <X11/fonts/bitmap.h>
+#include <X11/fonts/bdfint.h>
+
+int bdfFileLineNum;
+
+/***====================================================================***/
+
+void
+bdfError(char* message, ...)
+{
+    va_list args;
+
+    va_start (args, message);
+    fprintf(stderr, "BDF Error on line %d: ", bdfFileLineNum);
+    vfprintf(stderr, message, args);
+    va_end (args);
+}
+
+/***====================================================================***/
+
+void
+bdfWarning(char *message, ...)
+{
+    va_list args;
+
+    va_start (args, message);
+    fprintf(stderr, "BDF Warning on line %d: ", bdfFileLineNum);
+    vfprintf(stderr, message, args);
+    va_end (args);
+}
+
+/*
+ * read the next (non-comment) line and keep a count for error messages.
+ * Returns buf, or NULL if EOF.
+ */
+
+unsigned char *
+bdfGetLine(FontFilePtr file, unsigned char *buf, int len)
+{
+    int         c;
+    unsigned char *b;
+
+    for (;;) {
+       b = buf;
+       while ((c = FontFileGetc(file)) != FontFileEOF) {
+           if (c == '\r')
+               continue;
+           if (c == '\n') {
+               bdfFileLineNum++;
+               break;
+           }
+           if (b - buf >= (len - 1))
+               break;
+           *b++ = c;
+       }
+       *b = '\0';
+       if (c == FontFileEOF)
+           return NULL;
+       if (b != buf && !bdfIsPrefix(buf, "COMMENT"))
+           break;
+    }
+    return buf;
+}
+
+/***====================================================================***/
+
+Atom
+bdfForceMakeAtom(char *str, int *size)
+{
+    register int len = strlen(str);
+    Atom the_atom;
+
+    if (size != NULL)
+       *size += len + 1;
+    the_atom = MakeAtom(str, len, TRUE);
+    if (the_atom == None)
+      bdfError("Atom allocation failed\n");
+    return the_atom;
+}
+
+/***====================================================================***/
+
+/*
+ * Handle quoted strings.
+ */
+
+Atom
+bdfGetPropertyValue(char *s)
+{
+    register char *p,
+               *pp;
+    char *orig_s = s;
+    Atom        atom;
+
+    /* strip leading white space */
+    while (*s && (*s == ' ' || *s == '\t'))
+       s++;
+    if (*s == 0) {
+       return bdfForceMakeAtom(s, NULL);
+    }
+    if (*s != '"') {
+       pp = s;
+       /* no white space in value */
+       for (pp = s; *pp; pp++)
+           if (*pp == ' ' || *pp == '\t' || *pp == '\015' || *pp == '\n') {
+               *pp = 0;
+               break;
+           }
+       return bdfForceMakeAtom(s, NULL);
+    }
+    /* quoted string: strip outer quotes and undouble inner quotes */
+    s++;
+    pp = p = malloc((unsigned) strlen(s) + 1);
+    if (pp == NULL) {
+  bdfError("Couldn't allocate property value string (%d)\n", strlen(s) + 1);
+  return None;
+    }
+    while (*s) {
+       if (*s == '"') {
+           if (*(s + 1) != '"') {
+               *p++ = 0;
+               atom = bdfForceMakeAtom(pp, NULL);
+               free(pp);
+               return atom;
+           } else {
+               s++;
+           }
+       }
+       *p++ = *s++;
+    }
+    free (pp);
+    bdfError("unterminated quoted string property: %s\n", (pointer) orig_s);
+    return None;
+}
+
+/***====================================================================***/
+
+/*
+ * return TRUE if string is a valid integer
+ */
+int
+bdfIsInteger(char *str)
+{
+    char        c;
+
+    c = *str++;
+    if (!(isdigit(c) || c == '-' || c == '+'))
+       return (FALSE);
+
+    while ((c = *str++))
+       if (!isdigit(c))
+           return (FALSE);
+
+    return (TRUE);
+}
+
+/***====================================================================***/
+
+/*
+ * make a byte from the first two hex characters in glyph picture
+ */
+
+unsigned char
+bdfHexByte(unsigned char *s)
+{
+    unsigned char b = 0;
+    register char c;
+    int         i;
+
+    for (i = 2; i; i--) {
+       c = *s++;
+       if ((c >= '0') && (c <= '9'))
+           b = (b << 4) + (c - '0');
+       else if ((c >= 'A') && (c <= 'F'))
+           b = (b << 4) + 10 + (c - 'A');
+       else if ((c >= 'a') && (c <= 'f'))
+           b = (b << 4) + 10 + (c - 'a');
+       else
+           bdfError("bad hex char '%c'", c);
+    }
+    return b;
+}
+
+/***====================================================================***/
+
+/*
+ * check for known special property values
+ */
+
+static char *SpecialAtoms[] = {
+    "FONT_ASCENT",
+#define BDF_FONT_ASCENT        0
+    "FONT_DESCENT",
+#define BDF_FONT_DESCENT 1
+    "DEFAULT_CHAR",
+#define BDF_DEFAULT_CHAR 2
+    "POINT_SIZE",
+#define BDF_POINT_SIZE 3
+    "RESOLUTION",
+#define BDF_RESOLUTION 4
+    "X_HEIGHT",
+#define BDF_X_HEIGHT 5
+    "WEIGHT",
+#define BDF_WEIGHT 6
+    "QUAD_WIDTH",
+#define BDF_QUAD_WIDTH 7
+    "FONT",
+#define BDF_FONT 8
+    "RESOLUTION_X",
+#define BDF_RESOLUTION_X 9
+    "RESOLUTION_Y",
+#define BDF_RESOLUTION_Y 10
+    0,
+};
+
+Bool
+bdfSpecialProperty(FontPtr pFont, FontPropPtr prop, 
+                  char isString, bdfFileState *bdfState)
+{
+    char      **special;
+    char       *name;
+
+    name = NameForAtom(prop->name);
+    for (special = SpecialAtoms; *special; special++)
+       if (!strcmp(name, *special))
+           break;
+
+    switch (special - SpecialAtoms) {
+    case BDF_FONT_ASCENT:
+       if (!isString) {
+           pFont->info.fontAscent = prop->value;
+           bdfState->haveFontAscent = TRUE;
+       }
+       return TRUE;
+    case BDF_FONT_DESCENT:
+       if (!isString) {
+           pFont->info.fontDescent = prop->value;
+           bdfState->haveFontDescent = TRUE;
+       }
+       return TRUE;
+    case BDF_DEFAULT_CHAR:
+       if (!isString) {
+           pFont->info.defaultCh = prop->value;
+           bdfState->haveDefaultCh = TRUE;
+       }
+       return TRUE;
+    case BDF_POINT_SIZE:
+       bdfState->pointSizeProp = prop;
+       return FALSE;
+    case BDF_RESOLUTION:
+       bdfState->resolutionProp = prop;
+       return FALSE;
+    case BDF_X_HEIGHT:
+       bdfState->xHeightProp = prop;
+       return FALSE;
+    case BDF_WEIGHT:
+       bdfState->weightProp = prop;
+       return FALSE;
+    case BDF_QUAD_WIDTH:
+       bdfState->quadWidthProp = prop;
+       return FALSE;
+    case BDF_FONT:
+       bdfState->fontProp = prop;
+       return FALSE;
+    case BDF_RESOLUTION_X:
+       bdfState->resolutionXProp = prop;
+       return FALSE;
+    case BDF_RESOLUTION_Y:
+       bdfState->resolutionYProp = prop;
+       return FALSE;
+    default:
+       return FALSE;
+    }
+}
diff --git a/src/bitmap/bitmap.c b/src/bitmap/bitmap.c
new file mode 100755 (executable)
index 0000000..1ceb4bb
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+
+Copyright 1991, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+/*
+ * Author:  Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/bitmap.h>
+
+int
+bitmapGetGlyphs(FontPtr pFont, unsigned long count, unsigned char *chars, 
+               FontEncoding charEncoding, 
+               unsigned long *glyphCount,      /* RETURN */
+               CharInfoPtr *glyphs)            /* RETURN */
+{
+    BitmapFontPtr  bitmapFont;
+    unsigned int firstCol;
+    register unsigned int numCols;
+    unsigned int firstRow;
+    unsigned int numRows;
+    CharInfoPtr *glyphsBase;
+    register unsigned int c;
+    register CharInfoPtr pci;
+    unsigned int r;
+    CharInfoPtr **encoding;
+    CharInfoPtr pDefault;
+
+    bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+    encoding = bitmapFont->encoding;
+    pDefault = bitmapFont->pDefault;
+    firstCol = pFont->info.firstCol;
+    numCols = pFont->info.lastCol - firstCol + 1;
+    glyphsBase = glyphs;
+    switch (charEncoding) {
+
+    case Linear8Bit:
+    case TwoD8Bit:
+       if (pFont->info.firstRow > 0)
+           break;
+       if (pFont->info.allExist && pDefault) {
+           while (count--) {
+               c = (*chars++) - firstCol;
+               if (c < numCols)
+                   *glyphs++ = ACCESSENCODING(encoding,c);
+               else
+                   *glyphs++ = pDefault;
+           }
+       } else {
+           while (count--) {
+               c = (*chars++) - firstCol;
+               if (c < numCols && (pci = ACCESSENCODING(encoding,c)))
+                   *glyphs++ = pci;
+               else if (pDefault)
+                   *glyphs++ = pDefault;
+           }
+       }
+       break;
+    case Linear16Bit:
+       if (pFont->info.allExist && pDefault) {
+           while (count--) {
+               c = *chars++ << 8;
+               c = (c | *chars++) - firstCol;
+               if (c < numCols)
+                   *glyphs++ = ACCESSENCODING(encoding,c);
+               else
+                   *glyphs++ = pDefault;
+           }
+       } else {
+           while (count--) {
+               c = *chars++ << 8;
+               c = (c | *chars++) - firstCol;
+               if (c < numCols && (pci = ACCESSENCODING(encoding,c)))
+                   *glyphs++ = pci;
+               else if (pDefault)
+                   *glyphs++ = pDefault;
+           }
+       }
+       break;
+
+    case TwoD16Bit:
+       firstRow = pFont->info.firstRow;
+       numRows = pFont->info.lastRow - firstRow + 1;
+       while (count--) {
+           r = (*chars++) - firstRow;
+           c = (*chars++) - firstCol;
+           if (r < numRows && c < numCols &&
+                   (pci = ACCESSENCODING(encoding, r * numCols + c)))
+               *glyphs++ = pci;
+           else if (pDefault)
+               *glyphs++ = pDefault;
+       }
+       break;
+    }
+    *glyphCount = glyphs - glyphsBase;
+    return Successful;
+}
+
+static CharInfoRec nonExistantChar;
+
+int
+bitmapGetMetrics(FontPtr pFont, unsigned long count, unsigned char *chars, 
+                FontEncoding charEncoding, 
+                unsigned long *glyphCount,     /* RETURN */
+                xCharInfo **glyphs)            /* RETURN */
+{
+    int         ret;
+    xCharInfo  *ink_metrics;
+    CharInfoPtr metrics;
+    BitmapFontPtr  bitmapFont;
+    CharInfoPtr        oldDefault;
+    int         i;
+
+    bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+    oldDefault = bitmapFont->pDefault;
+    bitmapFont->pDefault = &nonExistantChar;
+    ret = bitmapGetGlyphs(pFont, count, chars, charEncoding, glyphCount, (CharInfoPtr *) glyphs);
+    if (ret == Successful) {
+       if (bitmapFont->ink_metrics) {
+           metrics = bitmapFont->metrics;
+           ink_metrics = bitmapFont->ink_metrics;
+           for (i = 0; i < *glyphCount; i++) {
+               if (glyphs[i] != (xCharInfo *) & nonExistantChar)
+                   glyphs[i] = ink_metrics + (((CharInfoPtr) glyphs[i]) - metrics);
+           }
+       }
+    }
+    bitmapFont->pDefault = oldDefault;
+    return ret;
+}
diff --git a/src/bitmap/bitmapfunc.c b/src/bitmap/bitmapfunc.c
new file mode 100755 (executable)
index 0000000..47ce488
--- /dev/null
@@ -0,0 +1,254 @@
+/*
+
+Copyright 1991, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+/*
+ * Author:  Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/*
+ * Translate monolithic #defines to modular definitions
+ */
+
+#ifdef PCFFORMAT
+#define XFONT_PCFFORMAT 1
+#endif
+
+#ifdef SNFFORMAT
+#define XFONT_SNFFORMAT 1
+#endif
+
+#ifdef BDFFORMAT
+#define XFONT_BDFFORMAT 1
+#endif
+
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/bitmap.h>
+#include <X11/fonts/fontutil.h>
+#include <X11/fonts/bdfint.h>
+#include <X11/fonts/pcf.h>
+#include "snfstr.h"
+
+typedef struct _BitmapFileFunctions {
+    int         (*ReadFont) (FontPtr /* pFont */, FontFilePtr /* file */,  
+                            int /* bit */, int /* byte */, 
+                            int /* glyph */, int /* scan */);
+    int         (*ReadInfo) (  FontInfoPtr /* pFontInfo */, 
+                              FontFilePtr /* file */ );
+}           BitmapFileFunctionsRec, *BitmapFileFunctionsPtr;
+
+static int BitmapGetRenderIndex(FontRendererPtr renderer);
+
+/*
+ * the readers[] and renderers[] arrays must be in the same order,
+ * and also in the same order as scale[] and find_scale[] in bitscale.c
+ *
+ */
+static BitmapFileFunctionsRec readers[] = {
+#if XFONT_PCFFORMAT
+    { pcfReadFont, pcfReadFontInfo} ,
+    { pcfReadFont, pcfReadFontInfo} ,
+# ifdef X_GZIP_FONT_COMPRESSION
+    { pcfReadFont, pcfReadFontInfo} ,
+# endif
+# ifdef X_BZIP2_FONT_COMPRESSION
+    { pcfReadFont, pcfReadFontInfo} ,
+# endif
+#endif
+#if XFONT_SNFFORMAT
+    { snfReadFont, snfReadFontInfo},
+    { snfReadFont, snfReadFontInfo},
+# ifdef X_GZIP_FONT_COMPRESSION
+    { snfReadFont, snfReadFontInfo} ,
+# endif
+# ifdef X_BZIP2_FONT_COMPRESSION
+    { snfReadFont, snfReadFontInfo} ,
+# endif
+#endif
+#if XFONT_BDFFORMAT
+    { bdfReadFont, bdfReadFontInfo} ,
+    { bdfReadFont, bdfReadFontInfo} ,
+# ifdef X_GZIP_FONT_COMPRESSION
+    { bdfReadFont, bdfReadFontInfo} ,
+# endif
+# ifdef X_BZIP2_FONT_COMPRESSION
+    { bdfReadFont, bdfReadFontInfo} ,
+# endif
+#endif
+};
+
+
+#define CAPABILITIES (CAP_MATRIX | CAP_CHARSUBSETTING)
+
+static int
+BitmapOpenBitmap (FontPathElementPtr fpe, FontPtr *ppFont, int flags, 
+                 FontEntryPtr entry, char *fileName, 
+                 fsBitmapFormat format, fsBitmapFormatMask fmask,
+                 FontPtr non_cachable_font) /* We don't do licensing */
+{
+    FontFilePtr        file;
+    FontPtr     pFont;
+    int         i;
+    int         ret;
+    int         bit,
+                byte,
+                glyph,
+                scan,
+               image;
+
+    i = BitmapGetRenderIndex(entry->u.bitmap.renderer);
+    file = FontFileOpen (fileName);
+    if (!file)
+       return BadFontName;
+    if (!(pFont = CreateFontRec())) {
+       fprintf(stderr, "Error: Couldn't allocate pFont (%ld)\n",
+               (unsigned long)sizeof(FontRec));
+       FontFileClose (file);
+       return AllocError;
+    }
+    /* set up default values */
+    FontDefaultFormat(&bit, &byte, &glyph, &scan);
+    /* get any changes made from above */
+    ret = CheckFSFormat(format, fmask, &bit, &byte, &scan, &glyph, &image);
+
+    /* Fill in font record. Data format filled in by reader. */
+    pFont->refcnt = 0;
+
+    ret = (*readers[i].ReadFont) (pFont, file, bit, byte, glyph, scan);
+
+    FontFileClose (file);
+    if (ret != Successful) {
+       free(pFont);
+    } else {
+       *ppFont = pFont;
+    }
+    return ret;
+}
+
+static int
+BitmapGetInfoBitmap (FontPathElementPtr fpe, FontInfoPtr pFontInfo, 
+                    FontEntryPtr entry, char *fileName)
+{
+    FontFilePtr file;
+    int                i;
+    int                ret;
+    FontRendererPtr renderer;
+
+    renderer = FontFileMatchRenderer (fileName);
+    if (!renderer)
+       return BadFontName;
+    i = BitmapGetRenderIndex(renderer);
+    file = FontFileOpen (fileName);
+    if (!file)
+       return BadFontName;
+    ret = (*readers[i].ReadInfo) (pFontInfo, file);
+    FontFileClose (file);
+    return ret;
+}
+
+static FontRendererRec renderers[] = {
+#if XFONT_PCFFORMAT
+    { ".pcf", 4, BitmapOpenBitmap, BitmapOpenScalable,
+       BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+       CAPABILITIES },
+    { ".pcf.Z", 6, BitmapOpenBitmap, BitmapOpenScalable,
+       BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+       CAPABILITIES },
+# ifdef X_GZIP_FONT_COMPRESSION
+    { ".pcf.gz", 7,
+       BitmapOpenBitmap, BitmapOpenScalable,
+       BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+       CAPABILITIES },
+# endif
+# ifdef X_BZIP2_FONT_COMPRESSION
+    { ".pcf.bz2", 8,
+       BitmapOpenBitmap, BitmapOpenScalable,
+       BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+       CAPABILITIES },
+# endif
+#endif
+#if XFONT_SNFFORMAT
+    { ".snf", 4, BitmapOpenBitmap, BitmapOpenScalable,
+       BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+       CAPABILITIES },
+    { ".snf.Z", 6, BitmapOpenBitmap, BitmapOpenScalable,
+       BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+       CAPABILITIES },
+# ifdef X_GZIP_FONT_COMPRESSION
+    { ".snf.gz", 7, BitmapOpenBitmap, BitmapOpenScalable,
+       BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+       CAPABILITIES },
+# endif
+# ifdef X_BZIP2_FONT_COMPRESSION
+    { ".snf.bz2", 8, BitmapOpenBitmap, BitmapOpenScalable,
+       BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+       CAPABILITIES },
+# endif
+#endif
+#if XFONT_BDFFORMAT
+    { ".bdf", 4, BitmapOpenBitmap, BitmapOpenScalable,
+       BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+       CAPABILITIES },
+    { ".bdf.Z", 6, BitmapOpenBitmap, BitmapOpenScalable,
+       BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+       CAPABILITIES },
+# ifdef X_GZIP_FONT_COMPRESSION
+    { ".bdf.gz", 7, BitmapOpenBitmap, BitmapOpenScalable,
+       BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+       CAPABILITIES },
+# endif
+# ifdef X_BZIP2_FONT_COMPRESSION
+    { ".bdf.bz2", 8, BitmapOpenBitmap, BitmapOpenScalable,
+       BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+       CAPABILITIES },
+# endif
+#endif
+};
+
+#define numRenderers   (sizeof renderers / sizeof renderers[0])
+
+void
+BitmapRegisterFontFileFunctions (void)
+{
+    int            i;
+
+    for (i = 0; i < numRenderers; i++)
+       FontFileRegisterRenderer (&renderers[i]);
+}
+
+/*
+ * compute offset into renderers array - used to find the font reader,
+ * the font info reader, and the bitmap scaling routine.  All users
+ * of this routine must be kept in step with the renderer array.
+ */
+static int
+BitmapGetRenderIndex(FontRendererPtr renderer)
+{
+    return renderer - renderers;
+}
diff --git a/src/bitmap/bitmaputil.c b/src/bitmap/bitmaputil.c
new file mode 100755 (executable)
index 0000000..0a1c87e
--- /dev/null
@@ -0,0 +1,229 @@
+/*
+
+Copyright 1990, 1994, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/bitmap.h>
+#include <X11/fonts/bdfint.h>
+
+#ifndef MAXSHORT
+#define MAXSHORT    32767
+#endif
+
+#ifndef MINSHORT
+#define MINSHORT    -32768
+#endif
+
+static xCharInfo initMinMetrics = {
+MAXSHORT, MAXSHORT, MAXSHORT, MAXSHORT, MAXSHORT, 0xFFFF};
+static xCharInfo initMaxMetrics = {
+MINSHORT, MINSHORT, MINSHORT, MINSHORT, MINSHORT, 0x0000};
+
+#define MINMAX(field,ci) \
+       if (minbounds->field > (ci)->field) \
+            minbounds->field = (ci)->field; \
+       if (maxbounds->field < (ci)->field) \
+            maxbounds->field = (ci)->field;
+
+#define COMPUTE_MINMAX(ci) \
+    if ((ci)->ascent || (ci)->descent || \
+       (ci)->leftSideBearing || (ci)->rightSideBearing || \
+       (ci)->characterWidth) \
+    { \
+       MINMAX(ascent, (ci)); \
+       MINMAX(descent, (ci)); \
+       MINMAX(leftSideBearing, (ci)); \
+       MINMAX(rightSideBearing, (ci)); \
+       MINMAX(characterWidth, (ci)); \
+    }
+
+void
+bitmapComputeFontBounds(FontPtr pFont)
+{
+    BitmapFontPtr  bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+    int         nchars;
+    int         r,
+                c;
+    CharInfoPtr ci;
+    int         maxOverlap;
+    int         overlap;
+    xCharInfo  *minbounds,
+               *maxbounds;
+    int         i;
+    int                numneg = 0, numpos = 0;
+
+    if (bitmapFont->bitmapExtra) {
+       minbounds = &bitmapFont->bitmapExtra->info.minbounds;
+       maxbounds = &bitmapFont->bitmapExtra->info.maxbounds;
+    } else {
+       minbounds = &pFont->info.minbounds;
+       maxbounds = &pFont->info.maxbounds;
+    }
+    *minbounds = initMinMetrics;
+    *maxbounds = initMaxMetrics;
+    maxOverlap = MINSHORT;
+    nchars = bitmapFont->num_chars;
+    for (i = 0, ci = bitmapFont->metrics; i < nchars; i++, ci++) {
+       COMPUTE_MINMAX(&ci->metrics);
+       if (ci->metrics.characterWidth < 0)
+           numneg++;
+       else
+           numpos++;
+       minbounds->attributes &= ci->metrics.attributes;
+       maxbounds->attributes |= ci->metrics.attributes;
+       overlap = ci->metrics.rightSideBearing - ci->metrics.characterWidth;
+       if (maxOverlap < overlap)
+           maxOverlap = overlap;
+    }
+    if (bitmapFont->bitmapExtra) {
+       if (numneg > numpos)
+           bitmapFont->bitmapExtra->info.drawDirection = RightToLeft;
+       else
+           bitmapFont->bitmapExtra->info.drawDirection = LeftToRight;
+       bitmapFont->bitmapExtra->info.maxOverlap = maxOverlap;
+       minbounds = &pFont->info.minbounds;
+       maxbounds = &pFont->info.maxbounds;
+       *minbounds = initMinMetrics;
+       *maxbounds = initMaxMetrics;
+        i = 0;
+       maxOverlap = MINSHORT;
+       for (r = pFont->info.firstRow; r <= pFont->info.lastRow; r++) {
+           for (c = pFont->info.firstCol; c <= pFont->info.lastCol; c++) {
+               ci = ACCESSENCODING(bitmapFont->encoding, i);
+               if (ci) {
+                   COMPUTE_MINMAX(&ci->metrics);
+                   if (ci->metrics.characterWidth < 0)
+                       numneg++;
+                   else
+                       numpos++;
+                   minbounds->attributes &= ci->metrics.attributes;
+                   maxbounds->attributes |= ci->metrics.attributes;
+                   overlap = ci->metrics.rightSideBearing -
+                       ci->metrics.characterWidth;
+                   if (maxOverlap < overlap)
+                       maxOverlap = overlap;
+               }
+                i++;
+           }
+       }
+    }
+    if (numneg > numpos)
+       pFont->info.drawDirection = RightToLeft;
+    else
+       pFont->info.drawDirection = LeftToRight;
+    pFont->info.maxOverlap = maxOverlap;
+}
+
+void
+bitmapComputeFontInkBounds(FontPtr pFont)
+{
+    BitmapFontPtr  bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+    int         nchars;
+    int         r,
+                c;
+    CharInfoPtr cit;
+    xCharInfo  *ci;
+    int         offset;
+    xCharInfo  *minbounds,
+               *maxbounds;
+    int         i;
+
+    if (!bitmapFont->ink_metrics) {
+       if (bitmapFont->bitmapExtra) {
+           bitmapFont->bitmapExtra->info.ink_minbounds = bitmapFont->bitmapExtra->info.minbounds;
+           bitmapFont->bitmapExtra->info.ink_maxbounds = bitmapFont->bitmapExtra->info.maxbounds;
+       }
+       pFont->info.ink_minbounds = pFont->info.minbounds;
+       pFont->info.ink_maxbounds = pFont->info.maxbounds;
+    } else {
+       if (bitmapFont->bitmapExtra) {
+           minbounds = &bitmapFont->bitmapExtra->info.ink_minbounds;
+           maxbounds = &bitmapFont->bitmapExtra->info.ink_maxbounds;
+       } else {
+           minbounds = &pFont->info.ink_minbounds;
+           maxbounds = &pFont->info.ink_maxbounds;
+       }
+       *minbounds = initMinMetrics;
+       *maxbounds = initMaxMetrics;
+       nchars = bitmapFont->num_chars;
+       for (i = 0, ci = bitmapFont->ink_metrics; i < nchars; i++, ci++) {
+           COMPUTE_MINMAX(ci);
+           minbounds->attributes &= ci->attributes;
+           maxbounds->attributes |= ci->attributes;
+       }
+       if (bitmapFont->bitmapExtra) {
+           minbounds = &pFont->info.ink_minbounds;
+           maxbounds = &pFont->info.ink_maxbounds;
+           *minbounds = initMinMetrics;
+           *maxbounds = initMaxMetrics;
+            i=0;
+           for (r = pFont->info.firstRow; r <= pFont->info.lastRow; r++) {
+               for (c = pFont->info.firstCol; c <= pFont->info.lastCol; c++) {
+                   cit = ACCESSENCODING(bitmapFont->encoding, i);
+                   if (cit) {
+                       offset = cit - bitmapFont->metrics;
+                       ci = &bitmapFont->ink_metrics[offset];
+                       COMPUTE_MINMAX(ci);
+                       minbounds->attributes &= ci->attributes;
+                       maxbounds->attributes |= ci->attributes;
+                   }
+                    i++;
+               }
+           }
+       }
+    }
+}
+
+Bool
+bitmapAddInkMetrics(FontPtr pFont)
+{
+    BitmapFontPtr  bitmapFont;
+    int         i;
+
+    bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+    bitmapFont->ink_metrics = malloc(bitmapFont->num_chars * sizeof(xCharInfo));
+    if (!bitmapFont->ink_metrics) {
+      fprintf(stderr, "Error: Couldn't allocate ink_metrics (%d*%ld)\n",
+             bitmapFont->num_chars, (unsigned long)sizeof(xCharInfo));
+       return FALSE;
+    }
+    for (i = 0; i < bitmapFont->num_chars; i++)
+       FontCharInkMetrics(pFont, &bitmapFont->metrics[i], &bitmapFont->ink_metrics[i]);
+    pFont->info.inkMetrics = TRUE;
+    return TRUE;
+}
+
+/* ARGSUSED */
+int
+bitmapComputeWeight(FontPtr pFont)
+{
+    return 10;
+}
diff --git a/src/bitmap/bitscale.c b/src/bitmap/bitscale.c
new file mode 100755 (executable)
index 0000000..cf16bff
--- /dev/null
@@ -0,0 +1,1691 @@
+/*
+
+Copyright 1991, 1994, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+/*
+ * Author:  Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/*
+ * Translate monolithic #defines to modular definitions
+ */
+
+#ifdef PCFFORMAT
+#define XFONT_PCFFORMAT 1
+#endif
+
+#ifdef SNFFORMAT
+#define XFONT_SNFFORMAT 1
+#endif
+
+#ifdef BDFFORMAT
+#define XFONT_BDFFORMAT 1
+#endif
+
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/bitmap.h>
+#include <X11/fonts/fontutil.h>
+#include <math.h>
+
+#ifndef MAX
+#define   MAX(a,b)    (((a)>(b)) ? a : b)
+#endif
+
+/* Should get this from elsewhere */
+extern unsigned long serverGeneration;
+
+static void bitmapUnloadScalable (FontPtr pFont);
+static void ScaleBitmap ( FontPtr pFont, CharInfoPtr opci, 
+                         CharInfoPtr pci, double *inv_xform, 
+                         double widthMult, double heightMult );
+static FontPtr BitmapScaleBitmaps(FontPtr pf, FontPtr opf, 
+                                 double widthMult, double heightMult,   
+                                 FontScalablePtr vals);
+
+enum scaleType {
+    atom, truncate_atom, pixel_size, point_size, resolution_x,
+    resolution_y, average_width, scaledX, scaledY, unscaled, fontname,
+    raw_ascent, raw_descent, raw_pixelsize, raw_pointsize,
+    raw_average_width, uncomputed
+};
+
+typedef struct _fontProp {
+    char       *name;
+    Atom        atom;
+    enum scaleType type;
+} fontProp;
+
+static FontEntryPtr FindBestToScale ( FontPathElementPtr fpe, 
+                                     FontEntryPtr entry, 
+                                     FontScalablePtr vals, 
+                                     FontScalablePtr best, 
+                                     double *dxp, double *dyp, 
+                                     double *sdxp, double *sdyp, 
+                                     FontPathElementPtr *fpep );
+
+static unsigned long bitscaleGeneration = 0;   /* initialization flag */
+
+static fontProp fontNamePropTable[] = {
+    { "FOUNDRY", 0, atom },
+    { "FAMILY_NAME", 0, atom },
+    { "WEIGHT_NAME", 0, atom },
+    { "SLANT", 0, atom },
+    { "SETWIDTH_NAME", 0, atom },
+    { "ADD_STYLE_NAME", 0, atom },
+    { "PIXEL_SIZE", 0, pixel_size },
+    { "POINT_SIZE", 0, point_size },
+    { "RESOLUTION_X", 0, resolution_x },
+    { "RESOLUTION_Y", 0, resolution_y },
+    { "SPACING", 0, atom },
+    { "AVERAGE_WIDTH", 0, average_width },
+    { "CHARSET_REGISTRY", 0, atom },
+    { "CHARSET_ENCODING", 0, truncate_atom },
+    { "FONT", 0, fontname },
+    { "RAW_ASCENT", 0, raw_ascent },
+    { "RAW_DESCENT", 0, raw_descent },
+    { "RAW_PIXEL_SIZE", 0, raw_pixelsize },
+    { "RAW_POINT_SIZE", 0, raw_pointsize },
+    { "RAW_AVERAGE_WIDTH", 0, raw_average_width }
+};
+
+#define TRANSFORM_POINT(matrix, x, y, dest) \
+       ((dest)[0] = (matrix)[0] * (x) + (matrix)[2] * (y), \
+        (dest)[1] = (matrix)[1] * (x) + (matrix)[3] * (y))
+
+#define CHECK_EXTENT(lsb, rsb, desc, asc, data) \
+       ((lsb) > (data)[0] ? (lsb) = (data)[0] : 0 , \
+        (rsb) < (data)[0] ? (rsb) = (data)[0] : 0, \
+        (-desc) > (data)[1] ? (desc) = -(data)[1] : 0 , \
+        (asc) < (data)[1] ? (asc) = (data)[1] : 0)
+
+#define NPROPS (sizeof(fontNamePropTable) / sizeof(fontProp))
+
+/* Warning: order of the next two tables is critically interdependent.
+   Location of "unscaled" properties at the end of fontPropTable[]
+   is important. */
+
+static fontProp fontPropTable[] = {
+    { "MIN_SPACE", 0, scaledX },
+    { "NORM_SPACE", 0, scaledX },
+    { "MAX_SPACE", 0, scaledX },
+    { "END_SPACE", 0, scaledX },
+    { "AVG_CAPITAL_WIDTH", 0, scaledX },
+    { "AVG_LOWERCASE_WIDTH", 0, scaledX },
+    { "QUAD_WIDTH", 0, scaledX },
+    { "FIGURE_WIDTH", 0, scaledX },
+    { "SUPERSCRIPT_X", 0, scaledX },
+    { "SUPERSCRIPT_Y", 0, scaledY },
+    { "SUBSCRIPT_X", 0, scaledX },
+    { "SUBSCRIPT_Y", 0, scaledY },
+    { "SUPERSCRIPT_SIZE", 0, scaledY },
+    { "SUBSCRIPT_SIZE", 0, scaledY },
+    { "SMALL_CAP_SIZE", 0, scaledY },
+    { "UNDERLINE_POSITION", 0, scaledY },
+    { "UNDERLINE_THICKNESS", 0, scaledY },
+    { "STRIKEOUT_ASCENT", 0, scaledY },
+    { "STRIKEOUT_DESCENT", 0, scaledY },
+    { "CAP_HEIGHT", 0, scaledY },
+    { "X_HEIGHT", 0, scaledY },
+    { "ITALIC_ANGLE", 0, unscaled },
+    { "RELATIVE_SETWIDTH", 0, unscaled },
+    { "RELATIVE_WEIGHT", 0, unscaled },
+    { "WEIGHT", 0, unscaled },
+    { "DESTINATION", 0, unscaled },
+    { "PCL_FONT_NAME", 0, unscaled },
+    { "_ADOBE_POSTSCRIPT_FONTNAME", 0, unscaled }
+};
+
+static fontProp rawFontPropTable[] = {
+    { "RAW_MIN_SPACE", 0, },
+    { "RAW_NORM_SPACE", 0, },
+    { "RAW_MAX_SPACE", 0, },
+    { "RAW_END_SPACE", 0, },
+    { "RAW_AVG_CAPITAL_WIDTH", 0, },
+    { "RAW_AVG_LOWERCASE_WIDTH", 0, },
+    { "RAW_QUAD_WIDTH", 0, },
+    { "RAW_FIGURE_WIDTH", 0, },
+    { "RAW_SUPERSCRIPT_X", 0, },
+    { "RAW_SUPERSCRIPT_Y", 0, },
+    { "RAW_SUBSCRIPT_X", 0, },
+    { "RAW_SUBSCRIPT_Y", 0, },
+    { "RAW_SUPERSCRIPT_SIZE", 0, },
+    { "RAW_SUBSCRIPT_SIZE", 0, },
+    { "RAW_SMALL_CAP_SIZE", 0, },
+    { "RAW_UNDERLINE_POSITION", 0, },
+    { "RAW_UNDERLINE_THICKNESS", 0, },
+    { "RAW_STRIKEOUT_ASCENT", 0, },
+    { "RAW_STRIKEOUT_DESCENT", 0, },
+    { "RAW_CAP_HEIGHT", 0, },
+    { "RAW_X_HEIGHT", 0, }
+};
+
+static void
+initFontPropTable(void)
+{
+    int         i;
+    fontProp   *t;
+
+    i = sizeof(fontNamePropTable) / sizeof(fontProp);
+    for (t = fontNamePropTable; i; i--, t++)
+       t->atom = MakeAtom(t->name, (unsigned) strlen(t->name), TRUE);
+
+    i = sizeof(fontPropTable) / sizeof(fontProp);
+    for (t = fontPropTable; i; i--, t++)
+       t->atom = MakeAtom(t->name, (unsigned) strlen(t->name), TRUE);
+
+    i = sizeof(rawFontPropTable) / sizeof(fontProp);
+    for (t = rawFontPropTable; i; i--, t++)
+       t->atom = MakeAtom(t->name, (unsigned) strlen(t->name), TRUE);
+}
+
+#if 0
+static FontEntryPtr
+GetScalableEntry (FontPathElementPtr fpe, FontNamePtr name)
+{
+    FontDirectoryPtr   dir;
+
+    dir = (FontDirectoryPtr) fpe->private;
+    return FontFileFindNameInDir (&dir->scalable, name);
+}
+#endif
+
+static double
+get_matrix_horizontal_component(double *matrix)
+{
+    return hypot(matrix[0], matrix[1]);
+}
+
+static double
+get_matrix_vertical_component(double *matrix)
+{
+    return hypot(matrix[2], matrix[3]);
+}
+
+
+static Bool
+ComputeScaleFactors(FontScalablePtr from, FontScalablePtr to, 
+                   double *dx, double *dy, double *sdx, double *sdy, 
+                   double *rescale_x)
+{
+    double srcpixelset, destpixelset, srcpixel, destpixel;
+
+    srcpixelset = get_matrix_horizontal_component(from->pixel_matrix);
+    destpixelset = get_matrix_horizontal_component(to->pixel_matrix);
+    srcpixel = get_matrix_vertical_component(from->pixel_matrix);
+    destpixel = get_matrix_vertical_component(to->pixel_matrix);
+
+    if (srcpixelset >= EPS)
+    {
+       *dx = destpixelset / srcpixelset;
+       *sdx = 1000.0 / srcpixelset;
+    }
+    else
+       *sdx = *dx = 0;
+
+    *rescale_x = 1.0;
+
+    /* If client specified a width, it overrides setsize; in this
+       context, we interpret width as applying to the font before any
+       rotation, even though that's not what is ultimately returned in
+       the width field. */
+    if (from->width > 0 && to->width > 0 && fabs(*dx) > EPS)
+    {
+       double rescale = (double)to->width / (double)from->width;
+
+       /* If the client specified a transformation matrix, the rescaling
+          for width does *not* override the setsize.  Instead, just check
+          for consistency between the setsize from the matrix and the
+          setsize that would result from rescaling according to the width.
+          This assumes (perhaps naively) that the width is correctly
+          reported in the name.  As an interesting side effect, this test
+          may result in choosing a different source bitmap (one that
+          scales consistently between the setsize *and* the width) than it
+          would choose if a width were not specified.  Sort of a hidden
+          multiple-master functionality. */
+       if ((to->values_supplied & PIXELSIZE_MASK) == PIXELSIZE_ARRAY ||
+           (to->values_supplied & POINTSIZE_MASK) == POINTSIZE_ARRAY)
+       {
+           /* Reject if resulting width difference is >= 1 pixel */
+           if (fabs(rescale * from->width - *dx * from->width) >= 10)
+               return FALSE;
+       }
+       else
+       {
+           *rescale_x = rescale/(*dx);
+           *dx = rescale;
+       }
+    }
+
+    if (srcpixel >= EPS)
+    {
+       *dy = destpixel / srcpixel;
+       *sdy = 1000.0 / srcpixel;
+    }
+    else
+       *sdy = *dy = 0;
+
+    return TRUE;
+}
+
+/* favor enlargement over reduction because of aliasing resulting
+   from reduction */
+#define SCORE(m,s) \
+if (m >= 1.0) { \
+    if (m == 1.0) \
+        score += (16 * s); \
+    else if (m == 2.0) \
+        score += (4 * s); \
+    else \
+        score += (int)(((double)(3 * s)) / m); \
+} else { \
+        score += (int)(((double)(2 * s)) * m); \
+}
+
+/* don't need to favor enlargement when looking for bitmap that can
+   be used unscalable */
+#define SCORE2(m,s) \
+if (m >= 1.0) \
+    score += (int)(((double)(8 * s)) / m); \
+else \
+    score += (int)(((double)(8 * s)) * m);
+
+static FontEntryPtr
+FindBestToScale(FontPathElementPtr fpe, FontEntryPtr entry, 
+               FontScalablePtr vals, FontScalablePtr best, 
+               double *dxp, double *dyp, 
+               double *sdxp, double *sdyp, 
+               FontPathElementPtr *fpep)
+{
+    FontScalableRec temp;
+    int                    source, i;
+    int                    best_score, best_unscaled_score,
+                   score;
+    double         dx = 0.0, sdx = 0.0, dx_amount = 0.0,
+                   dy = 0.0, sdy = 0.0, dy_amount = 0.0,
+                   best_dx = 0.0, best_sdx = 0.0, best_dx_amount = 0.0,
+                   best_dy = 0.0, best_sdy = 0.0, best_dy_amount = 0.0,
+                   best_unscaled_sdx = 0.0, best_unscaled_sdy = 0.0,
+                   rescale_x = 0.0, best_rescale_x = 0.0,
+                   best_unscaled_rescale_x = 0.0;
+    FontEntryPtr    zero;
+    FontNameRec            zeroName;
+    char           zeroChars[MAXFONTNAMELEN];
+    FontDirectoryPtr   dir;
+    FontScaledPtr   scaled;
+    FontScalableExtraPtr   extra;
+    FontScaledPtr   best_scaled, best_unscaled;
+    FontPathElementPtr best_fpe = NULL, best_unscaled_fpe = NULL;
+    FontEntryPtr    bitmap = NULL;
+    FontEntryPtr    result;
+    int                    aliascount = 20;
+    FontPathElementPtr bitmap_fpe = NULL;
+    FontNameRec            xlfdName;
+
+    /* find the best match */
+    rescale_x = 1.0;
+    best_scaled = 0;
+    best_score = 0;
+    best_unscaled = 0;
+    best_unscaled_score = -1;
+    best_dx_amount = best_dy_amount = HUGE_VAL;
+    memcpy (zeroChars, entry->name.name, entry->name.length);
+    zeroChars[entry->name.length] = '\0';
+    zeroName.name = zeroChars;
+    FontParseXLFDName (zeroChars, &temp, FONT_XLFD_REPLACE_ZERO);
+    zeroName.length = strlen (zeroChars);
+    zeroName.ndashes = entry->name.ndashes;
+    xlfdName.name = vals->xlfdName;
+    xlfdName.length = strlen(xlfdName.name);
+    xlfdName.ndashes = FontFileCountDashes(xlfdName.name, xlfdName.length);
+    restart_bestscale_loop: ;
+    /*
+     * Look through all the registered bitmap sources for
+     * the same zero name as ours; entries along that one
+     * can be scaled as desired.
+     */
+    for (source = 0; source < FontFileBitmapSources.count; source++)
+    {
+       /* There might already be a bitmap that satisfies the request
+          but didn't have a zero name that was found by the scalable
+          font matching logic.  Keep track if there is.  */
+       if (bitmap == NULL && vals->xlfdName != NULL)
+       {
+           bitmap_fpe = FontFileBitmapSources.fpe[source];
+           dir = (FontDirectoryPtr) bitmap_fpe->private;
+           bitmap = FontFileFindNameInDir (&dir->nonScalable, &xlfdName);
+           if (bitmap && bitmap->type != FONT_ENTRY_BITMAP)
+           {
+               if (bitmap->type == FONT_ENTRY_ALIAS && aliascount > 0)
+               {
+                   aliascount--;
+                   xlfdName.name = bitmap->u.alias.resolved;
+                   xlfdName.length = strlen(xlfdName.name);
+                   xlfdName.ndashes = FontFileCountDashes(xlfdName.name,
+                                                          xlfdName.length);
+                   bitmap = NULL;
+                   goto restart_bestscale_loop;
+               }
+               else
+                   bitmap = NULL;
+           }
+       }
+
+       if (FontFileBitmapSources.fpe[source] == fpe)
+           zero = entry;
+       else
+       {
+           dir = (FontDirectoryPtr) FontFileBitmapSources.fpe[source]->private;
+           zero = FontFileFindNameInDir (&dir->scalable, &zeroName);
+           if (!zero)
+               continue;
+       }
+       extra = zero->u.scalable.extra;
+       for (i = 0; i < extra->numScaled; i++)
+       {
+           scaled = &extra->scaled[i];
+           if (!scaled->bitmap)
+               continue;
+           if (!ComputeScaleFactors(&scaled->vals, vals, &dx, &dy, &sdx, &sdy,
+                                    &rescale_x))
+               continue;
+           score = 0;
+           dx_amount = dx;
+           dy_amount = dy;
+           SCORE(dy_amount, 10);
+           SCORE(dx_amount, 1);
+           if ((score > best_score) ||
+                   ((score == best_score) &&
+                    ((dy_amount < best_dy_amount) ||
+                     ((dy_amount == best_dy_amount) &&
+                      (dx_amount < best_dx_amount))))) 
+           {
+               best_fpe = FontFileBitmapSources.fpe[source];
+               best_scaled = scaled;
+               best_score = score;
+               best_dx = dx;
+               best_dy = dy;
+               best_sdx = sdx;
+               best_sdy = sdy;
+               best_dx_amount = dx_amount;
+               best_dy_amount = dy_amount;
+               best_rescale_x = rescale_x;
+           }
+           /* Is this font a candidate for use without ugly rescaling? */
+           if (fabs(dx) > EPS && fabs(dy) > EPS &&
+               fabs(vals->pixel_matrix[0] * rescale_x -
+                    scaled->vals.pixel_matrix[0]) < 1 &&
+               fabs(vals->pixel_matrix[1] * rescale_x -
+                    scaled->vals.pixel_matrix[1]) < EPS &&
+               fabs(vals->pixel_matrix[2] -
+                    scaled->vals.pixel_matrix[2]) < EPS &&
+               fabs(vals->pixel_matrix[3] -
+                    scaled->vals.pixel_matrix[3]) < 1)
+           {
+               /* Yes.  The pixel sizes are close on the diagonal and
+                  extremely close off the diagonal. */
+               score = 0;
+               SCORE2(vals->pixel_matrix[3] /
+                      scaled->vals.pixel_matrix[3], 10);
+               SCORE2(vals->pixel_matrix[0] * rescale_x /
+                      scaled->vals.pixel_matrix[0], 1);
+               if (score > best_unscaled_score)
+               {
+                   best_unscaled_fpe = FontFileBitmapSources.fpe[source];
+                   best_unscaled = scaled;
+                   best_unscaled_sdx = sdx / dx;
+                   best_unscaled_sdy = sdy / dy;
+                   best_unscaled_score = score;
+                   best_unscaled_rescale_x = rescale_x;
+               }
+           }
+       }
+    }
+    if (best_unscaled)
+    {
+       *best = best_unscaled->vals;
+       *fpep = best_unscaled_fpe;
+       *dxp = 1.0;
+       *dyp = 1.0;
+       *sdxp = best_unscaled_sdx;
+       *sdyp = best_unscaled_sdy;
+       rescale_x = best_unscaled_rescale_x;
+       result = best_unscaled->bitmap;
+    }
+    else if (best_scaled)
+    {
+       *best = best_scaled->vals;
+       *fpep = best_fpe;
+       *dxp = best_dx;
+       *dyp = best_dy;
+       *sdxp = best_sdx;
+       *sdyp = best_sdy;
+       rescale_x = best_rescale_x;
+       result = best_scaled->bitmap;
+    }
+    else
+       result = NULL;
+
+    if (bitmap != NULL && (result == NULL || *dxp != 1.0 || *dyp != 1.0))
+    {
+       *fpep = bitmap_fpe;
+       FontParseXLFDName (bitmap->name.name, best, FONT_XLFD_REPLACE_NONE);
+       if (ComputeScaleFactors(best, best, dxp, dyp, sdxp, sdyp, &rescale_x))
+           result = bitmap;
+       else
+           result = NULL;
+    }
+
+    if (result && rescale_x != 1.0)
+    {
+       /* We have rescaled horizontally due to an XLFD width field.  Change
+          the matrix appropriately */
+       vals->pixel_matrix[0] *= rescale_x;
+       vals->pixel_matrix[1] *= rescale_x;
+       vals->values_supplied = vals->values_supplied & ~POINTSIZE_MASK;
+       /* Recompute and reround the FontScalablePtr values after
+          rescaling for the new width. */
+       FontFileCompleteXLFD(vals, vals);
+    }
+
+    return result;
+}
+
+static long
+doround(double x)
+{
+    return (x >= 0) ? (long)(x + .5) : (long)(x - .5);
+}
+
+static int
+computeProps(FontPropPtr pf, char *wasStringProp, 
+            FontPropPtr npf, char *isStringProp, 
+            unsigned int nprops, double xfactor, double yfactor,
+            double sXfactor, double sYfactor)
+{
+    int         n;
+    int         count;
+    fontProp   *t;
+    double      rawfactor = 0.0;
+
+    for (count = 0; nprops > 0; nprops--, pf++, wasStringProp++) {
+       n = sizeof(fontPropTable) / sizeof(fontProp);
+       for (t = fontPropTable; n && (t->atom != pf->name); n--, t++);
+       if (!n)
+           continue;
+
+       switch (t->type) {
+       case scaledX:
+           npf->value = doround(xfactor * (double)pf->value);
+           rawfactor = sXfactor;
+           break;
+       case scaledY:
+           npf->value = doround(yfactor * (double)pf->value);
+           rawfactor = sYfactor;
+           break;
+       case unscaled:
+           npf->value = pf->value;
+           npf->name = pf->name;
+           npf++;
+           count++;
+           *isStringProp++ = *wasStringProp;
+           break;
+       default:
+           break;
+       }
+       if (t->type != unscaled)
+       {
+           npf->name = pf->name;
+           npf++;
+           count++;
+           npf->value = doround(rawfactor * (double)pf->value);
+           npf->name = rawFontPropTable[t - fontPropTable].atom;
+           npf++;
+           count++;
+           *isStringProp++ = *wasStringProp;
+           *isStringProp++ = *wasStringProp;
+       }
+    }
+    return count;
+}
+
+
+static int
+ComputeScaledProperties(FontInfoPtr sourceFontInfo, /* the font to be scaled */
+                       char *name,             /* name of resulting font */
+                       FontScalablePtr vals, 
+                       double dx, double dy,   /* scale factors in x and y */
+                       double sdx, double sdy, /* directions */
+                       long sWidth,            /* 1000-pixel average width */
+                       FontPropPtr *pProps,    /* returns properties; 
+                                                  preallocated */
+                       char **pIsStringProp)   /* return booleans; 
+                                                  preallocated */
+{
+    int         n;
+    char       *ptr1 = NULL, *ptr2 = NULL;
+    char       *ptr3;
+    FontPropPtr fp;
+    fontProp   *fpt;
+    char       *isStringProp;
+    int                nProps;
+
+    if (bitscaleGeneration != serverGeneration) {
+       initFontPropTable();
+       bitscaleGeneration = serverGeneration;
+    }
+    nProps = NPROPS + 1 + sizeof(fontPropTable) / sizeof(fontProp) +
+                         sizeof(rawFontPropTable) / sizeof(fontProp);
+    fp = malloc(sizeof(FontPropRec) * nProps);
+    *pProps = fp;
+    if (!fp) {
+       fprintf(stderr, "Error: Couldn't allocate font properties (%ld*%d)\n",
+               (unsigned long)sizeof(FontPropRec), nProps);
+       return 1;
+    }
+    isStringProp = malloc (nProps);
+    *pIsStringProp = isStringProp;
+    if (!isStringProp)
+    {
+ fprintf(stderr, "Error: Couldn't allocate isStringProp (%d)\n", nProps);
+       free (fp);
+       return 1;
+    }
+    ptr2 = name;
+    for (fpt = fontNamePropTable, n = NPROPS;
+        n;
+        fp++, fpt++, n--, isStringProp++)
+    {
+
+       if (*ptr2)
+       {
+           ptr1 = ptr2 + 1;
+           if (!(ptr2 = strchr(ptr1, '-'))) ptr2 = strchr(ptr1, '\0');
+       }
+
+       *isStringProp = 0;
+       switch (fpt->type) {
+       case atom:
+           fp->value = MakeAtom(ptr1, ptr2 - ptr1, TRUE);
+           *isStringProp = 1;
+           break;
+       case truncate_atom:
+           for (ptr3 = ptr1; *ptr3; ptr3++)
+               if (*ptr3 == '[')
+                   break;
+           if (!*ptr3) ptr3 = ptr2;
+           fp->value = MakeAtom(ptr1, ptr3 - ptr1, TRUE);
+           *isStringProp = 1;
+           break;
+       case pixel_size:
+           fp->value = doround(vals->pixel_matrix[3]);
+           break;
+       case point_size:
+           fp->value = doround(vals->point_matrix[3] * 10.0);
+           break;
+       case resolution_x:
+           fp->value = vals->x;
+           break;
+       case resolution_y:
+           fp->value = vals->y;
+           break;
+       case average_width:
+           fp->value = vals->width;
+           break;
+       case fontname:
+           fp->value = MakeAtom(name, strlen(name), TRUE);
+           *isStringProp = 1;
+           break;
+       case raw_ascent:
+           fp->value = sourceFontInfo->fontAscent * sdy;
+           break;
+       case raw_descent:
+           fp->value = sourceFontInfo->fontDescent * sdy;
+           break;
+       case raw_pointsize:
+           fp->value = (long)(72270.0 / (double)vals->y + .5);
+           break;
+       case raw_pixelsize:
+           fp->value = 1000;
+           break;
+       case raw_average_width:
+           fp->value = sWidth;
+           break;
+       default:
+           break;
+       }
+       fp->name = fpt->atom;
+    }
+    n = NPROPS;
+    n += computeProps(sourceFontInfo->props, sourceFontInfo->isStringProp,
+                     fp, isStringProp, sourceFontInfo->nprops, dx, dy,
+                     sdx, sdy);
+    return n;
+}
+
+
+static int
+compute_xform_matrix(FontScalablePtr vals, double dx, double dy, 
+                    double *xform, double *inv_xform, 
+                    double *xmult, double *ymult)
+{
+    double det;
+    double pixel = get_matrix_vertical_component(vals->pixel_matrix);
+    double pixelset = get_matrix_horizontal_component(vals->pixel_matrix);
+
+    if (pixel < EPS || pixelset < EPS) return 0;
+
+    /* Initialize the transformation matrix to the scaling factors */
+    xform[0] = dx / pixelset;
+    xform[1] = xform[2] = 0.0;
+    xform[3] = dy / pixel;
+
+/* Inline matrix multiply -- somewhat ugly to minimize register usage */
+#define MULTIPLY_XFORM(a,b,c,d) \
+{ \
+  register double aa = (a), bb = (b), cc = (c), dd = (d); \
+  register double temp; \
+  temp =     aa * xform[0] + cc * xform[1]; \
+  aa =       aa * xform[2] + cc * xform[3]; \
+  xform[1] = bb * xform[0] + dd * xform[1]; \
+  xform[3] = bb * xform[2] + dd * xform[3]; \
+  xform[0] = temp; \
+  xform[2] = aa; \
+}
+
+    /* Rescale the transformation matrix for size of source font */
+    MULTIPLY_XFORM(vals->pixel_matrix[0],
+                  vals->pixel_matrix[1],
+                  vals->pixel_matrix[2],
+                  vals->pixel_matrix[3]);
+
+    *xmult = xform[0];
+    *ymult = xform[3];
+
+
+    if (inv_xform == NULL) return 1;
+
+    /* Compute the determinant for use in inverting the matrix. */
+    det = xform[0] * xform[3] - xform[1] * xform[2];
+
+    /* If the determinant is tiny or zero, give up */
+    if (fabs(det) < EPS) return 0;
+
+    /* Compute the inverse */
+    inv_xform[0] = xform[3] / det;
+    inv_xform[1] = -xform[1] / det;
+    inv_xform[2] = -xform[2] / det;
+    inv_xform[3] = xform[0] / det;
+
+    return 1;
+}
+
+/*
+ *  ScaleFont
+ *  returns a pointer to the new scaled font, or NULL (due to AllocError).
+ */
+static FontPtr
+ScaleFont(FontPtr opf,            /* originating font */                    
+         double widthMult,       /* glyphs width scale factor */           
+         double heightMult,      /* glyphs height scale factor */          
+         double sWidthMult,      /* scalable glyphs width scale factor */  
+         double sHeightMult,     /* scalable glyphs height scale factor */ 
+         FontScalablePtr vals,                                             
+         double *newWidthMult,   /* return: X component of glyphs width    
+                                    scale factor */                        
+         double *newHeightMult,  /* return: Y component of glyphs height   
+                                    scale factor */                        
+         long *sWidth)           /* return: average 1000-pixel width */    
+{
+    FontPtr     pf;
+    FontInfoPtr pfi,
+                opfi;
+    BitmapFontPtr  bitmapFont,
+                obitmapFont;
+    CharInfoPtr pci,
+                opci;
+    int         nchars = 0;    /* how many characters in the font */
+    int         i;
+    int                firstCol, lastCol, firstRow, lastRow;
+    double     xform[4], inv_xform[4];
+    double     xmult, ymult;
+    int                totalwidth = 0, totalchars = 0;
+#define OLDINDEX(i) (((i)/(lastCol - firstCol + 1) + \
+                     firstRow - opf->info.firstRow) * \
+                    (opf->info.lastCol - opf->info.firstCol + 1) + \
+                    (i)%(lastCol - firstCol + 1) + \
+                    firstCol - opf->info.firstCol)
+
+    *sWidth = 0;
+
+    opfi = &opf->info;
+    obitmapFont = (BitmapFontPtr) opf->fontPrivate;
+
+    bitmapFont = 0;
+    if (!(pf = CreateFontRec())) {
+       fprintf(stderr, "Error: Couldn't allocate FontRec (%ld)\n",
+               (unsigned long)sizeof(FontRec));
+       goto bail;
+    }
+    pf->refcnt = 0;
+    pf->bit = opf->bit;
+    pf->byte = opf->byte;
+    pf->glyph = opf->glyph;
+    pf->scan = opf->scan;
+
+    pf->get_glyphs = bitmapGetGlyphs;
+    pf->get_metrics = bitmapGetMetrics;
+    pf->unload_font = bitmapUnloadScalable;
+    pf->unload_glyphs = NULL;
+
+    pfi = &pf->info;
+    *pfi = *opfi;
+    /* If charset subsetting specified in vals, determine what our range
+       needs to be for the output font */
+    if (vals->nranges)
+    {
+       int i;
+
+       pfi->allExist = 0;
+       firstCol = 255;
+       lastCol = 0;
+       firstRow = 255;
+       lastRow = 0;
+
+       for (i = 0; i < vals->nranges; i++)
+       {
+           if (vals->ranges[i].min_char_high != vals->ranges[i].max_char_high)
+           {
+               firstCol = opfi->firstCol;
+               lastCol = opfi->lastCol;
+           }
+           if (firstCol > vals->ranges[i].min_char_low)
+               firstCol = vals->ranges[i].min_char_low;
+           if (lastCol < vals->ranges[i].max_char_low)
+               lastCol = vals->ranges[i].max_char_low;
+           if (firstRow > vals->ranges[i].min_char_high)
+               firstRow = vals->ranges[i].min_char_high;
+           if (lastRow < vals->ranges[i].max_char_high)
+               lastRow = vals->ranges[i].max_char_high;
+       }
+
+       if (firstCol > lastCol || firstRow > lastRow)
+           goto bail;
+
+       if (firstCol < opfi->firstCol)
+           firstCol = opfi->firstCol;
+       if (lastCol > opfi->lastCol)
+           lastCol = opfi->lastCol;
+       if (firstRow < opfi->firstRow)
+           firstRow = opfi->firstRow;
+       if (lastRow > opfi->lastRow)
+           lastRow = opfi->lastRow;
+    }
+    else
+    {
+       firstCol = opfi->firstCol;
+       lastCol = opfi->lastCol;
+       firstRow = opfi->firstRow;
+       lastRow = opfi->lastRow;
+    }
+
+    bitmapFont = malloc(sizeof(BitmapFontRec));
+    if (!bitmapFont) {
+       fprintf(stderr, "Error: Couldn't allocate bitmapFont (%ld)\n",
+               (unsigned long)sizeof(BitmapFontRec));
+       goto bail;
+    }
+    nchars = (lastRow - firstRow + 1) * (lastCol - firstCol + 1);
+    pfi->firstRow = firstRow;
+    pfi->lastRow = lastRow;
+    pfi->firstCol = firstCol;
+    pfi->lastCol = lastCol;
+    pf->fontPrivate = (pointer) bitmapFont;
+    bitmapFont->version_num = obitmapFont->version_num;
+    bitmapFont->num_chars = nchars;
+    bitmapFont->num_tables = obitmapFont->num_tables;
+    bitmapFont->metrics = 0;
+    bitmapFont->ink_metrics = 0;
+    bitmapFont->bitmaps = 0;
+    bitmapFont->encoding = 0;
+    bitmapFont->bitmapExtra = 0;
+    bitmapFont->pDefault = 0;
+    bitmapFont->metrics = malloc(nchars * sizeof(CharInfoRec));
+    if (!bitmapFont->metrics) {
+       fprintf(stderr, "Error: Couldn't allocate metrics (%d*%ld)\n",
+               nchars, (unsigned long)sizeof(CharInfoRec));
+       goto bail;
+    }
+    bitmapFont->encoding = calloc(NUM_SEGMENTS(nchars), sizeof(CharInfoPtr*));
+    if (!bitmapFont->encoding) {
+       fprintf(stderr, "Error: Couldn't allocate encoding (%d*%ld)\n",
+               nchars, (unsigned long)sizeof(CharInfoPtr));
+       goto bail;
+    }
+
+#undef MAXSHORT
+#define MAXSHORT    32767
+#undef MINSHORT
+#define MINSHORT    -32768
+
+    pfi->anamorphic = FALSE;
+    if (heightMult != widthMult)
+       pfi->anamorphic = TRUE;
+    pfi->cachable = TRUE;
+
+    if (!compute_xform_matrix(vals, widthMult, heightMult, xform,
+                             inv_xform, &xmult, &ymult))
+       goto bail;
+
+    pfi->fontAscent = opfi->fontAscent * ymult;
+    pfi->fontDescent = opfi->fontDescent * ymult;
+
+    pfi->minbounds.leftSideBearing = MAXSHORT;
+    pfi->minbounds.rightSideBearing = MAXSHORT;
+    pfi->minbounds.ascent = MAXSHORT;
+    pfi->minbounds.descent = MAXSHORT;
+    pfi->minbounds.characterWidth = MAXSHORT;
+    pfi->minbounds.attributes = MAXSHORT;
+
+    pfi->maxbounds.leftSideBearing = MINSHORT;
+    pfi->maxbounds.rightSideBearing = MINSHORT;
+    pfi->maxbounds.ascent = MINSHORT;
+    pfi->maxbounds.descent = MINSHORT;
+    pfi->maxbounds.characterWidth = MINSHORT;
+    pfi->maxbounds.attributes = MINSHORT;
+
+    /* Compute the transformation and inverse transformation matrices.
+       Can fail if the determinant is zero. */
+
+    pci = bitmapFont->metrics;
+    for (i = 0; i < nchars; i++)
+    {
+       if ((opci = ACCESSENCODING(obitmapFont->encoding,OLDINDEX(i))))
+       {
+           double newlsb, newrsb, newdesc, newasc, point[2];
+
+#define minchar(p) ((p).min_char_low + ((p).min_char_high << 8))
+#define maxchar(p) ((p).max_char_low + ((p).max_char_high << 8))
+
+           if (vals->nranges)
+           {
+               int row = i / (lastCol - firstCol + 1) + firstRow;
+               int col = i % (lastCol - firstCol + 1) + firstCol;
+               int ch = (row << 8) + col;
+               int j;
+               for (j = 0; j < vals->nranges; j++)
+                   if (ch >= minchar(vals->ranges[j]) &&
+                       ch <= maxchar(vals->ranges[j]))
+                       break;
+               if (j == vals->nranges)
+               {
+                   continue;
+               }
+           }
+
+           if (opci->metrics.leftSideBearing == 0 &&
+               opci->metrics.rightSideBearing == 0 &&
+               opci->metrics.ascent == 0 &&
+               opci->metrics.descent == 0 &&
+               opci->metrics.characterWidth == 0)
+           {
+               continue;
+           }
+
+            if(!bitmapFont->encoding[SEGMENT_MAJOR(i)]) {
+                bitmapFont->encoding[SEGMENT_MAJOR(i)]=
+                  calloc(BITMAP_FONT_SEGMENT_SIZE, sizeof(CharInfoPtr));
+                if(!bitmapFont->encoding[SEGMENT_MAJOR(i)])
+                    goto bail;
+            }
+           ACCESSENCODINGL(bitmapFont->encoding, i) = pci;
+
+           /* Compute new extents for this glyph */
+           TRANSFORM_POINT(xform,
+                           opci->metrics.leftSideBearing,
+                           -opci->metrics.descent,
+                           point);
+           newlsb = point[0];
+           newrsb = newlsb;
+           newdesc = -point[1];
+           newasc = -newdesc;
+           TRANSFORM_POINT(xform,
+                           opci->metrics.leftSideBearing,
+                           opci->metrics.ascent,
+                           point);
+           CHECK_EXTENT(newlsb, newrsb, newdesc, newasc, point);
+           TRANSFORM_POINT(xform,
+                           opci->metrics.rightSideBearing,
+                           -opci->metrics.descent,
+                           point);
+           CHECK_EXTENT(newlsb, newrsb, newdesc, newasc, point);
+           TRANSFORM_POINT(xform,
+                           opci->metrics.rightSideBearing,
+                           opci->metrics.ascent,
+                           point);
+           CHECK_EXTENT(newlsb, newrsb, newdesc, newasc, point);
+
+           pci->metrics.leftSideBearing = (int)floor(newlsb);
+           pci->metrics.rightSideBearing = (int)floor(newrsb + .5);
+           pci->metrics.descent = (int)ceil(newdesc);
+           pci->metrics.ascent = (int)floor(newasc + .5);
+           /* Accumulate total width of characters before transformation,
+              to ascertain predominant direction of font. */
+           totalwidth += opci->metrics.characterWidth;
+           pci->metrics.characterWidth =
+               doround((double)opci->metrics.characterWidth * xmult);
+           pci->metrics.attributes =
+               doround((double)opci->metrics.characterWidth * sWidthMult);
+           if (!pci->metrics.characterWidth)
+           {
+               /* Since transformation may shrink width, height, and
+                  escapement to zero, make sure existing characters
+                  are not mistaken for undefined characters. */
+
+               if (pci->metrics.rightSideBearing ==
+                   pci->metrics.leftSideBearing)
+                   pci->metrics.rightSideBearing++;
+               if (pci->metrics.ascent == -pci->metrics.descent)
+                   pci->metrics.ascent++;
+           }
+    
+           pci++;
+       }
+    }
+
+
+    /*
+     * For each character, set the per-character metrics, scale the glyph, and
+     * check per-font minbounds and maxbounds character information.
+     */
+
+    pci = bitmapFont->metrics;
+    for (i = 0; i < nchars; i++)
+    {
+       if ((pci = ACCESSENCODING(bitmapFont->encoding,i)) &&
+           (opci = ACCESSENCODING(obitmapFont->encoding,OLDINDEX(i))))
+       {
+           totalchars++;
+           *sWidth += abs((int)(INT16)pci->metrics.attributes);
+#define MINMAX(field) \
+           if (pfi->minbounds.field > pci->metrics.field) \
+               pfi->minbounds.field = pci->metrics.field; \
+           if (pfi->maxbounds.field < pci->metrics.field) \
+               pfi->maxbounds.field = pci->metrics.field
+    
+           MINMAX(leftSideBearing);
+           MINMAX(rightSideBearing);
+           MINMAX(ascent);
+           MINMAX(descent);
+           MINMAX(characterWidth);
+
+           /* Hack: Cast attributes into a signed quantity.  Tread lightly
+              for now and don't go changing the global Xproto.h file */
+           if ((INT16)pfi->minbounds.attributes >
+               (INT16)pci->metrics.attributes)
+               pfi->minbounds.attributes = pci->metrics.attributes;
+           if ((INT16)pfi->maxbounds.attributes <
+               (INT16)pci->metrics.attributes)
+               pfi->maxbounds.attributes = pci->metrics.attributes;
+#undef MINMAX
+       }
+    }
+    pfi->ink_minbounds = pfi->minbounds;
+    pfi->ink_maxbounds = pfi->maxbounds;
+    if (totalchars)
+    {
+       *sWidth = (*sWidth * 10 + totalchars / 2) / totalchars;
+       if (totalwidth < 0)
+       {
+           /* Dominant direction is R->L */
+           *sWidth = -*sWidth;
+       }
+
+       if (pfi->minbounds.characterWidth == pfi->maxbounds.characterWidth)
+           vals->width = pfi->minbounds.characterWidth * 10;
+       else
+           vals->width = doround((double)*sWidth * vals->pixel_matrix[0] /
+                                 1000.0);
+    }
+    else
+    {
+       vals->width = 0;
+       *sWidth = 0;
+    }
+    FontComputeInfoAccelerators (pfi);
+
+    if (pfi->defaultCh != (unsigned short) NO_SUCH_CHAR) {
+       unsigned int r,
+                   c,
+                   cols;
+
+       r = pfi->defaultCh >> 8;
+       c = pfi->defaultCh & 0xFF;
+       if (pfi->firstRow <= r && r <= pfi->lastRow &&
+               pfi->firstCol <= c && c <= pfi->lastCol) {
+           cols = pfi->lastCol - pfi->firstCol + 1;
+           r = r - pfi->firstRow;
+           c = c - pfi->firstCol;
+           bitmapFont->pDefault = 
+                ACCESSENCODING(bitmapFont->encoding, r * cols + c);
+       }
+    }
+
+    *newWidthMult = xmult;
+    *newHeightMult = ymult;
+    return pf;
+bail:
+    if (pf)
+       free(pf);
+    if (bitmapFont) {
+       free(bitmapFont->metrics);
+       free(bitmapFont->ink_metrics);
+       free(bitmapFont->bitmaps);
+        if(bitmapFont->encoding)
+            for(i=0; i<NUM_SEGMENTS(nchars); i++)
+                free(bitmapFont->encoding[i]);
+       free(bitmapFont->encoding);
+    }
+    return NULL;
+}
+
+static void
+ScaleBitmap(FontPtr pFont, CharInfoPtr opci, CharInfoPtr pci, 
+           double *inv_xform, double widthMult, double heightMult)
+{
+    register char  *bitmap,            /* The bits */
+               *newBitmap;
+    register int   bpr,                        /* Padding information */
+               newBpr;
+    int         width,                 /* Extents information */
+                height,
+                newWidth,
+                newHeight;
+    register int row,                  /* Loop variables */
+               col;
+    INT32      deltaX,                 /* Increments for resampling loop */
+               deltaY;
+    INT32      xValue,                 /* Subscripts for resampling loop */
+               yValue;
+    double     point[2];
+    unsigned char *char_grayscale = 0;
+    INT32      *diffusion_workspace = NULL, *thisrow = NULL,
+                *nextrow = NULL, pixmult = 0;
+    int                box_x = 0, box_y = 0;
+
+    static unsigned char masklsb[] =
+       { 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80 };
+    static unsigned char maskmsb[] =
+       { 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1 };
+    unsigned char      *mask = (pFont->bit == LSBFirst ? masklsb : maskmsb);
+
+
+    bitmap = opci->bits;
+    newBitmap = pci->bits;
+    width = GLYPHWIDTHPIXELS(opci);
+    height = GLYPHHEIGHTPIXELS(opci);
+    newWidth = GLYPHWIDTHPIXELS(pci);
+    newHeight = GLYPHHEIGHTPIXELS(pci);
+    if (!newWidth || !newHeight || !width || !height)
+       return;
+
+    bpr = BYTES_PER_ROW(width, pFont->glyph);
+    newBpr = BYTES_PER_ROW(newWidth, pFont->glyph);
+
+    if (widthMult > 0.0 && heightMult > 0.0 &&
+       (widthMult < 1.0 || heightMult < 1.0))
+    {
+       /* We are reducing in one or both dimensions.  In an attempt to
+          reduce aliasing, we'll antialias by passing the original
+          glyph through a low-pass box filter (which results in a
+          grayscale image), then use error diffusion to create bitonal
+          output in the resampling loop.  */
+
+       /* First compute the sizes of the box filter */
+       widthMult = ceil(1.0 / widthMult);
+       heightMult = ceil(1.0 / heightMult);
+       box_x = width / 2;
+       box_y = height / 2;
+       if (widthMult < (double)box_x) box_x = (int)widthMult;
+       if (heightMult < (double)box_y) box_y = (int)heightMult;
+       /* The pixmult value (below) is used to darken the image before
+          we perform error diffusion: a necessary concession to the
+          fact that it's very difficult to generate readable halftoned
+          glyphs.  The degree of darkening is proportional to the size
+          of the blurring filter, hence inversely proportional to the
+          darkness of the lightest gray that results from antialiasing.
+          The result is that characters that exercise this logic (those
+          generated by reducing from a larger source font) tend to err
+          on the side of being too bold instead of being too light to
+          be readable. */
+       pixmult = box_x * box_y * 192;
+
+       if (box_x > 1 || box_y > 1)
+       {
+           /* Looks like we need to anti-alias.  Create a workspace to
+              contain the grayscale character plus an additional row and
+              column for scratch */
+           char_grayscale = malloc((width + 1) * (height + 1));
+           if (char_grayscale)
+           {
+               diffusion_workspace = calloc((newWidth + 2) * 2, sizeof(int));
+               if (!diffusion_workspace)
+               {
+                   fprintf(stderr, "Warning: Couldn't allocate diffusion"
+                           " workspace (%ld)\n",
+                           (newWidth + 2) * 2 * (unsigned long)sizeof(int));
+                   free(char_grayscale);
+                   char_grayscale = (unsigned char *)0;
+               }
+               /* Initialize our error diffusion workspace for later use */
+               thisrow = diffusion_workspace + 1;
+               nextrow = diffusion_workspace + newWidth + 3;
+     } else {
+  fprintf(stderr, "Warning: Couldn't allocate character grayscale (%d)\n", (width + 1) * (height + 1));
+           }
+       }
+    }
+
+    if (char_grayscale)
+    {
+       /* We will be doing antialiasing.  First copy the bitmap into
+          our buffer, mapping input range [0,1] to output range
+          [0,255].  */
+       register unsigned char *srcptr, *dstptr;
+       srcptr = (unsigned char *)bitmap;
+       dstptr = char_grayscale;
+       for (row = 0; row < height; row++)
+       {
+           for (col = 0; col < width; col++)
+               *dstptr++ = (srcptr[col >> 3] & mask[col & 0x7]) ? 255 : 0;
+           srcptr += bpr;      /* On to next row of source */
+           dstptr++;           /* Skip scratch column in dest */
+       }
+       if (box_x > 1)
+       {
+           /* Our box filter has a width > 1... let's filter the rows */
+
+           int right_width = box_x / 2;
+           int left_width = box_x - right_width - 1;
+
+           for (row = 0; row < height; row++)
+           {
+               int sum = 0;
+               int left_size = 0, right_size = 0;
+
+               srcptr = char_grayscale + (width + 1) * row;
+               dstptr = char_grayscale + (width + 1) * height; /* scratch */
+
+               /* We've computed the shape of our full box filter.  Now
+                  compute the right-hand part of the moving sum */
+               for (right_size = 0; right_size < right_width; right_size++)
+                   sum += srcptr[right_size];
+
+               /* Now start moving the sum, growing the box filter, and
+                  dropping averages into our scratch buffer */
+               for (left_size = 0; left_size < left_width; left_size++)
+               {
+                   sum += srcptr[right_width];
+                   *dstptr++ = sum / (left_size + right_width + 1);
+                   srcptr++;
+               }
+
+               /* The box filter has reached full width... continue
+                  computation of moving average until the right side
+                  hits the wall. */
+               for (col = left_size; col + right_size < width; col++)
+               {
+                   sum += srcptr[right_width];
+                   *dstptr++ = sum / box_x;
+                   sum -= srcptr[-left_width];
+                   srcptr++;
+               }
+
+               /* Collapse the right side of the box filter */
+               for (; right_size > 0; right_size--)
+               {
+                   *dstptr++ = sum / (left_width + right_size);
+                   sum -= srcptr[-left_width];
+                   srcptr++;
+               }
+
+               /* Done with the row... copy dest back over source */
+               memmove(char_grayscale + (width + 1) * row,
+                       char_grayscale + (width + 1) * height,
+                       width);
+           }
+       }
+       if (box_y > 1)
+       {
+           /* Our box filter has a height > 1... let's filter the columns */
+
+           int bottom_height = box_y / 2;
+           int top_height = box_y - bottom_height - 1;
+
+           for (col = 0; col < width; col++)
+           {
+               int sum = 0;
+               int top_size = 0, bottom_size = 0;
+
+               srcptr = char_grayscale + col;
+               dstptr = char_grayscale + width;         /* scratch */
+
+               /* We've computed the shape of our full box filter.  Now
+                  compute the bottom part of the moving sum */
+               for (bottom_size = 0;
+                    bottom_size < bottom_height;
+                    bottom_size++)
+                   sum += srcptr[bottom_size * (width + 1)];
+
+               /* Now start moving the sum, growing the box filter, and
+                  dropping averages into our scratch buffer */
+               for (top_size = 0; top_size < top_height; top_size++)
+               {
+                   sum += srcptr[bottom_height * (width + 1)];
+                   *dstptr = sum / (top_size + bottom_height + 1);
+                   dstptr += width + 1;
+                   srcptr += width + 1;
+               }
+
+               /* The box filter has reached full height... continue
+                  computation of moving average until the bottom
+                  hits the wall. */
+               for (row = top_size; row + bottom_size < height; row++)
+               {
+                   sum += srcptr[bottom_height * (width + 1)];
+                   *dstptr = sum / box_y;
+                   dstptr += width + 1;
+                   sum -= srcptr[-top_height * (width + 1)];
+                   srcptr += width + 1;
+               }
+
+               /* Collapse the bottom of the box filter */
+               for (; bottom_size > 0; bottom_size--)
+               {
+                   *dstptr = sum / (top_height + bottom_size);
+                   dstptr += width + 1;
+                   sum -= srcptr[-top_height * (width + 1)];
+                   srcptr += width + 1;
+               }
+
+               /* Done with the column... copy dest back over source */
+
+               dstptr = char_grayscale + col;
+               srcptr = char_grayscale + width;         /* scratch */
+               for (row = 0; row < height; row++)
+               {
+                   *dstptr = *srcptr;
+                   dstptr += width + 1;
+                   srcptr += width + 1;
+               }
+           }
+       }
+
+       /* Increase the grayvalue to increase ink a bit */
+       srcptr = char_grayscale;
+       for (row = 0; row < height; row++)
+       {
+           for (col = 0; col < width; col++)
+           {
+               register int pixvalue = (int)*srcptr * pixmult / 256;
+               if (pixvalue > 255) pixvalue = 255;
+               *srcptr = pixvalue;
+               srcptr++;
+           }
+           srcptr++;
+       }
+    }
+
+    /* Compute the increment values for the resampling loop */
+    TRANSFORM_POINT(inv_xform, 1, 0, point);
+    deltaX = (INT32)(point[0] * 65536.0);
+    deltaY = (INT32)(-point[1] * 65536.0);
+
+    /* Resampling loop:  resamples original glyph for generation of new
+       glyph in transformed coordinate system. */
+
+    for (row = 0; row < newHeight; row++)
+    {
+       /* Compute inverse transformation for start of this row */
+       TRANSFORM_POINT(inv_xform,
+                       (double)(pci->metrics.leftSideBearing) + .5,
+                       (double)(pci->metrics.ascent - row) - .5,
+                       point);
+
+       /* Adjust for coordinate system to get resampling point */
+       point[0] -= opci->metrics.leftSideBearing;
+       point[1] = opci->metrics.ascent - point[1];
+
+       /* Convert to integer coordinates */
+       xValue = (INT32)(point[0] * 65536.0);
+       yValue = (INT32)(point[1] * 65536.0);
+
+       if (char_grayscale)
+       {
+           INT32 *temp;
+           for (col = 0; col < newWidth; col++)
+           {
+               register int x = xValue >> 16, y = yValue >> 16;
+               int pixvalue, error;
+    
+               pixvalue = ((x >= 0 && x < width && y >= 0 && y < height) ?
+                           char_grayscale[x + y * (width + 1)] : 0) +
+                          thisrow[col] / 16;
+               if (pixvalue > 255) pixvalue = 255;
+               else if (pixvalue < 0) pixvalue = 0;
+
+               /* Choose the bit value and set resulting error value */
+               if (pixvalue >= 128)
+               {
+                   newBitmap[(col >> 3) + row * newBpr] |= mask[col & 0x7];
+                   error = pixvalue - 255;
+               }
+               else
+                   error = -pixvalue;
+
+               /* Diffuse the error */
+               thisrow[col + 1] += error * 7;
+               nextrow[col - 1] += error * 3;
+               nextrow[col] += error * 5;
+               nextrow[col + 1] = error;
+
+               xValue += deltaX;
+               yValue += deltaY;
+           }
+
+           /* Add in error values that fell off either end */
+           nextrow[0] += nextrow[-1];
+           nextrow[newWidth - 2] += thisrow[newWidth];
+           nextrow[newWidth - 1] += nextrow[newWidth];
+           nextrow[newWidth] = 0;
+
+           temp = nextrow;
+           nextrow = thisrow;
+           thisrow = temp;
+           nextrow[-1] = nextrow[0] = 0;
+       }
+       else
+       {
+           for (col = 0; col < newWidth; col++)
+           {
+               register int x = xValue >> 16, y = yValue >> 16;
+    
+               if (x >= 0 && x < width && y >= 0 && y < height)
+               {
+                   /* Use point-sampling for rescaling. */
+
+                   if (bitmap[(x >> 3) + y * bpr] & mask[x & 0x7])
+                       newBitmap[(col >> 3) + row * newBpr] |= mask[col & 0x7];
+               }
+
+               xValue += deltaX;
+               yValue += deltaY;
+           }
+       }
+    }
+
+
+    if (char_grayscale)
+    {
+       free(char_grayscale);
+       free(diffusion_workspace);
+    }
+}
+
+static FontPtr
+BitmapScaleBitmaps(FontPtr pf,          /* scaled font */
+                  FontPtr opf,         /* originating font */
+                  double widthMult,    /* glyphs width scale factor */
+                  double heightMult,   /* glyphs height scale factor */
+                  FontScalablePtr vals)
+{
+    register int i;
+    int                nchars = 0;
+    char       *glyphBytes;
+    BitmapFontPtr  bitmapFont,
+                  obitmapFont;
+    CharInfoPtr pci,
+               opci;
+    FontInfoPtr pfi;
+    int         glyph;
+    unsigned    bytestoalloc = 0;
+    int                firstCol, lastCol, firstRow, lastRow;
+
+    double     xform[4], inv_xform[4];
+    double     xmult, ymult;
+
+    bitmapFont = (BitmapFontPtr) pf->fontPrivate;
+    obitmapFont = (BitmapFontPtr) opf->fontPrivate;
+
+    if (!compute_xform_matrix(vals, widthMult, heightMult, xform,
+                             inv_xform, &xmult, &ymult))
+       goto bail;
+
+    pfi = &pf->info;
+    firstCol = pfi->firstCol;
+    lastCol = pfi->lastCol;
+    firstRow = pfi->firstRow;
+    lastRow = pfi->lastRow;
+
+    nchars = (lastRow - firstRow + 1) * (lastCol - firstCol + 1);
+    glyph = pf->glyph;
+    for (i = 0; i < nchars; i++)
+    {
+       if ((pci = ACCESSENCODING(bitmapFont->encoding, i)))
+           bytestoalloc += BYTES_FOR_GLYPH(pci, glyph);
+    }
+
+    /* Do we add the font malloc stuff for VALUE ADDED ? */
+    /* Will need to remember to free in the Unload routine */
+
+
+    bitmapFont->bitmaps = calloc(1, bytestoalloc);
+    if (!bitmapFont->bitmaps) {
+ fprintf(stderr, "Error: Couldn't allocate bitmaps (%d)\n", bytestoalloc);
+       goto bail;
+    }
+
+    glyphBytes = bitmapFont->bitmaps;
+    for (i = 0; i < nchars; i++)
+    {
+       if ((pci = ACCESSENCODING(bitmapFont->encoding, i)) &&
+           (opci = ACCESSENCODING(obitmapFont->encoding, OLDINDEX(i))))
+       {
+           pci->bits = glyphBytes;
+           ScaleBitmap (pf, opci, pci, inv_xform,
+                        widthMult, heightMult);
+           glyphBytes += BYTES_FOR_GLYPH(pci, glyph);
+       }
+    }
+    return pf;
+
+bail:
+    if (pf)
+       free(pf);
+    if (bitmapFont) {
+       free(bitmapFont->metrics);
+       free(bitmapFont->ink_metrics);
+       free(bitmapFont->bitmaps);
+        if(bitmapFont->encoding)
+            for(i=0; i<NUM_SEGMENTS(nchars); i++)
+                free(bitmapFont->encoding[i]);
+       free(bitmapFont->encoding);
+    }
+    return NULL;
+}
+
+/* ARGSUSED */
+int
+BitmapOpenScalable (FontPathElementPtr fpe, 
+                   FontPtr *pFont, 
+                   int flags, 
+                   FontEntryPtr entry, 
+                   char *fileName, /* unused */
+                   FontScalablePtr vals, 
+                   fsBitmapFormat format, 
+                   fsBitmapFormatMask fmask,
+                   FontPtr non_cachable_font)  /* We don't do licensing */
+{
+    FontScalableRec    best;
+    FontPtr            font = NullFont;
+    double             dx, sdx,
+                       dy, sdy,
+                       savedX, savedY;
+    FontPropPtr                props;
+    char               *isStringProp = NULL;
+    int                        propCount;
+    int                        status;
+    long               sWidth;
+
+    FontEntryPtr       scaleFrom;
+    FontPathElementPtr scaleFPE = NULL;
+    FontPtr            sourceFont;
+    char               fontName[MAXFONTNAMELEN];
+
+    /* Can't deal with mix-endian fonts yet */
+
+
+    /* Reject outrageously small font sizes to keep the math from
+       blowing up. */
+    if (get_matrix_vertical_component(vals->pixel_matrix) < 1.0 ||
+       get_matrix_horizontal_component(vals->pixel_matrix) < 1.0)
+       return BadFontName;
+
+    scaleFrom = FindBestToScale(fpe, entry, vals, &best, &dx, &dy, &sdx, &sdy,
+                               &scaleFPE);
+
+    if (!scaleFrom)
+       return BadFontName;
+
+    status = FontFileOpenBitmap(scaleFPE, &sourceFont, LoadAll, scaleFrom,
+                               format, fmask);
+
+    if (status != Successful)
+       return BadFontName;
+
+    if (!vals->width)
+       vals->width = best.width * dx;
+
+    /* Compute the scaled font */
+
+    savedX = dx;
+    savedY = dy;
+    font = ScaleFont(sourceFont, dx, dy, sdx, sdy, vals, &dx, &dy, &sWidth);
+    if (font)
+       font = BitmapScaleBitmaps(font, sourceFont, savedX, savedY, vals);
+
+    if (!font)
+    {
+       if (!sourceFont->refcnt)
+           FontFileCloseFont((FontPathElementPtr) 0, sourceFont);
+       return AllocError;
+    }
+
+    /* Prepare font properties for the new font */
+
+    strcpy (fontName, scaleFrom->name.name);
+    FontParseXLFDName (fontName, vals, FONT_XLFD_REPLACE_VALUE);
+
+    propCount = ComputeScaledProperties(&sourceFont->info, fontName, vals,
+                                       dx, dy, sdx, sdy, sWidth, &props,
+                                       &isStringProp);
+
+    if (!sourceFont->refcnt)
+       FontFileCloseFont((FontPathElementPtr) 0, sourceFont);
+
+    if (propCount && (!props || !isStringProp))
+    {
+       font->info.nprops = 0;
+       font->info.props = (FontPropPtr)0;
+       font->info.isStringProp = (char *)0;
+       bitmapUnloadScalable(font);
+       return AllocError;
+    }
+
+    font->info.props = props;
+    font->info.nprops = propCount;
+    font->info.isStringProp = isStringProp;
+
+    *pFont = font;
+    return Successful;
+}
+
+int
+BitmapGetInfoScalable (FontPathElementPtr fpe, 
+                      FontInfoPtr pFontInfo, 
+                      FontEntryPtr entry, 
+                      FontNamePtr fontName, 
+                      char *fileName, 
+                      FontScalablePtr vals)
+{
+    FontPtr pfont;
+    int flags = 0;
+    long format = 0;  /* It doesn't matter what format for just info */
+    long fmask = 0;
+    int ret;
+
+    ret = BitmapOpenScalable(fpe, &pfont, flags, entry, fileName, vals,
+                            format, fmask, NULL);
+    if (ret != Successful)
+        return ret;
+    *pFontInfo = pfont->info;
+
+    pfont->info.nprops = 0;
+    pfont->info.props = NULL;
+    pfont->info.isStringProp = NULL;
+
+    (*pfont->unload_font)(pfont);
+    return Successful;
+}
+
+static void
+bitmapUnloadScalable (FontPtr pFont)
+{
+    BitmapFontPtr   bitmapFont;
+    FontInfoPtr            pfi;
+    int             i, nencoding;
+
+    bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+    pfi = &pFont->info;
+    free (pfi->props);
+    free (pfi->isStringProp);
+    if(bitmapFont->encoding) {
+        nencoding = (pFont->info.lastCol - pFont->info.firstCol + 1) *
+           (pFont->info.lastRow - pFont->info.firstRow + 1);
+        for(i=0; i<NUM_SEGMENTS(nencoding); i++)
+            free(bitmapFont->encoding[i]);
+    }
+    free (bitmapFont->encoding);
+    free (bitmapFont->bitmaps);
+    free (bitmapFont->ink_metrics);
+    free (bitmapFont->metrics);
+    free (pFont->fontPrivate);
+    DestroyFontRec (pFont);
+}
diff --git a/src/bitmap/fontink.c b/src/bitmap/fontink.c
new file mode 100755 (executable)
index 0000000..ad7091f
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+
+Copyright 1990, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+/*
+ * Author:  Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/bitmap.h>
+#include <X11/fonts/bdfint.h>
+
+static unsigned char ink_mask_msb[8] = {
+    0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
+};
+
+static unsigned char ink_mask_lsb[8] = {
+    0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
+};
+
+void
+FontCharInkMetrics(FontPtr pFont, CharInfoPtr pCI, xCharInfo *pInk)
+{
+    int         leftBearing,
+                ascent,
+                descent;
+    register int vpos,
+                hpos,
+                bpos = 0;
+    int         bitmapByteWidth,
+                bitmapByteWidthPadded;
+    int         bitmapBitWidth;
+    int         span;
+    register unsigned char *p;
+    unsigned char *ink_mask = 0;
+    register int bmax;
+    register unsigned char charbits;
+
+    if (pFont->bit == MSBFirst)
+       ink_mask = ink_mask_msb;
+    else if (pFont->bit == LSBFirst)
+       ink_mask = ink_mask_lsb;
+    pInk->characterWidth = pCI->metrics.characterWidth;
+    pInk->attributes = pCI->metrics.attributes;
+
+    leftBearing = pCI->metrics.leftSideBearing;
+    ascent = pCI->metrics.ascent;
+    descent = pCI->metrics.descent;
+    bitmapBitWidth = GLYPHWIDTHPIXELS(pCI);
+    bitmapByteWidth = GLYPHWIDTHBYTES(pCI);
+    bitmapByteWidthPadded = BYTES_PER_ROW(bitmapBitWidth, pFont->glyph);
+    span = bitmapByteWidthPadded - bitmapByteWidth;
+
+    p = (unsigned char *) pCI->bits;
+    for (vpos = descent + ascent; --vpos >= 0;) {
+       for (hpos = bitmapByteWidth; --hpos >= 0;) {
+           if (*p++ != 0)
+               goto found_ascent;
+       }
+       p += span;
+    }
+    /*
+     * special case -- font with no bits gets all zeros
+     */
+    pInk->leftSideBearing = leftBearing;
+    pInk->rightSideBearing = leftBearing;
+    pInk->ascent = 0;
+    pInk->descent = 0;
+    return;
+found_ascent:
+    pInk->ascent = vpos - descent + 1;
+
+    p = ((unsigned char *) pCI->bits) + bitmapByteWidthPadded * 
+       (descent + ascent - 1) + bitmapByteWidth;
+
+    for (vpos = descent + ascent; --vpos >= 0;) {
+       for (hpos = bitmapByteWidth; --hpos >= 0;) {
+           if (*--p != 0)
+               goto found_descent;
+       }
+       p -= span;
+    }
+found_descent:
+    pInk->descent = vpos - ascent + 1;
+
+    bmax = 8;
+    for (hpos = 0; hpos < bitmapByteWidth; hpos++) {
+       charbits = 0;
+       p = (unsigned char *) pCI->bits + hpos;
+       for (vpos = descent + ascent; --vpos >= 0; p += bitmapByteWidthPadded)
+           charbits |= *p;
+       if (charbits) {
+           if (hpos == bitmapByteWidth - 1)
+               bmax = bitmapBitWidth - (hpos << 3);
+           p = ink_mask;
+           for (bpos = bmax; --bpos >= 0;) {
+               if (charbits & *p++)
+                   goto found_left;
+           }
+       }
+    }
+found_left:
+    pInk->leftSideBearing = leftBearing + (hpos << 3) + bmax - bpos - 1;
+
+    bmax = bitmapBitWidth - ((bitmapByteWidth - 1) << 3);
+    for (hpos = bitmapByteWidth; --hpos >= 0;) {
+       charbits = 0;
+       p = (unsigned char *) pCI->bits + hpos;
+       for (vpos = descent + ascent; --vpos >= 0; p += bitmapByteWidthPadded)
+           charbits |= *p;
+       if (charbits) {
+           p = ink_mask + bmax;
+           for (bpos = bmax; --bpos >= 0;) {
+               if (charbits & *--p)
+                   goto found_right;
+           }
+       }
+       bmax = 8;
+    }
+found_right:
+    pInk->rightSideBearing = leftBearing + (hpos << 3) + bpos + 1;
+}
+
+#define        ISBITONMSB(x, line)     ((line)[(x)/8] & (1 << (7-((x)%8))))
+#define        SETBITMSB(x, line)      ((line)[(x)/8] |= (1 << (7-((x)%8))))
+#define        ISBITONLSB(x, line)     ((line)[(x)/8] & (1 << ((x)%8)))
+#define        SETBITLSB(x, line)      ((line)[(x)/8] |= (1 << ((x)%8)))
+
+#define Min(a,b)    ((a)<(b)?(a):(b))
+#define Max(a,b)    ((a)>(b)?(a):(b))
+
+void
+FontCharReshape(FontPtr pFont, CharInfoPtr pSrc, CharInfoPtr pDst)
+{
+    int         x,
+                y;
+    unsigned char *in_line,
+               *out_line;
+    unsigned char *oldglyph,
+               *newglyph;
+    int         inwidth;
+    int         outwidth,
+                outheight;
+    int         out_bytes,
+                in_bytes;
+    int         y_min,
+                y_max,
+                x_min,
+                x_max;
+
+    newglyph = (unsigned char *) pDst->bits;
+    outwidth = pDst->metrics.rightSideBearing - pDst->metrics.leftSideBearing;
+    outheight = pDst->metrics.descent + pDst->metrics.ascent;
+    out_bytes = BYTES_PER_ROW(outwidth, pFont->glyph);
+
+    oldglyph = (unsigned char *) pSrc->bits;
+    inwidth = pSrc->metrics.rightSideBearing - pSrc->metrics.leftSideBearing;
+    in_bytes = BYTES_PER_ROW(inwidth, pFont->glyph);
+
+    bzero(newglyph, out_bytes * outheight);
+    in_line = oldglyph;
+    out_line = newglyph;
+    y_min = Max(-pSrc->metrics.ascent, -pDst->metrics.ascent);
+    y_max = Min(pSrc->metrics.descent, pDst->metrics.descent);
+    x_min = Max(pSrc->metrics.leftSideBearing, pDst->metrics.leftSideBearing);
+    x_max = Min(pSrc->metrics.rightSideBearing, pDst->metrics.rightSideBearing);
+    in_line += (y_min + pSrc->metrics.ascent) * in_bytes;
+    out_line += (y_min + pDst->metrics.ascent) * out_bytes;
+    if (pFont->bit == MSBFirst) {
+       for (y = y_min; y < y_max; y++) {
+           for (x = x_min; x < x_max; x++) {
+               if (ISBITONMSB(x - pSrc->metrics.leftSideBearing, in_line))
+                   SETBITMSB(x - pDst->metrics.leftSideBearing, out_line);
+           }
+           in_line += in_bytes;
+           out_line += out_bytes;
+       }
+    } else {
+       for (y = y_min; y < y_max; y++) {
+           for (x = x_min; x < x_max; x++) {
+               if (ISBITONLSB(x - pSrc->metrics.leftSideBearing, in_line))
+                   SETBITLSB(x - pDst->metrics.leftSideBearing, out_line);
+           }
+           in_line += in_bytes;
+           out_line += out_bytes;
+       }
+    }
+}
diff --git a/src/bitmap/pcfread.c b/src/bitmap/pcfread.c
new file mode 100755 (executable)
index 0000000..32f9856
--- /dev/null
@@ -0,0 +1,780 @@
+/*
+
+Copyright 1990, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+/*
+ * Author:  Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/bitmap.h>
+#include <X11/fonts/pcf.h>
+
+#ifndef MAX
+#define   MAX(a,b)    (((a)>(b)) ? a : b)
+#endif
+
+#include <stdarg.h>
+#include <stdint.h>
+
+void
+pcfError(const char* message, ...)
+{
+    va_list args;
+
+    va_start(args, message);
+
+    fprintf(stderr, "PCF Error: ");
+    vfprintf(stderr, message, args);
+    va_end(args);
+}
+                              
+/* Read PCF font files */
+
+static void pcfUnloadFont ( FontPtr pFont );
+static int  position;
+
+
+#define IS_EOF(file) ((file)->eof == BUFFILEEOF)
+
+#define FONT_FILE_GETC_ERR(f)  (tmp = FontFileGetc(f), BAIL_ON_EOF)
+
+static int
+pcfGetLSB32(FontFilePtr file)
+{
+    int         c;
+
+    c = FontFileGetc(file);
+    c |= FontFileGetc(file) << 8;
+    c |= FontFileGetc(file) << 16;
+    c |= FontFileGetc(file) << 24;
+    position += 4;
+    return c;
+}
+
+static int
+pcfGetINT32(FontFilePtr file, CARD32 format)
+{
+    int         c;
+
+    if (PCF_BYTE_ORDER(format) == MSBFirst) {
+       c = FontFileGetc(file) << 24;
+       c |= FontFileGetc(file) << 16;
+       c |= FontFileGetc(file) << 8;
+       c |= FontFileGetc(file);
+    } else {
+       c = FontFileGetc(file);
+       c |= FontFileGetc(file) << 8;
+       c |= FontFileGetc(file) << 16;
+       c |= FontFileGetc(file) << 24;
+    }
+    position += 4;
+    return c;
+}
+
+static int
+pcfGetINT16(FontFilePtr file, CARD32 format)
+{
+    int         c;
+
+    if (PCF_BYTE_ORDER(format) == MSBFirst) {
+       c = FontFileGetc(file) << 8;
+       c |= FontFileGetc(file);
+    } else {
+       c = FontFileGetc(file);
+       c |= FontFileGetc(file) << 8;
+    }
+    position += 2;
+    return c;
+}
+
+#define pcfGetINT8(file, format) (position++, FontFileGetc(file))
+
+static      PCFTablePtr
+pcfReadTOC(FontFilePtr file, int *countp)
+{
+    CARD32      version;
+    PCFTablePtr tables;
+    int         count;
+    int         i;
+
+    position = 0;
+    version = pcfGetLSB32(file);
+    if (version != PCF_FILE_VERSION)
+       return (PCFTablePtr) NULL;
+    count = pcfGetLSB32(file);
+    if (IS_EOF(file)) return (PCFTablePtr) NULL;
+    if (count < 0 || count > INT32_MAX / sizeof(PCFTableRec)) {
+       pcfError("pcfReadTOC(): invalid file format\n");
+       return NULL;
+    }
+    tables = malloc(count * sizeof(PCFTableRec));
+    if (!tables) {
+      pcfError("pcfReadTOC(): Couldn't allocate tables (%d*%d)\n", count, sizeof(PCFTableRec));
+       return (PCFTablePtr) NULL;
+    }
+    for (i = 0; i < count; i++) {
+       tables[i].type = pcfGetLSB32(file);
+       tables[i].format = pcfGetLSB32(file);
+       tables[i].size = pcfGetLSB32(file);
+       tables[i].offset = pcfGetLSB32(file);
+       if (IS_EOF(file)) goto Bail;
+    }
+
+    *countp = count;
+    return tables;
+
+ Bail:
+    free(tables);
+    return (PCFTablePtr) NULL;
+}
+
+/*
+ * PCF supports two formats for metrics, both the regular
+ * jumbo size, and 'lite' metrics, which are useful
+ * for most fonts which have even vaguely reasonable
+ * metrics
+ */
+
+static Bool
+pcfGetMetric(FontFilePtr file, CARD32 format, xCharInfo *metric)
+{
+    metric->leftSideBearing = pcfGetINT16(file, format);
+    metric->rightSideBearing = pcfGetINT16(file, format);
+    metric->characterWidth = pcfGetINT16(file, format);
+    metric->ascent = pcfGetINT16(file, format);
+    metric->descent = pcfGetINT16(file, format);
+    metric->attributes = pcfGetINT16(file, format);
+    if (IS_EOF(file)) return FALSE;
+
+    return TRUE;
+}
+
+static Bool
+pcfGetCompressedMetric(FontFilePtr file, CARD32 format, xCharInfo *metric)
+{
+    metric->leftSideBearing = pcfGetINT8(file, format) - 0x80;
+    metric->rightSideBearing = pcfGetINT8(file, format) - 0x80;
+    metric->characterWidth = pcfGetINT8(file, format) - 0x80;
+    metric->ascent = pcfGetINT8(file, format) - 0x80;
+    metric->descent = pcfGetINT8(file, format) - 0x80;
+    metric->attributes = 0;
+    if (IS_EOF(file)) return FALSE;
+
+    return TRUE;
+}
+
+/*
+ * Position the file to the begining of the specified table
+ * in the font file
+ */
+static Bool
+pcfSeekToType(FontFilePtr file, PCFTablePtr tables, int ntables, 
+             CARD32 type, CARD32 *formatp, CARD32 *sizep)
+{
+    int         i;
+
+    for (i = 0; i < ntables; i++)
+       if (tables[i].type == type) {
+           if (position > tables[i].offset)
+               return FALSE;
+           if (!FontFileSkip(file, tables[i].offset - position))
+               return FALSE;
+           position = tables[i].offset;
+           *sizep = tables[i].size;
+           *formatp = tables[i].format;
+           return TRUE;
+       }
+    return FALSE;
+}
+
+static Bool
+pcfHasType (PCFTablePtr tables, int ntables, CARD32 type)
+{
+    int         i;
+
+    for (i = 0; i < ntables; i++)
+       if (tables[i].type == type)
+           return TRUE;
+    return FALSE;
+}
+
+/*
+ * pcfGetProperties 
+ *
+ * Reads the font properties from the font file, filling in the FontInfo rec
+ * supplied.  Used by by both ReadFont and ReadFontInfo routines.
+ */
+
+static Bool
+pcfGetProperties(FontInfoPtr pFontInfo, FontFilePtr file, 
+                PCFTablePtr tables, int ntables)
+{
+    FontPropPtr props = 0;
+    int         nprops;
+    char       *isStringProp = 0;
+    CARD32      format;
+    int         i;
+    CARD32      size;
+    int         string_size;
+    char       *strings;
+
+    /* font properties */
+
+    if (!pcfSeekToType(file, tables, ntables, PCF_PROPERTIES, &format, &size))
+       goto Bail;
+    format = pcfGetLSB32(file);
+    if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
+       goto Bail;
+    nprops = pcfGetINT32(file, format);
+    if (nprops <= 0 || nprops > INT32_MAX / sizeof(FontPropRec)) {
+       pcfError("pcfGetProperties(): invalid nprops value (%d)\n", nprops);
+       goto Bail;
+    }
+    if (IS_EOF(file)) goto Bail;
+    props = malloc(nprops * sizeof(FontPropRec));
+    if (!props) {
+      pcfError("pcfGetProperties(): Couldn't allocate props (%d*%d)\n", nprops, sizeof(FontPropRec));
+       goto Bail;
+    }
+    isStringProp = malloc(nprops * sizeof(char));
+    if (!isStringProp) {
+      pcfError("pcfGetProperties(): Couldn't allocate isStringProp (%d*%d)\n", nprops, sizeof(char));
+       goto Bail;
+    }
+    for (i = 0; i < nprops; i++) {
+       props[i].name = pcfGetINT32(file, format);
+       isStringProp[i] = pcfGetINT8(file, format);
+       props[i].value = pcfGetINT32(file, format);
+       if (props[i].name < 0 
+           || (isStringProp[i] != 0 && isStringProp[i] != 1)
+           || (isStringProp[i] && props[i].value < 0)) {
+           pcfError("pcfGetProperties(): invalid file format %d %d %d\n",
+                    props[i].name, isStringProp[i], props[i].value);
+           goto Bail;
+       }
+       if (IS_EOF(file)) goto Bail;
+    }
+    /* pad the property array */
+    /*
+     * clever here - nprops is the same as the number of odd-units read, as
+     * only isStringProp are odd length
+     */
+    if (nprops & 3)
+    {
+       i = 4 - (nprops & 3);
+       (void)FontFileSkip(file, i);
+       position += i;
+    }
+    if (IS_EOF(file)) goto Bail;
+    string_size = pcfGetINT32(file, format);
+    if (string_size < 0) goto Bail;
+    if (IS_EOF(file)) goto Bail;
+    strings = malloc(string_size);
+    if (!strings) {
+      pcfError("pcfGetProperties(): Couldn't allocate strings (%d)\n", string_size);
+       goto Bail;
+    }
+    FontFileRead(file, strings, string_size);
+    if (IS_EOF(file)) goto Bail;
+    position += string_size;
+    for (i = 0; i < nprops; i++) {
+       props[i].name = MakeAtom(strings + props[i].name,
+                                strlen(strings + props[i].name), TRUE);
+       if (isStringProp[i]) {
+           props[i].value = MakeAtom(strings + props[i].value,
+                                     strlen(strings + props[i].value), TRUE);
+       }
+    }
+    free(strings);
+    pFontInfo->isStringProp = isStringProp;
+    pFontInfo->props = props;
+    pFontInfo->nprops = nprops;
+    return TRUE;
+Bail:
+    free(isStringProp);
+    free(props);
+    return FALSE;
+}
+
+
+/*
+ * pcfReadAccel
+ *
+ * Fill in the accelerator information from the font file; used
+ * to read both BDF_ACCELERATORS and old style ACCELERATORS
+ */
+
+static Bool
+pcfGetAccel(FontInfoPtr pFontInfo, FontFilePtr file, 
+           PCFTablePtr tables, int ntables, CARD32 type)
+{
+    CARD32      format;
+    CARD32     size;
+
+    if (!pcfSeekToType(file, tables, ntables, type, &format, &size) ||
+       IS_EOF(file))
+       goto Bail;
+    format = pcfGetLSB32(file);
+    if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT) &&
+       !PCF_FORMAT_MATCH(format, PCF_ACCEL_W_INKBOUNDS)) 
+    {
+       goto Bail;
+    }
+    pFontInfo->noOverlap = pcfGetINT8(file, format);
+    pFontInfo->constantMetrics = pcfGetINT8(file, format);
+    pFontInfo->terminalFont = pcfGetINT8(file, format);
+    pFontInfo->constantWidth = pcfGetINT8(file, format);
+    pFontInfo->inkInside = pcfGetINT8(file, format);
+    pFontInfo->inkMetrics = pcfGetINT8(file, format);
+    pFontInfo->drawDirection = pcfGetINT8(file, format);
+    pFontInfo->anamorphic = FALSE;
+    pFontInfo->cachable = TRUE;
+     /* natural alignment */ pcfGetINT8(file, format);
+    pFontInfo->fontAscent = pcfGetINT32(file, format);
+    pFontInfo->fontDescent = pcfGetINT32(file, format);
+    pFontInfo->maxOverlap = pcfGetINT32(file, format);
+    if (IS_EOF(file)) goto Bail;
+    if (!pcfGetMetric(file, format, &pFontInfo->minbounds))
+       goto Bail;
+    if (!pcfGetMetric(file, format, &pFontInfo->maxbounds))
+       goto Bail;
+    if (PCF_FORMAT_MATCH(format, PCF_ACCEL_W_INKBOUNDS)) {
+       if (!pcfGetMetric(file, format, &pFontInfo->ink_minbounds))
+           goto Bail;
+       if (!pcfGetMetric(file, format, &pFontInfo->ink_maxbounds))
+           goto Bail;
+    } else {
+       pFontInfo->ink_minbounds = pFontInfo->minbounds;
+       pFontInfo->ink_maxbounds = pFontInfo->maxbounds;
+    }
+    return TRUE;
+Bail:
+    return FALSE;
+}
+
+int
+pcfReadFont(FontPtr pFont, FontFilePtr file, 
+           int bit, int byte, int glyph, int scan)
+{
+    CARD32      format;
+    CARD32      size;
+    BitmapFontPtr  bitmapFont = 0;
+    int         i;
+    PCFTablePtr tables = 0;
+    int         ntables;
+    int         nmetrics;
+    int         nbitmaps;
+    int         sizebitmaps;
+    int         nink_metrics;
+    CharInfoPtr metrics = 0;
+    xCharInfo  *ink_metrics = 0;
+    char       *bitmaps = 0;
+    CharInfoPtr **encoding = 0;
+    int         nencoding = 0;
+    int         encodingOffset;
+    CARD32      bitmapSizes[GLYPHPADOPTIONS];
+    CARD32     *offsets = 0;
+    Bool       hasBDFAccelerators;
+
+    pFont->info.nprops = 0;
+    pFont->info.props = 0;
+    if (!(tables = pcfReadTOC(file, &ntables)))
+       goto Bail;
+
+    /* properties */
+
+    if (!pcfGetProperties(&pFont->info, file, tables, ntables))
+       goto Bail;
+
+    /* Use the old accelerators if no BDF accelerators are in the file */
+
+    hasBDFAccelerators = pcfHasType (tables, ntables, PCF_BDF_ACCELERATORS);
+    if (!hasBDFAccelerators)
+       if (!pcfGetAccel (&pFont->info, file, tables, ntables, PCF_ACCELERATORS))
+           goto Bail;
+
+    /* metrics */
+
+    if (!pcfSeekToType(file, tables, ntables, PCF_METRICS, &format, &size)) {
+       goto Bail;
+    }
+    format = pcfGetLSB32(file);
+    if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT) &&
+           !PCF_FORMAT_MATCH(format, PCF_COMPRESSED_METRICS)) {
+       goto Bail;
+    }
+    if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
+       nmetrics = pcfGetINT32(file, format);
+    else
+       nmetrics = pcfGetINT16(file, format);
+    if (IS_EOF(file)) goto Bail;
+    if (nmetrics < 0 || nmetrics > INT32_MAX / sizeof(CharInfoRec)) {
+       pcfError("pcfReadFont(): invalid file format\n");
+       goto Bail;
+    }
+    metrics = malloc(nmetrics * sizeof(CharInfoRec));
+    if (!metrics) {
+      pcfError("pcfReadFont(): Couldn't allocate metrics (%d*%d)\n", nmetrics, sizeof(CharInfoRec));
+       goto Bail;
+    }
+    for (i = 0; i < nmetrics; i++)
+       if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)) {
+           if (!pcfGetMetric(file, format, &(metrics + i)->metrics))
+               goto Bail;
+       } else {
+           if (!pcfGetCompressedMetric(file, format, &(metrics + i)->metrics))
+               goto Bail;
+       }
+    
+    /* bitmaps */
+
+    if (!pcfSeekToType(file, tables, ntables, PCF_BITMAPS, &format, &size))
+       goto Bail;
+    format = pcfGetLSB32(file);
+    if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
+       goto Bail;
+
+    nbitmaps = pcfGetINT32(file, format);
+    if (nbitmaps != nmetrics || IS_EOF(file))
+       goto Bail;
+    /* nmetrics is already ok, so nbitmap also is */
+    offsets = malloc(nbitmaps * sizeof(CARD32));
+    if (!offsets) {
+      pcfError("pcfReadFont(): Couldn't allocate offsets (%d*%d)\n", nbitmaps, sizeof(CARD32));
+       goto Bail;
+    }
+    for (i = 0; i < nbitmaps; i++) {
+       offsets[i] = pcfGetINT32(file, format);
+       if (IS_EOF(file)) goto Bail;
+    }
+
+    for (i = 0; i < GLYPHPADOPTIONS; i++) {
+       bitmapSizes[i] = pcfGetINT32(file, format);
+       if (IS_EOF(file)) goto Bail;
+       if (bitmapSizes[i] < 0) goto Bail;
+    }
+    
+    sizebitmaps = bitmapSizes[PCF_GLYPH_PAD_INDEX(format)];
+    /* guard against completely empty font */
+    bitmaps = malloc(sizebitmaps ? sizebitmaps : 1);
+    if (!bitmaps) {
+      pcfError("pcfReadFont(): Couldn't allocate bitmaps (%d)\n", sizebitmaps ? sizebitmaps : 1);
+       goto Bail;
+    }
+    FontFileRead(file, bitmaps, sizebitmaps);
+    if (IS_EOF(file)) goto Bail;
+    position += sizebitmaps;
+
+    if (PCF_BIT_ORDER(format) != bit)
+       BitOrderInvert((unsigned char *)bitmaps, sizebitmaps);
+    if ((PCF_BYTE_ORDER(format) == PCF_BIT_ORDER(format)) != (bit == byte)) {
+       switch (bit == byte ? PCF_SCAN_UNIT(format) : scan) {
+       case 1:
+           break;
+       case 2:
+           TwoByteSwap((unsigned char *)bitmaps, sizebitmaps);
+           break;
+       case 4:
+           FourByteSwap((unsigned char *)bitmaps, sizebitmaps);
+           break;
+       }
+    }
+    if (PCF_GLYPH_PAD(format) != glyph) {
+       char       *padbitmaps;
+       int         sizepadbitmaps;
+       int         old,
+                   new;
+       xCharInfo  *metric;
+
+       sizepadbitmaps = bitmapSizes[PCF_SIZE_TO_INDEX(glyph)];
+       padbitmaps = malloc(sizepadbitmaps);
+       if (!padbitmaps) {
+          pcfError("pcfReadFont(): Couldn't allocate padbitmaps (%d)\n", sizepadbitmaps);
+           goto Bail;
+       }
+       new = 0;
+       for (i = 0; i < nbitmaps; i++) {
+           old = offsets[i];
+           metric = &metrics[i].metrics;
+           offsets[i] = new;
+           new += RepadBitmap(bitmaps + old, padbitmaps + new,
+                              PCF_GLYPH_PAD(format), glyph,
+                         metric->rightSideBearing - metric->leftSideBearing,
+                              metric->ascent + metric->descent);
+       }
+       free(bitmaps);
+       bitmaps = padbitmaps;
+    }
+    for (i = 0; i < nbitmaps; i++)
+       metrics[i].bits = bitmaps + offsets[i];
+
+    free(offsets);
+    offsets = NULL;
+
+    /* ink metrics ? */
+
+    ink_metrics = NULL;
+    if (pcfSeekToType(file, tables, ntables, PCF_INK_METRICS, &format, &size)) {
+       format = pcfGetLSB32(file);
+       if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT) &&
+               !PCF_FORMAT_MATCH(format, PCF_COMPRESSED_METRICS)) {
+           goto Bail;
+       }
+       if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
+           nink_metrics = pcfGetINT32(file, format);
+       else
+           nink_metrics = pcfGetINT16(file, format);
+       if (IS_EOF(file)) goto Bail;
+       if (nink_metrics != nmetrics)
+           goto Bail;
+       /* nmetrics already checked */
+       ink_metrics = malloc(nink_metrics * sizeof(xCharInfo));
+      if (!ink_metrics) {
+          pcfError("pcfReadFont(): Couldn't allocate ink_metrics (%d*%d)\n", nink_metrics, sizeof(xCharInfo));       
+           goto Bail;
+      }
+       for (i = 0; i < nink_metrics; i++)
+           if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)) {
+               if (!pcfGetMetric(file, format, ink_metrics + i))
+                   goto Bail;
+           } else {
+               if (!pcfGetCompressedMetric(file, format, ink_metrics + i))
+                   goto Bail;
+           }
+    }
+
+    /* encoding */
+
+    if (!pcfSeekToType(file, tables, ntables, PCF_BDF_ENCODINGS, &format, &size))
+       goto Bail;
+    format = pcfGetLSB32(file);
+    if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
+       goto Bail;
+
+    pFont->info.firstCol = pcfGetINT16(file, format);
+    pFont->info.lastCol = pcfGetINT16(file, format);
+    pFont->info.firstRow = pcfGetINT16(file, format);
+    pFont->info.lastRow = pcfGetINT16(file, format);
+    pFont->info.defaultCh = pcfGetINT16(file, format);
+    if (IS_EOF(file)) goto Bail;
+    if (pFont->info.firstCol > pFont->info.lastCol ||
+       pFont->info.firstRow > pFont->info.lastRow ||
+       pFont->info.lastCol-pFont->info.firstCol > 255) goto Bail;
+
+    nencoding = (pFont->info.lastCol - pFont->info.firstCol + 1) *
+       (pFont->info.lastRow - pFont->info.firstRow + 1);
+
+    encoding = calloc(NUM_SEGMENTS(nencoding), sizeof(CharInfoPtr*));
+    if (!encoding) {
+      pcfError("pcfReadFont(): Couldn't allocate encoding (%d*%d)\n", nencoding, sizeof(CharInfoPtr));    
+       goto Bail;
+    }
+    
+    pFont->info.allExist = TRUE;
+    for (i = 0; i < nencoding; i++) {
+       encodingOffset = pcfGetINT16(file, format);
+       if (IS_EOF(file)) goto Bail;
+       if (encodingOffset == 0xFFFF) {
+           pFont->info.allExist = FALSE;
+       } else {
+            if(!encoding[SEGMENT_MAJOR(i)]) {
+                encoding[SEGMENT_MAJOR(i)]=
+                    calloc(BITMAP_FONT_SEGMENT_SIZE, sizeof(CharInfoPtr));
+                if(!encoding[SEGMENT_MAJOR(i)])
+                    goto Bail;
+            }
+           ACCESSENCODINGL(encoding, i) = metrics + encodingOffset;
+        }
+    }
+
+    /* BDF style accelerators (i.e. bounds based on encoded glyphs) */
+
+    if (hasBDFAccelerators)
+       if (!pcfGetAccel (&pFont->info, file, tables, ntables, PCF_BDF_ACCELERATORS))
+           goto Bail;
+
+    bitmapFont = malloc(sizeof *bitmapFont);
+    if (!bitmapFont) {
+      pcfError("pcfReadFont(): Couldn't allocate bitmapFont (%d)\n", sizeof *bitmapFont);
+       goto Bail;
+    }
+
+    bitmapFont->version_num = PCF_FILE_VERSION;
+    bitmapFont->num_chars = nmetrics;
+    bitmapFont->num_tables = ntables;
+    bitmapFont->metrics = metrics;
+    bitmapFont->ink_metrics = ink_metrics;
+    bitmapFont->bitmaps = bitmaps;
+    bitmapFont->encoding = encoding;
+    bitmapFont->pDefault = (CharInfoPtr) 0;
+    if (pFont->info.defaultCh != (unsigned short) NO_SUCH_CHAR) {
+       unsigned int r,
+                   c,
+                   cols;
+
+       r = pFont->info.defaultCh >> 8;
+       c = pFont->info.defaultCh & 0xFF;
+       if (pFont->info.firstRow <= r && r <= pFont->info.lastRow &&
+               pFont->info.firstCol <= c && c <= pFont->info.lastCol) {
+           cols = pFont->info.lastCol - pFont->info.firstCol + 1;
+           r = r - pFont->info.firstRow;
+           c = c - pFont->info.firstCol;
+           bitmapFont->pDefault = ACCESSENCODING(encoding, r * cols + c);
+       }
+    }
+    bitmapFont->bitmapExtra = (BitmapExtraPtr) 0;
+    pFont->fontPrivate = (pointer) bitmapFont;
+    pFont->get_glyphs = bitmapGetGlyphs;
+    pFont->get_metrics = bitmapGetMetrics;
+    pFont->unload_font = pcfUnloadFont;
+    pFont->unload_glyphs = NULL;
+    pFont->bit = bit;
+    pFont->byte = byte;
+    pFont->glyph = glyph;
+    pFont->scan = scan;
+    free(tables);
+    return Successful;
+Bail:
+    free(ink_metrics);
+    if(encoding) {
+        for(i=0; i<NUM_SEGMENTS(nencoding); i++)
+            free(encoding[i]);
+    }
+    free(encoding);
+    free(bitmaps);
+    free(metrics);
+    free(pFont->info.props);
+    pFont->info.nprops = 0;
+    pFont->info.props = 0;
+    free (pFont->info.isStringProp);
+    free(bitmapFont);
+    free(tables);
+    free(offsets);
+    return AllocError;
+}
+
+int
+pcfReadFontInfo(FontInfoPtr pFontInfo, FontFilePtr file)
+{
+    PCFTablePtr tables;
+    int         ntables;
+    CARD32      format;
+    CARD32      size;
+    int         nencoding;
+    Bool       hasBDFAccelerators;
+
+    pFontInfo->isStringProp = NULL;
+    pFontInfo->props = NULL;
+    pFontInfo->nprops = 0;
+
+    if (!(tables = pcfReadTOC(file, &ntables)))
+       goto Bail;
+
+    /* properties */
+
+    if (!pcfGetProperties(pFontInfo, file, tables, ntables))
+       goto Bail;
+
+    /* Use the old accelerators if no BDF accelerators are in the file */
+
+    hasBDFAccelerators = pcfHasType (tables, ntables, PCF_BDF_ACCELERATORS);
+    if (!hasBDFAccelerators)
+       if (!pcfGetAccel (pFontInfo, file, tables, ntables, PCF_ACCELERATORS))
+           goto Bail;
+
+    /* encoding */
+
+    if (!pcfSeekToType(file, tables, ntables, PCF_BDF_ENCODINGS, &format, &size))
+       goto Bail;
+    format = pcfGetLSB32(file);
+    if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
+       goto Bail;
+
+    pFontInfo->firstCol = pcfGetINT16(file, format);
+    pFontInfo->lastCol = pcfGetINT16(file, format);
+    pFontInfo->firstRow = pcfGetINT16(file, format);
+    pFontInfo->lastRow = pcfGetINT16(file, format);
+    pFontInfo->defaultCh = pcfGetINT16(file, format);
+    if (IS_EOF(file)) goto Bail;
+    if (pFontInfo->firstCol > pFontInfo->lastCol ||
+       pFontInfo->firstRow > pFontInfo->lastRow ||
+       pFontInfo->lastCol-pFontInfo->firstCol > 255) goto Bail;
+
+    nencoding = (pFontInfo->lastCol - pFontInfo->firstCol + 1) *
+       (pFontInfo->lastRow - pFontInfo->firstRow + 1);
+
+    pFontInfo->allExist = TRUE;
+    while (nencoding--) {
+       if (pcfGetINT16(file, format) == 0xFFFF)
+           pFontInfo->allExist = FALSE;
+       if (IS_EOF(file)) goto Bail;
+    }
+    if (IS_EOF(file)) goto Bail;
+
+    /* BDF style accelerators (i.e. bounds based on encoded glyphs) */
+
+    if (hasBDFAccelerators)
+       if (!pcfGetAccel (pFontInfo, file, tables, ntables, PCF_BDF_ACCELERATORS))
+           goto Bail;
+
+    free(tables);
+    return Successful;
+Bail:
+    pFontInfo->nprops = 0;
+    free (pFontInfo->props);
+    free (pFontInfo->isStringProp);
+    free(tables);
+    return AllocError;
+}
+
+static void
+pcfUnloadFont(FontPtr pFont)
+{
+    BitmapFontPtr  bitmapFont;
+    int i,nencoding;
+
+    bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+    free(bitmapFont->ink_metrics);
+    if(bitmapFont->encoding) {
+        nencoding = (pFont->info.lastCol - pFont->info.firstCol + 1) *
+           (pFont->info.lastRow - pFont->info.firstRow + 1);
+        for(i=0; i<NUM_SEGMENTS(nencoding); i++)
+            free(bitmapFont->encoding[i]);
+    }
+    free(bitmapFont->encoding);
+    free(bitmapFont->bitmaps);
+    free(bitmapFont->metrics);
+    free(pFont->info.isStringProp);
+    free(pFont->info.props);
+    free(bitmapFont);
+    DestroyFontRec(pFont);
+}
diff --git a/src/bitmap/pcfwrite.c b/src/bitmap/pcfwrite.c
new file mode 100755 (executable)
index 0000000..3ac07b3
--- /dev/null
@@ -0,0 +1,466 @@
+/*
+
+Copyright 1990, 1994, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+/*
+ * Author:  Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/bitmap.h>
+#include <X11/fonts/pcf.h>
+
+/* Write PCF font files */
+
+static CARD32  current_position;
+
+static int
+pcfWrite(FontFilePtr file, char *b, int c)
+{
+    current_position += c;
+    return FontFileWrite(file, b, c);
+}
+
+static int
+pcfPutLSB32(FontFilePtr file, int c)
+{
+    current_position += 4;
+    (void) FontFilePutc(c, file);
+    (void) FontFilePutc(c >> 8, file);
+    (void) FontFilePutc(c >> 16, file);
+    return FontFilePutc(c >> 24, file);
+}
+
+static int
+pcfPutINT32(FontFilePtr file, CARD32 format, int c)
+{
+    current_position += 4;
+    if (PCF_BYTE_ORDER(format) == MSBFirst) {
+       (void) FontFilePutc(c >> 24, file);
+       (void) FontFilePutc(c >> 16, file);
+       (void) FontFilePutc(c >> 8, file);
+       return FontFilePutc(c, file);
+    } else {
+       (void) FontFilePutc(c, file);
+       (void) FontFilePutc(c >> 8, file);
+       (void) FontFilePutc(c >> 16, file);
+       return FontFilePutc(c >> 24, file);
+    }
+}
+
+static int
+pcfPutINT16(FontFilePtr file, CARD32 format, int c)
+{
+    current_position += 2;
+    if (PCF_BYTE_ORDER(format) == MSBFirst) {
+       (void) FontFilePutc(c >> 8, file);
+       return FontFilePutc(c, file);
+    } else {
+       (void) FontFilePutc(c, file);
+       return FontFilePutc(c >> 8, file);
+    }
+}
+
+/*ARGSUSED*/
+static int
+pcfPutINT8(FontFilePtr file, CARD32 format, int c)
+{
+    current_position += 1;
+    return FontFilePutc(c, file);
+}
+
+static void
+pcfWriteTOC(FontFilePtr file, PCFTablePtr table, int count)
+{
+    CARD32      version;
+    int         i;
+
+    version = PCF_FILE_VERSION;
+    pcfPutLSB32(file, version);
+    pcfPutLSB32(file, count);
+    for (i = 0; i < count; i++) {
+       pcfPutLSB32(file, table->type);
+       pcfPutLSB32(file, table->format);
+       pcfPutLSB32(file, table->size);
+       pcfPutLSB32(file, table->offset);
+       table++;
+    }
+}
+
+static void
+pcfPutCompressedMetric(FontFilePtr file, CARD32 format, xCharInfo *metric)
+{
+    pcfPutINT8(file, format, metric->leftSideBearing + 0x80);
+    pcfPutINT8(file, format, metric->rightSideBearing + 0x80);
+    pcfPutINT8(file, format, metric->characterWidth + 0x80);
+    pcfPutINT8(file, format, metric->ascent + 0x80);
+    pcfPutINT8(file, format, metric->descent + 0x80);
+}
+
+static void
+pcfPutMetric(FontFilePtr file, CARD32 format, xCharInfo *metric)
+{
+    pcfPutINT16(file, format, metric->leftSideBearing);
+    pcfPutINT16(file, format, metric->rightSideBearing);
+    pcfPutINT16(file, format, metric->characterWidth);
+    pcfPutINT16(file, format, metric->ascent);
+    pcfPutINT16(file, format, metric->descent);
+    pcfPutINT16(file, format, metric->attributes);
+}
+
+static void
+pcfPutBitmap(FontFilePtr file, CARD32 format, CharInfoPtr pCI)
+{
+    int         count;
+    unsigned char *bits;
+
+    count = BYTES_FOR_GLYPH(pCI, PCF_GLYPH_PAD(format));
+    bits = (unsigned char *) pCI->bits;
+    current_position += count;
+    while (count--)
+       FontFilePutc(*bits++, file);
+}
+
+static void
+pcfPutAccel(FontFilePtr file, CARD32 format, FontInfoPtr pFontInfo)
+{
+    pcfPutINT8(file, format, pFontInfo->noOverlap);
+    pcfPutINT8(file, format, pFontInfo->constantMetrics);
+    pcfPutINT8(file, format, pFontInfo->terminalFont);
+    pcfPutINT8(file, format, pFontInfo->constantWidth);
+    pcfPutINT8(file, format, pFontInfo->inkInside);
+    pcfPutINT8(file, format, pFontInfo->inkMetrics);
+    pcfPutINT8(file, format, pFontInfo->drawDirection);
+    pcfPutINT8(file, format, 0);
+    pcfPutINT32(file, format, pFontInfo->fontAscent);
+    pcfPutINT32(file, format, pFontInfo->fontDescent);
+    pcfPutINT32(file, format, pFontInfo->maxOverlap);
+    pcfPutMetric(file, format, &pFontInfo->minbounds);
+    pcfPutMetric(file, format, &pFontInfo->maxbounds);
+    if (PCF_FORMAT_MATCH(format, PCF_ACCEL_W_INKBOUNDS)) {
+       pcfPutMetric(file, format, &pFontInfo->ink_minbounds);
+       pcfPutMetric(file, format, &pFontInfo->ink_maxbounds);
+    }
+}
+
+#define S32 4
+#define S16 2
+#define S8 1
+
+#define Pad(s)     (RoundUp(s) - (s))
+#define RoundUp(s)  (((s) + 3) & ~3)
+
+#define Compressable(i)        (-128 <= (i) && (i) <= 127)
+
+#define CanCompressMetric(m)   (Compressable((m)->leftSideBearing) && \
+                                Compressable((m)->rightSideBearing) && \
+                                Compressable((m)->characterWidth) && \
+                                Compressable((m)->ascent) && \
+                                Compressable((m)->descent) && \
+                                (m)->attributes == 0)
+
+#define CanCompressMetrics(min,max) (CanCompressMetric(min) && CanCompressMetric(max))
+
+static char *
+pcfNameForAtom(Atom a)
+{
+    return NameForAtom(a);
+}
+
+int
+pcfWriteFont(FontPtr pFont, FontFilePtr file)
+{
+    PCFTableRec tables[32],
+               *table;
+    CARD32      mask,
+                bit;
+    int         ntables;
+    int         size;
+    CARD32      format;
+    int         i;
+    int         cur_table;
+    int         prop_string_size;
+    int         glyph_string_size;
+    xCharInfo  *minbounds,
+               *maxbounds;
+    xCharInfo  *ink_minbounds,
+               *ink_maxbounds;
+    BitmapFontPtr  bitmapFont;
+    int         nencodings = 0;
+    int         header_size;
+    FontPropPtr offsetProps;
+    int         prop_pad = 0;
+    char       *atom_name;
+    int         glyph;
+    CARD32      offset;
+
+    bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+    if (bitmapFont->bitmapExtra) {
+       minbounds = &bitmapFont->bitmapExtra->info.minbounds;
+       maxbounds = &bitmapFont->bitmapExtra->info.maxbounds;
+       ink_minbounds = &bitmapFont->bitmapExtra->info.ink_minbounds;
+       ink_maxbounds = &bitmapFont->bitmapExtra->info.ink_maxbounds;
+    } else {
+       minbounds = &pFont->info.minbounds;
+       maxbounds = &pFont->info.maxbounds;
+       ink_minbounds = &pFont->info.ink_minbounds;
+       ink_maxbounds = &pFont->info.ink_maxbounds;
+    }
+    offsetProps = malloc(pFont->info.nprops * sizeof(FontPropRec));
+    if (!offsetProps) {
+      pcfError("pcfWriteFont(): Couldn't allocate offsetProps (%d*%d)", pFont->info.nprops, sizeof(FontPropRec));
+       return AllocError;
+    }
+    prop_string_size = 0;
+    for (i = 0; i < pFont->info.nprops; i++) {
+       offsetProps[i].name = prop_string_size;
+       prop_string_size += strlen(pcfNameForAtom(pFont->info.props[i].name)) + 1;
+       if (pFont->info.isStringProp[i]) {
+           offsetProps[i].value = prop_string_size;
+           prop_string_size += strlen(pcfNameForAtom(pFont->info.props[i].value)) + 1;
+       } else
+           offsetProps[i].value = pFont->info.props[i].value;
+    }
+    format = PCF_FORMAT(pFont->bit, pFont->byte, pFont->glyph, pFont->scan);
+    mask = 0xFFFFFFF;
+    ntables = 0;
+    table = tables;
+    while (mask) {
+       bit = lowbit(mask);
+       mask &= ~bit;
+       table->type = bit;
+       switch (bit) {
+       case PCF_PROPERTIES:
+           table->format = PCF_DEFAULT_FORMAT | format;
+           size = S32 + S32 + (S32 + S8 + S32) * pFont->info.nprops;
+           prop_pad = Pad(size);
+           table->size = RoundUp(size) + S32 +
+               RoundUp(prop_string_size);
+           table++;
+           break;
+       case PCF_ACCELERATORS:
+           if (bitmapFont->bitmapExtra->info.inkMetrics)
+               table->format = PCF_ACCEL_W_INKBOUNDS | format;
+           else
+               table->format = PCF_DEFAULT_FORMAT | format;
+           table->size = 100;
+           table++;
+           break;
+       case PCF_METRICS:
+           if (CanCompressMetrics(minbounds, maxbounds)) {
+               table->format = PCF_COMPRESSED_METRICS | format;
+               size = S32 + S16 + bitmapFont->num_chars * (5 * S8);
+               table->size = RoundUp(size);
+           } else {
+               table->format = PCF_DEFAULT_FORMAT | format;
+               table->size = S32 + S32 + bitmapFont->num_chars * (6 * S16);
+           }
+           table++;
+           break;
+       case PCF_BITMAPS:
+           table->format = PCF_DEFAULT_FORMAT | format;
+           size = S32 + S32 + bitmapFont->num_chars * S32 +
+               GLYPHPADOPTIONS * S32 +
+               bitmapFont->bitmapExtra->bitmapsSizes[PCF_GLYPH_PAD_INDEX(format)];
+           table->size = RoundUp(size);
+           table++;
+           break;
+       case PCF_INK_METRICS:
+           if (bitmapFont->ink_metrics) {
+               if (CanCompressMetrics(ink_minbounds, ink_maxbounds)) {
+                   table->format = PCF_COMPRESSED_METRICS | format;
+                   size = S32 + S16 + bitmapFont->num_chars * (5 * S8);
+                   table->size = RoundUp(size);
+               } else {
+                   table->format = PCF_DEFAULT_FORMAT | format;
+                   table->size = S32 + S32 + bitmapFont->num_chars * (6 * S16);
+               }
+               table++;
+           }
+           break;
+       case PCF_BDF_ENCODINGS:
+           table->format = PCF_DEFAULT_FORMAT | format;
+           nencodings = (pFont->info.lastRow - pFont->info.firstRow + 1) *
+               (pFont->info.lastCol - pFont->info.firstCol + 1);
+           size = S32 + 5 * S16 + nencodings * S16;
+           table->size = RoundUp(size);
+           table++;
+           break;
+       case PCF_SWIDTHS:
+           table->format = PCF_DEFAULT_FORMAT | format;
+           table->size = S32 + S32 + bitmapFont->num_chars * S32;
+           table++;
+           break;
+       case PCF_GLYPH_NAMES:
+           table->format = PCF_DEFAULT_FORMAT | format;
+           glyph_string_size = 0;
+           for (i = 0; i < bitmapFont->num_chars; i++)
+               glyph_string_size += strlen(pcfNameForAtom(bitmapFont->bitmapExtra->glyphNames[i])) + 1;
+           table->size = S32 + S32 + bitmapFont->num_chars * S32 +
+               S32 + RoundUp(glyph_string_size);
+           table++;
+           break;
+       case PCF_BDF_ACCELERATORS:
+           if (pFont->info.inkMetrics)
+               table->format = PCF_ACCEL_W_INKBOUNDS | format;
+           else
+               table->format = PCF_DEFAULT_FORMAT | format;
+           table->size = 100;
+           table++;
+           break;
+       }
+    }
+    ntables = table - tables;
+    offset = 0;
+    header_size = S32 + S32 + ntables * (4 * S32);
+    offset = header_size;
+    for (cur_table = 0, table = tables;
+           cur_table < ntables;
+           cur_table++, table++) {
+       table->offset = offset;
+       offset += table->size;
+    }
+    current_position = 0;
+    pcfWriteTOC(file, tables, ntables);
+    for (cur_table = 0, table = tables;
+           cur_table < ntables;
+           cur_table++, table++) {
+       if (current_position > table->offset) {
+           printf("can't go backwards... %d > %d\n",
+                  (int)current_position, (int)table->offset);
+           free(offsetProps);
+           return BadFontName;
+       }
+       while (current_position < table->offset)
+           pcfPutINT8(file, format, '\0');
+       pcfPutLSB32(file, table->format);
+       switch (table->type) {
+       case PCF_PROPERTIES:
+           pcfPutINT32(file, format, pFont->info.nprops);
+           for (i = 0; i < pFont->info.nprops; i++) {
+               pcfPutINT32(file, format, offsetProps[i].name);
+               pcfPutINT8(file, format, pFont->info.isStringProp[i]);
+               pcfPutINT32(file, format, offsetProps[i].value);
+           }
+           for (i = 0; i < prop_pad; i++)
+               pcfPutINT8(file, format, 0);
+           pcfPutINT32(file, format, prop_string_size);
+           for (i = 0; i < pFont->info.nprops; i++) {
+               atom_name = pcfNameForAtom(pFont->info.props[i].name);
+               pcfWrite(file, atom_name, strlen(atom_name) + 1);
+               if (pFont->info.isStringProp[i]) {
+                   atom_name = pcfNameForAtom(pFont->info.props[i].value);
+                   pcfWrite(file, atom_name, strlen(atom_name) + 1);
+               }
+           }
+           break;
+       case PCF_ACCELERATORS:
+           pcfPutAccel(file, table->format, &bitmapFont->bitmapExtra->info);
+           break;
+       case PCF_METRICS:
+           if (PCF_FORMAT_MATCH(table->format, PCF_COMPRESSED_METRICS)) {
+               pcfPutINT16(file, format, bitmapFont->num_chars);
+               for (i = 0; i < bitmapFont->num_chars; i++)
+                   pcfPutCompressedMetric(file, format, &bitmapFont->metrics[i].metrics);
+           } else {
+               pcfPutINT32(file, format, bitmapFont->num_chars);
+               for (i = 0; i < bitmapFont->num_chars; i++)
+                   pcfPutMetric(file, format, &bitmapFont->metrics[i].metrics);
+           }
+           break;
+       case PCF_BITMAPS:
+           pcfPutINT32(file, format, bitmapFont->num_chars);
+           glyph = PCF_GLYPH_PAD(format);
+           offset = 0;
+           for (i = 0; i < bitmapFont->num_chars; i++) {
+               pcfPutINT32(file, format, offset);
+               offset += BYTES_FOR_GLYPH(&bitmapFont->metrics[i], glyph);
+           }
+           for (i = 0; i < GLYPHPADOPTIONS; i++) {
+               pcfPutINT32(file, format,
+                           bitmapFont->bitmapExtra->bitmapsSizes[i]);
+           }
+           for (i = 0; i < bitmapFont->num_chars; i++)
+               pcfPutBitmap(file, format, &bitmapFont->metrics[i]);
+           break;
+       case PCF_INK_METRICS:
+           if (PCF_FORMAT_MATCH(table->format, PCF_COMPRESSED_METRICS)) {
+               pcfPutINT16(file, format, bitmapFont->num_chars);
+               for (i = 0; i < bitmapFont->num_chars; i++)
+                   pcfPutCompressedMetric(file, format, &bitmapFont->ink_metrics[i]);
+           } else {
+               pcfPutINT32(file, format, bitmapFont->num_chars);
+               for (i = 0; i < bitmapFont->num_chars; i++)
+                   pcfPutMetric(file, format, &bitmapFont->ink_metrics[i]);
+           }
+           break;
+       case PCF_BDF_ENCODINGS:
+           pcfPutINT16(file, format, pFont->info.firstCol);
+           pcfPutINT16(file, format, pFont->info.lastCol);
+           pcfPutINT16(file, format, pFont->info.firstRow);
+           pcfPutINT16(file, format, pFont->info.lastRow);
+           pcfPutINT16(file, format, pFont->info.defaultCh);
+           for (i = 0; i < nencodings; i++) {
+               if (ACCESSENCODING(bitmapFont->encoding,i))
+                   pcfPutINT16(file, format, 
+                                ACCESSENCODING(bitmapFont->encoding, i) - 
+                                  bitmapFont->metrics);
+               else
+                   pcfPutINT16(file, format, 0xFFFF);
+           }
+           break;
+       case PCF_SWIDTHS:
+           pcfPutINT32(file, format, bitmapFont->num_chars);
+           for (i = 0; i < bitmapFont->num_chars; i++)
+               pcfPutINT32(file, format, bitmapFont->bitmapExtra->sWidths[i]);
+           break;
+       case PCF_GLYPH_NAMES:
+           pcfPutINT32(file, format, bitmapFont->num_chars);
+           offset = 0;
+           for (i = 0; i < bitmapFont->num_chars; i++) {
+               pcfPutINT32(file, format, offset);
+               offset += strlen(pcfNameForAtom(bitmapFont->bitmapExtra->glyphNames[i])) + 1;
+           }
+           pcfPutINT32(file, format, offset);
+           for (i = 0; i < bitmapFont->num_chars; i++) {
+               atom_name = pcfNameForAtom(bitmapFont->bitmapExtra->glyphNames[i]);
+               pcfWrite(file, atom_name, strlen(atom_name) + 1);
+           }
+           break;
+       case PCF_BDF_ACCELERATORS:
+           pcfPutAccel(file, table->format, &pFont->info);
+           break;
+       }
+    }
+
+    free(offsetProps);
+    return Successful;
+}
diff --git a/src/bitmap/snfread.c b/src/bitmap/snfread.c
new file mode 100755 (executable)
index 0000000..d003cc5
--- /dev/null
@@ -0,0 +1,508 @@
+/************************************************************************
+Copyright 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+************************************************************************/
+
+/*
+
+Copyright 1994, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <ctype.h>
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/bitmap.h>
+#include "snfstr.h"
+
+#include <stdarg.h>
+
+static void
+snfError(const char* message, ...)
+{
+    va_list args;
+
+    va_start(args, message);
+
+    fprintf(stderr, "SNF Error: ");
+    vfprintf(stderr, message, args);
+    va_end(args);
+}
+              
+static void snfUnloadFont(FontPtr pFont);
+
+static int
+snfReadCharInfo(FontFilePtr file, CharInfoPtr charInfo, char *base)
+{
+    snfCharInfoRec snfCharInfo;
+
+#define Width(m)    ((m).rightSideBearing - (m).leftSideBearing)
+#define Height(m)   ((m).ascent + (m).descent)
+
+    if (FontFileRead(file, (char *) &snfCharInfo, sizeof snfCharInfo) !=
+           sizeof(snfCharInfo)) {
+       return BadFontName;
+    }
+    charInfo->metrics = snfCharInfo.metrics;
+    if (snfCharInfo.exists)
+       charInfo->bits = base + snfCharInfo.byteOffset;
+    else
+       charInfo->bits = 0;
+    return Successful;
+}
+
+static int
+snfReadxCharInfo(FontFilePtr file, xCharInfo *charInfo)
+{
+    snfCharInfoRec snfCharInfo;
+
+    if (FontFileRead(file, (char *) &snfCharInfo, sizeof snfCharInfo) !=
+           sizeof(snfCharInfo)) {
+       return BadFontName;
+    }
+    *charInfo = snfCharInfo.metrics;
+    return Successful;
+}
+
+static void
+snfCopyInfo(snfFontInfoPtr snfInfo, FontInfoPtr pFontInfo)
+{
+    pFontInfo->firstCol = snfInfo->firstCol;
+    pFontInfo->lastCol = snfInfo->lastCol;
+    pFontInfo->firstRow = snfInfo->firstRow;
+    pFontInfo->lastRow = snfInfo->lastRow;
+    pFontInfo->defaultCh = snfInfo->chDefault;
+    pFontInfo->noOverlap = snfInfo->noOverlap;
+    pFontInfo->terminalFont = snfInfo->terminalFont;
+    pFontInfo->constantMetrics = snfInfo->constantMetrics;
+    pFontInfo->constantWidth = snfInfo->constantWidth;
+    pFontInfo->inkInside = snfInfo->inkInside;
+    pFontInfo->inkMetrics = snfInfo->inkMetrics;
+    pFontInfo->allExist = snfInfo->allExist;
+    pFontInfo->drawDirection = snfInfo->drawDirection;
+    pFontInfo->anamorphic = FALSE;
+    pFontInfo->cachable = TRUE;
+    pFontInfo->maxOverlap = 0;
+    pFontInfo->minbounds = snfInfo->minbounds.metrics;
+    pFontInfo->maxbounds = snfInfo->maxbounds.metrics;
+    pFontInfo->fontAscent = snfInfo->fontAscent;
+    pFontInfo->fontDescent = snfInfo->fontDescent;
+    pFontInfo->nprops = snfInfo->nProps;
+}
+
+static int
+snfReadProps(snfFontInfoPtr snfInfo, FontInfoPtr pFontInfo, FontFilePtr file)
+{
+    char       *strings;
+    FontPropPtr pfp;
+    snfFontPropPtr psnfp;
+    char       *propspace;
+    int         bytestoalloc;
+    int         i;
+
+    bytestoalloc = snfInfo->nProps * sizeof(snfFontPropRec) +
+       BYTESOFSTRINGINFO(snfInfo);
+    propspace = malloc(bytestoalloc);
+    if (!propspace) {
+      snfError("snfReadProps(): Couldn't allocate propspace (%d)\n", bytestoalloc);
+       return AllocError;
+    }
+
+    if (FontFileRead(file, propspace, bytestoalloc) != bytestoalloc) {
+       free(propspace);
+       return BadFontName;
+    }
+    psnfp = (snfFontPropPtr) propspace;
+
+    strings = propspace + BYTESOFPROPINFO(snfInfo);
+
+    for (i = 0, pfp = pFontInfo->props; i < snfInfo->nProps; i++, pfp++, psnfp++) {
+       pfp->name = MakeAtom(&strings[psnfp->name],
+                            (unsigned) strlen(&strings[psnfp->name]), 1);
+       pFontInfo->isStringProp[i] = psnfp->indirect;
+       if (psnfp->indirect)
+           pfp->value = (INT32) MakeAtom(&strings[psnfp->value],
+                              (unsigned) strlen(&strings[psnfp->value]), 1);
+       else
+           pfp->value = psnfp->value;
+    }
+
+    free(propspace);
+    return Successful;
+}
+
+static int
+snfReadHeader(snfFontInfoPtr snfInfo, FontFilePtr file)
+{
+    if (FontFileRead(file, (char *) snfInfo, sizeof *snfInfo) != sizeof *snfInfo)
+       return BadFontName;
+
+    if (snfInfo->version1 != FONT_FILE_VERSION ||
+           snfInfo->version2 != FONT_FILE_VERSION)
+       return BadFontName;
+    return Successful;
+}
+
+static int  snf_set;
+static int  snf_bit, snf_byte, snf_glyph, snf_scan;
+
+void
+SnfSetFormat (int bit, int byte, int glyph, int scan)
+{
+    snf_bit = bit;
+    snf_byte = byte;
+    snf_glyph = glyph;
+    snf_scan = scan;
+    snf_set = 1;
+}
+
+static void
+SnfGetFormat (int *bit, int *byte, int *glyph, int *scan)
+{
+    if (!snf_set)
+       FontDefaultFormat (&snf_bit, &snf_byte, &snf_glyph, &snf_scan);
+    *bit = snf_bit;
+    *byte = snf_byte;
+    *glyph = snf_glyph;
+    *scan = snf_scan;
+}
+
+int
+snfReadFont(FontPtr pFont, FontFilePtr file, 
+           int bit, int byte, int glyph, int scan)
+{
+    snfFontInfoRec fi;
+    unsigned    bytestoalloc;
+    int         i, j;
+    char       *fontspace;
+    BitmapFontPtr  bitmapFont;
+    int         num_chars;
+    int         bitmapsSize;
+    int         ret;
+    int         metrics_off;
+    int         encoding_off;
+    int         props_off;
+    int         isStringProp_off;
+    int         ink_off;
+    char       *bitmaps;
+    int                def_bit, def_byte, def_glyph, def_scan;
+
+    ret = snfReadHeader(&fi, file);
+    if (ret != Successful)
+       return ret;
+
+    SnfGetFormat (&def_bit, &def_byte, &def_glyph, &def_scan);
+
+    /*
+     * we'll allocate one chunk of memory and split it among the various parts
+     * of the font:
+     * 
+     * BitmapFontRec CharInfoRec's Glyphs Encoding DIX Properties Ink CharInfoRec's
+     *
+     * If the glyphpad is not the same as the font file, then the glyphs
+     * are allocated separately, to be later realloc'ed when we know
+     * how big to make them.
+     */
+
+    bitmapsSize = BYTESOFGLYPHINFO(&fi);
+    num_chars = n2dChars(&fi);
+    bytestoalloc = sizeof(BitmapFontRec);      /* bitmapFont */
+    metrics_off = bytestoalloc;
+    bytestoalloc += num_chars * sizeof(CharInfoRec);   /* metrics */
+    encoding_off = bytestoalloc;
+    bytestoalloc += NUM_SEGMENTS(num_chars) * sizeof(CharInfoPtr**);   
+                                                /* encoding */
+    props_off = bytestoalloc;
+    bytestoalloc += fi.nProps * sizeof(FontPropRec);   /* props */
+    isStringProp_off = bytestoalloc;
+    bytestoalloc += fi.nProps * sizeof(char);  /* isStringProp */
+    bytestoalloc = (bytestoalloc + 3) & ~3;
+    ink_off = bytestoalloc;
+    if (fi.inkMetrics)
+       bytestoalloc += num_chars * sizeof(xCharInfo);  /* ink_metrics */
+
+    fontspace = malloc(bytestoalloc);
+    if (!fontspace) {
+      snfError("snfReadFont(): Couldn't allocate fontspace (%d)\n", bytestoalloc);
+       return AllocError;
+    }
+    bitmaps = malloc (bitmapsSize);
+    if (!bitmaps)
+    {
+      snfError("snfReadFont(): Couldn't allocate bitmaps (%d)\n", bitmapsSize);
+       free (fontspace);
+       return AllocError;
+    }
+    /*
+     * now fix up pointers
+     */
+
+    bitmapFont = (BitmapFontPtr) fontspace;
+    bitmapFont->num_chars = num_chars;
+    bitmapFont->metrics = (CharInfoPtr) (fontspace + metrics_off);
+    bitmapFont->encoding = (CharInfoPtr **) (fontspace + encoding_off);
+    bitmapFont->bitmaps = bitmaps;
+    bitmapFont->pDefault = NULL;
+    bitmapFont->bitmapExtra = NULL;
+    pFont->info.props = (FontPropPtr) (fontspace + props_off);
+    pFont->info.isStringProp = (char *) (fontspace + isStringProp_off);
+    if (fi.inkMetrics)
+       bitmapFont->ink_metrics = (xCharInfo *) (fontspace + ink_off);
+    else
+       bitmapFont->ink_metrics = 0;
+
+    /*
+     * read the CharInfo
+     */
+
+    ret = Successful;
+    memset(bitmapFont->encoding, 0, 
+           NUM_SEGMENTS(num_chars)*sizeof(CharInfoPtr*));
+    for (i = 0; ret == Successful && i < num_chars; i++) {
+       ret = snfReadCharInfo(file, &bitmapFont->metrics[i], bitmaps);
+       if (bitmapFont->metrics[i].bits) {
+            if (!bitmapFont->encoding[SEGMENT_MAJOR(i)]) {
+                bitmapFont->encoding[SEGMENT_MAJOR(i)]=
+                    calloc(BITMAP_FONT_SEGMENT_SIZE, sizeof(CharInfoPtr));
+                if (!bitmapFont->encoding[SEGMENT_MAJOR(i)]) {
+                    ret = AllocError;
+                    break;
+                }
+            }
+            ACCESSENCODINGL(bitmapFont->encoding,i) = &bitmapFont->metrics[i];
+        }
+    }
+
+    if (ret != Successful) {
+       free(bitmaps);
+        if(bitmapFont->encoding) {
+            for(j=0; j<SEGMENT_MAJOR(i); j++)
+                free(bitmapFont->encoding[i]);
+        }
+       free(fontspace);
+       return ret;
+    }
+    /*
+     * read the glyphs
+     */
+
+    if (FontFileRead(file, bitmaps, bitmapsSize) != bitmapsSize) {
+       free(bitmaps);
+       free(fontspace);
+       return BadFontName;
+    }
+
+    if (def_bit != bit)
+       BitOrderInvert((unsigned char *)bitmaps, bitmapsSize);
+    if ((def_byte == def_bit) != (bit == byte)) {
+       switch (bit == byte ? def_scan : scan) {
+       case 1:
+           break;
+       case 2:
+           TwoByteSwap((unsigned char *)bitmaps, bitmapsSize);
+           break;
+       case 4:
+           FourByteSwap((unsigned char *)bitmaps, bitmapsSize);
+           break;
+       }
+    }
+    if (def_glyph != glyph) {
+       char        *padbitmaps;
+       int         sizepadbitmaps;
+       int         sizechar;
+       CharInfoPtr metric;
+
+       sizepadbitmaps = 0;
+       metric = bitmapFont->metrics;
+       for (i = 0; i < num_chars; i++)
+       {
+           if (metric->bits)
+               sizepadbitmaps += BYTES_FOR_GLYPH(metric,glyph);
+           metric++;
+       }
+       padbitmaps = malloc(sizepadbitmaps);
+       if (!padbitmaps) {
+           snfError("snfReadFont(): Couldn't allocate padbitmaps (%d)\n", sizepadbitmaps);
+           free (bitmaps);
+           free (fontspace);
+           return AllocError;
+       }
+       metric = bitmapFont->metrics;
+       bitmapFont->bitmaps = padbitmaps;
+       for (i = 0; i < num_chars; i++) {
+           sizechar = RepadBitmap(metric->bits, padbitmaps,
+                              def_glyph, glyph,
+                              metric->metrics.rightSideBearing -
+                              metric->metrics.leftSideBearing,
+                              metric->metrics.ascent + metric->metrics.descent);
+           metric->bits = padbitmaps;
+           padbitmaps += sizechar;
+           metric++;
+       }
+       free(bitmaps);
+    }
+
+    /* now read and atom'ize properties */
+
+    ret = snfReadProps(&fi, &pFont->info, file);
+    if (ret != Successful) {
+       free(fontspace);
+       return ret;
+    }
+    snfCopyInfo(&fi, &pFont->info);
+
+    /* finally, read the ink metrics if the exist */
+
+    if (fi.inkMetrics) {
+       ret = Successful;
+       ret = snfReadxCharInfo(file, &pFont->info.ink_minbounds);
+       ret = snfReadxCharInfo(file, &pFont->info.ink_maxbounds);
+       for (i = 0; ret == Successful && i < num_chars; i++)
+           ret = snfReadxCharInfo(file, &bitmapFont->ink_metrics[i]);
+       if (ret != Successful) {
+           free(fontspace);
+           return ret;
+       }
+    } else {
+       pFont->info.ink_minbounds = pFont->info.minbounds;
+       pFont->info.ink_maxbounds = pFont->info.maxbounds;
+    }
+
+    if (pFont->info.defaultCh != (unsigned short) NO_SUCH_CHAR) {
+       unsigned int r,
+                   c,
+                   cols;
+
+       r = pFont->info.defaultCh >> 8;
+       c = pFont->info.defaultCh & 0xFF;
+       if (pFont->info.firstRow <= r && r <= pFont->info.lastRow &&
+               pFont->info.firstCol <= c && c <= pFont->info.lastCol) {
+           cols = pFont->info.lastCol - pFont->info.firstCol + 1;
+           r = r - pFont->info.firstRow;
+           c = c - pFont->info.firstCol;
+           bitmapFont->pDefault = &bitmapFont->metrics[r * cols + c];
+       }
+    }
+    bitmapFont->bitmapExtra = (BitmapExtraPtr) 0;
+    pFont->fontPrivate = (pointer) bitmapFont;
+    pFont->get_glyphs = bitmapGetGlyphs;
+    pFont->get_metrics = bitmapGetMetrics;
+    pFont->unload_font = snfUnloadFont;
+    pFont->unload_glyphs = NULL;
+    pFont->bit = bit;
+    pFont->byte = byte;
+    pFont->glyph = glyph;
+    pFont->scan = scan;
+    return Successful;
+}
+
+int
+snfReadFontInfo(FontInfoPtr pFontInfo, FontFilePtr file)
+{
+    int         ret;
+    snfFontInfoRec fi;
+    int         bytestoskip;
+    int         num_chars;
+
+    ret = snfReadHeader(&fi, file);
+    if (ret != Successful)
+       return ret;
+    snfCopyInfo(&fi, pFontInfo);
+
+    pFontInfo->props = malloc(fi.nProps * sizeof(FontPropRec));
+    if (!pFontInfo->props) {
+      snfError("snfReadFontInfo(): Couldn't allocate props (%d*%d)\n", fi.nProps, sizeof(FontPropRec));
+       return AllocError;
+    }
+    pFontInfo->isStringProp = malloc(fi.nProps * sizeof(char));
+    if (!pFontInfo->isStringProp) {
+      snfError("snfReadFontInfo(): Couldn't allocate isStringProp (%d*%d)\n", fi.nProps, sizeof(char));
+       free(pFontInfo->props);
+       return AllocError;
+    }
+    num_chars = n2dChars(&fi);
+    bytestoskip = num_chars * sizeof(snfCharInfoRec);  /* charinfos */
+    bytestoskip += BYTESOFGLYPHINFO(&fi);
+    (void)FontFileSkip(file, bytestoskip);
+
+    ret = snfReadProps(&fi, pFontInfo, file);
+    if (ret != Successful) {
+       free(pFontInfo->props);
+       free(pFontInfo->isStringProp);
+       return ret;
+    }
+    if (fi.inkMetrics) {
+       ret = snfReadxCharInfo(file, &pFontInfo->ink_minbounds);
+       if (ret != Successful) {
+           free(pFontInfo->props);
+           free(pFontInfo->isStringProp);
+           return ret;
+       }
+       ret = snfReadxCharInfo(file, &pFontInfo->ink_maxbounds);
+       if (ret != Successful) {
+           free(pFontInfo->props);
+           free(pFontInfo->isStringProp);
+           return ret;
+       }
+    } else {
+       pFontInfo->ink_minbounds = pFontInfo->minbounds;
+       pFontInfo->ink_maxbounds = pFontInfo->maxbounds;
+    }
+    return Successful;
+
+}
+
+static void
+snfUnloadFont(FontPtr pFont)
+{
+    BitmapFontPtr   bitmapFont;
+
+    bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+    free (bitmapFont->bitmaps);
+    free (bitmapFont);
+    DestroyFontRec (pFont);
+}
+
diff --git a/src/bitmap/snfstr.h b/src/bitmap/snfstr.h
new file mode 100755 (executable)
index 0000000..148bb1f
--- /dev/null
@@ -0,0 +1,182 @@
+/***********************************************************
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+
+/*
+
+Copyright 1994, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+#ifndef SNFSTR_H
+#define SNFSTR_H 1
+
+#include <X11/fonts/fntfilio.h>
+
+/*-
+ * This file describes the Server Natural Font format.
+ * SNF fonts are both CPU-dependent and frame buffer bit order dependent.
+ * This file is used by:
+ *     1)  the server, to hold font information read out of font files.
+ *     2)  font converters
+ *
+ * Each font file contains the following
+ * data structures, with no padding in-between.
+ *
+ *     1)  The XFONTINFO structure
+ *             hand-padded to a two-short boundary.
+ *             maxbounds.byteoffset is the total number of bytes in the
+ *                     glpyh array
+ *             maxbounds.bitOffset is thetotal width of the unpadded font
+ *
+ *     2)  The XCHARINFO array
+ *             indexed directly with character codes, both on disk
+ *             and in memory.
+ *
+ *     3)  Character glyphs
+ *             padded in the server-natural way, and
+ *             ordered in the device-natural way.
+ *             End of glyphs padded to 32-bit boundary.
+ *
+ *     4)  nProps font properties
+ *
+ *     5)  a sequence of null-terminated strings, for font properties
+ */
+
+#define FONT_FILE_VERSION      4
+
+typedef struct _snfFontProp {
+    CARD32      name;          /* offset of string */
+    INT32       value;         /* number or offset of string */
+    Bool        indirect;      /* value is a string offset */
+}           snfFontPropRec;
+
+/*
+ * the following macro definitions describe a font file image in memory
+ */
+#define ADDRCharInfoRec( pfi)  \
+       ((snfCharInfoRec *) &(pfi)[1])
+
+#define ADDRCHARGLYPHS( pfi)   \
+       (((char *) &(pfi)[1]) + BYTESOFCHARINFO(pfi))
+
+/*
+ * pad out glyphs to a CARD32 boundary
+ */
+#define ADDRXFONTPROPS( pfi)  \
+       ((snfFontPropRec *) ((char *)ADDRCHARGLYPHS( pfi) + BYTESOFGLYPHINFO(pfi)))
+
+#define ADDRSTRINGTAB( pfi)  \
+       ((char *)ADDRXFONTPROPS( pfi) + BYTESOFPROPINFO(pfi))
+
+#define n2dChars(pfi)  (((pfi)->lastRow - (pfi)->firstRow + 1) * \
+                        ((pfi)->lastCol - (pfi)->firstCol + 1))
+#define        BYTESOFFONTINFO(pfi)    (sizeof(snfFontInfoRec))
+#define BYTESOFCHARINFO(pfi)   (sizeof(snfCharInfoRec) * n2dChars(pfi))
+#define        BYTESOFPROPINFO(pfi)    (sizeof(snfFontPropRec) * (pfi)->nProps)
+#define        BYTESOFSTRINGINFO(pfi)  ((pfi)->lenStrings)
+#define        BYTESOFGLYPHINFO(pfi)   (((pfi)->maxbounds.byteOffset+3) & ~0x3)
+#define BYTESOFINKINFO(pfi)    (sizeof(snfCharInfoRec) * n2dChars(pfi))
+
+typedef struct _snfFontProp *snfFontPropPtr;
+typedef struct _snfCharInfo *snfCharInfoPtr;
+typedef struct _snfFontInfo *snfFontInfoPtr;
+
+typedef struct _snfCharInfo {
+    xCharInfo   metrics;       /* info preformatted for Queries */
+    unsigned    byteOffset:24; /* byte offset of the raster from pGlyphs */
+    unsigned    exists:1;      /* true iff glyph exists for this char */
+    unsigned    pad:7;         /* must be zero for now */
+}           snfCharInfoRec;
+
+typedef struct _snfFontInfo {
+    unsigned int version1;     /* version stamp */
+    unsigned int allExist;
+    unsigned int drawDirection;
+    unsigned int noOverlap;    /* true if:
+                                * max(rightSideBearing-characterWidth) <=
+                                * minbounds->metrics.leftSideBearing */
+    unsigned int constantMetrics;
+    unsigned int terminalFont; /* Should be deprecated!  true if: constant
+                                * metrics && leftSideBearing == 0 &&
+                                * rightSideBearing == characterWidth &&
+                                * ascent == fontAscent && descent ==
+                                * fontDescent */
+    unsigned int linear:1;     /* true if firstRow == lastRow */
+    unsigned int constantWidth:1;      /* true if
+                                        * minbounds->metrics.characterWidth
+                                        * ==
+                                        * maxbounds->metrics.characterWidth */
+    unsigned int inkInside:1;  /* true if for all defined glyphs:
+                                * leftSideBearing >= 0 && rightSideBearing <=
+                                * characterWidth && -fontDescent <= ascent <=
+                                * fontAscent && -fontAscent <= descent <=
+                                * fontDescent */
+    unsigned int inkMetrics:1; /* ink metrics != bitmap metrics */
+    /* used with terminalFont */
+    /* see font's pInk{CI,Min,Max} */
+    unsigned int padding:28;
+    unsigned int firstCol;
+    unsigned int lastCol;
+    unsigned int firstRow;
+    unsigned int lastRow;
+    unsigned int nProps;
+    unsigned int lenStrings;   /* length in bytes of string table */
+    unsigned int chDefault;    /* default character */
+    int         fontDescent;   /* minimum for quality typography */
+    int         fontAscent;    /* minimum for quality typography */
+    snfCharInfoRec minbounds;  /* MIN of glyph metrics over all chars */
+    snfCharInfoRec maxbounds;  /* MAX of glyph metrics over all chars */
+    unsigned int pixDepth;     /* intensity bits per pixel */
+    unsigned int glyphSets;    /* number of sets of glyphs, for sub-pixel
+                                * positioning */
+    unsigned int version2;     /* version stamp double-check */
+}           snfFontInfoRec;
+
+extern void SnfSetFormat ( int bit, int byte, int glyph, int scan );
+extern int snfReadFont ( FontPtr pFont, FontFilePtr file, 
+                        int bit, int byte, int glyph, int scan );
+extern int snfReadFontInfo ( FontInfoPtr pFontInfo, FontFilePtr file );
+
+#endif                         /* SNFSTR_H */
diff --git a/src/builtins/Makefile.am b/src/builtins/Makefile.am
new file mode 100644 (file)
index 0000000..b203fda
--- /dev/null
@@ -0,0 +1,17 @@
+INCLUDES =                     \
+       -I${top_srcdir}/include \
+       -I${top_srcdir}/src/bitmap
+
+AM_CFLAGS = $(XFONT_CFLAGS) $(OS_CFLAGS) $(CWARNFLAGS)
+
+noinst_LTLIBRARIES = libbuiltins.la
+
+libbuiltins_la_SOURCES =       \
+       builtin.h               \
+       dir.c                   \
+       file.c                  \
+       fonts.c                 \
+       fpe.c                   \
+       render.c
+
+EXTRA_DIST = buildfont
diff --git a/src/builtins/buildfont b/src/builtins/buildfont
new file mode 100644 (file)
index 0000000..aa4602f
--- /dev/null
@@ -0,0 +1,14 @@
+#!/bin/sh
+#
+# Convert a bdf file into C-code suitable for inclusion in
+# builtin fonts
+#
+FONT=$1
+NAME=$2
+echo 'static const char file_'$NAME'[] = {'
+bdftopcf -p1 -u1 $1 |
+      compress -b 12 |
+      od -b -v -w8 | 
+      sed 's/^[0-9]*\( *\)/\1\1\1\1/' |
+      sed 's/\([0-9][0-9]*\)/'"'"'\\\1'"'"',/g'
+echo '};'
diff --git a/src/builtins/builtin.h b/src/builtins/builtin.h
new file mode 100755 (executable)
index 0000000..418bfe9
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ *
+ * Copyright 1999 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author:  Keith Packard, SuSE, Inc.
+ */
+
+#include <X11/Xdefs.h>
+#include <X11/fonts/font.h>
+#include <X11/fonts/fontxlfd.h>
+#include <X11/fonts/fntfil.h>
+#include <X11/fonts/fntfilio.h>
+#include <X11/fonts/fntfilst.h>
+
+typedef struct _BuiltinFile {
+    const char  *name;
+    int                len;
+    const char  *bits;
+} BuiltinFileRec, *BuiltinFilePtr;
+
+typedef struct _BuiltinDir {
+    char       *file_name;
+    char       *font_name;
+} BuiltinDirRec, *BuiltinDirPtr;
+
+typedef struct _BuiltinAlias {
+    char       *alias_name;
+    char       *font_name;
+} BuiltinAliasRec, *BuiltinAliasPtr;
+
+extern const BuiltinFileRec    builtin_files[];
+extern const int               builtin_files_count;
+
+extern const BuiltinDirRec     builtin_dir[];
+extern const int               builtin_dir_count;
+
+extern const BuiltinAliasRec   builtin_alias[];
+extern const int               builtin_alias_count;
+
+extern FontFilePtr     BuiltinFileOpen (char *);
+extern int             BuiltinFileClose (BufFilePtr, int);
+extern int BuiltinReadDirectory (char *, FontDirectoryPtr *);
+extern void BuiltinRegisterFontFileFunctions (void);
+
+extern void BuiltinRegisterFpeFunctions (void);
diff --git a/src/builtins/dir.c b/src/builtins/dir.c
new file mode 100644 (file)
index 0000000..bf351b1
--- /dev/null
@@ -0,0 +1,208 @@
+/*
+ * Copyright 1999 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author:  Keith Packard, SuSE, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "builtin.h"
+
+static BuiltinDirPtr
+BuiltinDirsDup (const BuiltinDirPtr a_dirs,
+                int a_dirs_len)
+{
+    BuiltinDirPtr dirs=NULL ;
+    int i=0 ;
+
+    if (!a_dirs)
+        return NULL ;
+
+    dirs = calloc (a_dirs_len, sizeof (BuiltinDirRec)) ;
+    if (!dirs)
+        return NULL ;
+
+    for (i=0; i < a_dirs_len; i++) {
+       dirs[i].file_name = strdup(a_dirs[i].file_name);
+       dirs[i].font_name = strdup(a_dirs[i].font_name);
+    }
+    return dirs ;
+}
+
+/**
+ * Copy a_save back into a_cur
+ * @param a_cur the instance of BuiltinDir to restore
+ * @param a_saved the saved instance of BuiltinDir to copy into a_cur
+ * @return 0 if went okay, 1 otherwise.
+ */
+static int
+BuiltinDirRestore (BuiltinDirPtr a_cur,
+                   const BuiltinDirPtr a_saved)
+{
+    if (!a_cur)
+        return 1 ;
+    if (!a_saved)
+        return 0 ;
+
+    if (a_saved->font_name)
+        memmove (a_cur->font_name, a_saved->font_name, strlen (a_saved->font_name)) ;
+    return 0 ;
+}
+
+
+static int
+BuiltinDirsRestore (BuiltinDirPtr a_cur_tab,
+                    const BuiltinDirPtr a_saved_tab,
+                    int a_tab_len)
+{
+    int i=0 ;
+
+    if (!a_cur_tab)
+        return 1 ;
+    if (!a_saved_tab)
+        return 0 ;
+
+    for (i=0 ; i < a_tab_len; i++) {
+        if (BuiltinDirRestore (&a_cur_tab[i], &a_saved_tab[i]))
+            return 1 ;
+    }
+    return 0 ;
+}
+
+static BuiltinAliasPtr
+BuiltinAliasesDup (const BuiltinAliasPtr a_aliases,
+                   int a_aliases_len)
+{
+    BuiltinAliasPtr aliases=NULL ;
+    int i=0 ;
+
+    if (!a_aliases)
+        return NULL ;
+
+    aliases = calloc (a_aliases_len, sizeof (BuiltinAliasRec)) ;
+    if (!aliases)
+        return NULL ;
+
+    for (i=0; i < a_aliases_len; i++) {
+       aliases[i].font_name = strdup(a_aliases[i].font_name);
+    }
+    return aliases ;
+}
+
+/**
+ * Copy a_save back into a_cur
+ * @param a_cur the instance of BuiltinAlias to restore
+ * @param a_saved the saved instance of BuiltinAlias to copy into a_cur
+ * @return 0 if went okay, 1 otherwise.
+ */
+static int
+BuiltinAliasRestore (BuiltinAliasPtr a_cur,
+                     const BuiltinAliasPtr a_save)
+{
+    if (!a_cur)
+        return 1 ;
+    if (!a_save)
+        return 0 ;
+    if (a_save->alias_name)
+        memmove (a_cur->alias_name, a_save->alias_name, strlen (a_save->alias_name)) ;
+    if (a_save->font_name)
+        memmove (a_cur->font_name, a_save->font_name, strlen (a_save->font_name)) ;
+    return 0 ;
+}
+
+static int
+BuiltinAliasesRestore (BuiltinAliasPtr a_cur_tab,
+                       const BuiltinAliasPtr a_saved_tab,
+                       int a_tab_len)
+{
+    int i=0 ;
+
+    if (!a_cur_tab)
+        return 1 ;
+    if (!a_saved_tab)
+        return 0 ;
+
+    for (i=0 ; i < a_tab_len; i++) {
+        if (BuiltinAliasRestore (&a_cur_tab[i], &a_saved_tab[i]))
+            return 1 ;
+    }
+    return 0 ;
+}
+
+int
+BuiltinReadDirectory (char *directory, FontDirectoryPtr *pdir)
+{
+    FontDirectoryPtr   dir;
+    int                        i;
+
+    static BuiltinDirPtr saved_builtin_dir;
+    static BuiltinAliasPtr saved_builtin_alias;
+
+    dir = FontFileMakeDir ("", builtin_dir_count);
+
+    if (saved_builtin_dir)
+    {
+        BuiltinDirsRestore ((BuiltinDirPtr) builtin_dir,
+                            saved_builtin_dir,
+                            builtin_dir_count) ;
+    }
+    else
+    {
+        saved_builtin_dir = BuiltinDirsDup ((const BuiltinDirPtr) builtin_dir,
+                                            builtin_dir_count) ;
+    }
+
+    if (saved_builtin_alias)
+    {
+        BuiltinAliasesRestore ((BuiltinAliasPtr) builtin_alias,
+                               saved_builtin_alias,
+                               builtin_alias_count) ;
+    }
+    else
+    {
+        saved_builtin_alias = BuiltinAliasesDup ((const BuiltinAliasPtr) builtin_alias,
+                                                 builtin_alias_count) ;
+    }
+
+    for (i = 0; i < builtin_dir_count; i++)
+    {
+       if (!FontFileAddFontFile (dir,
+                                 (char *) builtin_dir[i].font_name,
+                                 (char *) builtin_dir[i].file_name))
+       {
+           FontFileFreeDir (dir);
+           return BadFontPath;
+       }
+    }
+    for (i = 0; i < builtin_alias_count; i++)
+    {
+       if (!FontFileAddFontAlias (dir, 
+                                  (char *) builtin_alias[i].alias_name,
+                                  (char *) builtin_alias[i].font_name))
+       {
+           FontFileFreeDir (dir);
+           return BadFontPath;
+       }
+    }
+    FontFileSortDir (dir);
+    *pdir = dir;
+    return Successful;
+}
diff --git a/src/builtins/file.c b/src/builtins/file.c
new file mode 100755 (executable)
index 0000000..5492539
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * Copyright 1999 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author:  Keith Packard, SuSE, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <string.h>
+#include "builtin.h"
+
+typedef struct _BuiltinIO {
+    int                    offset;
+    BuiltinFilePtr  file;
+} BuiltinIORec, *BuiltinIOPtr;
+
+static int
+BuiltinFill (BufFilePtr        f)
+{
+    int            left, len;
+    BuiltinIOPtr    io = ((BuiltinIOPtr) f->private);
+
+    left = io->file->len - io->offset;
+    if (left <= 0)
+    {
+       f->left = 0;
+       return BUFFILEEOF;
+    }
+    len = BUFFILESIZE;
+    if (len > left)
+       len = left;
+    memcpy (f->buffer, io->file->bits + io->offset, len);
+    io->offset += len;
+    f->left = len - 1;
+    f->bufp = f->buffer + 1;
+    return f->buffer[0];
+}
+
+static int
+BuiltinSkip (BufFilePtr        f, int count)
+{
+    BuiltinIOPtr    io = ((BuiltinIOPtr) f->private);
+    int            curoff;
+    int            fileoff;
+    int            todo;
+
+    curoff = f->bufp - f->buffer;
+    fileoff = curoff + f->left;
+    if (curoff + count <= fileoff) {
+       f->bufp += count;
+       f->left -= count;
+    } else {
+       todo = count - (fileoff - curoff);
+       io->offset += todo;
+       if (io->offset > io->file->len)
+           io->offset = io->file->len;
+       if (io->offset < 0)
+           io->offset = 0;
+       f->left = 0;
+    }
+    return count;
+}
+
+static int
+BuiltinClose (BufFilePtr f, int unused)
+{
+    BuiltinIOPtr    io = ((BuiltinIOPtr) f->private);
+    
+    free (io);
+    return 1;
+}
+
+
+FontFilePtr
+BuiltinFileOpen (char *name)
+{
+    int                    i;
+    BuiltinIOPtr    io;
+    BufFilePtr     raw, cooked;
+
+    if (*name == '/') name++;
+    for (i = 0; i < builtin_files_count; i++)
+       if (!strcmp (name, builtin_files[i].name))
+           break;
+    if (i == builtin_files_count)
+       return NULL;
+    io = malloc (sizeof (BuiltinIORec));
+    if (!io)
+       return NULL;
+    io->offset = 0;
+    io->file = (void *) &builtin_files[i];
+    raw = BufFileCreate ((char *) io, BuiltinFill, 0, BuiltinSkip, BuiltinClose);
+    if (!raw)
+    {
+       free (io);
+       return NULL;
+    }
+    if ((cooked = BufFilePushZIP (raw)))
+       raw = cooked;
+    else
+    {
+       raw->left += raw->bufp - raw->buffer;
+       raw->bufp = raw->buffer;
+    }
+    return (FontFilePtr) raw;
+}
+
+int
+BuiltinFileClose (FontFilePtr f, int unused)
+{
+    return BufFileClose ((BufFilePtr) f, TRUE);
+}
diff --git a/src/builtins/fonts.c b/src/builtins/fonts.c
new file mode 100755 (executable)
index 0000000..9a9d7d2
--- /dev/null
@@ -0,0 +1,1252 @@
+/*
+ * Copyright 1999 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author:  Keith Packard, SuSE, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "builtin.h"
+
+static const char file_cursor[] = {
+    '\037', '\213', '\010', '\010', '\143', '\117', '\054', '\100',
+    '\000', '\003', '\143', '\165', '\162', '\163', '\157', '\162',
+    '\056', '\160', '\143', '\146', '\000', '\355', '\233', '\177',
+    '\160', '\124', '\327', '\165', '\307', '\317', '\112', '\102',
+    '\022', '\130', '\040', '\021', '\300', '\226', '\023', '\031',
+    '\311', '\100', '\034', '\114', '\354', '\104', '\004', '\033',
+    '\013', '\233', '\040', '\141', '\040', '\006', '\327', '\001',
+    '\154', '\213', '\000', '\216', '\143', '\151', '\221', '\026',
+    '\244', '\146', '\365', '\203', '\325', '\352', '\027', '\010',
+    '\264', '\253', '\137', '\273', '\010', '\320', '\217', '\332',
+    '\155', '\035', '\217', '\123', '\323', '\044', '\323', '\361',
+    '\340', '\114', '\207', '\231', '\144', '\062', '\324', '\303',
+    '\324', '\212', '\235', '\232', '\046', '\045', '\305', '\323',
+    '\072', '\143', '\322', '\060', '\365', '\062', '\166', '\143',
+    '\246', '\166', '\221', '\360', '\057', '\224', '\262', '\150',
+    '\373', '\075', '\357', '\234', '\273', '\357', '\355', '\112',
+    '\313', '\217', '\244', '\371', '\057', '\232', '\371', '\274',
+    '\167', '\357', '\271', '\347', '\336', '\167', '\177', '\236',
+    '\173', '\356', '\173', '\053', '\327', '\316', '\252', '\306',
+    '\154', '\042', '\162', '\201', '\064', '\360', '\056', '\010',
+    '\153', '\230', '\251', '\006', '\136', '\044', '\146', '\160',
+    '\034', '\367', '\354', '\164', '\242', '\067', '\370', '\256',
+    '\351', '\147', '\027', '\021', '\235', '\101', '\142', '\221',
+    '\306', '\327', '\042', '\355', '\307', '\167', '\022', '\225',
+    '\151', '\274', '\021', '\227', '\361', '\045', '\104', '\001',
+    '\215', '\237', '\237', '\116', '\124', '\163', '\267', '\074',
+    '\320', '\224', '\277', '\371', '\076', '\011', '\043', '\311',
+    '\372', '\163', '\315', '\300', '\145', '\011', '\207', '\226',
+    '\103', '\353', '\136', '\226', '\334', '\217', '\313', '\152',
+    '\226', '\160', '\322', '\172', '\016', '\174', '\033', '\074',
+    '\316', '\201', '\215', '\240', '\322', '\004', '\352', '\070',
+    '\020', '\303', '\137', '\013', '\007', '\146', '\112', '\171',
+    '\101', '\260', '\146', '\323', '\346', '\355', '\217', '\155',
+    '\170', '\150', '\175', '\071', '\225', '\327', '\170', '\232',
+    '\074', '\105', '\013', '\166', '\171', '\333', '\033', '\153',
+    '\232', '\026', '\024', '\271', '\175', '\236', '\242', '\346',
+    '\172', '\117', '\175', '\125', '\163', '\335', '\016', '\217',
+    '\317', '\123', '\115', '\233', '\067', '\155', '\330', '\130',
+    '\136', '\361', '\370', '\206', '\047', '\326', '\321', '\327',
+    '\066', '\155', '\054', '\247', '\252', '\146', '\137', '\123',
+    '\203', '\217', '\266', '\256', '\263', '\162', '\077', '\266',
+    '\356', '\361', '\115', '\217', '\154', '\051', '\337', '\260',
+    '\151', '\243', '\043', '\130', '\261', '\315', '\031', '\331',
+    '\116', '\333', '\052', '\326', '\213', '\366', '\243', '\133',
+    '\126', '\257', '\255', '\330', '\272', '\141', '\155', '\271',
+    '\125', '\345', '\064', '\262', '\377', '\362', '\300', '\154',
+    '\255', '\353', '\305', '\030', '\267', '\053', '\026', '\263',
+    '\332', '\216', '\224', '\331', '\224', '\153', '\245', '\377',
+    '\076', '\177', '\074', '\106', '\317', '\321', '\236', '\360',
+    '\160', '\137', '\270', '\375', '\300', '\160', '\350', '\100',
+    '\123', '\160', '\070', '\060', '\340', '\353', '\032', '\016',
+    '\016', '\356', '\353', '\035', '\076', '\020', '\354', '\350',
+    '\033', '\356', '\357', '\262', '\103', '\110', '\350', '\356',
+    '\305', '\245', '\247', '\167', '\117', '\210', '\163', '\204',
+    '\221', '\043', '\060', '\060', '\174', '\070', '\330', '\071',
+    '\070', '\074', '\320', '\205', '\274', '\207', '\203', '\110',
+    '\035', '\350', '\102', '\352', '\341', '\040', '\122', '\007',
+    '\272', '\332', '\103', '\310', '\333', '\026', '\106', '\336',
+    '\266', '\320', '\160', '\070', '\214', '\120', '\070', '\214',
+    '\242', '\002', '\003', '\173', '\103', '\170', '\006', '\122',
+    '\103', '\041', '\113', '\206', '\032', '\164', '\037', '\336',
+    '\163', '\000', '\027', '\144', '\073', '\020', '\102', '\135',
+    '\254', '\113', '\110', '\152', '\025', '\017', '\205', '\035',
+    '\262', '\260', '\011', '\355', '\355', '\035', '\356', '\355',
+    '\335', '\323', '\067', '\334', '\327', '\207', '\113', '\157',
+    '\250', '\235', '\253', '\006', '\131', '\050', '\204', '\150',
+    '\070', '\354', '\103', '\213', '\006', '\371', '\062', '\024',
+    '\017', '\015', '\332', '\172', '\166', '\313', '\355', '\272',
+    '\240', '\011', '\135', '\207', '\271', '\251', '\207', '\367',
+    '\017', '\040', '\233', '\165', '\361', '\007', '\315', '\045',
+    '\060', '\210', '\332', '\007', '\206', '\120', '\173', '\124',
+    '\067', '\334', '\147', '\135', '\254', '\154', '\326', '\305',
+    '\052', '\264', '\315', '\352', '\227', '\060', '\364', '\072',
+    '\017', '\100', '\017', '\075', '\324', '\027', '\102', '\017',
+    '\205', '\302', '\201', '\176', '\074', '\243', '\363', '\240',
+    '\121', '\266', '\272', '\004', '\262', '\003', '\101', '\310',
+    '\372', '\273', '\132', '\203', '\010', '\265', '\164', '\111',
+    '\077', '\367', '\036', '\264', '\056', '\266', '\136', '\307',
+    '\301', '\341', '\340', '\341', '\216', '\103', '\050', '\257',
+    '\045', '\070', '\074', '\030', '\154', '\356', '\302', '\005',
+    '\175', '\160', '\250', '\007', '\265', '\077', '\324', '\203',
+    '\076', '\355', '\355', '\105', '\237', '\366', '\365', '\165',
+    '\240', '\345', '\341', '\275', '\334', '\362', '\166', '\036',
+    '\313', '\066', '\036', '\113', '\214', '\114', '\137', '\010',
+    '\345', '\205', '\302', '\170', '\106', '\050', '\204', '\147',
+    '\070', '\153', '\140', '\367', '\001', '\372', '\245', '\163',
+    '\000', '\011', '\201', '\241', '\175', '\075', '\303', '\203',
+    '\001', '\024', '\145', '\075', '\243', '\273', '\007', '\227',
+    '\236', '\336', '\340', '\020', '\102', '\150', '\171', '\117',
+    '\357', '\356', '\000', '\102', '\273', '\203', '\010', '\101',
+    '\257', '\163', '\010', '\172', '\126', '\216', '\120', '\330',
+    '\172', '\170', '\013', '\107', '\233', '\371', '\342', '\030',
+    '\337', '\176', '\056', '\236', '\057', '\255', '\350', '\335',
+    '\201', '\026', '\276', '\130', '\323', '\307', '\214', '\145',
+    '\237', '\065', '\334', '\241', '\075', '\241', '\041', '\204',
+    '\302', '\103', '\350', '\253', '\001', '\356', '\277', '\101',
+    '\351', '\077', '\015', '\331', '\263', '\023', '\063', '\054',
+    '\300', '\005', '\130', '\163', '\050', '\320', '\217', '\147',
+    '\004', '\017', '\242', '\006', '\001', '\251', '\013', '\372',
+    '\064', '\320', '\217', '\076', '\015', '\036', '\104', '\152',
+    '\327', '\041', '\244', '\166', '\015', '\240', '\345', '\201',
+    '\176', '\074', '\067', '\170', '\020', '\025', '\077', '\020',
+    '\262', '\056', '\373', '\172', '\372', '\103', '\241', '\216',
+    '\336', '\376', '\160', '\230', '\327', '\332', '\163', '\272',
+    '\046', '\112', '\100', '\033', '\070', '\006', '\306', '\100',
+    '\076', '\326', '\310', '\172', '\320', '\010', '\216', '\200',
+    '\021', '\360', '\056', '\050', '\100', '\246', '\047', '\301',
+    '\063', '\340', '\115', '\220', '\003', '\133', '\367', '\010',
+    '\350', '\001', '\077', '\003', '\037', '\200', '\002', '\330',
+    '\272', '\047', '\301', '\363', '\340', '\115', '\060', '\167',
+    '\032', '\164', '\300', '\041', '\160', '\012', '\344', '\144',
+    '\042', '\016', '\016', '\201', '\177', '\006', '\331', '\131',
+    '\260', '\211', '\040', '\000', '\116', '\200', '\050', '\050',
+    '\201', '\361', '\154', '\003', '\107', '\300', '\033', '\331',
+    '\142', '\370', '\112', '\100', '\043', '\070', '\006', '\076',
+    '\000', '\167', '\301', '\320', '\325', '\200', '\037', '\200',
+    '\067', '\101', '\316', '\115', '\050', '\007', '\364', '\200',
+    '\023', '\040', '\012', '\112', '\162', '\120', '\016', '\070',
+    '\016', '\306', '\101', '\011', '\354', '\135', '\033', '\070',
+    '\006', '\306', '\300', '\342', '\131', '\260', '\214', '\340',
+    '\010', '\210', '\200', '\374', '\134', '\242', '\155', '\140',
+    '\010', '\274', '\001', '\062', '\140', '\144', '\312', '\100',
+    '\033', '\070', '\016', '\306', '\101', '\011', '\214', '\122',
+    '\045', '\030', '\002', '\307', '\301', '\171', '\260', '\370',
+    '\063', '\250', '\013', '\170', '\021', '\234', '\007', '\105',
+    '\163', '\240', '\003', '\216', '\200', '\010', '\050', '\232',
+    '\213', '\070', '\010', '\203', '\343', '\340', '\143', '\160',
+    '\317', '\074', '\354', '\033', '\340', '\207', '\040', '\002',
+    '\012', '\156', '\046', '\052', '\007', '\317', '\200', '\067',
+    '\301', '\334', '\133', '\320', '\117', '\340', '\020', '\030',
+    '\271', '\205', '\007', '\205', '\150', '\045', '\350', '\000',
+    '\317', '\202', '\023', '\340', '\014', '\210', '\202', '\374',
+    '\133', '\221', '\006', '\332', '\300', '\161', '\360', '\061',
+    '\050', '\376', '\054', '\372', '\013', '\034', '\003', '\347',
+    '\301', '\342', '\317', '\241', '\216', '\340', '\105', '\160',
+    '\036', '\054', '\056', '\100', '\034', '\274', '\010', '\316',
+    '\202', '\271', '\267', '\141', '\314', '\101', '\017', '\070',
+    '\001', '\242', '\340', '\236', '\371', '\104', '\176', '\360',
+    '\103', '\360', '\001', '\130', '\124', '\210', '\375', '\010',
+    '\034', '\002', '\047', '\100', '\024', '\254', '\304', '\306',
+    '\126', '\015', '\236', '\001', '\247', '\100', '\316', '\355',
+    '\310', '\007', '\252', '\301', '\017', '\300', '\273', '\240',
+    '\140', '\001', '\321', '\217', '\320', '\167', '\137', '\102',
+    '\137', '\075', '\211', '\360', '\361', '\265', '\104', '\131',
+    '\230', '\164', '\271', '\053', '\211', '\012', '\127', '\021',
+    '\255', '\342', '\262', '\320', '\337', '\343', '\030', '\373',
+    '\261', '\164', '\201', '\303', '\054', '\343', '\064', '\326',
+    '\141', '\135', '\053', '\017', '\046', '\150', '\341', '\070',
+    '\121', '\151', '\224', '\250', '\163', '\202', '\150', '\242',
+    '\023', '\172', '\245', '\320', '\207', '\336', '\130', '\256',
+    '\300', '\141', '\226', '\161', '\032', '\353', '\260', '\056',
+    '\347', '\341', '\274', '\124', '\014', '\120', '\026', '\101',
+    '\147', '\104', '\363', '\360', '\163', '\106', '\360', '\274',
+    '\010', '\150', '\304', '\263', '\113', '\170', '\036', '\143',
+    '\276', '\317', '\002', '\131', '\146', '\137', '\212', '\000',
+    '\224', '\101', '\050', '\057', '\200', '\162', '\043', '\140',
+    '\274', '\124', '\236', '\303', '\375', '\020', '\321', '\262',
+    '\306', '\101', '\007', '\062', '\255', '\002', '\205', '\310',
+    '\210', '\151', '\145', '\371', '\006', '\061', '\135', '\153',
+    '\061', '\031', '\312', '\004', '\236', '\320', '\052', '\161',
+    '\070', '\226', '\076', '\231', '\066', '\135', '\237', '\023',
+    '\056', '\233', '\250', '\312', '\362', '\065', '\357', '\023',
+    '\123', '\224', '\353', '\174', '\146', '\361', '\024', '\145',
+    '\230', '\162', '\247', '\172', '\146', '\200', '\233', '\214',
+    '\373', '\354', '\114', '\222', '\235', '\067', '\137', '\033',
+    '\222', '\046', '\351', '\334', '\035', '\074', '\116', '\277',
+    '\313', '\222', '\364', '\070', '\350', '\207', '\130', '\226',
+    '\350', '\074', '\204', '\171', '\265', '\066', '\303', '\206',
+    '\323', '\326', '\315', '\115', '\204', '\145', '\116', '\035',
+    '\316', '\363', '\366', '\076', '\233', '\263', '\230', '\207',
+    '\261', '\116', '\033', '\043', '\167', '\312', '\130', '\307',
+    '\231', '\007', '\217', '\266', '\130', '\010', '\333', '\261',
+    '\020', '\145', '\056', '\104', '\235', '\027', '\242', '\275',
+    '\337', '\207', '\254', '\012', '\274', '\223', '\153', '\353',
+    '\060', '\261', '\122', '\001', '\142', '\213', '\121', '\164',
+    '\326', '\050', '\346', '\332', '\050', '\352', '\062', '\212',
+    '\001', '\034', '\105', '\173', '\106', '\241', '\070', '\132',
+    '\152', '\303', '\172', '\011', '\355', '\066', '\235', '\014',
+    '\062', '\226', '\302', '\256', '\201', '\074', '\120', '\004',
+    '\312', '\100', '\000', '\104', '\227', '\332', '\072', '\214',
+    '\171', '\256', '\145', '\164', '\101', '\316', '\045', '\314',
+    '\073', '\120', '\002', '\032', '\101', '\004', '\214', '\200',
+    '\250', '\003', '\326', '\113', '\176', '\156', '\031', '\115',
+    '\015', '\367', '\347', '\172', '\264', '\175', '\263', '\113',
+    '\306', '\253', '\314', '\314', '\207', '\102', '\141', '\304',
+    '\065', '\065', '\247', '\156', '\225', '\076', '\345', '\271',
+    '\074', '\226', '\045', '\363', '\200', '\345', '\316', '\076',
+    '\147', '\106', '\350', '\352', '\230', '\366', '\215', '\244',
+    '\137', '\235', '\344', '\366', '\160', '\331', '\354', '\157',
+    '\137', '\301', '\175', '\032', '\052', '\375', '\111', '\005',
+    '\321', '\274', '\315', '\104', '\277', '\332', '\112', '\264',
+    '\245', '\034', '\154', '\101', '\030', '\314', '\103', '\370',
+    '\023', '\310', '\246', '\041', '\355', '\012', '\164', '\134',
+    '\145', '\132', '\267', '\344', '\362', '\156', '\020', '\063',
+    '\104', '\146', '\175', '\104', '\025', '\263', '\156', '\226',
+    '\241', '\316', '\113', '\323', '\022', '\206', '\322', '\102',
+    '\207', '\221', '\306', '\135', '\102', '\064', '\135', '\230',
+    '\310', '\022', '\142', '\271', '\066', '\227', '\146', '\331',
+    '\372', '\206', '\210', '\313', '\266', '\173', '\363', '\141',
+    '\157', '\147', '\025', '\210', '\315', '\163', '\302', '\062',
+    '\116', '\063', '\366', '\222', '\363', '\260', '\335', '\162',
+    '\332', '\074', '\306', '\330', '\074', '\047', '\054', '\063',
+    '\351', '\306', '\146', '\106', '\364', '\171', '\277', '\305',
+    '\230', '\317', '\131', '\106', '\364', '\163', '\234', '\127',
+    '\332', '\301', '\154', '\330', '\351', '\167', '\060', '\137',
+    '\047', '\240', '\363', '\213', '\271', '\066', '\377', '\215',
+    '\275', '\352', '\137', '\356', '\021', '\173', '\154', '\306',
+    '\227', '\165', '\056', '\255', '\040', '\372', '\115', '\053',
+    '\321', '\377', '\340', '\204', '\161', '\245', '\001', '\166',
+    '\141', '\047', '\321', '\107', '\115', '\222', '\376', '\376',
+    '\275', '\066', '\227', '\161', '\226', '\171', '\277', '\231',
+    '\350', '\164', '\207', '\075', '\217', '\306', '\165', '\257',
+    '\315', '\254', '\204', '\237', '\277', '\215', '\350', '\303',
+    '\207', '\260', '\056', '\313', '\204', '\064', '\345', '\071',
+    '\310', '\277', '\201', '\061', '\177', '\013', '\174', '\163',
+    '\273', '\055', '\267', '\332', '\221', '\053', '\066', '\170',
+    '\042', '\046', '\044', '\217', '\347', '\325', '\344', '\234',
+    '\277', '\314', '\065', '\065', '\235', '\152', '\100', '\371',
+    '\236', '\112', '\207', '\327', '\106', '\062', '\123', '\315',
+    '\251', '\251', '\364', '\230', '\007', '\261', '\077', '\256',
+    '\173', '\224', '\350', '\141', '\234', '\011', '\313', '\321',
+    '\267', '\065', '\360', '\133', '\066', '\303', '\117', '\172',
+    '\145', '\102', '\312', '\347', '\073', '\307', '\131', '\316',
+    '\351', '\254', '\307', '\372', '\234', '\157', '\047', '\306',
+    '\253', '\356', '\067', '\104', '\173', '\321', '\337', '\055',
+    '\350', '\127', '\057', '\366', '\365', '\212', '\053', '\030',
+    '\347', '\011', '\261', '\337', '\174', '\347', '\070', '\313',
+    '\071', '\235', '\365', '\130', '\237', '\363', '\161', '\172',
+    '\052', '\270', '\275', '\127', '\113', '\117', '\145', '\067',
+    '\234', '\355', '\115', '\245', '\063', '\242', '\375', '\126',
+    '\231', '\056', '\355', '\132', '\017', '\137', '\156', '\355',
+    '\154', '\151', '\117', '\147', '\247', '\366', '\167', '\247',
+    '\304', '\131', '\316', '\351', '\254', '\307', '\372', '\246',
+    '\277', '\331', '\046', '\361', '\230', '\263', '\215', '\372',
+    '\127', '\314', '\273', '\223', '\273', '\345', '\231', '\235',
+    '\372', '\154', '\216', '\263', '\174', '\052', '\033', '\346',
+    '\334', '\003', '\223', '\367', '\074', '\347', '\276', '\310',
+    '\353', '\167', '\252', '\165', '\353', '\304', '\244', '\263',
+    '\056', '\307', '\135', '\331', '\211', '\270', '\225', '\144',
+    '\271', '\225', '\277', '\324', '\306', '\254', '\355', '\367',
+    '\126', '\044', '\142', '\344', '\116', '\135', '\143', '\227',
+    '\330', '\036', '\375', '\104', '\155', '\121', '\262', '\035',
+    '\142', '\331', '\117', '\034', '\076', '\202', '\261', '\115',
+    '\306', '\046', '\045', '\267', '\311', '\330', '\237', '\344',
+    '\266', '\261', '\056', '\347', '\341', '\064', '\153', '\363',
+    '\110', '\341', '\073', '\261', '\357', '\136', '\006', '\212',
+    '\240', '\237', '\007', '\262', '\371', '\175', '\210', '\276',
+    '\277', '\140', '\073', '\156', '\275', '\176', '\340', '\212',
+    '\354', '\207', '\156', '\251', '\370', '\112', '\154', '\173',
+    '\046', '\162', '\005', '\266', '\101', '\074', '\106', '\307',
+    '\221', '\367', '\171', '\060', '\200', '\114', '\041', '\227',
+    '\354', '\315', '\256', '\024', '\317', '\266', '\034', '\053',
+    '\370', '\360', '\001', '\354', '\161', '\145', '\372', '\176',
+    '\205', '\337', '\011', '\360', '\161', '\101', '\335', '\224',
+    '\304', '\147', '\257', '\262', '\237', '\315', '\004', '\330',
+    '\347', '\343', '\147', '\147', '\312', '\073', '\030', '\076',
+    '\003', '\025', '\150', '\261', '\354', '\363', '\245', '\153',
+    '\177', '\014', '\243', '\300', '\357', '\140', '\016', '\316',
+    '\304', '\372', '\313', '\232', '\145', '\217', '\051', '\207',
+    '\131', '\306', '\151', '\303', '\111', '\143', '\372', '\321',
+    '\062', '\261', '\163', '\245', '\010', '\277', '\215', '\347',
+    '\216', '\176', '\125', '\340', '\060', '\313', '\070', '\215',
+    '\165', '\214', '\376', '\105', '\074', '\354', '\062', '\373',
+    '\213', '\070', '\243', '\114', '\107', '\131', '\267', '\362',
+    '\332', '\045', '\307', '\037', '\107', '\356', '\100', '\273',
+    '\140', '\227', '\163', '\120', '\306', '\070', '\362', '\217',
+    '\055', '\204', '\175', '\106', '\236', '\113', '\271', '\272',
+    '\237', '\103', '\247', '\224', '\347', '\112', '\261', '\370',
+    '\173', '\226', '\351', '\322', '\100', '\016', '\354', '\100',
+    '\001', '\046', '\103', '\024', '\341', '\161', '\060', '\066',
+    '\212', '\166', '\237', '\224', '\075', '\232', '\367', '\017',
+    '\366', '\343', '\070', '\374', '\063', '\074', '\373', '\365',
+    '\174', '\273', '\136', '\034', '\146', '\031', '\247', '\261',
+    '\016', '\353', '\162', '\330', '\332', '\267', '\325', '\137',
+    '\346', '\071', '\160', '\036', '\347', '\223', '\263', '\017',
+    '\114', '\266', '\171', '\054', '\343', '\264', '\061', '\035',
+    '\143', '\263', '\337', '\323', '\174', '\351', '\150', '\327',
+    '\051', '\354', '\023', '\063', '\245', '\357', '\072', '\321',
+    '\366', '\122', '\220', '\311', '\203', '\240', '\173', '\133',
+    '\036', '\045', '\322', '\146', '\372', '\002', '\244', '\073',
+    '\237', '\125', '\072', '\031', '\336', '\223', '\170', '\355',
+    '\363', '\270', '\226', '\220', '\275', '\207', '\063', '\074',
+    '\077', '\347', '\140', '\314', '\267', '\302', '\256', '\314',
+    '\301', '\144', '\371', '\167', '\334', '\013', '\127', '\112',
+    '\037', '\345', '\275', '\053', '\014', '\175', '\014', '\370',
+    '\216', '\364', '\060', '\372', '\240', '\007', '\025', '\350',
+    '\050', '\224', '\374', '\227', '\221', '\377', '\022', '\333',
+    '\014', '\356', '\177', '\246', '\324', '\366', '\073', '\330',
+    '\107', '\033', '\143', '\142', '\172', '\177', '\317', '\336',
+    '\237', '\070', '\277', '\345', '\107', '\317', '\227', '\065',
+    '\063', '\222', '\156', '\367', '\077', '\267', '\367', '\177',
+    '\265', '\314', '\053', '\346', '\034', '\204', '\064', '\230',
+    '\173', '\302', '\120', '\023', '\216', '\204', '\224', '\103',
+    '\072', '\111', '\013', '\165', '\356', '\146', '\331', '\171',
+    '\047', '\222', '\355', '\223', '\372', '\340', '\061', '\336',
+    '\307', '\264', '\333', '\346', '\253', '\355', '\163', '\241',
+    '\355', '\373', '\321', '\256', '\154', '\264', '\213', '\137',
+    '\156', '\132', '\167', '\354', '\355', '\331', '\330', '\363',
+    '\213', '\127', '\243', '\154', '\054', '\246', '\062', '\234',
+    '\143', '\003', '\274', '\230', '\246', '\311', '\142', '\212',
+    '\333', '\113', '\265', '\035', '\023', '\272', '\206', '\271',
+    '\135', '\326', '\071', '\250', '\123', '\347', '\026', '\356',
+    '\221', '\122', '\131', '\243', '\274', '\306', '\314', '\001',
+    '\212', '\333', '\376', '\072', '\374', '\211', '\356', '\112',
+    '\361', '\323', '\234', '\244', '\103', '\226', '\211', '\171',
+    '\233', '\303', '\147', '\131', '\064', '\262', '\070', '\123',
+    '\354', '\075', '\333', '\153', '\316', '\067', '\121', '\052',
+    '\066', '\235', '\363', '\246', '\053', '\153', '\334', '\260',
+    '\021', '\215', '\230', '\106', '\030', '\334', '\002', '\364',
+    '\111', '\311', '\254', '\044', '\137', '\025', '\165', '\171',
+    '\351', '\050', '\174', '\305', '\137', '\311', '\175', '\332',
+    '\033', '\104', '\067', '\035', '\111', '\175', '\067', '\172',
+    '\174', '\377', '\103', '\375', '\107', '\313', '\267', '\050',
+    '\024', '\333', '\370', '\273', '\057', '\310', '\132', '\147',
+    '\173', '\176', '\332', '\341', '\063', '\161', '\230', '\145',
+    '\234', '\306', '\072', '\121', '\355', '\123', '\247', '\017',
+    '\167', '\335', '\317', '\352', '\264', '\175', '\072', '\227',
+    '\332', '\256', '\054', '\131', '\106', '\074', '\125', '\254',
+    '\261', '\357', '\124', '\163', '\300', '\161', '\270', '\003',
+    '\144', '\216', '\042', '\225', '\312', '\325', '\362', '\304',
+    '\034', '\173', '\045', '\313', '\370', '\030', '\362', '\221',
+    '\332', '\016', '\143', '\023', '\314', '\131', '\252', '\033',
+    '\254', '\321', '\071', '\073', '\207', '\327', '\112', '\251',
+    '\334', '\027', '\252', '\274', '\333', '\241', '\153', '\316',
+    '\133', '\271', '\210', '\014', '\202', '\323', '\050', '\153',
+    '\224', '\022', '\333', '\306', '\161', '\226', '\163', '\072',
+    '\353', '\231', '\074', '\351', '\051', '\060', '\365', '\114',
+    '\225', '\236', '\233', '\202', '\344', '\275', '\075', '\225',
+    '\236', '\013', '\215', '\235', '\170', '\105', '\130', '\360',
+    '\075', '\242', '\357', '\035', '\115', '\204', '\145', '\046',
+    '\075', '\031', '\053', '\257', '\261', '\025', '\277', '\007',
+    '\234', '\067', '\125', '\273', '\222', '\333', '\237', '\252',
+    '\376', '\251', '\332', '\173', '\255', '\202', '\115', '\271',
+    '\327', '\052', '\070', '\271', '\134', '\313', '\347', '\312',
+    '\025', '\337', '\215', '\277', '\063', '\274', '\172', '\216',
+    '\150', '\321', '\277', '\141', '\257', '\347', '\367', '\156',
+    '\260', '\013', '\105', '\151', '\222', '\306', '\167', '\266',
+    '\265', '\354', '\357', '\055', '\236', '\001', '\133', '\305',
+    '\357', '\206', '\242', '\366', '\171', '\210', '\355', '\314',
+    '\153', '\260', '\115', '\357', '\275', '\243', '\176', '\373',
+    '\333', '\142', '\127', '\043', '\131', '\211', '\076', '\041',
+    '\353', '\355', '\057', '\025', '\337', '\227', '\111', '\036',
+    '\257', '\045', '\107', '\023', '\371', '\143', '\217', '\127',
+    '\304', '\261', '\316', '\170', '\235', '\360', '\032', '\167',
+    '\025', '\021', '\375', '\322', '\153', '\343', '\252', '\024',
+    '\062', '\141', '\313', '\362', '\063', '\165', '\117', '\120',
+    '\077', '\324', '\072', '\027', '\152', '\076', '\313', '\166',
+    '\244', '\260', '\001', '\321', '\121', '\373', '\375', '\031',
+    '\347', '\147', '\077', '\146', '\266', '\256', '\363', '\307',
+    '\300', '\123', '\240', '\207', '\344', '\333', '\025', '\357',
+    '\177', '\171', '\240', '\330', '\364', '\177', '\206', '\354',
+    '\107', '\226', '\001', '\300', '\363', '\331', '\201', '\162',
+    '\256', '\177', '\164', '\043', '\105', '\135', '\302', '\170',
+    '\272', '\356', '\115', '\272', '\377', '\107', '\162', '\325',
+    '\326', '\027', '\252', '\341', '\340', '\115', '\246', '\040',
+    '\161', '\137', '\073', '\225', '\043', '\070', '\353', '\167',
+    '\016', '\376', '\375', '\071', '\330', '\360', '\127', '\261',
+    '\257', '\026', '\314', '\322', '\263', '\057', '\316', '\175',
+    '\271', '\035', '\322', '\077', '\316', '\167', '\200', '\334',
+    '\166', '\143', '\117', '\131', '\166', '\021', '\106', '\344',
+    '\042', '\346', '\301', '\107', '\060', '\102', '\243', '\053',
+    '\344', '\074', '\314', '\371', '\047', '\116', '\112', '\137',
+    '\160', '\031', '\311', '\076', '\261', '\231', '\277', '\251',
+    '\316', '\354', '\123', '\371', '\300', '\116', '\337', '\330',
+    '\320', '\241', '\375', '\161', '\022', '\317', '\353', '\126',
+    '\077', '\365', '\165', '\175', '\277', '\302', '\343', '\305',
+    '\276', '\306', '\142', '\345', '\002', '\360', '\252', '\214',
+    '\375', '\227', '\161', '\355', '\307', '\011', '\335', '\107',
+    '\007', '\301', '\013', '\340', '\077', '\035', '\276', '\366',
+    '\170', '\222', '\136', '\124', '\145', '\330', '\352', '\344',
+    '\354', '\245', '\363', '\141', '\314', '\350', '\151', '\175',
+    '\142', '\032', '\077', '\003', '\016', '\221', '\370', '\012',
+    '\231', '\012', '\257', '\337', '\200', '\372', '\136', '\021',
+    '\035', '\077', '\036', '\107', '\353', '\054', '\340', '\130',
+    '\333', '\054', '\073', '\001', '\126', '\246', '\313', '\060',
+    '\316', '\327', '\162', '\114', '\147', '\225', '\201', '\100',
+    '\261', '\116', '\252', '\257', '\040', '\317', '\175', '\162',
+    '\347', '\170', '\100', '\323', '\223', '\073', '\166', '\204',
+    '\271', '\210', '\164', '\336', '\060', '\056', '\045', '\316',
+    '\131', '\216', '\263', '\234', '\323', '\107', '\234', '\235',
+    '\174', '\055', '\033', '\164', '\203', '\306', '\175', '\222',
+    '\255', '\113', '\101', '\262', '\255', '\070', '\232', '\304',
+    '\037', '\333', '\126', '\360', '\372', '\166', '\055', '\260',
+    '\211', '\055', '\224', '\367', '\060', '\116', '\056', '\102',
+    '\147', '\166', '\221', '\115', '\262', '\115', '\310', '\302',
+    '\244', '\213', '\215', '\332', '\264', '\136', '\020', '\056',
+    '\305', '\154', '\132', '\043', '\211', '\171', '\002', '\072',
+    '\267', '\370', '\133', '\017', '\163', '\214', '\111', '\227',
+    '\363', '\030', '\163', '\102', '\277', '\315', '\374', '\043',
+    '\203', '\176', '\052', '\064', '\007', '\044', '\375', '\156',
+    '\063', '\142', '\316', '\122', '\271', '\372', '\036', '\134',
+    '\141', '\277', '\060', '\376', '\216', '\074', '\246', '\357',
+    '\140', '\012', '\345', '\154', '\011', '\167', '\363', '\272',
+    '\141', '\073', '\264', '\112', '\314', '\212', '\165', '\276',
+    '\353', '\270', '\116', '\054', '\277', '\305', '\045', '\353',
+    '\243', '\303', '\261', '\016', '\331', '\337', '\145', '\137',
+    '\223', '\373', '\074', '\267', '\115', '\356', '\034', '\147',
+    '\071', '\373', '\237', '\354', '\117', '\046', '\217', '\045',
+    '\307', '\131', '\316', '\351', '\331', '\272', '\056', '\330',
+    '\347', '\312', '\325', '\173', '\216', '\326', '\255', '\130',
+    '\237', '\023', '\157', '\257', '\336', '\071', '\136', '\242',
+    '\351', '\226', '\242', '\236', '\263', '\330', '\150', '\130',
+    '\367', '\174', '\262', '\013', '\056', '\320', '\161', '\355',
+    '\244', '\370', '\373', '\120', '\113', '\247', '\100', '\322',
+    '\263', '\065', '\270', '\112', '\373', '\346', '\106', '\372',
+    '\062', '\117', '\353', '\147', '\354', '\230', '\351', '\243',
+    '\353', '\355', '\323', '\033', '\171', '\166', '\362', '\270',
+    '\135', '\357', '\163', '\247', '\032', '\067', '\353', '\120',
+    '\317', '\233', '\032', '\357', '\065', '\173', '\061', '\117',
+    '\301', '\020', '\010', '\047', '\161', '\010', '\014', '\200',
+    '\127', '\100', '\076', '\157', '\200', '\306', '\210', '\071',
+    '\053', '\215', '\076', '\255', '\004', '\215', '\240', '\055',
+    '\211', '\016', '\260', '\077', '\046', '\357', '\222', '\366',
+    '\103', '\267', '\170', '\077', '\131', '\357', '\035', '\330',
+    '\134', '\271', '\034', '\360', '\231', '\175', '\166', '\232',
+    '\275', '\056', '\363', '\026', '\310', '\231', '\234', '\160',
+    '\106', '\267', '\214', '\077', '\006', '\172', '\244', '\224',
+    '\022', '\336', '\057', '\361', '\262', '\341', '\363', '\272',
+    '\205', '\163', '\155', '\216', '\312', '\231', '\174', '\114',
+    '\215', '\370', '\110', '\314', '\046', '\203', '\317', '\147',
+    '\031', '\102', '\136', '\232', '\160', '\356', '\234', '\274',
+    '\257', '\345', '\275', '\220', '\341', '\060', '\313', '\114',
+    '\272', '\321', '\347', '\274', '\231', '\230', '\127', '\071',
+    '\071', '\022', '\147', '\337', '\202', '\367', '\116', '\336',
+    '\067', '\077', '\175', '\100', '\375', '\052', '\344', '\377',
+    '\264', '\120', '\144', '\234', '\226', '\237', '\046', '\172',
+    '\234', '\207', '\363', '\362', '\006', '\302', '\266', '\341',
+    '\056', '\334', '\377', '\006', '\367', '\233', '\063', '\305',
+    '\067', '\300', '\366', '\115', '\070', '\266', '\320', '\347',
+    '\223', '\356', '\137', '\320', '\064', '\206', '\365', '\270',
+    '\357', '\363', '\161', '\306', '\357', '\120', '\366', '\317',
+    '\244', '\370', '\373', '\211', '\353', '\201', '\237', '\355',
+    '\174', '\337', '\132', '\224', '\146', '\363', '\174', '\201',
+    '\234', '\005', '\171', '\135', '\032', '\337', '\161', '\021',
+    '\316', '\255', '\163', '\347', '\312', '\172', '\346', '\167',
+    '\312', '\234', '\337', '\274', '\167', '\344', '\063', '\045',
+    '\303', '\347', '\313', '\022', '\314', '\213', '\027', '\060',
+    '\271', '\322', '\043', '\230', '\122', '\035', '\122', '\026',
+    '\177', '\367', '\340', '\167', '\243', '\313', '\227', '\213',
+    '\377', '\311', '\147', '\113', '\316', '\307', '\276', '\016',
+    '\237', '\057', '\271', '\114', '\076', '\247', '\166', '\127',
+    '\312', '\371', '\223', '\357', '\346', '\334', '\152', '\316',
+    '\237', '\043', '\111', '\357', '\050', '\127', '\316', '\227',
+    '\162', '\370', '\254', '\372', '\032', '\306', '\250', '\352',
+    '\035', '\271', '\233', '\263', '\053', '\247', '\133', '\176',
+    '\154', '\172', '\352', '\357', '\070', '\154', '\063', '\123',
+    '\245', '\245', '\174', '\027', '\353', '\260', '\135', '\251',
+    '\164', '\314', '\226', '\271', '\112', '\327', '\244', '\365',
+    '\275', '\042', '\327', '\366', '\101', '\212', '\215', '\217',
+    '\310', '\357', '\327', '\170', '\001', '\263', '\361', '\050',
+    '\222', '\171', '\134', '\250', '\113', '\151', '\102', '\337',
+    '\223', '\106', '\325', '\316', '\133', '\066', '\137', '\333',
+    '\077', '\306', '\176', '\035', '\373', '\202', '\150', '\147',
+    '\204', '\035', '\230', '\010', '\131', '\016', '\214', '\071',
+    '\003', '\073', '\267', '\156', '\376', '\046', '\127', '\105',
+    '\362', '\215', '\216', '\277', '\325', '\131', '\337', '\354',
+    '\062', '\344', '\033', '\136', '\374', '\154', '\023', '\113',
+    '\204', '\353', '\356', '\374', '\046', '\147', '\175', '\243',
+    '\313', '\322', '\157', '\166', '\005', '\372', '\015', '\257',
+    '\330', '\161', '\346', '\321', '\347', '\072', '\035', '\300',
+    '\250', '\176', '\233', '\053', '\323', '\157', '\165', '\171',
+    '\372', '\355', '\056', '\303', '\361', '\255', '\156', '\322',
+    '\167', '\276', '\261', '\304', '\157', '\162', '\043', '\372',
+    '\255', '\256', '\121', '\277', '\335', '\361', '\067', '\274',
+    '\034', '\375', '\126', '\147', '\175', '\257', '\053', '\024',
+    '\110', '\307', '\214', '\273', '\201', '\277', '\311', '\361',
+    '\267', '\071', '\376', '\106', '\227', '\162', '\334', '\073',
+    '\047', '\217', '\143', '\362', '\373', '\157', '\236', '\263',
+    '\051', '\347', '\200', '\266', '\167', '\204', '\256', '\361',
+    '\235', '\056', '\251', '\175', '\327', '\372', '\136', '\227',
+    '\055', '\115', '\111', '\060', '\251', '\255', '\064', '\331',
+    '\336', '\177', '\213', '\344', '\147', '\150', '\033', '\110',
+    '\176', '\234', '\146', '\060', '\357', '\344', '\222', '\367',
+    '\002', '\247', '\315', '\177', '\071', '\111', '\376', '\226',
+    '\162', '\322', '\361', '\056', '\342', '\232', '\147', '\341',
+    '\353', '\074', '\323', '\033', '\302', '\074', '\317', '\161',
+    '\366', '\374', '\071', '\174', '\332', '\017', '\247', '\313',
+    '\357', '\124', '\326', '\344', '\247', '\030', '\037', '\265',
+    '\107', '\001', '\204', '\317', '\267', '\020', '\135', '\176',
+    '\233', '\350', '\112', '\251', '\356', '\371', '\352', '\223',
+    '\235', '\156', '\237', '\142', '\134', '\262', '\022', '\011',
+    '\134', '\217', '\137', '\153', '\374', '\337', '\353', '\364',
+    '\143', '\015', '\146', '\177', '\060', '\347', '\250', '\076',
+    '\264', '\245', '\033', '\363', '\071', '\210', '\011', '\370',
+    '\323', '\163', '\302', '\355', '\010', '\317', '\051', '\026',
+    '\133', '\037', '\235', '\042', '\217', '\341', '\132', '\347',
+    '\117', '\363', '\316', '\325', '\231', '\247', '\325', '\061',
+    '\027', '\256', '\207', '\002', '\235', '\107', '\243', '\216',
+    '\161', '\067', '\373', '\377', '\325', '\160', '\372', '\014',
+    '\234', '\127', '\176', '\107', '\370', '\035', '\062', '\177',
+    '\056', '\110', '\322', '\341', '\100', '\114', '\303', '\146',
+    '\226', '\205', '\047', '\115', '\247', '\031', '\164', '\023',
+    '\066', '\246', '\231', '\160', '\050', '\162', '\255', '\337',
+    '\023', '\176', '\206', '\346', '\300', '\143', '\231', '\107',
+    '\067', '\323', '\055', '\160', '\304', '\156', '\245', '\317',
+    '\322', '\347', '\120', '\233', '\333', '\340', '\074', '\024',
+    '\302', '\340', '\335', '\116', '\013', '\150', '\041', '\066',
+    '\366', '\317', '\323', '\035', '\330', '\337', '\026', '\323',
+    '\235', '\264', '\204', '\276', '\110', '\167', '\321', '\335',
+    '\364', '\045', '\372', '\062', '\014', '\304', '\122', '\034',
+    '\202', '\226', '\321', '\075', '\164', '\057', '\055', '\247',
+    '\373', '\120', '\243', '\025', '\164', '\077', '\075', '\000',
+    '\247', '\341', '\253', '\130', '\015', '\245', '\230', '\055',
+    '\253', '\351', '\101', '\132', '\103', '\153', '\151', '\035',
+    '\175', '\215', '\036', '\242', '\365', '\130', '\017', '\017',
+    '\323', '\237', '\321', '\043', '\364', '\165', '\332', '\110',
+    '\233', '\150', '\063', '\075', '\212', '\023', '\372', '\343',
+    '\124', '\116', '\133', '\350', '\033', '\264', '\225', '\266',
+    '\321', '\166', '\172', '\202', '\276', '\111', '\117', '\142',
+    '\375', '\074', '\105', '\025', '\124', '\111', '\156', '\332',
+    '\001', '\333', '\130', '\115', '\036', '\332', '\111', '\273',
+    '\250', '\206', '\152', '\351', '\317', '\261', '\256', '\274',
+    '\124', '\107', '\365', '\324', '\200', '\223', '\341', '\156',
+    '\362', '\121', '\023', '\371', '\251', '\231', '\132', '\320',
+    '\177', '\155', '\324', '\116', '\173', '\150', '\057', '\172',
+    '\145', '\037', '\355', '\307', '\232', '\014', '\120', '\220',
+    '\272', '\250', '\033', '\247', '\377', '\136', '\352', '\243',
+    '\020', '\205', '\351', '\000', '\365', '\323', '\101', '\234',
+    '\022', '\017', '\323', '\000', '\015', '\322', '\020', '\015',
+    '\323', '\137', '\320', '\323', '\364', '\014', '\375', '\045',
+    '\375', '\025', '\375', '\065', '\075', '\153', '\365', '\234',
+    '\371', '\175', '\330', '\242', '\264', '\077', '\361', '\047',
+    '\260', '\037', '\052', '\377', '\337', '\345', '\076', '\350',
+    '\022', '\322', '\310', '\376', '\075', '\042', '\377', '\316',
+    '\231', '\177', '\362', '\206', '\355', '\315', '\162', '\245',
+    '\127', '\200', '\115', '\044', '\357', '\260', '\174', '\152',
+    '\043', '\370', '\135', '\142', '\077', '\170', '\026', '\274',
+    '\004', '\136', '\003', '\157', '\221', '\154', '\271', '\374',
+    '\116', '\144', '\246', '\113', '\176', '\307', '\270', '\030',
+    '\054', '\003', '\153', '\300', '\106', '\360', '\024', '\360',
+    '\200', '\335', '\240', '\025', '\164', '\201', '\303', '\340',
+    '\273', '\340', '\373', '\340', '\357', '\301', '\011', '\227',
+    '\274', '\163', '\376', '\065', '\070', '\017', '\076', '\005',
+    '\323', '\121', '\301', '\231', '\340', '\146', '\160', '\033',
+    '\270', '\023', '\054', '\117', '\223', '\075', '\274', '\034',
+    '\170', '\300', '\156', '\320', '\005', '\016', '\203', '\357',
+    '\202', '\277', '\003', '\077', '\006', '\057', '\203', '\177',
+    '\002', '\277', '\004', '\377', '\001', '\042', '\340', '\175',
+    '\160', '\021', '\104', '\101', '\032', '\154', '\373', '\114',
+    '\060', '\207', '\337', '\273', '\200', '\205', '\340', '\356',
+    '\164', '\371', '\035', '\332', '\172', '\360', '\050', '\250',
+    '\000', '\265', '\240', '\015', '\004', '\323', '\345', '\175',
+    '\370', '\163', '\340', '\050', '\370', '\021', '\370', '\051',
+    '\370', '\005', '\070', '\003', '\316', '\202', '\377', '\002',
+    '\037', '\202', '\014', '\354', '\151', '\063', '\300', '\274',
+    '\014', '\371', '\155', '\346', '\142', '\360', '\145', '\360',
+    '\200', '\176', '\067', '\175', '\030', '\154', '\007', '\165',
+    '\240', '\025', '\364', '\201', '\141', '\360', '\267', '\340',
+    '\045', '\360', '\062', '\170', '\035', '\274', '\005', '\042',
+    '\340', '\002', '\270', '\004', '\246', '\361', '\267', '\063',
+    '\160', '\007', '\050', '\001', '\233', '\300', '\267', '\100',
+    '\043', '\350', '\004', '\117', '\203', '\027', '\300', '\061',
+    '\360', '\052', '\370', '\065', '\070', '\007', '\056', '\200',
+    '\117', '\200', '\213', '\177', '\373', '\011', '\346', '\202',
+    '\333', '\300', '\027', '\063', '\305', '\057', '\277', '\037',
+    '\254', '\006', '\137', '\007', '\345', '\374', '\035', '\010',
+    '\064', '\200', '\156', '\360', '\064', '\170', '\021', '\374',
+    '\003', '\070', '\015', '\316', '\200', '\337', '\202', '\013',
+    '\340', '\062', '\277', '\350', '\302', '\236', '\065', '\003',
+    '\314', '\001', '\267', '\203', '\045', '\354', '\267', '\203',
+    '\325', '\140', '\023', '\330', '\002', '\052', '\301', '\116',
+    '\260', '\033', '\154', '\253', '\320', '\337', '\256', '\233',
+    '\100', '\105', '\235', '\273', '\351', '\333', '\344', '\366',
+    '\371', '\032', '\132', '\345', '\052', '\202', '\035', '\356',
+    '\046', '\117', '\165', '\205', '\010', '\252', '\033', '\132',
+    '\353', '\047', '\011', '\046', '\253', '\065', '\067', '\046',
+    '\105', '\125', '\245', '\301', '\355', '\267', '\056', '\046',
+    '\272', '\253', '\241', '\251', '\326', '\337', '\036', '\017',
+    '\030', '\261', '\337', '\337', '\120', '\127', '\341', '\365',
+    '\354', '\364', '\127', '\124', '\065', '\370', '\352', '\075',
+    '\276', '\051', '\104', '\011', '\252', '\276', '\332', '\135',
+    '\065', '\311', '\272', '\116', '\131', '\202', '\162', '\123',
+    '\155', '\265', '\307', '\031', '\116', '\110', '\364', '\173',
+    '\074', '\216', '\240', '\111', '\152', '\253', '\150', '\152',
+    '\254', '\365', '\271', '\275', '\216', '\240', '\044', '\125',
+    '\171', '\352', '\375', '\050', '\276', '\321', '\357', '\163',
+    '\004', '\065', '\251', '\326', '\127', '\345', '\365', '\350',
+    '\115', '\105', '\336', '\206', '\052', '\275', '\252', '\240',
+    '\141', '\347', '\116', '\176', '\112', '\363', '\056', '\107',
+    '\120', '\223', '\174', '\015', '\115', '\115', '\162', '\165',
+    '\010', '\052', '\174', '\236', '\026', '\217', '\257', '\311',
+    '\223', '\030', '\163', '\050', '\324', '\270', '\153', '\175',
+    '\166', '\110', '\022', '\252', '\153', '\335', '\165', '\015',
+    '\365', '\325', '\025', '\122', '\144', '\102', '\114', '\025',
+    '\032', '\374', '\114', '\074', '\202', '\126', '\352', '\315',
+    '\210', '\232', '\167', '\240', '\015', '\062', '\061', '\234',
+    '\021', '\115', '\366', '\271', '\061', '\054', '\136', '\267',
+    '\157', '\227', '\307', '\031', '\166', '\046', '\066', '\325',
+    '\271', '\275', '\136', '\147', '\070', '\236', '\330', '\210',
+    '\111', '\142', '\075', '\057', '\036', '\224', '\044', '\117',
+    '\133', '\125', '\215', '\273', '\036', '\045', '\232', '\200',
+    '\210', '\167', '\172', '\075', '\315', '\076', '\271', '\212',
+    '\140', '\127', '\303', '\016', '\124', '\307', '\147', '\356',
+    '\052', '\154', '\256', '\333', '\321', '\056', '\127', '\021',
+    '\240', '\204', '\352', '\245', '\162', '\265', '\005', '\137',
+    '\221', '\253', '\012', '\074', '\156', '\237', '\137', '\256',
+    '\042', '\250', '\255', '\152', '\250', '\267', '\056', '\032',
+    '\365', '\041', '\044', '\075', '\150', '\007', '\045', '\311',
+    '\232', '\225', '\074', '\005', '\114', '\300', '\041', '\266',
+    '\046', '\133', '\074', '\344', '\110', '\340', '\211', '\146',
+    '\002', '\266', '\170', '\107', '\063', '\246', '\136', '\275',
+    '\043', '\250', '\111', '\336', '\012', '\164', '\001', '\146',
+    '\223', '\011', '\250', '\330', '\147', '\304', '\076', '\247',
+    '\270', '\316', '\135', '\317', '\150', '\244', '\266', '\272',
+    '\332', '\353', '\321', '\162', '\235', '\021', '\115', '\156',
+    '\150', '\306', '\154', '\262', '\256', '\042', '\150', '\364',
+    '\324', '\127', '\325', '\172', '\365', '\246', '\042', '\314',
+    '\167', '\277', '\107', '\157', '\052', '\362', '\066', '\067',
+    '\131', '\027', '\211', '\356', '\156', '\366', '\064', '\371',
+    '\153', '\121', '\246', '\114', '\221', '\304', '\250', '\250',
+    '\310', '\162', '\344', '\136', '\212', '\207', '\234', '\011',
+    '\126', '\077', '\331', '\101', '\147', '\022', '\367', '\124',
+    '\074', '\344', '\110', '\320', '\066', '\071', '\302', '\232',
+    '\350', '\367', '\126', '\170', '\141', '\120', '\342', '\001',
+    '\021', '\067', '\271', '\153', '\275', '\226', '\375', '\061',
+    '\001', '\025', '\357', '\020', '\023', '\046', '\065', '\117',
+    '\210', '\305', '\025', '\152', '\052', '\022', '\126', '\300',
+    '\044', '\111', '\134', '\321', '\032', '\320', '\270', '\222',
+    '\035', '\213', '\053', '\110', '\073', '\342', '\032', '\216',
+    '\150', '\134', '\005', '\266', '\062', '\236', '\156', '\302',
+    '\361', '\304', '\226', '\111', '\065', '\151', '\231', '\252',
+    '\046', '\065', '\350', '\016', '\114', '\013', '\275', '\253',
+    '\260', '\166', '\117', '\155', '\375', '\056', '\275', '\251',
+    '\250', '\021', '\135', '\355', '\323', '\233', '\021', '\371',
+    '\334', '\355', '\125', '\230', '\100', '\046', '\240', '\142',
+    '\277', '\333', '\147', '\135', '\044', '\352', '\347', '\365',
+    '\355', '\327', '\233', '\212', '\144', '\155', '\370', '\035',
+    '\353', '\302', '\337', '\320', '\350', '\354', '\221', '\304',
+    '\150', '\222', '\212', '\332', '\356', '\244', '\270', '\255',
+    '\224', '\140', '\341', '\223', '\005', '\266', '\232', '\065',
+    '\215', '\114', '\300', '\026', '\363', '\024', '\322', '\273',
+    '\012', '\175', '\036', '\271', '\110', '\264', '\331', '\254',
+    '\257', '\346', '\204', '\365', '\005', '\373', '\341', '\363',
+    '\170', '\275', '\356', '\170', '\100', '\305', '\146', '\331',
+    '\065', '\047', '\054', '\273', '\126', '\267', '\277', '\252',
+    '\106', '\256', '\042', '\150', '\303', '\176', '\120', '\047',
+    '\127', '\021', '\320', '\215', '\377', '\217', '\327', '\377',
+    '\001', '\226', '\047', '\030', '\162', '\200', '\067', '\000',
+    '\000',
+
+};
+
+static const char file_6x13[] = {
+    '\037', '\213', '\010', '\010', '\126', '\121', '\054', '\100',
+    '\000', '\003', '\066', '\170', '\061', '\063', '\055', '\111',
+    '\123', '\117', '\070', '\070', '\065', '\071', '\055', '\061',
+    '\056', '\160', '\143', '\146', '\000', '\355', '\234', '\177',
+    '\170', '\024', '\307', '\171', '\307', '\277', '\002', '\001',
+    '\002', '\013', '\020', '\106', '\004', '\141', '\203', '\045',
+    '\333', '\330', '\306', '\066', '\262', '\045', '\014', '\030',
+    '\073', '\330', '\346', '\054', '\035', '\240', '\104', '\110',
+    '\030', '\111', '\061', '\070', '\151', '\345', '\343', '\156',
+    '\045', '\155', '\270', '\037', '\362', '\375', '\300', '\222',
+    '\215', '\101', '\010', '\044', '\204', '\114', '\012', '\051',
+    '\216', '\103', '\034', '\222', '\100', '\203', '\123', '\334',
+    '\342', '\032', '\327', '\264', '\265', '\023', '\307', '\165',
+    '\152', '\047', '\301', '\055', '\165', '\150', '\202', '\133',
+    '\352', '\322', '\230', '\076', '\365', '\037', '\364', '\251',
+    '\363', '\074', '\116', '\037', '\047', '\161', '\373', '\270',
+    '\245', '\337', '\331', '\335', '\071', '\215', '\206', '\335',
+    '\273', '\225', '\340', '\111', '\237', '\247', '\017', '\003',
+    '\237', '\331', '\331', '\335', '\171', '\147', '\346', '\175',
+    '\347', '\335', '\231', '\331', '\071', '\335', '\025', '\264',
+    '\205', '\073', '\047', '\002', '\050', '\040', '\143', '\110',
+    '\007', '\243', '\175', '\116', '\172', '\014', '\057', '\106',
+    '\170', '\304', '\130', '\240', '\120', '\236', '\063', '\021',
+    '\341', '\171', '\221', '\223', '\347', '\154', '\025', '\160',
+    '\174', '\002', '\120', '\242', '\334', '\077', '\274', '\004',
+    '\250', '\160', '\356', '\227', '\060', '\052', '\276', '\007',
+    '\130', '\346', '\234', '\157', '\247', '\354', '\354', '\373',
+    '\200', '\036', '\347', '\174', '\037', '\053', '\077', '\160',
+    '\277', '\335', '\000', '\131', '\337', '\222', '\172', '\373',
+    '\336', '\247', '\140', '\207', '\202', '\053', '\031', '\115',
+    '\027', '\211', '\253', '\141', '\227', '\134', '\060', '\237',
+    '\321', '\002', '\221', '\270', '\227', '\121', '\120', '\044',
+    '\076', '\313', '\150', '\225', '\110', '\174', '\236', '\221',
+    '\051', '\022', '\135', '\214', '\272', '\205', '\374', '\144',
+    '\121', '\257', '\110', '\210', '\053', '\273', '\105', '\102',
+    '\144', '\336', '\057', '\023', '\317', '\211', '\314', '\057',
+    '\062', '\172', '\111', '\134', '\131', '\112', '\176', '\040',
+    '\256', '\374', '\224', '\321', '\273', '\042', '\361', '\357',
+    '\214', '\176', '\041', '\022', '\277', '\141', '\064', '\107',
+    '\030', '\112', '\030', '\154', '\236', '\110', '\214', '\047',
+    '\325', '\114', '\024', '\054', '\146', '\264', '\121', '\134',
+    '\231', '\104', '\236', '\020', '\211', '\166', '\062', '\040',
+    '\363', '\000', '\173', '\231', '\134', '\336', '\330', '\320',
+    '\334', '\020', '\130', '\025', '\154', '\135', '\023', '\134',
+    '\121', '\327', '\324', '\274', '\146', '\235', '\270', '\324',
+    '\322', '\120', '\313', '\304', '\052', '\063', '\025', '\306',
+    '\362', '\300', '\252', '\272', '\372', '\165', '\255', '\042',
+    '\013', '\226', '\233', '\135', '\106', '\004', '\017', '\006',
+    '\353', '\126', '\254', '\154', '\266', '\257', '\254', '\062',
+    '\042', '\146', '\046', '\206', '\246', '\372', '\100', '\103',
+    '\063', '\326', '\240', '\051', '\330', '\374', '\140', '\135',
+    '\155', '\363', '\112', '\373', '\146', '\223', '\021', '\063',
+    '\153', '\022', '\361', '\210', '\021', '\117', '\121', '\054',
+    '\120', '\133', '\333', '\332', '\324', '\274', '\256', '\076',
+    '\150', '\337', '\304', '\352', '\272', '\265', '\301', '\372',
+    '\326', '\246', '\272', '\207', '\202', '\130', '\335', '\130',
+    '\327', '\320', '\154', '\047', '\327', '\004', '\233', '\032',
+    '\353', '\133', '\232', '\353', '\032', '\033', '\132', '\327',
+    '\252', '\047', '\353', '\320', '\264', '\072', '\120', '\123',
+    '\327', '\260', '\002', '\065', '\010', '\174', '\056', '\270',
+    '\046', '\260', '\042', '\330', '\152', '\125', '\205', '\232',
+    '\225', '\201', '\065', '\254', '\167', '\250', '\375', '\165',
+    '\115', '\215', '\113', '\226', '\054', '\272', '\053', '\173',
+    '\043', '\330', '\120', '\323', '\130', '\053', '\044', '\253',
+    '\121', '\323', '\270', '\172', '\335', '\032', '\321', '\172',
+    '\254', '\316', '\254', '\217', '\232', '\341', '\212', '\110',
+    '\042', '\026', '\062', '\343', '\025', '\155', '\211', '\170',
+    '\372', '\266', '\212', '\212', '\246', '\216', '\120', '\322',
+    '\250', '\010', '\305', '\043', '\025', '\106', '\374', '\213',
+    '\211', '\356', '\333', '\120', '\023', '\130', '\335', '\272',
+    '\322', '\122', '\027', '\153', '\145', '\102', '\030', '\014',
+    '\225', '\302', '\066', '\225', '\226', '\075', '\052', '\155',
+    '\033', '\124', '\256', '\251', '\034', '\246', '\157', '\145',
+    '\145', '\365', '\035', '\225', '\325', '\013', '\252', '\052',
+    '\357', '\134', '\044', '\376', '\327', '\124', '\056', '\256',
+    '\252', '\164', '\132', '\126', '\131', '\355', '\330', '\120',
+    '\121', '\020', '\017', '\264', '\004', '\152', '\035', '\215',
+    '\054', '\237', '\053', '\260', '\002', '\160', '\205', '\343',
+    '\223', '\166', '\030', '\317', '\177', '\127', '\070', '\347',
+    '\152', '\132', '\234', '\235', '\077', '\377', '\353', '\363',
+    '\042', '\357', '\360', '\353', '\136', '\101', '\324', '\361',
+    '\036', '\172', '\372', '\373', '\237', '\354', '\275', '\034',
+    '\135', '\216', '\056', '\107', '\227', '\243', '\113', '\033',
+    '\071', '\343', '\326', '\173', '\316', '\170', '\263', '\120',
+    '\314', '\343', '\316', '\014', '\167', '\222', '\024', '\162',
+    '\374', '\131', '\102', '\242', '\344', '\000', '\071', '\105',
+    '\212', '\050', '\260', '\224', '\164', '\222', '\103', '\344',
+    '\264', '\230', '\247', '\071', '\067', '\057', '\043', '\151',
+    '\162', '\230', '\234', '\041', '\045', '\234', '\317', '\153',
+    '\111', '\027', '\071', '\102', '\316', '\222', '\322', '\161',
+    '\300', '\112', '\262', '\211', '\034', '\045', '\357', '\223',
+    '\062', '\116', '\163', '\365', '\244', '\207', '\034', '\043',
+    '\347', '\310', '\154', '\256', '\013', '\126', '\223', '\355',
+    '\344', '\145', '\362', '\001', '\251', '\340', '\302', '\241',
+    '\231', '\014', '\220', '\127', '\311', '\207', '\144', '\056',
+    '\347', '\323', '\265', '\144', '\027', '\171', '\235', '\174',
+    '\104', '\346', '\161', '\042', '\375', '\002', '\331', '\103',
+    '\336', '\044', '\037', '\223', '\371', '\034', '\240', '\037',
+    '\046', '\117', '\221', '\343', '\344', '\023', '\122', '\125',
+    '\314', '\065', '\003', '\331', '\107', '\116', '\024', '\333',
+    '\223', '\375', '\102', '\322', '\101', '\366', '\223', '\223',
+    '\244', '\160', '\012', '\365', '\047', '\121', '\162', '\200',
+    '\234', '\042', '\105', '\123', '\251', '\077', '\351', '\044',
+    '\207', '\310', '\151', '\122', '\314', '\105', '\314', '\062',
+    '\222', '\046', '\207', '\311', '\031', '\122', '\062', '\215',
+    '\372', '\223', '\056', '\162', '\204', '\234', '\045', '\245',
+    '\134', '\217', '\254', '\044', '\233', '\310', '\121', '\362',
+    '\076', '\051', '\343', '\372', '\244', '\236', '\364', '\220',
+    '\143', '\344', '\034', '\231', '\135', '\112', '\375', '\311',
+    '\166', '\362', '\062', '\371', '\200', '\124', '\314', '\240',
+    '\376', '\144', '\200', '\274', '\112', '\076', '\044', '\163',
+    '\271', '\320', '\131', '\113', '\166', '\221', '\327', '\311',
+    '\107', '\144', '\336', '\114', '\352', '\117', '\366', '\220',
+    '\067', '\311', '\307', '\144', '\176', '\031', '\365', '\047',
+    '\117', '\221', '\343', '\344', '\023', '\122', '\065', '\213',
+    '\372', '\223', '\175', '\344', '\004', '\301', '\125', '\324',
+    '\237', '\164', '\220', '\375', '\344', '\044', '\051', '\344',
+    '\262', '\151', '\011', '\211', '\222', '\003', '\344', '\024',
+    '\051', '\232', '\115', '\375', '\111', '\047', '\071', '\104',
+    '\116', '\223', '\342', '\071', '\324', '\237', '\244', '\311',
+    '\141', '\162', '\206', '\224', '\134', '\103', '\375', '\111',
+    '\027', '\071', '\102', '\316', '\222', '\322', '\162', '\352',
+    '\117', '\066', '\221', '\243', '\344', '\175', '\122', '\306',
+    '\145', '\131', '\075', '\351', '\041', '\307', '\310', '\071',
+    '\062', '\373', '\132', '\352', '\117', '\266', '\223', '\227',
+    '\311', '\007', '\244', '\342', '\072', '\352', '\117', '\006',
+    '\310', '\253', '\344', '\103', '\062', '\367', '\172', '\352',
+    '\117', '\166', '\221', '\327', '\311', '\107', '\144', '\336',
+    '\134', '\352', '\117', '\366', '\220', '\067', '\311', '\307',
+    '\144', '\376', '\015', '\324', '\237', '\074', '\105', '\216',
+    '\223', '\117', '\110', '\325', '\215', '\324', '\237', '\354',
+    '\043', '\047', '\010', '\156', '\242', '\376', '\244', '\203',
+    '\354', '\047', '\047', '\111', '\341', '\074', '\352', '\117',
+    '\242', '\344', '\000', '\071', '\105', '\212', '\156', '\246',
+    '\376', '\244', '\223', '\034', '\042', '\247', '\111', '\361',
+    '\055', '\324', '\237', '\244', '\311', '\141', '\162', '\206',
+    '\224', '\334', '\112', '\375', '\111', '\027', '\071', '\102',
+    '\316', '\222', '\122', '\256', '\076', '\127', '\222', '\115',
+    '\344', '\050', '\171', '\237', '\224', '\125', '\002', '\115',
+    '\364', '\307', '\357', '\260', '\357', '\352', '\231', '\336',
+    '\367', '\320', '\320', '\374', '\077', '\303', '\071', '\116',
+    '\363', '\070', '\316', '\200', '\167', '\020', '\353', '\156',
+    '\272', '\053', '\312', '\235', '\143', '\241', '\113', '\036',
+    '\041', '\177', '\313', '\010', '\217', '\062', '\214', '\163',
+    '\230', '\240', '\244', '\351', '\012', '\326', '\372', '\136',
+    '\242', '\007', '\221', '\127', '\254', '\154', '\307', '\072',
+    '\307', '\071', '\116', '\273', '\212', '\235', '\243', '\133',
+    '\033', '\307', '\073', '\171', '\345', '\212', '\130', '\344',
+    '\055', '\125', '\216', '\245', '\056', '\062', '\005', '\012',
+    '\023', '\234', '\166', '\345', '\253', '\107', '\334', '\273',
+    '\322', '\241', '\330', '\345', '\276', '\127', '\220', '\345',
+    '\225', '\153', '\145', '\227', '\173', '\344', '\027', '\257',
+    '\000', '\142', '\275', '\070', '\331', '\111', '\027', '\152',
+    '\314', '\166', '\221', '\031', '\247', '\060', '\306', '\301',
+    '\313', '\326', '\172', '\171', '\222', '\011', '\043', '\320',
+    '\111', '\206', '\011', '\071', '\312', '\363', '\012', '\113',
+    '\163', '\310', '\170', '\261', '\064', '\107', '\171', '\136',
+    '\062', '\367', '\345', '\271', '\167', '\061', '\341', '\377',
+    '\203', '\174', '\056', '\133', '\217', '\264', '\177', '\162',
+    '\371', '\301', '\245', '\354', '\203', '\134', '\355', '\036',
+    '\015', '\152', '\340', '\224', '\227', '\035', '\113', '\306',
+    '\073', '\347', '\042', '\170', '\075', '\247', '\042', '\210',
+    '\161', '\112', '\214', '\005', '\045', '\316', '\161', '\254',
+    '\017', '\031', '\031', '\104', '\236', '\111', '\056', '\344',
+    '\012', '\045', '\030', '\032', '\107', '\312', '\235', '\266',
+    '\272', '\005', '\071', '\126', '\311', '\261', '\140', '\202',
+    '\222', '\026', '\327', '\047', '\373', '\150', '\337', '\110',
+    '\306', '\270', '\221', '\204', '\174', '\375', '\341', '\066',
+    '\166', '\370', '\265', '\217', '\227', '\134', '\271', '\166',
+    '\364', '\052', '\107', '\324', '\315', '\145', '\110', '\166',
+    '\054', '\025', '\363', '\242', '\234', '\103', '\246', '\172',
+    '\264', '\115', '\330', '\163', '\206', '\123', '\146', '\221',
+    '\223', '\147', '\214', '\163', '\056', '\256', '\117', '\364',
+    '\250', '\153', '\014', '\206', '\217', '\331', '\342', '\070',
+    '\313', '\311', '\377', '\051', '\227', '\374', '\176', '\306',
+    '\126', '\065', '\310', '\266', '\310', '\366', '\350', '\310',
+    '\173', '\352', '\334', '\240', '\137', '\327', '\121', '\313',
+    '\323', '\333', '\046', '\164', '\235', '\342', '\034', '\375',
+    '\266', '\121', '\325', '\113', '\237', '\037', '\107', '\032',
+    '\344', '\334', '\235', '\157', '\317', '\304', '\317', '\263',
+    '\231', '\053', '\210', '\072', '\334', '\326', '\113', '\045',
+    '\016', '\252', '\255', '\244', '\255', '\345', '\132', '\303',
+    '\255', '\054', '\341', '\047', '\323', '\134', '\230', '\344',
+    '\122', '\207', '\224', '\021', '\343', '\323', '\070', '\270',
+    '\077', '\103', '\156', '\372', '\115', '\121', '\312', '\225',
+    '\155', '\224', '\355', '\053', '\360', '\220', '\051', '\327',
+    '\362', '\116', '\121', '\164', '\234', '\346', '\234', '\353',
+    '\101', '\352', '\136', '\214', '\241', '\347', '\154', '\242',
+    '\123', '\226', '\327', '\232', '\117', '\216', '\143', '\002',
+    '\061', '\056', '\115', '\367', '\121', '\217', '\324', '\107',
+    '\312', '\115', '\305', '\160', '\333', '\271', '\311', '\250',
+    '\372', '\170', '\075', '\033', '\136', '\365', '\250', '\345',
+    '\346', '\253', '\107', '\317', '\163', '\215', '\017', '\175',
+    '\144', '\160', '\363', '\055', '\057', '\177', '\313', '\165',
+    '\337', '\353', '\131', '\160', '\353', '\173', '\371', '\314',
+    '\027', '\071', '\367', '\163', '\205', '\162', '\217', '\264',
+    '\036', '\334', '\312', '\325', '\353', '\325', '\203', '\227',
+    '\217', '\346', '\232', '\027', '\124', '\031', '\061', '\166',
+    '\316', '\160', '\230', '\354', '\324', '\161', '\215', '\213',
+    '\214', '\333', '\063', '\127', '\256', '\235', '\353', '\101',
+    '\370', '\327', '\225', '\012', '\123', '\264', '\363', '\251',
+    '\071', '\332', '\126', '\340', '\202', '\227', '\037', '\350',
+    '\365', '\350', '\270', '\325', '\243', '\076', '\077', '\362',
+    '\131', '\120', '\317', '\275', '\236', '\355', '\134', '\062',
+    '\271', '\372', '\107', '\315', '\063', '\013', '\271', '\237',
+    '\005', '\175', '\114', '\323', '\355', '\354', '\146', '\153',
+    '\351', '\313', '\136', '\270', '\325', '\243', '\277', '\353',
+    '\250', '\210', '\361', '\147', '\174', '\216', '\266', '\211',
+    '\373', '\142', '\054', '\035', '\353', '\034', '\047', '\346',
+    '\150', '\233', '\133', '\137', '\346', '\263', '\265', '\054',
+    '\113', '\174', '\302', '\044', '\375', '\063', '\237', '\015',
+    '\304', '\265', '\351', '\016', '\122', '\146', '\026', '\206',
+    '\333', '\133', '\017', '\372', '\270', '\243', '\343', '\345',
+    '\157', '\152', '\236', '\221', '\370', '\201', '\033', '\162',
+    '\015', '\240', '\217', '\043', '\156', '\365', '\344', '\263',
+    '\265', '\356', '\157', '\176', '\346', '\037', '\165', '\015',
+    '\341', '\147', '\315', '\217', '\034', '\272', '\214', '\304',
+    '\257', '\325', '\365', '\251', '\337', '\172', '\146', '\150',
+    '\270', '\255', '\111', '\365', '\362', '\013', '\225', '\164',
+    '\056', '\337', '\321', '\145', '\362', '\331', '\300', '\155',
+    '\156', '\124', '\327', '\056', '\272', '\137', '\117', '\201',
+    '\373', '\232', '\122', '\107', '\267', '\235', '\354', '\113',
+    '\165', '\015', '\052', '\353', '\224', '\175', '\253', '\327',
+    '\343', '\365', '\134', '\253', '\350', '\365', '\250', '\143',
+    '\374', '\245', '\014', '\252', '\035', '\364', '\265', '\363',
+    '\150', '\202', '\364', '\151', '\061', '\117', '\311', '\071',
+    '\314', '\155', '\355', '\257', '\217', '\325', '\272', '\057',
+    '\271', '\315', '\013', '\172', '\075', '\352', '\263', '\344',
+    '\345', '\327', '\045', '\012', '\262', '\115', '\372', '\132',
+    '\306', '\117', '\075', '\162', '\176', '\361', '\252', '\107',
+    '\177', '\077', '\235', '\212', '\013', '\175', '\307', '\117',
+    '\075', '\372', '\032', '\113', '\257', '\117', '\265', '\233',
+    '\134', '\133', '\346', '\033', '\173', '\105', '\220', '\317',
+    '\310', '\170', '\370', '\233', '\177', '\104', '\220', '\276',
+    '\120', '\014', '\367', '\071', '\110', '\237', '\207', '\324',
+    '\266', '\171', '\315', '\101', '\172', '\160', '\153', '\217',
+    '\237', '\266', '\311', '\040', '\366', '\025', '\365', '\161',
+    '\047', '\337', '\063', '\062', '\022', '\273', '\311', '\340',
+    '\066', '\107', '\344', '\153', '\133', '\276', '\271', '\310',
+    '\055', '\350', '\076', '\252', '\256', '\265', '\275', '\326',
+    '\262', '\122', '\237', '\174', '\363', '\234', '\233', '\076',
+    '\302', '\376', '\105', '\171', '\364', '\361', '\362', '\151',
+    '\077', '\373', '\306', '\272', '\315', '\274', '\306', '\003',
+    '\057', '\031', '\165', '\314', '\367', '\043', '\223', '\157',
+    '\376', '\321', '\145', '\324', '\371', '\304', '\317', '\370',
+    '\352', '\246', '\113', '\276', '\367', '\040', '\371', '\256',
+    '\230', '\353', '\375', '\264', '\014', '\027', '\372', '\376',
+    '\130', '\227', '\153', '\145', '\232', '\334', '\110', '\367',
+    '\004', '\275', '\312', '\164', '\253', '\133', '\015', '\162',
+    '\117', '\310', '\153', '\357', '\347', '\122', '\005', '\365',
+    '\335', '\310', '\357', '\172', '\107', '\216', '\023', '\242',
+    '\175', '\162', '\377', '\111', '\256', '\333', '\274', '\374',
+    '\346', '\142', '\366', '\023', '\145', '\137', '\113', '\337',
+    '\224', '\317', '\222', '\127', '\136', '\325', '\217', '\325',
+    '\275', '\316', '\134', '\372', '\350', '\372', '\346', '\262',
+    '\201', '\252', '\213', '\376', '\231', '\116', '\011', '\334',
+    '\237', '\323', '\321', '\354', '\075', '\112', '\075', '\205',
+    '\155', '\305', '\332', '\177', '\072', '\206', '\336', '\001',
+    '\162', '\371', '\277', '\276', '\046', '\220', '\163', '\256',
+    '\237', '\175', '\253', '\122', '\247', '\235', '\262', '\137',
+    '\047', '\301', '\375', '\363', '\057', '\267', '\040', '\327',
+    '\200', '\371', '\366', '\000', '\364', '\266', '\346', '\273',
+    '\057', '\164', '\230', '\011', '\133', '\367', '\253', '\225',
+    '\164', '\276', '\061', '\140', '\244', '\341', '\267', '\361',
+    '\371', '\234', '\334', '\247', '\225', '\143', '\223', '\237',
+    '\317', '\314', '\244', '\214', '\134', '\357', '\352', '\143',
+    '\205', '\133', '\220', '\343', '\337', '\305', '\004', '\267',
+    '\271', '\104', '\330', '\136', '\237', '\357', '\256', '\161',
+    '\256', '\253', '\210', '\161', '\272', '\024', '\336', '\237',
+    '\237', '\352', '\341', '\122', '\175', '\126', '\240', '\352',
+    '\055', '\354', '\065', '\026', '\303', '\307', '\034', '\077',
+    '\301', '\153', '\217', '\316', '\217', '\117', '\251', '\317',
+    '\214', '\372', '\054', '\351', '\301', '\255', '\155', '\342',
+    '\271', '\051', '\163', '\344', '\146', '\343', '\302', '\347',
+    '\310', '\115', '\246', '\310', '\311', '\057', '\337', '\275',
+    '\364', '\317', '\166', '\165', '\337', '\021', '\351', '\053',
+    '\363', '\324', '\003', '\134', '\070', '\016', '\312', '\171',
+    '\324', '\153', '\055', '\066', '\106', '\223', '\121', '\337',
+    '\057', '\325', '\075', '\033', '\065', '\024', '\215', '\102',
+    '\106', '\076', '\243', '\043', '\221', '\221', '\375', '\060',
+    '\022', '\231', '\111', '\243', '\220', '\221', '\371', '\364',
+    '\365', '\115', '\056', '\031', '\021', '\256', '\302', '\360',
+    '\317', '\337', '\305', '\134', '\250', '\376', '\315', '\303',
+    '\034', '\027', '\031', '\077', '\173', '\203', '\352', '\376',
+    '\255', '\332', '\077', '\352', '\336', '\235', '\272', '\106',
+    '\326', '\375', '\273', '\150', '\024', '\062', '\152', '\377',
+    '\370', '\225', '\121', '\155', '\355', '\127', '\106', '\325',
+    '\307', '\153', '\277', '\117', '\367', '\321', '\242', '\121',
+    '\310', '\250', '\372', '\370', '\225', '\121', '\365', '\361',
+    '\053', '\003', '\134', '\270', '\167', '\073', '\023', '\271',
+    '\367', '\156', '\125', '\277', '\226', '\276', '\045', '\367',
+    '\373', '\274', '\366', '\371', '\164', '\273', '\371', '\331',
+    '\257', '\322', '\355', '\346', '\107', '\106', '\267', '\233',
+    '\037', '\031', '\125', '\037', '\277', '\062', '\272', '\255',
+    '\375', '\310', '\350', '\101', '\175', '\057', '\361', '\172',
+    '\047', '\051', '\161', '\312', '\221', '\173', '\250', '\352',
+    '\173', '\217', '\334', '\147', '\025', '\367', '\325', '\171',
+    '\121', '\265', '\265', '\133', '\273', '\362', '\331', '\332',
+    '\257', '\214', '\152', '\153', '\277', '\062', '\252', '\335',
+    '\056', '\246', '\155', '\156', '\373', '\203', '\172', '\160',
+    '\333', '\163', '\312', '\367', '\156', '\056', '\336', '\223',
+    '\345', '\236', '\207', '\034', '\007', '\325', '\275', '\136',
+    '\267', '\367', '\005', '\335', '\267', '\375', '\354', '\213',
+    '\351', '\276', '\355', '\107', '\106', '\367', '\155', '\077',
+    '\062', '\272', '\157', '\373', '\221', '\321', '\175', '\073',
+    '\237', '\214', '\154', '\127', '\361', '\010', '\144', '\364',
+    '\040', '\377', '\136', '\101', '\034', '\345', '\173', '\135',
+    '\276', '\367', '\026', '\257', '\275', '\101', '\165', '\376',
+    '\001', '\334', '\307', '\236', '\174', '\373', '\174', '\156',
+    '\143', '\217', '\337', '\275', '\301', '\221', '\310', '\270',
+    '\215', '\043', '\371', '\144', '\124', '\175', '\374', '\356',
+    '\363', '\025', '\215', '\102', '\106', '\325', '\307', '\257',
+    '\214', '\252', '\217', '\037', '\031', '\371', '\034', '\313',
+    '\375', '\051', '\277', '\373', '\157', '\252', '\137', '\373',
+    '\335', '\347', '\313', '\067', '\007', '\371', '\365', '\203',
+    '\174', '\062', '\371', '\346', '\240', '\174', '\372', '\370',
+    '\225', '\311', '\067', '\007', '\171', '\315', '\077', '\156',
+    '\357', '\212', '\136', '\143', '\250', '\032', '\324', '\271',
+    '\110', '\235', '\203', '\364', '\371', '\107', '\204', '\134',
+    '\163', '\220', '\237', '\061', '\321', '\257', '\114', '\256',
+    '\071', '\310', '\317', '\370', '\166', '\261', '\155', '\313',
+    '\267', '\067', '\350', '\265', '\207', '\077', '\035', '\103',
+    '\237', '\365', '\253', '\266', '\363', '\152', '\233', '\133',
+    '\075', '\316', '\167', '\250', '\372', '\372', '\167', '\366',
+    '\060', '\332', '\261', '\331', '\376', '\362', '\203', '\163',
+    '\252', '\106', '\133', '\031', '\075', '\316', '\324', '\300',
+    '\026', '\345', '\306', '\266', '\376', '\047', '\067', '\061',
+    '\352', '\353', '\355', '\355', '\267', '\043', '\236', '\312',
+    '\157', '\117', '\154', '\144', '\064', '\320', '\315', '\250',
+    '\117', '\134', '\353', '\335', '\302', '\150', '\213', '\225',
+    '\245', '\127', '\210', '\131', '\131', '\304', '\015', '\212',
+    '\155', '\263', '\253', '\264', '\112', '\266', '\242', '\176',
+    '\121', '\174', '\277', '\135', '\121', '\357', '\166', '\121',
+    '\100', '\017', '\057', '\061', '\037', '\233', '\261', '\275',
+    '\177', '\347', '\143', '\172', '\063', '\170', '\152', '\335',
+    '\175', '\214', '\167', '\007', '\267', '\132', '\221', '\270',
+    '\261', '\311', '\322', '\210', '\247', '\275', '\342', '\264',
+    '\157', '\223', '\114', '\135', '\240', '\233', '\217', '\210',
+    '\262', '\073', '\266', '\132', '\221', '\274', '\326', '\277',
+    '\171', '\364', '\105', '\371', '\316', '\074', '\262', '\346',
+    '\146', '\065', '\037', '\112', '\011', '\133', '\365', '\154',
+    '\245', '\021', '\007', '\273', '\244', '\141', '\355', '\326',
+    '\273', '\245', '\172', '\245', '\354', '\100', '\117', '\017',
+    '\243', '\336', '\141', '\315', '\355', '\327', '\242', '\336',
+    '\154', '\224', '\275', '\066', '\340', '\226', '\257', '\147',
+    '\130', '\276', '\301', '\255', '\126', '\067', '\132', '\051',
+    '\273', '\175', '\331', '\256', '\025', '\247', '\331', '\136',
+    '\335', '\341', '\364', '\376', '\066', '\333', '\365', '\006',
+    '\055', '\215', '\204', '\012', '\203', '\326', '\215', '\315',
+    '\062', '\113', '\237', '\350', '\337', '\276', '\115', '\331',
+    '\033', '\135', '\212', '\237', '\156', '\353', '\037', '\174',
+    '\334', '\212', '\262', '\352', '\367', '\016', '\271', '\024',
+    '\243', '\236', '\136', '\073', '\213', '\132', '\336', '\140',
+    '\317', '\260', '\150', '\147', '\317', '\205', '\327', '\334',
+    '\262', '\354', '\354', '\165', '\273', '\053', '\332', '\354',
+    '\104', '\331', '\123', '\177', '\205', '\132', '\316', '\157',
+    '\131', '\050', '\117', '\275', '\071', '\243', '\301', '\341',
+    '\035', '\340', '\356', '\211', '\166', '\244', '\366', '\264',
+    '\217', '\342', '\255', '\307', '\157', '\207', '\247', '\167',
+    '\132', '\217', '\263', '\125', '\245', '\374', '\016', '\025',
+    '\160', '\136', '\031', '\317', '\306', '\140', '\054', '\107',
+    '\302', '\161', '\234', '\261', '\047', '\160', '\124', '\234',
+    '\310', '\321', '\352', '\012', '\216', '\302', '\223', '\071',
+    '\042', '\115', '\345', '\350', '\064', '\215', '\243', '\361',
+    '\164', '\316', '\146', '\063', '\070', '\132', '\315', '\104',
+    '\031', '\307', '\255', '\253', '\160', '\065', '\146', '\143',
+    '\016', '\127', '\203', '\345', '\250', '\300', '\265', '\270',
+    '\016', '\327', '\143', '\056', '\156', '\300', '\215', '\270',
+    '\011', '\363', '\160', '\063', '\156', '\301', '\255', '\230',
+    '\217', '\112', '\334', '\206', '\333', '\121', '\205', '\152',
+    '\054', '\300', '\035', '\130', '\210', '\105', '\130', '\214',
+    '\073', '\261', '\004', '\167', '\341', '\156', '\174', '\032',
+    '\113', '\161', '\017', '\356', '\305', '\175', '\130', '\206',
+    '\000', '\356', '\107', '\015', '\152', '\021', '\304', '\162',
+    '\254', '\300', '\112', '\324', '\341', '\063', '\370', '\054',
+    '\352', '\261', '\012', '\015', '\150', '\304', '\152', '\074',
+    '\040', '\276', '\006', '\214', '\146', '\264', '\340', '\163',
+    '\170', '\020', '\153', '\261', '\016', '\017', '\341', '\363',
+    '\370', '\002', '\176', '\007', '\277', '\213', '\126', '\074',
+    '\214', '\020', '\326', '\043', '\214', '\010', '\014', '\264',
+    '\241', '\035', '\035', '\060', '\361', '\105', '\154', '\100',
+    '\024', '\061', '\304', '\221', '\100', '\047', '\036', '\101',
+    '\022', '\051', '\244', '\221', '\301', '\106', '\074', '\212',
+    '\056', '\164', '\343', '\061', '\074', '\216', '\115', '\170',
+    '\002', '\233', '\161', '\376', '\242', '\303', '\026', '\364',
+    '\140', '\053', '\172', '\261', '\015', '\333', '\321', '\207',
+    '\176', '\354', '\300', '\000', '\166', '\142', '\020', '\117',
+    '\142', '\027', '\276', '\204', '\337', '\303', '\156', '\354',
+    '\301', '\227', '\361', '\373', '\330', '\213', '\247', '\360',
+    '\025', '\074', '\215', '\257', '\142', '\037', '\276', '\206',
+    '\147', '\360', '\165', '\354', '\307', '\067', '\360', '\115',
+    '\174', '\013', '\007', '\160', '\020', '\177', '\200', '\157',
+    '\343', '\020', '\236', '\305', '\167', '\360', '\207', '\070',
+    '\214', '\347', '\360', '\107', '\370', '\143', '\034', '\301',
+    '\363', '\370', '\023', '\274', '\200', '\243', '\170', '\021',
+    '\177', '\212', '\227', '\160', '\014', '\177', '\206', '\077',
+    '\307', '\137', '\340', '\145', '\274', '\202', '\357', '\342',
+    '\173', '\170', '\025', '\337', '\307', '\153', '\370', '\113',
+    '\274', '\216', '\037', '\340', '\257', '\360', '\006', '\336',
+    '\304', '\017', '\361', '\043', '\374', '\030', '\307', '\361',
+    '\026', '\376', '\032', '\177', '\203', '\023', '\370', '\133',
+    '\274', '\215', '\237', '\340', '\044', '\376', '\016', '\077',
+    '\305', '\317', '\160', '\012', '\357', '\340', '\357', '\361',
+    '\017', '\070', '\215', '\177', '\304', '\273', '\370', '\047',
+    '\234', '\301', '\077', '\343', '\347', '\030', '\372', '\116',
+    '\335', '\331', '\202', '\313', '\134', '\346', '\062', '\377',
+    '\027', '\250', '\337', '\153', '\225', '\337', '\025', '\023',
+    '\173', '\271', '\327', '\301', '\376', '\056', '\233', '\370',
+    '\021', '\210', '\273', '\111', '\000', '\366', '\217', '\071',
+    '\064', '\021', '\361', '\013', '\020', '\021', '\022', '\043',
+    '\033', '\311', '\026', '\062', '\100', '\366', '\300', '\376',
+    '\155', '\213', '\203', '\260', '\177', '\364', '\341', '\105',
+    '\362', '\135', '\362', '\006', '\071', '\101', '\336', '\041',
+    '\342', '\271', '\077', '\107', '\176', '\105', '\076', '\026',
+    '\163', '\000', '\333', '\060', '\211', '\314', '\042', '\345',
+    '\344', '\106', '\162', '\073', '\271', '\233', '\004', '\110',
+    '\035', '\151', '\042', '\255', '\304', '\044', '\351', '\002',
+    '\373', '\367', '\037', '\172', '\013', '\354', '\237', '\177',
+    '\330', '\115', '\236', '\046', '\373', '\311', '\101', '\362',
+    '\054', '\171', '\216', '\274', '\100', '\216', '\221', '\127',
+    '\310', '\367', '\311', '\033', '\344', '\055', '\362', '\166',
+    '\201', '\375', '\375', '\334', '\237', '\223', '\177', '\045',
+    '\377', '\106', '\176', '\111', '\376', '\213', '\374', '\067',
+    '\071', '\117', '\012', '\150', '\224', '\261', '\144', '\034',
+    '\231', '\100', '\046', '\222', '\053', '\310', '\144', '\062',
+    '\225', '\114', '\043', '\323', '\311', '\014', '\062', '\223',
+    '\314', '\042', '\127', '\223', '\071', '\244', '\234', '\134',
+    '\113', '\256', '\047', '\067', '\220', '\233', '\310', '\315',
+    '\344', '\126', '\122', '\111', '\156', '\047', '\325', '\344',
+    '\036', '\262', '\202', '\064', '\223', '\207', '\311', '\006',
+    '\362', '\010', '\111', '\221', '\014', '\171', '\224', '\164',
+    '\223', '\307', '\311', '\023', '\144', '\013', '\331', '\112',
+    '\266', '\221', '\076', '\262', '\203', '\354', '\044', '\117',
+    '\222', '\057', '\221', '\335', '\344', '\313', '\144', '\057',
+    '\371', '\012', '\371', '\052', '\371', '\032', '\371', '\072',
+    '\371', '\006', '\371', '\026', '\071', '\110', '\276', '\115',
+    '\236', '\045', '\057', '\220', '\227', '\310', '\153', '\344',
+    '\055', '\362', '\023', '\362', '\056', '\171', '\217', '\234',
+    '\043', '\277', '\044', '\277', '\042', '\347', '\205', '\015',
+    '\304', '\367', '\224', '\311', '\125', '\344', '\106', '\262',
+    '\220', '\334', '\107', '\226', '\223', '\007', '\310', '\132',
+    '\322', '\112', '\114', '\222', '\041', '\333', '\310', '\116',
+    '\262', '\213', '\074', '\115', '\236', '\045', '\317', '\223',
+    '\127', '\310', '\217', '\310', '\073', '\344', '\054', '\071',
+    '\107', '\176', '\115', '\306', '\362', '\145', '\150', '\022',
+    '\231', '\106', '\346', '\220', '\271', '\344', '\066', '\262',
+    '\220', '\334', '\111', '\226', '\221', '\025', '\244', '\201',
+    '\074', '\124', '\150', '\377', '\006', '\312', '\006', '\222',
+    '\044', '\233', '\311', '\000', '\331', '\105', '\366', '\222',
+    '\147', '\310', '\101', '\362', '\074', '\071', '\106', '\136',
+    '\043', '\077', '\046', '\157', '\223', '\167', '\310', '\031',
+    '\162', '\216', '\374', '\007', '\371', '\117', '\162', '\136',
+    '\324', '\075', '\216', '\165', '\213', '\357', '\130', '\223',
+    '\271', '\344', '\126', '\262', '\210', '\174', '\232', '\334',
+    '\113', '\126', '\220', '\006', '\322', '\102', '\102', '\144',
+    '\003', '\111', '\222', '\156', '\322', '\107', '\166', '\223',
+    '\275', '\344', '\031', '\162', '\220', '\034', '\046', '\307',
+    '\310', '\367', '\310', '\017', '\311', '\011', '\362', '\063',
+    '\362', '\056', '\371', '\027', '\362', '\013', '\362', '\033',
+    '\362', '\077', '\244', '\160', '\074', '\337', '\277', '\110',
+    '\304', '\150', '\013', '\145', '\242', '\351', '\160', '\107',
+    '\050', '\211', '\114', '\334', '\134', '\260', '\250', '\146',
+    '\061', '\122', '\035', '\241', '\210', '\141', '\235', '\055',
+    '\254', '\272', '\313', '\071', '\326', '\070', '\307', '\132',
+    '\347', '\030', '\240', '\144', '\173', '\322', '\060', '\320',
+    '\031', '\315', '\244', '\142', '\146', '\074', '\223', '\262',
+    '\157', '\054', '\130', '\350', '\144', '\270', '\037', '\115',
+    '\313', '\253', '\026', '\126', '\061', '\210', '\304', '\035',
+    '\062', '\121', '\055', '\023', '\013', '\144', '\142', '\221',
+    '\225', '\020', '\102', '\167', '\334', '\037', '\160', '\216',
+    '\102', '\330', '\312', '\051', '\157', '\324', '\070', '\307',
+    '\132', '\041', '\261', '\104', '\212', '\336', '\045', '\023',
+    '\167', '\312', '\304', '\142', '\047', '\121', '\155', '\327',
+    '\023', '\065', '\122', '\051', '\343', '\221', '\114', '\050',
+    '\012', '\266', '\065', '\224', '\066', '\222', '\366', '\111',
+    '\247', '\211', '\170', '\042', '\155', '\247', '\123', '\274',
+    '\032', '\065', '\343', '\355', '\350', '\064', '\222', '\146',
+    '\042', '\022', '\066', '\342', '\042', '\133', '\004', '\251',
+    '\316', '\120', '\330', '\200', '\321', '\025', '\216', '\206',
+    '\142', '\170', '\044', '\303', '\354', '\221', '\365', '\121',
+    '\304', '\063', '\261', '\365', '\106', '\062', '\145', '\266',
+    '\307', '\021', '\111', '\104', '\243', '\064', '\032', '\305',
+    '\204', '\014', '\102', '\061', '\246', '\122', '\241', '\170',
+    '\304', '\316', '\234', '\142', '\221', '\121', '\132', '\047',
+    '\224', '\064', '\342', '\121', '\243', '\055', '\155', '\247',
+    '\222', '\146', '\173', '\007', '\263', '\212', '\072', '\315',
+    '\324', '\006', '\313', '\166', '\010', '\047', '\142', '\261',
+    '\020', '\072', '\272', '\073', '\073', '\214', '\270', '\323',
+    '\010', '\244', '\242', '\241', '\124', '\007', '\036', '\063',
+    '\222', '\011', '\044', '\342', '\006', '\322', '\217', '\046',
+    '\220', '\356', '\020', '\326', '\156', '\113', '\144', '\222',
+    '\150', '\063', '\067', '\032', '\110', '\231', '\135', '\110',
+    '\031', '\033', '\051', '\143', '\130', '\205', '\306', '\115',
+    '\146', '\014', '\047', '\242', '\211', '\070', '\057', '\307',
+    '\114', '\073', '\045', '\364', '\307', '\060', '\003', '\260',
+    '\165', '\106', '\052', '\155', '\362', '\136', '\050', '\075',
+    '\252', '\205', '\350', '\372', '\144', '\050', '\274', '\301',
+    '\110', '\133', '\072', '\255', '\147', '\322', '\156', '\252',
+    '\163', '\125', '\352', '\027', '\066', '\315', '\260', '\231',
+    '\014', '\147', '\142', '\354', '\266', '\010', '\315', '\022',
+    '\116', '\044', '\015', '\266', '\040', '\304', '\166', '\217',
+    '\146', '\361', '\052', '\112', '\067', '\234', '\032', '\223',
+    '\366', '\231', '\122', '\123', '\332', '\214', '\322', '\135',
+    '\325', '\376', '\212', '\044', '\036', '\215', '\303', '\352',
+    '\225', '\154', '\357', '\206', '\063', '\111', '\332', '\077',
+    '\334', '\215', '\156', '\132', '\154', '\175', '\062', '\261',
+    '\301', '\210', '\213', '\262', '\122', '\106', '\330', '\062',
+    '\106', '\304', '\144', '\247', '\247', '\114', '\321', '\033',
+    '\235', '\335', '\166', '\331', '\211', '\144', '\244', '\215',
+    '\206', '\264', '\354', '\332', '\236', '\061', '\243', '\121',
+    '\043', '\226', '\260', '\325', '\216', '\046', '\332', '\315',
+    '\160', '\050', '\112', '\027', '\222', '\335', '\226', '\064',
+    '\332', '\315', '\224', '\355', '\067', '\261', '\120', '\070',
+    '\051', '\012', '\324', '\237', '\016', '\366', '\141', '\052',
+    '\143', '\165', '\157', '\322', '\356', '\313', '\354', '\131',
+    '\050', '\234', '\111', '\033', '\210', '\145', '\204', '\213',
+    '\204', '\150', '\244', '\316', '\016', '\335', '\027', '\303',
+    '\106', '\204', '\365', '\207', '\204', '\057', '\144', '\245',
+    '\330', '\274', '\030', '\325', '\317', '\104', '\207', '\265',
+    '\317', '\151', '\172', '\134', '\364', '\171', '\122', '\164',
+    '\067', '\223', '\035', '\241', '\150', '\233', '\135', '\245',
+    '\163', '\061', '\225', '\165', '\002', '\313', '\120', '\001',
+    '\273', '\143', '\002', '\166', '\073', '\002', '\166', '\307',
+    '\265', '\105', '\215', '\056', '\004', '\154', '\323', '\006',
+    '\262', '\326', '\011', '\044', '\205', '\055', '\003', '\101',
+    '\324', '\310', '\046', '\005', '\155', '\341', '\240', '\055',
+    '\034', '\124', '\204', '\203', '\131', '\251', '\072', '\073',
+    '\117', '\235', '\235', '\247', '\116', '\311', '\123', '\227',
+    '\315', '\023', '\114', '\167', '\240', '\301', '\256', '\256',
+    '\321', '\316', '\336', '\150', '\147', '\157', '\124', '\262',
+    '\067', '\072', '\031', '\262', '\122', '\061', '\016', '\135',
+    '\146', '\147', '\264', '\033', '\215', '\266', '\033', '\266',
+    '\330', '\242', '\055', '\266', '\150', '\213', '\042', '\332',
+    '\222', '\225', '\131', '\147', '\337', '\154', '\356', '\110',
+    '\044', '\343', '\150', '\067', '\222', '\061', '\076', '\263',
+    '\353', '\243', '\051', '\204', '\034', '\377', '\264', '\157',
+    '\207', '\024', '\331', '\220', '\135', '\155', '\050', '\133',
+    '\104', '\310', '\062', '\103', '\210', '\317', '\233', '\064',
+    '\203', '\141', '\013', '\033', '\266', '\260', '\241', '\010',
+    '\033', '\131', '\051', '\323', '\316', '\143', '\332', '\171',
+    '\114', '\045', '\217', '\231', '\315', '\143', '\320', '\014',
+    '\161', '\273', '\272', '\204', '\235', '\075', '\141', '\147',
+    '\117', '\050', '\331', '\023', '\116', '\206', '\254', '\124',
+    '\304', '\334', '\150', '\212', '\013', '\266', '\021', '\062',
+    '\266', '\140', '\306', '\026', '\314', '\050', '\202', '\231',
+    '\254', '\104', '\267', '\175', '\063', '\155', '\031', '\241',
+    '\073', '\173', '\371', '\322', '\375', '\156', '\322', '\377',
+    '\002', '\174', '\155', '\142', '\140', '\200', '\114', '\000',
+    '\000',
+
+};
+
+static char name_6x13[] = "-misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso8859-1";
+static char name_cursor[] = "cursor";
+
+const BuiltinFileRec builtin_files[] = {
+ { "6x13.builtin", sizeof file_6x13, file_6x13, },
+ { "cursor.builtin", sizeof file_cursor, file_cursor, }
+};
+
+const int builtin_files_count = sizeof (builtin_files) / sizeof (builtin_files[0]);
+
+const BuiltinDirRec builtin_dir[] = {
+ { "6x13.builtin", name_6x13, },
+ { "cursor.builtin", name_cursor, }
+};
+
+const int builtin_dir_count = sizeof (builtin_dir) / sizeof (builtin_dir[0]);
+
+static char alias_fixed[] = "fixed";
+static char alias_6x13[] = "6x13";
+static char alias_6x13_100[] = "-misc-fixed-medium-r-semicondensed--13-100-100-100-c-60-iso8859-1";
+
+const BuiltinAliasRec builtin_alias[] = {
+ { alias_fixed, name_6x13, },
+ { alias_6x13, name_6x13, },
+ { alias_6x13_100, name_6x13, }
+};
+
+const int builtin_alias_count = sizeof (builtin_alias) / sizeof (builtin_alias[0]);
diff --git a/src/builtins/fpe.c b/src/builtins/fpe.c
new file mode 100755 (executable)
index 0000000..403dbb7
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright 1999 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author:  Keith Packard, SuSE, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include    <X11/fonts/fntfilst.h>
+#include "builtin.h"
+
+static int  font_file_type;
+
+static const char builtin_fonts[] = "built-ins";
+
+static int
+BuiltinNameCheck (char *name)
+{
+    return (strcmp (name, builtin_fonts) == 0);
+}
+
+static int
+BuiltinInitFPE (FontPathElementPtr fpe)
+{
+    int                        status;
+    FontDirectoryPtr   dir;
+
+    status = BuiltinReadDirectory (fpe->name, &dir);
+
+    if (status == Successful)
+       fpe->private = (pointer) dir;
+    return status;
+}
+
+/* ARGSUSED */
+static int
+BuiltinResetFPE (FontPathElementPtr fpe)
+{
+    FontDirectoryPtr   dir;
+
+    dir = (FontDirectoryPtr) fpe->private;
+    /* builtins can't change! */
+    return Successful;
+}
+
+static int
+BuiltinFreeFPE (FontPathElementPtr fpe)
+{
+    FontFileFreeDir ((FontDirectoryPtr) fpe->private);
+    return Successful;
+}
+
+void
+BuiltinRegisterFpeFunctions(void)
+{
+    BuiltinRegisterFontFileFunctions ();
+
+    font_file_type = RegisterFPEFunctions(BuiltinNameCheck,
+                                         BuiltinInitFPE,
+                                         BuiltinFreeFPE,
+                                         BuiltinResetFPE,
+                                         FontFileOpenFont,
+                                         FontFileCloseFont,
+                                         FontFileListFonts,
+                                         FontFileStartListFontsWithInfo,
+                                         FontFileListNextFontWithInfo,
+                                         (WakeupFpeFunc) 0,
+                                         (ClientDiedFunc) 0,
+                                         (LoadGlyphsFunc) 0,
+                                         (StartLaFunc) 0,
+                                         (NextLaFunc) 0,
+                                         (SetPathFunc) 0);
+}
diff --git a/src/builtins/render.c b/src/builtins/render.c
new file mode 100755 (executable)
index 0000000..4d10483
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Copyright 1999 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author:  Keith Packard, SuSE, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include    <X11/fonts/fntfilst.h>
+#include    <X11/fonts/fontutil.h>
+#include    <X11/fonts/pcf.h>
+#include    "builtin.h"
+
+static int
+BuiltinOpenBitmap (FontPathElementPtr fpe, FontPtr *ppFont, int        flags,
+                  FontEntryPtr entry, char *fileName, fsBitmapFormat format,
+                  fsBitmapFormatMask fmask, FontPtr unused)
+{
+    FontFilePtr        file;
+    FontPtr     pFont;
+    int         ret;
+    int         bit,
+                byte,
+                glyph,
+                scan,
+               image;
+
+    file = BuiltinFileOpen (fileName);
+    if (!file)
+       return BadFontName;
+    pFont = malloc(sizeof(FontRec));
+    if (!pFont) {
+       BuiltinFileClose (file, 0);
+       return AllocError;
+    }
+    /* set up default values */
+    FontDefaultFormat(&bit, &byte, &glyph, &scan);
+    /* get any changes made from above */
+    ret = CheckFSFormat(format, fmask, &bit, &byte, &scan, &glyph, &image);
+
+    /* Fill in font record. Data format filled in by reader. */
+    pFont->refcnt = 0;
+    pFont->maxPrivate = -1;
+    pFont->devPrivates = (pointer *) 0;
+
+    ret = pcfReadFont (pFont, file, bit, byte, glyph, scan);
+
+    BuiltinFileClose (file, 0);
+    if (ret != Successful)
+       free(pFont);
+    else
+       *ppFont = pFont;
+    return ret;
+}
+
+static int
+BuiltinGetInfoBitmap (FontPathElementPtr fpe, FontInfoPtr pFontInfo,
+                     FontEntryPtr entry, char *fileName)
+{
+    FontFilePtr file;
+    int                ret;
+
+    file = BuiltinFileOpen (fileName);
+    if (!file)
+       return BadFontName;
+    ret = pcfReadFontInfo (pFontInfo, file);
+    BuiltinFileClose (file, 0);
+    return ret;
+}
+
+static int
+BuiltinOpenScalable (FontPathElementPtr fpe,
+                    FontPtr *pFont,
+                    int flags,
+                    FontEntryPtr entry,
+                    char *fileName,
+                    FontScalablePtr vals,
+                    fsBitmapFormat format,
+                    fsBitmapFormatMask fmask,
+                    FontPtr non_cachable_font) /* We don't do licensing */
+{
+    return BadFontName;
+}
+
+static int
+BuiltinGetInfoScalable (FontPathElementPtr fpe,
+                       FontInfoPtr pFontInfo,
+                       FontEntryPtr entry,
+                       FontNamePtr fontName,
+                       char *fileName,
+                       FontScalablePtr vals)
+{
+    return BadFontName;
+}
+
+static FontRendererRec renderers[] = {
+    { ".builtin", 8,
+    BuiltinOpenBitmap,
+    BuiltinOpenScalable,
+    BuiltinGetInfoBitmap,
+    BuiltinGetInfoScalable,
+    0 }
+};
+
+#define numRenderers   (sizeof renderers / sizeof renderers[0])
+
+void
+BuiltinRegisterFontFileFunctions(void)
+{
+    int        i;
+    for (i = 0; i < numRenderers; i++)
+       FontFileRegisterRenderer ((FontRendererRec *) &renderers[i]);
+}
+
diff --git a/src/dummy.c b/src/dummy.c
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/fc/Makefile.am b/src/fc/Makefile.am
new file mode 100644 (file)
index 0000000..3bfd231
--- /dev/null
@@ -0,0 +1,16 @@
+INCLUDES =                      \
+       -I${top_srcdir}/include
+
+AM_CFLAGS = $(XFONT_CFLAGS) $(OS_CFLAGS) $(CWARNFLAGS)
+
+noinst_LTLIBRARIES = libfc.la
+
+libfc_la_SOURCES =             \
+       fsconvert.c             \
+       fserve.c                \
+       fserve.h                \
+       fservestr.h             \
+       fsio.c                  \
+       fsio.h                  \
+       fslibos.h               \
+       fstrans.c
diff --git a/src/fc/fsconvert.c b/src/fc/fsconvert.c
new file mode 100755 (executable)
index 0000000..15c5e42
--- /dev/null
@@ -0,0 +1,719 @@
+/*
+ * Copyright 1990 Network Computing Devices
+ *
+ * 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 Network Computing Devices not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.  Network Computing Devices
+ * makes no representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+ * IN NO EVENT SHALL NETWORK COMPUTING DEVICES 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.
+ *
+ * Author:     Dave Lemke, Network Computing Devices, Inc
+ */
+/*
+ * FS data conversion
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include        <X11/X.h>
+#include       <X11/Xtrans/Xtrans.h>
+#include       <X11/Xpoll.h>
+#include       <X11/fonts/FS.h>
+#include       <X11/fonts/FSproto.h>
+#include       <X11/fonts/fontmisc.h>
+#include       <X11/fonts/fontstruct.h>
+#include       "fservestr.h"
+#include       <X11/fonts/fontutil.h>
+#include       "fslibos.h"
+
+extern char _fs_glyph_undefined;
+extern char _fs_glyph_requested;
+
+/*
+ * converts data from font server form to X server form
+ */
+
+void
+_fs_convert_char_info(fsXCharInfo *src, xCharInfo *dst)
+{
+    dst->ascent = src->ascent;
+    dst->descent = src->descent;
+    dst->leftSideBearing = src->left;
+    dst->rightSideBearing = src->right;
+    dst->characterWidth = src->width;
+    dst->attributes = src->attributes;
+}
+
+void
+_fs_init_fontinfo(FSFpePtr conn, FontInfoPtr pfi)
+{
+    if (conn->fsMajorVersion == 1) {
+       unsigned short n;
+       n = pfi->firstCol;
+       pfi->firstCol = pfi->firstRow;
+       pfi->firstRow = n;
+       n = pfi->lastCol;
+       pfi->lastCol = pfi->lastRow;
+       pfi->lastRow = n;
+       pfi->defaultCh = ((pfi->defaultCh >> 8) & 0xff)
+                          + ((pfi->defaultCh & 0xff) << 8);
+    }
+
+    if (FontCouldBeTerminal (pfi))
+    {
+       pfi->terminalFont = TRUE;
+       pfi->minbounds.ascent = pfi->fontAscent;
+       pfi->minbounds.descent = pfi->fontDescent;
+       pfi->minbounds.leftSideBearing = 0;
+       pfi->minbounds.rightSideBearing = pfi->minbounds.characterWidth;
+       pfi->maxbounds = pfi->minbounds;
+    }
+
+    FontComputeInfoAccelerators (pfi);
+}
+
+int
+_fs_convert_props(fsPropInfo *pi, fsPropOffset *po, pointer pd, 
+                 FontInfoPtr pfi)
+{
+    FontPropPtr dprop;
+    int         i,
+                nprops;
+    char       *is_str;
+    fsPropOffset local_off;
+    char *off_adr;
+    char *pdc = pd;
+
+/* stolen from server/include/resource.h */
+#define BAD_RESOURCE 0xe0000000
+
+    nprops = pfi->nprops = pi->num_offsets;
+
+    if (nprops < 0 
+       || nprops > SIZE_MAX/(sizeof(FontPropRec) + sizeof(char))) 
+       return -1;
+          
+    dprop = malloc(sizeof(FontPropRec) * nprops + sizeof (char) * nprops);
+    if (!dprop)
+       return -1;
+    
+    is_str = (char *) (dprop + nprops);
+    pfi->props = dprop;
+    pfi->isStringProp = is_str;
+
+    off_adr = (char *)po;
+    for (i = 0; i < nprops; i++, dprop++, is_str++) 
+    {
+       memcpy(&local_off, off_adr, SIZEOF(fsPropOffset));
+       dprop->name = MakeAtom(&pdc[local_off.name.position],
+                              local_off.name.length, 1);
+       if (local_off.type != PropTypeString) {
+           *is_str = FALSE;
+           dprop->value = local_off.value.position;
+       } else {
+           *is_str = TRUE;
+           dprop->value = (INT32) MakeAtom(&pdc[local_off.value.position],
+                                           local_off.value.length, 1);
+           if (dprop->value == BAD_RESOURCE)
+           {
+               free (pfi->props);
+               pfi->nprops = 0;
+               pfi->props = 0;
+               pfi->isStringProp = 0;
+               return -1;
+           }
+       }
+       off_adr += SIZEOF(fsPropOffset);
+    }
+
+    return nprops;
+}
+
+void
+_fs_free_props (FontInfoPtr pfi)
+{
+    if (pfi->props)
+    {
+       free (pfi->props);
+       pfi->nprops = 0;
+       pfi->props = 0;
+    }
+}
+
+int
+_fs_convert_lfwi_reply(FSFpePtr conn, FontInfoPtr pfi, 
+                      fsListFontsWithXInfoReply *fsrep, 
+                      fsPropInfo *pi, fsPropOffset *po, pointer pd)
+{
+    fsUnpack_XFontInfoHeader(fsrep, pfi);
+    _fs_init_fontinfo(conn, pfi);
+
+    if (_fs_convert_props(pi, po, pd, pfi) == -1)
+       return AllocError;
+
+    return Successful;
+}
+
+
+#define ENCODING_UNDEFINED(enc) \
+       ((enc)->bits == &_fs_glyph_undefined ? \
+        TRUE : \
+        (access_done = access_done && (enc)->bits != &_fs_glyph_requested, \
+         FALSE))
+
+#define GLYPH_UNDEFINED(loc) ENCODING_UNDEFINED(encoding + (loc))
+
+/*
+ * figures out what glyphs to request
+ *
+ * Includes logic to attempt to reduce number of round trips to the font
+ * server:  when a glyph is requested, fs_build_range() requests a
+ * 16-glyph range of glyphs that contains the requested glyph.  This is
+ * predicated on the belief that using a glyph increases the chances
+ * that nearby glyphs will be used: a good assumption for phonetic
+ * alphabets, but a questionable one for ideographic/pictographic ones.
+ */
+/* ARGSUSED */
+int
+fs_build_range(FontPtr pfont, Bool range_flag, unsigned int count, 
+              int item_size, unsigned char *data, int *nranges, 
+              fsRange **ranges)
+{
+    FSFontDataPtr fsd = (FSFontDataPtr) (pfont->fpePrivate);
+    FSFontPtr fsfont = (FSFontPtr) (pfont->fontPrivate);
+    register CharInfoPtr encoding = fsfont->encoding;
+    FontInfoPtr pfi = &(pfont->info);
+    fsRange    range;
+    int                access_done = TRUE;
+    int                err;
+    register unsigned long firstrow, lastrow, firstcol, lastcol;
+    register unsigned long row;
+    register unsigned long col;
+    register unsigned long loc;
+
+    if (!fsd->glyphs_to_get)
+       return AccessDone;
+
+    firstrow = pfi->firstRow;
+    lastrow = pfi->lastRow;
+    firstcol = pfi->firstCol;
+    lastcol = pfi->lastCol;
+
+    /* Make sure we have default char */
+    if (fsfont->pDefault && ENCODING_UNDEFINED(fsfont->pDefault))
+    {
+       loc = fsfont->pDefault - encoding;
+       row = loc / (lastcol - firstcol + 1) + firstrow;
+       col = loc % (lastcol - firstcol + 1) + firstcol;
+
+       range.min_char_low = range.max_char_low = col;
+       range.min_char_high = range.max_char_high = row;
+
+       if ((err = add_range(&range, nranges, ranges, FALSE)) !=
+           Successful) return err;
+       encoding[loc].bits = &_fs_glyph_requested;
+       access_done = FALSE;
+    }
+
+    if (!range_flag && item_size == 1)
+    {
+       if (firstrow != 0) return AccessDone;
+       while (count--)
+       {
+           col = *data++;
+           if (col >= firstcol && col <= lastcol &&
+               GLYPH_UNDEFINED(col - firstcol))
+           {
+               int col1, col2;
+               col1 = col & 0xf0;
+               col2 = col1 + 15;
+               if (col1 < firstcol) col1 = firstcol;
+               if (col2 > lastcol) col2 = lastcol;
+               /* Collect a 16-glyph neighborhood containing the requested
+                  glyph... should in most cases reduce the number of round
+                  trips to the font server. */
+               for (col = col1; col <= col2; col++)
+               {
+                   if (!GLYPH_UNDEFINED(col - firstcol)) continue;
+                   range.min_char_low = range.max_char_low = col;
+                   range.min_char_high = range.max_char_high = 0;
+                   if ((err = add_range(&range, nranges, ranges, FALSE)) !=
+                       Successful) return err;
+                   encoding[col - firstcol].bits = &_fs_glyph_requested;
+                   access_done = FALSE;
+               }
+           }
+       }
+    }
+    else
+    {
+       fsRange fullrange[1];
+
+       if (range_flag && count == 0)
+       {
+           count = 2;
+           data = (unsigned char *)fullrange;
+           fullrange[0].min_char_high = firstrow;
+           fullrange[0].min_char_low = firstcol;
+           fullrange[0].max_char_high = lastrow;
+           fullrange[0].max_char_low = lastcol;
+       }
+
+       while (count--)
+       {
+           int row1, col1, row2, col2;
+           row1 = row2 = *data++;
+           col1 = col2 = *data++;
+           if (range_flag)
+           {
+               if (count)
+               {
+                   row2 = *data++;
+                   col2 = *data++;
+                   count--;
+               }
+               else
+               {
+                   row2 = lastrow;
+                   col2 = lastcol;
+               }
+               if (row1 < firstrow) row1 = firstrow;
+               if (row2 > lastrow) row2 = lastrow;
+               if (col1 < firstcol) col1 = firstcol;
+               if (col2 > lastcol) col2 = lastcol;
+           }
+           else
+           {
+               if (row1 < firstrow || row1 > lastrow ||
+                   col1 < firstcol || col1 > lastcol)
+                   continue;
+           }
+           for (row = row1; row <= row2; row++)
+           {
+           expand_glyph_range: ;
+               loc = (row - firstrow) * (lastcol + 1 - firstcol) +
+                     (col1 - firstcol);
+               for (col = col1; col <= col2; col++, loc++)
+               {
+                   if (GLYPH_UNDEFINED(loc))
+                   {
+                       if (row1 == row2 &&
+                           (((col1 & 0xf) && col1 > firstcol) ||
+                            (col2 & 0xf) != 0xf) && (col2 < lastcol))
+                       {
+                           /* If we're loading from a single row, expand
+                              range of glyphs loaded to a multiple of
+                              a 16-glyph range -- attempt to reduce number
+                              of round trips to the font server. */
+                           col1 &= 0xf0;
+                           col2 = (col2 & 0xf0) + 15;
+                           if (col1 < firstcol) col1 = firstcol;
+                           if (col2 > lastcol) col2 = lastcol;
+                           goto expand_glyph_range;
+                       }
+                       range.min_char_low = range.max_char_low = col;
+                       range.min_char_high = range.max_char_high = row;
+                       if ((err = add_range(&range, nranges, ranges, FALSE)) !=
+                           Successful) return err;
+                       encoding[loc].bits = &_fs_glyph_requested;
+                       access_done = FALSE;
+                   }
+               }
+           }
+       }
+    }
+
+    return access_done ?
+          AccessDone :
+          Successful;
+}
+
+#undef GLYPH_UNDEFINED
+#undef ENCODING_UNDEFINED
+
+
+/* _fs_clean_aborted_loadglyphs(): Undoes the changes to the encoding array
+   performed by fs_build_range(); for use if the associated LoadGlyphs
+   requests needs to be cancelled. */
+
+void
+_fs_clean_aborted_loadglyphs(FontPtr pfont, int num_expected_ranges, 
+                            fsRange *expected_ranges)
+{
+    register FSFontPtr fsfont;
+    register int i;
+
+    fsfont = (FSFontPtr) pfont->fontPrivate;
+    if (fsfont->encoding)
+    {
+       fsRange full_range[1];
+       if (!num_expected_ranges)
+       {
+           full_range[0].min_char_low = pfont->info.firstCol;
+           full_range[0].min_char_high = pfont->info.firstRow;
+           full_range[0].max_char_low = pfont->info.lastCol;
+           full_range[0].max_char_high = pfont->info.lastRow;
+           num_expected_ranges = 1;
+           expected_ranges = full_range;
+       }
+
+       for (i = 0; i < num_expected_ranges; i++)
+       {
+           int row, col;
+           for (row = expected_ranges[i].min_char_high;
+                row <= expected_ranges[i].max_char_high;
+                row++)
+           {
+               register CharInfoPtr encoding = fsfont->encoding +
+                   ((row - pfont->info.firstRow) *
+                    (pfont->info.lastCol -
+                     pfont->info.firstCol + 1) +
+                    expected_ranges[i].min_char_low -
+                    pfont->info.firstCol);
+               for (col = expected_ranges[i].min_char_low;
+                    col <= expected_ranges[i].max_char_low;
+                    encoding++, col++)
+               {
+                   if (encoding->bits == &_fs_glyph_requested)
+                       encoding->bits = &_fs_glyph_undefined;
+               }
+           }
+       }
+    }
+}
+
+static int
+_fs_get_glyphs(FontPtr pFont, unsigned long count, unsigned char *chars, 
+              FontEncoding charEncoding, 
+              unsigned long *glyphCount, /* RETURN */
+              CharInfoPtr *glyphs)       /* RETURN  */
+{
+    FSFontPtr   fsdata;
+    unsigned int firstCol;
+    register unsigned int numCols;
+    unsigned int firstRow;
+    unsigned int numRows;
+    CharInfoPtr *glyphsBase;
+    register unsigned int c;
+    register CharInfoPtr pci;
+    unsigned int r;
+    CharInfoPtr encoding;
+    CharInfoPtr pDefault;
+    FSFontDataPtr fsd = (FSFontDataPtr) pFont->fpePrivate;
+    int         err = Successful;
+
+    fsdata = (FSFontPtr) pFont->fontPrivate;
+    encoding = fsdata->encoding;
+    pDefault = fsdata->pDefault;
+    firstCol = pFont->info.firstCol;
+    numCols = pFont->info.lastCol - firstCol + 1;
+    glyphsBase = glyphs;
+
+    /* In this age of glyph caching, any glyphs gotten through this
+       procedure should already be loaded.  If they are not, we are
+       dealing with someone (perhaps a ddx driver optimizing a font)
+       that doesn't understand the finer points of glyph caching.  The
+       CHECK_ENCODING macro checks for this condition...  if found, it
+       calls fs_load_all_glyphs(), which corrects it.  Since the caller
+       of this code will not know how to handle a return value of
+       Suspended, the fs_load_all_glyphs() procedure will block and
+       freeze the server until the load operation is done.  Moral: the
+       glyphCachingMode flag really must indicate the capabilities of
+       the ddx drivers.  */
+
+#define CHECK_ENCODING(cnum) \
+    ( pci = encoding + (cnum), \
+      fsd->glyphs_to_get ? \
+      ( pci->bits == &_fs_glyph_undefined || pci->bits == &_fs_glyph_requested ? \
+       ((err = fs_load_all_glyphs(pFont)), pci) : \
+       pci ) : \
+      pci )
+
+    switch (charEncoding) {
+
+    case Linear8Bit:
+    case TwoD8Bit:
+       if (pFont->info.firstRow > 0)
+           break;
+       if (pFont->info.allExist && pDefault) {
+           while (err == Successful && count--) {
+               c = (*chars++) - firstCol;
+               if (c < numCols)
+                   *glyphs++ = CHECK_ENCODING(c);
+               else
+                   *glyphs++ = pDefault;
+           }
+       } else {
+           while (err == Successful && count--) {
+               c = (*chars++) - firstCol;
+               if (c < numCols && CHECK_ENCODING(c)->bits)
+                   *glyphs++ = pci;
+               else if (pDefault)
+                   *glyphs++ = pDefault;
+           }
+       }
+       break;
+    case Linear16Bit:
+       if (pFont->info.allExist && pDefault) {
+           while (err == Successful && count--) {
+               c = *chars++ << 8;
+               c = (c | *chars++) - firstCol;
+               if (c < numCols)
+                   *glyphs++ = CHECK_ENCODING(c);
+               else
+                   *glyphs++ = pDefault;
+           }
+       } else {
+           while (err == Successful && count--) {
+               c = *chars++ << 8;
+               c = (c | *chars++) - firstCol;
+               if (c < numCols && CHECK_ENCODING(c)->bits)
+                   *glyphs++ = pci;
+               else if (pDefault)
+                   *glyphs++ = pDefault;
+           }
+       }
+       break;
+
+    case TwoD16Bit:
+       firstRow = pFont->info.firstRow;
+       numRows = pFont->info.lastRow - firstRow + 1;
+       while (err == Successful && count--) {
+           r = (*chars++) - firstRow;
+           c = (*chars++) - firstCol;
+           if (r < numRows && c < numCols &&
+                   CHECK_ENCODING(r * numCols + c)->bits)
+               *glyphs++ = pci;
+           else if (pDefault)
+               *glyphs++ = pDefault;
+       }
+       break;
+    }
+    *glyphCount = glyphs - glyphsBase;
+    return err;
+}
+
+
+static int
+_fs_get_metrics(FontPtr pFont, unsigned long count, unsigned char *chars, 
+               FontEncoding charEncoding, 
+               unsigned long *glyphCount, /* RETURN */
+               xCharInfo **glyphs)        /* RETURN */
+{
+    FSFontPtr   fsdata;
+    unsigned int firstCol;
+    register unsigned int numCols;
+    unsigned int firstRow;
+    unsigned int numRows;
+    xCharInfo **glyphsBase;
+    register unsigned int c;
+    unsigned int r;
+    CharInfoPtr encoding;
+    CharInfoPtr pDefault;
+
+    fsdata = (FSFontPtr) pFont->fontPrivate;
+    encoding = fsdata->inkMetrics;
+    pDefault = fsdata->pDefault;
+    /* convert default bitmap metric to default ink metric */
+    if (pDefault)
+       pDefault = encoding + (pDefault - fsdata->encoding);
+    firstCol = pFont->info.firstCol;
+    numCols = pFont->info.lastCol - firstCol + 1;
+    glyphsBase = glyphs;
+
+
+    /* XXX - this should be much smarter */
+    /* make sure the glyphs are there */
+    switch (charEncoding) {
+
+    case Linear8Bit:
+    case TwoD8Bit:
+       if (pFont->info.firstRow > 0)
+           break;
+       if (pFont->info.allExist && pDefault) {
+           while (count--) {
+               c = (*chars++) - firstCol;
+               if (c < numCols)
+                   *glyphs++ = (xCharInfo *)&encoding[c];
+               else
+                   *glyphs++ = (xCharInfo *)pDefault;
+           }
+       } else {
+           while (count--) {
+               c = (*chars++) - firstCol;
+               if (c < numCols)
+                   *glyphs++ = (xCharInfo *)(encoding + c);
+               else if (pDefault)
+                   *glyphs++ = (xCharInfo *)pDefault;
+           }
+       }
+       break;
+    case Linear16Bit:
+       if (pFont->info.allExist && pDefault) {
+           while (count--) {
+               c = *chars++ << 8;
+               c = (c | *chars++) - firstCol;
+               if (c < numCols)
+                   *glyphs++ = (xCharInfo *)(encoding + c);
+               else
+                   *glyphs++ = (xCharInfo *)pDefault;
+           }
+       } else {
+           while (count--) {
+               c = *chars++ << 8;
+               c = (c | *chars++) - firstCol;
+               if (c < numCols)
+                   *glyphs++ = (xCharInfo *)(encoding + c);
+               else if (pDefault)
+                   *glyphs++ = (xCharInfo *)pDefault;
+           }
+       }
+       break;
+
+    case TwoD16Bit:
+       firstRow = pFont->info.firstRow;
+       numRows = pFont->info.lastRow - firstRow + 1;
+       while (count--) {
+           r = (*chars++) - firstRow;
+           c = (*chars++) - firstCol;
+           if (r < numRows && c < numCols)
+               *glyphs++ = (xCharInfo *)(encoding + (r * numCols + c));
+           else if (pDefault)
+               *glyphs++ = (xCharInfo *)pDefault;
+       }
+       break;
+    }
+    *glyphCount = glyphs - glyphsBase;
+    return Successful;
+}
+
+
+static void
+_fs_unload_font(FontPtr pfont)
+{
+    FSFontPtr      fsdata = (FSFontPtr) pfont->fontPrivate;
+    FSFontDataPtr   fsd = (FSFontDataPtr) pfont->fpePrivate;
+    CharInfoPtr            encoding = fsdata->encoding;
+    FSGlyphPtr     glyphs;
+
+    /*
+     * fsdata points at FSFontRec, FSFontDataRec and name
+     */
+    if (encoding)
+       free(encoding);
+
+    while ((glyphs = fsdata->glyphs))
+    {
+       fsdata->glyphs = glyphs->next;
+       free (glyphs);
+    }
+    
+    /* XXX we may get called after the resource DB has been cleaned out */
+    if (find_old_font(fsd->fontid))
+       DeleteFontClientID (fsd->fontid);
+    
+    _fs_free_props (&pfont->info);
+    
+    free(fsdata);
+           
+    DestroyFontRec(pfont);
+}
+
+FontPtr
+fs_create_font (FontPathElementPtr  fpe,
+               char                *name,
+               int                 namelen,
+               fsBitmapFormat      format,
+               fsBitmapFormatMask  fmask)
+{
+    FontPtr        pfont;
+    FSFontPtr      fsfont;
+    FSFontDataPtr   fsd;
+    int                    bit, byte, scan, glyph;
+
+    pfont = CreateFontRec ();
+    if (!pfont)
+       return 0;
+    fsfont = malloc (sizeof (FSFontRec) + sizeof (FSFontDataRec) + namelen + 1);
+    if (!fsfont)
+    {
+       DestroyFontRec (pfont);
+       return 0;
+    }
+    fsd = (FSFontDataPtr) (fsfont + 1);
+    bzero((char *) fsfont, sizeof(FSFontRec));
+    bzero((char *) fsd, sizeof(FSFontDataRec));
+    
+    pfont->fpe = fpe;
+    pfont->fontPrivate = (pointer) fsfont;
+    pfont->fpePrivate = (pointer) fsd;
+    
+    /* These font components will be needed in packGlyphs */
+    CheckFSFormat(format, BitmapFormatMaskBit |
+                 BitmapFormatMaskByte |
+                 BitmapFormatMaskScanLineUnit |
+                 BitmapFormatMaskScanLinePad,
+                 &bit,
+                 &byte,
+                 &scan,
+                 &glyph,
+                 NULL);
+    pfont->format = format;
+    pfont->bit = bit;
+    pfont->byte = byte;
+    pfont->scan = scan;
+    pfont->glyph = glyph;
+    
+    pfont->info.nprops = 0;
+    pfont->info.props = 0;
+    pfont->info.isStringProp = 0;
+    
+    /* set font function pointers */
+    pfont->get_glyphs = _fs_get_glyphs;
+    pfont->get_metrics = _fs_get_metrics;
+    pfont->unload_font = _fs_unload_font;
+    pfont->unload_glyphs = NULL;
+    
+    /* set the FPE private information */
+    fsd->format = format;
+    fsd->fmask = fmask;
+    fsd->name = (char *) (fsd + 1);
+    memcpy (fsd->name, name, namelen);
+    fsd->name[namelen] = '\0';
+    fsd->fontid = GetNewFontClientID ();
+    
+    /* save the ID */
+    if (!StoreFontClientFont(pfont, fsd->fontid)) 
+    {
+       free (fsfont);
+       DestroyFontRec (pfont);
+       return 0;
+    }
+
+    return pfont;
+}
+
+pointer
+fs_alloc_glyphs (FontPtr pFont, int size)
+{
+    FSGlyphPtr glyphs;
+    FSFontPtr  fsfont = (FSFontPtr) pFont->fontPrivate;
+
+    glyphs = malloc (sizeof (FSGlyphRec) + size);
+    glyphs->next = fsfont->glyphs;
+    fsfont->glyphs = glyphs;
+    return (pointer) (glyphs + 1);
+}
diff --git a/src/fc/fserve.c b/src/fc/fserve.c
new file mode 100755 (executable)
index 0000000..b02b0b7
--- /dev/null
@@ -0,0 +1,3198 @@
+/*
+
+Copyright 1990, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+/*
+ * Copyright 1990 Network Computing Devices
+ *
+ * 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 names of Network Computing Devices, or Digital
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ *
+ * NETWORK COMPUTING DEVICES, AND DIGITAL AND DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES,
+ * OR DIGITAL 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.
+ *
+ * Author:     Dave Lemke, Network Computing Devices, Inc
+ */
+/*
+ * font server specific font access
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef WIN32
+#define _WILLWINSOCK_
+#endif
+#define FONT_t
+#define TRANS_CLIENT
+#include       "X11/Xtrans/Xtrans.h"
+#include       "X11/Xpoll.h"
+#include       <X11/fonts/FS.h>
+#include       <X11/fonts/FSproto.h>
+#include       <X11/X.h>
+#include       <X11/Xos.h>
+#include       <X11/fonts/fontmisc.h>
+#include       <X11/fonts/fontstruct.h>
+#include       "fservestr.h"
+#include       <X11/fonts/fontutil.h>
+#include       <errno.h>
+
+#include       <time.h>
+#define Time_t time_t
+
+#ifdef NCD
+#include       <ncd/nvram.h>
+#endif
+
+#include <stddef.h>
+
+#ifndef MIN
+#define MIN(a,b)    ((a)<(b)?(a):(b))
+#endif
+#define TimeCmp(a,c,b) ((int) ((a) - (b)) c 0)
+    
+#define NONZEROMETRICS(pci) ((pci)->leftSideBearing || \
+                            (pci)->rightSideBearing || \
+                            (pci)->ascent || \
+                            (pci)->descent || \
+                            (pci)->characterWidth)
+
+extern void ErrorF(const char *f, ...);
+
+static int fs_read_glyphs ( FontPathElementPtr fpe, FSBlockDataPtr blockrec );
+static int fs_read_list ( FontPathElementPtr fpe, FSBlockDataPtr blockrec );
+static int fs_read_list_info ( FontPathElementPtr fpe, 
+                              FSBlockDataPtr blockrec );
+
+extern fd_set _fs_fd_mask;
+
+static void fs_block_handler ( pointer data, OSTimePtr wt, 
+                              pointer LastSelectMask );
+static int fs_wakeup ( FontPathElementPtr fpe, unsigned long *mask );
+
+/*
+ * List of all FPEs 
+ */
+static FSFpePtr fs_fpes;
+/*
+ * Union of all FPE blockStates
+ */
+static CARD32  fs_blockState;
+
+static int _fs_restart_connection ( FSFpePtr conn );
+static void fs_send_query_bitmaps ( FontPathElementPtr fpe, 
+                                  FSBlockDataPtr blockrec );
+static int fs_send_close_font ( FontPathElementPtr fpe, Font id );
+static void fs_client_died ( pointer client, FontPathElementPtr fpe );
+static void _fs_client_access ( FSFpePtr conn, pointer client, Bool sync );
+static void _fs_client_resolution ( FSFpePtr conn );
+static fsGenericReply *fs_get_reply (FSFpePtr conn, int *error);
+static int fs_await_reply (FSFpePtr conn);
+static void _fs_do_blocked (FSFpePtr conn);
+static void fs_cleanup_bfont (FSBlockedFontPtr bfont);
+
+char _fs_glyph_undefined;
+char _fs_glyph_requested;
+static char _fs_glyph_zero_length;
+
+static int  generationCount;
+
+static int FontServerRequestTimeout = 30 * 1000;
+
+static void
+_fs_close_server (FSFpePtr conn);
+
+static FSFpePtr
+_fs_init_conn (char *servername);
+
+static int
+_fs_wait_connect (FSFpePtr conn);
+
+static int
+_fs_send_init_packets (FSFpePtr conn);
+
+static void
+_fs_check_reconnect (FSFpePtr conn);
+
+static void
+_fs_start_reconnect (FSFpePtr conn);
+
+static void
+_fs_free_conn (FSFpePtr conn);
+
+static int
+fs_free_fpe(FontPathElementPtr fpe);
+
+/*
+ * Font server access
+ *
+ * the basic idea for the non-blocking access is to have the function
+ * called multiple times until the actual data is returned, instead
+ * of ClientBlocked.
+ *
+ * the first call to the function will cause the request to be sent to
+ * the font server, and a block record to be stored in the fpe's list
+ * of outstanding requests.  the FS block handler also sticks the
+ * proper set of fd's into the select mask.  when data is ready to be
+ * read in, the FS wakup handler will be hit.  this will read the
+ * data off the wire into the proper block record, and then signal the
+ * client that caused the block so that it can restart.  it will then
+ * call the access function again, which will realize that the data has
+ * arrived and return it.
+ */
+
+
+#ifdef DEBUG
+static void
+_fs_add_req_log(FSFpePtr conn, int opcode)
+{
+    conn->current_seq++;
+    fprintf (stderr, "\t\tRequest: %5d Opcode: %2d\n",
+            conn->current_seq, opcode);
+    conn->reqbuffer[conn->reqindex].opcode = opcode;
+    conn->reqbuffer[conn->reqindex].sequence = conn->current_seq;
+    conn->reqindex++;
+    if (conn->reqindex == REQUEST_LOG_SIZE)
+       conn->reqindex = 0;
+}
+
+static void
+_fs_add_rep_log (FSFpePtr conn, fsGenericReply *rep)
+{
+    int            i;
+
+    for (i = 0; i < REQUEST_LOG_SIZE; i++)
+       if (conn->reqbuffer[i].sequence == rep->sequenceNumber)
+           break;
+    if (i == REQUEST_LOG_SIZE)
+       fprintf (stderr, "\t\t\t\t\tReply:  %5d Opcode: unknown\n",
+                rep->sequenceNumber);
+    else
+       fprintf (stderr, "\t\t\t\t\tReply:  %5d Opcode: %d\n",
+                rep->sequenceNumber,
+                conn->reqbuffer[i].opcode);
+}
+#else
+#define _fs_add_req_log(conn,op)    ((conn)->current_seq++)
+#define _fs_add_rep_log(conn,rep)
+#endif
+
+static Bool
+fs_name_check(char *name)
+{
+    /* Just make sure there is a protocol/ prefix */
+    return (name && *name != '/' && strchr(name, '/'));
+}
+
+static void
+_fs_client_resolution(FSFpePtr conn)
+{
+    fsSetResolutionReq srreq;
+    int         num_res;
+    FontResolutionPtr res;
+
+    res = GetClientResolutions(&num_res);
+
+    if (num_res) {
+       srreq.reqType = FS_SetResolution;
+       srreq.num_resolutions = num_res;
+       srreq.length = (SIZEOF(fsSetResolutionReq) +
+                       (num_res * SIZEOF(fsResolution)) + 3) >> 2;
+
+       _fs_add_req_log(conn, FS_SetResolution);
+       if (_fs_write(conn, (char *) &srreq, SIZEOF(fsSetResolutionReq)) != -1)
+           (void)_fs_write_pad(conn, (char *) res,
+                               (num_res * SIZEOF(fsResolution)));
+    }
+}
+
+/* 
+ * close font server and remove any state associated with
+ * this connection - this includes any client records.
+ */
+
+static void
+fs_close_conn(FSFpePtr conn)
+{
+    FSClientPtr        client, nclient;
+
+    _fs_close_server (conn);
+    
+    for (client = conn->clients; client; client = nclient) 
+    {
+       nclient = client->next;
+       free (client);
+    }
+    conn->clients = NULL;
+}
+
+/*
+ * the wakeup handlers have to be set when the FPE is open, and not
+ * removed until it is freed, in order to handle unexpected data, like
+ * events
+ */
+/* ARGSUSED */
+static int
+fs_init_fpe(FontPathElementPtr fpe)
+{
+    FSFpePtr    conn;
+    char       *name;
+    int         err;
+    int                ret;
+
+    /* open font server */
+    /* create FS specific fpe info */
+    name = fpe->name;
+
+    /* hack for old style names */
+    if (*name == ':')
+       name++;                 /* skip ':' */
+
+    conn = _fs_init_conn (name);
+    if (!conn)
+       err = AllocError;
+    else
+    {
+       err = init_fs_handlers (fpe, fs_block_handler);
+       if (err != Successful)
+       {
+           _fs_free_conn (conn);
+           err = AllocError;
+       }
+       else
+       {
+           fpe->private = conn;
+           conn->next = fs_fpes;
+           fs_fpes = conn;
+           ret = _fs_wait_connect (conn);
+           if (ret != FSIO_READY)
+           {
+               fs_free_fpe (fpe);
+               err = BadFontPath;
+           }
+           else
+               err = Successful;
+       }
+    }
+    
+    if (err == Successful)
+    {
+#ifdef NCD
+       if (configData.ExtendedFontDiags)
+           printf("Connected to font server \"%s\"\n", name);
+#endif
+#ifdef DEBUG
+       fprintf (stderr, "connected to FS \"%s\"\n", name);
+#endif
+    }
+    else
+    {
+#ifdef DEBUG
+       fprintf(stderr, "failed to connect to FS \"%s\" %d\n", name, err);
+#endif
+#ifdef NCD
+       if (configData.ExtendedFontDiags)
+           printf("Failed to connect to font server \"%s\"\n", name);
+#endif
+       ;
+    }
+    return err;
+}
+
+static int
+fs_reset_fpe(FontPathElementPtr fpe)
+{
+    (void) _fs_send_init_packets((FSFpePtr) fpe->private);
+    return Successful;
+}
+
+/*
+ * this shouldn't be called till all refs to the FPE are gone
+ */
+
+static int
+fs_free_fpe(FontPathElementPtr fpe)
+{
+    FSFpePtr    conn = (FSFpePtr) fpe->private, *prev;
+    
+    /* unhook from chain of all font servers */
+    for (prev = &fs_fpes; *prev; prev = &(*prev)->next)
+    {
+       if (*prev == conn)
+       {
+           *prev = conn->next;
+           break;
+       }
+    }
+    _fs_unmark_block (conn, conn->blockState);
+    fs_close_conn(conn);
+    remove_fs_handlers(fpe, fs_block_handler, fs_fpes == 0);
+    _fs_free_conn (conn);
+    fpe->private = (pointer) 0;
+
+#ifdef NCD
+    if (configData.ExtendedFontDiags)
+       printf("Disconnected from font server \"%s\"\n", fpe->name);
+#endif
+#ifdef DEBUG
+    fprintf (stderr, "disconnect from FS \"%s\"\n", fpe->name);
+#endif
+
+    return Successful;
+}
+
+static      FSBlockDataPtr
+fs_new_block_rec(FontPathElementPtr fpe, pointer client, int type)
+{
+    FSBlockDataPtr blockrec,
+                *prev;
+    FSFpePtr    conn = (FSFpePtr) fpe->private;
+    int         size;
+
+    switch (type) {
+    case FS_OPEN_FONT:
+       size = sizeof(FSBlockedFontRec);
+       break;
+    case FS_LOAD_GLYPHS:
+       size = sizeof(FSBlockedGlyphRec);
+       break;
+    case FS_LIST_FONTS:
+       size = sizeof(FSBlockedListRec);
+       break;
+    case FS_LIST_WITH_INFO:
+       size = sizeof(FSBlockedListInfoRec);
+       break;
+    default:
+       size = 0;
+       break;
+    }
+    blockrec = malloc(sizeof(FSBlockDataRec) + size);
+    if (!blockrec)
+       return (FSBlockDataPtr) 0;
+    blockrec->data = (pointer) (blockrec + 1);
+    blockrec->client = client;
+    blockrec->sequenceNumber = -1;
+    blockrec->errcode = StillWorking;
+    blockrec->type = type;
+    blockrec->depending = 0;
+    blockrec->next = (FSBlockDataPtr) 0;
+    
+    /* stick it on the end of the list (since its expected last) */
+    for (prev = &conn->blockedRequests; *prev; prev = &(*prev)->next)
+       ;
+    *prev = blockrec;
+
+    return blockrec;
+}
+
+static void
+_fs_set_pending_reply (FSFpePtr conn)
+{
+    FSBlockDataPtr  blockrec;
+    
+    for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next)
+       if (blockrec->errcode == StillWorking)
+           break;
+    if (blockrec)
+    {
+       conn->blockedReplyTime = GetTimeInMillis () + FontServerRequestTimeout;
+       _fs_mark_block (conn, FS_PENDING_REPLY);
+    }
+    else
+       _fs_unmark_block (conn, FS_PENDING_REPLY);
+}
+
+static void
+_fs_remove_block_rec(FSFpePtr conn, FSBlockDataPtr blockrec)
+{
+    FSBlockDataPtr *prev;
+
+    for (prev = &conn->blockedRequests; *prev; prev = &(*prev)->next)
+       if (*prev == blockrec) 
+       {
+           *prev = blockrec->next;
+           break;
+       }
+    if (blockrec->type == FS_LOAD_GLYPHS)
+    {
+       FSBlockedGlyphPtr bglyph = (FSBlockedGlyphPtr)blockrec->data;
+       if (bglyph->num_expected_ranges)
+           free(bglyph->expected_ranges);
+    }
+    free(blockrec);
+    _fs_set_pending_reply (conn);
+}
+
+static void
+_fs_signal_clients_depending(FSClientsDependingPtr *clients_depending)
+{
+    FSClientsDependingPtr p;
+    
+    while ((p = *clients_depending))
+    {
+       *clients_depending = p->next;
+       ClientSignal(p->client);
+       free(p);
+    }
+}
+
+static int
+_fs_add_clients_depending(FSClientsDependingPtr *clients_depending, pointer client)
+{
+    FSClientsDependingPtr   new, cd;
+    
+    for (; (cd = *clients_depending); 
+        clients_depending = &(*clients_depending)->next)
+    {
+       if (cd->client == client) 
+           return Suspended;
+    }
+    
+    new = malloc (sizeof (FSClientsDependingRec));
+    if (!new)
+       return BadAlloc;
+
+    new->client = client;
+    new->next = 0;
+    *clients_depending = new;
+    return Suspended;
+}
+
+/*
+ * When a request is aborted due to a font server failure,
+ * signal any depending clients to restart their dependant
+ * requests
+ */
+static void
+_fs_clean_aborted_blockrec(FSFpePtr conn, FSBlockDataPtr blockrec)
+{
+    switch(blockrec->type) {
+    case FS_OPEN_FONT: {
+       FSBlockedFontPtr bfont = (FSBlockedFontPtr)blockrec->data;
+       
+       fs_cleanup_bfont (bfont);
+       _fs_signal_clients_depending(&bfont->clients_depending);
+       break;
+    }
+    case FS_LOAD_GLYPHS: {
+       FSBlockedGlyphPtr bglyph = (FSBlockedGlyphPtr)blockrec->data;
+       
+       _fs_clean_aborted_loadglyphs(bglyph->pfont,
+                                    bglyph->num_expected_ranges,
+                                    bglyph->expected_ranges); 
+       _fs_signal_clients_depending(&bglyph->clients_depending);
+       break;
+    }
+    case FS_LIST_FONTS:
+       break;
+    case FS_LIST_WITH_INFO: {
+       FSBlockedListInfoPtr binfo;
+       binfo = (FSBlockedListInfoPtr) blockrec->data;
+       if (binfo->status == FS_LFWI_REPLY)
+           FD_SET(conn->fs_fd, &_fs_fd_mask);
+       _fs_free_props (&binfo->info);
+    }
+    default:
+       break;
+    }
+}
+
+static void
+fs_abort_blockrec(FSFpePtr conn, FSBlockDataPtr blockrec)
+{
+    _fs_clean_aborted_blockrec (conn, blockrec);
+    _fs_remove_block_rec (conn, blockrec);
+}
+
+/*
+ * Tell the font server we've failed to complete an open and
+ * then unload the partially created font
+ */
+static void
+fs_cleanup_bfont (FSBlockedFontPtr bfont)
+{
+    FSFontDataRec *fsd;
+
+    if (bfont->pfont)
+    {
+       fsd = (FSFontDataRec *) bfont->pfont->fpePrivate;
+    
+       /* make sure the FS knows we choked on it */
+       fs_send_close_font(bfont->pfont->fpe, bfont->fontid);
+       
+       /*
+        * Either unload the font if it's being opened for 
+        * the first time, or smash the generation field to
+        * mark this font as an orphan
+        */
+       if (!(bfont->flags & FontReopen))
+       {
+           if (bfont->freeFont)
+               (*bfont->pfont->unload_font) (bfont->pfont);
+#ifdef DEBUG
+           else
+               fprintf (stderr, "Not freeing other font in cleanup_bfont\n");
+#endif
+           bfont->pfont = 0;
+       }
+       else
+           fsd->generation = -1;
+    }
+}
+
+/*
+ * Check to see if a complete reply is waiting
+ */
+static fsGenericReply *
+fs_get_reply (FSFpePtr conn, int *error)
+{
+    char           *buf;
+    fsGenericReply  *rep;
+    int                    ret;
+
+    /* block if the connection is down or paused in lfwi */
+    if (conn->fs_fd == -1 || !FD_ISSET (conn->fs_fd, &_fs_fd_mask))
+    {
+       *error = FSIO_BLOCK;
+       return 0;
+    }
+    
+    ret = _fs_start_read (conn, sizeof (fsGenericReply), &buf);
+    if (ret != FSIO_READY)
+    {
+       *error = FSIO_BLOCK;
+       return 0;
+    }
+    
+    rep = (fsGenericReply *) buf;
+
+    ret = _fs_start_read (conn, rep->length << 2, &buf);
+    if (ret != FSIO_READY)
+    {
+       *error = FSIO_BLOCK;
+       return 0;
+    }
+
+    *error = FSIO_READY;
+    
+    return (fsGenericReply *) buf;
+}
+
+static Bool
+fs_reply_ready (FSFpePtr conn)
+{
+    fsGenericReply  *rep;
+    
+    if (conn->fs_fd == -1 || !FD_ISSET (conn->fs_fd, &_fs_fd_mask))
+       return FALSE;
+    if (fs_data_read (conn) < sizeof (fsGenericReply))
+       return FALSE;
+    rep = (fsGenericReply *) (conn->inBuf.buf + conn->inBuf.remove);
+    if (fs_data_read (conn) < rep->length << 2)
+       return FALSE;
+    return TRUE;
+}
+
+static void
+_fs_pending_reply (FSFpePtr conn)
+{
+    if (!(conn->blockState & FS_PENDING_REPLY))
+    {
+       _fs_mark_block (conn, FS_PENDING_REPLY);
+       conn->blockedReplyTime = GetTimeInMillis () + FontServerRequestTimeout;
+    }
+}
+
+static void
+_fs_prepare_for_reply (FSFpePtr conn)
+{
+    _fs_pending_reply (conn);
+    _fs_flush (conn);
+}
+
+/*
+ * Block (for a while) awaiting a complete reply
+ */
+static int
+fs_await_reply (FSFpePtr conn)
+{
+    int                    ret;
+    
+    if (conn->blockState & FS_COMPLETE_REPLY)
+       return FSIO_READY;
+    
+    while (!fs_get_reply (conn, &ret))
+    {
+       if (ret != FSIO_BLOCK)
+           return ret;
+       if (_fs_wait_for_readable (conn, FontServerRequestTimeout) != FSIO_READY)
+       {
+           _fs_connection_died (conn);
+           return FSIO_ERROR;
+       }
+    }
+    return FSIO_READY;
+}
+
+/*
+ * Process the reply to an OpenBitmapFont request
+ */
+static int
+fs_read_open_font(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
+{
+    FSFpePtr               conn = (FSFpePtr) fpe->private;
+    FSBlockedFontPtr       bfont = (FSBlockedFontPtr) blockrec->data;
+    fsOpenBitmapFontReply   *rep;
+    FSBlockDataPtr         blockOrig;
+    FSBlockedFontPtr       origBfont;
+    int                            ret;
+
+    rep = (fsOpenBitmapFontReply *) fs_get_reply (conn, &ret);
+    if (!rep || rep->type == FS_Error)
+    {
+       if (ret == FSIO_BLOCK)
+           return StillWorking;
+       if (rep)
+           _fs_done_read (conn, rep->length << 2);
+       fs_cleanup_bfont (bfont);
+       return BadFontName;
+    }
+          
+    /* If we're not reopening a font and FS detected a duplicate font
+       open request, replace our reference to the new font with a
+       reference to an existing font (possibly one not finished
+       opening).  If this is a reopen, keep the new font reference...
+       it's got the metrics and extents we read when the font was opened
+       before.  This also gives us the freedom to easily close the font
+       if we we decide (in fs_read_query_info()) that we don't like what
+       we got. */
+
+    if (rep->otherid && !(bfont->flags & FontReopen)) 
+    {
+       fs_cleanup_bfont (bfont);
+       
+       /* Find old font if we're completely done getting it from server. */
+       bfont->pfont = find_old_font(rep->otherid);
+       bfont->freeFont = FALSE;
+       bfont->fontid = rep->otherid;
+       bfont->state = FS_DONE_REPLY;
+       /*
+        * look for a blocked request to open the same font
+        */
+       for (blockOrig = conn->blockedRequests;
+               blockOrig;
+               blockOrig = blockOrig->next) 
+       {
+           if (blockOrig != blockrec && blockOrig->type == FS_OPEN_FONT) 
+           {
+               origBfont = (FSBlockedFontPtr) blockOrig->data;
+               if (origBfont->fontid == rep->otherid) 
+               {
+                   blockrec->depending = blockOrig->depending;
+                   blockOrig->depending = blockrec;
+                   bfont->state = FS_DEPENDING;
+                   bfont->pfont = origBfont->pfont;
+                   break;
+               }
+           }
+       }
+       if (bfont->pfont == NULL)
+       {
+           /* XXX - something nasty happened */
+           ret = BadFontName;
+       }
+       else
+           ret = AccessDone;
+    }
+    else
+    {
+       bfont->pfont->info.cachable = rep->cachable != 0;
+       bfont->state = FS_INFO_REPLY;
+       /*
+        * Reset the blockrec for the next reply
+        */
+       blockrec->sequenceNumber = bfont->queryInfoSequence;
+       conn->blockedReplyTime = GetTimeInMillis () + FontServerRequestTimeout;
+       ret = StillWorking;
+    }
+    _fs_done_read (conn, rep->length << 2);
+    return ret;
+}
+
+static Bool
+fs_fonts_match (FontInfoPtr pInfo1, FontInfoPtr pInfo2)
+{
+    int            i;
+    
+    if (pInfo1->firstCol != pInfo2->firstCol ||
+       pInfo1->lastCol != pInfo2->lastCol ||
+       pInfo1->firstRow != pInfo2->firstRow ||
+       pInfo1->lastRow != pInfo2->lastRow ||
+       pInfo1->defaultCh != pInfo2->defaultCh ||
+       pInfo1->noOverlap != pInfo2->noOverlap ||
+       pInfo1->terminalFont != pInfo2->terminalFont ||
+       pInfo1->constantMetrics != pInfo2->constantMetrics ||
+       pInfo1->constantWidth != pInfo2->constantWidth ||
+       pInfo1->inkInside != pInfo2->inkInside ||
+       pInfo1->inkMetrics != pInfo2->inkMetrics ||
+       pInfo1->allExist != pInfo2->allExist ||
+       pInfo1->drawDirection != pInfo2->drawDirection ||
+       pInfo1->cachable != pInfo2->cachable ||
+       pInfo1->anamorphic != pInfo2->anamorphic ||
+       pInfo1->maxOverlap != pInfo2->maxOverlap ||
+       pInfo1->fontAscent != pInfo2->fontAscent ||
+       pInfo1->fontDescent != pInfo2->fontDescent ||
+       pInfo1->nprops != pInfo2->nprops)
+       return FALSE;
+
+#define MATCH(xci1, xci2) \
+    (((xci1).leftSideBearing == (xci2).leftSideBearing) && \
+     ((xci1).rightSideBearing == (xci2).rightSideBearing) && \
+     ((xci1).characterWidth == (xci2).characterWidth) && \
+     ((xci1).ascent == (xci2).ascent) && \
+     ((xci1).descent == (xci2).descent) && \
+     ((xci1).attributes == (xci2).attributes))
+
+    if (!MATCH(pInfo1->maxbounds, pInfo2->maxbounds) ||
+       !MATCH(pInfo1->minbounds, pInfo2->minbounds) ||
+       !MATCH(pInfo1->ink_maxbounds, pInfo2->ink_maxbounds) ||
+       !MATCH(pInfo1->ink_minbounds, pInfo2->ink_minbounds))
+       return FALSE;
+
+#undef MATCH
+
+    for (i = 0; i < pInfo1->nprops; i++)
+       if (pInfo1->isStringProp[i] !=
+               pInfo2->isStringProp[i] ||
+           pInfo1->props[i].name !=
+               pInfo2->props[i].name ||
+           pInfo1->props[i].value !=
+               pInfo2->props[i].value)
+       {
+           return FALSE;
+       }
+    return TRUE;
+}
+
+static int
+fs_read_query_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
+{
+    FSBlockedFontPtr   bfont = (FSBlockedFontPtr) blockrec->data;
+    FSFpePtr           conn = (FSFpePtr) fpe->private;
+    fsQueryXInfoReply  *rep;
+    char               *buf;
+    fsPropInfo         *pi;
+    fsPropOffset       *po;
+    pointer            pd;
+    FontInfoPtr                pInfo;
+    FontInfoRec                tempInfo;
+    int                        err;
+    int                        ret;
+
+    rep = (fsQueryXInfoReply *) fs_get_reply (conn, &ret);
+    if (!rep || rep->type == FS_Error)
+    {
+       if (ret == FSIO_BLOCK)
+           return StillWorking;
+       if (rep)
+           _fs_done_read (conn, rep->length << 2);
+       fs_cleanup_bfont (bfont);
+       return BadFontName;
+    }
+       
+    /* If this is a reopen, accumulate the query info into a dummy
+       font and compare to our original data. */
+    if (bfont->flags & FontReopen)
+       pInfo = &tempInfo;
+    else
+       pInfo = &bfont->pfont->info;
+
+    buf = (char *) rep;
+    buf += SIZEOF(fsQueryXInfoReply);
+    
+    /* move the data over */
+    fsUnpack_XFontInfoHeader(rep, pInfo);
+    
+    /* compute accelerators */
+    _fs_init_fontinfo(conn, pInfo);
+
+    /* Compute offsets into the reply */
+    pi = (fsPropInfo *) buf;
+    buf += SIZEOF (fsPropInfo);
+    
+    po = (fsPropOffset *) buf;
+    buf += pi->num_offsets * SIZEOF(fsPropOffset);
+
+    pd = (pointer) buf;
+    buf += pi->data_len;
+    
+    /* convert the properties and step over the reply */
+    ret = _fs_convert_props(pi, po, pd, pInfo);
+    _fs_done_read (conn, rep->length << 2);
+    
+    if (ret == -1)
+    {
+       fs_cleanup_bfont (bfont);
+       return AllocError;
+    }
+
+    if (bfont->flags & FontReopen)
+    {
+       /* We're reopening a font that we lost because of a downed
+          connection.  In the interest of avoiding corruption from
+          opening a different font than the old one (we already have
+          its metrics, extents, and probably some of its glyphs),
+          verify that the metrics and properties all match.  */
+
+       if (fs_fonts_match (pInfo, &bfont->pfont->info))
+       {
+           err = Successful;
+           bfont->state = FS_DONE_REPLY;
+       }
+       else
+       {
+           fs_cleanup_bfont (bfont);
+           err = BadFontName;
+       }
+       _fs_free_props (pInfo);
+       
+       return err;
+    }
+
+    /*
+     * Ask for terminal format fonts if possible
+     */
+    if (bfont->pfont->info.terminalFont)
+       bfont->format = ((bfont->format & ~ (BitmapFormatImageRectMask)) |
+                        BitmapFormatImageRectMax);
+
+    /*
+     * Figure out if the whole font should get loaded right now.
+     */
+    if (glyphCachingMode == CACHING_OFF ||
+       (glyphCachingMode == CACHE_16_BIT_GLYPHS 
+        && !bfont->pfont->info.lastRow))
+    {
+       bfont->flags |= FontLoadAll;
+    }
+    
+    /*
+     * Ready to send the query bitmaps; the terminal font bit has 
+     * been computed and glyphCaching has been considered
+     */
+    if (bfont->flags & FontLoadBitmaps)
+    {
+       fs_send_query_bitmaps (fpe, blockrec);
+       _fs_flush (conn);
+    }
+
+    bfont->state = FS_EXTENT_REPLY;
+
+    /*
+     * Reset the blockrec for the next reply
+     */
+    blockrec->sequenceNumber = bfont->queryExtentsSequence;
+    conn->blockedReplyTime = GetTimeInMillis () + FontServerRequestTimeout;
+    
+    return StillWorking;
+}
+
+static int
+fs_read_extent_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
+{
+    FSFpePtr               conn = (FSFpePtr) fpe->private;
+    FSBlockedFontPtr       bfont = (FSBlockedFontPtr) blockrec->data;
+    FSFontDataPtr          fsd = (FSFontDataPtr) bfont->pfont->fpePrivate;
+    FSFontPtr              fsfont = (FSFontPtr) bfont->pfont->fontPrivate;
+    fsQueryXExtents16Reply  *rep;
+    char                   *buf;
+    int                            i;
+    int                            numExtents;
+    int                            numInfos;
+    int                            ret;
+    Bool                   haveInk = FALSE; /* need separate ink metrics? */
+    CharInfoPtr                    ci, pCI;
+    char                   *fsci;
+    fsXCharInfo                    fscilocal;
+    FontInfoRec                    *fi = &bfont->pfont->info;
+
+    rep = (fsQueryXExtents16Reply *) fs_get_reply (conn, &ret);
+    if (!rep || rep->type == FS_Error)
+    {
+       if (ret == FSIO_BLOCK)
+           return StillWorking;
+       if (rep)
+           _fs_done_read (conn, rep->length << 2);
+       fs_cleanup_bfont (bfont);
+       return BadFontName;
+    }
+       
+    /* move the data over */
+    /* need separate inkMetrics for fixed font server protocol version */
+    numExtents = rep->num_extents;
+    numInfos = numExtents;
+    if (bfont->pfont->info.terminalFont && conn->fsMajorVersion > 1)
+    {
+       numInfos *= 2;
+       haveInk = TRUE;
+    }
+    ci = pCI = malloc(sizeof(CharInfoRec) * numInfos);
+
+    if (!pCI) 
+    {
+       _fs_done_read (conn, rep->length << 2);
+       fs_cleanup_bfont(bfont);
+       return AllocError;
+    }
+    fsfont->encoding = pCI;
+    if (haveInk)
+       fsfont->inkMetrics = pCI + numExtents;
+    else
+        fsfont->inkMetrics = pCI;
+
+    buf = (char *) rep;
+    buf += SIZEOF (fsQueryXExtents16Reply);
+    fsci = buf;
+    
+    fsd->glyphs_to_get = 0;
+    ci = fsfont->inkMetrics;
+    for (i = 0; i < numExtents; i++) 
+    {
+       memcpy(&fscilocal, fsci, SIZEOF(fsXCharInfo)); /* align it */
+       _fs_convert_char_info(&fscilocal, &ci->metrics);
+       /* Bounds check. */
+       if (ci->metrics.ascent > fi->maxbounds.ascent)
+       {
+           ErrorF("fserve: warning: %s %s ascent (%d) > maxascent (%d)\n",
+                  fpe->name, fsd->name,
+                  ci->metrics.ascent, fi->maxbounds.ascent);
+           ci->metrics.ascent = fi->maxbounds.ascent;
+       }
+       if (ci->metrics.descent > fi->maxbounds.descent)
+       {
+           ErrorF("fserve: warning: %s %s descent (%d) > maxdescent (%d)\n",
+                  fpe->name, fsd->name,
+                  ci->metrics.descent, fi->maxbounds.descent);
+           ci->metrics.descent = fi->maxbounds.descent;
+       }
+       fsci = fsci + SIZEOF(fsXCharInfo);
+       /* Initialize the bits field for later glyph-caching use */
+       if (NONZEROMETRICS(&ci->metrics))
+       {
+           if (!haveInk &&
+               (ci->metrics.leftSideBearing == ci->metrics.rightSideBearing ||
+                ci->metrics.ascent == -ci->metrics.descent))
+               pCI[i].bits = &_fs_glyph_zero_length;
+           else
+           {
+               pCI[i].bits = &_fs_glyph_undefined;
+               fsd->glyphs_to_get++;
+           }
+       }
+       else
+           pCI[i].bits = (char *)0;
+       ci++;
+    }
+
+    /* Done with reply */
+    _fs_done_read (conn, rep->length << 2);
+    
+    /* build bitmap metrics, ImageRectMax style */
+    if (haveInk)
+    {
+       CharInfoPtr ii;
+
+       ci = fsfont->encoding;
+       ii = fsfont->inkMetrics;
+       for (i = 0; i < numExtents; i++, ci++, ii++)
+       {
+           if (NONZEROMETRICS(&ii->metrics))
+           {
+               ci->metrics.leftSideBearing = FONT_MIN_LEFT(fi);
+               ci->metrics.rightSideBearing = FONT_MAX_RIGHT(fi);
+               ci->metrics.ascent = FONT_MAX_ASCENT(fi);
+               ci->metrics.descent = FONT_MAX_DESCENT(fi);
+               ci->metrics.characterWidth = FONT_MAX_WIDTH(fi);
+               ci->metrics.attributes = ii->metrics.attributes;
+           }
+           else
+           {
+               ci->metrics = ii->metrics;
+           }
+           /* Bounds check. */
+           if (ci->metrics.ascent > fi->maxbounds.ascent)
+           {
+               ErrorF("fserve: warning: %s %s ascent (%d) "
+                      "> maxascent (%d)\n",
+                      fpe->name, fsd->name,
+                      ci->metrics.ascent, fi->maxbounds.ascent);
+               ci->metrics.ascent = fi->maxbounds.ascent;
+           }
+           if (ci->metrics.descent > fi->maxbounds.descent)
+           {
+               ErrorF("fserve: warning: %s %s descent (%d) "
+                      "> maxdescent (%d)\n",
+                      fpe->name, fsd->name,
+                      ci->metrics.descent, fi->maxbounds.descent);
+               ci->metrics.descent = fi->maxbounds.descent;
+           }
+       }
+    }
+    {
+       unsigned int r, c, numCols, firstCol;
+
+       firstCol = bfont->pfont->info.firstCol;
+       numCols = bfont->pfont->info.lastCol - firstCol + 1;
+       c = bfont->pfont->info.defaultCh;
+       fsfont->pDefault = 0;
+       if (bfont->pfont->info.lastRow)
+       {
+           r = c >> 8;
+           r -= bfont->pfont->info.firstRow;
+           c &= 0xff;
+           c -= firstCol;
+           if (r < bfont->pfont->info.lastRow-bfont->pfont->info.firstRow+1 &&
+               c < numCols)
+               fsfont->pDefault = &pCI[r * numCols + c];
+       }
+       else
+       {
+           c -= firstCol;
+           if (c < numCols)
+               fsfont->pDefault = &pCI[c];
+       }
+    }
+    bfont->state = FS_GLYPHS_REPLY;
+
+    if (bfont->flags & FontLoadBitmaps) 
+    {
+       /*
+        * Reset the blockrec for the next reply
+        */
+       blockrec->sequenceNumber = bfont->queryBitmapsSequence;
+       conn->blockedReplyTime = GetTimeInMillis () + FontServerRequestTimeout;
+       return StillWorking;
+    }
+    return Successful;
+}
+
+#ifdef DEBUG
+static char *fs_open_states[] = {
+    "OPEN_REPLY  ",
+    "INFO_REPLY  ",
+    "EXTENT_REPLY",
+    "GLYPHS_REPLY",
+    "DONE_REPLY  ",
+    "DEPENDING   ",
+};
+#endif
+
+static int
+fs_do_open_font(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
+{
+    FSBlockedFontPtr   bfont = (FSBlockedFontPtr) blockrec->data;
+    int                        err;
+
+#ifdef DEBUG
+    fprintf (stderr, "fs_do_open_font state %s %s\n",
+            fs_open_states[bfont->state], 
+            ((FSFontDataPtr) (bfont->pfont->fpePrivate))->name);
+#endif
+    err = BadFontName;
+    switch (bfont->state) {
+    case FS_OPEN_REPLY:
+       err = fs_read_open_font(fpe, blockrec);
+       if (err != StillWorking) {      /* already loaded, or error */
+           /* if font's already loaded, massage error code */
+           switch (bfont->state) {
+           case FS_DONE_REPLY:
+               err = Successful;
+               break;
+           case FS_DEPENDING:
+               err = StillWorking;
+               break;
+           }
+       }
+       break;
+    case FS_INFO_REPLY:
+       err = fs_read_query_info(fpe, blockrec);
+       break;
+    case FS_EXTENT_REPLY:
+       err = fs_read_extent_info(fpe, blockrec);
+       break;
+    case FS_GLYPHS_REPLY:
+       if (bfont->flags & FontLoadBitmaps)
+           err = fs_read_glyphs(fpe, blockrec);
+       break;
+    case FS_DEPENDING:         /* can't happen */
+    default:
+       break;
+    }
+#ifdef DEBUG
+    fprintf (stderr, "fs_do_open_font err %d\n", err);
+#endif
+    if (err != StillWorking) 
+    {
+       bfont->state = FS_DONE_REPLY;   /* for _fs_load_glyphs() */
+       while ((blockrec = blockrec->depending)) 
+       {
+           bfont = (FSBlockedFontPtr) blockrec->data;
+           bfont->state = FS_DONE_REPLY;       /* for _fs_load_glyphs() */
+       }
+    }
+    return err;
+}
+
+void
+_fs_mark_block (FSFpePtr conn, CARD32 mask)
+{
+    conn->blockState |= mask;
+    fs_blockState |= mask;
+}
+
+void
+_fs_unmark_block (FSFpePtr conn, CARD32 mask)
+{
+    FSFpePtr   c;
+    
+    if (conn->blockState & mask)
+    {
+       conn->blockState &= ~mask;
+       fs_blockState = 0;
+       for (c = fs_fpes; c; c = c->next)
+           fs_blockState |= c->blockState;
+    }
+}
+
+/* ARGSUSED */
+static void
+fs_block_handler(pointer data, OSTimePtr wt, pointer LastSelectMask)
+{
+    static struct timeval block_timeout;
+    CARD32     now, earliest, wakeup;
+    int                soonest;
+    FSFpePtr    conn;
+
+    XFD_ORSET((fd_set *)LastSelectMask, (fd_set *)LastSelectMask, 
+             &_fs_fd_mask);
+    /*
+     * Flush all pending output
+     */
+    if (fs_blockState & FS_PENDING_WRITE)
+       for (conn = fs_fpes; conn; conn = conn->next)
+           if (conn->blockState & FS_PENDING_WRITE)
+               _fs_flush (conn);
+    /*
+     * Check for any fpe with a complete reply, set sleep time to zero
+     */
+    if (fs_blockState & FS_COMPLETE_REPLY)
+    {
+       block_timeout.tv_sec = 0;
+       block_timeout.tv_usec = 0;
+       if (*wt == NULL)
+           *wt = &block_timeout;
+       else
+           **wt = block_timeout;
+    }
+    /*
+     * Walk through fpe list computing sleep time
+     */
+    else if (fs_blockState & (FS_BROKEN_WRITE|
+                             FS_BROKEN_CONNECTION|
+                             FS_PENDING_REPLY|
+                             FS_RECONNECTING))
+    {
+       now = GetTimeInMillis ();
+       earliest = now + 10000000;
+       for (conn = fs_fpes; conn; conn = conn->next)
+       {
+           if (conn->blockState & FS_RECONNECTING)
+           {
+               wakeup = conn->blockedConnectTime;
+               if (TimeCmp (wakeup, <, earliest))
+                   earliest = wakeup;
+           }
+           if (conn->blockState & FS_BROKEN_CONNECTION)
+           {
+               wakeup = conn->brokenConnectionTime;
+               if (TimeCmp (wakeup, <, earliest))
+                   earliest = wakeup;
+           }
+           if (conn->blockState & FS_BROKEN_WRITE)
+           {
+               wakeup = conn->brokenWriteTime;
+               if (TimeCmp (wakeup, <, earliest))
+                   earliest = wakeup;
+           }
+           if (conn->blockState & FS_PENDING_REPLY)
+           {
+               wakeup = conn->blockedReplyTime;
+               if (TimeCmp (wakeup, <, earliest))
+                   earliest = wakeup;
+           }
+       }
+       soonest = earliest - now;
+       if (soonest < 0)
+           soonest = 0;
+       block_timeout.tv_sec = soonest / 1000;
+       block_timeout.tv_usec = (soonest % 1000) * 1000;
+       if (*wt == NULL)
+           *wt = &block_timeout;
+       else if (soonest < (*wt)->tv_sec * 1000 + (*wt)->tv_usec / 1000)
+           **wt = block_timeout;
+    }
+}
+
+static void
+fs_handle_unexpected(FSFpePtr conn, fsGenericReply *rep)
+{
+    if (rep->type == FS_Event && rep->data1 == KeepAlive) 
+    {
+       fsNoopReq   req;
+
+       /* ping it back */
+       req.reqType = FS_Noop;
+       req.length = SIZEOF(fsNoopReq) >> 2;
+       _fs_add_req_log(conn, FS_Noop);
+       _fs_write(conn, (char *) &req, SIZEOF(fsNoopReq));
+    }
+    /* this should suck up unexpected replies and events */
+    _fs_done_read (conn, rep->length << 2);
+}
+
+static void
+fs_read_reply (FontPathElementPtr fpe, pointer client)
+{
+    FSFpePtr       conn = (FSFpePtr) fpe->private;
+    FSBlockDataPtr  blockrec;
+    int                    ret;
+    int                    err;
+    fsGenericReply  *rep;
+    
+    if ((rep = fs_get_reply (conn, &ret)))
+    {
+       _fs_add_rep_log (conn, rep);
+       for (blockrec = conn->blockedRequests; 
+            blockrec; 
+            blockrec = blockrec->next) 
+       {
+           if (blockrec->sequenceNumber == rep->sequenceNumber)
+               break;
+       }
+       err = Successful;
+       if (!blockrec) 
+       {
+           fs_handle_unexpected(conn, rep);
+       }
+       else
+       {
+           /* 
+            * go read it, and if we're done, 
+            * wake up the appropriate client 
+            */
+           switch (blockrec->type) {
+           case FS_OPEN_FONT:
+               blockrec->errcode = fs_do_open_font(fpe, blockrec);
+               break;
+           case FS_LOAD_GLYPHS:
+               blockrec->errcode = fs_read_glyphs(fpe, blockrec);
+               break;
+           case FS_LIST_FONTS:
+               blockrec->errcode = fs_read_list(fpe, blockrec);
+               break;
+           case FS_LIST_WITH_INFO:
+               blockrec->errcode = fs_read_list_info(fpe, blockrec);
+               break;
+           default:
+               break;
+           }
+           err = blockrec->errcode;
+           if (err != StillWorking)
+           {
+               while (blockrec) 
+               {
+                   blockrec->errcode = err;
+                   if (client != blockrec->client)
+                       ClientSignal(blockrec->client);
+                   blockrec = blockrec->depending;
+               }
+               _fs_unmark_block (conn, FS_PENDING_REPLY);
+           }
+       }
+       if (fs_reply_ready (conn))
+           _fs_mark_block (conn, FS_COMPLETE_REPLY);
+       else
+           _fs_unmark_block (conn, FS_COMPLETE_REPLY);
+    }
+}
+
+static int
+fs_wakeup(FontPathElementPtr fpe, unsigned long *mask)
+{
+    fd_set         *LastSelectMask = (fd_set *) mask;
+    FSFpePtr       conn = (FSFpePtr) fpe->private;
+
+    /* 
+     * Don't continue if the fd is -1 (which will be true when the
+     * font server terminates
+     */
+    if ((conn->blockState & FS_RECONNECTING))
+       _fs_check_reconnect (conn);
+    else if ((conn->blockState & FS_COMPLETE_REPLY) ||
+            (conn->fs_fd != -1 && FD_ISSET(conn->fs_fd, LastSelectMask)))
+       fs_read_reply (fpe, 0);
+    if (conn->blockState & (FS_PENDING_REPLY|FS_BROKEN_CONNECTION|FS_BROKEN_WRITE))
+       _fs_do_blocked (conn);
+#ifdef DEBUG
+    {
+       FSBlockDataPtr      blockrec;
+       FSBlockedFontPtr    bfont;
+       FSBlockedListPtr    blist;
+       static CARD32       lastState;
+       static FSBlockDataPtr   lastBlock;
+
+       if (conn->blockState || conn->blockedRequests || lastState || lastBlock)
+       {
+           fprintf (stderr, "  Block State 0x%x\n", (int) conn->blockState);
+           lastState = conn->blockState;
+           lastBlock = conn->blockedRequests;
+       }
+       for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next)
+       {
+           switch (blockrec->type) {
+           case FS_OPEN_FONT:
+               bfont = (FSBlockedFontPtr) blockrec->data;
+               fprintf (stderr, "  Blocked font errcode %d sequence %d state %s %s\n",
+                        blockrec->errcode,
+                        blockrec->sequenceNumber,
+                        fs_open_states[bfont->state],
+                        bfont->pfont ? 
+                        ((FSFontDataPtr) (bfont->pfont->fpePrivate))->name :
+                        "<freed>");
+               break;
+           case FS_LIST_FONTS:
+               blist = (FSBlockedListPtr) blockrec->data;
+               fprintf (stderr, "  Blocked list errcode %d sequence %d\n",
+                        blockrec->errcode, blockrec->sequenceNumber);
+               break;
+           default:
+               fprintf (stderr, "  Blocked type %d errcode %d sequence %d\n",
+                        blockrec->type,
+                        blockrec->errcode,
+                        blockrec->sequenceNumber);
+               break;
+           }
+       }
+    }
+#endif                  
+    return FALSE;
+}
+
+/*
+ * Notice a dead connection and prepare for reconnect
+ */
+
+void
+_fs_connection_died(FSFpePtr conn)
+{
+    if (conn->blockState & FS_BROKEN_CONNECTION)
+       return;
+    fs_close_conn(conn);
+    conn->brokenConnectionTime = GetTimeInMillis ();
+    _fs_mark_block (conn, FS_BROKEN_CONNECTION);
+    _fs_unmark_block (conn, FS_BROKEN_WRITE|FS_PENDING_WRITE|FS_RECONNECTING);
+}
+
+/*
+ * Signal clients that the connection has come back up
+ */
+static int
+_fs_restart_connection(FSFpePtr conn)
+{
+    FSBlockDataPtr block;
+
+    _fs_unmark_block (conn, FS_GIVE_UP);
+    while ((block = (FSBlockDataPtr) conn->blockedRequests)) 
+    {
+       if (block->errcode == StillWorking)
+       {
+           ClientSignal(block->client);
+           fs_abort_blockrec(conn, block);
+       }
+    }
+    return TRUE;
+}
+
+/*
+ * Declare this font server connection useless
+ */
+static void
+_fs_giveup (FSFpePtr conn)
+{
+    FSBlockDataPtr  block;
+
+    if (conn->blockState & FS_GIVE_UP)
+       return;
+#ifdef DEBUG
+    fprintf (stderr, "give up on FS \"%s\"\n", conn->servername);
+#endif
+    _fs_mark_block (conn, FS_GIVE_UP);
+    while ((block = (FSBlockDataPtr) conn->blockedRequests)) 
+    {
+       if (block->errcode == StillWorking)
+       {
+           ClientSignal (block->client);
+           fs_abort_blockrec (conn, block);
+       }
+    }
+    if (conn->fs_fd >= 0)
+       _fs_connection_died (conn);
+}
+
+static void
+_fs_do_blocked (FSFpePtr conn)
+{
+    CARD32      now;
+
+    now = GetTimeInMillis ();
+    if ((conn->blockState & FS_PENDING_REPLY) &&
+       TimeCmp (conn->blockedReplyTime, <=, now))
+    {
+       _fs_giveup (conn);
+    }
+    else 
+    {
+       if (conn->blockState & FS_BROKEN_CONNECTION)
+       {
+           /* Try to reconnect broken connections */
+           if (TimeCmp (conn->brokenConnectionTime, <=, now))
+               _fs_start_reconnect (conn);
+       }
+       else if (conn->blockState & FS_BROKEN_WRITE)
+       {
+           /* Try to flush blocked connections */
+           if (TimeCmp (conn->brokenWriteTime, <=, now))
+               _fs_flush (conn);
+       }
+    }
+}
+
+/*
+ * sends the actual request out
+ */
+/* ARGSUSED */
+static int
+fs_send_open_font(pointer client, FontPathElementPtr fpe, Mask flags, 
+                 char *name, int namelen, 
+                 fsBitmapFormat format, fsBitmapFormatMask fmask, 
+                 XID id, FontPtr *ppfont)
+{
+    FSFpePtr               conn = (FSFpePtr) fpe->private;
+    FontPtr                font;
+    FSBlockDataPtr         blockrec = NULL;
+    FSBlockedFontPtr       bfont;
+    FSFontDataPtr          fsd;
+    fsOpenBitmapFontReq            openreq;
+    fsQueryXInfoReq        inforeq;
+    fsQueryXExtents16Req    extreq;
+    int                            err;
+    unsigned char          buf[1024];
+
+    if (conn->blockState & FS_GIVE_UP)
+       return BadFontName;
+    if (namelen <= 0 || namelen > sizeof (buf) - 1)
+       return BadFontName;
+    
+    /*
+     * Get the font structure put together, either by reusing
+     * the existing one or creating a new one
+     */
+    if (flags & FontReopen)
+    {
+       Atom    nameatom, fn = None;
+       int     i;
+
+       font = *ppfont;
+       fsd = (FSFontDataPtr)font->fpePrivate;
+       /* This is an attempt to reopen a font.  Did the font have a
+          NAME property? */
+       if ((nameatom = MakeAtom("FONT", 4, 0)) != None)
+       {
+           for (i = 0; i < font->info.nprops; i++)
+               if (font->info.props[i].name == nameatom &&
+                   font->info.isStringProp[i])
+               {
+                   fn = font->info.props[i].value;
+                   break;
+               }
+       }
+       if (fn == None || !(name = NameForAtom(fn)))
+       {
+           name = fsd->name;
+           namelen = fsd->namelen;
+       }
+       else
+           namelen = strlen(name);
+    }
+    else
+    {
+       font = fs_create_font (fpe, name, namelen, format, fmask);
+       if (!font)
+           return AllocError;
+       
+       fsd = (FSFontDataPtr)font->fpePrivate;
+    }
+    
+    /* make a new block record, and add it to the end of the list */
+    blockrec = fs_new_block_rec(font->fpe, client, FS_OPEN_FONT);
+    if (!blockrec)
+    {
+       if (!(flags & FontReopen))
+           (*font->unload_font) (font);
+       return AllocError;
+    }
+    
+    /*
+     * Must check this before generating any protocol, otherwise we'll
+     * mess up a reconnect in progress
+     */
+    if (conn->blockState & (FS_BROKEN_CONNECTION | FS_RECONNECTING))
+    {
+       _fs_pending_reply (conn);
+       return Suspended;
+    }
+       
+    fsd->generation = conn->generation;
+
+    bfont = (FSBlockedFontPtr) blockrec->data;
+    bfont->fontid = fsd->fontid;
+    bfont->pfont = font;
+    bfont->state = FS_OPEN_REPLY;
+    bfont->flags = flags;
+    bfont->format = fsd->format;
+    bfont->clients_depending = (FSClientsDependingPtr)0;
+    bfont->freeFont = (flags & FontReopen) == 0;
+
+    _fs_client_access (conn, client, (flags & FontOpenSync) != 0);
+    _fs_client_resolution(conn);
+
+    /* do an FS_OpenFont, FS_QueryXInfo and FS_QueryXExtents */
+    buf[0] = (unsigned char) namelen;
+    memcpy(&buf[1], name, namelen);
+    openreq.reqType = FS_OpenBitmapFont;
+    openreq.pad = 0;
+    openreq.fid = fsd->fontid;
+    openreq.format_hint = fsd->format;
+    openreq.format_mask = fsd->fmask;
+    openreq.length = (SIZEOF(fsOpenBitmapFontReq) + namelen + 4) >> 2;
+
+    _fs_add_req_log(conn, FS_OpenBitmapFont);
+    _fs_write(conn, (char *) &openreq, SIZEOF(fsOpenBitmapFontReq));
+    _fs_write_pad(conn, (char *) buf, namelen + 1);
+
+    blockrec->sequenceNumber = conn->current_seq;
+    
+    inforeq.reqType = FS_QueryXInfo;
+    inforeq.pad = 0;
+    inforeq.id = fsd->fontid;
+    inforeq.length = SIZEOF(fsQueryXInfoReq) >> 2;
+
+    bfont->queryInfoSequence = conn->current_seq + 1;
+    
+    _fs_add_req_log(conn, FS_QueryXInfo);
+    _fs_write(conn, (char *) &inforeq, SIZEOF(fsQueryXInfoReq));
+    
+    if (!(bfont->flags & FontReopen))
+    {
+       extreq.reqType = FS_QueryXExtents16;
+       extreq.range = fsTrue;
+       extreq.fid = fsd->fontid;
+       extreq.num_ranges = 0;
+       extreq.length = SIZEOF(fsQueryXExtents16Req) >> 2;
+       
+       bfont->queryExtentsSequence = conn->current_seq + 1;
+       
+       _fs_add_req_log(conn, FS_QueryXExtents16);
+       _fs_write(conn, (char *) &extreq, SIZEOF(fsQueryXExtents16Req));
+    }
+    
+#ifdef NCD
+    if (configData.ExtendedFontDiags) 
+    {
+       memcpy(buf, name, MIN(256, namelen));
+       buf[MIN(256, namelen)] = '\0';
+       printf("Requesting font \"%s\" from font server \"%s\"\n",
+              buf, font->fpe->name);
+    }
+#endif
+    _fs_prepare_for_reply (conn);
+    
+    err = blockrec->errcode;
+    if (bfont->flags & FontOpenSync)
+    {
+       while (blockrec->errcode == StillWorking)
+       {
+           if (fs_await_reply (conn) != FSIO_READY)
+           {
+               blockrec->errcode = BadFontName;
+               break;
+           }
+           fs_read_reply (font->fpe, client);
+       }
+       err = blockrec->errcode;
+       if (err == Successful)
+           *ppfont = bfont->pfont;
+       else
+           fs_cleanup_bfont (bfont);
+       bfont->freeFont = FALSE;
+       _fs_remove_block_rec (conn, blockrec);
+    }
+    return err == StillWorking ? Suspended : err;
+}
+
+static void
+fs_send_query_bitmaps(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
+{
+    FSFpePtr               conn = (FSFpePtr) fpe->private;
+    FSBlockedFontPtr       bfont = (FSBlockedFontPtr) blockrec->data;
+    fsQueryXBitmaps16Req    bitreq;
+
+    /* send the request */
+    bitreq.reqType = FS_QueryXBitmaps16;
+    bitreq.fid = bfont->fontid;
+    bitreq.format = bfont->format;
+    bitreq.range = TRUE;
+    bitreq.length = SIZEOF(fsQueryXBitmaps16Req) >> 2;
+    bitreq.num_ranges = 0;
+
+    bfont->queryBitmapsSequence = conn->current_seq + 1;
+    
+    _fs_add_req_log(conn, FS_QueryXBitmaps16);
+    _fs_write(conn, (char *) &bitreq, SIZEOF(fsQueryXBitmaps16Req));
+}
+
+/* ARGSUSED */
+static int
+fs_open_font(pointer client, FontPathElementPtr fpe, Mask flags, 
+            char *name, int namelen, 
+            fsBitmapFormat format, fsBitmapFormatMask fmask, 
+            XID id, FontPtr *ppfont,
+            char **alias, FontPtr non_cachable_font)
+{
+    FSFpePtr           conn = (FSFpePtr) fpe->private;
+    FSBlockDataPtr     blockrec;
+    FSBlockedFontPtr   bfont;
+    int                        err;
+
+    /* libfont interface expects ImageRectMin glyphs */
+    format = (format & ~BitmapFormatImageRectMask) | BitmapFormatImageRectMin;
+
+    *alias = (char *) 0;
+    for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next)
+    {
+       if (blockrec->type == FS_OPEN_FONT && blockrec->client == client) 
+       {
+           err = blockrec->errcode;
+           if (err == StillWorking)
+               return Suspended;
+           
+           bfont = (FSBlockedFontPtr) blockrec->data;
+           if (err == Successful)
+               *ppfont = bfont->pfont;
+           else
+               fs_cleanup_bfont (bfont);
+           _fs_remove_block_rec (conn, blockrec);
+           return err;
+       }
+    }
+    return fs_send_open_font(client, fpe, flags, name, namelen, format, fmask,
+                            id, ppfont);
+}
+
+/* ARGSUSED */
+static int
+fs_send_close_font(FontPathElementPtr fpe, Font id)
+{
+    FSFpePtr    conn = (FSFpePtr) fpe->private;
+    fsCloseReq  req;
+
+    if (conn->blockState & FS_GIVE_UP)
+       return Successful;
+    /* tell the font server to close the font */
+    req.reqType = FS_CloseFont;
+    req.pad = 0;
+    req.length = SIZEOF(fsCloseReq) >> 2;
+    req.id = id;
+    _fs_add_req_log(conn, FS_CloseFont);
+    _fs_write(conn, (char *) &req, SIZEOF(fsCloseReq));
+
+    return Successful;
+}
+
+/* ARGSUSED */
+static void
+fs_close_font(FontPathElementPtr fpe, FontPtr pfont)
+{
+    FSFontDataPtr   fsd = (FSFontDataPtr) pfont->fpePrivate;
+    FSFpePtr       conn = (FSFpePtr) fpe->private;
+
+    if (conn->generation == fsd->generation)
+       fs_send_close_font(fpe, fsd->fontid);
+
+#ifdef DEBUG
+    {
+       FSBlockDataPtr      blockrec;
+       FSBlockedFontPtr    bfont;
+
+       for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next)
+       {
+           if (blockrec->type == FS_OPEN_FONT)
+           {
+               bfont = (FSBlockedFontPtr) blockrec->data;
+               if (bfont->pfont == pfont)
+                   fprintf (stderr, "closing font which hasn't been opened\n");
+           }
+       }
+    }
+#endif
+    (*pfont->unload_font) (pfont);
+}
+
+static int
+fs_read_glyphs(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
+{
+    FSBlockedGlyphPtr      bglyph = (FSBlockedGlyphPtr) blockrec->data;
+    FSBlockedFontPtr       bfont = (FSBlockedFontPtr) blockrec->data;
+    FSFpePtr               conn = (FSFpePtr) fpe->private;
+    FontPtr                pfont = bglyph->pfont;
+                                       /* works for either blocked font
+                                          or glyph rec...  pfont is at
+                                          the very beginning of both
+                                          blockrec->data structures */
+    FSFontDataPtr          fsd = (FSFontDataPtr) (pfont->fpePrivate);
+    FSFontPtr              fsdata = (FSFontPtr) pfont->fontPrivate;
+    FontInfoPtr                    pfi = &pfont->info;
+    fsQueryXBitmaps16Reply  *rep;
+    char                   *buf;
+    fsOffset32             *ppbits;
+    fsOffset32             local_off;
+    char                   *off_adr;
+    pointer                pbitmaps;
+    char                   *bits, *allbits;
+#ifdef DEBUG
+    char                   *origallbits;
+#endif
+    int                            i,
+                           err;
+    int                            nranges = 0;
+    int                            ret;
+    fsRange                *nextrange = 0;
+    unsigned long          minchar, maxchar;
+
+    rep = (fsQueryXBitmaps16Reply *) fs_get_reply (conn, &ret);
+    if (!rep || rep->type == FS_Error)
+    {
+       if (ret == FSIO_BLOCK)
+           return StillWorking;
+       if (rep)
+           _fs_done_read (conn, rep->length << 2);
+       err = AllocError;
+       goto bail;
+    }
+
+    buf = (char *) rep;
+    buf += SIZEOF (fsQueryXBitmaps16Reply);
+
+    ppbits = (fsOffset32 *) buf;
+    buf += SIZEOF (fsOffset32) * (rep->num_chars);
+
+    pbitmaps = (pointer ) buf;
+
+    if (blockrec->type == FS_LOAD_GLYPHS)
+    {
+       nranges = bglyph->num_expected_ranges;
+       nextrange = bglyph->expected_ranges;
+    }
+
+    /* place the incoming glyphs */
+    if (nranges)
+    {
+       /* We're operating under the assumption that the ranges
+          requested in the LoadGlyphs call were all legal for this
+          font, and that individual ranges do not cover multiple
+          rows...  fs_build_range() is designed to ensure this. */
+       minchar = (nextrange->min_char_high - pfi->firstRow) *
+                 (pfi->lastCol - pfi->firstCol + 1) +
+                 nextrange->min_char_low - pfi->firstCol;
+       maxchar = (nextrange->max_char_high - pfi->firstRow) *
+                 (pfi->lastCol - pfi->firstCol + 1) +
+                 nextrange->max_char_low - pfi->firstCol;
+       nextrange++;
+    }
+    else
+    {
+       minchar = 0;
+       maxchar = rep->num_chars;
+    }
+
+    off_adr = (char *)ppbits;
+    
+    allbits = fs_alloc_glyphs (pfont, rep->nbytes);
+    
+    if (!allbits)
+    {
+       err = AllocError;
+       goto bail;
+    }
+    
+#ifdef DEBUG
+    origallbits = allbits;
+    fprintf (stderr, "Reading %d glyphs in %d bytes for %s\n",
+            (int) rep->num_chars, (int) rep->nbytes, fsd->name);
+#endif
+    
+    for (i = 0; i < rep->num_chars; i++)
+    {
+       memcpy(&local_off, off_adr, SIZEOF(fsOffset32));        /* align it */
+       if (blockrec->type == FS_OPEN_FONT ||
+           fsdata->encoding[minchar].bits == &_fs_glyph_requested)
+       {
+           /*
+            * Broken X font server returns bits for missing characters
+            * when font is padded
+            */
+           if (NONZEROMETRICS(&fsdata->encoding[minchar].metrics))
+           {
+               if (local_off.length)
+               {
+                   bits = allbits;
+                   allbits += local_off.length;
+                   memcpy(bits, (char *)pbitmaps + local_off.position,
+                          local_off.length);
+               }
+               else
+                   bits = &_fs_glyph_zero_length;
+           }
+           else
+               bits = 0;
+           if (fsdata->encoding[minchar].bits == &_fs_glyph_requested)
+               fsd->glyphs_to_get--;
+           fsdata->encoding[minchar].bits = bits;
+       }
+       if (minchar++ == maxchar)
+       {
+           if (!--nranges) break;
+           minchar = (nextrange->min_char_high - pfi->firstRow) *
+                     (pfi->lastCol - pfi->firstCol + 1) +
+                     nextrange->min_char_low - pfi->firstCol;
+           maxchar = (nextrange->max_char_high - pfi->firstRow) *
+                     (pfi->lastCol - pfi->firstCol + 1) +
+                     nextrange->max_char_low - pfi->firstCol;
+           nextrange++;
+       }
+       off_adr += SIZEOF(fsOffset32);
+    }
+#ifdef DEBUG
+    fprintf (stderr, "Used %d bytes instead of %d\n",
+            (int) (allbits - origallbits), (int) rep->nbytes);
+#endif
+
+    if (blockrec->type == FS_OPEN_FONT)
+    {
+       fsd->glyphs_to_get = 0;
+       bfont->state = FS_DONE_REPLY;
+    }
+    err = Successful;
+
+bail:
+    _fs_done_read (conn, rep->length << 2);
+    return err;
+}
+
+static int
+fs_send_load_glyphs(pointer client, FontPtr pfont, 
+                   int nranges, fsRange *ranges)
+{
+    FontPathElementPtr     fpe = pfont->fpe;
+    FSFpePtr               conn = (FSFpePtr) fpe->private;
+    FSBlockedGlyphPtr      blockedglyph;
+    fsQueryXBitmaps16Req    req;
+    FSBlockDataPtr         blockrec;
+
+    if (conn->blockState & FS_GIVE_UP)
+       return BadCharRange;
+    
+    /* make a new block record, and add it to the end of the list */
+    blockrec = fs_new_block_rec(fpe, client, FS_LOAD_GLYPHS);
+    if (!blockrec)
+       return AllocError;
+    blockedglyph = (FSBlockedGlyphPtr) blockrec->data;
+    blockedglyph->pfont = pfont;
+    blockedglyph->num_expected_ranges = nranges;
+    /* Assumption: it's our job to free ranges */
+    blockedglyph->expected_ranges = ranges;
+    blockedglyph->clients_depending = (FSClientsDependingPtr)0;
+
+    if (conn->blockState & (FS_BROKEN_CONNECTION|FS_RECONNECTING))
+    {
+       _fs_pending_reply (conn);
+       return Suspended;
+    }
+    
+    /* send the request */
+    req.reqType = FS_QueryXBitmaps16;
+    req.fid = ((FSFontDataPtr) pfont->fpePrivate)->fontid;
+    req.format = pfont->format;
+    if (pfont->info.terminalFont)
+       req.format = (req.format & ~(BitmapFormatImageRectMask)) |
+                    BitmapFormatImageRectMax;
+    req.range = TRUE;
+    /* each range takes up 4 bytes */
+    req.length = (SIZEOF(fsQueryXBitmaps16Req) >> 2) + nranges;
+    req.num_ranges = nranges * 2;      /* protocol wants count of fsChar2bs */
+    _fs_add_req_log(conn, FS_QueryXBitmaps16);
+    _fs_write(conn, (char *) &req, SIZEOF(fsQueryXBitmaps16Req));
+
+    blockrec->sequenceNumber = conn->current_seq;
+    
+    /* Send ranges to the server... pack into a char array by hand
+       to avoid structure-packing portability problems and to
+       handle swapping for version1 protocol */
+    if (nranges)
+    {
+#define RANGE_BUFFER_SIZE 64
+#define RANGE_BUFFER_SIZE_MASK 63
+       int i;
+       char range_buffer[RANGE_BUFFER_SIZE * 4];
+       char *range_buffer_p;
+
+       range_buffer_p = range_buffer;
+       for (i = 0; i < nranges;)
+       {
+           if (conn->fsMajorVersion > 1)
+           {
+               *range_buffer_p++ = ranges[i].min_char_high;
+               *range_buffer_p++ = ranges[i].min_char_low;
+               *range_buffer_p++ = ranges[i].max_char_high;
+               *range_buffer_p++ = ranges[i].max_char_low;
+           }
+           else
+           {
+               *range_buffer_p++ = ranges[i].min_char_low;
+               *range_buffer_p++ = ranges[i].min_char_high;
+               *range_buffer_p++ = ranges[i].max_char_low;
+               *range_buffer_p++ = ranges[i].max_char_high;
+           }
+
+           if (!(++i & RANGE_BUFFER_SIZE_MASK))
+           {
+               _fs_write(conn, range_buffer, RANGE_BUFFER_SIZE * 4);
+               range_buffer_p = range_buffer;
+           }
+       }
+       if (i &= RANGE_BUFFER_SIZE_MASK)
+           _fs_write(conn, range_buffer, i * 4);
+    }
+
+    _fs_prepare_for_reply (conn);
+    return Suspended;
+}
+
+
+extern pointer serverClient;   /* This could be any number that
+                                  doesn't conflict with existing
+                                  client values. */
+
+static int
+_fs_load_glyphs(pointer client, FontPtr pfont, Bool range_flag, 
+               unsigned int nchars, int item_size, unsigned char *data)
+{
+    FSFpePtr               conn = (FSFpePtr) pfont->fpe->private;
+    int                            nranges = 0;
+    fsRange                *ranges = NULL;
+    int                            res;
+    FSBlockDataPtr         blockrec;
+    FSBlockedGlyphPtr      blockedglyph;
+    FSClientsDependingPtr   *clients_depending = NULL;
+    int                            err;
+
+    /* see if the result is already there */
+    for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next)
+    {
+       if (blockrec->type == FS_LOAD_GLYPHS)
+       {
+           blockedglyph = (FSBlockedGlyphPtr) blockrec->data;
+           if (blockedglyph->pfont == pfont)
+           {
+               /* Look for this request */
+               if (blockrec->client == client)
+               {
+                   err = blockrec->errcode;
+                   if (err == StillWorking)
+                       return Suspended;
+                   _fs_signal_clients_depending(&blockedglyph->clients_depending);
+                   _fs_remove_block_rec(conn, blockrec);
+                   return err;
+               }
+               /* We've found an existing LoadGlyphs blockrec for this
+                  font but for another client.  Rather than build a
+                  blockrec for it now (which entails some complex
+                  maintenance), we'll add it to a queue of clients to
+                  be signalled when the existing LoadGlyphs is
+                  completed.  */
+               clients_depending = &blockedglyph->clients_depending;
+               break;
+           }
+       }
+       else if (blockrec->type == FS_OPEN_FONT)
+       {
+           FSBlockedFontPtr bfont;
+           bfont = (FSBlockedFontPtr) blockrec->data;
+           if (bfont->pfont == pfont)
+           {
+               /*
+                * An OpenFont is pending for this font, this must
+                * be from a reopen attempt, so finish the open
+                * attempt and retry the LoadGlyphs
+                */
+               if (blockrec->client == client)
+               {
+                   err = blockrec->errcode;
+                   if (err == StillWorking)
+                       return Suspended;
+                   
+                   _fs_signal_clients_depending(&bfont->clients_depending);
+                   _fs_remove_block_rec(conn, blockrec);
+                   if (err != Successful)
+                       return err;
+                   break;
+               }
+               /* We've found an existing OpenFont blockrec for this
+                  font but for another client.  Rather than build a
+                  blockrec for it now (which entails some complex
+                  maintenance), we'll add it to a queue of clients to
+                  be signalled when the existing OpenFont is
+                  completed.  */
+               if (blockrec->errcode == StillWorking)
+               {
+                   clients_depending = &bfont->clients_depending;
+                   break;
+               }
+           }
+       }
+    }
+
+    /*
+     * see if the desired glyphs already exist, and return Successful if they
+     * do, otherwise build up character range/character string
+     */
+    res = fs_build_range(pfont, range_flag, nchars, item_size, data,
+                        &nranges, &ranges);
+
+    switch (res)
+    {
+       case AccessDone:
+           return Successful;
+
+       case Successful:
+           break;
+
+       default:
+           return res;
+    }
+
+    /*
+     * If clients_depending is not null, this request must wait for
+     * some prior request(s) to complete.
+     */
+    if (clients_depending)
+    {
+       /* Since we're not ready to send the load_glyphs request yet,
+          clean up the damage (if any) caused by the fs_build_range()
+          call. */
+       if (nranges)
+       {
+           _fs_clean_aborted_loadglyphs(pfont, nranges, ranges);
+           free(ranges);
+       }
+       return _fs_add_clients_depending(clients_depending, client);
+    }
+
+    /*
+     * If fsd->generation != conn->generation, the font has been closed
+     * due to a lost connection.  We will reopen it, which will result
+     * in one of three things happening:
+     *  1) The open will succeed and obtain the same font.  Life
+     *     is wonderful.
+     *  2) The open will fail.  There is code above to recognize this
+     *     and flunk the LoadGlyphs request.  The client might not be
+     *     thrilled.
+     *  3) Worst case: the open will succeed but the font we open will
+     *     be different.  The fs_read_query_info() procedure attempts
+     *     to detect this by comparing the existing metrics and
+     *     properties against those of the reopened font... if they
+     *     don't match, we flunk the reopen, which eventually results
+     *     in flunking the LoadGlyphs request.  We could go a step
+     *     further and compare the extents, but this should be
+     *     sufficient.
+     */
+    if (((FSFontDataPtr)pfont->fpePrivate)->generation != conn->generation)
+    {
+       /* Since we're not ready to send the load_glyphs request yet,
+          clean up the damage caused by the fs_build_range() call. */
+       _fs_clean_aborted_loadglyphs(pfont, nranges, ranges);
+       free(ranges);
+
+       /* Now try to reopen the font. */
+       return fs_send_open_font(client, pfont->fpe,
+                                (Mask)FontReopen, (char *)0, 0,
+                                (fsBitmapFormat)0, (fsBitmapFormatMask)0,
+                                (XID)0, &pfont);
+    }
+
+    return fs_send_load_glyphs(client, pfont, nranges, ranges);
+}
+
+int
+fs_load_all_glyphs(FontPtr pfont)
+{
+    int                err;
+    FSFpePtr   conn = (FSFpePtr) pfont->fpe->private;
+
+    /*
+     * The purpose of this procedure is to load all glyphs in the event
+     * that we're dealing with someone who doesn't understand the finer
+     * points of glyph caching...  it is called from _fs_get_glyphs() if
+     * the latter is called to get glyphs that have not yet been loaded.
+     * We assume that the caller will not know how to handle a return
+     * value of Suspended (usually the case for a GetGlyphs() caller),
+     * so this procedure hangs around, freezing the server, for the
+     * request to complete.  This is an unpleasant kluge called to
+     * perform an unpleasant job that, we hope, will never be required.
+     */
+
+    while ((err = _fs_load_glyphs(serverClient, pfont, TRUE, 0, 0, NULL)) ==
+          Suspended)
+    {
+       if (fs_await_reply (conn) != FSIO_READY)
+       {
+           /* Get rid of blockrec */
+           fs_client_died(serverClient, pfont->fpe);
+           err = BadCharRange;
+           break;
+       }
+       fs_read_reply (pfont->fpe, serverClient);
+    }
+    return err;
+}
+
+static int
+fs_read_list(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
+{
+    FSFpePtr           conn = (FSFpePtr) fpe->private;
+    FSBlockedListPtr   blist = (FSBlockedListPtr) blockrec->data;
+    fsListFontsReply   *rep;
+    char               *data;
+    int                        length,
+                       i,
+                       ret;
+    int                        err;
+
+    rep = (fsListFontsReply *) fs_get_reply (conn, &ret);
+    if (!rep || rep->type == FS_Error)
+    {
+       if (ret == FSIO_BLOCK)
+           return StillWorking;
+       if (rep)
+           _fs_done_read (conn, rep->length << 2);
+       return AllocError;
+    }
+    data = (char *) rep + SIZEOF (fsListFontsReply);
+
+    err = Successful;
+    /* copy data into FontPathRecord */
+    for (i = 0; i < rep->nFonts; i++) 
+    {
+       length = *(unsigned char *)data++;
+       err = AddFontNamesName(blist->names, data, length);
+       if (err != Successful)
+           break;
+       data += length;
+    }
+    _fs_done_read (conn, rep->length << 2);
+    return err;
+}
+
+static int
+fs_send_list_fonts(pointer client, FontPathElementPtr fpe, char *pattern, 
+                  int patlen, int maxnames, FontNamesPtr newnames)
+{
+    FSFpePtr           conn = (FSFpePtr) fpe->private;
+    FSBlockDataPtr     blockrec;
+    FSBlockedListPtr   blockedlist;
+    fsListFontsReq     req;
+
+    if (conn->blockState & FS_GIVE_UP)
+       return BadFontName;
+    
+    /* make a new block record, and add it to the end of the list */
+    blockrec = fs_new_block_rec(fpe, client, FS_LIST_FONTS);
+    if (!blockrec)
+       return AllocError;
+    blockedlist = (FSBlockedListPtr) blockrec->data;
+    blockedlist->names = newnames;
+
+    if (conn->blockState & (FS_BROKEN_CONNECTION | FS_RECONNECTING))
+    {
+       _fs_pending_reply (conn);
+       return Suspended;
+    }
+       
+    _fs_client_access (conn, client, FALSE);
+    _fs_client_resolution(conn);
+
+    /* send the request */
+    req.reqType = FS_ListFonts;
+    req.pad = 0;
+    req.maxNames = maxnames;
+    req.nbytes = patlen;
+    req.length = (SIZEOF(fsListFontsReq) + patlen + 3) >> 2;
+    _fs_add_req_log(conn, FS_ListFonts);
+    _fs_write(conn, (char *) &req, SIZEOF(fsListFontsReq));
+    _fs_write_pad(conn, (char *) pattern, patlen);
+
+    blockrec->sequenceNumber = conn->current_seq;
+    
+#ifdef NCD
+    if (configData.ExtendedFontDiags) {
+       char        buf[256];
+
+       memcpy(buf, pattern, MIN(256, patlen));
+       buf[MIN(256, patlen)] = '\0';
+       printf("Listing fonts on pattern \"%s\" from font server \"%s\"\n",
+              buf, fpe->name);
+    }
+#endif
+
+    _fs_prepare_for_reply (conn);
+    return Suspended;
+}
+
+static int
+fs_list_fonts(pointer client, FontPathElementPtr fpe, 
+             char *pattern, int patlen, int maxnames, FontNamesPtr newnames)
+{
+    FSFpePtr           conn = (FSFpePtr) fpe->private;
+    FSBlockDataPtr     blockrec;
+    int                        err;
+
+    /* see if the result is already there */
+    for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next)
+    {
+       if (blockrec->type == FS_LIST_FONTS && blockrec->client == client) 
+       {
+           err = blockrec->errcode;
+           if (err == StillWorking)
+               return Suspended;
+           _fs_remove_block_rec(conn, blockrec);
+           return err;
+       }
+    }
+
+    /* didn't find waiting record, so send a new one */
+    return fs_send_list_fonts(client, fpe, pattern, patlen, maxnames, newnames);
+}
+
+/*
+ * Read a single list info reply and restart for the next reply
+ */
+static int
+fs_read_list_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
+{
+    FSBlockedListInfoPtr       binfo = (FSBlockedListInfoPtr) blockrec->data;
+    fsListFontsWithXInfoReply  *rep;
+    char                       *buf;
+    FSFpePtr                   conn = (FSFpePtr) fpe->private;
+    fsPropInfo                 *pi;
+    fsPropOffset               *po;
+    pointer                    pd;
+    int                                ret;
+    int                                err;
+
+    /* clean up anything from the last trip */
+    _fs_free_props (&binfo->info);
+
+    rep = (fsListFontsWithXInfoReply *) fs_get_reply (conn, &ret);
+    if (!rep || rep->type == FS_Error)
+    {
+       if (ret == FSIO_BLOCK)
+           return StillWorking;
+       binfo->status = FS_LFWI_FINISHED;
+       err = AllocError;
+       goto done;
+    }
+    /*
+     * Normal termination -- the list ends with a name of length 0
+     */
+    if (rep->nameLength == 0)
+    {
+#ifdef DEBUG
+       fprintf (stderr, "fs_read_list_info done\n");
+#endif
+       binfo->status = FS_LFWI_FINISHED;
+       err = BadFontName;
+       goto done;
+    }
+
+    buf = (char *) rep + SIZEOF (fsListFontsWithXInfoReply);
+    
+    /*
+     * The original FS implementation didn't match
+     * the spec, version 1 was respecified to match the FS.
+     * Version 2 matches the original intent
+     */
+    if (conn->fsMajorVersion <= 1)
+    {
+       memcpy (binfo->name, buf, rep->nameLength);
+       buf += _fs_pad_length (rep->nameLength);
+    }
+    pi = (fsPropInfo *) buf;
+    buf += SIZEOF (fsPropInfo);
+    po = (fsPropOffset *) buf;
+    buf += pi->num_offsets * SIZEOF (fsPropOffset);
+    pd = (pointer) buf;
+    buf += pi->data_len;
+    if (conn->fsMajorVersion > 1)
+    {
+       memcpy (binfo->name, buf, rep->nameLength);
+       buf += _fs_pad_length (rep->nameLength);
+    }
+
+#ifdef DEBUG
+    binfo->name[rep->nameLength] = '\0';
+    fprintf (stderr, "fs_read_list_info %s\n", binfo->name);
+#endif
+    err = _fs_convert_lfwi_reply(conn, &binfo->info, rep, pi, po, pd);
+    if (err != Successful)
+    {
+       binfo->status = FS_LFWI_FINISHED;
+       goto done;
+    }
+    binfo->namelen = rep->nameLength;
+    binfo->remaining = rep->nReplies;
+
+    binfo->status = FS_LFWI_REPLY;
+    
+    /* disable this font server until we've processed this response */
+    _fs_unmark_block (conn, FS_COMPLETE_REPLY);
+    FD_CLR(conn->fs_fd, &_fs_fd_mask);
+done:    
+    _fs_done_read (conn, rep->length << 2);
+    return err;
+}
+
+/* ARGSUSED */
+static int
+fs_start_list_with_info(pointer client, FontPathElementPtr fpe, 
+                       char *pattern, int len, int maxnames, pointer *pdata)
+{
+    FSFpePtr               conn = (FSFpePtr) fpe->private;
+    FSBlockDataPtr         blockrec;
+    FSBlockedListInfoPtr    binfo;
+    fsListFontsWithXInfoReq req;
+
+    if (conn->blockState & FS_GIVE_UP)
+       return BadFontName;
+
+    /* make a new block record, and add it to the end of the list */
+    blockrec = fs_new_block_rec(fpe, client, FS_LIST_WITH_INFO);
+    if (!blockrec)
+       return AllocError;
+    
+    binfo = (FSBlockedListInfoPtr) blockrec->data;
+    bzero((char *) binfo, sizeof(FSBlockedListInfoRec));
+    binfo->status = FS_LFWI_WAITING;
+
+    if (conn->blockState & (FS_BROKEN_CONNECTION | FS_RECONNECTING))
+    {
+       _fs_pending_reply (conn);
+       return Suspended;
+    }
+    
+    _fs_client_access (conn, client, FALSE);
+    _fs_client_resolution(conn);
+
+    /* send the request */
+    req.reqType = FS_ListFontsWithXInfo;
+    req.pad = 0;
+    req.maxNames = maxnames;
+    req.nbytes = len;
+    req.length = (SIZEOF(fsListFontsWithXInfoReq) + len + 3) >> 2;
+    _fs_add_req_log(conn, FS_ListFontsWithXInfo);
+    (void) _fs_write(conn, (char *) &req, SIZEOF(fsListFontsWithXInfoReq));
+    (void) _fs_write_pad(conn, pattern, len);
+
+    blockrec->sequenceNumber = conn->current_seq;
+    
+#ifdef NCD
+    if (configData.ExtendedFontDiags) {
+       char        buf[256];
+
+       memcpy(buf, pattern, MIN(256, len));
+       buf[MIN(256, len)] = '\0';
+       printf("Listing fonts with info on pattern \"%s\" from font server \"%s\"\n",
+              buf, fpe->name);
+    }
+#endif
+
+    _fs_prepare_for_reply (conn);
+    return Successful;
+}
+
+/* ARGSUSED */
+static int
+fs_next_list_with_info(pointer client, FontPathElementPtr fpe, 
+                      char **namep, int *namelenp, 
+                      FontInfoPtr *pFontInfo, int *numFonts,
+                      pointer private)
+{
+    FSFpePtr               conn = (FSFpePtr) fpe->private;
+    FSBlockDataPtr         blockrec;
+    FSBlockedListInfoPtr    binfo;
+    int                            err;
+
+    /* see if the result is already there */
+    for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next)
+       if (blockrec->type == FS_LIST_WITH_INFO && blockrec->client == client) 
+           break;
+
+    if (!blockrec)
+    {
+       /* The only good reason for not finding a blockrec would be if
+          disconnect/reconnect to the font server wiped it out and the
+          code that called us didn't do the right thing to create
+          another one.  Under those circumstances, we need to return an
+          error to prevent that code from attempting to interpret the
+          information we don't return.  */
+       return BadFontName;
+    }
+
+    binfo = (FSBlockedListInfoPtr) blockrec->data;
+    
+    if (binfo->status == FS_LFWI_WAITING)
+       return Suspended;
+
+    *namep = binfo->name;
+    *namelenp = binfo->namelen;
+    *pFontInfo = &binfo->info;
+    *numFonts = binfo->remaining;
+    
+    /* Restart reply processing from this font server */
+    FD_SET(conn->fs_fd, &_fs_fd_mask);
+    if (fs_reply_ready (conn))
+       _fs_mark_block (conn, FS_COMPLETE_REPLY);
+    
+    err = blockrec->errcode;
+    switch (binfo->status) {
+    case FS_LFWI_FINISHED:
+       _fs_remove_block_rec(conn, blockrec);
+       break;
+    case FS_LFWI_REPLY:
+       binfo->status = FS_LFWI_WAITING;
+       blockrec->errcode = StillWorking;
+       conn->blockedReplyTime = GetTimeInMillis () + FontServerRequestTimeout;
+       _fs_mark_block (conn, FS_PENDING_REPLY);
+       break;
+    }
+    
+    return err;
+}
+
+/*
+ * Called when client exits
+ */
+
+static void
+fs_client_died(pointer client, FontPathElementPtr fpe)
+{
+    FSFpePtr       conn = (FSFpePtr) fpe->private;
+    FSBlockDataPtr  blockrec,
+                   depending;
+    FSClientPtr            *prev, cur;
+    fsFreeACReq            freeac;
+
+    for (prev = &conn->clients; (cur = *prev); prev = &cur->next)
+    {
+       if (cur->client == client) {
+           freeac.reqType = FS_FreeAC;
+           freeac.pad = 0;
+           freeac.id = cur->acid;
+           freeac.length = sizeof (fsFreeACReq) >> 2;
+           _fs_add_req_log(conn, FS_FreeAC);
+           _fs_write (conn, (char *) &freeac, sizeof (fsFreeACReq));
+           *prev = cur->next;
+           free (cur);
+           break;
+       }
+    }
+    /* find a pending requests */
+    for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next)
+       if (blockrec->client == client)
+           break;
+    
+    if (!blockrec)
+       return;
+    
+    /* replace the client pointers in this block rec with the chained one */
+    if ((depending = blockrec->depending)) 
+    {
+       blockrec->client = depending->client;
+       blockrec->depending = depending->depending;
+       blockrec = depending;
+    }
+    fs_abort_blockrec(conn, blockrec);
+}
+
+static void
+_fs_client_access (FSFpePtr conn, pointer client, Bool sync)
+{
+    FSClientPtr        *prev,      cur;
+    fsCreateACReq          crac;
+    fsSetAuthorizationReq   setac;
+    char                   *authorizations;
+    int                            authlen;
+    Bool                   new_cur = FALSE;
+    char                   padding[4] = { 0, 0, 0, 0 };
+
+#ifdef DEBUG
+    if (conn->blockState & (FS_RECONNECTING|FS_BROKEN_CONNECTION))
+    {
+       fprintf (stderr, "Sending requests without a connection\n");
+    }
+#endif
+    for (prev = &conn->clients; (cur = *prev); prev = &cur->next)
+    {
+       if (cur->client == client)
+       {
+           if (prev != &conn->clients)
+           {
+               *prev = cur->next;
+               cur->next = conn->clients;
+               conn->clients = cur;
+           }
+           break;
+       }
+    }
+    if (!cur)
+    {
+       cur = malloc (sizeof (FSClientRec));
+       if (!cur)
+           return;
+       cur->client = client;
+       cur->next = conn->clients;
+       conn->clients = cur;
+       cur->acid = GetNewFontClientID ();
+       new_cur = TRUE;
+    }
+    if (new_cur || cur->auth_generation != client_auth_generation(client))
+    {
+       if (!new_cur)
+       {
+           fsFreeACReq freeac;
+           freeac.reqType = FS_FreeAC;
+           freeac.pad = 0;
+           freeac.id = cur->acid;
+           freeac.length = sizeof (fsFreeACReq) >> 2;
+           _fs_add_req_log(conn, FS_FreeAC);
+           _fs_write (conn, (char *) &freeac, sizeof (fsFreeACReq));
+       }
+       crac.reqType = FS_CreateAC;
+       crac.num_auths = set_font_authorizations(&authorizations, &authlen,
+                                                client);
+       /* Work around bug in xfs versions up through modular release 1.0.8
+          which rejects CreateAC packets with num_auths = 0 & authlen < 4 */
+       if (crac.num_auths == 0) {
+           authorizations = padding;
+           authlen = 4;
+       } else {
+           authlen = (authlen + 3) & ~0x3;
+       }
+       crac.length = (sizeof (fsCreateACReq) + authlen) >> 2;
+       crac.acid = cur->acid;
+       _fs_add_req_log(conn, FS_CreateAC);
+       _fs_write(conn, (char *) &crac, sizeof (fsCreateACReq));
+       _fs_write(conn, authorizations, authlen);
+       /* ignore reply; we don't even care about it */
+       conn->curacid = 0;
+       cur->auth_generation = client_auth_generation(client);
+    }
+    if (conn->curacid != cur->acid)
+    {
+       setac.reqType = FS_SetAuthorization;
+       setac.pad = 0;
+       setac.length = sizeof (fsSetAuthorizationReq) >> 2;
+       setac.id = cur->acid;
+       _fs_add_req_log(conn, FS_SetAuthorization);
+       _fs_write(conn, (char *) &setac, sizeof (fsSetAuthorizationReq));
+       conn->curacid = cur->acid;
+    }
+}
+
+/*
+ * Poll a pending connect
+ */
+
+static int
+_fs_check_connect (FSFpePtr conn)
+{
+    int            ret;
+    
+    ret = _fs_poll_connect (conn->trans_conn, 0);
+    switch (ret) {
+    case FSIO_READY:
+       conn->fs_fd = _FontTransGetConnectionNumber (conn->trans_conn);
+       FD_SET (conn->fs_fd, &_fs_fd_mask);
+       break;
+    case FSIO_BLOCK:
+       break;
+    }
+    return ret;
+}
+
+/*
+ * Return an FSIO status while waiting for the completed connection
+ * reply to arrive
+ */
+
+static fsConnSetup *
+_fs_get_conn_setup (FSFpePtr conn, int *error, int *setup_len)
+{
+    int                        ret;
+    char               *data;
+    int                        headlen;
+    int                        len;
+    fsConnSetup                *setup;
+    fsConnSetupAccept  *accept;
+
+    ret = _fs_start_read (conn, SIZEOF (fsConnSetup), &data);
+    if (ret != FSIO_READY)
+    {
+       *error = ret;
+       return 0;
+    }
+    
+    setup = (fsConnSetup *) data;
+    if (setup->major_version > FS_PROTOCOL)
+    {
+       *error = FSIO_ERROR;
+       return 0;
+    }
+
+    headlen = (SIZEOF (fsConnSetup) +
+              (setup->alternate_len << 2) +
+              (setup->auth_len << 2));
+    /* On anything but Success, no extra data is sent */
+    if (setup->status != AuthSuccess)
+    {
+       len = headlen;
+    }
+    else
+    {
+       ret = _fs_start_read (conn, headlen + SIZEOF (fsConnSetupAccept), &data);
+       if (ret != FSIO_READY)
+       {
+           *error = ret;
+           return 0;
+       }
+       setup = (fsConnSetup *) data;
+       accept = (fsConnSetupAccept *) (data + headlen);
+       len = headlen + (accept->length << 2);
+    }
+    ret = _fs_start_read (conn, len, &data);
+    if (ret != FSIO_READY)
+    {
+       *error = ret;
+       return 0;
+    }
+    *setup_len = len;
+    return (fsConnSetup *) data;
+}
+
+static int
+_fs_send_conn_client_prefix (FSFpePtr conn)
+{
+    fsConnClientPrefix req;
+    int                        endian;
+    int                        ret;
+
+    /* send setup prefix */
+    endian = 1;
+    if (*(char *) &endian)
+       req.byteOrder = 'l';
+    else
+       req.byteOrder = 'B';
+
+    req.major_version = FS_PROTOCOL;
+    req.minor_version = FS_PROTOCOL_MINOR;
+
+/* XXX add some auth info here */
+    req.num_auths = 0;
+    req.auth_len = 0;
+    ret = _fs_write (conn, (char *) &req, SIZEOF (fsConnClientPrefix));
+    if (ret != FSIO_READY)
+       return FSIO_ERROR;
+    conn->blockedConnectTime = GetTimeInMillis () + FontServerRequestTimeout;
+    return ret;
+}
+
+static int
+_fs_recv_conn_setup (FSFpePtr conn)
+{
+    int                        ret = FSIO_ERROR;
+    fsConnSetup                *setup;
+    FSFpeAltPtr                alts;
+    int                        i, alt_len;
+    int                        setup_len;
+    char               *alt_save, *alt_names;
+    
+    setup = _fs_get_conn_setup (conn, &ret, &setup_len);
+    if (!setup)
+       return ret;
+    conn->current_seq = 0;
+    conn->fsMajorVersion = setup->major_version;
+    /*
+     * Create an alternate list from the initial server, but
+     * don't chain looking for alternates.
+     */
+    if (conn->alternate == 0)
+    {
+       /*
+        * free any existing alternates list, allowing the list to
+        * be updated
+        */
+       if (conn->alts)
+       {
+           free (conn->alts);
+           conn->alts = 0;
+           conn->numAlts = 0;
+       }
+       if (setup->num_alternates)
+       {
+           alts = malloc (setup->num_alternates * sizeof (FSFpeAltRec) +
+                          (setup->alternate_len << 2));
+           if (alts)
+           {
+               alt_names = (char *) (setup + 1);
+               alt_save = (char *) (alts + setup->num_alternates);
+               for (i = 0; i < setup->num_alternates; i++)
+               {
+                   alts[i].subset = alt_names[0];
+                   alt_len = alt_names[1];
+                   alts[i].name = alt_save;
+                   memcpy (alt_save, alt_names + 2, alt_len);
+                   alt_save[alt_len] = '\0';
+                   alt_save += alt_len + 1;
+                   alt_names += _fs_pad_length (alt_len + 2);
+               }
+               conn->numAlts = setup->num_alternates;
+               conn->alts = alts;
+           }
+       }
+    }
+    _fs_done_read (conn, setup_len);
+    if (setup->status != AuthSuccess)
+       return FSIO_ERROR;
+    return FSIO_READY;
+}
+
+static int
+_fs_open_server (FSFpePtr conn)
+{
+    int            ret;
+    char    *servername;
+    
+    if (conn->alternate == 0)
+       servername = conn->servername;
+    else
+       servername = conn->alts[conn->alternate-1].name;
+    conn->trans_conn = _fs_connect (servername, &ret);
+    conn->blockedConnectTime = GetTimeInMillis () + FS_RECONNECT_WAIT;
+    return ret;
+}
+
+static char *
+_fs_catalog_name (char *servername)
+{
+    char    *sp;
+
+    sp = strchr (servername, '/');
+    if (!sp)
+       return 0;
+    return strrchr (sp + 1, '/');
+}
+
+static int
+_fs_send_init_packets (FSFpePtr conn)
+{
+    fsSetResolutionReq     srreq;
+    fsSetCataloguesReq     screq;
+    int                            num_cats,
+                           clen;
+    char                   *catalogues;
+    char                   *cat;
+    char                   len;
+    char                   *end;
+    int                            num_res;    
+    FontResolutionPtr      res;
+
+#define        CATALOGUE_SEP   '+'
+
+    res = GetClientResolutions(&num_res);
+    if (num_res) 
+    {
+       srreq.reqType = FS_SetResolution;
+       srreq.num_resolutions = num_res;
+       srreq.length = (SIZEOF(fsSetResolutionReq) +
+                       (num_res * SIZEOF(fsResolution)) + 3) >> 2;
+
+       _fs_add_req_log(conn, FS_SetResolution);
+       if (_fs_write(conn, (char *) &srreq, SIZEOF(fsSetResolutionReq)) != FSIO_READY)
+           return FSIO_ERROR;
+       if (_fs_write_pad(conn, (char *) res, (num_res * SIZEOF(fsResolution))) != FSIO_READY)
+           return FSIO_ERROR;
+    }
+
+    catalogues = 0;
+    if (conn->alternate != 0)
+       catalogues = _fs_catalog_name (conn->alts[conn->alternate-1].name);
+    if (!catalogues)
+       catalogues = _fs_catalog_name (conn->servername);
+    
+    if (!catalogues)
+    {
+       conn->has_catalogues = FALSE;
+       return FSIO_READY;
+    }
+    conn->has_catalogues = TRUE;
+    
+    /* turn cats into counted list */
+    catalogues++;
+
+    cat = catalogues;
+    num_cats = 0;
+    clen = 0;
+    while (*cat)
+    {
+       num_cats++;
+       end = strchr(cat, CATALOGUE_SEP);
+       if (!end)
+           end = cat + strlen (cat);
+       clen += (end - cat) + 1;        /* length byte + string */
+       cat = end;
+    }
+
+    screq.reqType = FS_SetCatalogues;
+    screq.num_catalogues = num_cats;
+    screq.length = (SIZEOF(fsSetCataloguesReq) + clen + 3) >> 2;
+    
+    _fs_add_req_log(conn, FS_SetCatalogues);
+    if (_fs_write(conn, (char *) &screq, SIZEOF(fsSetCataloguesReq)) != FSIO_READY)
+       return FSIO_ERROR;
+    
+    while (*cat)
+    {
+       num_cats++;
+       end = strchr(cat, CATALOGUE_SEP);
+       if (!end)
+           end = cat + strlen (cat);
+       len = end - cat;
+       if (_fs_write (conn, &len, 1) != FSIO_READY)
+           return FSIO_ERROR;
+       if (_fs_write (conn, cat, (int) len) != FSIO_READY)
+           return FSIO_ERROR;
+       cat = end;
+    }
+    
+    if (_fs_write (conn, "....", _fs_pad_length (clen) - clen) != FSIO_READY)
+       return FSIO_ERROR;
+    
+    return FSIO_READY;
+}
+
+static int
+_fs_send_cat_sync (FSFpePtr conn)
+{
+    fsListCataloguesReq            lcreq;
+    
+    /*
+     * now sync up with the font server, to see if an error was generated
+     * by a bogus catalogue
+     */
+    lcreq.reqType = FS_ListCatalogues;
+    lcreq.length = (SIZEOF(fsListCataloguesReq)) >> 2;
+    lcreq.maxNames = 0;
+    lcreq.nbytes = 0;
+    lcreq.pad2 = 0;
+    _fs_add_req_log(conn, FS_SetCatalogues);
+    if (_fs_write(conn, (char *) &lcreq, SIZEOF(fsListCataloguesReq)) != FSIO_READY)
+       return FSIO_ERROR;
+    conn->blockedConnectTime = GetTimeInMillis () + FontServerRequestTimeout;
+    return FSIO_READY;
+}
+
+static int
+_fs_recv_cat_sync (FSFpePtr conn)
+{
+    fsGenericReply  *reply;
+    fsError        *error;
+    int                    err;
+    int                    ret;
+
+    reply = fs_get_reply (conn, &err);
+    if (!reply)
+       return err;
+    
+    ret = FSIO_READY;
+    if (reply->type == FS_Error)
+    {
+       error = (fsError *) reply;
+       if (error->major_opcode == FS_SetCatalogues)
+           ret = FSIO_ERROR;
+    }
+    _fs_done_read (conn, reply->length << 2);
+    return ret;
+}
+
+static void
+_fs_close_server (FSFpePtr conn)
+{
+    _fs_unmark_block (conn, FS_PENDING_WRITE|FS_BROKEN_WRITE|FS_COMPLETE_REPLY|FS_BROKEN_CONNECTION);
+    if (conn->trans_conn)
+    {
+       _FontTransClose (conn->trans_conn);
+       conn->trans_conn = 0;
+       _fs_io_reinit (conn);
+    }
+    if (conn->fs_fd >= 0)
+    {
+       FD_CLR (conn->fs_fd, &_fs_fd_mask);
+       conn->fs_fd = -1;
+    }
+    conn->fs_conn_state = FS_CONN_UNCONNECTED;
+}
+
+static int
+_fs_do_setup_connection (FSFpePtr conn)
+{
+    int            ret;
+    
+    do
+    {
+#ifdef DEBUG
+       fprintf (stderr, "fs_do_setup_connection state %d\n", conn->fs_conn_state);
+#endif
+       switch (conn->fs_conn_state) {
+       case FS_CONN_UNCONNECTED:
+           ret = _fs_open_server (conn);
+           if (ret == FSIO_BLOCK)
+               conn->fs_conn_state = FS_CONN_CONNECTING;
+           break;
+       case FS_CONN_CONNECTING:
+           ret = _fs_check_connect (conn);
+           break;
+       case FS_CONN_CONNECTED:
+           ret = _fs_send_conn_client_prefix (conn);
+           break;
+       case FS_CONN_SENT_PREFIX:
+           ret = _fs_recv_conn_setup (conn);
+           break;
+       case FS_CONN_RECV_INIT:
+           ret = _fs_send_init_packets (conn);
+           if (conn->has_catalogues)
+               ret = _fs_send_cat_sync (conn);
+           break;
+       case FS_CONN_SENT_CAT:
+           if (conn->has_catalogues)
+               ret = _fs_recv_cat_sync (conn);
+           else
+               ret = FSIO_READY;
+           break;
+       default:
+           ret = FSIO_READY;
+           break;
+       }
+       switch (ret) {
+       case FSIO_READY:
+           if (conn->fs_conn_state < FS_CONN_RUNNING)
+               conn->fs_conn_state++;
+           break;
+       case FSIO_BLOCK:
+           if (TimeCmp (GetTimeInMillis (), <, conn->blockedConnectTime))
+               break;
+           ret = FSIO_ERROR;
+           /* fall through... */
+       case FSIO_ERROR:
+           _fs_close_server (conn);
+           /*
+            * Try the next alternate
+            */
+           if (conn->alternate < conn->numAlts)
+           {
+               conn->alternate++;
+               ret = FSIO_READY;
+           }
+           else
+               conn->alternate = 0;
+           break;
+       }
+    } while (conn->fs_conn_state != FS_CONN_RUNNING && ret == FSIO_READY);
+    if (ret == FSIO_READY)
+       conn->generation = ++generationCount;
+    return ret;
+}
+
+static int
+_fs_wait_connect (FSFpePtr conn)
+{
+    int            ret;
+
+    for (;;)
+    {
+       ret = _fs_do_setup_connection (conn);
+       if (ret != FSIO_BLOCK)
+           break;
+       if (conn->fs_conn_state <= FS_CONN_CONNECTING)
+           ret = _fs_poll_connect (conn->trans_conn, 1000);
+       else
+           ret = _fs_wait_for_readable (conn, 1000);
+       if (ret == FSIO_ERROR)
+           break;
+    }
+    return ret;
+}
+
+/*
+ * Poll a connection in the process of reconnecting
+ */
+static void
+_fs_check_reconnect (FSFpePtr conn)
+{
+    int            ret;
+    
+    ret = _fs_do_setup_connection (conn);
+    switch (ret) {
+    case FSIO_READY:
+       _fs_unmark_block (conn, FS_RECONNECTING|FS_GIVE_UP);
+       _fs_restart_connection (conn);
+       break;
+    case FSIO_BLOCK:
+       break;
+    case FSIO_ERROR:
+       conn->brokenConnectionTime = GetTimeInMillis () + FS_RECONNECT_POLL;
+       break;
+    }
+}
+
+/*
+ * Start the reconnection process
+ */
+static void
+_fs_start_reconnect (FSFpePtr conn)
+{
+    if (conn->blockState & FS_RECONNECTING)
+       return;
+    conn->alternate = 0;
+    _fs_mark_block (conn, FS_RECONNECTING);
+    _fs_unmark_block (conn, FS_BROKEN_CONNECTION);
+    _fs_check_reconnect (conn);
+}
+
+
+static FSFpePtr
+_fs_init_conn (char *servername)
+{
+    FSFpePtr   conn;
+
+    conn = calloc (1, sizeof (FSFpeRec) + strlen (servername) + 1);
+    if (!conn)
+       return 0;
+    if (!_fs_io_init (conn))
+    {
+       free (conn);
+       return 0;
+    }
+    conn->servername = (char *) (conn + 1);
+    conn->fs_conn_state = FS_CONN_UNCONNECTED;
+    conn->fs_fd = -1;
+    strcpy (conn->servername, servername);
+    return conn;
+}
+
+static void
+_fs_free_conn (FSFpePtr conn)
+{
+    _fs_close_server (conn);
+    _fs_io_fini (conn);
+    if (conn->alts)
+       free (conn->alts);
+    free (conn);
+}
+
+/*
+ * called at server init time
+ */
+
+void
+fs_register_fpe_functions(void)
+{
+    RegisterFPEFunctions(fs_name_check,
+                        fs_init_fpe,
+                        fs_free_fpe,
+                        fs_reset_fpe,
+                        fs_open_font,
+                        fs_close_font,
+                        fs_list_fonts,
+                        fs_start_list_with_info,
+                        fs_next_list_with_info,
+                        fs_wakeup,
+                        fs_client_died,
+                        _fs_load_glyphs,
+                        NULL,
+                        NULL,
+                        NULL);
+}
diff --git a/src/fc/fserve.h b/src/fc/fserve.h
new file mode 100755 (executable)
index 0000000..5999861
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright 1990 Network Computing Devices
+ *
+ * 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 Network Computing Devices not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.  Network Computing
+ * Devices makes no representations about the suitability of this software
+ * for any purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+ * IN NO EVENT SHALL NETWORK COMPUTING DEVICES 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.
+ *
+ * Author:     Dave Lemke, Network Computing Devices, Inc
+ *
+ */
+
+#ifndef _FSERVE_H_
+#define _FSERVE_H_
+/*
+ * font server data structures
+ */
+
+/* types of block records */
+#define        FS_OPEN_FONT            1
+#define        FS_LOAD_GLYPHS          2
+#define        FS_LIST_FONTS           3
+#define        FS_LIST_WITH_INFO       4
+
+/* states of OpenFont */
+#define        FS_OPEN_REPLY           0
+#define        FS_INFO_REPLY           1
+#define        FS_EXTENT_REPLY         2
+#define        FS_GLYPHS_REPLY         3
+#define        FS_DONE_REPLY           4
+#define FS_DEPENDING           5
+
+/* status of ListFontsWithInfo */
+#define        FS_LFWI_WAITING         0
+#define        FS_LFWI_REPLY           1
+#define        FS_LFWI_FINISHED        2
+
+/* states of connection */
+#define FS_CONN_CLOSED         0
+#define FS_CONN_CONNECTING     1
+#define FS_CONN_READ_HEADER    2
+#define FS_CONN_READ_DATA      3
+
+#define        AccessDone      0x400
+
+typedef struct _fs_font_data *FSFontDataPtr;
+typedef struct _fs_blocked_font *FSBlockedFontPtr;
+typedef struct _fs_blocked_glyphs *FSBlockedGlyphPtr;
+typedef struct _fs_blocked_list *FSBlockedListPtr;
+typedef struct _fs_blocked_list_info *FSBlockedListInfoPtr;
+typedef struct _fs_block_data *FSBlockDataPtr;
+typedef struct _fs_font_table *FSFontTablePtr;
+typedef struct _fs_fpe_data *FSFpePtr;
+
+typedef struct _fs_blocked_bitmaps *FSBlockedBitmapPtr;
+typedef struct _fs_blocked_extents *FSBlockedExtentPtr;
+
+extern void _fs_convert_char_info ( fsXCharInfo *src, xCharInfo *dst );
+extern void _fs_free_props (FontInfoPtr pfi);
+extern FontPtr fs_create_font (FontPathElementPtr   fpe,
+                              char                 *name,
+                              int                  namelen,
+                              fsBitmapFormat       format,
+                              fsBitmapFormatMask   fmask);
+
+extern int fs_load_all_glyphs ( FontPtr pfont );
+
+/*
+ * These should be declared elsewhere, but I'm concerned that moving them
+ * would cause problems building other pieces
+ */
+extern FontPtr find_old_font (Font id);
+extern int  set_font_authorizations (char **a, int *len, pointer client);
+extern long   GetTimeInMillis (void);
+
+
+#endif                         /* _FSERVE_H_ */
diff --git a/src/fc/fservestr.h b/src/fc/fservestr.h
new file mode 100755 (executable)
index 0000000..a6d0d1d
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * Copyright 1990 Network Computing Devices
+ *
+ * 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 Network Computing Devices not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.  Network Computing
+ * Devices makes no representations about the suitability of this software
+ * for any purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+ * IN NO EVENT SHALL NETWORK COMPUTING DEVICES 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.
+ *
+ * Author:     Dave Lemke, Network Computing Devices, Inc
+ */
+
+#ifndef _FSERVESTR_H_
+#define _FSERVESTR_H_
+
+#include       "fserve.h"
+#include       "fsio.h"
+
+/*
+ * font server data structures
+ */
+/*
+ * font server private storage
+ */
+
+typedef struct _fs_glyph {
+    struct _fs_glyph   *next;
+} FSGlyphRec, *FSGlyphPtr;
+
+typedef struct _fs_font {
+    CharInfoPtr pDefault;
+    CharInfoPtr encoding;
+    CharInfoPtr inkMetrics;
+    FSGlyphPtr glyphs;
+}           FSFontRec, *FSFontPtr;
+
+/* FS special data for the font */
+typedef struct _fs_font_data {
+    long        fontid;
+    int                generation;     /* FS generation when opened */
+    unsigned long glyphs_to_get;       /* # glyphs remaining to be gotten */
+
+    /* Following data needed in case font needs to be reopened. */
+    int                namelen;
+    char       *name;
+    fsBitmapFormat     format;
+    fsBitmapFormatMask fmask;
+}           FSFontDataRec;
+
+typedef struct fs_clients_depending {
+    pointer    client;
+    struct fs_clients_depending *next;
+}      FSClientsDependingRec, *FSClientsDependingPtr;
+
+/* OpenFont specific data for blocked request */
+typedef struct _fs_blocked_font {
+    FontPtr     pfont;         /* must be first for fs_read_glyphs */
+    long        fontid;
+    int         state;         /* how many of the replies have landed */
+    int         flags;
+    Bool       freeFont;       /* free this font on failure */
+    CARD16     queryInfoSequence;
+    CARD16     queryExtentsSequence;
+    CARD16     queryBitmapsSequence;
+    fsBitmapFormat format;
+    FSClientsDependingPtr      clients_depending;
+}           FSBlockedFontRec;
+
+/* LoadGlyphs data for blocked request */
+typedef struct _fs_blocked_glyphs {
+    FontPtr     pfont;         /* must be first for fs_read_glyphs */
+    int                num_expected_ranges;
+    fsRange     *expected_ranges;
+    FSClientsDependingPtr      clients_depending;
+}           FSBlockedGlyphRec;
+
+/* LoadExtents data for blocked request */
+typedef struct _fs_blocked_extents {
+    FontPtr     pfont;
+    fsRange    *expected_ranges;
+    int         nranges;
+    unsigned long nextents;
+    fsXCharInfo *extents;
+}           FSBlockedExtentRec;
+
+/* LoadBitmaps data for blocked request */
+typedef struct _fs_blocked_bitmaps {
+    FontPtr     pfont;
+    fsRange    *expected_ranges;
+    int         nranges;
+    unsigned long size;
+    unsigned long nglyphs;
+    fsOffset32   *offsets;
+    pointer     gdata;
+}           FSBlockedBitmapRec;
+
+/* state for blocked ListFonts */
+typedef struct _fs_blocked_list {
+    FontNamesPtr names;
+}           FSBlockedListRec;
+
+/* state for blocked ListFontsWithInfo */
+typedef struct _fs_blocked_list_info {
+    int         status;
+    int         namelen;
+    FontInfoRec info;
+    char       name[256];
+    int         remaining;
+}           FSBlockedListInfoRec;
+
+/* state for blocked request */
+typedef struct _fs_block_data {
+    int                            type;           /* Open Font, LoadGlyphs, ListFonts,
+                                            * ListWithInfo */
+    pointer                client;         /* who wants it */
+    CARD16                 sequenceNumber; /* expected */
+    pointer                data;           /* type specific data */
+    int                            errcode;        /* Suspended, et al. */
+    struct _fs_block_data   *depending;            /* clients depending on this one */
+    struct _fs_block_data   *next;
+}           FSBlockDataRec;
+
+/* state for reconnected to dead font server */
+typedef struct _fs_reconnect {
+    int            i;
+} FSReconnectRec, *FSReconnectPtr;
+
+
+#if !defined(UNIXCPP) || defined(ANSICPP)
+#define fsCat(x,y) x##_##y
+#else
+#define fsCat(x,y) x/**/_/**/y
+#endif
+
+
+/* copy XCharInfo parts of a protocol reply into a xCharInfo */
+
+#define fsUnpack_XCharInfo(packet, structure) \
+    (structure)->leftSideBearing = fsCat(packet,left); \
+    (structure)->rightSideBearing = fsCat(packet,right); \
+    (structure)->characterWidth = fsCat(packet,width); \
+    (structure)->ascent = fsCat(packet,ascent); \
+    (structure)->descent = fsCat(packet,descent); \
+    (structure)->attributes = fsCat(packet,attributes)
+
+
+/* copy XFontInfoHeader parts of a protocol reply into a FontInfoRec */
+
+#define fsUnpack_XFontInfoHeader(packet, structure) \
+    (structure)->allExist = ((packet)->font_header_flags & FontInfoAllCharsExist) != 0; \
+    (structure)->drawDirection = \
+        ((packet)->font_header_draw_direction == LeftToRightDrawDirection) ? \
+       LeftToRight : RightToLeft; \
+    (structure)->inkInside = ((packet)->font_header_flags & FontInfoInkInside) != 0; \
+ \
+    (structure)->firstRow = (packet)->font_hdr_char_range_min_char_high; \
+    (structure)->firstCol = (packet)->font_hdr_char_range_min_char_low; \
+    (structure)->lastRow = (packet)->font_hdr_char_range_max_char_high; \
+    (structure)->lastCol = (packet)->font_hdr_char_range_max_char_low; \
+    (structure)->defaultCh = (packet)->font_header_default_char_low \
+                           + ((packet)->font_header_default_char_high << 8); \
+ \
+    (structure)->fontDescent = (packet)->font_header_font_descent; \
+    (structure)->fontAscent = (packet)->font_header_font_ascent; \
+ \
+    fsUnpack_XCharInfo((packet)->font_header_min_bounds, &(structure)->minbounds); \
+    fsUnpack_XCharInfo((packet)->font_header_min_bounds, &(structure)->ink_minbounds); \
+    fsUnpack_XCharInfo((packet)->font_header_max_bounds, &(structure)->maxbounds); \
+    fsUnpack_XCharInfo((packet)->font_header_max_bounds, &(structure)->ink_maxbounds)
+
+extern void _fs_init_fontinfo ( FSFpePtr conn, FontInfoPtr pfi );
+extern int _fs_convert_props ( fsPropInfo *pi, fsPropOffset *po, pointer pd, 
+                              FontInfoPtr pfi );
+extern int _fs_convert_lfwi_reply ( FSFpePtr conn, FontInfoPtr pfi, 
+                                   fsListFontsWithXInfoReply *fsrep, 
+                                   fsPropInfo *pi, fsPropOffset *po, 
+                                   pointer pd );
+extern int fs_build_range ( FontPtr pfont, Bool range_flag, 
+                           unsigned int count, int item_size, 
+                           unsigned char *data, int *nranges, 
+                           fsRange **ranges );
+extern void _fs_clean_aborted_loadglyphs ( FontPtr pfont, 
+                                          int num_expected_ranges, 
+                                          fsRange *expected_ranges );
+extern void _fs_init_font ( FontPtr pfont );
+extern pointer fs_alloc_glyphs (FontPtr pFont, int size);
+#endif                         /* _FSERVESTR_H_ */
diff --git a/src/fc/fsio.c b/src/fc/fsio.c
new file mode 100755 (executable)
index 0000000..63d3b4f
--- /dev/null
@@ -0,0 +1,451 @@
+/*
+ * Copyright 1990 Network Computing Devices
+ *
+ * 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 Network Computing Devices not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.  Network Computing
+ * Devices makes no representations about the suitability of this software
+ * for any purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+ * IN NO EVENT SHALL NETWORK COMPUTING DEVICES 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.
+ *
+ * Author:     Dave Lemke, Network Computing Devices, Inc
+ */
+/*
+ * font server i/o routines
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef WIN32
+#define _WILLWINSOCK_
+#include       "X11/Xwindows.h"
+#endif
+
+#define FONT_t
+#define TRANS_CLIENT
+#include       "X11/Xtrans/Xtrans.h"
+#include       "X11/Xpoll.h"
+#include       <X11/fonts/FS.h>
+#include       <X11/fonts/FSproto.h>
+#include       <X11/fonts/fontmisc.h>
+#include       <X11/fonts/fontstruct.h>
+#include       "fservestr.h"
+
+#include       <stdio.h>
+#include       <signal.h>
+#include       <sys/types.h>
+#if !defined(WIN32)
+#ifndef Lynx
+#include       <sys/socket.h>
+#else
+#include       <socket.h>
+#endif
+#endif
+#include       <errno.h>
+#ifdef WIN32
+#define EWOULDBLOCK WSAEWOULDBLOCK
+#undef EINTR
+#define EINTR WSAEINTR
+#endif
+
+
+
+static int  padlength[4] = {0, 3, 2, 1};
+fd_set _fs_fd_mask;
+
+static int
+_fs_resize (FSBufPtr buf, long size);
+
+static void
+_fs_downsize (FSBufPtr buf, long size);
+    
+int
+_fs_poll_connect (XtransConnInfo trans_conn, int timeout)
+{
+    fd_set         w_mask;
+    struct timeval  tv;
+    int                    fs_fd = _FontTransGetConnectionNumber (trans_conn);
+    int                    ret;
+
+    do
+    {
+       tv.tv_usec = 0;
+       tv.tv_sec = timeout;
+       FD_ZERO (&w_mask);
+       FD_SET (fs_fd, &w_mask);
+       ret = Select (fs_fd + 1, NULL, &w_mask, NULL, &tv);
+    } while (ret < 0 && ECHECK(EINTR));
+    if (ret == 0)
+       return FSIO_BLOCK;
+    if (ret < 0)
+       return FSIO_ERROR;
+    return FSIO_READY;
+}
+
+XtransConnInfo
+_fs_connect(char *servername, int *err)
+{
+    XtransConnInfo  trans_conn;                /* transport connection object */
+    int                    ret;
+    int                    i = 0;
+    int                    retries = 5;
+
+    /*
+     * Open the network connection.
+     */
+    if( (trans_conn=_FontTransOpenCOTSClient(servername)) == NULL )
+    {
+       *err = FSIO_ERROR;
+       return 0;
+    }
+
+    /*
+     * Set the connection non-blocking since we use select() to block.
+     */
+
+    _FontTransSetOption(trans_conn, TRANS_NONBLOCKING, 1);
+
+    do {
+       i = _FontTransConnect(trans_conn,servername);
+    } while ((i == TRANS_TRY_CONNECT_AGAIN) && (retries-- > 0));
+
+    if (i < 0)
+    {
+       if (i == TRANS_IN_PROGRESS)
+           ret = FSIO_BLOCK;
+       else
+           ret = FSIO_ERROR;
+    }
+    else
+       ret = FSIO_READY;
+
+    if (ret == FSIO_ERROR)
+    {
+       _FontTransClose(trans_conn);
+       trans_conn = 0;
+    }
+
+    *err = ret;
+    return trans_conn;
+}
+
+static int
+_fs_fill (FSFpePtr conn)
+{
+    long    avail;
+    long    bytes_read;
+    Bool    waited = FALSE;
+    
+    if (_fs_flush (conn) < 0)
+       return FSIO_ERROR;
+    /*
+     * Don't go overboard here; stop reading when we've
+     * got enough to satisfy the pending request
+     */
+    while ((conn->inNeed - (conn->inBuf.insert - conn->inBuf.remove)) > 0)
+    {
+       avail = conn->inBuf.size - conn->inBuf.insert;
+       /*
+        * For SVR4 with a unix-domain connection, ETEST() after selecting
+        * readable means the server has died.  To do this here, we look for
+        * two consecutive reads returning ETEST().
+        */
+       ESET (0);
+       bytes_read =_FontTransRead(conn->trans_conn,
+                                  conn->inBuf.buf + conn->inBuf.insert,
+                                  avail);
+       if (bytes_read > 0) {
+           conn->inBuf.insert += bytes_read;
+           waited = FALSE;
+       }
+       else
+       {
+           if (bytes_read == 0 || ETEST ())
+           {
+               if (!waited)
+               {
+                   waited = TRUE;
+                   if (_fs_wait_for_readable (conn, 0) == FSIO_BLOCK)
+                       return FSIO_BLOCK;
+                   continue;
+               }
+           }
+           _fs_connection_died (conn);
+           return FSIO_ERROR;
+       }
+    }
+    return FSIO_READY;
+}
+
+/*
+ * Make space and return whether data have already arrived
+ */
+
+int
+_fs_start_read (FSFpePtr conn, long size, char **buf)
+{
+    int            ret;
+    
+    conn->inNeed = size;
+    if (fs_inqueued(conn) < size)
+    {
+       if (_fs_resize (&conn->inBuf, size) != FSIO_READY)
+       {
+           _fs_connection_died (conn);
+           return FSIO_ERROR;
+       }
+       ret = _fs_fill (conn);
+       if (ret == FSIO_ERROR)
+           return ret;
+       if (ret == FSIO_BLOCK || fs_inqueued(conn) < size)
+           return FSIO_BLOCK;
+    }
+    if (buf)
+       *buf = conn->inBuf.buf + conn->inBuf.remove;
+    return FSIO_READY;
+}
+
+void
+_fs_done_read (FSFpePtr conn, long size)
+{
+    if (conn->inBuf.insert - conn->inBuf.remove < size)
+    {
+#ifdef DEBUG
+       fprintf (stderr, "_fs_done_read skipping to many bytes\n");
+#endif
+       return;
+    }
+    conn->inBuf.remove += size;
+    conn->inNeed -= size;
+    _fs_downsize (&conn->inBuf, FS_BUF_MAX);
+}
+
+long
+_fs_pad_length (long len)
+{
+    return len + padlength[len&3];
+}
+
+int
+_fs_flush (FSFpePtr conn)
+{
+    long    bytes_written;
+    long    remain;
+    
+    /* XXX - hack.  The right fix is to remember that the font server
+       has gone away when we first discovered it. */
+    if (conn->fs_fd < 0)
+       return FSIO_ERROR;
+
+    while ((remain = conn->outBuf.insert - conn->outBuf.remove) > 0)
+    {
+       bytes_written = _FontTransWrite(conn->trans_conn,
+                                       conn->outBuf.buf + conn->outBuf.remove,
+                                       (int) remain);
+       if (bytes_written > 0)
+       {
+           conn->outBuf.remove += bytes_written;
+       }
+       else
+       {
+           if (bytes_written == 0 || ETEST ())
+           {
+               conn->brokenWriteTime = GetTimeInMillis () + FS_FLUSH_POLL;
+               _fs_mark_block (conn, FS_BROKEN_WRITE);
+               break;
+           }
+           if (!ECHECK (EINTR))
+           {
+               _fs_connection_died (conn);
+               return FSIO_ERROR;
+           }
+       }
+    }
+    if (conn->outBuf.remove == conn->outBuf.insert)
+    {
+       _fs_unmark_block (conn, FS_BROKEN_WRITE|FS_PENDING_WRITE);
+       if (conn->outBuf.size > FS_BUF_INC)
+           conn->outBuf.buf = realloc (conn->outBuf.buf, FS_BUF_INC);
+       conn->outBuf.remove = conn->outBuf.insert = 0;
+    }
+    return FSIO_READY;
+}
+
+static int
+_fs_resize (FSBufPtr buf, long size)
+{
+    char    *new;
+    long    new_size;
+
+    if (buf->remove)
+    {
+       if (buf->remove != buf->insert)
+       {
+           memmove (buf->buf, 
+                    buf->buf + buf->remove,
+                    buf->insert - buf->remove);
+       }
+       buf->insert -= buf->remove;
+       buf->remove = 0;
+    }
+    if (buf->size - buf->remove < size)
+    {
+       new_size = ((buf->remove + size + FS_BUF_INC) / FS_BUF_INC) * FS_BUF_INC;
+       new = realloc (buf->buf, new_size);
+       if (!new)
+           return FSIO_ERROR;
+       buf->buf = new;
+       buf->size = new_size;
+    }
+    return FSIO_READY;
+}
+
+static void
+_fs_downsize (FSBufPtr buf, long size)
+{
+    if (buf->insert == buf->remove)
+    {
+       buf->insert = buf->remove = 0;
+       if (buf->size > size)
+       {
+           buf->buf = realloc (buf->buf, size);
+           buf->size = size;
+       }
+    }
+}
+
+void
+_fs_io_reinit (FSFpePtr conn)
+{
+    conn->outBuf.insert = conn->outBuf.remove = 0;
+    _fs_downsize (&conn->outBuf, FS_BUF_INC);
+    conn->inBuf.insert = conn->inBuf.remove = 0;
+    _fs_downsize (&conn->inBuf, FS_BUF_MAX);
+}
+
+Bool
+_fs_io_init (FSFpePtr conn)
+{
+    conn->outBuf.insert = conn->outBuf.remove = 0;
+    conn->outBuf.buf = malloc (FS_BUF_INC);
+    if (!conn->outBuf.buf)
+       return FALSE;
+    conn->outBuf.size = FS_BUF_INC;
+    
+    conn->inBuf.insert = conn->inBuf.remove = 0;
+    conn->inBuf.buf = malloc (FS_BUF_INC);
+    if (!conn->inBuf.buf)
+    {
+       free (conn->outBuf.buf);
+       conn->outBuf.buf = 0;
+       return FALSE;
+    }
+    conn->inBuf.size = FS_BUF_INC;
+    
+    return TRUE;
+}
+
+void
+_fs_io_fini (FSFpePtr conn)
+{
+    if (conn->outBuf.buf)
+       free (conn->outBuf.buf);
+    if (conn->inBuf.buf)
+       free (conn->inBuf.buf);
+}
+
+static int
+_fs_do_write(FSFpePtr conn, char *data, long len, long size)
+{
+    if (size == 0) {
+#ifdef DEBUG
+       fprintf(stderr, "tried to write 0 bytes \n");
+#endif
+       return FSIO_READY;
+    }
+
+    if (conn->fs_fd == -1)
+       return FSIO_ERROR;
+    
+    while (conn->outBuf.insert + size > conn->outBuf.size) 
+    {
+       if (_fs_flush (conn) < 0)
+           return FSIO_ERROR;
+       if (_fs_resize (&conn->outBuf, size) < 0)
+       {
+           _fs_connection_died (conn);
+           return FSIO_ERROR;
+       }
+    }
+    memcpy (conn->outBuf.buf + conn->outBuf.insert, data, len);
+    /* Clear pad data */
+    memset (conn->outBuf.buf + conn->outBuf.insert + len, 0, size - len);
+    conn->outBuf.insert += size;
+    _fs_mark_block (conn, FS_PENDING_WRITE);
+    return FSIO_READY;
+}
+
+/*
+ * Write the indicated bytes
+ */
+int
+_fs_write (FSFpePtr conn, char *data, long len)
+{
+    return _fs_do_write (conn, data, len, len);
+}
+    
+/*
+ * Write the indicated bytes adding any appropriate pad
+ */
+int
+_fs_write_pad(FSFpePtr conn, char *data, long len)
+{
+    return _fs_do_write (conn, data, len, len + padlength[len & 3]);
+}
+
+int
+_fs_wait_for_readable(FSFpePtr conn, int ms)
+{
+    fd_set     r_mask;
+    fd_set     e_mask;
+    int         result;
+    struct timeval  tv;
+
+    for (;;) {
+       if (conn->fs_fd < 0)
+           return FSIO_ERROR;
+       FD_ZERO(&r_mask);
+       FD_ZERO(&e_mask);
+       tv.tv_sec = ms / 1000;
+       tv.tv_usec = (ms % 1000) * 1000;
+       FD_SET(conn->fs_fd, &r_mask);
+       FD_SET(conn->fs_fd, &e_mask);
+       result = Select(conn->fs_fd + 1, &r_mask, NULL, &e_mask, &tv);
+       if (result < 0)
+       {
+           if (ECHECK(EINTR) || ECHECK(EAGAIN))
+               continue;
+           else
+               return FSIO_ERROR;
+       }
+       if (result == 0)
+           return FSIO_BLOCK;
+       if (FD_ISSET(conn->fs_fd, &r_mask))
+           return FSIO_READY;
+       return FSIO_ERROR;
+    }
+}
diff --git a/src/fc/fsio.h b/src/fc/fsio.h
new file mode 100755 (executable)
index 0000000..bd0c621
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * Copyright 1990 Network Computing Devices
+ *
+ * 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 Network Computing Devices not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.  Network Computing
+ * Devices makes no representations about the suitability of this software
+ * for any purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+ * IN NO EVENT SHALL NETWORK COMPUTING DEVICES 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.
+ *
+ * Author:     Dave Lemke, Network Computing Devices, Inc
+ */
+
+#ifndef        _FSIO_H_
+#define        _FSIO_H_
+
+#undef DEBUG
+#define        REQUEST_LOG_SIZE        100
+
+typedef struct _fs_fpe_alternate {
+    char       *name;
+    Bool        subset;
+}           FSFpeAltRec, *FSFpeAltPtr;
+
+
+/* Per client access contexts */
+typedef struct _fs_client_data {
+    pointer                client;
+    struct _fs_client_data  *next;
+    XID                            acid;
+    int                            auth_generation;
+} FSClientRec, *FSClientPtr;
+
+#define FS_RECONNECT_POLL      1000
+#define FS_RECONNECT_WAIT      5000
+#define FS_GIVEUP_WAIT         20000
+#define FS_REQUEST_TIMEOUT     20000
+#define FS_OPEN_TIMEOUT                30000
+#define FS_REOPEN_TIMEOUT      10000
+#define FS_FLUSH_POLL          1000
+
+typedef struct _fs_buf {
+    char    *buf;              /* data */
+    long    size;              /* sizeof data */
+    long    insert;            /* where to insert new data */
+    long    remove;            /* where to remove old data */
+} FSBufRec, *FSBufPtr;
+
+#define FS_BUF_INC  1024
+#define FS_BUF_MAX  32768
+
+#define FS_PENDING_WRITE       0x01        /* some write data is queued */
+#define FS_BROKEN_WRITE                0x02        /* writes are broken */
+#define FS_BROKEN_CONNECTION   0x04        /* connection is broken */
+#define FS_PENDING_REPLY       0x08        /* waiting for a reply */
+#define FS_GIVE_UP             0x10        /* font server declared useless */
+#define FS_COMPLETE_REPLY      0x20        /* complete reply ready */
+#define FS_RECONNECTING                0x40
+
+#define FS_CONN_UNCONNECTED    0
+#define FS_CONN_CONNECTING     1
+#define FS_CONN_CONNECTED      2
+#define FS_CONN_SENT_PREFIX    3
+#define FS_CONN_RECV_INIT      4
+#define FS_CONN_SENT_CAT       5
+#define FS_CONN_RUNNING                6
+
+/* FS specific font FontPathElement data */
+typedef struct _fs_fpe_data {
+    FSFpePtr   next;           /* list of all active fs fpes */
+    int         fs_fd;         /* < 0 when not running */
+    int                fs_conn_state;  /* connection state */
+    int         current_seq;
+    char       *servername;
+    Bool       has_catalogues;
+
+    int         generation;
+    int         numAlts;
+    int                alternate;      /* which alternate is in use +1 */
+    int                fsMajorVersion; /* font server major version number */
+    FSFpeAltPtr alts;
+
+    FSClientPtr        clients;
+    XID                curacid;
+#ifdef DEBUG
+    int         reqindex;
+    struct {
+       int     opcode;
+       int     sequence;
+    } reqbuffer[REQUEST_LOG_SIZE];
+#endif
+    FSBufRec   outBuf;         /* request queue */
+    FSBufRec   inBuf;          /* reply queue */
+    long       inNeed;         /* amount needed for reply */
+
+    CARD32     blockState;
+    CARD32     blockedReplyTime;       /* time to abort blocked read */
+    CARD32     brokenWriteTime;        /* time to retry broken write */
+    CARD32     blockedConnectTime;     /* time to abort blocked connect */
+    CARD32     brokenConnectionTime;   /* time to retry broken connection */
+    
+    FSBlockDataPtr  blockedRequests;
+    
+    struct _XtransConnInfo *trans_conn; /* transport connection object */
+}           FSFpeRec;
+
+#define fs_outspace(conn)   ((conn)->outBuf.size - (conn)->outBuf.insert)
+#define fs_outqueued(conn)  ((conn)->outBuf.insert - (conn)->outBuf.remove)
+#define fs_inqueued(conn)   ((conn)->inBuf.insert - (conn)->inBuf.remove)
+#define fs_needsflush(conn) (fs_outqueued(conn) != 0)
+#define fs_needsfill(conn)  (fs_inqueued(conn) < (conn)->inNeed)
+#define fs_needsconnect(conn)  ((conn)->fs_fd < 0)
+#define fs_data_read(conn)   ((conn)->inBuf.insert - (conn)->inBuf.remove)
+
+#define FSIO_READY  1
+#define FSIO_BLOCK  0
+#define FSIO_ERROR  -1
+
+extern Bool _fs_reopen_server ( FSFpePtr conn );
+extern int _fs_write ( FSFpePtr conn, char *data, long size );
+extern int _fs_write_pad ( FSFpePtr conn, char *data, long len );
+extern int _fs_wait_for_readable ( FSFpePtr conn, int ms );
+extern long _fs_pad_length (long len);
+
+extern void _fs_connection_died ( FSFpePtr conn );
+
+extern int  _fs_flush (FSFpePtr conn);
+extern void _fs_mark_block (FSFpePtr conn, CARD32 mask);
+extern void _fs_unmark_block (FSFpePtr conn, CARD32 mask);
+extern void _fs_done_read (FSFpePtr conn, long size);
+extern void _fs_io_reinit (FSFpePtr conn);
+extern int  _fs_start_read (FSFpePtr conn, long size, char **buf);
+extern Bool _fs_io_init (FSFpePtr conn);
+extern void _fs_io_fini (FSFpePtr conn);
+extern int  _fs_poll_connect (XtransConnInfo trans_conn, int timeout);
+extern XtransConnInfo  _fs_connect(char *servername, int *ret);
+
+/* check for both EAGAIN and EWOULDBLOCK, because some supposedly POSIX
+ * systems are broken and return EWOULDBLOCK when they should return EAGAIN
+ */
+#ifdef WIN32
+#define ETEST() (WSAGetLastError() == WSAEWOULDBLOCK)
+#else
+#if defined(EAGAIN) && defined(EWOULDBLOCK)
+#define ETEST() (errno == EAGAIN || errno == EWOULDBLOCK)
+#else
+#ifdef EAGAIN
+#define ETEST() (errno == EAGAIN)
+#else
+#define ETEST() (errno == EWOULDBLOCK)
+#endif
+#endif
+#endif
+#ifdef WIN32
+#define ECHECK(err) (WSAGetLastError() == err)
+#define ESET(val) WSASetLastError(val)
+#else
+#ifdef ISC
+#define ECHECK(err) ((errno == err) || ETEST())
+#else
+#define ECHECK(err) (errno == err)
+#endif
+#define ESET(val) errno = val
+#endif
+
+#endif                         /* _FSIO_H_ */
diff --git a/src/fc/fslibos.h b/src/fc/fslibos.h
new file mode 100755 (executable)
index 0000000..c49f52e
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ * Copyright 1990 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ */
+
+/*
+
+Copyright 1987, 1994, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+/*
+ * FSlib networking & os include file
+ */
+
+#include <X11/Xtrans/Xtrans.h>
+
+#ifndef WIN32
+
+/*
+ * makedepend screws up on #undef OPEN_MAX, so we define a new symbol
+ */
+
+#ifndef FONT_OPEN_MAX
+
+#ifndef X_NOT_POSIX
+# ifdef _POSIX_SOURCE
+#  include <limits.h>
+# else
+#  define _POSIX_SOURCE
+#  include <limits.h>
+#  undef _POSIX_SOURCE
+# endif
+#endif
+#ifndef SIZE_MAX
+# ifdef ULONG_MAX
+#  define SIZE_MAX ULONG_MAX
+# else
+#  define SIZE_MAX UINT_MAX
+# endif
+#endif
+#ifndef OPEN_MAX
+#if defined(SVR4) 
+#define OPEN_MAX 256
+#else
+#include <sys/param.h>
+#ifndef OPEN_MAX
+#ifdef __OSF1__
+#define OPEN_MAX 256
+#else
+#ifdef NOFILE
+#define OPEN_MAX NOFILE
+#else
+#define OPEN_MAX NOFILES_MAX
+#endif
+#endif
+#endif
+#endif
+#endif
+
+#if OPEN_MAX > 256
+#define FONT_OPEN_MAX 256
+#else
+#define FONT_OPEN_MAX OPEN_MAX
+#endif
+
+#endif /* FONT_OPEN_MAX */
+
+#ifdef WORD64
+#define NMSKBITS 64
+#else
+#define NMSKBITS 32
+#endif
+
+#define MSKCNT ((FONT_OPEN_MAX + NMSKBITS - 1) / NMSKBITS)
+
+typedef unsigned long FdSet[MSKCNT];
+typedef FdSet FdSetPtr;
+
+#if (MSKCNT==1)
+#define BITMASK(i) (1 << (i))
+#define MASKIDX(i) 0
+#endif
+
+#if (MSKCNT>1)
+#define BITMASK(i) (1 << ((i) & (NMSKBITS - 1)))
+#define MASKIDX(i) ((i) / NMSKBITS)
+#endif
+
+#define MASKWORD(buf, i) buf[MASKIDX(i)]
+#define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i)
+#define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
+#define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
+
+#if (MSKCNT==1)
+#define COPYBITS(src, dst) dst[0] = src[0]
+#define CLEARBITS(buf) buf[0] = 0
+#define MASKANDSETBITS(dst, b1, b2) dst[0] = (b1[0] & b2[0])
+#define ORBITS(dst, b1, b2) dst[0] = (b1[0] | b2[0])
+#define UNSETBITS(dst, b1) (dst[0] &= ~b1[0])
+#define ANYSET(src) (src[0])
+#endif
+
+#if (MSKCNT==2)
+#define COPYBITS(src, dst) { dst[0] = src[0]; dst[1] = src[1]; }
+#define CLEARBITS(buf) { buf[0] = 0; buf[1] = 0; }
+#define MASKANDSETBITS(dst, b1, b2)  {\
+                     dst[0] = (b1[0] & b2[0]);\
+                     dst[1] = (b1[1] & b2[1]); }
+#define ORBITS(dst, b1, b2)  {\
+                     dst[0] = (b1[0] | b2[0]);\
+                     dst[1] = (b1[1] | b2[1]); }
+#define UNSETBITS(dst, b1) {\
+                      dst[0] &= ~b1[0]; \
+                      dst[1] &= ~b1[1]; }
+#define ANYSET(src) (src[0] || src[1])
+#endif
+
+#if (MSKCNT==3)
+#define COPYBITS(src, dst) { dst[0] = src[0]; dst[1] = src[1]; \
+                            dst[2] = src[2]; }
+#define CLEARBITS(buf) { buf[0] = 0; buf[1] = 0; buf[2] = 0; }
+#define MASKANDSETBITS(dst, b1, b2)  {\
+                     dst[0] = (b1[0] & b2[0]);\
+                     dst[1] = (b1[1] & b2[1]);\
+                     dst[2] = (b1[2] & b2[2]); }
+#define ORBITS(dst, b1, b2)  {\
+                     dst[0] = (b1[0] | b2[0]);\
+                     dst[1] = (b1[1] | b2[1]);\
+                     dst[2] = (b1[2] | b2[2]); }
+#define UNSETBITS(dst, b1) {\
+                      dst[0] &= ~b1[0]; \
+                      dst[1] &= ~b1[1]; \
+                      dst[2] &= ~b1[2]; }
+#define ANYSET(src) (src[0] || src[1] || src[2])
+#endif
+
+#if (MSKCNT==4)
+#define COPYBITS(src, dst) dst[0] = src[0]; dst[1] = src[1]; \
+                          dst[2] = src[2]; dst[3] = src[3]
+#define CLEARBITS(buf) buf[0] = 0; buf[1] = 0; buf[2] = 0; buf[3] = 0
+#define MASKANDSETBITS(dst, b1, b2)  \
+                      dst[0] = (b1[0] & b2[0]);\
+                      dst[1] = (b1[1] & b2[1]);\
+                      dst[2] = (b1[2] & b2[2]);\
+                      dst[3] = (b1[3] & b2[3])
+#define ORBITS(dst, b1, b2)  \
+                      dst[0] = (b1[0] | b2[0]);\
+                      dst[1] = (b1[1] | b2[1]);\
+                      dst[2] = (b1[2] | b2[2]);\
+                      dst[3] = (b1[3] | b2[3])
+#define UNSETBITS(dst, b1) \
+                      dst[0] &= ~b1[0]; \
+                      dst[1] &= ~b1[1]; \
+                      dst[2] &= ~b1[2]; \
+                      dst[3] &= ~b1[3]
+#define ANYSET(src) (src[0] || src[1] || src[2] || src[3])
+#endif
+
+#if (MSKCNT>4)
+#define COPYBITS(src, dst) memmove((caddr_t) dst, (caddr_t) src,\
+                                  MSKCNT*sizeof(long))
+#define CLEARBITS(buf) bzero((caddr_t) buf, MSKCNT*sizeof(long))
+#define MASKANDSETBITS(dst, b1, b2)  \
+                     { int cri;                        \
+                       for (cri=MSKCNT; --cri>=0; )    \
+                         dst[cri] = (b1[cri] & b2[cri]); }
+#define ORBITS(dst, b1, b2)  \
+                     { int cri;                        \
+                     for (cri=MSKCNT; --cri>=0; )      \
+                         dst[cri] = (b1[cri] | b2[cri]); }
+#define UNSETBITS(dst, b1) \
+                     { int cri;                        \
+                     for (cri=MSKCNT; --cri>=0; )      \
+                         dst[cri] &= ~b1[cri];  }
+#if (MSKCNT==8)
+#define ANYSET(src) (src[0] || src[1] || src[2] || src[3] || \
+                    src[4] || src[5] || src[6] || src[7])
+#endif
+#endif
+
+#else /* not WIN32 */
+
+#include <X11/Xwinsock.h>
+#include <X11/Xw32defs.h>
+
+typedef fd_set FdSet;
+typedef FdSet *FdSetPtr;
+
+#define CLEARBITS(set) FD_ZERO(&set)
+#define BITSET(set,s) FD_SET(s,&set)
+#define BITCLEAR(set,s) FD_CLR(s,&set)
+#define GETBIT(set,s) FD_ISSET(s,&set)
+#define ANYSET(set) set->fd_count
+
+#endif
diff --git a/src/fc/fstrans.c b/src/fc/fstrans.c
new file mode 100644 (file)
index 0000000..c334c25
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright Â© 2004 Keith Packard
+ *
+ * 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.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#define FONT_t
+#define TRANS_CLIENT
+#include <X11/Xtrans/transport.c>
diff --git a/src/fontfile/Makefile.am b/src/fontfile/Makefile.am
new file mode 100644 (file)
index 0000000..aa64ca5
--- /dev/null
@@ -0,0 +1,29 @@
+INCLUDES = -I${top_srcdir}/include
+
+AM_CFLAGS = $(XFONT_CFLAGS) $(OS_CFLAGS) $(CWARNFLAGS)
+
+noinst_LTLIBRARIES = libfontfile.la
+
+libfontfile_la_LIBADD =        \
+       $(Z_LIBS)
+
+libfontfile_la_SOURCES =       \
+       bitsource.c             \
+       bufio.c                 \
+       decompress.c            \
+       defaults.c              \
+       dirfile.c               \
+       fileio.c                \
+       filewr.c                \
+       fontdir.c               \
+       fontencc.c              \
+       fontfile.c              \
+       fontscale.c             \
+       gunzip.c                \
+       register.c              \
+       renderers.c             \
+       catalogue.c
+
+if X_BZIP2_FONT_COMPRESSION
+libfontfile_la_SOURCES += bunzip2.c
+endif
diff --git a/src/fontfile/bitsource.c b/src/fontfile/bitsource.c
new file mode 100755 (executable)
index 0000000..1b79c2b
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+
+Copyright 1991, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+/*
+ * Author:  Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fntfilst.h>
+
+BitmapSourcesRec       FontFileBitmapSources;
+
+Bool
+FontFileRegisterBitmapSource (FontPathElementPtr fpe)
+{
+    FontPathElementPtr *new;
+    int                        i;
+    int                        newsize;
+
+    for (i = 0; i < FontFileBitmapSources.count; i++)
+       if (FontFileBitmapSources.fpe[i] == fpe)
+           return TRUE;
+    if (FontFileBitmapSources.count == FontFileBitmapSources.size)
+    {
+       newsize = FontFileBitmapSources.size + 4;
+       new = realloc (FontFileBitmapSources.fpe, newsize * sizeof *new);
+       if (!new)
+           return FALSE;
+       FontFileBitmapSources.size = newsize;
+       FontFileBitmapSources.fpe = new;
+    }
+    FontFileBitmapSources.fpe[FontFileBitmapSources.count++] = fpe;
+    return TRUE;
+}
+
+void
+FontFileUnregisterBitmapSource (FontPathElementPtr fpe)
+{
+    int            i;
+
+    for (i = 0; i < FontFileBitmapSources.count; i++)
+       if (FontFileBitmapSources.fpe[i] == fpe)
+       {
+           FontFileBitmapSources.count--;
+           if (FontFileBitmapSources.count == 0)
+           {
+               FontFileBitmapSources.size = 0;
+               free (FontFileBitmapSources.fpe);
+               FontFileBitmapSources.fpe = 0;
+           }
+           else
+           {
+               for (; i < FontFileBitmapSources.count; i++)
+                   FontFileBitmapSources.fpe[i] = FontFileBitmapSources.fpe[i+1];
+           }
+           break;
+       }
+}
+
+/*
+ * Our set_path_hook: unregister all bitmap sources.
+ * This is necessary because already open fonts will keep their FPEs
+ * allocated, but they may not be on the new font path.
+ * The bitmap sources in the new path will be registered by the init_func.
+ */
+void
+FontFileEmptyBitmapSource(void)
+{
+    if (FontFileBitmapSources.count == 0)
+       return;
+
+    FontFileBitmapSources.count = 0;
+    FontFileBitmapSources.size = 0;
+    free (FontFileBitmapSources.fpe);
+    FontFileBitmapSources.fpe = 0;
+}
+
+int
+FontFileMatchBitmapSource (FontPathElementPtr fpe, 
+                          FontPtr *pFont, 
+                          int flags, 
+                          FontEntryPtr entry, 
+                          FontNamePtr zeroPat, 
+                          FontScalablePtr vals, 
+                          fsBitmapFormat format, 
+                          fsBitmapFormatMask fmask, 
+                          Bool noSpecificSize)
+{
+    int                        source;
+    FontEntryPtr       zero;
+    FontBitmapEntryPtr bitmap;
+    int                        ret;
+    FontDirectoryPtr   dir;
+    FontScaledPtr      scaled;
+
+    /*
+     * Look through all the registered bitmap sources for
+     * the same zero name as ours; entries along that one
+     * can be scaled as desired.
+     */
+    ret = BadFontName;
+    for (source = 0; source < FontFileBitmapSources.count; source++)
+    {
+       if (FontFileBitmapSources.fpe[source] == fpe)
+           continue;
+       dir = (FontDirectoryPtr) FontFileBitmapSources.fpe[source]->private;
+       zero = FontFileFindNameInDir (&dir->scalable, zeroPat);
+       if (!zero)
+           continue;
+       scaled = FontFileFindScaledInstance (zero, vals, noSpecificSize);
+       if (scaled)
+       {
+           if (scaled->pFont)
+           {
+               *pFont = scaled->pFont;
+               (*pFont)->fpe = FontFileBitmapSources.fpe[source];
+               ret = Successful;
+           }
+           else if (scaled->bitmap)
+           {
+               entry = scaled->bitmap;
+               bitmap = &entry->u.bitmap;
+               if (bitmap->pFont)
+               {
+                   *pFont = bitmap->pFont;
+                   (*pFont)->fpe = FontFileBitmapSources.fpe[source];
+                   ret = Successful;
+               }
+               else
+               {
+                   ret = FontFileOpenBitmap (
+                               FontFileBitmapSources.fpe[source],
+                               pFont, flags, entry, format, fmask);
+                   if (ret == Successful && *pFont)
+                       (*pFont)->fpe = FontFileBitmapSources.fpe[source];
+               }
+           }
+           else /* "cannot" happen */
+           {
+               ret = BadFontName;
+           }
+           break;
+       }
+    }
+    return ret;
+}
diff --git a/src/fontfile/bufio.c b/src/fontfile/bufio.c
new file mode 100755 (executable)
index 0000000..34b7f36
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+
+Copyright 1991, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+/*
+ * Author:  Keith Packard, MIT X Consortium
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/Xos.h>
+#include <X11/fonts/fontmisc.h>
+#include <X11/fonts/bufio.h>
+#include <errno.h>
+
+BufFilePtr
+BufFileCreate (char *private,
+              int (*input)(BufFilePtr),
+              int (*output)(int, BufFilePtr),
+              int (*skip)(BufFilePtr, int),
+              int (*close)(BufFilePtr, int))
+{
+    BufFilePtr f;
+
+    f = malloc (sizeof *f);
+    if (!f)
+       return 0;
+    f->private = private;
+    f->bufp = f->buffer;
+    f->left = 0;
+    f->input = input;
+    f->output = output;
+    f->skip = skip;
+    f->eof  = 0;
+    f->close = close;
+    return f;
+}
+
+#define FileDes(f)  ((int)(long) (f)->private)
+
+static int
+BufFileRawFill (BufFilePtr f)
+{
+    int        left;
+
+    left = read (FileDes(f), (char *)f->buffer, BUFFILESIZE);
+    if (left <= 0) {
+       f->left = 0;
+       return BUFFILEEOF;
+    }
+    f->left = left - 1;
+    f->bufp = f->buffer + 1;
+    return f->buffer[0];
+}
+
+static int
+BufFileRawSkip (BufFilePtr f, int count)
+{
+    int            curoff;
+    int            fileoff;
+    int            todo;
+
+    curoff = f->bufp - f->buffer;
+    fileoff = curoff + f->left;
+    if (curoff + count <= fileoff) {
+       f->bufp += count;
+       f->left -= count;
+    } else {
+       todo = count - (fileoff - curoff);
+       if (lseek (FileDes(f), todo, 1) == -1) {
+           if (errno != ESPIPE)
+               return BUFFILEEOF;
+           while (todo) {
+               curoff = BUFFILESIZE;
+               if (curoff > todo)
+                   curoff = todo;
+               fileoff = read (FileDes(f), (char *)f->buffer, curoff);
+               if (fileoff <= 0)
+                   return BUFFILEEOF;
+               todo -= fileoff;
+           }
+       }
+       f->left = 0;
+    }
+    return count;
+}
+
+static int
+BufFileRawClose (BufFilePtr f, int doClose)
+{
+    if (doClose)
+       close (FileDes (f));
+    return 1;
+}
+
+BufFilePtr
+BufFileOpenRead (int fd)
+{
+#if defined (WIN32)
+    /* hv: I'd bet WIN32 has the same effect here */
+    setmode(fd,O_BINARY);
+#endif
+    return BufFileCreate ((char *)(long) fd, BufFileRawFill, 0, BufFileRawSkip, BufFileRawClose);
+}
+
+static int
+BufFileRawFlush (int c, BufFilePtr f)
+{
+    int        cnt;
+
+    if (c != BUFFILEEOF)
+       *f->bufp++ = c;
+    cnt = f->bufp - f->buffer;
+    f->bufp = f->buffer;
+    f->left = BUFFILESIZE;
+    if (write (FileDes(f), (char *)f->buffer, cnt) != cnt)
+       return BUFFILEEOF;
+    return c;
+}
+
+static int
+BufFileFlush (BufFilePtr f, int doClose)
+{
+    if (f->bufp != f->buffer)
+       return (*f->output) (BUFFILEEOF, f);
+    return 0;
+}
+
+BufFilePtr
+BufFileOpenWrite (int fd)
+{
+    BufFilePtr f;
+
+#if defined(WIN32)
+    /* hv: I'd bet WIN32 has the same effect here */
+    setmode(fd,O_BINARY);
+#endif
+    f = BufFileCreate ((char *)(long) fd, 0, BufFileRawFlush, 0, BufFileFlush);
+    f->bufp = f->buffer;
+    f->left = BUFFILESIZE;
+    return f;
+}
+
+int
+BufFileRead (BufFilePtr f, char *b, int n)
+{
+    int            c, cnt;
+    cnt = n;
+    while (cnt--) {
+       c = BufFileGet (f);
+       if (c == BUFFILEEOF)
+           break;
+       *b++ = c;
+    }
+    return n - cnt - 1;
+}
+
+int
+BufFileWrite (BufFilePtr f, char *b, int n)
+{
+    int            cnt;
+    cnt = n;
+    while (cnt--) {
+       if (BufFilePut (*b++, f) == BUFFILEEOF)
+           return BUFFILEEOF;
+    }
+    return n;
+}
+
+int
+BufFileClose (BufFilePtr f, int doClose)
+{
+    int ret;
+    ret = (*f->close) (f, doClose);
+    free (f);
+    return ret;
+}
diff --git a/src/fontfile/bunzip2.c b/src/fontfile/bunzip2.c
new file mode 100755 (executable)
index 0000000..d927bd5
--- /dev/null
@@ -0,0 +1,174 @@
+/* Based on src/fontfile/gunzip.c
+   written by Mark Eichin <eichin@kitten.gen.ma.us> September 1996.
+   intended for inclusion in X11 public releases. */
+
+/*
+ * Copyright Â© 2008 Sun Microsystems, Inc.  All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include "config.h"
+
+#include <X11/fonts/fontmisc.h>
+#include <X11/fonts/bufio.h>
+#include <bzlib.h>
+
+typedef struct _xzip_buf {
+    bz_stream z;
+    int zstat;
+    BufChar b[BUFFILESIZE];
+    BufChar b_in[BUFFILESIZE];
+    BufFilePtr f;
+} xzip_buf;
+
+static int BufBzip2FileClose ( BufFilePtr f, int flag );
+static int BufBzip2FileFill ( BufFilePtr f );
+static int BufBzip2FileSkip ( BufFilePtr f, int c );
+
+_X_HIDDEN BufFilePtr
+BufFilePushBZIP2 (BufFilePtr f)
+{
+    xzip_buf *x;
+
+    x = malloc (sizeof (xzip_buf));
+    if (!x) return NULL;
+
+    bzero(&(x->z), sizeof(bz_stream));
+    x->f = f;
+
+    x->zstat = BZ2_bzDecompressInit(&(x->z),
+                                   0,  /* verbosity: 0 silent, 4 max */
+                                   0); /* 0: go faster, 1: use less memory */
+    if (x->zstat != BZ_OK) {
+       free(x);
+       return NULL;
+    }
+
+    /* now that the history buffer is allocated, we provide the data buffer */
+    x->z.next_out = (char *) x->b;
+    x->z.avail_out = BUFFILESIZE;
+    x->z.next_in = (char *) x->b_in;
+    x->z.avail_in = 0;
+
+    return BufFileCreate((char *)x,
+                        BufBzip2FileFill,
+                        NULL,
+                        BufBzip2FileSkip,
+                        BufBzip2FileClose);
+}
+
+static int 
+BufBzip2FileClose(BufFilePtr f, int flag)
+{
+    xzip_buf *x = (xzip_buf *)f->private;
+    BZ2_bzDecompressEnd (&(x->z));
+    BufFileClose (x->f, flag);
+    free (x);
+    return 1;
+}
+
+/* here's the real work. 
+   -- we need to put stuff in f.buffer, update f.left and f.bufp,
+   then return the first byte (or BUFFILEEOF).
+   -- to do this, we need to get stuff into avail_in, and next_in, 
+   and call BZ2_bzDecompress appropriately.
+   -- we may also need to add CRC maintenance - if BZ2_bzDecompress tells us
+   BZ_STREAM_END, we then have 4bytes CRC and 4bytes length...
+*/
+static int 
+BufBzip2FileFill (BufFilePtr f)
+{
+    xzip_buf *x = (xzip_buf *)f->private;
+
+    /* we only get called when left == 0... */
+    /* but just in case, deal */
+    if (f->left >= 0) {
+       f->left--;
+       return *(f->bufp++);
+    }
+    /* did we run out last time? */
+    switch (x->zstat) {
+    case BZ_OK:
+       break;
+    case BZ_STREAM_END:
+    case BZ_DATA_ERROR:
+    case BZ_DATA_ERROR_MAGIC:
+       f->left = 0;
+       return BUFFILEEOF;
+    default:
+       return BUFFILEEOF;
+    }
+    /* now we work to consume what we can */
+    /* let libbz2 know what we can handle */
+    x->z.next_out = (char *) x->b;
+    x->z.avail_out = BUFFILESIZE;
+
+    /* and try to consume all of it */
+    while (x->z.avail_out > 0) {
+       /* if we don't have anything to work from... */
+       if (x->z.avail_in == 0) {
+           /* ... fill the z buf from underlying file */
+           int i, c;
+           for (i = 0; i < sizeof(x->b_in); i++) {
+               c = BufFileGet(x->f);
+               if (c == BUFFILEEOF) break;
+               x->b_in[i] = c;
+           }
+           x->z.avail_in += i;
+           x->z.next_in = (char *) x->b_in;
+       }
+       /* so now we have some output space and some input data */
+       x->zstat = BZ2_bzDecompress(&(x->z));
+       /* the inflation output happens in the f buffer directly... */
+       if (x->zstat == BZ_STREAM_END) {
+           /* deal with EOF, crc */
+           break;
+       }
+       if (x->zstat != BZ_OK) {
+           break;
+       }
+    }
+    f->bufp = x->b;
+    f->left = BUFFILESIZE - x->z.avail_out;  
+
+    if (f->left >= 0) {
+       f->left--;
+       return *(f->bufp++);
+    } else {
+       return BUFFILEEOF;
+    }
+}
+
+/* there should be a BufCommonSkip... */
+static int 
+BufBzip2FileSkip (BufFilePtr f, int c)
+{
+    /* BufFileRawSkip returns the count unchanged.
+       BufCompressedSkip returns 0.
+       That means it probably never gets called... */
+    int retval = c;
+    while(c--) {
+       int get = BufFileGet(f);
+       if (get == BUFFILEEOF) return get;
+    }
+    return retval;
+}
diff --git a/src/fontfile/catalogue.c b/src/fontfile/catalogue.c
new file mode 100755 (executable)
index 0000000..3a04a75
--- /dev/null
@@ -0,0 +1,476 @@
+/*
+ * Copyright Â© 2007 Red Hat, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author:
+ *   Kristian Høgsberg <krh@redhat.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fntfilst.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <unistd.h>
+
+static const char CataloguePrefix[] = "catalogue:";
+
+static int CatalogueFreeFPE (FontPathElementPtr fpe);
+
+static int
+CatalogueNameCheck (char *name)
+{
+    return strncmp(name, CataloguePrefix, sizeof(CataloguePrefix) - 1) == 0;
+}
+
+typedef struct _CatalogueRec {
+    time_t mtime;
+    int fpeCount, fpeAlloc;
+    FontPathElementPtr *fpeList;
+} CatalogueRec, *CataloguePtr;
+
+static int
+CatalogueAddFPE (CataloguePtr cat, FontPathElementPtr fpe)
+{
+    FontPathElementPtr *new;
+
+    if (cat->fpeCount >= cat->fpeAlloc)
+    {
+       if (cat->fpeAlloc == 0)
+           cat->fpeAlloc = 16;
+       else
+           cat->fpeAlloc *= 2;
+       
+       new = realloc(cat->fpeList, cat->fpeAlloc * sizeof(FontPathElementPtr));
+       if (new == NULL)
+           return AllocError;
+
+       cat->fpeList = new;
+    }
+
+    cat->fpeList[cat->fpeCount++] = fpe;
+
+    return Successful;
+}
+
+static const char PriorityAttribute[] = "pri=";
+
+static int
+ComparePriority(const void *p1, const void *p2)
+{
+    FontDirectoryPtr dir1 = (*(FontPathElementPtr*) p1)->private;
+    FontDirectoryPtr dir2 = (*(FontPathElementPtr*) p2)->private;
+    const char *pri1 = NULL;
+    const char *pri2 = NULL;
+
+    if (dir1->attributes != NULL)
+       pri1 = strstr(dir1->attributes, PriorityAttribute);
+    if (dir2->attributes != NULL)
+       pri2 = strstr(dir2->attributes, PriorityAttribute);
+
+    if (pri1 == NULL && pri2 == NULL)
+       return 0;
+    else if (pri1 == NULL)
+       return 1;
+    else if (pri2 == NULL)
+       return -1;
+    else
+       return
+           atoi(pri1 + strlen(PriorityAttribute)) -
+           atoi(pri2 + strlen(PriorityAttribute));
+}
+
+static void
+CatalogueUnrefFPEs (FontPathElementPtr fpe)
+{
+    CataloguePtr       cat = fpe->private;
+    FontPathElementPtr subfpe;
+    int                        i;
+
+    for (i = 0; i < cat->fpeCount; i++)
+    {
+       subfpe = cat->fpeList[i];
+       subfpe->refcount--;
+       if (subfpe->refcount == 0)
+       {
+           FontFileFreeFPE (subfpe);
+           free(subfpe->name);
+           free(subfpe);
+       }
+    }
+
+    cat->fpeCount = 0;
+}
+
+/* Rescan catalogue directory if modified timestamp has changed or
+ * the forceScan argument says to do it anyway (like on first load). */
+static int
+CatalogueRescan (FontPathElementPtr fpe, Bool forceScan)
+{
+    CataloguePtr       cat = fpe->private;
+    char               link[MAXFONTFILENAMELEN];
+    char               dest[MAXFONTFILENAMELEN];
+    char               *attrib;
+    FontPathElementPtr subfpe;
+    struct stat                statbuf;
+    const char         *path;
+    DIR                        *dir;
+    struct dirent      *entry;
+    int                        len;
+    int                        pathlen;
+
+    path = fpe->name + strlen(CataloguePrefix);
+    if (stat(path, &statbuf) < 0 || !S_ISDIR(statbuf.st_mode))
+       return BadFontPath;
+
+    if ((forceScan == FALSE) && (statbuf.st_mtime <= cat->mtime))
+       return Successful;
+
+    dir = opendir(path);
+    if (dir == NULL)
+    {
+       free(cat);
+       return BadFontPath;
+    }
+
+    CatalogueUnrefFPEs (fpe);
+    while (entry = readdir(dir), entry != NULL)
+    {
+       snprintf(link, sizeof link, "%s/%s", path, entry->d_name);
+       len = readlink(link, dest, sizeof dest - 1);
+       if (len < 0)
+           continue;
+
+       dest[len] = '\0';
+
+       if (dest[0] != '/')
+       {
+          pathlen = strlen(path);
+          memmove(dest + pathlen + 1, dest, sizeof dest - pathlen - 1);
+          memcpy(dest, path, pathlen);
+          memcpy(dest + pathlen, "/", 1);
+          len += pathlen + 1;
+       }
+
+       attrib = strchr(link, ':');
+       if (attrib && len + strlen(attrib) < sizeof dest)
+       {
+           memcpy(dest + len, attrib, strlen(attrib));
+           len += strlen(attrib);
+       }
+
+       subfpe = malloc(sizeof *subfpe);
+       if (subfpe == NULL)
+           continue;
+
+       /* The fonts returned by OpenFont will point back to the
+        * subfpe they come from.  So set the type of the subfpe to
+        * what the catalogue fpe was assigned, so calls to CloseFont
+        * (which uses font->fpe->type) goes to CatalogueCloseFont. */
+       subfpe->type = fpe->type;
+       subfpe->name_length = len;
+       subfpe->name = malloc (len + 1);
+       if (subfpe == NULL)
+       {
+           free(subfpe);
+           continue;
+       }
+
+       memcpy(subfpe->name, dest, len);
+       subfpe->name[len] = '\0';
+
+       /* The X server will manipulate the subfpe ref counts
+        * associated with the font in OpenFont and CloseFont, so we
+        * have to make sure it's valid. */
+       subfpe->refcount = 1;
+
+       if (FontFileInitFPE (subfpe) != Successful)
+       {
+           free(subfpe->name);
+           free(subfpe);
+           continue;
+       }
+
+       if (CatalogueAddFPE(cat, subfpe) != Successful)
+       {
+           FontFileFreeFPE (subfpe);
+           free(subfpe);
+           continue;
+       }
+    }
+
+    closedir(dir);
+
+    qsort(cat->fpeList,
+         cat->fpeCount, sizeof cat->fpeList[0], ComparePriority);
+
+    cat->mtime = statbuf.st_mtime;
+
+    return Successful;
+}
+
+static int
+CatalogueInitFPE (FontPathElementPtr fpe)
+{
+    CataloguePtr       cat;
+
+    cat = malloc(sizeof *cat);
+    if (cat == NULL)
+       return AllocError;
+
+    fpe->private = (pointer) cat;
+    cat->fpeCount = 0;
+    cat->fpeAlloc = 0;
+    cat->fpeList = NULL;
+    cat->mtime = 0;
+
+    return CatalogueRescan (fpe, TRUE);
+}
+
+static int
+CatalogueResetFPE (FontPathElementPtr fpe)
+{
+    /* Always just tell the caller to close and re-open */
+    return FPEResetFailed;     
+}
+
+static int
+CatalogueFreeFPE (FontPathElementPtr fpe)
+{
+    CataloguePtr       cat = fpe->private;
+
+    /* If the catalogue is modified while the xserver has fonts open
+     * from the previous subfpes, we'll unref the old subfpes when we
+     * reload the catalogue, and the xserver will the call FreeFPE on
+     * them once it drops its last reference. Thus, the FreeFPE call
+     * for the subfpe ends up here and we just forward it to
+     * FontFileFreeFPE. */
+
+    if (!CatalogueNameCheck (fpe->name))
+       return FontFileFreeFPE (fpe);
+
+    CatalogueUnrefFPEs (fpe);
+    free(cat->fpeList);
+    free(cat);
+
+    return Successful;
+}
+
+static int
+CatalogueOpenFont (pointer client, FontPathElementPtr fpe, Mask flags, 
+                  char *name, int namelen, 
+                  fsBitmapFormat format, fsBitmapFormatMask fmask,
+                  XID id, FontPtr *pFont, char **aliasName, 
+                  FontPtr non_cachable_font)
+{
+    CataloguePtr cat = fpe->private;
+    FontPathElementPtr subfpe;
+    FontDirectoryPtr dir;
+    int i, status;
+
+    CatalogueRescan (fpe, FALSE);
+
+    for (i = 0; i < cat->fpeCount; i++)
+    {
+       subfpe = cat->fpeList[i];
+       dir = subfpe->private;
+       status = FontFileOpenFont(client, subfpe, flags,
+                                 name, namelen, format, fmask, id,
+                                 pFont, aliasName, non_cachable_font);
+       if (status == Successful || status == FontNameAlias)
+           return status;
+    }
+           
+    return BadFontName;
+}
+
+static void
+CatalogueCloseFont (FontPathElementPtr fpe, FontPtr pFont)
+{
+    /* Note: this gets called with the actual subfpe where we found
+     * the font, not the catalogue fpe. */
+
+    FontFileCloseFont(fpe, pFont);
+}
+
+static int
+CatalogueListFonts (pointer client, FontPathElementPtr fpe, char *pat, 
+                   int len, int max, FontNamesPtr names)
+{
+    CataloguePtr cat = fpe->private;
+    FontPathElementPtr subfpe;
+    FontDirectoryPtr dir;
+    int i;
+
+    CatalogueRescan (fpe, FALSE);
+
+    for (i = 0; i < cat->fpeCount; i++)
+    {
+       subfpe = cat->fpeList[i];
+       dir = subfpe->private;
+       FontFileListFonts(client, subfpe, pat, len, max, names);
+    }
+
+    return Successful;
+}
+
+int
+FontFileStartListFonts(pointer client, FontPathElementPtr fpe, 
+                      char *pat, int len, int max, 
+                      pointer *privatep, int mark_aliases);
+
+typedef struct _LFWIData {
+    pointer            *privates;
+    int                        current;
+} LFWIDataRec, *LFWIDataPtr;
+
+static int
+CatalogueStartListFonts(pointer client, FontPathElementPtr fpe, 
+                       char *pat, int len, int max, pointer *privatep,
+                       int mark_aliases)
+{
+    CataloguePtr       cat = fpe->private;
+    LFWIDataPtr                data;
+    int                        ret, i, j;
+
+    CatalogueRescan (fpe, FALSE);
+
+    data = malloc (sizeof *data + sizeof data->privates[0] * cat->fpeCount);
+    if (!data)
+       return AllocError;
+    data->privates = (pointer *) (data + 1);
+
+    for (i = 0; i < cat->fpeCount; i++)
+    {
+       ret = FontFileStartListFonts(client, cat->fpeList[i], pat, len,
+                                    max, &data->privates[i], mark_aliases);
+       if (ret != Successful)
+           goto bail;
+    }
+
+    data->current = 0;
+    *privatep = (pointer) data;
+    return Successful;
+
+ bail:
+    for (j = 0; j < i; j++)
+       /* FIXME: we have no way to free the per-fpe privates. */;
+    free (data);
+
+    return AllocError;
+}
+
+static int
+CatalogueStartListFontsWithInfo(pointer client, FontPathElementPtr fpe, 
+                               char *pat, int len, int max, 
+                               pointer *privatep)
+{
+    return CatalogueStartListFonts(client, fpe, pat, len, max, privatep, 0);
+}
+
+static int
+CatalogueListNextFontWithInfo(pointer client, FontPathElementPtr fpe, 
+                             char **namep, int *namelenp, 
+                             FontInfoPtr *pFontInfo,
+                             int *numFonts, pointer private)
+{
+    LFWIDataPtr                data = private;
+    CataloguePtr       cat = fpe->private;
+    int                        ret;
+
+    if (data->current == cat->fpeCount)
+    {
+       free(data);
+       return BadFontName;
+    }
+
+    ret = FontFileListNextFontWithInfo(client, cat->fpeList[data->current],
+                                      namep, namelenp,
+                                      pFontInfo, numFonts,
+                                      data->privates[data->current]);
+    if (ret == BadFontName)
+    {
+       data->current++;
+       return CatalogueListNextFontWithInfo(client, fpe, namep, namelenp,
+                                            pFontInfo, numFonts, private);
+    }
+
+    return ret;
+}
+
+static int
+CatalogueStartListFontsAndAliases(pointer client, FontPathElementPtr fpe, 
+                                 char *pat, int len, int max, 
+                                 pointer *privatep)
+{
+    return CatalogueStartListFonts(client, fpe, pat, len, max, privatep, 1);
+}
+
+static int
+CatalogueListNextFontOrAlias(pointer client, FontPathElementPtr fpe, 
+                            char **namep, int *namelenp, char **resolvedp,
+                            int *resolvedlenp, pointer private)
+{
+    LFWIDataPtr                data = private;
+    CataloguePtr       cat = fpe->private;
+    int                        ret;
+
+    if (data->current == cat->fpeCount)
+    {
+       free(data);
+       return BadFontName;
+    }
+
+    ret = FontFileListNextFontOrAlias(client, cat->fpeList[data->current],
+                                     namep, namelenp,
+                                     resolvedp, resolvedlenp,
+                                     data->privates[data->current]);
+    if (ret == BadFontName)
+    {
+       data->current++;
+       return CatalogueListNextFontOrAlias(client, fpe, namep, namelenp,
+                                           resolvedp, resolvedlenp, private);
+    }
+
+    return ret;
+}
+
+void
+CatalogueRegisterLocalFpeFunctions (void)
+{
+    RegisterFPEFunctions(CatalogueNameCheck,
+                        CatalogueInitFPE,
+                        CatalogueFreeFPE,
+                        CatalogueResetFPE,
+                        CatalogueOpenFont,
+                        CatalogueCloseFont,
+                        CatalogueListFonts,
+                        CatalogueStartListFontsWithInfo,
+                        CatalogueListNextFontWithInfo,
+                        NULL,
+                        NULL,
+                        NULL,
+                        CatalogueStartListFontsAndAliases,
+                        CatalogueListNextFontOrAlias,
+                        FontFileEmptyBitmapSource);
+}
diff --git a/src/fontfile/decompress.c b/src/fontfile/decompress.c
new file mode 100755 (executable)
index 0000000..b1fc37b
--- /dev/null
@@ -0,0 +1,408 @@
+/*
+ * Copyright 1985, 1986 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * James A. Woods, derived from original work by Spencer Thomas
+ * and Joseph Orost.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+
+Copyright 1993, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/* 
+ * decompress - cat a compressed file
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fontmisc.h>
+#include <X11/fonts/bufio.h>
+
+#define BITS   16
+
+/*
+ * a code_int must be able to hold 2**BITS values of type int, and also -1
+ */
+#if BITS > 15
+typedef long int       code_int;
+#else
+typedef int            code_int;
+#endif
+
+typedef long int         count_int;
+
+#ifdef NO_UCHAR
+ typedef char  char_type;
+#else
+ typedef       unsigned char   char_type;
+#endif /* UCHAR */
+
+static char_type magic_header[] = { "\037\235" };      /* 1F 9D */
+
+/* Defines for third byte of header */
+#define BIT_MASK       0x1f
+#define BLOCK_MASK     0x80
+/* Masks 0x40 and 0x20 are free.  I think 0x20 should mean that there is
+   a fourth header byte (for expansion).
+*/
+
+#define INIT_BITS 9                    /* initial number of bits/code */
+
+#ifdef COMPATIBLE              /* But wrong! */
+# define MAXCODE(n_bits)       (1 << (n_bits) - 1)
+#else
+# define MAXCODE(n_bits)       ((1 << (n_bits)) - 1)
+#endif /* COMPATIBLE */
+
+/*
+ * the next two codes should not be changed lightly, as they must not
+ * lie within the contiguous general code space.
+ */ 
+#define FIRST  257     /* first free entry */
+#define        CLEAR   256     /* table clear output code */
+
+#define STACK_SIZE  8192
+
+typedef struct _compressedFILE {
+    BufFilePtr     file;
+
+    char_type      *stackp;
+    code_int       oldcode;
+    char_type      finchar;
+
+    int                block_compress;
+    int                maxbits;
+    code_int   maxcode, maxmaxcode;
+
+    code_int   free_ent;
+    int                clear_flg;
+    int                n_bits;
+
+    /* bit buffer */
+    int                offset, size;
+    char_type  buf[BITS];
+
+    char_type      de_stack[STACK_SIZE];
+    char_type      *tab_suffix;
+    unsigned short  *tab_prefix;
+} CompressedFile;
+
+
+static int hsize_table[] = {
+    5003,      /* 12 bits - 80% occupancy */
+    9001,      /* 13 bits - 91% occupancy */
+    18013,     /* 14 bits - 91% occupancy */
+    35023,     /* 15 bits - 94% occupancy */
+    69001      /* 16 bits - 95% occupancy */
+};
+
+static int BufCompressedClose ( BufFilePtr f, int doClose );
+static int BufCompressedFill ( BufFilePtr f );
+static code_int getcode ( CompressedFile *file );
+static int BufCompressedSkip ( BufFilePtr f, int bytes );
+
+BufFilePtr
+BufFilePushCompressed (BufFilePtr f)
+{
+    int                    code;
+    int                    maxbits;
+    int                    hsize;
+    CompressedFile  *file;
+    int                    extra;
+
+    if ((BufFileGet(f) != (magic_header[0] & 0xFF)) ||
+       (BufFileGet(f) != (magic_header[1] & 0xFF)))
+    {
+       return 0;
+    }
+    code = BufFileGet (f);
+    if (code == BUFFILEEOF) return 0;
+    
+    maxbits = code & BIT_MASK;
+    if (maxbits > BITS || maxbits < 12)
+       return 0;
+    hsize = hsize_table[maxbits - 12];
+    extra = (1 << maxbits) * sizeof (char_type) +
+           hsize * sizeof (unsigned short);
+    file = malloc (sizeof (CompressedFile) + extra);
+    if (!file)
+       return 0;
+    file->file = f;
+    file->maxbits = maxbits;
+    file->block_compress = code & BLOCK_MASK;
+    file->maxmaxcode = 1 << file->maxbits;
+    file->tab_suffix = (char_type *) &file[1];
+    file->tab_prefix = (unsigned short *) (file->tab_suffix + file->maxmaxcode);
+    /*
+     * As above, initialize the first 256 entries in the table.
+     */
+    file->maxcode = MAXCODE(file->n_bits = INIT_BITS);
+    for ( code = 255; code >= 0; code-- ) {
+       file->tab_prefix[code] = 0;
+       file->tab_suffix[code] = (char_type) code;
+    }
+    file->free_ent = ((file->block_compress) ? FIRST : 256 );
+    file->clear_flg = 0;
+    file->offset = 0;
+    file->size = 0;
+    file->stackp = file->de_stack;
+    bzero(file->buf, BITS);
+    file->finchar = file->oldcode = getcode (file);
+    if (file->oldcode != -1)
+       *file->stackp++ = file->finchar;
+    return BufFileCreate ((char *) file,
+                         BufCompressedFill,
+                         0,
+                         BufCompressedSkip,
+                         BufCompressedClose);
+}
+
+static int
+BufCompressedClose (BufFilePtr f, int doClose)
+{
+    CompressedFile  *file;
+    BufFilePtr     raw;
+
+    file = (CompressedFile *) f->private;
+    raw = file->file;
+    free (file);
+    BufFileClose (raw, doClose);
+    return 1;
+}
+
+static int
+BufCompressedFill (BufFilePtr f)
+{
+    CompressedFile  *file;
+    register char_type *stackp, *de_stack;
+    register char_type finchar;
+    register code_int code, oldcode, incode;
+    BufChar        *buf, *bufend;
+
+    file = (CompressedFile *) f->private;
+
+    buf = f->buffer;
+    bufend = buf + BUFFILESIZE;
+    stackp = file->stackp;
+    de_stack = file->de_stack;
+    finchar = file->finchar;
+    oldcode = file->oldcode;
+    while (buf < bufend) {
+       while (stackp > de_stack && buf < bufend)
+           *buf++ = *--stackp;
+
+       if (buf == bufend)
+           break;
+
+       if (oldcode == -1)
+           break;
+
+       code = getcode (file);
+       if (code == -1)
+           break;
+    
+       if ( (code == CLEAR) && file->block_compress ) {
+           for ( code = 255; code >= 0; code-- )
+               file->tab_prefix[code] = 0;
+           file->clear_flg = 1;
+           file->free_ent = FIRST - 1;
+           if ( (code = getcode (file)) == -1 )        /* O, untimely death! */
+               break;
+       }
+       incode = code;
+       /*
+        * Special case for KwKwK string.
+        */
+       if ( code >= file->free_ent ) {
+           *stackp++ = finchar;
+           code = oldcode;
+       }
+    
+       /*
+        * Generate output characters in reverse order
+        */
+       while ( code >= 256 )
+       {
+           *stackp++ = file->tab_suffix[code];
+           code = file->tab_prefix[code];
+       }
+       finchar = file->tab_suffix[code];
+       *stackp++ = finchar;
+    
+       /*
+        * Generate the new entry.
+        */
+       if ( (code=file->free_ent) < file->maxmaxcode ) {
+           file->tab_prefix[code] = (unsigned short)oldcode;
+           file->tab_suffix[code] = finchar;
+           file->free_ent = code+1;
+       } 
+       /*
+        * Remember previous code.
+        */
+       oldcode = incode;
+    }
+    file->oldcode = oldcode;
+    file->stackp = stackp;
+    file->finchar = finchar;
+    if (buf == f->buffer) {
+       f->left = 0;
+       return BUFFILEEOF;
+    }
+    f->bufp = f->buffer + 1;
+    f->left = (buf - f->buffer) - 1;
+    return f->buffer[0];
+}
+
+/*****************************************************************
+ * TAG( getcode )
+ *
+ * Read one code from the standard input.  If BUFFILEEOF, return -1.
+ * Inputs:
+ *     stdin
+ * Outputs:
+ *     code or -1 is returned.
+ */
+
+static char_type rmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
+
+static code_int
+getcode(CompressedFile *file)
+{
+    register code_int code;
+    register int r_off, bits;
+    register char_type *bp = file->buf;
+    register BufFilePtr        raw;
+
+    if ( file->clear_flg > 0 || file->offset >= file->size ||
+       file->free_ent > file->maxcode )
+    {
+       /*
+        * If the next entry will be too big for the current code
+        * size, then we must increase the size.  This implies reading
+        * a new buffer full, too.
+        */
+       if ( file->free_ent > file->maxcode ) {
+           file->n_bits++;
+           if ( file->n_bits == file->maxbits )
+               file->maxcode = file->maxmaxcode;       /* won't get any bigger now */
+           else
+               file->maxcode = MAXCODE(file->n_bits);
+       }
+       if ( file->clear_flg > 0) {
+           file->maxcode = MAXCODE (file->n_bits = INIT_BITS);
+           file->clear_flg = 0;
+       }
+       bits = file->n_bits;
+       raw = file->file;
+       while (bits > 0 && (code = BufFileGet (raw)) != BUFFILEEOF)
+       {
+           *bp++ = code;
+           --bits;
+       }
+       bp = file->buf;
+       if (bits == file->n_bits)
+           return -1;                  /* end of file */
+       file->size = file->n_bits - bits;
+       file->offset = 0;
+       /* Round size down to integral number of codes */
+       file->size = (file->size << 3) - (file->n_bits - 1);
+    }
+    r_off = file->offset;
+    bits = file->n_bits;
+    /*
+     * Get to the first byte.
+     */
+    bp += (r_off >> 3);
+    r_off &= 7;
+    /* Get first part (low order bits) */
+#ifdef NO_UCHAR
+    code = ((*bp++ >> r_off) & rmask[8 - r_off]) & 0xff;
+#else
+    code = (*bp++ >> r_off);
+#endif /* NO_UCHAR */
+    bits -= (8 - r_off);
+    r_off = 8 - r_off;         /* now, offset into code word */
+    /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
+    if ( bits >= 8 ) {
+#ifdef NO_UCHAR
+       code |= (*bp++ & 0xff) << r_off;
+#else
+       code |= *bp++ << r_off;
+#endif /* NO_UCHAR */
+       r_off += 8;
+       bits -= 8;
+    }
+    /* high order bits. */
+    code |= (*bp & rmask[bits]) << r_off;
+    file->offset += file->n_bits;
+
+    return code;
+}
+
+static int
+BufCompressedSkip (BufFilePtr f, int bytes)
+{
+    int                    c;
+    while (bytes--) 
+    {
+       c = BufFileGet(f);
+       if (c == BUFFILEEOF)
+           return BUFFILEEOF;
+    }
+    return 0;
+}
+
+#ifdef TEST
+int
+main (int argc, char *argv[])
+{
+    BufFilePtr     inputraw, input, output;
+    int                    c;
+    
+    inputraw = BufFileOpenRead (0);
+    input = BufFilePushCompressed (inputraw);
+    output = BufFileOpenWrite (1);
+    while ((c = BufFileGet (input)) != BUFFILEEOF)
+       BufFilePut (c, output);
+    BufFileClose (input, FALSE);
+    BufFileClose (output, FALSE);
+    return 0;
+}
+#endif
diff --git a/src/fontfile/defaults.c b/src/fontfile/defaults.c
new file mode 100755 (executable)
index 0000000..1ad7d7c
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+
+Copyright 1990, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+/*
+ * Author:  Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include    <X11/X.h>
+#include    <X11/Xproto.h>
+
+#ifndef DEFAULT_BIT_ORDER
+#ifdef BITMAP_BIT_ORDER
+#define DEFAULT_BIT_ORDER BITMAP_BIT_ORDER
+#else
+#define DEFAULT_BIT_ORDER MSBFirst
+#endif
+#endif
+
+#ifndef DEFAULT_BYTE_ORDER
+#ifdef IMAGE_BYTE_ORDER
+#define DEFAULT_BYTE_ORDER IMAGE_BYTE_ORDER
+#else
+#define DEFAULT_BYTE_ORDER MSBFirst
+#endif
+#endif
+
+#ifndef DEFAULT_GLYPH_PAD
+#ifdef GLYPHPADBYTES
+#define DEFAULT_GLYPH_PAD GLYPHPADBYTES
+#else
+#define DEFAULT_GLYPH_PAD 4
+#endif
+#endif
+
+#ifndef DEFAULT_SCAN_UNIT
+#define DEFAULT_SCAN_UNIT 1
+#endif
+
+#include <X11/fonts/fntfilst.h>
+
+void
+FontDefaultFormat (int *bit, int *byte, int *glyph, int *scan)
+{
+    *bit = DEFAULT_BIT_ORDER;
+    *byte = DEFAULT_BYTE_ORDER;
+    *glyph = DEFAULT_GLYPH_PAD;
+    *scan = DEFAULT_SCAN_UNIT;
+}
diff --git a/src/fontfile/dirfile.c b/src/fontfile/dirfile.c
new file mode 100755 (executable)
index 0000000..c8aff6f
--- /dev/null
@@ -0,0 +1,492 @@
+/*
+
+Copyright 1991, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+/*
+ * Author:  Keith Packard, MIT X Consortium
+ */
+
+/*
+ * dirfile.c
+ *
+ * Read fonts.dir and fonts.alias files
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fntfilst.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+static Bool AddFileNameAliases ( FontDirectoryPtr dir );
+static int ReadFontAlias ( char *directory, Bool isFile,
+                          FontDirectoryPtr *pdir );
+static int lexAlias ( FILE *file, char **lexToken );
+static int lexc ( FILE *file );
+
+int
+FontFileReadDirectory (char *directory, FontDirectoryPtr *pdir)
+{
+    char        file_name[MAXFONTFILENAMELEN];
+    char        font_name[MAXFONTNAMELEN];
+    char        dir_file[MAXFONTFILENAMELEN];
+    char       dir_path[MAXFONTFILENAMELEN];
+    char       *ptr;
+    FILE       *file;
+    int         count,
+                num_fonts,
+                status;
+    struct stat        statb;
+    static char format[24] = "";
+#if defined(WIN32)
+    int i;
+#endif
+
+    FontDirectoryPtr   dir = NullFontDirectory;
+
+    if (strlen(directory) + 1 + sizeof(FontDirFile) > sizeof(dir_file))
+       return BadFontPath;
+
+    /* Check for font directory attributes */
+#if !defined(WIN32)
+    if ((ptr = strchr(directory, ':'))) {
+#else
+    /* OS/2 and WIN32 path might start with a drive letter, don't clip this */
+    if ((ptr = strchr(directory+2, ':'))) {
+#endif
+       strncpy(dir_path, directory, ptr - directory);
+       dir_path[ptr - directory] = '\0';
+    } else {
+       strcpy(dir_path, directory);
+    }
+    strcpy(dir_file, dir_path);
+    if (dir_file[strlen(dir_file) - 1] != '/')
+       strcat(dir_file, "/");
+    strcat(dir_file, FontDirFile);
+    file = fopen(dir_file, "rt");
+    if (file) {
+#ifndef WIN32        
+       if (fstat (fileno(file), &statb) == -1)
+#else
+       if (stat (dir_file, &statb) == -1)
+#endif
+        {
+            fclose(file);
+           return BadFontPath;
+        }
+       count = fscanf(file, "%d\n", &num_fonts);
+       if ((count == EOF) || (count != 1)) {
+           fclose(file);
+           return BadFontPath;
+       }
+       dir = FontFileMakeDir(directory, num_fonts);
+       if (dir == NULL) {
+           fclose(file);
+           return BadFontPath;
+       }
+       dir->dir_mtime = statb.st_mtime;
+       if (format[0] == '\0')
+           sprintf(format, "%%%ds %%%d[^\n]\n",
+               MAXFONTFILENAMELEN-1, MAXFONTNAMELEN-1);
+
+       while ((count = fscanf(file, format, file_name, font_name)) != EOF) {
+#if defined(WIN32)
+           /* strip any existing trailing CR */
+           for (i=0; i<strlen(font_name); i++) {
+               if (font_name[i]=='\r') font_name[i] = '\0';
+           }
+#endif
+           if (count != 2) {
+               FontFileFreeDir (dir);
+               fclose(file);
+               return BadFontPath;
+           }
+
+           /*
+            * We blindly try to load all the font files specified.
+            * In theory, we might want to warn that some of the fonts
+            * couldn't be loaded.
+            */
+           FontFileAddFontFile (dir, font_name, file_name);
+       }
+       fclose(file);
+       
+    } else if (errno != ENOENT) {
+       return BadFontPath;
+    }
+    status = ReadFontAlias(dir_path, FALSE, &dir);
+    if (status != Successful) {
+       if (dir)
+           FontFileFreeDir (dir);
+       return status;
+    }
+    if (!dir)
+       return BadFontPath;
+
+    FontFileSortDir(dir);
+
+    *pdir = dir;
+    return Successful;
+}
+
+Bool
+FontFileDirectoryChanged(FontDirectoryPtr dir)
+{
+    char       dir_file[MAXFONTFILENAMELEN];
+    struct stat        statb;
+
+    if (strlen(dir->directory) + sizeof(FontDirFile) > sizeof(dir_file))
+       return FALSE;
+
+    strcpy (dir_file, dir->directory);
+    strcat (dir_file, FontDirFile);
+    if (stat (dir_file, &statb) == -1)
+    {
+       if (errno != ENOENT || dir->dir_mtime != 0)
+           return TRUE;
+       return FALSE;           /* doesn't exist and never did: no change */
+    }
+    if (dir->dir_mtime != statb.st_mtime)
+       return TRUE;
+
+    if ((strlen(dir->directory) + sizeof(FontAliasFile)) > sizeof(dir_file))
+       return FALSE;
+    strcpy (dir_file, dir->directory);
+    strcat (dir_file, FontAliasFile);
+    if (stat (dir_file, &statb) == -1)
+    {
+       if (errno != ENOENT || dir->alias_mtime != 0)
+           return TRUE;
+       return FALSE;           /* doesn't exist and never did: no change */
+    }
+    if (dir->alias_mtime != statb.st_mtime)
+       return TRUE;
+    return FALSE;
+}
+    
+/*
+ * Make each of the file names an automatic alias for each of the files.
+ */
+
+static Bool
+AddFileNameAliases(FontDirectoryPtr dir)
+{
+    int                    i;
+    char           copy[MAXFONTFILENAMELEN];
+    char           *fileName;
+    FontTablePtr    table;
+    FontRendererPtr renderer;
+    int                    len;
+    FontNameRec            name;
+
+    table = &dir->nonScalable;
+    for (i = 0; i < table->used; i++) {
+       if (table->entries[i].type != FONT_ENTRY_BITMAP)
+           continue;
+       fileName = table->entries[i].u.bitmap.fileName;
+       renderer = FontFileMatchRenderer (fileName);
+       if (!renderer)
+           continue;
+       
+       len = strlen (fileName) - renderer->fileSuffixLen;
+       if (len >= sizeof(copy))
+           continue;
+       CopyISOLatin1Lowered (copy, fileName, len);
+       copy[len] = '\0';
+       name.name = copy;
+       name.length = len;
+       name.ndashes = FontFileCountDashes (copy, len);
+
+       if (!FontFileFindNameInDir(table, &name)) {
+           if (!FontFileAddFontAlias (dir, copy, table->entries[i].name.name))
+               return FALSE;
+       }
+    }
+    return TRUE;
+}
+
+/*
+ * parse the font.alias file.  Format is:
+ *
+ * alias font-name
+ *
+ * To imbed white-space in an alias name, enclose it like "font name"
+ * in double quotes.  \ escapes and character, so
+ * "font name \"With Double Quotes\" \\ and \\ back-slashes"
+ * works just fine.
+ *
+ * A line beginning with a ! denotes a newline-terminated comment.
+ */
+
+/*
+ * token types
+ */
+
+#define NAME           0
+#define NEWLINE                1
+#define DONE           2
+#define EALLOC         3
+
+static int
+ReadFontAlias(char *directory, Bool isFile, FontDirectoryPtr *pdir)
+{
+    char               alias[MAXFONTNAMELEN];
+    char               font_name[MAXFONTNAMELEN];
+    char               alias_file[MAXFONTFILENAMELEN];
+    FILE               *file;
+    FontDirectoryPtr   dir;
+    int                        token;
+    char               *lexToken;
+    int                        status = Successful;
+    struct stat                statb;
+
+    if (strlen(directory) >= sizeof(alias_file))
+       return BadFontPath;
+    dir = *pdir;
+    strcpy(alias_file, directory);
+    if (!isFile) {
+       if (strlen(directory) + 1 + sizeof(FontAliasFile) > sizeof(alias_file))
+           return BadFontPath;
+       if (directory[strlen(directory) - 1] != '/')
+           strcat(alias_file, "/");
+       strcat(alias_file, FontAliasFile);
+    }
+    file = fopen(alias_file, "rt");
+    if (!file)
+       return ((errno == ENOENT) ? Successful : BadFontPath);
+    if (!dir)
+       *pdir = dir = FontFileMakeDir(directory, 10);
+    if (!dir)
+    {
+       fclose (file);
+       return AllocError;
+    }
+#ifndef WIN32
+    if (fstat (fileno (file), &statb) == -1)
+#else
+    if (stat (alias_file, &statb) == -1)
+#endif
+    {
+       fclose (file);
+       return BadFontPath;
+    }
+    dir->alias_mtime = statb.st_mtime;
+    while (status == Successful) {
+       token = lexAlias(file, &lexToken);
+       switch (token) {
+       case NEWLINE:
+           break;
+       case DONE:
+           fclose(file);
+           return Successful;
+       case EALLOC:
+           status = AllocError;
+           break;
+       case NAME:
+           if (strlen(lexToken) >= sizeof(alias)) {
+               status = BadFontPath;
+               break;
+           }
+           strcpy(alias, lexToken);
+           token = lexAlias(file, &lexToken);
+           switch (token) {
+           case NEWLINE:
+               if (strcmp(alias, "FILE_NAMES_ALIASES"))
+                   status = BadFontPath;
+               else if (!AddFileNameAliases(dir))
+                   status = AllocError;
+               break;
+           case DONE:
+               status = BadFontPath;
+               break;
+           case EALLOC:
+               status = AllocError;
+               break;
+           case NAME:
+               if (strlen(lexToken) >= sizeof(font_name)) {
+                   status = BadFontPath;
+                   break;
+               }
+               CopyISOLatin1Lowered(alias, alias, strlen(alias));
+               CopyISOLatin1Lowered(font_name, lexToken, strlen(lexToken));
+               if (!FontFileAddFontAlias (dir, alias, font_name))
+                   status = AllocError;
+               break;
+           }
+       }
+    }
+    fclose(file);
+    return status;
+}
+
+#define QUOTE          0
+#define WHITE          1
+#define NORMAL         2
+#define END            3
+#define NL             4
+#define BANG           5
+
+static int  charClass;
+
+static int
+lexAlias(FILE *file, char **lexToken)
+{
+    int         c;
+    char       *t;
+    enum state {
+       Begin, Normal, Quoted, Comment
+    }           state;
+    int         count;
+
+    static char *tokenBuf = (char *) NULL;
+    static int  tokenSize = 0;
+
+    t = tokenBuf;
+    count = 0;
+    state = Begin;
+    for (;;) {
+       if (count == tokenSize) {
+           int         nsize;
+           char       *nbuf;
+
+           nsize = tokenSize ? (tokenSize << 1) : 64;
+           nbuf = realloc(tokenBuf, nsize);
+           if (!nbuf)
+               return EALLOC;
+           tokenBuf = nbuf;
+           tokenSize = nsize;
+           t = tokenBuf + count;
+       }
+       c = lexc(file);
+       switch (charClass) {
+       case QUOTE:
+           switch (state) {
+           case Begin:
+           case Normal:
+               state = Quoted;
+               break;
+           case Quoted:
+               state = Normal;
+               break;
+           case Comment:
+               break;
+           }
+           break;
+       case WHITE:
+           switch (state) {
+           case Begin:
+           case Comment:
+               continue;
+           case Normal:
+               *t = '\0';
+               *lexToken = tokenBuf;
+               return NAME;
+           case Quoted:
+               break;
+           }
+           /* fall through */
+       case NORMAL:
+           switch (state) {
+           case Begin:
+               state = Normal;
+               break;
+           case Comment:
+               continue;
+           default:
+               break;
+           }
+           *t++ = c;
+           ++count;
+           break;
+       case END:
+       case NL:
+           switch (state) {
+           case Begin:
+           case Comment:
+               *lexToken = (char *) NULL;
+               return charClass == END ? DONE : NEWLINE;
+           default:
+               *t = '\0';
+               *lexToken = tokenBuf;
+               ungetc(c, file);
+               return NAME;
+           }
+           break;
+       case BANG:
+           switch (state) {
+           case Begin:
+               state = Comment;
+               break;
+            case Comment:
+               break;
+            default:
+               *t++ = c;
+               ++count;
+           }
+           break;
+       }
+    }
+}
+
+static int
+lexc(FILE *file)
+{
+    int         c;
+
+    c = getc(file);
+    switch (c) {
+    case EOF:
+       charClass = END;
+       break;
+    case '\\':
+       c = getc(file);
+       if (c == EOF)
+           charClass = END;
+       else
+           charClass = NORMAL;
+       break;
+    case '"':
+       charClass = QUOTE;
+       break;
+    case ' ':
+    case '\t':
+       charClass = WHITE;
+       break;
+    case '\r':
+    case '\n':
+       charClass = NL;
+       break;
+    case '!':
+       charClass = BANG;
+       break;
+    default:
+       charClass = NORMAL;
+       break;
+    }
+    return c;
+}
diff --git a/src/fontfile/fileio.c b/src/fontfile/fileio.c
new file mode 100755 (executable)
index 0000000..80af511
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+
+Copyright 1991, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+/*
+ * Author:  Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fntfilio.h>
+#include <X11/Xos.h>
+#ifndef O_BINARY
+#define O_BINARY O_RDONLY
+#endif
+
+FontFilePtr
+FontFileOpen (const char *name)
+{
+    int                fd;
+    int                len;
+    BufFilePtr raw, cooked;
+
+    fd = open (name, O_BINARY);
+    if (fd < 0)
+       return 0;
+    raw = BufFileOpenRead (fd);
+    if (!raw)
+    {
+       close (fd);
+       return 0;
+    }
+    len = strlen (name);
+    if (len > 2 && !strcmp (name + len - 2, ".Z")) {
+       cooked = BufFilePushCompressed (raw);
+       if (!cooked) {
+           BufFileClose (raw, TRUE);
+           return 0;
+       }
+       raw = cooked;
+#ifdef X_GZIP_FONT_COMPRESSION
+    } else if (len > 3 && !strcmp (name + len - 3, ".gz")) {
+       cooked = BufFilePushZIP (raw);
+       if (!cooked) {
+           BufFileClose (raw, TRUE);
+           return 0;
+       }
+       raw = cooked;
+#endif
+#ifdef X_BZIP2_FONT_COMPRESSION
+    } else if (len > 4 && !strcmp (name + len - 4, ".bz2")) {
+       cooked = BufFilePushBZIP2 (raw);
+       if (!cooked) {
+           BufFileClose (raw, TRUE);
+           return 0;
+       }
+       raw = cooked;
+#endif
+    }
+    return (FontFilePtr) raw;
+}
+
+int
+FontFileClose (FontFilePtr f)
+{
+    return BufFileClose ((BufFilePtr) f, TRUE);
+}
+
diff --git a/src/fontfile/filewr.c b/src/fontfile/filewr.c
new file mode 100755 (executable)
index 0000000..bcc7b1e
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+
+Copyright 1991, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+/*
+ * Author:  Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fntfilio.h>
+#include <X11/Xos.h>
+
+FontFilePtr
+FontFileOpenWrite (const char *name)
+{
+    int        fd;
+
+#if defined(WIN32) || defined(__CYGWIN__)
+    fd = open (name, O_CREAT|O_TRUNC|O_RDWR|O_BINARY, 0666);
+#else
+    fd = creat (name, 0666);
+#endif
+    if (fd < 0)
+       return 0;
+    return (FontFilePtr) BufFileOpenWrite (fd);
+}
+
+FontFilePtr
+FontFileOpenWriteFd (int fd)
+{
+    return (FontFilePtr) BufFileOpenWrite (fd);
+}
+
+FontFilePtr
+FontFileOpenFd (int fd)
+{
+    return (FontFilePtr) BufFileOpenRead (fd);
+}
diff --git a/src/fontfile/fontdir.c b/src/fontfile/fontdir.c
new file mode 100755 (executable)
index 0000000..e052bb3
--- /dev/null
@@ -0,0 +1,825 @@
+/*
+
+Copyright 1991, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+/*
+ * Author:  Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include    <X11/fonts/fntfilst.h>
+#include    <X11/keysym.h>
+
+#if HAVE_STDINT_H
+#include <stdint.h>
+#elif !defined(INT32_MAX)
+#define INT32_MAX 0x7fffffff
+#endif
+
+Bool
+FontFileInitTable (FontTablePtr table, int size)
+{
+    if (size < 0 || (size > INT32_MAX/sizeof(FontEntryRec))) 
+       return FALSE;
+    if (size)
+    {
+       table->entries = malloc(sizeof(FontEntryRec) * size);
+       if (!table->entries)
+           return FALSE;
+    }
+    else
+       table->entries = 0;
+    table->used = 0;
+    table->size = size;
+    table->sorted = FALSE;
+    return TRUE;
+}
+
+void
+FontFileFreeEntry (FontEntryPtr entry)
+{
+    FontScalableExtraPtr   extra;
+    int i;
+
+    if (entry->name.name)
+       free(entry->name.name);
+    entry->name.name = NULL;
+
+    switch (entry->type)
+    {
+    case FONT_ENTRY_SCALABLE:
+       free (entry->u.scalable.fileName);
+       extra = entry->u.scalable.extra;
+       for (i = 0; i < extra->numScaled; i++)
+           if (extra->scaled[i].vals.ranges)
+               free (extra->scaled[i].vals.ranges);
+       free (extra->scaled);
+       free (extra);
+       break;
+    case FONT_ENTRY_BITMAP:
+       free (entry->u.bitmap.fileName);
+       entry->u.bitmap.fileName = NULL;
+       break;
+    case FONT_ENTRY_ALIAS:
+       free (entry->u.alias.resolved);
+       entry->u.alias.resolved = NULL;
+       break;
+    }
+}
+
+void
+FontFileFreeTable (FontTablePtr table)
+{
+    int        i;
+
+    for (i = 0; i < table->used; i++)
+       FontFileFreeEntry (&table->entries[i]);
+    free (table->entries);
+}
+
+FontDirectoryPtr
+FontFileMakeDir(char *dirName, int size)
+{
+    FontDirectoryPtr   dir;
+    int                        dirlen;
+    int                        needslash = 0;
+    char               *attrib;
+    int                        attriblen;
+
+#if !defined(WIN32)
+    attrib = strchr(dirName, ':');
+#else
+    /* OS/2 uses the colon in the drive letter descriptor, skip this */
+    attrib = strchr(dirName+2, ':');
+#endif
+    if (attrib) {
+       dirlen = attrib - dirName;
+       attriblen = strlen(attrib);
+    } else {
+       dirlen = strlen(dirName);
+       attriblen = 0;
+    }
+    if (dirName[dirlen - 1] != '/')
+#ifdef NCD
+    if (dirlen)     /* leave out slash for builtins */
+#endif
+       needslash = 1;
+    dir = malloc(sizeof *dir + dirlen + needslash + 1 +
+                (attriblen ? attriblen + 1 : 0));
+    if (!dir)
+       return (FontDirectoryPtr)0;
+    if (!FontFileInitTable (&dir->scalable, 0))
+    {
+       free (dir);
+       return (FontDirectoryPtr)0;
+    }
+    if (!FontFileInitTable (&dir->nonScalable, size))
+    {
+       FontFileFreeTable (&dir->scalable);
+       free (dir);
+       return (FontDirectoryPtr)0;
+    }
+    dir->directory = (char *) (dir + 1);
+    dir->dir_mtime = 0;
+    dir->alias_mtime = 0;
+    if (attriblen)
+       dir->attributes = dir->directory + dirlen + needslash + 1;
+    else
+       dir->attributes = NULL;
+    strncpy(dir->directory, dirName, dirlen);
+    dir->directory[dirlen] = '\0';
+    if (dir->attributes)
+       strcpy(dir->attributes, attrib);
+    if (needslash)
+       strcat(dir->directory, "/");
+    return dir;
+}
+
+void
+FontFileFreeDir (FontDirectoryPtr dir)
+{
+    FontFileFreeTable (&dir->scalable);
+    FontFileFreeTable (&dir->nonScalable);
+    free(dir);
+}
+
+FontEntryPtr
+FontFileAddEntry(FontTablePtr table, FontEntryPtr prototype)
+{
+    FontEntryPtr    entry;
+    int                    newsize;
+
+    /* can't add entries to a sorted table, pointers get broken! */
+    if (table->sorted)
+       return (FontEntryPtr) 0;    /* "cannot" happen */
+    if (table->used == table->size) {
+       newsize = table->size + 100;
+       entry = realloc(table->entries, newsize * sizeof(FontEntryRec));
+       if (!entry)
+           return (FontEntryPtr)0;
+       table->size = newsize;
+       table->entries = entry;
+    }
+    entry = &table->entries[table->used];
+    *entry = *prototype;
+    entry->name.name = malloc(prototype->name.length + 1);
+    if (!entry->name.name)
+       return (FontEntryPtr)0;
+    memcpy (entry->name.name, prototype->name.name, prototype->name.length);
+    entry->name.name[entry->name.length] = '\0';
+    table->used++;
+    return entry;
+}
+
+/*
+ * Compare two strings just like strcmp, but preserve decimal integer
+ * sorting order, i.e. "2" < "10" or "iso8859-2" < "iso8859-10" <
+ * "iso10646-1". Strings are sorted as if sequences of digits were
+ * prefixed by a length indicator (i.e., does not ignore leading zeroes).
+ *
+ * Markus Kuhn <Markus.Kuhn@cl.cam.ac.uk>
+ */
+#define Xisdigit(c) ('\060' <= (c) && (c) <= '\071')
+
+static int strcmpn(const char *s1, const char *s2)
+{
+    int digits, predigits = 0;
+    const char *ss1, *ss2;
+
+    while (1) {
+       if (*s1 == 0 && *s2 == 0)
+           return 0;
+       digits = Xisdigit(*s1) && Xisdigit(*s2);
+       if (digits && !predigits) {
+           ss1 = s1;
+           ss2 = s2;
+           while (Xisdigit(*ss1) && Xisdigit(*ss2))
+               ss1++, ss2++;
+           if (!Xisdigit(*ss1) && Xisdigit(*ss2))
+               return -1;
+           if (Xisdigit(*ss1) && !Xisdigit(*ss2))
+               return 1;
+       }
+       if ((unsigned char)*s1 < (unsigned char)*s2)
+           return -1;
+       if ((unsigned char)*s1 > (unsigned char)*s2)
+           return 1;
+       predigits = digits;
+       s1++, s2++;
+    }
+}
+
+
+static int
+FontFileNameCompare(const void* a, const void* b)
+{
+    FontEntryPtr    a_name = (FontEntryPtr) a,
+                   b_name = (FontEntryPtr) b;
+
+    return strcmpn(a_name->name.name, b_name->name.name);
+}
+
+void
+FontFileSortTable (FontTablePtr table)
+{
+    if (!table->sorted) {
+       qsort((char *) table->entries, table->used, sizeof(FontEntryRec),
+             FontFileNameCompare);
+       table->sorted = TRUE;
+    }
+}
+
+void
+FontFileSortDir(FontDirectoryPtr dir)
+{
+    FontFileSortTable (&dir->scalable);
+    FontFileSortTable (&dir->nonScalable);
+    /* now that the table is fixed in size, swizzle the pointers */
+    FontFileSwitchStringsToBitmapPointers (dir);
+}
+
+/*
+  Given a Font Table, SetupWildMatch() sets up various pointers and state
+  information so the table can be searched for name(s) that match a given
+  fontname pattern -- which may contain wildcards.  Under certain
+  circumstances, SetupWildMatch() will find the one table entry that
+  matches the pattern.  If those circumstances do not pertain,
+  SetupWildMatch() returns a range within the the table that should be
+  searched for matching name(s).  With the information established by
+  SetupWildMatch(), including state information in "private", the
+  PatternMatch() procedure is then used to test names in the range for a
+  match.
+*/
+
+#define isWild(c)   ((c) == XK_asterisk || (c) == XK_question)
+#define isDigit(c)  (XK_0 <= (c) && (c) <= XK_9)
+
+static int
+SetupWildMatch(FontTablePtr table, FontNamePtr pat, 
+              int *leftp, int *rightp, int *privatep)
+{
+    int         nDashes;
+    char        c;
+    char       *t;
+    char       *firstWild;
+    char       *firstDigit;
+    int         first;
+    int         center,
+                left,
+                right;
+    int         result;
+    char       *name;
+
+    name = pat->name;
+    nDashes = pat->ndashes;
+    firstWild = 0;
+    firstDigit = 0;
+    t = name;
+    while ((c = *t++)) {
+       if (isWild(c)) {
+           if (!firstWild)
+               firstWild = t - 1;
+       }
+       if (isDigit(c)) {
+           if (!firstDigit)
+               firstDigit = t - 1;
+       }
+    }
+    left = 0;
+    right = table->used;
+    if (firstWild)
+       *privatep = nDashes;
+    else
+       *privatep = -1;
+    if (!table->sorted) {
+       *leftp = left;
+       *rightp = right;
+       return -1;
+    } else if (firstWild) {
+       if (firstDigit && firstDigit < firstWild)
+           first = firstDigit - name;
+       else
+           first = firstWild - name;
+       while (left < right) {
+           center = (left + right) / 2;
+           result = strncmp(name, table->entries[center].name.name, first);
+           if (result == 0)
+               break;
+           if (result < 0)
+               right = center;
+           else
+               left = center + 1;
+       }
+       *leftp = left;
+       *rightp = right;
+       return -1;
+    } else {
+       while (left < right) {
+           center = (left + right) / 2;
+           result = strcmpn(name, table->entries[center].name.name);
+           if (result == 0)
+               return center;
+           if (result < 0)
+               right = center;
+           else
+               left = center + 1;
+       }
+       *leftp = 1;
+       *rightp = 0;
+       return -1;
+    }
+}
+
+static int
+PatternMatch(char *pat, int patdashes, char *string, int stringdashes)
+{
+    char        c,
+                t;
+
+    if (stringdashes < patdashes)
+       return 0;
+    for (;;) {
+       switch (c = *pat++) {
+       case '*':
+           if (!(c = *pat++))
+               return 1;
+           if (c == XK_minus) {
+               patdashes--;
+               for (;;) {
+                   while ((t = *string++) != XK_minus)
+                       if (!t)
+                           return 0;
+                   stringdashes--;
+                   if (PatternMatch(pat, patdashes, string, stringdashes))
+                       return 1;
+                   if (stringdashes == patdashes)
+                       return 0;
+               }
+           } else {
+               for (;;) {
+                   while ((t = *string++) != c) {
+                       if (!t)
+                           return 0;
+                       if (t == XK_minus) {
+                           if (stringdashes-- < patdashes)
+                               return 0;
+                       }
+                   }
+                   if (PatternMatch(pat, patdashes, string, stringdashes))
+                       return 1;
+               }
+           }
+       case '?':
+           if (*string++ == XK_minus)
+               stringdashes--;
+           break;
+       case '\0':
+           return (*string == '\0');
+       case XK_minus:
+           if (*string++ == XK_minus) {
+               patdashes--;
+               stringdashes--;
+               break;
+           }
+           return 0;
+       default:
+           if (c == *string++)
+               break;
+           return 0;
+       }
+    }
+}
+
+int
+FontFileCountDashes (char *name, int namelen)
+{
+    int        ndashes = 0;
+
+    while (namelen--)
+       if (*name++ == '\055')  /* avoid non ascii systems */
+           ++ndashes;
+    return ndashes;
+}
+
+char *
+FontFileSaveString (char *s)
+{
+    char    *n;
+
+    n = malloc (strlen (s) + 1);
+    if (!n)
+       return 0;
+    strcpy (n, s);
+    return n;
+}
+
+FontEntryPtr
+FontFileFindNameInScalableDir(FontTablePtr table, FontNamePtr pat, 
+                             FontScalablePtr vals)
+{
+    int         i,
+                start,
+                stop,
+                res,
+                private;
+    FontNamePtr        name;
+
+    if (!table->entries)
+       return NULL;
+    if ((i = SetupWildMatch(table, pat, &start, &stop, &private)) >= 0)
+       return &table->entries[i];
+    for (i = start; i < stop; i++) {
+       name = &table->entries[i].name;
+       res = PatternMatch(pat->name, private, name->name, name->ndashes);
+       if (res > 0)
+       {
+           /* Check to see if enhancements requested are available */
+           if (vals)
+           {
+               int vs = vals->values_supplied;
+               int cap;
+
+               if (table->entries[i].type == FONT_ENTRY_SCALABLE)
+                   cap = table->entries[i].u.scalable.renderer->capabilities;
+               else if (table->entries[i].type == FONT_ENTRY_ALIAS)
+                   cap = ~0;   /* Calling code will have to see if true */
+               else
+                   cap = 0;
+               if ((((vs & PIXELSIZE_MASK) == PIXELSIZE_ARRAY ||
+                     (vs & POINTSIZE_MASK) == POINTSIZE_ARRAY) &&
+                    !(cap & CAP_MATRIX)) ||
+                   ((vs & CHARSUBSET_SPECIFIED) &&
+                    !(cap & CAP_CHARSUBSETTING)))
+                   continue;
+           }
+           return &table->entries[i];
+       }
+       if (res < 0)
+           break;
+    }
+    return (FontEntryPtr)0;
+}
+
+FontEntryPtr
+FontFileFindNameInDir(FontTablePtr table, FontNamePtr pat)
+{
+    return FontFileFindNameInScalableDir(table, pat, (FontScalablePtr)0);
+}
+
+int
+FontFileFindNamesInScalableDir(FontTablePtr table, FontNamePtr pat, int max, 
+                              FontNamesPtr names, FontScalablePtr vals,
+                              int alias_behavior, int *newmax)
+{
+    int                    i,
+                   start,
+                   stop,
+                   res,
+                   private;
+    int                    ret = Successful;
+    FontEntryPtr    fname;
+    FontNamePtr            name;
+
+    if (max <= 0)
+       return Successful;
+    if ((i = SetupWildMatch(table, pat, &start, &stop, &private)) >= 0) {
+       if (alias_behavior == NORMAL_ALIAS_BEHAVIOR ||
+           table->entries[i].type != FONT_ENTRY_ALIAS)
+       {
+           name = &table->entries[i].name;
+           if (newmax) *newmax = max - 1;
+           return AddFontNamesName(names, name->name, name->length);
+       }
+       start = i;
+       stop = i + 1;
+    }
+    for (i = start, fname = &table->entries[start]; i < stop; i++, fname++) {
+       res = PatternMatch(pat->name, private, fname->name.name, fname->name.ndashes);
+       if (res > 0) {
+           if (vals)
+           {
+               int vs = vals->values_supplied;
+               int cap;
+
+               if (fname->type == FONT_ENTRY_SCALABLE)
+                   cap = fname->u.scalable.renderer->capabilities;
+               else if (fname->type == FONT_ENTRY_ALIAS)
+                   cap = ~0;   /* Calling code will have to see if true */
+               else
+                   cap = 0;
+               if ((((vs & PIXELSIZE_MASK) == PIXELSIZE_ARRAY ||
+                    (vs & POINTSIZE_MASK) == POINTSIZE_ARRAY) &&
+                   !(cap & CAP_MATRIX)) ||
+                   ((vs & CHARSUBSET_SPECIFIED) &&
+                   !(cap & CAP_CHARSUBSETTING)))
+                   continue;
+           }
+
+           if ((alias_behavior & IGNORE_SCALABLE_ALIASES) &&
+               fname->type == FONT_ENTRY_ALIAS)
+           {
+               FontScalableRec tmpvals;
+               if (FontParseXLFDName (fname->name.name, &tmpvals,
+                                      FONT_XLFD_REPLACE_NONE) &&
+                   !(tmpvals.values_supplied & SIZE_SPECIFY_MASK))
+                   continue;
+           }
+
+           ret = AddFontNamesName(names, fname->name.name, fname->name.length);
+           if (ret != Successful)
+               goto bail;
+
+           /* If alias_behavior is LIST_ALIASES_AND_TARGET_NAMES, mark
+              this entry as an alias by negating its length and follow
+              it by the resolved name */
+           if ((alias_behavior & LIST_ALIASES_AND_TARGET_NAMES) &&
+               fname->type == FONT_ENTRY_ALIAS)
+           {
+               names->length[names->nnames - 1] =
+                   -names->length[names->nnames - 1];
+               ret = AddFontNamesName(names, fname->u.alias.resolved,
+                                      strlen(fname->u.alias.resolved));
+               if (ret != Successful)
+                   goto bail;
+           }
+
+           if (--max <= 0)
+               break;
+       } else if (res < 0)
+           break;
+    }
+  bail: ;
+    if (newmax) *newmax = max;
+    return ret;
+}
+
+int
+FontFileFindNamesInDir(FontTablePtr table, FontNamePtr pat, 
+                      int max, FontNamesPtr names)
+{
+    return FontFileFindNamesInScalableDir(table, pat, max, names,
+                                         (FontScalablePtr)0,
+                                         NORMAL_ALIAS_BEHAVIOR, (int *)0);
+}
+
+Bool
+FontFileMatchName(char *name, int length, FontNamePtr pat)
+{
+    /* Perform a fontfile-type name match on a single name */
+    FontTableRec table;
+    FontEntryRec entries[1];
+
+    /* Dummy up a table */
+    table.used = 1;
+    table.size = 1;
+    table.sorted = TRUE;
+    table.entries = entries;
+    entries[0].name.name = name;
+    entries[0].name.length = length;
+    entries[0].name.ndashes = FontFileCountDashes(name, length);
+
+    return FontFileFindNameInDir(&table, pat) != (FontEntryPtr)0;
+}
+
+/*
+ * Add a font file to a directory.  This handles bitmap and
+ * scalable names both
+ */
+
+Bool
+FontFileAddFontFile (FontDirectoryPtr dir, char *fontName, char *fileName)
+{
+    FontEntryRec           entry;
+    FontScalableRec        vals, zeroVals;
+    FontRendererPtr        renderer;
+    FontEntryPtr           existing;
+    FontScalableExtraPtr    extra;
+    FontEntryPtr           bitmap = 0, scalable;
+    Bool                   isscale;
+    Bool                   scalable_xlfd;
+
+    renderer = FontFileMatchRenderer (fileName);
+    if (!renderer)
+       return FALSE;
+    entry.name.length = strlen (fontName);
+    if (entry.name.length > MAXFONTNAMELEN)
+       entry.name.length = MAXFONTNAMELEN;
+    entry.name.name = fontName;
+    CopyISOLatin1Lowered (entry.name.name, fontName, entry.name.length);
+    entry.name.ndashes = FontFileCountDashes (entry.name.name, entry.name.length);
+    entry.name.name[entry.name.length] = '\0';
+    /*
+     * Add a bitmap name if the incoming name isn't an XLFD name, or
+     * if it isn't a scalable name (i.e. non-zero scalable fields)
+     *
+     * If name of bitmapped font contains XLFD enhancements, do not add
+     * a scalable version of the name... this can lead to confusion and
+     * ambiguity between the font name and the field enhancements.
+     */
+    isscale = entry.name.ndashes == 14 &&
+             FontParseXLFDName(entry.name.name,
+                               &vals, FONT_XLFD_REPLACE_NONE) &&
+             (vals.values_supplied & PIXELSIZE_MASK) != PIXELSIZE_ARRAY &&
+             (vals.values_supplied & POINTSIZE_MASK) != POINTSIZE_ARRAY &&
+             !(vals.values_supplied & ENHANCEMENT_SPECIFY_MASK);
+#define UNSCALED_ATTRIB "unscaled"
+    scalable_xlfd = (isscale &&
+               (((vals.values_supplied & PIXELSIZE_MASK) == 0) ||
+                ((vals.values_supplied & POINTSIZE_MASK) == 0)));
+    /*
+     * For scalable fonts without a scalable XFLD, check if the "unscaled"
+     * attribute is present.
+     */
+    if (isscale && !scalable_xlfd &&
+           dir->attributes && dir->attributes[0] == ':') {
+       char *ptr1 = dir->attributes + 1;
+       char *ptr2;
+       int length;
+       int uslength = strlen(UNSCALED_ATTRIB);
+
+       do {
+           ptr2 = strchr(ptr1, ':');
+           if (ptr2)
+               length = ptr2 - ptr1;
+           else
+               length = dir->attributes + strlen(dir->attributes) - ptr1;
+           if (length == uslength && !strncmp(ptr1, UNSCALED_ATTRIB, uslength))
+               isscale = FALSE;
+           if (ptr2)
+               ptr1 = ptr2 + 1;
+       } while (ptr2);
+    }
+    if (!isscale || (vals.values_supplied & SIZE_SPECIFY_MASK))
+    {
+      /*
+       * If the renderer doesn't support OpenBitmap, FontFileOpenFont
+       * will still do the right thing.
+       */
+       entry.type = FONT_ENTRY_BITMAP;
+       entry.u.bitmap.renderer = renderer;
+       entry.u.bitmap.pFont = NullFont;
+       if (!(entry.u.bitmap.fileName = FontFileSaveString (fileName)))
+           return FALSE;
+       if (!(bitmap = FontFileAddEntry (&dir->nonScalable, &entry)))
+       {
+           free (entry.u.bitmap.fileName);
+           return FALSE;
+       }
+    }
+    /*
+     * Parse out scalable fields from XLFD names - a scalable name
+     * just gets inserted, a scaled name has more things to do.
+     */
+    if (isscale)
+    {
+       if (vals.values_supplied & SIZE_SPECIFY_MASK)
+       {
+           bzero((char *)&zeroVals, sizeof(zeroVals));
+           zeroVals.x = vals.x;
+           zeroVals.y = vals.y;
+           zeroVals.values_supplied = PIXELSIZE_SCALAR | POINTSIZE_SCALAR;
+           FontParseXLFDName (entry.name.name, &zeroVals,
+                              FONT_XLFD_REPLACE_VALUE);
+           entry.name.length = strlen (entry.name.name);
+           existing = FontFileFindNameInDir (&dir->scalable, &entry.name);
+           if (existing)
+           {
+               if ((vals.values_supplied & POINTSIZE_MASK) ==
+                       POINTSIZE_SCALAR &&
+                   (int)(vals.point_matrix[3] * 10) == GetDefaultPointSize())
+               {
+                   existing->u.scalable.extra->defaults = vals;
+
+                   free (existing->u.scalable.fileName);
+                   if (!(existing->u.scalable.fileName = FontFileSaveString (fileName)))
+                       return FALSE;
+               }
+                if(bitmap)
+                {
+                    FontFileCompleteXLFD(&vals, &vals);
+                    FontFileAddScaledInstance (existing, &vals, NullFont,
+                                               bitmap->name.name);
+                    return TRUE;
+                }
+           }
+       }
+       if (!(entry.u.scalable.fileName = FontFileSaveString (fileName)))
+           return FALSE;
+       extra = malloc (sizeof (FontScalableExtraRec));
+       if (!extra)
+       {
+           free (entry.u.scalable.fileName);
+           return FALSE;
+       }
+       bzero((char *)&extra->defaults, sizeof(extra->defaults));
+       if ((vals.values_supplied & POINTSIZE_MASK) == POINTSIZE_SCALAR &&
+           (int)(vals.point_matrix[3] * 10) == GetDefaultPointSize())
+           extra->defaults = vals;
+       else
+       {
+           FontResolutionPtr resolution;
+           int num;
+           int default_point_size = GetDefaultPointSize();
+
+           extra->defaults.point_matrix[0] =
+               extra->defaults.point_matrix[3] =
+                   (double)default_point_size / 10.0;
+           extra->defaults.point_matrix[1] =
+               extra->defaults.point_matrix[2] = 0.0;
+           extra->defaults.values_supplied =
+               POINTSIZE_SCALAR | PIXELSIZE_UNDEFINED;
+           extra->defaults.width = -1;
+           if (vals.x <= 0 || vals.y <= 0)
+           {
+               resolution = GetClientResolutions (&num);
+               if (resolution && num > 0)
+               {
+                   extra->defaults.x = resolution->x_resolution;
+                   extra->defaults.y = resolution->y_resolution;
+               }
+               else
+               {
+                   extra->defaults.x = 75;
+                   extra->defaults.y = 75;
+               }
+            }
+            else 
+            {
+               extra->defaults.x = vals.x;
+               extra->defaults.y = vals.y;
+            }
+            FontFileCompleteXLFD (&extra->defaults, &extra->defaults);
+       }
+       extra->numScaled = 0;
+       extra->sizeScaled = 0;
+       extra->scaled = 0;
+       extra->private = 0;
+       entry.type = FONT_ENTRY_SCALABLE;
+       entry.u.scalable.renderer = renderer;
+       entry.u.scalable.extra = extra;
+       if (!(scalable = FontFileAddEntry (&dir->scalable, &entry)))
+       {
+           free (extra);
+           free (entry.u.scalable.fileName);
+           return FALSE;
+       }
+       if (vals.values_supplied & SIZE_SPECIFY_MASK)
+       {
+            if(bitmap)
+            {
+                FontFileCompleteXLFD(&vals, &vals);
+                FontFileAddScaledInstance (scalable, &vals, NullFont,
+                                           bitmap->name.name);
+            }
+       }
+    }
+    return TRUE;
+}
+
+Bool
+FontFileAddFontAlias (FontDirectoryPtr dir, char *aliasName, char *fontName)
+{
+    FontEntryRec       entry;
+
+    if (strcmp(aliasName,fontName) == 0) {
+        /* Don't allow an alias to point to itself and create a loop */
+        return FALSE;
+    }
+    entry.name.length = strlen (aliasName);
+    CopyISOLatin1Lowered (aliasName, aliasName, entry.name.length);
+    entry.name.name = aliasName;
+    entry.name.ndashes = FontFileCountDashes (entry.name.name, entry.name.length);
+    entry.type = FONT_ENTRY_ALIAS;
+    if (!(entry.u.alias.resolved = FontFileSaveString (fontName)))
+       return FALSE;
+    if (!FontFileAddEntry (&dir->nonScalable, &entry))
+    {
+       free (entry.u.alias.resolved);
+       return FALSE;
+    }
+    return TRUE;
+}
diff --git a/src/fontfile/fontencc.c b/src/fontfile/fontencc.c
new file mode 100755 (executable)
index 0000000..7997785
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+Copyright (c) 1998-2001 by Juliusz Chroboczek
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+/* Binary compatibility code. */
+
+/* This file includes code to make modules compiled for earlier
+   versions of the fontenc interfaces link with this one.  It does
+   *not* provide source compatibility, as many of the data structures
+   now have different names. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fontenc.h>
+#include <X11/fonts/fontencc.h>
+
+extern void ErrorF(const char *f, ...);
+
+char *
+font_encoding_from_xlfd(const char * name, int length)
+{
+    return FontEncFromXLFD(name, length);
+}
+
+FontEncPtr
+font_encoding_find(const char *encoding_name, const char *filename)
+{
+    return FontEncFind(encoding_name, filename);
+}
+
+unsigned
+font_encoding_recode(unsigned code, 
+                     FontEncPtr encoding, FontMapPtr mapping)
+{
+    if(encoding != mapping->encoding) {
+        ErrorF("Inconsistent mapping/encoding\n");
+        return 0;
+    }
+    return FontEncRecode(code, mapping);
+}
+
+char *
+font_encoding_name(unsigned code,
+                     FontEncPtr encoding, FontMapPtr mapping)
+{
+    if(encoding != mapping->encoding) {
+        ErrorF("Inconsistent mapping/encoding\n");
+        return 0;
+    }
+    return FontEncName(code, mapping);
+}
+
+char **
+identifyEncodingFile(const char *filename)
+{
+    return FontEncIdentify(filename);
+}
diff --git a/src/fontfile/fontfile.c b/src/fontfile/fontfile.c
new file mode 100755 (executable)
index 0000000..eb37a87
--- /dev/null
@@ -0,0 +1,1136 @@
+/*
+
+Copyright 1991, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+/*
+ * Author:  Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fntfilst.h>
+#include <X11/keysym.h>
+#ifdef WIN32
+#include <ctype.h>
+#endif
+
+static unsigned char
+ISOLatin1ToLower(unsigned char source)
+{
+    if (source >= XK_A && source <= XK_Z)
+       return source + (XK_a - XK_A);
+    if (source >= XK_Agrave && source <= XK_Odiaeresis)
+       return source + (XK_agrave - XK_Agrave);
+    if (source >= XK_Ooblique && source <= XK_Thorn)
+       return source + (XK_oslash - XK_Ooblique);
+    return source;
+}
+
+_X_HIDDEN void
+CopyISOLatin1Lowered(char *dest, char *source, int length)
+{
+    int i;
+    for (i = 0; i < length; i++, source++, dest++)
+       *dest = ISOLatin1ToLower(*source);
+    *dest = '\0';
+}
+
+/*
+ * Map FPE functions to renderer functions
+ */
+
+static int FontFileOpenBitmapNCF (FontPathElementPtr fpe, FontPtr *pFont, 
+                                 int flags, FontEntryPtr entry, 
+                                 fsBitmapFormat format, 
+                                 fsBitmapFormatMask fmask,
+                                 FontPtr non_cachable_font);
+
+int
+FontFileNameCheck (char *name)
+{
+#ifndef NCD
+#if defined(WIN32)
+    /* OS/2 uses D:/... as a path name for fonts, so accept this as a valid
+     * path if it starts with a letter and a colon. Same applies for WIN32
+     */
+    if (isalpha(*name) && name[1]==':')
+        return TRUE;
+#endif
+    return *name == '/';
+#else
+    return ((strcmp(name, "built-ins") == 0) || (*name == '/'));
+#endif
+}
+
+int
+FontFileInitFPE (FontPathElementPtr fpe)
+{
+    int                        status;
+    FontDirectoryPtr   dir;
+
+    status = FontFileReadDirectory (fpe->name, &dir);
+    if (status == Successful)
+    {
+       if (dir->nonScalable.used > 0)
+           if (!FontFileRegisterBitmapSource (fpe))
+           {
+               FontFileFreeFPE (fpe);
+               return AllocError;
+           }
+       fpe->private = (pointer) dir;
+    }
+    return status;
+}
+
+/* ARGSUSED */
+int
+FontFileResetFPE (FontPathElementPtr fpe)
+{
+    FontDirectoryPtr   dir;
+
+    dir = (FontDirectoryPtr) fpe->private;
+    /*
+     * The reset must fail for bitmap fonts because they get cleared when
+     * the path is set.
+     */
+    if (FontFileDirectoryChanged (dir))
+    {
+       /* can't do it, so tell the caller to close and re-open */
+       return FPEResetFailed;  
+    }
+    else 
+    {
+       if (dir->nonScalable.used > 0)
+           if (!FontFileRegisterBitmapSource (fpe))
+           {
+               return FPEResetFailed;  
+           }
+        return Successful;
+    }
+}
+
+int
+FontFileFreeFPE (FontPathElementPtr fpe)
+{
+    FontFileUnregisterBitmapSource (fpe);
+    FontFileFreeDir ((FontDirectoryPtr) fpe->private);
+    return Successful;
+}
+
+static int
+transfer_values_to_alias(char *entryname, int entrynamelength, 
+                        char *resolvedname,
+                        char **aliasName, FontScalablePtr vals)
+{
+    static char                aliasname[MAXFONTNAMELEN];
+    int                        nameok = 1, len;
+    char               lowerName[MAXFONTNAMELEN];
+
+    *aliasName = resolvedname;
+    if ((len = strlen(*aliasName)) <= MAXFONTNAMELEN &&
+       (entrynamelength < MAXFONTNAMELEN) &&
+       FontFileCountDashes (*aliasName, len) == 14)
+    {
+       FontScalableRec tmpVals;
+       FontScalableRec tmpVals2;
+
+       tmpVals2 = *vals;
+
+       /* If we're aliasing a scalable name, transfer values
+          from the name into the destination alias, multiplying
+          by matrices that appear in the alias. */
+
+       CopyISOLatin1Lowered (lowerName, entryname,
+                             entrynamelength);
+       lowerName[entrynamelength] = '\0';
+
+       if (FontParseXLFDName(lowerName, &tmpVals,
+                             FONT_XLFD_REPLACE_NONE) &&
+           !tmpVals.values_supplied &&
+           FontParseXLFDName(*aliasName, &tmpVals,
+                             FONT_XLFD_REPLACE_NONE))
+       {
+           double *matrix = 0, tempmatrix[4];
+
+           /* Use a matrix iff exactly one is defined */
+           if ((tmpVals.values_supplied & PIXELSIZE_MASK) ==
+               PIXELSIZE_ARRAY &&
+               !(tmpVals.values_supplied & POINTSIZE_MASK))
+               matrix = tmpVals.pixel_matrix;
+           else if ((tmpVals.values_supplied & POINTSIZE_MASK) ==
+                    POINTSIZE_ARRAY &&
+                    !(tmpVals.values_supplied & PIXELSIZE_MASK))
+               matrix = tmpVals.point_matrix;
+
+           /* If matrix given in the alias, compute new point
+              and/or pixel matrices */
+           if (matrix)
+           {
+               /* Complete the XLFD name to avoid potential
+                  gotchas */
+               if (FontFileCompleteXLFD(&tmpVals2, &tmpVals2))
+               {
+                   tempmatrix[0] =
+                       matrix[0] * tmpVals2.point_matrix[0] +
+                       matrix[1] * tmpVals2.point_matrix[2];
+                   tempmatrix[1] =
+                       matrix[0] * tmpVals2.point_matrix[1] +
+                       matrix[1] * tmpVals2.point_matrix[3];
+                   tempmatrix[2] =
+                       matrix[2] * tmpVals2.point_matrix[0] +
+                       matrix[3] * tmpVals2.point_matrix[2];
+                   tempmatrix[3] =
+                       matrix[2] * tmpVals2.point_matrix[1] +
+                       matrix[3] * tmpVals2.point_matrix[3];
+                   tmpVals2.point_matrix[0] = tempmatrix[0];
+                   tmpVals2.point_matrix[1] = tempmatrix[1];
+                   tmpVals2.point_matrix[2] = tempmatrix[2];
+                   tmpVals2.point_matrix[3] = tempmatrix[3];
+
+                   tempmatrix[0] =
+                       matrix[0] * tmpVals2.pixel_matrix[0] +
+                       matrix[1] * tmpVals2.pixel_matrix[2];
+                   tempmatrix[1] =
+                       matrix[0] * tmpVals2.pixel_matrix[1] +
+                       matrix[1] * tmpVals2.pixel_matrix[3];
+                   tempmatrix[2] =
+                       matrix[2] * tmpVals2.pixel_matrix[0] +
+                       matrix[3] * tmpVals2.pixel_matrix[2];
+                   tempmatrix[3] =
+                       matrix[2] * tmpVals2.pixel_matrix[1] +
+                       matrix[3] * tmpVals2.pixel_matrix[3];
+                   tmpVals2.pixel_matrix[0] = tempmatrix[0];
+                   tmpVals2.pixel_matrix[1] = tempmatrix[1];
+                   tmpVals2.pixel_matrix[2] = tempmatrix[2];
+                   tmpVals2.pixel_matrix[3] = tempmatrix[3];
+
+                   tmpVals2.values_supplied =
+                       (tmpVals2.values_supplied &
+                        ~(PIXELSIZE_MASK | POINTSIZE_MASK)) |
+                       PIXELSIZE_ARRAY | POINTSIZE_ARRAY;
+               }
+               else
+                   nameok = 0;
+           }
+
+           CopyISOLatin1Lowered (aliasname, *aliasName, len + 1);
+           if (nameok && FontParseXLFDName(aliasname, &tmpVals2,
+                                 FONT_XLFD_REPLACE_VALUE))
+               /* Return a version of the aliasname that has
+                  had the vals stuffed into it.  To avoid
+                  memory leak, this alias name lives in a
+                  static buffer.  The caller needs to be done
+                  with this buffer before this procedure is
+                  called again to avoid reentrancy problems. */
+                   *aliasName = aliasname;
+       }
+    }
+    return nameok;
+}
+
+/* ARGSUSED */
+int
+FontFileOpenFont (pointer client, FontPathElementPtr fpe, Mask flags, 
+                 char *name, int namelen, 
+                 fsBitmapFormat format, fsBitmapFormatMask fmask,
+                 XID id, FontPtr *pFont, char **aliasName, 
+                 FontPtr non_cachable_font)
+{
+    FontDirectoryPtr   dir;
+    char               lowerName[MAXFONTNAMELEN];
+    char               fileName[MAXFONTFILENAMELEN*2 + 1];
+    FontNameRec                tmpName;
+    FontEntryPtr       entry;
+    FontScalableRec    vals;
+    FontScalableEntryPtr   scalable;
+    FontScaledPtr      scaled;
+    FontBitmapEntryPtr bitmap;
+    int                        ret;
+    Bool               noSpecificSize;
+    int                        nranges;
+    fsRange            *ranges;
+    
+    if (namelen >= MAXFONTNAMELEN)
+       return AllocError;
+    dir = (FontDirectoryPtr) fpe->private;
+
+    /* Match non-scalable pattern */
+    CopyISOLatin1Lowered (lowerName, name, namelen);
+    lowerName[namelen] = '\0';
+    ranges = FontParseRanges(lowerName, &nranges);
+    tmpName.name = lowerName;
+    tmpName.length = namelen;
+    tmpName.ndashes = FontFileCountDashes (lowerName, namelen);
+    if (!FontParseXLFDName(lowerName, &vals, FONT_XLFD_REPLACE_NONE))
+       bzero(&vals, sizeof(vals));
+    if (!(entry = FontFileFindNameInDir (&dir->nonScalable, &tmpName)) &&
+       tmpName.ndashes == 14 &&
+       FontParseXLFDName (lowerName, &vals, FONT_XLFD_REPLACE_ZERO))
+    {
+        tmpName.length = strlen(lowerName);
+       entry = FontFileFindNameInDir (&dir->nonScalable, &tmpName);
+    }
+
+    if (entry)
+    {
+       switch (entry->type) {
+       case FONT_ENTRY_BITMAP:
+           bitmap = &entry->u.bitmap;
+           if (bitmap->pFont)
+           {
+               *pFont = bitmap->pFont;
+               (*pFont)->fpe = fpe;
+               ret = Successful;
+           }
+           else
+           {
+               ret = FontFileOpenBitmapNCF (fpe, pFont, flags, entry, format,
+                                            fmask, non_cachable_font);
+               if (ret == Successful && *pFont)
+                   (*pFont)->fpe = fpe;
+           }
+           break;
+       case FONT_ENTRY_ALIAS:
+           vals.nranges = nranges;
+           vals.ranges = ranges;
+           transfer_values_to_alias(entry->name.name, entry->name.length,
+                                    entry->u.alias.resolved, aliasName, &vals);
+           ret = FontNameAlias;
+           break;
+       default:
+           ret = BadFontName;
+       }
+    }
+    else
+    {
+       ret = BadFontName;
+    }
+
+    if (ret != BadFontName)
+    {
+       if (ranges) free(ranges);
+       return ret;
+    }
+
+    /* Match XLFD patterns */
+    CopyISOLatin1Lowered (lowerName, name, namelen);
+    lowerName[namelen] = '\0';
+    tmpName.name = lowerName;
+    tmpName.length = namelen;
+    tmpName.ndashes = FontFileCountDashes (lowerName, namelen);
+    if (!FontParseXLFDName (lowerName, &vals, FONT_XLFD_REPLACE_ZERO) ||
+       !(tmpName.length = strlen (lowerName),
+         entry = FontFileFindNameInScalableDir (&dir->scalable, &tmpName,
+                                                &vals))) {
+       CopyISOLatin1Lowered (lowerName, name, namelen);
+       lowerName[namelen] = '\0';
+       tmpName.name = lowerName;
+       tmpName.length = namelen;
+       tmpName.ndashes = FontFileCountDashes (lowerName, namelen);
+       entry = FontFileFindNameInScalableDir (&dir->scalable, &tmpName, &vals);
+       if (entry)
+       {
+           strcpy(lowerName, entry->name.name);
+           tmpName.name = lowerName;
+           tmpName.length = entry->name.length;
+           tmpName.ndashes = entry->name.ndashes;
+       }
+    }
+
+    if (entry)
+    {
+       noSpecificSize = FALSE; /* TRUE breaks XLFD enhancements */
+       if (entry->type == FONT_ENTRY_SCALABLE &&
+           FontFileCompleteXLFD (&vals, &entry->u.scalable.extra->defaults))
+       {
+           scalable = &entry->u.scalable;
+           if ((vals.values_supplied & PIXELSIZE_MASK) == PIXELSIZE_ARRAY ||
+               (vals.values_supplied & POINTSIZE_MASK) == POINTSIZE_ARRAY ||
+               (vals.values_supplied &
+                ~SIZE_SPECIFY_MASK & ~CHARSUBSET_SPECIFIED))
+               scaled = 0;
+           else
+               scaled = FontFileFindScaledInstance (entry, &vals,
+                                                    noSpecificSize);
+           /*
+            * A scaled instance can occur one of two ways:
+            *
+            *  Either the font has been scaled to this
+            *   size already, in which case scaled->pFont
+            *   will point at that font.
+            *
+            *  Or a bitmap instance in this size exists,
+            *   which is handled as if we got a pattern
+            *   matching the bitmap font name.
+            */
+           if (scaled)
+           {
+               if (scaled->pFont)
+               {
+                   *pFont = scaled->pFont;
+                   (*pFont)->fpe = fpe;
+                   ret = Successful;
+               }
+               else if (scaled->bitmap)
+               {
+                   entry = scaled->bitmap;
+                   bitmap = &entry->u.bitmap;
+                   if (bitmap->pFont)
+                   {
+                       *pFont = bitmap->pFont;
+                       (*pFont)->fpe = fpe;
+                       ret = Successful;
+                   }
+                   else
+                   {
+                       ret = FontFileOpenBitmapNCF (fpe, pFont, flags, entry,
+                                                    format, fmask,
+                                                    non_cachable_font);
+                       if (ret == Successful && *pFont)
+                           (*pFont)->fpe = fpe;
+                   }
+               }
+               else /* "cannot" happen */
+               {
+                   ret = BadFontName;
+               }
+           }
+           else
+           {
+               ret = FontFileMatchBitmapSource (fpe, pFont, flags, entry, &tmpName, &vals, format, fmask, noSpecificSize);
+               if (ret != Successful)
+               {
+                   char origName[MAXFONTNAMELEN];
+
+                   CopyISOLatin1Lowered (origName, name, namelen);
+                   origName[namelen] = '\0';
+
+                   /* Pass the original XLFD name in the vals
+                      structure; the rasterizer is free to examine it
+                      for hidden meanings.  This information will not
+                      be saved in the scaled-instances table.  */
+
+                   vals.xlfdName = origName;
+                   vals.ranges = ranges;
+                   vals.nranges = nranges;
+
+                   if (strlen(dir->directory) + strlen(scalable->fileName) >=
+                       sizeof(fileName)) {
+                       ret = BadFontName;
+                   } else {
+                       strcpy (fileName, dir->directory);
+                       strcat (fileName, scalable->fileName);
+                        if (scalable->renderer->OpenScalable) {
+                           ret = (*scalable->renderer->OpenScalable) (fpe, pFont,
+                              flags, entry, fileName, &vals, format, fmask,
+                              non_cachable_font);
+                        }
+                        else if (scalable->renderer->OpenBitmap) {
+                            ret = (*scalable->renderer->OpenBitmap) (fpe, pFont,
+                               flags, entry, fileName, format, fmask,
+                               non_cachable_font);
+                        }
+                   }
+
+                   /* In case rasterizer does something bad because of
+                      charset subsetting... */
+                   if (ret == Successful &&
+                       ((*pFont)->info.firstCol > (*pFont)->info.lastCol ||
+                        (*pFont)->info.firstRow > (*pFont)->info.lastRow))
+                   {
+                       (*(*pFont)->unload_font)(*pFont);
+                       ret = BadFontName;
+                   }
+                   /* Save the instance */
+                   if (ret == Successful)
+                   {
+                       if (FontFileAddScaledInstance (entry, &vals,
+                                                   *pFont, (char *) 0))
+                           ranges = 0;
+                       else
+                           (*pFont)->fpePrivate = (pointer) 0;
+                       (*pFont)->fpe = fpe;
+                   }
+               }
+           }
+       }
+    }
+    else
+       ret = BadFontName;
+
+    if (ranges)
+       free(ranges);
+    return ret;
+}
+
+/* ARGSUSED */
+void
+FontFileCloseFont (FontPathElementPtr fpe, FontPtr pFont)
+{
+    FontEntryPtr    entry;
+
+    if ((entry = (FontEntryPtr) pFont->fpePrivate)) {
+       switch (entry->type) {
+       case FONT_ENTRY_SCALABLE:
+           FontFileRemoveScaledInstance (entry, pFont);
+           break;
+       case FONT_ENTRY_BITMAP:
+           entry->u.bitmap.pFont = 0;
+           break;
+       default:
+           /* "cannot" happen */
+           break;
+       }
+       pFont->fpePrivate = 0;
+    }
+    (*pFont->unload_font) (pFont);
+}
+
+static int
+FontFileOpenBitmapNCF (FontPathElementPtr fpe, FontPtr *pFont, 
+                      int flags, FontEntryPtr entry, 
+                      fsBitmapFormat format, fsBitmapFormatMask fmask,
+                      FontPtr non_cachable_font)
+{
+    FontBitmapEntryPtr bitmap;
+    char               fileName[MAXFONTFILENAMELEN*2+1];
+    int                        ret;
+    FontDirectoryPtr   dir;
+
+    dir = (FontDirectoryPtr) fpe->private;
+    bitmap = &entry->u.bitmap;
+    if(!bitmap || !bitmap->renderer->OpenBitmap)
+        return BadFontName;
+    if (strlen(dir->directory) + strlen(bitmap->fileName) >= sizeof(fileName))
+       return BadFontName;
+    strcpy (fileName, dir->directory);
+    strcat (fileName, bitmap->fileName);
+    ret = (*bitmap->renderer->OpenBitmap) 
+                       (fpe, pFont, flags, entry, fileName, format, fmask,
+                        non_cachable_font);
+    if (ret == Successful)
+    {
+       bitmap->pFont = *pFont;
+       (*pFont)->fpePrivate = (pointer) entry;
+    }
+    return ret;
+}
+
+int
+FontFileOpenBitmap (FontPathElementPtr fpe, FontPtr *pFont, 
+                   int flags, FontEntryPtr entry, 
+                   fsBitmapFormat format, fsBitmapFormatMask fmask)
+{
+    return FontFileOpenBitmapNCF (fpe, pFont, flags, entry, format, fmask,
+                                 (FontPtr)0);
+}
+
+static int
+FontFileGetInfoBitmap (FontPathElementPtr fpe, FontInfoPtr pFontInfo, 
+                      FontEntryPtr entry)
+{
+    FontBitmapEntryPtr bitmap;
+    char               fileName[MAXFONTFILENAMELEN*2+1];
+    int                        ret;
+    FontDirectoryPtr   dir;
+
+    dir = (FontDirectoryPtr) fpe->private;
+    bitmap = &entry->u.bitmap;
+    if (!bitmap || !bitmap->renderer->GetInfoBitmap)
+       return BadFontName;
+    if (strlen(dir->directory) + strlen(bitmap->fileName) >= sizeof(fileName))
+       return BadFontName;
+    strcpy (fileName, dir->directory);
+    strcat (fileName, bitmap->fileName);
+    ret = (*bitmap->renderer->GetInfoBitmap) (fpe, pFontInfo, entry, fileName);
+    return ret;
+}
+
+static void
+_FontFileAddScalableNames(FontNamesPtr names, FontNamesPtr scaleNames, 
+                         FontNamePtr nameptr, char *zeroChars, 
+                         FontScalablePtr vals, fsRange *ranges,
+                         int nranges, int *max)
+{
+    int i;
+    FontScalableRec    zeroVals, tmpVals;
+    for (i = 0; i < scaleNames->nnames; i++)
+    {
+       char nameChars[MAXFONTNAMELEN];
+       if (!*max)
+           return;
+       FontParseXLFDName (scaleNames->names[i], &zeroVals,
+                          FONT_XLFD_REPLACE_NONE);
+       tmpVals = *vals;
+       if (FontFileCompleteXLFD (&tmpVals, &zeroVals))
+       {
+           --*max;
+
+           strcpy (nameChars, scaleNames->names[i]);
+           if ((vals->values_supplied & PIXELSIZE_MASK) ||
+               !(vals->values_supplied & PIXELSIZE_WILDCARD) ||
+               vals->y == 0)
+           {
+               tmpVals.values_supplied =
+                   (tmpVals.values_supplied & ~PIXELSIZE_MASK) |
+                   (vals->values_supplied & PIXELSIZE_MASK);
+               tmpVals.pixel_matrix[0] = vals->pixel_matrix[0];
+               tmpVals.pixel_matrix[1] = vals->pixel_matrix[1];
+               tmpVals.pixel_matrix[2] = vals->pixel_matrix[2];
+               tmpVals.pixel_matrix[3] = vals->pixel_matrix[3];
+           }
+           if ((vals->values_supplied & POINTSIZE_MASK) ||
+               !(vals->values_supplied & POINTSIZE_WILDCARD) ||
+               vals->y == 0)
+           {
+               tmpVals.values_supplied =
+                   (tmpVals.values_supplied & ~POINTSIZE_MASK) |
+                   (vals->values_supplied & POINTSIZE_MASK);
+               tmpVals.point_matrix[0] = vals->point_matrix[0];
+               tmpVals.point_matrix[1] = vals->point_matrix[1];
+               tmpVals.point_matrix[2] = vals->point_matrix[2];
+               tmpVals.point_matrix[3] = vals->point_matrix[3];
+           }
+           if (vals->width <= 0)
+               tmpVals.width = 0;
+           if (vals->x == 0)
+               tmpVals.x = 0;
+           if (vals->y == 0)
+               tmpVals.y = 0;
+           tmpVals.ranges = ranges;
+           tmpVals.nranges = nranges;
+           FontParseXLFDName (nameChars, &tmpVals,
+                              FONT_XLFD_REPLACE_VALUE);
+           /* If we're marking aliases with negative lengths, we
+              need to concoct a valid target name to follow it.
+              Otherwise we're done.  */
+           if (scaleNames->length[i] >= 0)
+           {
+               (void) AddFontNamesName (names, nameChars,
+                                        strlen (nameChars));
+               /* If our original pattern matches the name from
+                  the table and that name doesn't duplicate what
+                  we just added, add the name from the table */
+               if (strcmp(nameChars, scaleNames->names[i]) &&
+                   FontFileMatchName(scaleNames->names[i],
+                                     scaleNames->length[i],
+                                     nameptr) &&
+                   *max)
+               {
+                   --*max;
+                   (void) AddFontNamesName (names, scaleNames->names[i],
+                                            scaleNames->length[i]);
+               }
+           }
+           else
+           {
+               char *aliasName;
+               vals->ranges = ranges;
+               vals->nranges = nranges;
+               if (transfer_values_to_alias(zeroChars,
+                                            strlen(zeroChars),
+                                            scaleNames->names[++i],
+                                            &aliasName, vals))
+               {
+                   (void) AddFontNamesName (names, nameChars,
+                                            strlen (nameChars));
+                   names->length[names->nnames - 1] =
+                       -names->length[names->nnames - 1];
+                   (void) AddFontNamesName (names, aliasName,
+                                            strlen (aliasName));
+                   /* If our original pattern matches the name from
+                      the table and that name doesn't duplicate what
+                      we just added, add the name from the table */
+                   if (strcmp(nameChars, scaleNames->names[i - 1]) &&
+                       FontFileMatchName(scaleNames->names[i - 1],
+                                         -scaleNames->length[i - 1],
+                                         nameptr) &&
+                       *max)
+                   {
+                       --*max;
+                       (void) AddFontNamesName (names,
+                                                scaleNames->names[i - 1],
+                                                -scaleNames->length[i - 1]);
+                       names->length[names->nnames - 1] =
+                           -names->length[names->nnames - 1];
+                       (void) AddFontNamesName (names, aliasName,
+                                                strlen (aliasName));
+                   }
+               }
+           }
+       }
+    }
+}
+
+/* ARGSUSED */
+static int
+_FontFileListFonts (pointer client, FontPathElementPtr fpe, 
+                   char *pat, int len, int max, FontNamesPtr names, 
+                   int mark_aliases)
+{
+    FontDirectoryPtr   dir;
+    char               lowerChars[MAXFONTNAMELEN], zeroChars[MAXFONTNAMELEN];
+    FontNameRec                lowerName;
+    FontNameRec                zeroName;
+    FontNamesPtr       scaleNames;
+    FontScalableRec    vals;
+    fsRange            *ranges;
+    int                        nranges;
+    int                        result = BadFontName;
+
+    if (len >= MAXFONTNAMELEN)
+       return AllocError;
+    dir = (FontDirectoryPtr) fpe->private;
+    CopyISOLatin1Lowered (lowerChars, pat, len);
+    lowerChars[len] = '\0';
+    lowerName.name = lowerChars;
+    lowerName.length = len;
+    lowerName.ndashes = FontFileCountDashes (lowerChars, len);
+
+    /* Match XLFD patterns */
+
+    strcpy (zeroChars, lowerChars);
+    if (lowerName.ndashes == 14 &&
+       FontParseXLFDName (zeroChars, &vals, FONT_XLFD_REPLACE_ZERO))
+    {
+       ranges = FontParseRanges(lowerChars, &nranges);
+        result = FontFileFindNamesInScalableDir (&dir->nonScalable,
+                               &lowerName, max, names,
+                               (FontScalablePtr)0,
+                               (mark_aliases ?
+                                LIST_ALIASES_AND_TARGET_NAMES :
+                                NORMAL_ALIAS_BEHAVIOR) |
+                               IGNORE_SCALABLE_ALIASES,
+                               &max);
+       zeroName.name = zeroChars;
+       zeroName.length = strlen (zeroChars);
+       zeroName.ndashes = lowerName.ndashes;
+
+       /* Look for scalable names and aliases, adding scaled instances of
+          them to the output */
+
+       /* Scalable names... */
+       scaleNames = MakeFontNamesRecord (0);
+       if (!scaleNames)
+       {
+           if (ranges) free(ranges);
+           return AllocError;
+       }
+       FontFileFindNamesInScalableDir (&dir->scalable, &zeroName, max,
+                                       scaleNames, &vals,
+                                       mark_aliases ?
+                                       LIST_ALIASES_AND_TARGET_NAMES :
+                                       NORMAL_ALIAS_BEHAVIOR, (int *)0);
+       _FontFileAddScalableNames(names, scaleNames, &lowerName,
+                                 zeroChars, &vals, ranges, nranges,
+                                 &max);
+       FreeFontNames (scaleNames);
+
+       /* Scalable aliases... */
+       scaleNames = MakeFontNamesRecord (0);
+       if (!scaleNames)
+       {
+           if (ranges) free(ranges);
+           return AllocError;
+       }
+       FontFileFindNamesInScalableDir (&dir->nonScalable, &zeroName,
+                                       max, scaleNames, &vals,
+                                       mark_aliases ?
+                                       LIST_ALIASES_AND_TARGET_NAMES :
+                                       NORMAL_ALIAS_BEHAVIOR, (int *)0);
+       _FontFileAddScalableNames(names, scaleNames, &lowerName,
+                                 zeroChars, &vals, ranges, nranges,
+                                 &max);
+       FreeFontNames (scaleNames);
+
+       if (ranges) free(ranges);
+    }
+    else
+    {
+        result = FontFileFindNamesInScalableDir (&dir->nonScalable,
+                               &lowerName, max, names,
+                               (FontScalablePtr)0,
+                               mark_aliases ?
+                               LIST_ALIASES_AND_TARGET_NAMES :
+                               NORMAL_ALIAS_BEHAVIOR,
+                               &max);
+       if (result == Successful)
+           result = FontFileFindNamesInScalableDir (&dir->scalable,
+                               &lowerName, max, names,
+                               (FontScalablePtr)0,
+                               mark_aliases ?
+                               LIST_ALIASES_AND_TARGET_NAMES :
+                               NORMAL_ALIAS_BEHAVIOR, (int *)0);
+    }
+    return result;
+}
+
+typedef struct _LFWIData {
+    FontNamesPtr    names;
+    int                   current;
+} LFWIDataRec, *LFWIDataPtr;
+
+int
+FontFileListFonts (pointer client, FontPathElementPtr fpe, char *pat, 
+                  int len, int max, FontNamesPtr names)
+{
+    return _FontFileListFonts (client, fpe, pat, len, max, names, 0);
+}
+
+int
+FontFileStartListFonts(pointer client, FontPathElementPtr fpe, 
+                      char *pat, int len, int max, 
+                      pointer *privatep, int mark_aliases)
+{
+    LFWIDataPtr        data;
+    int                ret;
+
+    data = malloc (sizeof *data);
+    if (!data)
+       return AllocError;
+    data->names = MakeFontNamesRecord (0);
+    if (!data->names)
+    {
+       free (data);
+       return AllocError;
+    }
+    ret = _FontFileListFonts (client, fpe, pat, len,
+                             max, data->names, mark_aliases);
+    if (ret != Successful)
+    {
+       FreeFontNames (data->names);
+       free (data);
+       return ret;
+    }
+    data->current = 0;
+    *privatep = (pointer) data;
+    return Successful;
+}
+
+
+int
+FontFileStartListFontsWithInfo(pointer client, FontPathElementPtr fpe, 
+                              char *pat, int len, int max, 
+                              pointer *privatep)
+{
+    return FontFileStartListFonts(client, fpe, pat, len, max, privatep, 0);
+}
+
+/* ARGSUSED */
+static int
+FontFileListOneFontWithInfo (pointer client, FontPathElementPtr fpe, 
+                            char **namep, int *namelenp, 
+                            FontInfoPtr *pFontInfo)
+{
+    FontDirectoryPtr   dir;
+    char               lowerName[MAXFONTNAMELEN];
+    char               fileName[MAXFONTFILENAMELEN*2 + 1];
+    FontNameRec                tmpName;
+    FontEntryPtr       entry;
+    FontScalableRec    vals;
+    FontScalableEntryPtr   scalable;
+    FontScaledPtr      scaled;
+    FontBitmapEntryPtr bitmap;
+    int                        ret;
+    Bool               noSpecificSize;
+    int                        nranges;
+    fsRange            *ranges;
+    
+    char               *name = *namep;
+    int                        namelen = *namelenp;
+    
+    if (namelen >= MAXFONTNAMELEN)
+       return AllocError;
+    dir = (FontDirectoryPtr) fpe->private;
+    
+    /* Match non-scalable pattern */
+    CopyISOLatin1Lowered (lowerName, name, namelen);
+    lowerName[namelen] = '\0';
+    ranges = FontParseRanges(lowerName, &nranges);
+    tmpName.name = lowerName;
+    tmpName.length = namelen;
+    tmpName.ndashes = FontFileCountDashes (lowerName, namelen);
+    if (!FontParseXLFDName(lowerName, &vals, FONT_XLFD_REPLACE_NONE))
+       bzero(&vals, sizeof(vals));
+    if (!(entry = FontFileFindNameInDir (&dir->nonScalable, &tmpName)) &&
+       tmpName.ndashes == 14 &&
+       FontParseXLFDName (lowerName, &vals, FONT_XLFD_REPLACE_ZERO))
+    {
+        tmpName.length = strlen(lowerName);
+       entry = FontFileFindNameInDir (&dir->nonScalable, &tmpName);
+    }
+    
+    if (entry)
+    {
+       switch (entry->type) {
+       case FONT_ENTRY_BITMAP:
+           bitmap = &entry->u.bitmap;
+           if (bitmap->pFont)
+           {
+               *pFontInfo = &bitmap->pFont->info;
+               ret = Successful;
+           }
+           else
+           {
+               ret = FontFileGetInfoBitmap (fpe, *pFontInfo, entry);
+           }
+           break;
+       case FONT_ENTRY_ALIAS:
+           vals.nranges = nranges;
+           vals.ranges = ranges;
+           transfer_values_to_alias(entry->name.name, entry->name.length,
+                                    entry->u.alias.resolved, namep, &vals);
+           *namelenp = strlen (*namep);
+           ret = FontNameAlias;
+           break;
+       default:
+           ret = BadFontName;
+       }
+    }
+    else
+    {
+      ret = BadFontName;
+    }
+    
+    if (ret != BadFontName)
+    {
+       if (ranges) free(ranges);
+       return ret;
+    }
+
+    /* Match XLFD patterns */
+    CopyISOLatin1Lowered (lowerName, name, namelen);
+    lowerName[namelen] = '\0';
+    tmpName.name = lowerName;
+    tmpName.length = namelen;
+    tmpName.ndashes = FontFileCountDashes (lowerName, namelen);
+    if (!FontParseXLFDName (lowerName, &vals, FONT_XLFD_REPLACE_ZERO) ||
+       !(tmpName.length = strlen (lowerName),
+         entry = FontFileFindNameInScalableDir (&dir->scalable, &tmpName,
+                                                &vals))) {
+       CopyISOLatin1Lowered (lowerName, name, namelen);
+       lowerName[namelen] = '\0';
+       tmpName.name = lowerName;
+       tmpName.length = namelen;
+       tmpName.ndashes = FontFileCountDashes (lowerName, namelen);
+       entry = FontFileFindNameInScalableDir (&dir->scalable, &tmpName, &vals);
+       if (entry)
+       {
+           strcpy(lowerName, entry->name.name);
+           tmpName.name = lowerName;
+           tmpName.length = entry->name.length;
+           tmpName.ndashes = entry->name.ndashes;
+       }
+    }
+    
+    if (entry)
+    {
+       noSpecificSize = FALSE; /* TRUE breaks XLFD enhancements */
+       if (entry && entry->type == FONT_ENTRY_SCALABLE &&
+           FontFileCompleteXLFD (&vals, &entry->u.scalable.extra->defaults))
+       {
+           scalable = &entry->u.scalable;
+           scaled = FontFileFindScaledInstance (entry, &vals, noSpecificSize);
+           /*
+            * A scaled instance can occur one of two ways:
+            *
+            *  Either the font has been scaled to this
+            *   size already, in which case scaled->pFont
+            *   will point at that font.
+            *
+            *  Or a bitmap instance in this size exists,
+            *   which is handled as if we got a pattern
+            *   matching the bitmap font name.
+            */
+           if (scaled)
+           {
+               if (scaled->pFont)
+               {
+                   *pFontInfo = &scaled->pFont->info;
+                   ret = Successful;
+               }
+               else if (scaled->bitmap)
+               {
+                   entry = scaled->bitmap;
+                   bitmap = &entry->u.bitmap;
+                   if (bitmap->pFont)
+                   {
+                       *pFontInfo = &bitmap->pFont->info;
+                       ret = Successful;
+                   }
+                   else
+                   {
+                       ret = FontFileGetInfoBitmap (fpe, *pFontInfo, entry);
+                   }
+               }
+               else /* "cannot" happen */
+               {
+                   ret = BadFontName;
+               }
+           }
+           else
+           {
+               {
+                   char origName[MAXFONTNAMELEN];
+
+                   CopyISOLatin1Lowered (origName, name, namelen);
+                   origName[namelen] = '\0';
+                   vals.xlfdName = origName;
+                   vals.ranges = ranges;
+                   vals.nranges = nranges;
+                   
+                   /* Make a new scaled instance */
+                   if (strlen(dir->directory) + strlen(scalable->fileName) >=
+                       sizeof(fileName)) {
+                       ret = BadFontName;
+                   } else {
+                       strcpy (fileName, dir->directory);
+                       strcat (fileName, scalable->fileName);
+                        if (scalable->renderer->GetInfoScalable)
+                           ret = (*scalable->renderer->GetInfoScalable)
+                               (fpe, *pFontInfo, entry, &tmpName, fileName,
+                                 &vals);
+                        else if (scalable->renderer->GetInfoBitmap)
+                            ret = (*scalable->renderer->GetInfoBitmap)
+                                (fpe, *pFontInfo, entry, fileName);
+                   }
+                   if (ranges) {
+                       free(ranges);
+                       ranges = NULL;
+                   }
+               }
+           }
+           if (ret == Successful) return ret;
+       }
+       CopyISOLatin1Lowered (lowerName, name, namelen);
+       tmpName.length = namelen;
+    }
+    else
+       ret = BadFontName;
+
+    if (ranges)
+       free(ranges);
+    return ret;
+}
+
+int
+FontFileListNextFontWithInfo(pointer client, FontPathElementPtr fpe, 
+                            char **namep, int *namelenp, 
+                            FontInfoPtr *pFontInfo,
+                            int *numFonts, pointer private)
+{
+    LFWIDataPtr        data = (LFWIDataPtr) private;
+    int                ret;
+    char       *name;
+    int                namelen;
+
+    if (data->current == data->names->nnames)
+    {
+       FreeFontNames (data->names);
+       free (data);
+       return BadFontName;
+    }
+    name = data->names->names[data->current];
+    namelen = data->names->length[data->current];
+    ret = FontFileListOneFontWithInfo (client, fpe, &name, &namelen, pFontInfo);
+    if (ret == BadFontName)
+       ret = AllocError;
+    *namep = name;
+    *namelenp = namelen;
+    ++data->current;
+    *numFonts = data->names->nnames - data->current;
+    return ret;
+}
+
+int
+FontFileStartListFontsAndAliases(pointer client, FontPathElementPtr fpe, 
+                                char *pat, int len, int max, 
+                                pointer *privatep)
+{
+    return FontFileStartListFonts(client, fpe, pat, len, max, privatep, 1);
+}
+
+int
+FontFileListNextFontOrAlias(pointer client, FontPathElementPtr fpe, 
+                           char **namep, int *namelenp, char **resolvedp,
+                           int *resolvedlenp, pointer private)
+{
+    LFWIDataPtr        data = (LFWIDataPtr) private;
+    int                ret;
+    char       *name;
+    int                namelen;
+
+    if (data->current == data->names->nnames)
+    {
+       FreeFontNames (data->names);
+       free (data);
+       return BadFontName;
+    }
+    name = data->names->names[data->current];
+    namelen = data->names->length[data->current];
+
+    /* If this is a real font name... */
+    if (namelen >= 0)
+    {
+       *namep = name;
+       *namelenp = namelen;
+       ret = Successful;
+    }
+    /* Else if an alias */
+    else
+    {
+       /* Tell the caller that this is an alias... let him resolve it to
+          see if it's valid */
+       *namep = name;
+       *namelenp = -namelen;
+       *resolvedp = data->names->names[++data->current];
+       *resolvedlenp = data->names->length[data->current];
+       ret = FontNameAlias;
+    }
+
+    ++data->current;
+    return ret;
+}
+
+void
+FontFileRegisterLocalFpeFunctions (void)
+{
+    RegisterFPEFunctions(FontFileNameCheck,
+                        FontFileInitFPE,
+                        FontFileFreeFPE,
+                        FontFileResetFPE,
+                        FontFileOpenFont,
+                        FontFileCloseFont,
+                        FontFileListFonts,
+                        FontFileStartListFontsWithInfo,
+                        FontFileListNextFontWithInfo,
+                        NULL,
+                        NULL,
+                        NULL,
+                        FontFileStartListFontsAndAliases,
+                        FontFileListNextFontOrAlias,
+                        FontFileEmptyBitmapSource);
+}
diff --git a/src/fontfile/fontscale.c b/src/fontfile/fontscale.c
new file mode 100755 (executable)
index 0000000..55aca29
--- /dev/null
@@ -0,0 +1,437 @@
+/*
+
+Copyright 1991, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+/*
+ * Author:  Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include    <X11/fonts/fntfilst.h>
+#include <math.h>
+
+Bool
+FontFileAddScaledInstance (FontEntryPtr entry, FontScalablePtr vals, 
+                          FontPtr pFont, char *bitmapName)
+{
+    FontScalableEntryPtr    scalable;
+    FontScalableExtraPtr    extra;
+    FontScaledPtr          new;
+    int                            newsize;
+
+    scalable = &entry->u.scalable;
+    extra = scalable->extra;
+    if (extra->numScaled == extra->sizeScaled)
+    {
+       newsize = extra->sizeScaled + 4;
+       new = realloc (extra->scaled, newsize * sizeof (FontScaledRec));
+       if (!new)
+           return FALSE;
+       extra->sizeScaled = newsize;
+       extra->scaled = new;
+    }
+    new = &extra->scaled[extra->numScaled++];
+    new->vals = *vals;
+    new->pFont = pFont;
+    new->bitmap = (FontEntryPtr) bitmapName;
+    if (pFont)
+       pFont->fpePrivate = (pointer) entry;
+    return TRUE;
+}
+
+/* Must call this after the directory is sorted */
+
+void
+FontFileSwitchStringsToBitmapPointers (FontDirectoryPtr dir)
+{
+    int            s;
+    int            b;
+    int            i;
+    FontEntryPtr           scalable;
+    FontEntryPtr           nonScalable;
+    FontScaledPtr          scaled;
+    FontScalableExtraPtr    extra;
+    
+    scalable = dir->scalable.entries;
+    nonScalable = dir->nonScalable.entries;
+    for (s = 0; s < dir->scalable.used; s++)
+    {
+       extra = scalable[s].u.scalable.extra;
+       scaled = extra->scaled;
+       for (i = 0; i < extra->numScaled; i++)
+           for (b = 0; b < dir->nonScalable.used; b++)
+               if (nonScalable[b].name.name == (char *) scaled[i].bitmap)
+                   scaled[i].bitmap = &nonScalable[b];
+    }
+}
+
+void
+FontFileRemoveScaledInstance (FontEntryPtr entry, FontPtr pFont)
+{
+    FontScalableEntryPtr    scalable;
+    FontScalableExtraPtr    extra;
+    int                            i;
+
+    scalable = &entry->u.scalable;
+    extra = scalable->extra;
+    for (i = 0; i < extra->numScaled; i++)
+    {
+       if (extra->scaled[i].pFont == pFont)
+       {
+           if (extra->scaled[i].vals.ranges)
+               free (extra->scaled[i].vals.ranges);
+           extra->numScaled--;
+           for (; i < extra->numScaled; i++)
+               extra->scaled[i] = extra->scaled[i+1];
+       }
+    }
+}
+
+Bool
+FontFileCompleteXLFD (FontScalablePtr vals, FontScalablePtr def)
+{
+    FontResolutionPtr res;
+    int                num_res;
+    double     sx, sy, temp_matrix[4];
+    double     pixel_setsize_adjustment = 1.0;
+    /*
+     * If two of the three vertical scale values are specified, compute the
+     * third.  If all three are specified, make sure they are consistent
+     * (within a pixel)
+     *
+     * One purpose of this procedure is to complete XLFD names in a
+     * repeatable manner.  That is, if the user partially specifies
+     * a name (say, pixelsize but not pointsize), the results generated
+     * here result in a fully specified name that will result in the
+     * same font.
+     */
+
+    res = GetClientResolutions(&num_res);
+
+    if (!(vals->values_supplied & PIXELSIZE_MASK) ||
+       !(vals->values_supplied & POINTSIZE_MASK))
+    {
+       /* If resolution(s) unspecified and cannot be computed from
+          pixelsize and pointsize, get appropriate defaults. */
+
+       if (num_res)
+       {
+           if (vals->x <= 0)
+               vals->x = res->x_resolution;
+           if (vals->y <= 0)
+               vals->y = res->y_resolution;
+       }
+
+       if (vals->x <= 0)
+           vals->x = def->x;
+       if (vals->y <= 0)
+           vals->y = def->y;
+    }
+    else
+    {
+       /* If needed, compute resolution values from the pixel and
+          pointsize information we were given.  This problem is
+          overdetermined (four equations, two unknowns), but we don't
+          check for inconsistencies here.  If they exist, they will
+          show up in later tests for the point and pixel sizes.  */
+
+       if (vals->y <= 0)
+       {
+           double x = hypot(vals->pixel_matrix[1], vals->pixel_matrix[3]);
+           double y = hypot(vals->point_matrix[1], vals->point_matrix[3]);
+           if (y < EPS) return FALSE;
+           vals->y = (int)(x * 72.27 / y + .5);
+       }
+       if (vals->x <= 0)
+       {
+           /* If the pixelsize was given as an array, or as a scalar that
+              has been normalized for the pixel shape, we have enough
+              information to compute a separate horizontal resolution */
+
+           if ((vals->values_supplied & PIXELSIZE_MASK) == PIXELSIZE_ARRAY ||
+               (vals->values_supplied & PIXELSIZE_MASK) ==
+                   PIXELSIZE_SCALAR_NORMALIZED)
+           {
+               double x = hypot(vals->pixel_matrix[0], vals->pixel_matrix[2]);
+               double y = hypot(vals->point_matrix[0], vals->point_matrix[2]);
+               if (y < EPS) return FALSE;
+               vals->x = (int)(x * 72.27 / y + .5);
+           }
+           else
+           {
+               /* Not enough information in the pixelsize array.  Just
+                  assume the pixels are square. */
+               vals->x = vals->y;
+           }
+       }
+    }
+
+    if (vals->x <= 0 || vals->y <= 0) return FALSE;
+
+    /* If neither pixelsize nor pointsize is defined, take the pointsize
+       from the defaults structure we've been passed. */
+    if (!(vals->values_supplied & PIXELSIZE_MASK) &&
+       !(vals->values_supplied & POINTSIZE_MASK))
+    {
+       if (num_res)
+       {
+           vals->point_matrix[0] =
+           vals->point_matrix[3] = (double)res->point_size / 10.0;
+           vals->point_matrix[1] =
+           vals->point_matrix[2] = 0;
+           vals->values_supplied = (vals->values_supplied & ~POINTSIZE_MASK) |
+                                   POINTSIZE_SCALAR;
+       }
+       else if (def->values_supplied & POINTSIZE_MASK)
+       {
+           vals->point_matrix[0] = def->point_matrix[0];
+           vals->point_matrix[1] = def->point_matrix[1];
+           vals->point_matrix[2] = def->point_matrix[2];
+           vals->point_matrix[3] = def->point_matrix[3];
+           vals->values_supplied = (vals->values_supplied & ~POINTSIZE_MASK) |
+                                   (def->values_supplied & POINTSIZE_MASK);
+       }
+       else return FALSE;
+    }
+
+    /* At this point, at least two of the three vertical scale values
+       should be specified.  Our job now is to compute the missing ones
+       and check for agreement between overspecified values */
+
+    /* If pixelsize was specified by a scalar, we need to fix the matrix
+       now that we know the resolutions.  */
+    if ((vals->values_supplied & PIXELSIZE_MASK) == PIXELSIZE_SCALAR)
+    {
+       /* pixel_setsize_adjustment used below to modify permissible
+          error in pixel/pointsize matching, since multiplying a
+          number rounded to integer changes the amount of the error
+          caused by the rounding */
+
+       pixel_setsize_adjustment = (double)vals->x / (double)vals->y;
+       vals->pixel_matrix[0] *= pixel_setsize_adjustment;
+       vals->values_supplied  = (vals->values_supplied & ~PIXELSIZE_MASK) |
+                                PIXELSIZE_SCALAR_NORMALIZED;
+    }
+
+    sx = (double)vals->x / 72.27;
+    sy = (double)vals->y / 72.27;
+
+    /* If a pointsize was specified, make sure pixelsize is consistent
+       to within 1 pixel, then replace pixelsize with a consistent
+       floating-point value.  */
+
+    if (vals->values_supplied & POINTSIZE_MASK)
+    {
+    recompute_pixelsize: ;
+       temp_matrix[0] = vals->point_matrix[0] * sx;
+       temp_matrix[1] = vals->point_matrix[1] * sy;
+       temp_matrix[2] = vals->point_matrix[2] * sx;
+       temp_matrix[3] = vals->point_matrix[3] * sy;
+       if (vals->values_supplied & PIXELSIZE_MASK)
+       {
+           if (fabs(vals->pixel_matrix[0] - temp_matrix[0]) >
+                   pixel_setsize_adjustment ||
+               fabs(vals->pixel_matrix[1] - temp_matrix[1]) > 1 ||
+               fabs(vals->pixel_matrix[2] - temp_matrix[2]) > 1 ||
+               fabs(vals->pixel_matrix[3] - temp_matrix[3]) > 1)
+               return FALSE;
+       }
+       if ((vals->values_supplied & PIXELSIZE_MASK) == PIXELSIZE_ARRAY &&
+           (vals->values_supplied & POINTSIZE_MASK) == POINTSIZE_SCALAR)
+       {
+           /* In the special case that pixelsize came as an array and
+              pointsize as a scalar, recompute the pointsize matrix
+              from the pixelsize matrix. */
+           goto recompute_pointsize;
+       }
+
+       /* Refresh pixel matrix with precise values computed from
+          pointsize and resolution.  */
+       vals->pixel_matrix[0] = temp_matrix[0];
+       vals->pixel_matrix[1] = temp_matrix[1];
+       vals->pixel_matrix[2] = temp_matrix[2];
+       vals->pixel_matrix[3] = temp_matrix[3];
+
+       /* Set values_supplied for pixel to match that for point */
+       vals->values_supplied =
+           (vals->values_supplied & ~PIXELSIZE_MASK) |
+           (((vals->values_supplied & POINTSIZE_MASK) == POINTSIZE_ARRAY) ?
+               PIXELSIZE_ARRAY : PIXELSIZE_SCALAR_NORMALIZED);
+    }
+    else
+    {
+       /* Pointsize unspecified...  compute from pixel size and
+          resolutions */
+    recompute_pointsize: ;
+       if (fabs(sx) < EPS || fabs(sy) < EPS) return FALSE;
+       vals->point_matrix[0] = vals->pixel_matrix[0] / sx;
+       vals->point_matrix[1] = vals->pixel_matrix[1] / sy;
+       vals->point_matrix[2] = vals->pixel_matrix[2] / sx;
+       vals->point_matrix[3] = vals->pixel_matrix[3] / sy;
+
+       /* Set values_supplied for pixel to match that for point */
+       vals->values_supplied =
+           (vals->values_supplied & ~POINTSIZE_MASK) |
+           (((vals->values_supplied & PIXELSIZE_MASK) == PIXELSIZE_ARRAY) ?
+               POINTSIZE_ARRAY : POINTSIZE_SCALAR);
+
+       /* If we computed scalar pointsize from scalar pixelsize, round
+          pointsize to decipoints and recompute pixelsize so we end up
+          with a repeatable name */
+       if ((vals->values_supplied & POINTSIZE_MASK) == POINTSIZE_SCALAR)
+       {
+           /* Off-diagonal elements should be zero since no matrix was
+              specified. */
+           vals->point_matrix[0] =
+               (double)(int)(vals->point_matrix[0] * 10.0 + .5) / 10.0;
+           vals->point_matrix[3] =
+               (double)(int)(vals->point_matrix[3] * 10.0 + .5) / 10.0;
+           goto recompute_pixelsize;
+       }
+    }
+
+    /* We've succeeded.  Round everything to a few decimal places
+       for repeatability. */
+
+    vals->pixel_matrix[0] = xlfd_round_double(vals->pixel_matrix[0]);
+    vals->pixel_matrix[1] = xlfd_round_double(vals->pixel_matrix[1]);
+    vals->pixel_matrix[2] = xlfd_round_double(vals->pixel_matrix[2]);
+    vals->pixel_matrix[3] = xlfd_round_double(vals->pixel_matrix[3]);
+    vals->point_matrix[0] = xlfd_round_double(vals->point_matrix[0]);
+    vals->point_matrix[1] = xlfd_round_double(vals->point_matrix[1]);
+    vals->point_matrix[2] = xlfd_round_double(vals->point_matrix[2]);
+    vals->point_matrix[3] = xlfd_round_double(vals->point_matrix[3]);
+
+    /* Fill in the deprecated fields for the benefit of rasterizers
+       that do not handle the matrices. */
+    vals->point = vals->point_matrix[3] * 10;
+    vals->pixel = vals->pixel_matrix[3];
+
+    return TRUE;
+}
+
+static Bool
+MatchScalable (FontScalablePtr a, FontScalablePtr b)
+{
+    int i;
+
+    /* Some asymmetry here:  we assume that the first argument (a) is
+       the table entry and the second (b) the item we're trying to match
+       (the key).  We'll consider the fonts matched if the relevant
+       metrics match *and* if a) the table entry doesn't have charset
+       subsetting or b) the table entry has identical charset subsetting
+       to that in the key.  We could add logic to check if the table
+       entry has a superset of the charset required by the key, but
+       we'll resist the urge for now.  */
+
+#define EQUAL(a,b) ((a)[0] == (b)[0] && \
+                    (a)[1] == (b)[1] && \
+                    (a)[2] == (b)[2] && \
+                    (a)[3] == (b)[3])
+
+    if (!(a->x == b->x &&
+         a->y == b->y &&
+         (a->width == b->width || a->width == 0 || b->width == 0 || b->width == -1) &&
+         (!(b->values_supplied & PIXELSIZE_MASK) ||
+           ((a->values_supplied & PIXELSIZE_MASK) ==
+            (b->values_supplied & PIXELSIZE_MASK) &&
+           EQUAL(a->pixel_matrix, b->pixel_matrix))) &&
+         (!(b->values_supplied & POINTSIZE_MASK) ||
+           ((a->values_supplied & POINTSIZE_MASK) ==
+            (b->values_supplied & POINTSIZE_MASK) &&
+           EQUAL(a->point_matrix, b->point_matrix))) &&
+         (a->nranges == 0 || a->nranges == b->nranges)))
+      return FALSE;
+
+    for (i = 0; i < a->nranges; i++)
+       if (a->ranges[i].min_char_low != b->ranges[i].min_char_low ||
+           a->ranges[i].min_char_high != b->ranges[i].min_char_high ||
+           a->ranges[i].max_char_low != b->ranges[i].max_char_low ||
+           a->ranges[i].max_char_high != b->ranges[i].max_char_high)
+               return FALSE;
+    return TRUE;
+}
+
+FontScaledPtr
+FontFileFindScaledInstance (FontEntryPtr entry, FontScalablePtr vals, 
+                           int noSpecificSize)
+{
+    FontScalableEntryPtr    scalable;
+    FontScalableExtraPtr    extra;
+    FontScalablePtr        mvals;
+    int                            dist, i;
+    int                            mini;
+    double                 mindist;
+    register double        temp, sum=0.0;
+
+#define NORMDIFF(a, b) ( \
+    temp = (a)[0] - (b)[0], \
+    sum = temp * temp, \
+    temp = (a)[1] - (b)[1], \
+    sum += temp * temp, \
+    temp = (a)[2] - (b)[2], \
+    sum += temp * temp, \
+    temp = (a)[3] - (b)[3], \
+    sum + temp * temp )
+
+    scalable = &entry->u.scalable;
+    extra = scalable->extra;
+    if (noSpecificSize && extra->numScaled)
+    {
+       mini = 0;
+       mindist = NORMDIFF(extra->scaled[0].vals.point_matrix,
+                          vals->point_matrix);
+       for (i = 1; i < extra->numScaled; i++)
+       {
+           if (extra->scaled[i].pFont &&
+               !extra->scaled[i].pFont->info.cachable) continue;
+           mvals = &extra->scaled[i].vals;
+           dist = NORMDIFF(mvals->point_matrix, vals->point_matrix);
+           if (dist < mindist)
+           {
+               mindist = dist;
+               mini = i;
+           }
+       }
+       if (extra->scaled[mini].pFont &&
+           !extra->scaled[mini].pFont->info.cachable) return 0;
+       return &extra->scaled[mini];
+    }
+    else
+    {
+       /* See if we've scaled to this value yet */
+       for (i = 0; i < extra->numScaled; i++)
+       {
+           if (extra->scaled[i].pFont &&
+               !extra->scaled[i].pFont->info.cachable) continue;
+           if (MatchScalable (&extra->scaled[i].vals, vals))
+               return &extra->scaled[i];
+       }
+    }
+    return 0;
+}
diff --git a/src/fontfile/gunzip.c b/src/fontfile/gunzip.c
new file mode 100755 (executable)
index 0000000..9fa3eed
--- /dev/null
@@ -0,0 +1,225 @@
+/* lib/font/fontfile/gunzip.c
+   written by Mark Eichin <eichin@kitten.gen.ma.us> September 1996.
+   intended for inclusion in X11 public releases. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fontmisc.h>
+#include <X11/fonts/bufio.h>
+#include <zlib.h>
+
+typedef struct _xzip_buf {
+  z_stream z;
+  int zstat;
+  BufChar b[BUFFILESIZE];
+  BufChar b_in[BUFFILESIZE];
+  BufFilePtr f;
+} xzip_buf;
+
+static int BufZipFileClose ( BufFilePtr f, int flag );
+static int BufZipFileFill ( BufFilePtr f );
+static int BufZipFileSkip ( BufFilePtr f, int c );
+static int BufCheckZipHeader ( BufFilePtr f );
+
+BufFilePtr
+BufFilePushZIP (BufFilePtr f)
+{
+  xzip_buf *x;
+
+  x = malloc (sizeof (xzip_buf));
+  if (!x) return 0;
+  /* these are just for raw calloc/free */
+  x->z.zalloc = Z_NULL;
+  x->z.zfree = Z_NULL;
+  x->z.opaque = Z_NULL;
+  x->f = f;
+
+  /* force inflateInit to allocate it's own history buffer */
+  x->z.next_in = Z_NULL;
+  x->z.next_out = Z_NULL;
+  x->z.avail_in = x->z.avail_out = 0;
+
+  /* using negative windowBits sets "nowrap" mode, which turns off
+     zlib header checking [undocumented, for gzip compatibility only?] */
+  x->zstat = inflateInit2(&(x->z), -MAX_WBITS);
+  if (x->zstat != Z_OK) {
+    free(x);
+    return 0;
+  }
+
+  /* now that the history buffer is allocated, we provide the data buffer */
+  x->z.next_out = x->b;
+  x->z.avail_out = BUFFILESIZE;
+  x->z.next_out = x->b_in;
+  x->z.avail_in = 0;
+
+  if (BufCheckZipHeader(x->f)) {
+    free(x);
+    return 0;
+  }
+
+  return BufFileCreate((char *)x,
+                      BufZipFileFill,
+                      0,
+                      BufZipFileSkip,
+                      BufZipFileClose);
+}
+
+static int 
+BufZipFileClose(BufFilePtr f, int flag)
+{
+  xzip_buf *x = (xzip_buf *)f->private;
+  inflateEnd (&(x->z));
+  BufFileClose (x->f, flag);
+  free (x);
+  return 1;
+}
+
+/* here's the real work. 
+   -- we need to put stuff in f.buffer, update f.left and f.bufp,
+      then return the first byte (or BUFFILEEOF).
+   -- to do this, we need to get stuff into avail_in, and next_in, 
+      and call inflate appropriately.
+   -- we may also need to add CRC maintenance - if inflate tells us
+      Z_STREAM_END, we then have 4bytes CRC and 4bytes length...
+   gzio.c:gzread shows most of the mechanism.
+   */
+static int 
+BufZipFileFill (BufFilePtr f)
+{
+  xzip_buf *x = (xzip_buf *)f->private;
+
+  /* we only get called when left == 0... */
+  /* but just in case, deal */
+  if (f->left >= 0) {
+    f->left--;
+    return *(f->bufp++);
+  }
+  /* did we run out last time? */
+  switch (x->zstat) {
+  case Z_OK:
+    break;
+  case Z_STREAM_END:
+  case Z_DATA_ERROR:
+  case Z_ERRNO:
+      f->left = 0;
+      return BUFFILEEOF;
+  default:
+    return BUFFILEEOF;
+  }
+  /* now we work to consume what we can */
+  /* let zlib know what we can handle */
+  x->z.next_out = x->b;
+  x->z.avail_out = BUFFILESIZE;
+
+  /* and try to consume all of it */
+  while (x->z.avail_out > 0) {
+    /* if we don't have anything to work from... */
+    if (x->z.avail_in == 0) {
+      /* ... fill the z buf from underlying file */
+      int i, c;
+      for (i = 0; i < sizeof(x->b_in); i++) {
+       c = BufFileGet(x->f);
+       if (c == BUFFILEEOF) break;
+       x->b_in[i] = c;
+      }
+      x->z.avail_in += i;
+      x->z.next_in = x->b_in;
+    }
+    /* so now we have some output space and some input data */
+    x->zstat = inflate(&(x->z), Z_NO_FLUSH);
+    /* the inflation output happens in the f buffer directly... */
+    if (x->zstat == Z_STREAM_END) {
+      /* deal with EOF, crc */
+      break;
+    }
+    if (x->zstat != Z_OK) {
+      break;
+    }
+  }
+  f->bufp = x->b;
+  f->left = BUFFILESIZE - x->z.avail_out;  
+
+  if (f->left >= 0) {
+    f->left--;
+    return *(f->bufp++);
+  } else {
+    return BUFFILEEOF;
+  }
+}
+
+/* there should be a BufCommonSkip... */
+static int 
+BufZipFileSkip (BufFilePtr f, int c)
+{
+  /* BufFileRawSkip returns the count unchanged.
+     BufCompressedSkip returns 0.
+     That means it probably never gets called... */
+  int retval = c;
+  while(c--) {
+    int get = BufFileGet(f);
+    if (get == BUFFILEEOF) return get;
+  }
+  return retval;
+}
+
+/* now we need to duplicate check_header */
+/* contents:
+     0x1f, 0x8b        -- magic number
+     1 byte    -- method (Z_DEFLATED)
+     1 byte    -- flags (mask with RESERVED -> fail)
+     4 byte    -- time (discard)
+     1 byte    -- xflags (discard)
+     1 byte    -- "os" code (discard)
+     [if flags & EXTRA_FIELD:
+         2 bytes -- LSBfirst length n
+        n bytes -- extra data (discard)]
+     [if flags & ORIG_NAME:
+        n bytes -- null terminated name (discard)]
+     [if flags & COMMENT:
+        n bytes -- null terminated comment (discard)]
+     [if flags & HEAD_CRC:
+         2 bytes -- crc of headers? (discard)]
+ */
+
+/* gzip flag byte -- from gzio.c */
+#define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
+#define HEAD_CRC     0x02 /* bit 1 set: header CRC present */
+#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
+#define COMMENT      0x10 /* bit 4 set: file comment present */
+#define RESERVED     0xE0 /* bits 5..7: reserved */
+
+#define GET(f) do {c = BufFileGet(f); if (c == BUFFILEEOF) return c;} while(0)
+static int 
+BufCheckZipHeader(BufFilePtr f)
+{
+  int c, flags;
+  GET(f); if (c != 0x1f) return 1; /* magic 1 */
+  GET(f); if (c != 0x8b) return 2; /* magic 2 */
+  GET(f); if (c != Z_DEFLATED) return 3; /* method */
+  GET(f); if (c & RESERVED) return 4; /* reserved flags */
+  flags = c;
+  GET(f); GET(f); GET(f); GET(f); /* time */
+  GET(f);                      /* xflags */
+  GET(f);                      /* os code */
+  if (flags & EXTRA_FIELD) {
+    int len;
+    GET(f); len = c;
+    GET(f); len += (c<<8);
+    while (len-- >= 0) {
+      GET(f);
+    }
+  }
+  if (flags & ORIG_NAME) {
+    do { GET(f); } while (c != 0);
+  }
+  if (flags & COMMENT) {
+    do { GET(f); } while (c != 0);
+  }
+  if (flags & HEAD_CRC) {
+    GET(f); GET(f);            /* header crc */
+  }
+  return 0;
+}
diff --git a/src/fontfile/register.c b/src/fontfile/register.c
new file mode 100644 (file)
index 0000000..1a63cb3
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+
+Copyright 1994, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#else
+#define XFONT_BITMAP 1
+#endif
+
+#include <X11/fonts/fontmisc.h>
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/bitmap.h>
+
+/*
+ * Translate monolithic build symbols to modular build symbols.
+ * I chose to make the modular symbols 'canonical' because they
+ * are prefixed with XFONT_, neatly avoiding name collisions
+ * with other packages.
+ */
+
+#ifdef BUILD_FREETYPE
+# define XFONT_FREETYPE 1
+#endif
+
+void
+FontFileRegisterFpeFunctions(void)
+{
+#ifdef XFONT_BITMAP
+    /* bitmap is always builtin to libXfont now */
+    BitmapRegisterFontFileFunctions ();
+#endif
+#ifdef XFONT_FREETYPE
+    FreeTypeRegisterFontFileFunctions();
+#endif
+    
+    FontFileRegisterLocalFpeFunctions ();
+    CatalogueRegisterLocalFpeFunctions ();
+}
+
diff --git a/src/fontfile/renderers.c b/src/fontfile/renderers.c
new file mode 100755 (executable)
index 0000000..a9e4bef
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+
+Copyright 1991, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+/*
+ * Author:  Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fntfilst.h>
+extern void ErrorF(const char *f, ...);
+
+static FontRenderersRec        renderers;
+
+/*
+ * XXX Maybe should allow unregistering renders. For now, just clear the
+ * list at each new generation.
+ */
+extern unsigned long serverGeneration;
+static unsigned long rendererGeneration = 0;
+
+Bool
+FontFileRegisterRenderer (FontRendererPtr renderer)
+{
+    return FontFilePriorityRegisterRenderer(renderer, 0);
+}
+
+Bool
+FontFilePriorityRegisterRenderer (FontRendererPtr renderer, int priority)
+{
+    int                    i;
+    struct _FontRenderersElement *new;
+
+    if (rendererGeneration != serverGeneration) {
+       rendererGeneration = serverGeneration;
+       renderers.number = 0;
+       if (renderers.renderers)
+          free(renderers.renderers);
+       renderers.renderers = NULL;
+    }
+
+    for (i = 0; i < renderers.number; i++) {
+       if (!strcasecmp (renderers.renderers[i].renderer->fileSuffix, 
+                         renderer->fileSuffix)) {
+            if(renderers.renderers[i].priority >= priority) {
+                if(renderers.renderers[i].priority == priority) {
+                    if (rendererGeneration == 1)
+                        ErrorF("Warning: font renderer for \"%s\" "
+                               "already registered at priority %d\n",
+                               renderer->fileSuffix, priority);
+                }
+                return TRUE;
+            } else {
+                break;
+            }
+        }
+    }
+
+    if(i >= renderers.number) {
+        new = realloc (renderers.renderers, sizeof(*new) * (i + 1));
+        if (!new)
+            return FALSE;
+        renderers.renderers = new;
+        renderers.number = i + 1;
+    }
+    renderer->number = i;
+    renderers.renderers[i].renderer = renderer;
+    renderers.renderers[i].priority = priority;
+    return TRUE;
+}
+
+FontRendererPtr
+FontFileMatchRenderer (char *fileName)
+{
+    int                        i;
+    int                        fileLen;
+    FontRendererPtr    r;
+    
+    fileLen = strlen (fileName);
+    for (i = 0; i < renderers.number; i++)
+    {
+       r = renderers.renderers[i].renderer;
+       if (fileLen >= r->fileSuffixLen &&
+           !strcasecmp (fileName + fileLen - r->fileSuffixLen, r->fileSuffix))
+       {
+           return r;
+       }
+    }
+    return 0;
+}
diff --git a/src/stubs/Makefile.am b/src/stubs/Makefile.am
new file mode 100644 (file)
index 0000000..4d60c2a
--- /dev/null
@@ -0,0 +1,25 @@
+INCLUDES =                     \
+       -I${top_srcdir}/include
+
+AM_CFLAGS = $(XFONT_CFLAGS) $(OS_CFLAGS) $(CWARNFLAGS)
+
+noinst_LTLIBRARIES = libstubs.la
+
+libstubs_la_SOURCES =          \
+       cauthgen.c              \
+       csignal.c               \
+       delfntcid.c             \
+       errorf.c                \
+       fatalerror.c            \
+       findoldfnt.c            \
+       getcres.c               \
+       getdefptsize.c          \
+       getnewfntcid.c          \
+       gettime.c               \
+       initfshdl.c             \
+       regfpefunc.c            \
+       rmfshdl.c               \
+       servclient.c            \
+       setfntauth.c            \
+       stfntcfnt.c             \
+       stubs.h 
diff --git a/src/stubs/cauthgen.c b/src/stubs/cauthgen.c
new file mode 100644 (file)
index 0000000..026c52d
--- /dev/null
@@ -0,0 +1,14 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "stubs.h"
+
+#ifdef __SUNPRO_C
+#pragma weak client_auth_generation
+#endif
+
+weak int
+client_auth_generation(ClientPtr client)
+{
+    return 0;
+}
diff --git a/src/stubs/csignal.c b/src/stubs/csignal.c
new file mode 100644 (file)
index 0000000..e6fdeae
--- /dev/null
@@ -0,0 +1,14 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "stubs.h"
+
+#ifdef __SUNPRO_C
+#pragma weak ClientSignal
+#endif
+
+weak Bool
+ClientSignal(ClientPtr client)
+{
+    return True;
+}
diff --git a/src/stubs/delfntcid.c b/src/stubs/delfntcid.c
new file mode 100644 (file)
index 0000000..ca71328
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "stubs.h"
+
+#ifdef __SUNPRO_C
+#pragma weak DeleteFontClientID
+#endif
+
+weak void
+DeleteFontClientID(Font id)
+{
+}
diff --git a/src/stubs/errorf.c b/src/stubs/errorf.c
new file mode 100644 (file)
index 0000000..fd32965
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "stubs.h"
+
+#ifdef __SUNPRO_C
+#pragma weak ErrorF
+#endif
+
+weak void
+ErrorF(const char *f, ...)
+{
+}
diff --git a/src/stubs/fatalerror.c b/src/stubs/fatalerror.c
new file mode 100644 (file)
index 0000000..1549ad3
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "stubs.h"
+
+#ifdef __SUNPRO_C
+#pragma weak FatalError
+#endif
+
+weak void
+FatalError(const char *f, ...)
+{
+}
diff --git a/src/stubs/findoldfnt.c b/src/stubs/findoldfnt.c
new file mode 100644 (file)
index 0000000..7a00084
--- /dev/null
@@ -0,0 +1,14 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "stubs.h"
+
+#ifdef __SUNPRO_C
+#pragma weak find_old_font
+#endif
+
+weak FontPtr
+find_old_font(FSID id)
+{
+    return (FontPtr)NULL;
+}
diff --git a/src/stubs/getcres.c b/src/stubs/getcres.c
new file mode 100644 (file)
index 0000000..0b98f46
--- /dev/null
@@ -0,0 +1,14 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "stubs.h"
+
+#ifdef __SUNPRO_C
+#pragma weak GetClientResolutions
+#endif
+
+weak FontResolutionPtr
+GetClientResolutions(int *num)
+{
+  return (FontResolutionPtr) 0;
+}
diff --git a/src/stubs/getdefptsize.c b/src/stubs/getdefptsize.c
new file mode 100644 (file)
index 0000000..0b9e409
--- /dev/null
@@ -0,0 +1,14 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "stubs.h"
+
+#ifdef __SUNPRO_C
+#pragma weak GetDefaultPointSize
+#endif
+
+weak int
+GetDefaultPointSize(void)
+{
+    return 0;
+}
diff --git a/src/stubs/getnewfntcid.c b/src/stubs/getnewfntcid.c
new file mode 100644 (file)
index 0000000..e2fe8bb
--- /dev/null
@@ -0,0 +1,14 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "stubs.h"
+
+#ifdef __SUNPRO_C
+#pragma weak GetNewFontClientID
+#endif
+
+weak Font
+GetNewFontClientID(void)
+{
+    return (Font)0;
+}
diff --git a/src/stubs/gettime.c b/src/stubs/gettime.c
new file mode 100644 (file)
index 0000000..7b2d3b3
--- /dev/null
@@ -0,0 +1,14 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "stubs.h"
+
+#ifdef __SUNPRO_C
+#pragma weak GetTimeInMillis
+#endif
+
+weak unsigned long
+GetTimeInMillis (void)
+{
+    return 0;
+}
diff --git a/src/stubs/initfshdl.c b/src/stubs/initfshdl.c
new file mode 100644 (file)
index 0000000..a14daff
--- /dev/null
@@ -0,0 +1,15 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "stubs.h"
+
+#ifdef __SUNPRO_C
+#pragma weak init_fs_handlers
+#endif
+
+weak int
+init_fs_handlers(FontPathElementPtr fpe,
+                 BlockHandlerProcPtr block_handler)
+{
+  return Successful;
+}
diff --git a/src/stubs/regfpefunc.c b/src/stubs/regfpefunc.c
new file mode 100644 (file)
index 0000000..a79b4bf
--- /dev/null
@@ -0,0 +1,28 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "stubs.h"
+
+#ifdef __SUNPRO_C
+#pragma weak RegisterFPEFunctions
+#endif
+
+weak int 
+RegisterFPEFunctions(NameCheckFunc name_func, 
+                    InitFpeFunc init_func, 
+                    FreeFpeFunc free_func, 
+                    ResetFpeFunc reset_func, 
+                    OpenFontFunc open_func, 
+                    CloseFontFunc close_func, 
+                    ListFontsFunc list_func, 
+                    StartLfwiFunc start_lfwi_func, 
+                    NextLfwiFunc next_lfwi_func, 
+                    WakeupFpeFunc wakeup_func, 
+                    ClientDiedFunc client_died, 
+                    LoadGlyphsFunc load_glyphs, 
+                    StartLaFunc start_list_alias_func, 
+                    NextLaFunc next_list_alias_func, 
+                    SetPathFunc set_path_func)
+{
+    return 0;
+}
diff --git a/src/stubs/rmfshdl.c b/src/stubs/rmfshdl.c
new file mode 100644 (file)
index 0000000..d0bdd3d
--- /dev/null
@@ -0,0 +1,15 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "stubs.h"
+
+#ifdef __SUNPRO_C
+#pragma weak remove_fs_handlers
+#endif
+
+weak void 
+remove_fs_handlers(FontPathElementPtr fpe,
+                   BlockHandlerProcPtr blockHandler,
+                   Bool all)
+{
+}
diff --git a/src/stubs/servclient.c b/src/stubs/servclient.c
new file mode 100644 (file)
index 0000000..9b6cebb
--- /dev/null
@@ -0,0 +1,10 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "stubs.h"
+
+#ifdef __SUNPRO_C
+#pragma weak serverClient
+#endif
+
+weak void *serverClient = 0;
diff --git a/src/stubs/setfntauth.c b/src/stubs/setfntauth.c
new file mode 100644 (file)
index 0000000..0c7eccc
--- /dev/null
@@ -0,0 +1,14 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "stubs.h"
+
+#ifdef __SUNPRO_C
+#pragma weak set_font_authorizations
+#endif
+
+weak int
+set_font_authorizations(char **authorizations, int *authlen, ClientPtr client)
+{
+    return 0;
+}
diff --git a/src/stubs/stfntcfnt.c b/src/stubs/stfntcfnt.c
new file mode 100644 (file)
index 0000000..5fc1745
--- /dev/null
@@ -0,0 +1,14 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "stubs.h"
+
+#ifdef __SUNPRO_C
+#pragma weak StoreFontClientFont
+#endif
+
+weak int
+StoreFontClientFont(FontPtr pfont, Font id)
+{
+    return 0;
+}
diff --git a/src/stubs/stubs.h b/src/stubs/stubs.h
new file mode 100755 (executable)
index 0000000..7f0eef2
--- /dev/null
@@ -0,0 +1,41 @@
+#include <stdio.h>
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/font.h>
+
+#ifndef True
+#define True (-1)
+#endif
+#ifndef False
+#define False (0)
+#endif
+
+/* this probably works for Mach-O too, but probably not for PE */
+#if (defined(__APPLE__) || defined(__ELF__)) && defined(__GNUC__) && (__GNUC__ >= 3)
+#define weak __attribute__((weak))
+#else
+#define weak
+#ifndef __SUNPRO_C /* Sun compilers use #pragma weak in .c files instead */
+#define NO_WEAK_SYMBOLS
+#endif
+#endif
+
+/* This is really just a hack for now... __APPLE__ really should be using
+ * the weak symbols route above, but it's causing an as-yet unresolved issue,
+ * so we're instead building with flat_namespace.
+ */
+#ifdef __APPLE__
+#undef weak
+#define weak
+#endif
+
+extern FontPtr find_old_font ( FSID id );
+extern int set_font_authorizations ( char **authorizations, 
+                                    int *authlen, 
+                                    ClientPtr client );
+
+extern unsigned long GetTimeInMillis (void);
+
+extern void ErrorF(const char *format, ...);
+extern void FatalError(const char *format, ...);
+
+/* end of file */
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
new file mode 100644 (file)
index 0000000..055fc9d
--- /dev/null
@@ -0,0 +1,19 @@
+INCLUDES =                     \
+       -I${top_srcdir}/include \
+       -I$(top_srcdir)/src/stubs
+
+AM_CFLAGS = $(XFONT_CFLAGS) $(OS_CFLAGS) $(CWARNFLAGS)
+
+noinst_LTLIBRARIES = libutil.la
+
+libutil_la_SOURCES =           \
+       atom.c                  \
+       fontaccel.c             \
+       fontnames.c             \
+       fontutil.c              \
+       fontxlfd.c              \
+       format.c                \
+       miscutil.c              \
+       patcache.c              \
+       private.c               \
+       utilbitmap.c
diff --git a/src/util/atom.c b/src/util/atom.c
new file mode 100755 (executable)
index 0000000..f15e3d8
--- /dev/null
@@ -0,0 +1,242 @@
+/*
+
+Copyright 1990, 1994, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+/*
+ * Author:  Keith Packard, MIT X Consortium
+ */
+
+/* lame atom replacement routines for font applications */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fontmisc.h>
+#include "stubs.h"
+
+typedef struct _AtomList {
+    char               *name;
+    int                        len;
+    int                        hash;
+    Atom               atom;
+} AtomListRec, *AtomListPtr;
+
+static AtomListPtr  *hashTable;
+
+static int         hashSize, hashUsed;
+static int         hashMask;
+static int         rehash;
+
+static AtomListPtr  *reverseMap;
+static int         reverseMapSize;
+static Atom        lastAtom;
+
+static int
+Hash(char *string, int len)
+{
+    int        h;
+
+    h = 0;
+    while (len--)
+       h = (h << 3) ^ *string++;
+    if (h < 0)
+       return -h;
+    return h;
+}
+
+static int
+ResizeHashTable (void)
+{
+    int                newHashSize;
+    int                newHashMask;
+    AtomListPtr        *newHashTable;
+    int                i;
+    int                h;
+    int                newRehash;
+    int                r;
+
+    if (hashSize == 0)
+       newHashSize = 1024;
+    else
+       newHashSize = hashSize * 2;
+    newHashTable = calloc (newHashSize, sizeof (AtomListPtr));
+    if (!newHashTable) {
+       fprintf(stderr, "ResizeHashTable(): Error: Couldn't allocate"
+               " newHashTable (%ld)\n",
+               newHashSize * (unsigned long)sizeof (AtomListPtr));
+       return FALSE;
+    }
+    newHashMask = newHashSize - 1;
+    newRehash = (newHashMask - 2);
+    for (i = 0; i < hashSize; i++)
+    {
+       if (hashTable[i])
+       {
+           h = (hashTable[i]->hash) & newHashMask;
+           if (newHashTable[h])
+           {
+               r = hashTable[i]->hash % newRehash | 1;
+               do {
+                   h += r;
+                   if (h >= newHashSize)
+                       h -= newHashSize;
+               } while (newHashTable[h]);
+           }
+           newHashTable[h] = hashTable[i];
+       }
+    }
+    free (hashTable);
+    hashTable = newHashTable;
+    hashSize = newHashSize;
+    hashMask = newHashMask;
+    rehash = newRehash;
+    return TRUE;
+}
+
+static int
+ResizeReverseMap (void)
+{
+    int ret = TRUE;
+    if (reverseMapSize == 0)
+       reverseMapSize = 1000;
+    else
+       reverseMapSize *= 2;
+    reverseMap = realloc (reverseMap, reverseMapSize * sizeof (AtomListPtr));
+    if (!reverseMap) {
+       fprintf(stderr, "ResizeReverseMap(): Error: Couldn't reallocate"
+               " reverseMap (%ld)\n",
+               reverseMapSize * (unsigned long)sizeof(AtomListPtr));
+       ret = FALSE;
+    }
+    return ret;
+}
+
+static int
+NameEqual (const char *a, const char *b, int l)
+{
+    while (l--)
+       if (*a++ != *b++)
+           return FALSE;
+    return TRUE;
+}
+
+#ifdef __SUNPRO_C
+#pragma weak MakeAtom
+#endif
+
+weak Atom 
+MakeAtom(char *string, unsigned len, int makeit)
+{
+    AtomListPtr        a;
+    int                hash;
+    int                h = 0;
+    int                r;
+
+    hash = Hash (string, len);
+    if (hashTable)
+    {
+       h = hash & hashMask;
+       if (hashTable[h])
+       {
+           if (hashTable[h]->hash == hash && hashTable[h]->len == len &&
+               NameEqual (hashTable[h]->name, string, len))
+           {
+               return hashTable[h]->atom;
+           }
+           r = (hash % rehash) | 1;
+           for (;;)
+           {
+               h += r;
+               if (h >= hashSize)
+                   h -= hashSize;
+               if (!hashTable[h])
+                   break;
+               if (hashTable[h]->hash == hash && hashTable[h]->len == len &&
+                   NameEqual (hashTable[h]->name, string, len))
+               {
+                   return hashTable[h]->atom;
+               }
+           }
+       }
+    }
+    if (!makeit)
+       return None;
+    a = malloc (sizeof (AtomListRec) + len + 1);
+    if (a == NULL) {
+       fprintf(stderr, "MakeAtom(): Error: Couldn't allocate AtomListRec"
+               " (%ld)\n", (unsigned long)sizeof (AtomListRec) + len + 1);
+       return None;
+    }
+    a->name = (char *) (a + 1);
+    a->len = len;
+    strncpy (a->name, string, len);
+    a->name[len] = '\0';
+    a->atom = ++lastAtom;
+    a->hash = hash;
+    if (hashUsed >= hashSize / 2)
+    {
+       ResizeHashTable ();
+       h = hash & hashMask;
+       if (hashTable[h])
+       {
+           r = (hash % rehash) | 1;
+           do {
+               h += r;
+               if (h >= hashSize)
+                   h -= hashSize;
+           } while (hashTable[h]);
+       }
+    }
+    hashTable[h] = a;
+    hashUsed++;
+    if (reverseMapSize <= a->atom) {
+       if (!ResizeReverseMap())
+           return None;
+    }
+    reverseMap[a->atom] = a;
+    return a->atom;
+}
+
+#ifdef __SUNPRO_C
+#pragma weak ValidAtom
+#endif
+
+weak int 
+ValidAtom(Atom atom)
+{
+    return (atom != None) && (atom <= lastAtom);
+}
+
+#ifdef __SUNPRO_C
+#pragma weak NameForAtom
+#endif
+
+weak char *
+NameForAtom(Atom atom)
+{
+    if (atom != None && atom <= lastAtom)
+       return reverseMap[atom]->name;
+    return NULL;
+}
diff --git a/src/util/fontaccel.c b/src/util/fontaccel.c
new file mode 100755 (executable)
index 0000000..c5915db
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+
+Copyright 1990, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+/*
+ * Author:  Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include    <X11/fonts/fontmisc.h>
+#include    <X11/fonts/fontstruct.h>
+#include    <X11/fonts/fontutil.h>
+
+void
+FontComputeInfoAccelerators(FontInfoPtr pFontInfo)
+{
+    pFontInfo->noOverlap = FALSE;
+    if (pFontInfo->maxOverlap <= pFontInfo->minbounds.leftSideBearing)
+       pFontInfo->noOverlap = TRUE;
+
+    if ((pFontInfo->minbounds.ascent == pFontInfo->maxbounds.ascent) &&
+           (pFontInfo->minbounds.descent == pFontInfo->maxbounds.descent) &&
+           (pFontInfo->minbounds.leftSideBearing ==
+            pFontInfo->maxbounds.leftSideBearing) &&
+           (pFontInfo->minbounds.rightSideBearing ==
+            pFontInfo->maxbounds.rightSideBearing) &&
+           (pFontInfo->minbounds.characterWidth ==
+            pFontInfo->maxbounds.characterWidth) &&
+      (pFontInfo->minbounds.attributes == pFontInfo->maxbounds.attributes)) {
+       pFontInfo->constantMetrics = TRUE;
+       if ((pFontInfo->maxbounds.leftSideBearing == 0) &&
+               (pFontInfo->maxbounds.rightSideBearing ==
+                pFontInfo->maxbounds.characterWidth) &&
+               (pFontInfo->maxbounds.ascent == pFontInfo->fontAscent) &&
+               (pFontInfo->maxbounds.descent == pFontInfo->fontDescent))
+           pFontInfo->terminalFont = TRUE;
+       else
+           pFontInfo->terminalFont = FALSE;
+    } else {
+       pFontInfo->constantMetrics = FALSE;
+       pFontInfo->terminalFont = FALSE;
+    }
+    if (pFontInfo->minbounds.characterWidth == pFontInfo->maxbounds.characterWidth)
+       pFontInfo->constantWidth = TRUE;
+    else
+       pFontInfo->constantWidth = FALSE;
+
+    if ((pFontInfo->minbounds.leftSideBearing >= 0) &&
+           (pFontInfo->maxOverlap <= 0) &&
+           (pFontInfo->minbounds.ascent >= -pFontInfo->fontDescent) &&
+           (pFontInfo->maxbounds.ascent <= pFontInfo->fontAscent) &&
+           (-pFontInfo->minbounds.descent <= pFontInfo->fontAscent) &&
+           (pFontInfo->maxbounds.descent <= pFontInfo->fontDescent))
+       pFontInfo->inkInside = TRUE;
+    else
+       pFontInfo->inkInside = FALSE;
+}
+
+int 
+FontCouldBeTerminal(FontInfoPtr pFontInfo)
+{
+    if ((pFontInfo->minbounds.leftSideBearing >= 0) &&
+           (pFontInfo->maxbounds.rightSideBearing <= pFontInfo->maxbounds.characterWidth) &&
+           (pFontInfo->minbounds.characterWidth == pFontInfo->maxbounds.characterWidth) &&
+           (pFontInfo->maxbounds.ascent <= pFontInfo->fontAscent) &&
+           (pFontInfo->maxbounds.descent <= pFontInfo->fontDescent) &&
+           (pFontInfo->maxbounds.leftSideBearing != 0 ||
+            pFontInfo->minbounds.rightSideBearing != pFontInfo->minbounds.characterWidth ||
+            pFontInfo->minbounds.ascent != pFontInfo->fontAscent ||
+            pFontInfo->minbounds.descent != pFontInfo->fontDescent)) {
+       /* blow off font with nothing but a SPACE */
+       if (pFontInfo->maxbounds.ascent == 0 && 
+           pFontInfo->maxbounds.descent == 0)
+               return FALSE;
+       return TRUE;
+    }
+    return FALSE;
+}
diff --git a/src/util/fontnames.c b/src/util/fontnames.c
new file mode 100755 (executable)
index 0000000..ceafce5
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+
+Copyright 1991, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+/*
+ * Author:  Keith Packard, MIT X Consortium
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include       <X11/fonts/fontmisc.h>
+#include       <X11/fonts/fontstruct.h>
+
+void
+FreeFontNames(FontNamesPtr pFN)
+{
+    int         i;
+
+    if (!pFN)
+       return;
+    for (i = 0; i < pFN->nnames; i++) {
+       free(pFN->names[i]);
+    }
+    free(pFN->names);
+    free(pFN->length);
+    free(pFN);
+}
+
+FontNamesPtr
+MakeFontNamesRecord(unsigned int size)
+{
+    FontNamesPtr pFN;
+
+    pFN = malloc(sizeof(FontNamesRec));
+    if (pFN) {
+       pFN->nnames = 0;
+       pFN->size = size;
+       if (size)
+       {
+           pFN->length = malloc(size * sizeof(int));
+           pFN->names = malloc(size * sizeof(char *));
+           if (!pFN->length || !pFN->names) {
+               free(pFN->length);
+               free(pFN->names);
+               free(pFN);
+               pFN = (FontNamesPtr) 0;
+           }
+       }
+       else
+       {
+           pFN->length = 0;
+           pFN->names = 0;
+       }
+    }
+    return pFN;
+}
+
+int
+AddFontNamesName(FontNamesPtr names, char *name, int length)
+{
+    int         index = names->nnames;
+    char       *nelt;
+
+    nelt = malloc(length + 1);
+    if (!nelt)
+       return AllocError;
+    if (index >= names->size) {
+       int         size = names->size << 1;
+       int        *nlength;
+       char      **nnames;
+
+       if (size == 0)
+           size = 8;
+       nlength = realloc(names->length, size * sizeof(int));
+       nnames = realloc(names->names, size * sizeof(char *));
+       if (nlength && nnames) {
+           names->size = size;
+           names->length = nlength;
+           names->names = nnames;
+       } else {
+           free(nelt);
+           free(nlength);
+           free(nnames);
+           return AllocError;
+       }
+    }
+    names->length[index] = length;
+    names->names[index] = nelt;
+    strncpy(nelt, name, length);
+    nelt[length] = '\0';
+    names->nnames++;
+    return Successful;
+}
diff --git a/src/util/fontutil.c b/src/util/fontutil.c
new file mode 100755 (executable)
index 0000000..22f6119
--- /dev/null
@@ -0,0 +1,410 @@
+/*
+
+Copyright 1991, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+/*
+ * Author:  Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include    <X11/fonts/fontmisc.h>
+#include    <X11/fonts/fontstruct.h>
+#include    <X11/fonts/FSproto.h>
+#include    <X11/fonts/fontutil.h>
+
+/* Define global here...  doesn't hurt the servers, and avoids
+   unresolved references in font clients.  */
+
+static int defaultGlyphCachingMode = DEFAULT_GLYPH_CACHING_MODE;
+int glyphCachingMode = DEFAULT_GLYPH_CACHING_MODE;
+
+void
+GetGlyphs(FontPtr font, 
+         unsigned long count, 
+         unsigned char *chars, 
+         FontEncoding fontEncoding, 
+         unsigned long *glyphcount,    /* RETURN */
+         CharInfoPtr *glyphs)          /* RETURN */
+{
+    (*font->get_glyphs) (font, count, chars, fontEncoding, glyphcount, glyphs);
+}
+
+#define MIN(a,b)    ((a)<(b)?(a):(b))
+#define MAX(a,b)    ((a)>(b)?(a):(b))
+
+void
+QueryGlyphExtents(FontPtr pFont, 
+                 CharInfoPtr *charinfo, 
+                 unsigned long count, 
+                 ExtentInfoRec *info)
+{
+    register unsigned long i;
+    xCharInfo  *pCI;
+
+    info->drawDirection = pFont->info.drawDirection;
+
+    info->fontAscent = pFont->info.fontAscent;
+    info->fontDescent = pFont->info.fontDescent;
+
+    if (count != 0) {
+
+       pCI = &((*charinfo)->metrics); charinfo++;
+       /* ignore nonexisting characters when calculating text extents */
+       if ( !((pCI->characterWidth == 0)
+              && (pCI->rightSideBearing == 0)
+              && (pCI->leftSideBearing == 0)
+              && (pCI->ascent == 0)
+              && (pCI->descent == 0)) ) {
+           info->overallAscent = pCI->ascent;
+           info->overallDescent = pCI->descent;
+           info->overallLeft = pCI->leftSideBearing;
+           info->overallRight = pCI->rightSideBearing;
+           info->overallWidth = pCI->characterWidth;
+       }
+
+       if (pFont->info.constantMetrics && pFont->info.noOverlap) {
+           info->overallWidth *= count;
+           info->overallRight += (info->overallWidth -
+                                  pCI->characterWidth);
+       } else {
+           for (i = 1; i < count; i++) {
+               pCI = &((*charinfo)->metrics); charinfo++;
+               /* ignore nonexisting characters when calculating extents */
+               if ( !((pCI->characterWidth == 0)
+                      && (pCI->rightSideBearing == 0)
+                      && (pCI->leftSideBearing == 0)
+                      && (pCI->ascent == 0)
+                      && (pCI->descent == 0)) ) {
+                   info->overallAscent = MAX(
+                                             info->overallAscent,
+                                             pCI->ascent);
+                   info->overallDescent = MAX(
+                                              info->overallDescent,
+                                              pCI->descent);
+                   info->overallLeft = MIN(
+                                           info->overallLeft,
+                                           info->overallWidth + pCI->leftSideBearing);
+                   info->overallRight = MAX(
+                                            info->overallRight,
+                                            info->overallWidth + pCI->rightSideBearing);
+                   /*
+                    * yes, this order is correct; overallWidth IS incremented
+                    * last
+                    */
+                   info->overallWidth += pCI->characterWidth;
+               }
+           }
+       }
+    } else {
+       info->overallAscent = 0;
+       info->overallDescent = 0;
+       info->overallWidth = 0;
+       info->overallLeft = 0;
+       info->overallRight = 0;
+    }
+}
+
+Bool
+QueryTextExtents(FontPtr pFont, 
+                unsigned long count, 
+                unsigned char *chars, 
+                ExtentInfoRec *info)
+{
+    xCharInfo     **charinfo;
+    unsigned long   n;
+    FontEncoding    encoding;
+    int             cm;
+    int             i;
+    unsigned long   t;
+    xCharInfo      *defaultChar = 0;
+    unsigned char   defc[2];
+    int             firstReal;
+
+    charinfo = malloc(count * sizeof(xCharInfo *));
+    if (!charinfo)
+       return FALSE;
+    encoding = TwoD16Bit;
+    if (pFont->info.lastRow == 0)
+       encoding = Linear16Bit;
+    (*pFont->get_metrics) (pFont, count, chars, encoding, &n, charinfo);
+
+    /* Do default character substitution as get_metrics doesn't */
+
+#define IsNonExistentChar(ci) (!(ci) || \
+                              ((ci)->ascent == 0 && \
+                              (ci)->descent == 0 && \
+                              (ci)->leftSideBearing == 0 && \
+                              (ci)->rightSideBearing == 0 && \
+                              (ci)->characterWidth == 0))
+
+    firstReal = n;
+    defc[0] = pFont->info.defaultCh >> 8;
+    defc[1] = pFont->info.defaultCh;
+    (*pFont->get_metrics) (pFont, 1, defc, encoding, &t, &defaultChar);
+    if ((IsNonExistentChar (defaultChar)))
+       defaultChar = 0;
+    for (i = 0; i < n; i++)
+    {
+       if ((IsNonExistentChar (charinfo[i])))
+       {
+           if (!defaultChar)
+               continue;
+           charinfo[i] = defaultChar;
+       }
+       if (firstReal == n)
+           firstReal = i;
+    }
+    cm = pFont->info.constantMetrics;
+    pFont->info.constantMetrics = FALSE;
+    QueryGlyphExtents(pFont, (CharInfoPtr*) charinfo + firstReal, 
+                     n - firstReal, info);
+    pFont->info.constantMetrics = cm;
+    free(charinfo);
+    return TRUE;
+}
+
+Bool
+ParseGlyphCachingMode(char *str)
+{
+    if (!strcmp(str, "none")) defaultGlyphCachingMode = CACHING_OFF;
+    else if (!strcmp(str, "all")) defaultGlyphCachingMode = CACHE_ALL_GLYPHS;
+    else if (!strcmp(str, "16")) defaultGlyphCachingMode = CACHE_16_BIT_GLYPHS;
+    else return FALSE;
+    return TRUE;
+}
+
+void
+InitGlyphCaching(void)
+{
+    /* Set glyphCachingMode to the mode the server hopes to
+       support.  DDX drivers that do not support the requested level
+       of glyph caching can call SetGlyphCachingMode to lower the
+       level of support.
+     */
+
+    glyphCachingMode = defaultGlyphCachingMode;
+}
+
+/* ddxen can call SetGlyphCachingMode to inform us of what level of glyph
+ * caching they can support.
+ */
+void
+SetGlyphCachingMode(int newmode)
+{
+    if ( (glyphCachingMode > newmode) && (newmode >= 0) )
+       glyphCachingMode = newmode;
+}
+
+#define range_alloc_granularity 16
+#define mincharp(p) ((p)->min_char_low + ((p)->min_char_high << 8))
+#define maxcharp(p) ((p)->max_char_low + ((p)->max_char_high << 8))
+
+/* add_range(): Add range to a list of ranges, with coalescence */
+int
+add_range(fsRange *newrange, 
+         int *nranges, 
+         fsRange **range, 
+         Bool charset_subset)
+{
+    int first, last, middle;
+    unsigned long keymin, keymax;
+    unsigned long ptrmin = 0, ptrmax = 0;
+    fsRange *ptr = NULL, *ptr1, *ptr2, *endptr;
+
+    /* There are two different ways to treat ranges:
+
+       1) Charset subsetting (support of the HP XLFD enhancements), in
+         which a range of 0x1234,0x3456 means all numbers between
+         0x1234 and 0x3456, and in which min and max might be swapped.
+
+       2) Row/column ranges, in which a range of 0x1234,0x3456 means the
+         ranges 0x1234-0x1256, 0x1334-0x1356, ...  , 0x3434-0x3456.
+         This is for support of glyph caching.
+
+       The choice of treatment is selected with the "charset_subset"
+       flag */
+
+    /* If newrange covers multiple rows; break up the rows */
+    if (!charset_subset && newrange->min_char_high != newrange->max_char_high)
+    {
+       int i, err = 0;
+       fsRange temprange;
+       for (i = newrange->min_char_high;
+            i <= newrange->max_char_high;
+            i++)
+       {
+           temprange.min_char_low = newrange->min_char_low;
+           temprange.max_char_low = newrange->max_char_low;
+           temprange.min_char_high = temprange.max_char_high = i;
+           err = add_range(&temprange, nranges, range, charset_subset);
+           if (err != Successful) break;
+       }
+       return err;
+    }
+
+    keymin = mincharp(newrange);
+    keymax = maxcharp(newrange);
+
+    if (charset_subset && keymin > keymax)
+    {
+       unsigned long temp = keymin;
+       keymin = keymax;
+       keymax = temp;
+    }
+
+    /* add_range() maintains a sorted list; this makes possible coalescence
+       and binary searches */
+
+    /* Binary search for a range with which the new range can merge */
+
+    first = middle = 0;
+    last = *nranges - 1;
+    while (last >= first)
+    {
+       middle = (first + last) / 2;
+       ptr = (*range) + middle;
+       ptrmin = mincharp(ptr);
+       ptrmax = maxcharp(ptr);
+
+       if (ptrmin > 0 && keymax < ptrmin - 1) last = middle - 1;
+       else if (keymin > ptrmax + 1) first = middle + 1;
+       else if (!charset_subset)
+       {
+           /* We might have a range with which to merge... IF the
+              result doesn't cross rows */
+           if (newrange->min_char_high != ptr->min_char_high)
+               last = first - 1;       /* Force adding a new range */
+           break;
+       }
+       else break;     /* We have at least one range with which we can merge */
+    }
+
+    if (last < first)
+    {
+       /* Search failed; we need to add a new range to the list. */
+
+       /* Grow the list if necessary */
+       if (*nranges == 0 || *range == (fsRange *)0)
+       {
+           *range = malloc(range_alloc_granularity * SIZEOF(fsRange));
+           *nranges = 0;
+       }
+       else if (!(*nranges % range_alloc_granularity))
+       {
+           *range = realloc(*range, (*nranges + range_alloc_granularity) *
+                                     SIZEOF(fsRange));
+       }
+
+       /* If alloc failed, just return a null list */
+       if (*range == (fsRange *)0)
+       {
+           *nranges = 0;
+           return AllocError;
+       }
+
+       /* Should new entry go *at* or *after* ptr? */
+       ptr = (*range) + middle;
+       if (middle < *nranges && keymin > ptrmin) ptr++;        /* after */
+
+       /* Open up a space for our new range */
+       memmove((char *)(ptr + 1),
+               (char *)ptr,
+               (char *)(*range + *nranges) - (char *)ptr);
+
+       /* Insert the new range */
+       ptr->min_char_low = keymin & 0xff;
+       ptr->min_char_high = keymin >> 8;
+       ptr->max_char_low = keymax & 0xff;
+       ptr->max_char_high = keymax >> 8;
+
+       /* Update range count */
+       (*nranges)++;
+
+       /* Done */
+       return Successful;
+    }
+
+    /* Join our new range to that pointed to by "ptr" */
+    if (keymin < ptrmin)
+    {
+       ptr->min_char_low = keymin & 0xff;
+       ptr->min_char_high = keymin >> 8;
+    }
+    if (keymax > ptrmax)
+    {
+       ptr->max_char_low = keymax & 0xff;
+       ptr->max_char_high = keymax >> 8;
+    }
+
+    ptrmin = mincharp(ptr);
+    ptrmax = maxcharp(ptr);
+
+    endptr = *range + *nranges;
+
+    for (ptr1 = ptr; ptr1 >= *range; ptr1--)
+    {
+       if (ptrmin <= maxcharp(ptr1) + 1)
+       {
+           if (!charset_subset && ptr->min_char_high != ptr1->min_char_high)
+               break;
+           if (ptrmin >= mincharp(ptr1))
+               ptrmin = mincharp(ptr1);
+       }
+       else break;
+    }
+    for (ptr2 = ptr; ptr2 < endptr; ptr2++)
+    {
+       if ((ptr2->min_char_low == 0 && ptr2->min_char_high == 0) ||
+           ptrmax >= mincharp(ptr2) - 1)
+       {
+           if (!charset_subset && ptr->min_char_high != ptr2->min_char_high)
+               break;
+           if (ptrmax <= maxcharp(ptr2))
+               ptrmax = maxcharp(ptr2);
+       }
+       else break;
+    }
+
+    /* We need to coalesce ranges between ptr1 and ptr2 exclusive */
+    ptr1++;
+    ptr2--;
+    if (ptr1 != ptr2)
+    {
+       memmove(ptr1, ptr2, (char *)endptr - (char *)ptr2);
+       *nranges -= (ptr2 - ptr1);
+    }
+
+    /* Write the new range into the range list */
+    ptr1->min_char_low = ptrmin & 0xff;
+    ptr1->min_char_high = ptrmin >> 8;
+    ptr1->max_char_low = ptrmax & 0xff;
+    ptr1->max_char_high = ptrmax >> 8;
+
+    return Successful;
+}
diff --git a/src/util/fontxlfd.c b/src/util/fontxlfd.c
new file mode 100755 (executable)
index 0000000..8124037
--- /dev/null
@@ -0,0 +1,632 @@
+/*
+
+Copyright 1990, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+/*
+ * Author:  Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include       <X11/fonts/fontmisc.h>
+#include       <X11/fonts/fontstruct.h>
+#include       <X11/fonts/fontxlfd.h>
+#include       <X11/fonts/fontutil.h>
+#include       <X11/Xos.h>
+#include       <math.h>
+#include       <stdlib.h>
+#if defined(sony) && !defined(SYSTYPE_SYSV) && !defined(_SYSTYPE_SYSV)
+#define NO_LOCALE
+#endif
+#ifndef NO_LOCALE
+#include       <locale.h>
+#endif
+#include       <ctype.h>
+#include       <stdio.h>       /* for sprintf() */
+
+static char *
+GetInt(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;
+}
+
+#define minchar(p) ((p).min_char_low + ((p).min_char_high << 8))
+#define maxchar(p) ((p).max_char_low + ((p).max_char_high << 8))
+
+
+#ifndef NO_LOCALE
+static struct lconv *locale = 0;
+#endif
+static char *radix = ".", *plus = "+", *minus = "-";
+
+static char *
+readreal(char *ptr, double *result)
+{
+    char buffer[80], *p1, *p2;
+
+#ifndef NO_LOCALE
+    /* Figure out what symbols apply in this locale */
+
+    if (!locale)
+    {
+       locale = localeconv();
+       if (locale->decimal_point && *locale->decimal_point)
+           radix = locale->decimal_point;
+       if (locale->positive_sign && *locale->positive_sign)
+           plus = locale->positive_sign;
+       if (locale->negative_sign && *locale->negative_sign)
+           minus = locale->negative_sign;
+    }
+#endif
+    /* Copy the first 80 chars of ptr into our local buffer, changing
+       symbols as needed. */
+    for (p1 = ptr, p2 = buffer;
+        *p1 && (p2 - buffer) < sizeof(buffer) - 1;
+        p1++, p2++)
+    {
+       switch(*p1)
+       {
+           case '~': *p2 = *minus; break;
+           case '+': *p2 = *plus; break;
+           case '.': *p2 = *radix; break;
+           default: *p2 = *p1;
+       }
+    }
+    *p2 = 0;
+
+    /* Now we have something that strtod() can interpret... do it. */
+    *result = strtod(buffer, &p1);
+    /* Return NULL if failure, pointer past number if success */
+    return (p1 == buffer) ? (char *)0 : (ptr + (p1 - buffer));
+}
+
+static char *
+xlfd_double_to_text(double value, char *buffer, int space_required)
+{
+    char formatbuf[40];
+    register char *p1;
+    int ndigits, exponent;
+
+#ifndef NO_LOCALE
+    if (!locale)
+    {
+       locale = localeconv();
+       if (locale->decimal_point && *locale->decimal_point)
+           radix = locale->decimal_point;
+       if (locale->positive_sign && *locale->positive_sign)
+           plus = locale->positive_sign;
+       if (locale->negative_sign && *locale->negative_sign)
+           minus = locale->negative_sign;
+    }
+#endif
+    /* Compute a format to use to render the number */
+    sprintf(formatbuf, "%%.%dle", XLFD_NDIGITS);
+
+    if (space_required)
+       *buffer++ = ' ';
+
+    /* Render the number using printf's idea of formatting */
+    sprintf(buffer, formatbuf, value);
+
+    /* Find and read the exponent value */
+    for (p1 = buffer + strlen(buffer);
+       *p1-- != 'e' && p1[1] != 'E';);
+    exponent = atoi(p1 + 2);
+    if (value == 0.0) exponent = 0;
+
+    /* Figure out how many digits are significant */
+    while (p1 >= buffer && (!isdigit(*p1) || *p1 == '0')) p1--;
+    ndigits = 0;
+    while (p1 >= buffer) if (isdigit(*p1--)) ndigits++;
+
+    /* Figure out notation to use */
+    if (exponent >= XLFD_NDIGITS || ndigits - exponent > XLFD_NDIGITS + 1)
+    {
+       /* Scientific */
+       sprintf(formatbuf, "%%.%dle", ndigits - 1);
+       sprintf(buffer, formatbuf, value);
+    }
+    else
+    {
+       /* Fixed */
+       ndigits -= exponent + 1;
+       if (ndigits < 0) ndigits = 0;
+       sprintf(formatbuf, "%%.%dlf", ndigits);
+       sprintf(buffer, formatbuf, value);
+       if (exponent < 0)
+       {
+           p1 = buffer;
+           while (*p1 && *p1 != '0') p1++;
+           while (*p1++) p1[-1] = *p1;
+       }
+    }
+
+    /* Last step, convert the locale-specific sign and radix characters
+       to our own. */
+    for (p1 = buffer; *p1; p1++)
+    {
+       if (*p1 == *minus) *p1 = '~';
+       else if (*p1 == *plus) *p1 = '+';
+       else if (*p1 == *radix) *p1 = '.';
+    }
+
+    return buffer - space_required;
+}
+
+double
+xlfd_round_double(double x)
+{
+   /* Utility for XLFD users to round numbers to XLFD_NDIGITS
+      significant digits.  How do you round to n significant digits on
+      a binary machine?  */
+
+#if defined(i386) || defined(__i386__) || \
+    defined(ia64) || defined(__ia64__) || \
+    defined(__alpha__) || defined(__alpha) || \
+    defined(__hppa__) || \
+    defined(__amd64__) || defined(__amd64) || \
+    defined(sgi)
+#include <float.h>
+
+/* if we have IEEE 754 fp, we can round to binary digits... */
+
+#if (FLT_RADIX == 2) && (DBL_DIG == 15) && (DBL_MANT_DIG == 53)
+
+#ifndef M_LN2
+#define M_LN2       0.69314718055994530942
+#endif
+#ifndef M_LN10
+#define M_LN10      2.30258509299404568402
+#endif
+
+/* convert # of decimal digits to # of binary digits */
+#define XLFD_NDIGITS_2 ((int)(XLFD_NDIGITS * M_LN10 / M_LN2 + 0.5))
+
+   union conv_d {
+      double d;
+      unsigned char b[8];
+   } d;
+   int i,j,k,d_exp;
+
+   if (x == 0)
+      return x;
+
+   /* do minor sanity check for IEEE 754 fp and correct byte order */
+   d.d = 1.0;
+   if (sizeof(double) == 8 && d.b[7] == 0x3f && d.b[6] == 0xf0) {
+
+      /*
+       * this code will round IEEE 754 double to XLFD_NDIGITS_2 binary digits
+       */
+
+      d.d = x;
+      d_exp = (d.b[7] << 4) | (d.b[6] >> 4);
+
+      i = (DBL_MANT_DIG-XLFD_NDIGITS_2) >> 3;
+      j = 1 << ((DBL_MANT_DIG-XLFD_NDIGITS_2) & 0x07);
+      for (; i<7; i++) {
+        k = d.b[i] + j;
+        d.b[i] = k;
+        if (k & 0x100) j = 1;
+        else break;
+      }
+      if ((i==7) && ((d.b[6] & 0xf0) != ((d_exp<<4) & 0xf0))) {
+        /* mantissa overflow: increment exponent */
+        d_exp = (d_exp & 0x800 ) | ((d_exp & 0x7ff) + 1);
+        d.b[7] = d_exp >> 4;
+        d.b[6] = (d.b[6] & 0x0f) | (d_exp << 4);
+      }
+
+      i = (DBL_MANT_DIG-XLFD_NDIGITS_2) >> 3;
+      j = 1 << ((DBL_MANT_DIG-XLFD_NDIGITS_2) & 0x07);
+      d.b[i] &= ~(j-1);
+      for (;--i>=0;) d.b[i] = 0;
+
+      return d.d;
+   }
+   else
+#endif
+#endif /* i386 || __i386__ */
+    {
+       /*
+        * If not IEEE 754:  Let printf() do it for you.
+        */
+
+       char formatbuf[40], buffer[40];
+
+       sprintf(formatbuf, "%%.%dlg", XLFD_NDIGITS);
+       sprintf(buffer, formatbuf, x);
+       return atof(buffer);
+    }
+}
+
+static char *
+GetMatrix(char *ptr, FontScalablePtr vals, int which)
+{
+    double *matrix;
+
+    if (which == PIXELSIZE_MASK)
+       matrix = vals->pixel_matrix;
+    else if (which == POINTSIZE_MASK)
+       matrix = vals->point_matrix;
+    else return (char *)0;
+
+    while (isspace(*ptr)) ptr++;
+    if (*ptr == '[')
+    {
+       /* This is a matrix containing real numbers.  It would be nice
+          to use strtod() or sscanf() to read the numbers, but those
+          don't handle '~' for minus and we cannot force them to use a
+          "."  for the radix.  We'll have to do the hard work ourselves
+          (in readreal()).  */
+
+       if ((ptr = readreal(++ptr, matrix + 0)) &&
+           (ptr = readreal(ptr, matrix + 1)) &&
+           (ptr = readreal(ptr, matrix + 2)) &&
+           (ptr = readreal(ptr, matrix + 3)))
+       {
+           while (isspace(*ptr)) ptr++;
+           if (*ptr != ']')
+               ptr = (char *)0;
+           else
+           {
+               ptr++;
+               while (isspace(*ptr)) ptr++;
+               if (*ptr == '-')
+               {
+                   if (which == POINTSIZE_MASK)
+                       vals->values_supplied |= POINTSIZE_ARRAY;
+                   else
+                       vals->values_supplied |= PIXELSIZE_ARRAY;
+               }
+               else ptr = (char *)0;
+           }
+       }
+    }
+    else
+    {
+       int value;
+       if ((ptr = GetInt(ptr, &value)))
+       {
+           vals->values_supplied &= ~which;
+           if (value > 0)
+           {
+               matrix[3] = (double)value;
+               if (which == POINTSIZE_MASK)
+               {
+                   matrix[3] /= 10.0;
+                   vals->values_supplied |= POINTSIZE_SCALAR;
+               }
+               else
+                   vals->values_supplied |= PIXELSIZE_SCALAR;
+               /* If we're concocting the pixelsize array from a scalar,
+                  we will need to normalize element 0 for the pixel shape.
+                  This is done in FontFileCompleteXLFD(). */
+               matrix[0] = matrix[3];
+               matrix[1] = matrix[2] = 0.0;
+           }
+           else if (value < 0)
+           {
+               if (which == POINTSIZE_MASK)
+                   vals->values_supplied |= POINTSIZE_WILDCARD;
+               else
+                   vals->values_supplied |= PIXELSIZE_WILDCARD;
+           }
+       }
+    }
+    return ptr;
+}
+
+
+static void
+append_ranges(char *fname, int nranges, fsRange *ranges)
+{
+    if (nranges)
+    {
+        int i;
+
+        strcat(fname, "[");
+        for (i = 0; i < nranges && strlen(fname) < 1010; i++)
+        {
+           if (i) strcat(fname, " ");
+           sprintf(fname + strlen(fname), "%d",
+                   minchar(ranges[i]));
+           if (ranges[i].min_char_low ==
+               ranges[i].max_char_low &&
+               ranges[i].min_char_high ==
+               ranges[i].max_char_high) continue;
+           sprintf(fname + strlen(fname), "_%d",
+                   maxchar(ranges[i]));
+        }
+        strcat(fname, "]");
+    }
+}
+
+Bool
+FontParseXLFDName(char *fname, FontScalablePtr vals, int subst)
+{
+    register char *ptr;
+    register char *ptr1,
+               *ptr2,
+               *ptr3,
+               *ptr4;
+    register char *ptr5;
+    FontScalableRec tmpvals;
+    char        replaceChar = '0';
+    char        tmpBuf[1024];
+    int         spacingLen;
+    int                l;
+    char       *p;
+
+    bzero(&tmpvals, sizeof(tmpvals));
+    if (subst != FONT_XLFD_REPLACE_VALUE)
+       *vals = tmpvals;
+
+    if (!(*(ptr = fname) == '-' || (*ptr++ == '*' && *ptr == '-')) ||  /* fndry */
+           !(ptr = strchr(ptr + 1, '-')) ||    /* family_name */
+           !(ptr1 = ptr = strchr(ptr + 1, '-')) ||     /* weight_name */
+           !(ptr = strchr(ptr + 1, '-')) ||    /* slant */
+           !(ptr = strchr(ptr + 1, '-')) ||    /* setwidth_name */
+           !(ptr = strchr(ptr + 1, '-')) ||    /* add_style_name */
+           !(ptr = strchr(ptr + 1, '-')) ||    /* pixel_size */
+           !(ptr = GetMatrix(ptr + 1, &tmpvals, PIXELSIZE_MASK)) ||
+           !(ptr2 = ptr = GetMatrix(ptr + 1, &tmpvals, POINTSIZE_MASK)) ||
+           !(ptr = GetInt(ptr + 1, &tmpvals.x)) ||     /* resolution_x */
+           !(ptr3 = ptr = GetInt(ptr + 1, &tmpvals.y)) ||  /* resolution_y */
+           !(ptr4 = ptr = strchr(ptr + 1, '-')) ||     /* spacing */
+           !(ptr5 = ptr = GetInt(ptr + 1, &tmpvals.width)) || /* average_width */
+           !(ptr = strchr(ptr + 1, '-')) ||    /* charset_registry */
+           strchr(ptr + 1, '-'))/* charset_encoding */
+       return FALSE;
+
+    /* Lop off HP charset subsetting enhancement.  Interpreting this
+       field requires allocating some space in which to return the
+       results.  So, to prevent memory leaks, this procedure will simply
+       lop off and ignore charset subsetting, and initialize the
+       relevant vals fields to zero.  It's up to the caller to make its
+       own call to FontParseRanges() if it's interested in the charset
+       subsetting.  */
+
+    if (subst != FONT_XLFD_REPLACE_NONE &&
+       (p = strchr(strrchr(fname, '-'), '[')))
+    {
+       tmpvals.values_supplied |= CHARSUBSET_SPECIFIED;
+       *p = '\0';
+    }
+
+    /* Fill in deprecated fields for the benefit of rasterizers that care
+       about them. */
+    tmpvals.pixel = (tmpvals.pixel_matrix[3] >= 0) ?
+                   (int)(tmpvals.pixel_matrix[3] + .5) :
+                   (int)(tmpvals.pixel_matrix[3] - .5);
+    tmpvals.point = (tmpvals.point_matrix[3] >= 0) ?
+                    (int)(tmpvals.point_matrix[3] * 10 + .5) :
+                    (int)(tmpvals.point_matrix[3] * 10 - .5);
+
+    spacingLen = ptr4 - ptr3 + 1;
+
+    switch (subst) {
+    case FONT_XLFD_REPLACE_NONE:
+       *vals = tmpvals;
+       break;
+    case FONT_XLFD_REPLACE_STAR:
+       replaceChar = '*';
+    case FONT_XLFD_REPLACE_ZERO:
+       strcpy(tmpBuf, ptr2);
+       ptr5 = tmpBuf + (ptr5 - ptr2);
+       ptr3 = tmpBuf + (ptr3 - ptr2);
+       ptr2 = tmpBuf;
+       ptr = ptr1 + 1;
+
+       ptr = strchr(ptr, '-') + 1;             /* skip weight */
+       ptr = strchr(ptr, '-') + 1;             /* skip slant */
+       ptr = strchr(ptr, '-') + 1;             /* skip setwidth_name */
+       ptr = strchr(ptr, '-') + 1;             /* skip add_style_name */
+
+       if ((ptr - fname) + spacingLen + strlen(ptr5) + 10 >= (unsigned)1024)
+           return FALSE;
+       *ptr++ = replaceChar;
+       *ptr++ = '-';
+       *ptr++ = replaceChar;
+       *ptr++ = '-';
+       *ptr++ = '*';
+       *ptr++ = '-';
+       *ptr++ = '*';
+       if (spacingLen > 2)
+       {
+           memmove(ptr, ptr3, spacingLen);
+           ptr += spacingLen;
+       }
+       else
+       {
+           *ptr++ = '-';
+           *ptr++ = '*';
+           *ptr++ = '-';
+       }
+       *ptr++ = replaceChar;
+       strcpy(ptr, ptr5);
+       *vals = tmpvals;
+       break;
+    case FONT_XLFD_REPLACE_VALUE:
+       if (vals->values_supplied & PIXELSIZE_MASK)
+       {
+           tmpvals.values_supplied =
+               (tmpvals.values_supplied & ~PIXELSIZE_MASK) |
+               (vals->values_supplied & PIXELSIZE_MASK);
+           tmpvals.pixel_matrix[0] = vals->pixel_matrix[0];
+           tmpvals.pixel_matrix[1] = vals->pixel_matrix[1];
+           tmpvals.pixel_matrix[2] = vals->pixel_matrix[2];
+           tmpvals.pixel_matrix[3] = vals->pixel_matrix[3];
+       }
+       if (vals->values_supplied & POINTSIZE_MASK)
+       {
+           tmpvals.values_supplied =
+               (tmpvals.values_supplied & ~POINTSIZE_MASK) |
+               (vals->values_supplied & POINTSIZE_MASK);
+           tmpvals.point_matrix[0] = vals->point_matrix[0];
+           tmpvals.point_matrix[1] = vals->point_matrix[1];
+           tmpvals.point_matrix[2] = vals->point_matrix[2];
+           tmpvals.point_matrix[3] = vals->point_matrix[3];
+       }
+       if (vals->x >= 0)
+           tmpvals.x = vals->x;
+       if (vals->y >= 0)
+           tmpvals.y = vals->y;
+       if (vals->width >= 0)
+           tmpvals.width = vals->width;
+       else if (vals->width < -1)      /* overload: -1 means wildcard */
+           tmpvals.width = -vals->width;
+
+
+       p = ptr1 + 1;                           /* weight field */
+       l = strchr(p, '-') - p;
+       sprintf(tmpBuf, "%*.*s", l, l, p);
+
+       p += l + 1;                             /* slant field */
+       l = strchr(p, '-') - p;
+       sprintf(tmpBuf + strlen(tmpBuf), "-%*.*s", l, l, p);
+
+       p += l + 1;                             /* setwidth_name */
+       l = strchr(p, '-') - p;
+       sprintf(tmpBuf + strlen(tmpBuf), "-%*.*s", l, l, p);
+
+       p += l + 1;                             /* add_style_name field */
+       l = strchr(p, '-') - p;
+       sprintf(tmpBuf + strlen(tmpBuf), "-%*.*s", l, l, p);
+
+       strcat(tmpBuf, "-");
+       if ((tmpvals.values_supplied & PIXELSIZE_MASK) == PIXELSIZE_ARRAY)
+       {
+           char buffer[80];
+           strcat(tmpBuf, "[");
+           strcat(tmpBuf, xlfd_double_to_text(tmpvals.pixel_matrix[0],
+                  buffer, 0));
+           strcat(tmpBuf, xlfd_double_to_text(tmpvals.pixel_matrix[1],
+                  buffer, 1));
+           strcat(tmpBuf, xlfd_double_to_text(tmpvals.pixel_matrix[2],
+                  buffer, 1));
+           strcat(tmpBuf, xlfd_double_to_text(tmpvals.pixel_matrix[3],
+                  buffer, 1));
+           strcat(tmpBuf, "]");
+       }
+       else
+       {
+           sprintf(tmpBuf + strlen(tmpBuf), "%d",
+                   (int)(tmpvals.pixel_matrix[3] + .5));
+       }
+       strcat(tmpBuf, "-");
+       if ((tmpvals.values_supplied & POINTSIZE_MASK) == POINTSIZE_ARRAY)
+       {
+           char buffer[80];
+           strcat(tmpBuf, "[");
+           strcat(tmpBuf, xlfd_double_to_text(tmpvals.point_matrix[0],
+                  buffer, 0));
+           strcat(tmpBuf, xlfd_double_to_text(tmpvals.point_matrix[1],
+                  buffer, 1));
+           strcat(tmpBuf, xlfd_double_to_text(tmpvals.point_matrix[2],
+                  buffer, 1));
+           strcat(tmpBuf, xlfd_double_to_text(tmpvals.point_matrix[3],
+                  buffer, 1));
+           strcat(tmpBuf, "]");
+       }
+       else
+       {
+           sprintf(tmpBuf + strlen(tmpBuf), "%d",
+                   (int)(tmpvals.point_matrix[3] * 10.0 + .5));
+       }
+       sprintf(tmpBuf + strlen(tmpBuf), "-%d-%d%*.*s%d%s",
+               tmpvals.x, tmpvals.y,
+               spacingLen, spacingLen, ptr3, tmpvals.width, ptr5);
+       strcpy(ptr1 + 1, tmpBuf);
+       if ((vals->values_supplied & CHARSUBSET_SPECIFIED) && !vals->nranges)
+           strcat(fname, "[]");
+       else
+           append_ranges(fname, vals->nranges, vals->ranges);
+       break;
+    }
+    return TRUE;
+}
+
+fsRange *FontParseRanges(char *name, int *nranges)
+{
+    int n;
+    unsigned long l;
+    char *p1, *p2;
+    fsRange *result = (fsRange *)0;
+
+    name = strchr(name, '-');
+    for (n = 1; name && n < 14; n++)
+       name = strchr(name + 1, '-');
+
+    *nranges = 0;
+    if (!name || !(p1 = strchr(name, '['))) return (fsRange *)0;
+    p1++;
+
+    while (*p1 && *p1 != ']')
+    {
+       fsRange thisrange;
+
+       l = strtol(p1, &p2, 0);
+       if (p2 == p1 || l > 0xffff) break;
+       thisrange.max_char_low = thisrange.min_char_low = l & 0xff;
+       thisrange.max_char_high = thisrange.min_char_high = l >> 8;
+
+       p1 = p2;
+       if (*p1 == ']' || *p1 == ' ')
+       {
+           while (*p1 == ' ') p1++;
+           if (add_range(&thisrange, nranges, &result, TRUE) != Successful)
+               break;
+       }
+       else if (*p1 == '_')
+       {
+           l = strtol(++p1, &p2, 0);
+           if (p2 == p1 || l > 0xffff) break;
+           thisrange.max_char_low = l & 0xff;
+           thisrange.max_char_high = l >> 8;
+           p1 = p2;
+           if (*p1 == ']' || *p1 == ' ')
+           {
+               while (*p1 == ' ') p1++;
+               if (add_range(&thisrange, nranges, &result, TRUE) != Successful)
+                   break;
+           }
+       }
+       else break;
+    }
+
+    return result;
+}
diff --git a/src/util/format.c b/src/util/format.c
new file mode 100755 (executable)
index 0000000..f5424fe
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * 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 names of Network Computing Devices or Digital 
+ * not be used in advertising or publicity pertaining to distribution of the 
+ * software without specific, written prior permission. Network Computing 
+ * Devices and Digital make no representations about the suitability of 
+ * this software for any purpose.  It is provided "as is" without express 
+ * or implied warranty.
+ *
+ * NETWORK COMPUTING DEVICES AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES OR DIGITAL 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.
+ */
+
+/*
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include       <X11/fonts/FSproto.h>
+#include       <X11/fonts/font.h>
+#include       <X11/fonts/fontstruct.h>
+#include       <X11/fonts/fontutil.h>
+
+int
+CheckFSFormat(fsBitmapFormat format, 
+             fsBitmapFormatMask fmask, 
+             int *bit_order, 
+             int *byte_order, 
+             int *scan, 
+             int *glyph, 
+             int *image)
+{
+    /* convert format to what the low levels want */
+    if (fmask & BitmapFormatMaskBit) {
+       *bit_order = format & BitmapFormatBitOrderMask;
+       *bit_order = (*bit_order == BitmapFormatBitOrderMSB)
+                    ? MSBFirst : LSBFirst;
+    }
+    if (fmask & BitmapFormatMaskByte) {
+       *byte_order = format & BitmapFormatByteOrderMask;
+       *byte_order = (*byte_order == BitmapFormatByteOrderMSB)
+                     ? MSBFirst : LSBFirst;
+    }
+    if (fmask & BitmapFormatMaskScanLineUnit) {
+       *scan = format & BitmapFormatScanlineUnitMask;
+       /* convert byte paddings into byte counts */
+       switch (*scan) {
+       case BitmapFormatScanlineUnit8:
+           *scan = 1;
+           break;
+       case BitmapFormatScanlineUnit16:
+           *scan = 2;
+           break;
+       case BitmapFormatScanlineUnit32:
+           *scan = 4;
+           break;
+       default:
+           return BadFontFormat;
+       }
+    }
+    if (fmask & BitmapFormatMaskScanLinePad) {
+       *glyph = format & BitmapFormatScanlinePadMask;
+       /* convert byte paddings into byte counts */
+       switch (*glyph) {
+       case BitmapFormatScanlinePad8:
+           *glyph = 1;
+           break;
+       case BitmapFormatScanlinePad16:
+           *glyph = 2;
+           break;
+       case BitmapFormatScanlinePad32:
+           *glyph = 4;
+           break;
+       default:
+           return BadFontFormat;
+       }
+    }
+    if (fmask & BitmapFormatMaskImageRectangle) {
+       *image = format & BitmapFormatImageRectMask;
+
+       if (*image != BitmapFormatImageRectMin &&
+               *image != BitmapFormatImageRectMaxWidth &&
+               *image != BitmapFormatImageRectMax)
+           return BadFontFormat;
+    }
+    return Successful;
+}
diff --git a/src/util/miscutil.c b/src/util/miscutil.c
new file mode 100755 (executable)
index 0000000..7173d36
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+
+Copyright 1991, 1994, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/Xosdefs.h>
+#include <stdlib.h>
+#include <X11/fonts/fontmisc.h>
+#include "stubs.h"
+
+#define XK_LATIN1
+#include    <X11/keysymdef.h>
+
+
+#ifdef __SUNPRO_C
+#pragma weak serverGeneration
+#pragma weak register_fpe_functions
+#endif
+
+extern void BuiltinRegisterFpeFunctions(void);
+
+#ifndef NO_WEAK_SYMBOLS
+/* make sure everything initializes themselves at least once */
+weak long serverGeneration = 1;
+#endif
+
+weak void
+register_fpe_functions (void)
+{
+    BuiltinRegisterFpeFunctions();
+    FontFileRegisterFpeFunctions();
+#ifdef XFONT_FC
+    fs_register_fpe_functions();
+#endif
+}
diff --git a/src/util/patcache.c b/src/util/patcache.c
new file mode 100755 (executable)
index 0000000..548105a
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+
+Copyright 1991, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+/*
+ * Author:  Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include    <X11/fonts/fontmisc.h>
+#include    <X11/fonts/fontstruct.h>
+
+/*
+ * Static sized hash table for looking up font name patterns
+ *
+ * LRU entries, reusing old entries
+ */
+
+#define NBUCKETS       16
+#define NENTRIES       64
+
+#define UNSET          (NENTRIES+1)
+
+typedef unsigned char  EntryPtr;
+
+typedef struct _FontPatternCacheEntry {
+    struct _FontPatternCacheEntry   *next, **prev;
+    short                          patlen;
+    char                           *pattern;
+    int                                    hash;
+    FontPtr                        pFont;      /* associated font */
+} FontPatternCacheEntryRec, *FontPatternCacheEntryPtr;
+
+typedef struct _FontPatternCache {
+    FontPatternCacheEntryPtr   buckets[NBUCKETS];
+    FontPatternCacheEntryRec   entries[NENTRIES];
+    FontPatternCacheEntryPtr   free;
+} FontPatternCacheRec;
+
+/* Empty cache (for rehash) */
+void
+EmptyFontPatternCache (FontPatternCachePtr cache)
+{
+    int            i;
+    
+    for (i = 0; i < NBUCKETS; i++)
+       cache->buckets[i] = 0;
+    for (i = 0; i < NENTRIES; i++)
+    {
+       cache->entries[i].next = &cache->entries[i+1];
+       cache->entries[i].prev = 0;
+       cache->entries[i].pFont = 0;
+       free (cache->entries[i].pattern);
+       cache->entries[i].pattern = 0;
+       cache->entries[i].patlen = 0;
+    }
+    cache->free = &cache->entries[0];
+    cache->entries[NENTRIES - 1].next = 0;
+}
+
+/* Create and initialize cache */
+FontPatternCachePtr
+MakeFontPatternCache (void)
+{
+    FontPatternCachePtr        cache;
+    int                        i;
+    cache = malloc (sizeof *cache);
+    if (!cache)
+       return 0;
+    for (i = 0; i < NENTRIES; i++) {
+       cache->entries[i].patlen = 0;
+       cache->entries[i].pattern = 0;
+       cache->entries[i].pFont = 0;
+    }
+    EmptyFontPatternCache (cache);
+    return cache;
+}
+
+/* toss cache */
+void
+FreeFontPatternCache (FontPatternCachePtr cache)
+{
+    int            i;
+
+    for (i = 0; i < NENTRIES; i++)
+       free (cache->entries[i].pattern);
+    free (cache);
+}
+
+/* compute id for string */
+static int
+Hash (const char *string, int len)
+{
+    int        hash;
+
+    hash = 0;
+    while (len--)
+       hash = (hash << 1) ^ *string++;
+    if (hash < 0)
+       hash = -hash;
+    return hash;
+}
+
+/* add entry */
+void
+CacheFontPattern (FontPatternCachePtr cache, 
+                 char *pattern, 
+                 int patlen, 
+                 FontPtr pFont)
+{
+    FontPatternCacheEntryPtr   e;
+    char                       *newpat;
+    int                                i;
+
+    newpat = malloc (patlen);
+    if (!newpat)
+       return;
+    if (cache->free)
+    {
+       e = cache->free;
+       cache->free = e->next;
+    }
+    else
+    {
+       i = rand ();
+       if (i < 0)
+           i = -i;
+       i %= NENTRIES;
+       e = &cache->entries[i];
+       if (e->next)
+           e->next->prev = e->prev;
+       *e->prev = e->next;
+       free (e->pattern);
+    }
+    /* set pattern */
+    memcpy (newpat, pattern, patlen);
+    e->pattern = newpat;
+    e->patlen = patlen;
+    /* link to new hash chain */
+    e->hash = Hash (pattern, patlen);
+    i = e->hash % NBUCKETS;
+    e->next = cache->buckets[i];
+    if (e->next)
+       e->next->prev = &(e->next);
+    cache->buckets[i] = e;
+    e->prev = &(cache->buckets[i]);
+    e->pFont = pFont;
+}
+
+/* find matching entry */
+FontPtr
+FindCachedFontPattern (FontPatternCachePtr cache, 
+                      char *pattern, 
+                      int patlen)
+{
+    int                                hash;
+    int                                i;
+    FontPatternCacheEntryPtr   e;
+
+    hash = Hash (pattern, patlen);
+    i = hash % NBUCKETS;
+    for (e = cache->buckets[i]; e; e = e->next)
+    {
+       if (e->patlen == patlen && e->hash == hash &&
+           !memcmp (e->pattern, pattern, patlen))
+       {
+           return e->pFont;
+       }
+    }
+    return 0;
+}
+
+void
+RemoveCachedFontPattern (FontPatternCachePtr cache, 
+                        FontPtr pFont)
+{
+    FontPatternCacheEntryPtr   e;
+    int                                i;
+
+    for (i = 0; i < NENTRIES; i++)
+    {
+       if ((e = &cache->entries[i])->pFont == pFont)
+       {
+           e->pFont = 0;
+           if (e->next)
+               e->next->prev = e->prev;
+           *e->prev = e->next;
+           e->next = cache->free;
+           cache->free = e;
+           free (e->pattern);
+           e->pattern = 0;
+       }
+    }
+}
diff --git a/src/util/private.c b/src/util/private.c
new file mode 100755 (executable)
index 0000000..36715b1
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+
+Copyright 1991, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+/*
+ * Author:  Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include    <X11/fonts/fontmisc.h>
+#include    <X11/fonts/fontstruct.h>
+
+static int _FontPrivateAllocateIndex = 0;
+
+int
+AllocateFontPrivateIndex (void)
+{
+    return _FontPrivateAllocateIndex++;
+}
+
+FontPtr 
+CreateFontRec (void)
+{
+    FontPtr pFont;
+    int size;
+
+    size = sizeof(FontRec) + (sizeof(pointer) * _FontPrivateAllocateIndex);
+
+    pFont = malloc(size);
+    
+    if(pFont) {
+       bzero((char*)pFont, size);
+       pFont->maxPrivate = _FontPrivateAllocateIndex - 1;
+       if(_FontPrivateAllocateIndex)
+           pFont->devPrivates = (pointer)(&pFont[1]);
+    }
+
+    return pFont;
+}
+
+void
+DestroyFontRec (FontPtr pFont)
+{
+   if (pFont->devPrivates && pFont->devPrivates != (pointer)(&pFont[1]))
+       free(pFont->devPrivates);
+   free(pFont);
+}
+
+void
+ResetFontPrivateIndex (void)
+{
+    _FontPrivateAllocateIndex = 0;
+}
+
+Bool
+_FontSetNewPrivate (FontPtr pFont, int n, pointer ptr)
+{
+    pointer *new;
+
+    if (n > pFont->maxPrivate) {
+       if (pFont->devPrivates && pFont->devPrivates != (pointer)(&pFont[1])) {
+           new = realloc (pFont->devPrivates, (n + 1) * sizeof (pointer));
+           if (!new)
+               return FALSE;
+       } else {
+           /* omg realloc */
+           new = malloc ((n + 1) * sizeof (pointer));
+           if (!new)
+               return FALSE;
+           if (pFont->devPrivates)
+               memcpy (new, pFont->devPrivates, (pFont->maxPrivate + 1) * sizeof (pointer));
+       }
+       pFont->devPrivates = new;
+       /* zero out new, uninitialized privates */
+       while(++pFont->maxPrivate < n)
+           pFont->devPrivates[pFont->maxPrivate] = (pointer)0;
+    }
+    pFont->devPrivates[n] = ptr;
+    return TRUE;
+}
+
diff --git a/src/util/utilbitmap.c b/src/util/utilbitmap.c
new file mode 100755 (executable)
index 0000000..5feb2d1
--- /dev/null
@@ -0,0 +1,185 @@
+/*
+
+Copyright 1990, 1994, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+/*
+ * Author:  Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/fonts/fontmisc.h>
+
+/* Utility functions for reformating font bitmaps */
+
+static const unsigned char _reverse_byte[0x100] = {
+       0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+       0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+       0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+       0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+       0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+       0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+       0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+       0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+       0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+       0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+       0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+       0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+       0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+       0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+       0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+       0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+       0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+       0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+       0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+       0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+       0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+       0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+       0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+       0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+       0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+       0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+       0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+       0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+       0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+       0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+       0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+       0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
+};
+
+/*
+ *     Invert bit order within each BYTE of an array.
+ */
+void
+BitOrderInvert(unsigned char *buf, int nbytes)
+{
+    const unsigned char *rev = _reverse_byte;
+
+    for (; --nbytes >= 0; buf++)
+       *buf = rev[*buf];
+}
+
+/*
+ *     Invert byte order within each 16-bits of an array.
+ */
+void
+TwoByteSwap(unsigned char *buf, int nbytes)
+{
+    unsigned char c;
+
+    for (; nbytes > 0; nbytes -= 2, buf += 2)
+    {
+       c = buf[0];
+       buf[0] = buf[1];
+       buf[1] = c;
+    }
+}
+
+/*
+ *     Invert byte order within each 32-bits of an array.
+ */
+void
+FourByteSwap(unsigned char *buf, int nbytes)
+{
+    unsigned char c;
+
+    for (; nbytes > 0; nbytes -= 4, buf += 4) 
+    {
+       c = buf[0];
+       buf[0] = buf[3];
+       buf[3] = c;
+       c = buf[1];
+       buf[1] = buf[2];
+       buf[2] = c;
+    }
+}
+
+/*
+ *     Repad a bitmap
+ */
+
+int
+RepadBitmap (char *pSrc, char *pDst, 
+            unsigned int srcPad, unsigned int dstPad, 
+            int width, int height)
+{
+    int            srcWidthBytes,dstWidthBytes;
+    int            row,col;
+    char    *pTmpSrc,*pTmpDst;
+
+    switch (srcPad) {
+    case 1:    
+       srcWidthBytes = (width+7)>>3;
+       break;
+    case 2:
+       srcWidthBytes = ((width+15)>>4)<<1;
+       break;
+    case 4:    
+       srcWidthBytes = ((width+31)>>5)<<2;
+       break;
+    case 8:    
+       srcWidthBytes = ((width+63)>>6)<<3; 
+       break;
+    default:
+       return 0;
+    }
+    switch (dstPad) {
+    case 1:    
+       dstWidthBytes = (width+7)>>3;
+       break;
+    case 2:
+       dstWidthBytes = ((width+15)>>4)<<1;
+       break;
+    case 4:    
+       dstWidthBytes = ((width+31)>>5)<<2;
+       break;
+    case 8:    
+       dstWidthBytes = ((width+63)>>6)<<3; 
+       break;
+    default:
+       return 0;
+    }
+
+    width = srcWidthBytes;
+    if (width > dstWidthBytes)
+       width = dstWidthBytes;
+    pTmpSrc= pSrc;
+    pTmpDst= pDst;
+    for (row = 0; row < height; row++)
+    {
+       for (col = 0; col < width; col++)
+           *pTmpDst++ = *pTmpSrc++;
+       while (col < dstWidthBytes)
+       {
+           *pTmpDst++ = '\0';
+           col++;
+       }
+       pTmpSrc += srcWidthBytes - width;
+    }
+    return dstWidthBytes * height;
+}
+
+
diff --git a/xfont.pc.in b/xfont.pc.in
new file mode 100644 (file)
index 0000000..f08dea0
--- /dev/null
@@ -0,0 +1,13 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: Xfont
+Description: X font Library
+Version: @VERSION@
+Requires: xproto fontsproto
+Requires.private: fontenc @FREETYPE_REQUIRES@
+Cflags: -I${includedir}
+Libs: -L${libdir} -lXfont
+Libs.private: @Z_LIBS@ -lm