From dafebc5bb70303f0b5baf0b087cf4d9a64b5c7f0 Mon Sep 17 00:00:00 2001 From: marha Date: Mon, 12 Sep 2011 11:27:51 +0200 Subject: Synchronised line endinge with release branch --- mkfontscale/COPYING | 80 +- mkfontscale/Makefile.am | 114 +- mkfontscale/configure.ac | 128 +-- mkfontscale/data.h | 166 +-- mkfontscale/hash.h | 94 +- mkfontscale/ident.c | 904 ++++++++-------- mkfontscale/ident.h | 56 +- mkfontscale/list.c | 562 +++++----- mkfontscale/list.h | 96 +- mkfontscale/mkfontscale.c | 2592 ++++++++++++++++++++++----------------------- 10 files changed, 2396 insertions(+), 2396 deletions(-) (limited to 'mkfontscale') diff --git a/mkfontscale/COPYING b/mkfontscale/COPYING index 27c949ebc..cc8baddeb 100644 --- a/mkfontscale/COPYING +++ b/mkfontscale/COPYING @@ -1,40 +1,40 @@ -Copyright (c) 2002-2008 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. - -Copyright (c) 2008, 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. +Copyright (c) 2002-2008 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. + +Copyright (c) 2008, 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. diff --git a/mkfontscale/Makefile.am b/mkfontscale/Makefile.am index 381a1f3d1..e276fec13 100644 --- a/mkfontscale/Makefile.am +++ b/mkfontscale/Makefile.am @@ -1,57 +1,57 @@ -# -# Copyright 2005 Red Hat, 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 Red Hat not be used in -# advertising or publicity pertaining to distribution of the software -# without specific, written prior permission. Red Hat makes no -# representations about the suitability of this software for any -# purpose. It is provided "as is" without express or implied warranty. -# -# RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN -# NO EVENT SHALL RED HAT 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 = man -bin_PROGRAMS = mkfontscale - -AM_CPPFLAGS = @MKFONTSCALE_CFLAGS@ @X11_CFLAGS@ -D_BSD_SOURCE -AM_CFLAGS = $(CWARNFLAGS) -mkfontscale_LDADD = @MKFONTSCALE_LIBS@ - -mkfontscale_SOURCES = \ - data.h \ - hash.c \ - hash.h \ - ident.c \ - ident.h \ - list.c \ - list.h \ - mkfontscale.c - -MAINTAINERCLEANFILES = ChangeLog INSTALL - -.PHONY: ChangeLog INSTALL - -INSTALL: - $(INSTALL_CMD) - -ChangeLog: - $(CHANGELOG_CMD) - -dist-hook: ChangeLog INSTALL - -if LINT -ALL_LINT_FLAGS=$(LINT_FLAGS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) - -lint: - $(LINT) $(ALL_LINT_FLAGS) $(mkfontscale_SOURCES) -endif LINT +# +# Copyright 2005 Red Hat, 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 Red Hat not be used in +# advertising or publicity pertaining to distribution of the software +# without specific, written prior permission. Red Hat makes no +# representations about the suitability of this software for any +# purpose. It is provided "as is" without express or implied warranty. +# +# RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN +# NO EVENT SHALL RED HAT 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 = man +bin_PROGRAMS = mkfontscale + +AM_CPPFLAGS = @MKFONTSCALE_CFLAGS@ @X11_CFLAGS@ -D_BSD_SOURCE +AM_CFLAGS = $(CWARNFLAGS) +mkfontscale_LDADD = @MKFONTSCALE_LIBS@ + +mkfontscale_SOURCES = \ + data.h \ + hash.c \ + hash.h \ + ident.c \ + ident.h \ + list.c \ + list.h \ + mkfontscale.c + +MAINTAINERCLEANFILES = ChangeLog INSTALL + +.PHONY: ChangeLog INSTALL + +INSTALL: + $(INSTALL_CMD) + +ChangeLog: + $(CHANGELOG_CMD) + +dist-hook: ChangeLog INSTALL + +if LINT +ALL_LINT_FLAGS=$(LINT_FLAGS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) + +lint: + $(LINT) $(ALL_LINT_FLAGS) $(mkfontscale_SOURCES) +endif LINT diff --git a/mkfontscale/configure.ac b/mkfontscale/configure.ac index f20ff6ac7..f001e0937 100644 --- a/mkfontscale/configure.ac +++ b/mkfontscale/configure.ac @@ -1,64 +1,64 @@ -dnl Copyright 2005 Red Hat, Inc. -dnl -dnl Permission to use, copy, modify, distribute, and sell this software -dnl and its documentation for any purpose is hereby granted without fee, -dnl provided that the above copyright notice appear in all copies and -dnl that both that copyright notice and this permission notice appear in -dnl supporting documentation, and that the name of Red Hat not be used in -dnl advertising or publicity pertaining to distribution of the software -dnl without specific, written prior permission. Red Hat makes no -dnl representations about the suitability of this software for any -dnl purpose. It is provided "as is" without express or implied warranty. -dnl -dnl RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -dnl INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN -dnl NO EVENT SHALL RED HAT BE LIABLE FOR ANY SPECIAL, INDIRECT OR -dnl CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS -dnl OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -dnl OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE -dnl USE OR PERFORMANCE OF THIS SOFTWARE. -dnl -dnl Process this file with autoconf to create configure. - -# Initialize Autoconf -AC_PREREQ([2.60]) -AC_INIT([mkfontscale], [1.0.9], - [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], - [mkfontscale]) -AC_CONFIG_SRCDIR([Makefile.am]) -AC_CONFIG_HEADERS([config.h]) - -# Initialize Automake -AM_INIT_AUTOMAKE([foreign dist-bzip2]) -AM_MAINTAINER_MODE - -# Require X.Org macros 1.8 or later for MAN_SUBSTS set by XORG_MANPAGE_SECTIONS -m4_ifndef([XORG_MACROS_VERSION], - [m4_fatal([must install xorg-macros 1.8 or later before running autoconf/autogen])]) -XORG_MACROS_VERSION(1.8) -XORG_DEFAULT_OPTIONS - -AC_CHECK_LIB(z, gzopen, [], - [AC_MSG_ERROR([zlib is required, but was not found.])]) - -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, [], - AC_MSG_ERROR([*** libbz2 is required for bzip2 support])) - AC_DEFINE(X_BZIP2_FONT_COMPRESSION,1,[Support bzip2 for bitmap fonts]) -fi - -# Checks for pkg-config packages -PKG_CHECK_MODULES(MKFONTSCALE, fontenc freetype2) -PKG_CHECK_MODULES(X11, xproto) - -dnl Allow checking code with lint, sparse, etc. -XORG_WITH_LINT - -AC_CONFIG_FILES([ - Makefile - man/Makefile]) -AC_OUTPUT +dnl Copyright 2005 Red Hat, Inc. +dnl +dnl Permission to use, copy, modify, distribute, and sell this software +dnl and its documentation for any purpose is hereby granted without fee, +dnl provided that the above copyright notice appear in all copies and +dnl that both that copyright notice and this permission notice appear in +dnl supporting documentation, and that the name of Red Hat not be used in +dnl advertising or publicity pertaining to distribution of the software +dnl without specific, written prior permission. Red Hat makes no +dnl representations about the suitability of this software for any +dnl purpose. It is provided "as is" without express or implied warranty. +dnl +dnl RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +dnl INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN +dnl NO EVENT SHALL RED HAT BE LIABLE FOR ANY SPECIAL, INDIRECT OR +dnl CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +dnl OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +dnl OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE +dnl USE OR PERFORMANCE OF THIS SOFTWARE. +dnl +dnl Process this file with autoconf to create configure. + +# Initialize Autoconf +AC_PREREQ([2.60]) +AC_INIT([mkfontscale], [1.0.9], + [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], + [mkfontscale]) +AC_CONFIG_SRCDIR([Makefile.am]) +AC_CONFIG_HEADERS([config.h]) + +# Initialize Automake +AM_INIT_AUTOMAKE([foreign dist-bzip2]) +AM_MAINTAINER_MODE + +# Require X.Org macros 1.8 or later for MAN_SUBSTS set by XORG_MANPAGE_SECTIONS +m4_ifndef([XORG_MACROS_VERSION], + [m4_fatal([must install xorg-macros 1.8 or later before running autoconf/autogen])]) +XORG_MACROS_VERSION(1.8) +XORG_DEFAULT_OPTIONS + +AC_CHECK_LIB(z, gzopen, [], + [AC_MSG_ERROR([zlib is required, but was not found.])]) + +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, [], + AC_MSG_ERROR([*** libbz2 is required for bzip2 support])) + AC_DEFINE(X_BZIP2_FONT_COMPRESSION,1,[Support bzip2 for bitmap fonts]) +fi + +# Checks for pkg-config packages +PKG_CHECK_MODULES(MKFONTSCALE, fontenc freetype2) +PKG_CHECK_MODULES(X11, xproto) + +dnl Allow checking code with lint, sparse, etc. +XORG_WITH_LINT + +AC_CONFIG_FILES([ + Makefile + man/Makefile]) +AC_OUTPUT diff --git a/mkfontscale/data.h b/mkfontscale/data.h index 17086be58..bb5b170d5 100644 --- a/mkfontscale/data.h +++ b/mkfontscale/data.h @@ -1,83 +1,83 @@ -/* - Copyright (c) 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 _MKS_DATA_H_ -#define _MKS_DATA_H_ 1 - -/* Order is significant. For example, some B&H fonts are hinted by - URW++, and both strings appear in the notice. */ - -static char *notice_foundries[][2] = - {{"Bigelow", "b&h"}, - {"Adobe", "adobe"}, - {"Bitstream", "bitstream"}, - {"Monotype", "monotype"}, - {"Linotype", "linotype"}, - {"LINOTYPE-HELL", "linotype"}, - {"IBM", "ibm"}, - {"URW", "urw"}, - {"International Typeface Corporation", "itc"}, - {"Tiro Typeworks", "tiro"}, - {"XFree86", "xfree86"}, - {"Xorg", "xorg"}, - {"Microsoft", "microsoft"}, - {"Omega", "omega"}, - {"Font21", "hwan"}, - {"HanYang System", "hanyang"}}; - -/* This table is partly taken from ttmkfdir by Joerg Pommnitz. */ - -/* It should not contain useless entries (such as UNKN) nor duplicate - entries for padding both with spaces and NULs. */ - -static char *vendor_foundries[][2] = - {{"ADBE", "adobe"}, - {"AGFA", "agfa"}, - {"ALTS", "altsys"}, - {"APPL", "apple"}, - {"ARPH", "arphic"}, - {"ATEC", "alltype"}, - {"B&H", "b&h"}, - {"BITS", "bitstream"}, - {"CANO", "cannon"}, - {"DYNA", "dynalab"}, - {"EPSN", "epson"}, - {"FJ", "fujitsu"}, - {"IBM", "ibm"}, - {"ITC", "itc"}, - {"IMPR", "impress"}, - {"LARA", "larabiefonts"}, - {"LEAF", "interleaf"}, - {"LETR", "letraset"}, - {"LINO", "linotype"}, - {"MACR", "macromedia"}, - {"MONO", "monotype"}, - {"MS", "microsoft"}, - {"MT", "monotype"}, - {"NEC", "nec"}, - {"PARA", "paratype"}, - {"QMSI", "qms"}, - {"RICO", "ricoh"}, - {"URW", "urw"}, - {"Y&Y", "y&y"}}; - -#endif /* _MKS_DATA_H_ */ +/* + Copyright (c) 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 _MKS_DATA_H_ +#define _MKS_DATA_H_ 1 + +/* Order is significant. For example, some B&H fonts are hinted by + URW++, and both strings appear in the notice. */ + +static char *notice_foundries[][2] = + {{"Bigelow", "b&h"}, + {"Adobe", "adobe"}, + {"Bitstream", "bitstream"}, + {"Monotype", "monotype"}, + {"Linotype", "linotype"}, + {"LINOTYPE-HELL", "linotype"}, + {"IBM", "ibm"}, + {"URW", "urw"}, + {"International Typeface Corporation", "itc"}, + {"Tiro Typeworks", "tiro"}, + {"XFree86", "xfree86"}, + {"Xorg", "xorg"}, + {"Microsoft", "microsoft"}, + {"Omega", "omega"}, + {"Font21", "hwan"}, + {"HanYang System", "hanyang"}}; + +/* This table is partly taken from ttmkfdir by Joerg Pommnitz. */ + +/* It should not contain useless entries (such as UNKN) nor duplicate + entries for padding both with spaces and NULs. */ + +static char *vendor_foundries[][2] = + {{"ADBE", "adobe"}, + {"AGFA", "agfa"}, + {"ALTS", "altsys"}, + {"APPL", "apple"}, + {"ARPH", "arphic"}, + {"ATEC", "alltype"}, + {"B&H", "b&h"}, + {"BITS", "bitstream"}, + {"CANO", "cannon"}, + {"DYNA", "dynalab"}, + {"EPSN", "epson"}, + {"FJ", "fujitsu"}, + {"IBM", "ibm"}, + {"ITC", "itc"}, + {"IMPR", "impress"}, + {"LARA", "larabiefonts"}, + {"LEAF", "interleaf"}, + {"LETR", "letraset"}, + {"LINO", "linotype"}, + {"MACR", "macromedia"}, + {"MONO", "monotype"}, + {"MS", "microsoft"}, + {"MT", "monotype"}, + {"NEC", "nec"}, + {"PARA", "paratype"}, + {"QMSI", "qms"}, + {"RICO", "ricoh"}, + {"URW", "urw"}, + {"Y&Y", "y&y"}}; + +#endif /* _MKS_DATA_H_ */ diff --git a/mkfontscale/hash.h b/mkfontscale/hash.h index 63b27867d..631004e63 100644 --- a/mkfontscale/hash.h +++ b/mkfontscale/hash.h @@ -1,47 +1,47 @@ -/* - Copyright (c) 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. -*/ - -#ifndef _MKS_HASH_H_ -#define _MKS_HASH_H_ 1 - -#ifdef _MSC_VER -#define strcasecmp _stricmp -#endif - -typedef struct _HashBucket { - char *key; - char *value; - int prio; - struct _HashBucket *next; -} HashBucketRec, *HashBucketPtr; - -typedef HashBucketPtr* HashTablePtr; - -HashTablePtr makeHashTable(void); -void destroyHashTable(HashTablePtr table); -char *getHash(HashTablePtr table, char *key); -int putHash(HashTablePtr table, char *key, char *value, int prio); -int hashElements(HashTablePtr table); -HashBucketPtr *hashArray(HashTablePtr table, int value_first); -void destroyHashArray(HashBucketPtr *array); - -#endif /* _MKS_HASH_H */ +/* + Copyright (c) 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. +*/ + +#ifndef _MKS_HASH_H_ +#define _MKS_HASH_H_ 1 + +#ifdef _MSC_VER +#define strcasecmp _stricmp +#endif + +typedef struct _HashBucket { + char *key; + char *value; + int prio; + struct _HashBucket *next; +} HashBucketRec, *HashBucketPtr; + +typedef HashBucketPtr* HashTablePtr; + +HashTablePtr makeHashTable(void); +void destroyHashTable(HashTablePtr table); +char *getHash(HashTablePtr table, char *key); +int putHash(HashTablePtr table, char *key, char *value, int prio); +int hashElements(HashTablePtr table); +HashBucketPtr *hashArray(HashTablePtr table, int value_first); +void destroyHashArray(HashBucketPtr *array); + +#endif /* _MKS_HASH_H */ diff --git a/mkfontscale/ident.c b/mkfontscale/ident.c index 6143a0e3f..15fb76be2 100644 --- a/mkfontscale/ident.c +++ b/mkfontscale/ident.c @@ -1,452 +1,452 @@ -/* - Copyright (c) 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. -*/ -/* - * Copyright (c) 2008, 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. - */ - -/* The function identifyBitmap returns -1 if filename is definitively not - a font file, 1 if it is a single-face bitmap font with a XLFD name, - and 0 if it should be processed normally. identifyBitmap is - much faster than parsing the whole font. */ - -#include "config.h" - -#include -#include -#include "zlib.h" -#include "ident.h" - -#ifdef X_BZIP2_FONT_COMPRESSION -# include -#endif - -#define PCF_VERSION (('p'<<24)|('c'<<16)|('f'<<8)|1) -#define PCF_PROPERTIES (1 << 0) - -typedef struct _Prop { - unsigned name; - int isString; - unsigned value; -} PropRec, *PropPtr; - -#ifdef X_BZIP2_FONT_COMPRESSION -typedef struct { - enum { gzFontFile, bz2FontFile } type; - union { - gzFile gz; - BZFILE *bz2; - } f; - unsigned pos; -} fontFile; - -static inline void * -fontFileOpen(fontFile *ff, const char *filename) { - int n = strlen(filename); - - if (strcmp(filename + n - 4, ".bz2") == 0) { - ff->type = bz2FontFile; - ff->f.bz2 = BZ2_bzopen(filename, "rb"); - ff->pos = 0; - return ff->f.bz2; - } else { - ff->type = gzFontFile; - ff->f.gz = gzopen(filename, "rb"); - return ff->f.gz; - } -} - -static inline int -fontFileRead(fontFile *ff, void *buf, unsigned len) -{ - if (ff->type == gzFontFile) { - return gzread(ff->f.gz, buf, len); - } else { - int r = BZ2_bzread(ff->f.bz2, buf, len); - ff->pos += r; - return r; - } -} - -static inline int -fontFileGetc(fontFile *ff) -{ - if (ff->type == gzFontFile) { - return gzgetc(ff->f.gz); - } else { - char buf; - if (BZ2_bzread(ff->f.bz2, &buf, 1) != 1) { - return -1; - } else { - ff->pos += 1; - return (int) buf; - } - } -} - -static int -fontFileSeek(fontFile *ff, z_off_t offset, int whence) -{ - if (ff->type == gzFontFile) { - return gzseek(ff->f.gz, offset, whence); - } else { - /* bzlib has no easy equivalent so we have to fake it, - * fortunately, we only have to handle a couple of cases - */ - int n; - char buf[BUFSIZ]; - - switch (whence) { - case SEEK_SET: - n = offset - ff->pos; - break; - case SEEK_CUR: - n = offset; - break; - default: - return -1; - } - - while (n > BUFSIZ) { - if (BZ2_bzread(ff->f.bz2, buf, BUFSIZ) != BUFSIZ) - return -1; - n -= BUFSIZ; - } - if (BZ2_bzread(ff->f.bz2, buf, n) != n) - return -1; - ff->pos = offset; - return offset; - } -} - - -static inline int -fontFileClose(fontFile *ff) -{ - if (ff->type == gzFontFile) { - return gzclose(ff->f.gz); - } else { - BZ2_bzclose(ff->f.bz2); - return 0; - } -} - -#else /* no bzip2, only gzip */ -typedef gzFile fontFile; -# define fontFileOpen(ff, filename) (*(ff) = gzopen(filename, "rb")) -# define fontFileRead(ff, buf, len) gzread(*(ff), buf, len) -# define fontFileGetc(ff) gzgetc(*(ff)) -# define fontFileSeek(ff, off, whence) gzseek(*(ff), off, whence) -# define fontFileClose(ff) gzclose(*(ff)) -#endif - -static int pcfIdentify(fontFile *f, char **name); -static int bdfIdentify(fontFile *f, char **name); - -static int -getLSB32(fontFile *f) -{ - int rc; - unsigned char c[4]; - - rc = fontFileRead(f, c, 4); - if(rc != 4) - return -1; - return (c[0]) | (c[1] << 8) | (c[2] << 16) | (c[3] << 24); -} - -static int -getInt8(fontFile *f, int format) -{ - unsigned char c; - int rc; - - rc = fontFileRead(f, &c, 1); - if(rc != 1) - return -1; - return c; -} - -static int -getInt32(fontFile *f, int format) -{ - int rc; - unsigned char c[4]; - - rc = fontFileRead(f, c, 4); - if(rc != 4) - return -1; - - if(format & (1 << 2)) { - return (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | (c[3]); - } else { - return (c[0]) | (c[1] << 8) | (c[2] << 16) | (c[3] << 24); - } -} - -int -bitmapIdentify(const char *filename, char **name) -{ - fontFile ff; - int magic; - - if (fontFileOpen(&ff, filename) == NULL) - return -1; - - magic = getLSB32(&ff); - if(magic == PCF_VERSION) - return pcfIdentify(&ff, name); - else if(magic == ('S' | ('T' << 8) | ('A' << 16) | ('R') << 24)) - return bdfIdentify(&ff, name); - - fontFileClose(&ff); - return 0; -} - -static int -pcfIdentify(fontFile *f, char **name) -{ - int prop_position; - PropPtr props = NULL; - int format, count, nprops, i, string_size, rc; - char *strings = NULL, *s; - - count = getLSB32(f); - if(count <= 0) - goto fail; - - prop_position = -1; - for(i = 0; i < count; i++) { - int type, offset; - type = getLSB32(f); - (void) getLSB32(f); - (void) getLSB32(f); - offset = getLSB32(f); - if(type == PCF_PROPERTIES) { - prop_position = offset; - break; - } - } - if(prop_position < 0) - goto fail; - - rc = fontFileSeek(f, prop_position, SEEK_SET); - if(rc < 0) - goto fail; - - format = getLSB32(f); - if((format & 0xFFFFFF00) != 0) - goto fail; - nprops = getInt32(f, format); - if(nprops <= 0 || nprops > 1000) - goto fail; - props = malloc(nprops * sizeof(PropRec)); - if(props == NULL) - goto fail; - - for(i = 0; i < nprops; i++) { - props[i].name = getInt32(f, format); - props[i].isString = getInt8(f, format); - props[i].value = getInt32(f, format); - } - if(nprops & 3) { - rc = fontFileSeek(f, 4 - (nprops & 3), SEEK_CUR); - if(rc < 0) - goto fail; - } - - string_size = getInt32(f, format); - if(string_size < 0 || string_size > 100000) - goto fail; - strings = malloc(string_size); - if(!strings) - goto fail; - - rc = fontFileRead(f, strings, string_size); - if(rc != string_size) - goto fail; - - for(i = 0; i < nprops; i++) { - if(!props[i].isString || - props[i].name >= string_size - 4 || - props[i].value >= string_size) - continue; - if(strcmp(strings + props[i].name, "FONT") == 0) - break; - } - - if(i >= nprops) - goto fail; - - s = malloc(strlen(strings + props[i].value) + 1); - if(s == NULL) - goto fail; - strcpy(s, strings + props[i].value); - *name = s; - free(strings); - free(props); - fontFileClose(f); - return 1; - - fail: - if(strings) free(strings); - if(props) free(props); - fontFileClose(f); - return 0; -} - -#define NKEY 20 - -static char* -getKeyword(fontFile *f, int *eol) -{ - static char keyword[NKEY + 1]; - int c, i; - i = 0; - while(i < NKEY) { - c = fontFileGetc(f); - if(c == ' ' || c == '\n') { - if(i <= 0) - return NULL; - if(eol) - *eol = (c == '\n'); - keyword[i] = '\0'; - return keyword; - } - if(c < 'A' || c > 'Z') - return NULL; - keyword[i++] = c; - } - return NULL; -} - -static int -bdfskip(fontFile *f) -{ - int c; - do { - c = fontFileGetc(f); - } while(c >= 0 && c != '\n'); - if(c < 0) - return -1; - return 1; -} - -static char * -bdfend(fontFile *f) -{ - int c; - char *buf = NULL; - int bufsize = 0; - int i = 0; - - do { - c = fontFileGetc(f); - } while (c == ' '); - - while(i < 1000) { - if(c < 0 || (c == '\n' && i == 0)) { - goto fail; - } - if(bufsize < i + 1) { - char *newbuf; - if(bufsize == 0) { - bufsize = 20; - newbuf = malloc(bufsize); - } else { - bufsize = 2 * bufsize; - newbuf = realloc(buf, bufsize); - } - if(newbuf == NULL) - goto fail; - buf = newbuf; - } - if(c == '\n') { - buf[i] = '\0'; - return buf; - } - buf[i++] = c; - c = fontFileGetc(f); - } - - fail: - if(buf) - free(buf); - return NULL; -} - -static int -bdfIdentify(fontFile *f, char **name) -{ - char *k; - int rc; - int eol; - /* bitmapIdentify already read "STAR", so we need to check for - "TFONT" */ - k = getKeyword(f, &eol); - if(k == NULL || eol) - goto fail; - if(strcmp(k, "TFONT") != 0) - goto fail; - while(1) { - if(!eol) { - rc = bdfskip(f); - if(rc < 0) - goto fail; - } - k = getKeyword(f, &eol); - if(k == NULL) - goto fail; - else if(strcmp(k, "FONT") == 0) { - if(eol) - goto fail; - k = bdfend(f); - if(k == NULL) - goto fail; - *name = k; - fontFileClose(f); - return 1; - } else if(strcmp(k, "CHARS") == 0) - goto fail; - } - fail: - fontFileClose(f); - return 0; -} +/* + Copyright (c) 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. +*/ +/* + * Copyright (c) 2008, 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. + */ + +/* The function identifyBitmap returns -1 if filename is definitively not + a font file, 1 if it is a single-face bitmap font with a XLFD name, + and 0 if it should be processed normally. identifyBitmap is + much faster than parsing the whole font. */ + +#include "config.h" + +#include +#include +#include "zlib.h" +#include "ident.h" + +#ifdef X_BZIP2_FONT_COMPRESSION +# include +#endif + +#define PCF_VERSION (('p'<<24)|('c'<<16)|('f'<<8)|1) +#define PCF_PROPERTIES (1 << 0) + +typedef struct _Prop { + unsigned name; + int isString; + unsigned value; +} PropRec, *PropPtr; + +#ifdef X_BZIP2_FONT_COMPRESSION +typedef struct { + enum { gzFontFile, bz2FontFile } type; + union { + gzFile gz; + BZFILE *bz2; + } f; + unsigned pos; +} fontFile; + +static inline void * +fontFileOpen(fontFile *ff, const char *filename) { + int n = strlen(filename); + + if (strcmp(filename + n - 4, ".bz2") == 0) { + ff->type = bz2FontFile; + ff->f.bz2 = BZ2_bzopen(filename, "rb"); + ff->pos = 0; + return ff->f.bz2; + } else { + ff->type = gzFontFile; + ff->f.gz = gzopen(filename, "rb"); + return ff->f.gz; + } +} + +static inline int +fontFileRead(fontFile *ff, void *buf, unsigned len) +{ + if (ff->type == gzFontFile) { + return gzread(ff->f.gz, buf, len); + } else { + int r = BZ2_bzread(ff->f.bz2, buf, len); + ff->pos += r; + return r; + } +} + +static inline int +fontFileGetc(fontFile *ff) +{ + if (ff->type == gzFontFile) { + return gzgetc(ff->f.gz); + } else { + char buf; + if (BZ2_bzread(ff->f.bz2, &buf, 1) != 1) { + return -1; + } else { + ff->pos += 1; + return (int) buf; + } + } +} + +static int +fontFileSeek(fontFile *ff, z_off_t offset, int whence) +{ + if (ff->type == gzFontFile) { + return gzseek(ff->f.gz, offset, whence); + } else { + /* bzlib has no easy equivalent so we have to fake it, + * fortunately, we only have to handle a couple of cases + */ + int n; + char buf[BUFSIZ]; + + switch (whence) { + case SEEK_SET: + n = offset - ff->pos; + break; + case SEEK_CUR: + n = offset; + break; + default: + return -1; + } + + while (n > BUFSIZ) { + if (BZ2_bzread(ff->f.bz2, buf, BUFSIZ) != BUFSIZ) + return -1; + n -= BUFSIZ; + } + if (BZ2_bzread(ff->f.bz2, buf, n) != n) + return -1; + ff->pos = offset; + return offset; + } +} + + +static inline int +fontFileClose(fontFile *ff) +{ + if (ff->type == gzFontFile) { + return gzclose(ff->f.gz); + } else { + BZ2_bzclose(ff->f.bz2); + return 0; + } +} + +#else /* no bzip2, only gzip */ +typedef gzFile fontFile; +# define fontFileOpen(ff, filename) (*(ff) = gzopen(filename, "rb")) +# define fontFileRead(ff, buf, len) gzread(*(ff), buf, len) +# define fontFileGetc(ff) gzgetc(*(ff)) +# define fontFileSeek(ff, off, whence) gzseek(*(ff), off, whence) +# define fontFileClose(ff) gzclose(*(ff)) +#endif + +static int pcfIdentify(fontFile *f, char **name); +static int bdfIdentify(fontFile *f, char **name); + +static int +getLSB32(fontFile *f) +{ + int rc; + unsigned char c[4]; + + rc = fontFileRead(f, c, 4); + if(rc != 4) + return -1; + return (c[0]) | (c[1] << 8) | (c[2] << 16) | (c[3] << 24); +} + +static int +getInt8(fontFile *f, int format) +{ + unsigned char c; + int rc; + + rc = fontFileRead(f, &c, 1); + if(rc != 1) + return -1; + return c; +} + +static int +getInt32(fontFile *f, int format) +{ + int rc; + unsigned char c[4]; + + rc = fontFileRead(f, c, 4); + if(rc != 4) + return -1; + + if(format & (1 << 2)) { + return (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | (c[3]); + } else { + return (c[0]) | (c[1] << 8) | (c[2] << 16) | (c[3] << 24); + } +} + +int +bitmapIdentify(const char *filename, char **name) +{ + fontFile ff; + int magic; + + if (fontFileOpen(&ff, filename) == NULL) + return -1; + + magic = getLSB32(&ff); + if(magic == PCF_VERSION) + return pcfIdentify(&ff, name); + else if(magic == ('S' | ('T' << 8) | ('A' << 16) | ('R') << 24)) + return bdfIdentify(&ff, name); + + fontFileClose(&ff); + return 0; +} + +static int +pcfIdentify(fontFile *f, char **name) +{ + int prop_position; + PropPtr props = NULL; + int format, count, nprops, i, string_size, rc; + char *strings = NULL, *s; + + count = getLSB32(f); + if(count <= 0) + goto fail; + + prop_position = -1; + for(i = 0; i < count; i++) { + int type, offset; + type = getLSB32(f); + (void) getLSB32(f); + (void) getLSB32(f); + offset = getLSB32(f); + if(type == PCF_PROPERTIES) { + prop_position = offset; + break; + } + } + if(prop_position < 0) + goto fail; + + rc = fontFileSeek(f, prop_position, SEEK_SET); + if(rc < 0) + goto fail; + + format = getLSB32(f); + if((format & 0xFFFFFF00) != 0) + goto fail; + nprops = getInt32(f, format); + if(nprops <= 0 || nprops > 1000) + goto fail; + props = malloc(nprops * sizeof(PropRec)); + if(props == NULL) + goto fail; + + for(i = 0; i < nprops; i++) { + props[i].name = getInt32(f, format); + props[i].isString = getInt8(f, format); + props[i].value = getInt32(f, format); + } + if(nprops & 3) { + rc = fontFileSeek(f, 4 - (nprops & 3), SEEK_CUR); + if(rc < 0) + goto fail; + } + + string_size = getInt32(f, format); + if(string_size < 0 || string_size > 100000) + goto fail; + strings = malloc(string_size); + if(!strings) + goto fail; + + rc = fontFileRead(f, strings, string_size); + if(rc != string_size) + goto fail; + + for(i = 0; i < nprops; i++) { + if(!props[i].isString || + props[i].name >= string_size - 4 || + props[i].value >= string_size) + continue; + if(strcmp(strings + props[i].name, "FONT") == 0) + break; + } + + if(i >= nprops) + goto fail; + + s = malloc(strlen(strings + props[i].value) + 1); + if(s == NULL) + goto fail; + strcpy(s, strings + props[i].value); + *name = s; + free(strings); + free(props); + fontFileClose(f); + return 1; + + fail: + if(strings) free(strings); + if(props) free(props); + fontFileClose(f); + return 0; +} + +#define NKEY 20 + +static char* +getKeyword(fontFile *f, int *eol) +{ + static char keyword[NKEY + 1]; + int c, i; + i = 0; + while(i < NKEY) { + c = fontFileGetc(f); + if(c == ' ' || c == '\n') { + if(i <= 0) + return NULL; + if(eol) + *eol = (c == '\n'); + keyword[i] = '\0'; + return keyword; + } + if(c < 'A' || c > 'Z') + return NULL; + keyword[i++] = c; + } + return NULL; +} + +static int +bdfskip(fontFile *f) +{ + int c; + do { + c = fontFileGetc(f); + } while(c >= 0 && c != '\n'); + if(c < 0) + return -1; + return 1; +} + +static char * +bdfend(fontFile *f) +{ + int c; + char *buf = NULL; + int bufsize = 0; + int i = 0; + + do { + c = fontFileGetc(f); + } while (c == ' '); + + while(i < 1000) { + if(c < 0 || (c == '\n' && i == 0)) { + goto fail; + } + if(bufsize < i + 1) { + char *newbuf; + if(bufsize == 0) { + bufsize = 20; + newbuf = malloc(bufsize); + } else { + bufsize = 2 * bufsize; + newbuf = realloc(buf, bufsize); + } + if(newbuf == NULL) + goto fail; + buf = newbuf; + } + if(c == '\n') { + buf[i] = '\0'; + return buf; + } + buf[i++] = c; + c = fontFileGetc(f); + } + + fail: + if(buf) + free(buf); + return NULL; +} + +static int +bdfIdentify(fontFile *f, char **name) +{ + char *k; + int rc; + int eol; + /* bitmapIdentify already read "STAR", so we need to check for + "TFONT" */ + k = getKeyword(f, &eol); + if(k == NULL || eol) + goto fail; + if(strcmp(k, "TFONT") != 0) + goto fail; + while(1) { + if(!eol) { + rc = bdfskip(f); + if(rc < 0) + goto fail; + } + k = getKeyword(f, &eol); + if(k == NULL) + goto fail; + else if(strcmp(k, "FONT") == 0) { + if(eol) + goto fail; + k = bdfend(f); + if(k == NULL) + goto fail; + *name = k; + fontFileClose(f); + return 1; + } else if(strcmp(k, "CHARS") == 0) + goto fail; + } + fail: + fontFileClose(f); + return 0; +} diff --git a/mkfontscale/ident.h b/mkfontscale/ident.h index e937a000c..69e3ef7ea 100644 --- a/mkfontscale/ident.h +++ b/mkfontscale/ident.h @@ -1,28 +1,28 @@ -/* - Copyright (c) 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. -*/ - -#ifndef _MKS_IDENT_H_ -#define _MKS_IDENT_H_ 1 - -int bitmapIdentify(const char *filename, char **xlfd); - -#endif /* _MKS_IDENT_H_ */ +/* + Copyright (c) 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. +*/ + +#ifndef _MKS_IDENT_H_ +#define _MKS_IDENT_H_ 1 + +int bitmapIdentify(const char *filename, char **xlfd); + +#endif /* _MKS_IDENT_H_ */ diff --git a/mkfontscale/list.c b/mkfontscale/list.c index 34abf1bff..a10b5ed4c 100644 --- a/mkfontscale/list.c +++ b/mkfontscale/list.c @@ -1,281 +1,281 @@ -/* - Copyright (c) 2002-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. -*/ - -#include -#include -#include -#include -#include "list.h" - -int -listMember(char *elt, ListPtr list) -{ - while(list != NULL) { - if(strcmp(elt, list->value) == 0) - return 1; - list = list->next; - } - return 0; -} - -ListPtr -listCons(char *car, ListPtr cdr) -{ - ListPtr lcar = malloc(sizeof(ListRec)); - if(!lcar) - return NULL; - lcar -> value = car; - lcar -> next = cdr; - return lcar; -} - -ListPtr -listAdjoin(char *car, ListPtr cdr) -{ - if(listMember(car, cdr)) { - free(car); - return cdr; - } - return listCons(car, cdr); -} - -char * -dsprintf(char *f, ...) -{ - va_list args; - char *string; - { - int n, size = 20; - while(1) { - if(size > 4096) - return NULL; - string = malloc(size); - if(!string) - return NULL; - va_start(args, f); - n = vsnprintf(string, size, f, args); - va_end(args); - if(n >= 0 && n < size) - return string; - else if(n >= size) - size = n + 1; - else - size = size * 3 / 2 + 1; - free(string); - } - } -} - - -ListPtr -listConsF(ListPtr cdr, char *f, ...) -{ - va_list args; - char *string; - { - int n, size = 20; - while(1) { - if(size > 4096) - return NULL; - string = malloc(size); - if(!string) - return NULL; - va_start(args, f); - n = vsnprintf(string, size, f, args); - va_end(args); - if(n >= 0 && n < size) - return listCons(string, cdr); - else if(n >= size) - size = n + 1; - else - size = size * 3 / 2 + 1; - free(string); - } - } -} - -ListPtr -listAdjoinF(ListPtr cdr, char *f, ...) -{ - va_list args; - char *string; - { - int n, size = 20; - while(1) { - if(size > 4096) - return NULL; - string = malloc(size); - if(!string) - return NULL; - va_start(args, f); - n = vsnprintf(string, size, f, args); - va_end(args); - if(n >= 0 && n < size) - return listAdjoin(string, cdr); - else if(n >= size) - size = n + 1; - else - size = size * 3 / 2 + 1; - free(string); - } - } -} - -int -listLength(ListPtr list) -{ - int n = 0; - while(list) { - n++; - list = list->next; - } - return n; -} - -ListPtr -appendList(ListPtr first, ListPtr second) -{ - ListPtr current; - - if(second == NULL) - return first; - - if(first == NULL) - return second; - - for(current = first; current->next; current = current->next) - ; - - current->next = second; - return first; -} - -ListPtr -makeList(char **a, int n, ListPtr old, int begin) -{ - ListPtr first, current, next; - int i; - - if(n == 0) - return old; - - first = malloc(sizeof(ListRec)); - if(!first) - return NULL; - - first->value = a[0]; - first->next = NULL; - - current = first; - for(i = 1; i < n; i++) { - next = malloc(sizeof(ListRec)); - if(!next) { - destroyList(first); - return NULL; - } - next->value = a[i]; - next->next = NULL; - - current->next = next; - current = next; - } - if(begin) { - current->next = old; - return first; - } else { - return appendList(old, first); - } -} - -ListPtr -reverseList(ListPtr old) -{ - ListPtr new = NULL, current; - while(old) { - current = old; - old = old->next; - current->next = new; - new = current; - } - return new; -} - -/* qsort helper for sorting list entries */ -static int -compareListEntries(const void *a, const void *b) -{ - const ListPtr lista = *(const ListPtr *) a; - const ListPtr listb = *(const ListPtr *) b; - - return strcmp(lista->value, listb->value); -} - -ListPtr -sortList(ListPtr old) -{ - int i; - int l = listLength(old); - ListPtr n; - ListPtr *sorted = malloc(l * sizeof(ListPtr)); - - if (sorted == NULL) - return old; - - for (n = old, i = 0; n != NULL; n = n->next) { - sorted[i++] = n; - } - qsort(sorted, i, sizeof(ListPtr), compareListEntries); - n = sorted[0]; - for (i = 0; i < (l - 1); i++) { - sorted[i]->next = sorted[i+1]; - } - sorted[i]->next = NULL; - free(sorted); - return n; -} - -void -destroyList(ListPtr old) -{ - ListPtr next; - if(!old) - return; - while(old) { - next = old->next; - free(old); - old = next; - } -} - -void -deepDestroyList(ListPtr old) -{ - ListPtr next; - if(!old) - return; - while(old) { - next = old->next; - free(old->value); - free(old); - old = next; - } -} +/* + Copyright (c) 2002-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. +*/ + +#include +#include +#include +#include +#include "list.h" + +int +listMember(char *elt, ListPtr list) +{ + while(list != NULL) { + if(strcmp(elt, list->value) == 0) + return 1; + list = list->next; + } + return 0; +} + +ListPtr +listCons(char *car, ListPtr cdr) +{ + ListPtr lcar = malloc(sizeof(ListRec)); + if(!lcar) + return NULL; + lcar -> value = car; + lcar -> next = cdr; + return lcar; +} + +ListPtr +listAdjoin(char *car, ListPtr cdr) +{ + if(listMember(car, cdr)) { + free(car); + return cdr; + } + return listCons(car, cdr); +} + +char * +dsprintf(char *f, ...) +{ + va_list args; + char *string; + { + int n, size = 20; + while(1) { + if(size > 4096) + return NULL; + string = malloc(size); + if(!string) + return NULL; + va_start(args, f); + n = vsnprintf(string, size, f, args); + va_end(args); + if(n >= 0 && n < size) + return string; + else if(n >= size) + size = n + 1; + else + size = size * 3 / 2 + 1; + free(string); + } + } +} + + +ListPtr +listConsF(ListPtr cdr, char *f, ...) +{ + va_list args; + char *string; + { + int n, size = 20; + while(1) { + if(size > 4096) + return NULL; + string = malloc(size); + if(!string) + return NULL; + va_start(args, f); + n = vsnprintf(string, size, f, args); + va_end(args); + if(n >= 0 && n < size) + return listCons(string, cdr); + else if(n >= size) + size = n + 1; + else + size = size * 3 / 2 + 1; + free(string); + } + } +} + +ListPtr +listAdjoinF(ListPtr cdr, char *f, ...) +{ + va_list args; + char *string; + { + int n, size = 20; + while(1) { + if(size > 4096) + return NULL; + string = malloc(size); + if(!string) + return NULL; + va_start(args, f); + n = vsnprintf(string, size, f, args); + va_end(args); + if(n >= 0 && n < size) + return listAdjoin(string, cdr); + else if(n >= size) + size = n + 1; + else + size = size * 3 / 2 + 1; + free(string); + } + } +} + +int +listLength(ListPtr list) +{ + int n = 0; + while(list) { + n++; + list = list->next; + } + return n; +} + +ListPtr +appendList(ListPtr first, ListPtr second) +{ + ListPtr current; + + if(second == NULL) + return first; + + if(first == NULL) + return second; + + for(current = first; current->next; current = current->next) + ; + + current->next = second; + return first; +} + +ListPtr +makeList(char **a, int n, ListPtr old, int begin) +{ + ListPtr first, current, next; + int i; + + if(n == 0) + return old; + + first = malloc(sizeof(ListRec)); + if(!first) + return NULL; + + first->value = a[0]; + first->next = NULL; + + current = first; + for(i = 1; i < n; i++) { + next = malloc(sizeof(ListRec)); + if(!next) { + destroyList(first); + return NULL; + } + next->value = a[i]; + next->next = NULL; + + current->next = next; + current = next; + } + if(begin) { + current->next = old; + return first; + } else { + return appendList(old, first); + } +} + +ListPtr +reverseList(ListPtr old) +{ + ListPtr new = NULL, current; + while(old) { + current = old; + old = old->next; + current->next = new; + new = current; + } + return new; +} + +/* qsort helper for sorting list entries */ +static int +compareListEntries(const void *a, const void *b) +{ + const ListPtr lista = *(const ListPtr *) a; + const ListPtr listb = *(const ListPtr *) b; + + return strcmp(lista->value, listb->value); +} + +ListPtr +sortList(ListPtr old) +{ + int i; + int l = listLength(old); + ListPtr n; + ListPtr *sorted = malloc(l * sizeof(ListPtr)); + + if (sorted == NULL) + return old; + + for (n = old, i = 0; n != NULL; n = n->next) { + sorted[i++] = n; + } + qsort(sorted, i, sizeof(ListPtr), compareListEntries); + n = sorted[0]; + for (i = 0; i < (l - 1); i++) { + sorted[i]->next = sorted[i+1]; + } + sorted[i]->next = NULL; + free(sorted); + return n; +} + +void +destroyList(ListPtr old) +{ + ListPtr next; + if(!old) + return; + while(old) { + next = old->next; + free(old); + old = next; + } +} + +void +deepDestroyList(ListPtr old) +{ + ListPtr next; + if(!old) + return; + while(old) { + next = old->next; + free(old->value); + free(old); + old = next; + } +} diff --git a/mkfontscale/list.h b/mkfontscale/list.h index 42e4c0756..686fd9b09 100644 --- a/mkfontscale/list.h +++ b/mkfontscale/list.h @@ -1,48 +1,48 @@ -/* - Copyright (c) 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 _MKS_LIST_H_ -#define _MKS_LIST_H_ 1 - -#include /* for _X_ATTRIBUTE_PRINTF */ - -char *dsprintf(char *f, ...) _X_ATTRIBUTE_PRINTF(1,2); - -typedef struct _List { - char *value; - struct _List *next; -} ListRec, *ListPtr; - -int listMember(char *elt, ListPtr list); -ListPtr listCons(char *car, ListPtr cdr); -ListPtr listAdjoin(char *car, ListPtr cdr); -ListPtr listConsF(ListPtr cdr, char *f, ...) _X_ATTRIBUTE_PRINTF(2,3); -ListPtr listAdjoinF(ListPtr cdr, char *f, ...) _X_ATTRIBUTE_PRINTF(2,3); -int listLength(ListPtr list); -ListPtr appendList(ListPtr first, ListPtr second); -ListPtr makeList(char **a, int n, ListPtr old, int begin); -ListPtr reverseList(ListPtr old); -ListPtr sortList(ListPtr old); -void destroyList(ListPtr old); -void deepDestroyList(ListPtr old); - -#endif /* _MKS_LIST_H_ */ +/* + Copyright (c) 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 _MKS_LIST_H_ +#define _MKS_LIST_H_ 1 + +#include /* for _X_ATTRIBUTE_PRINTF */ + +char *dsprintf(char *f, ...) _X_ATTRIBUTE_PRINTF(1,2); + +typedef struct _List { + char *value; + struct _List *next; +} ListRec, *ListPtr; + +int listMember(char *elt, ListPtr list); +ListPtr listCons(char *car, ListPtr cdr); +ListPtr listAdjoin(char *car, ListPtr cdr); +ListPtr listConsF(ListPtr cdr, char *f, ...) _X_ATTRIBUTE_PRINTF(2,3); +ListPtr listAdjoinF(ListPtr cdr, char *f, ...) _X_ATTRIBUTE_PRINTF(2,3); +int listLength(ListPtr list); +ListPtr appendList(ListPtr first, ListPtr second); +ListPtr makeList(char **a, int n, ListPtr old, int begin); +ListPtr reverseList(ListPtr old); +ListPtr sortList(ListPtr old); +void destroyList(ListPtr old); +void deepDestroyList(ListPtr old); + +#endif /* _MKS_LIST_H_ */ diff --git a/mkfontscale/mkfontscale.c b/mkfontscale/mkfontscale.c index 74c749b60..31553cb5d 100644 --- a/mkfontscale/mkfontscale.c +++ b/mkfontscale/mkfontscale.c @@ -1,1296 +1,1296 @@ -/* - Copyright (c) 2002-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. -*/ - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include FT_FREETYPE_H -#include FT_SFNT_NAMES_H -#include FT_TRUETYPE_TABLES_H -#include FT_TRUETYPE_IDS_H -#include FT_TYPE1_TABLES_H -#include FT_BDF_H -#include FT_XFREE86_H - -#include "list.h" -#include "hash.h" -#include "data.h" -#include "ident.h" - -#define NPREFIX 1024 - -#ifndef MAXFONTFILENAMELEN -#define MAXFONTFILENAMELEN 1024 -#endif -#ifndef MAXFONTNAMELEN -#define MAXFONTNAMELEN 1024 -#endif - -/* Two levels of macro calls are needed so that we stringify the value - of MAXFONT... and not the string "MAXFONT..." */ -#define QUOTE(x) #x -#define STRINGIFY(x) QUOTE(x) - -static char *encodings_array[] = - { "ascii-0", - "iso8859-1", "iso8859-2", "iso8859-3", "iso8859-4", "iso8859-5", - "iso8859-6", "iso8859-6.8", "iso8859-6.8x", "iso8859-6.16", - "iso8859-7", "iso8859-8", "iso8859-9", "iso8859-10", - "iso8859-11", "iso8859-12", "iso8859-13", "iso8859-14", - "iso8859-15", "iso8859-16", - "ansi-1251", "koi8-r", "koi8-u", "koi8-ru", "koi8-e", "koi8-uni", - "tis620-2", - "sun.unicode.india-0", "suneu-greek", - "adobe-standard", "adobe-symbol", - "ibm-cp437", "ibm-cp850", "ibm-cp852", "ibm-cp866", "microsoft-cp1252", - /* But not "adobe-dingbats", as it uses generic glyph names. */ - "cns11643-1", "cns11643-2", "cns11643-3", - "jisx0201.1976-0", "jisx0208.1983-0", "jisx0208.1990-0", - "jisx0212.1990-0", "big5-0", "big5.eten-0", "big5hkscs-0", - "gb2312.1980-0", "gb18030.2000-0", "gb18030.2000-1", - "ksc5601.1987-0", "ksc5601.1992-3"}; - -static char *extra_encodings_array[] = - { "iso10646-1", "adobe-fontspecific", "microsoft-symbol" }; - -static ListPtr encodings, extra_encodings; -static char *outfilename; - -#define countof(_a) (sizeof(_a)/sizeof((_a)[0])) - -static int doDirectory(char*, int, ListPtr); -static int checkEncoding(FT_Face face, char *encoding_name); -static int checkExtraEncoding(FT_Face face, char *encoding_name, int found); -static int find_cmap(int type, int pid, int eid, FT_Face face); -static char* notice_foundry(char *notice); -static char* vendor_foundry(signed char *vendor); -static int readFontScale(HashTablePtr entries, char *dirname); -ListPtr makeXLFD(char *filename, FT_Face face, int); -static int readEncodings(ListPtr encodings, char *dirname); - -static FT_Library ft_library; -static float bigEncodingFuzz = 0.02; - -static int relative; -static int doScalable; -static int doBitmaps; -static int doISO10646_1_encoding; -static int onlyEncodings; -static ListPtr encodingsToDo; -static int reencodeLegacy; -static char *encodingPrefix; -static char *exclusionSuffix; - -static void -usage(void) -{ - fprintf(stderr, - "mkfontscale [ -b ] [ -s ] [ -o filename ] [-x suffix ]\n" - " [ -a encoding ] [ -f fuzz ] [ -l ] " - " [ -e directory ] [ -p prefix ] [ -n ] [ -r ] \n" - " [-u] [-U] [ directory ]...\n"); -} - -int -main(int argc, char **argv) -{ - int argn; - FT_Error ftrc; - int rc, ll = 0; - char prefix[NPREFIX]; - - encodingPrefix = NULL; - exclusionSuffix = NULL; - - if(getcwd(prefix, NPREFIX - 1) == NULL) { - perror("Couldn't get cwd"); - exit(1); - } - if(prefix[strlen(prefix) - 1] != '/') - strcat(prefix, "/"); - encodingPrefix = dsprintf("%s", prefix); - - outfilename = NULL; - - encodings = makeList(encodings_array, countof(encodings_array), NULL, 0); - - extra_encodings = makeList(extra_encodings_array, - countof(extra_encodings_array), - NULL, 0); - doBitmaps = 0; - doISO10646_1_encoding = 1; - doScalable = 1; - onlyEncodings = 0; - relative = 0; - reencodeLegacy = 1; - encodingsToDo = NULL; - - argn = 1; - while(argn < argc) { - if(argv[argn][0] == '\0' || argv[argn][0] != '-') - break; - if(argv[argn][1] == '-') { - argn++; - break; - } else if (strcmp(argv[argn], "-x") == 0) { - if(argn >= argc - 1) { - usage(); - exit(1); - } - exclusionSuffix = argv[argn + 1]; - argn += 2; - } else if(strcmp(argv[argn], "-a") == 0) { - if(argn >= argc - 1) { - usage(); - exit(1); - } - makeList(&argv[argn + 1], 1, encodings, 0); - argn += 2; - } else if(strcmp(argv[argn], "-p") == 0) { - if(argn >= argc - 1) { - usage(); - exit(1); - } - if(strlen(argv[argn + 1]) > NPREFIX - 1) { - usage(); - exit(1); - } - free(encodingPrefix); - encodingPrefix = dsprintf("%s", argv[argn + 1]); - argn += 2; - } else if(strcmp(argv[argn], "-e") == 0) { - if(argn >= argc - 1) { - usage(); - exit(1); - } - rc = readEncodings(encodingsToDo, argv[argn + 1]); - if(rc < 0) - exit(1); - argn += 2; - } else if(strcmp(argv[argn], "-b") == 0) { - doBitmaps = 1; - argn++; - } else if(strcmp(argv[argn], "-u") == 0) { - doISO10646_1_encoding = 0; - argn++; - } else if(strcmp(argv[argn], "-U") == 0) { - doISO10646_1_encoding = 1; - argn++; - } else if(strcmp(argv[argn], "-s") == 0) { - doScalable = 0; - argn++; - } else if(strcmp(argv[argn], "-n") == 0) { - onlyEncodings = 1; - argn++; - } else if(strcmp(argv[argn], "-r") == 0) { - relative = 1; - argn++; - } else if(strcmp(argv[argn], "-l") == 0) { - reencodeLegacy = !reencodeLegacy; - argn++; - } else if(strcmp(argv[argn], "-o") == 0) { - if(argn >= argc - 1) { - usage(); - exit(1); - } - outfilename = argv[argn + 1]; - argn += 2; - } else if(strcmp(argv[argn], "-f") == 0) { - if(argn >= argc - 1) { - usage(); - exit(1); - } - bigEncodingFuzz = atof(argv[argn + 1]) / 100.0; - argn += 2; - } else if (strcmp(argv[argn], "-r") == 0) { /* ignore for now */ - argn++; - } else if (strcmp(argv[argn], "-n") == 0) { - argn++; - } else { - usage(); - exit(1); - } - } - - if(outfilename == NULL) { - if(doBitmaps) - outfilename = "fonts.dir"; - else - outfilename = "fonts.scale"; - } - - ftrc = FT_Init_FreeType(&ft_library); - if(ftrc) { - fprintf(stderr, "Could not initialise FreeType library: %d\n", ftrc); - exit(1); - } - - ll = listLength(encodingsToDo); - - if (argn == argc) - doDirectory(".", ll, encodingsToDo); - else - while(argn < argc) { - doDirectory(argv[argn], ll, encodingsToDo); - argn++; - } - return 0; -} - -static int -getNameHelper(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) - continue; - break; - default: - continue; - } - if(name.string_len > 0) { - *name_return = name; - return 1; - } - } - } - return 0; -} - -static char * -getName(FT_Face face, int nid) -{ - FT_SfntName name; - char *string; - int i; - - if(getNameHelper(face, nid, - TT_PLATFORM_MICROSOFT, TT_MS_ID_UNICODE_CS, &name) || - getNameHelper(face, nid, - TT_PLATFORM_APPLE_UNICODE, -1, &name)) { - string = malloc(name.string_len / 2 + 1); - if(string == NULL) { - fprintf(stderr, "Couldn't allocate name\n"); - exit(1); - } - for(i = 0; i < name.string_len / 2; i++) { - if(name.string[2 * i] != 0) - string[i] = '?'; - else - string[i] = name.string[2 * i + 1]; - } - string[i] = '\0'; - return string; - } - - /* Pretend that Apple Roman is ISO 8859-1. */ - if(getNameHelper(face, nid, TT_PLATFORM_MACINTOSH, TT_MAC_ID_ROMAN, - &name)) { - string = malloc(name.string_len + 1); - if(string == NULL) { - fprintf(stderr, "Couldn't allocate name\n"); - exit(1); - } - memcpy(string, name.string, name.string_len); - string[name.string_len] = '\0'; - return string; - } - - return NULL; -} - -static char* -os2Weight(int weight) -{ - if(weight < 150) - return "thin"; - else if(weight < 250) - return "extralight"; - else if(weight < 350) - return "light"; - else if(weight < 450) - return "medium"; /* officially "normal" */ - else if(weight < 550) - return "medium"; - else if(weight < 650) - return "semibold"; - else if(weight < 750) - return "bold"; - else if(weight < 850) - return "extrabold"; - else - return "black"; -} - -static char* -os2Width(int width) -{ - if(width <= 1) - return "ultracondensed"; - else if(width <= 2) - return "extracondensed"; - else if(width <= 3) - return "condensed"; - else if(width <= 4) - return "semicondensed"; - else if(width <= 5) - return "normal"; - else if(width <= 6) - return "semiexpanded"; - else if(width <= 7) - return "expanded"; - else if(width <= 8) - return "extraexpanded"; - else - return "ultraexpanded"; -} - -static char *widths[] = { - "ultracondensed", "extracondensed", "condensed", "semicondensed", - "normal", "semiexpanded", "expanded", "extraexpanded", "ultraexpanded" -}; - -#define NUMWIDTHS (sizeof(widths) / sizeof(widths[0])) - -static char* -nameWidth(char *name) -{ - char buf[500]; - int i; - int n = strlen(name); - - if(n >= 499) return NULL; - for(i = 0; i < n; i++) - buf[i] = tolower(name[i]); - buf[i] = '\0'; - - for(i = 0; i < NUMWIDTHS; i++) - if(strstr(buf, widths[i])) - return widths[i]; - return NULL; -} - -static char* -t1Weight(char *weight) -{ - if(!weight) - return NULL; - if(strcmp(weight, "Thin") == 0) - return "thin"; - if(strcmp(weight, "Light") == 0) - return "light"; - if(strcmp(weight, "Regular") == 0) - return "medium"; - if(strcmp(weight, "Normal") == 0) - return "medium"; - if(strcmp(weight, "Medium") == 0) - return "medium"; - if(strcmp(weight, "Book") == 0) - return "medium"; - if(strcmp(weight, "Roman") == 0) /* Some URW++ fonts do that! */ - return "medium"; - if(strcmp(weight, "Demi") == 0) - return "semibold"; - if(strcmp(weight, "DemiBold") == 0) - return "semibold"; - if(strcmp(weight, "SemiBold") == 0) /* some TeX fonts apparently do that */ - return "semibold"; - else if(strcmp(weight, "Bold") == 0) - return "bold"; - else if(strcmp(weight, "Black") == 0) - return "black"; - else { - fprintf(stderr, "Unknown Type 1 weight \"%s\"\n", weight); - return NULL; - } -} - -static int -unsafe(char c) -{ - return - c < 0x20 || c > 0x7E || - c == '[' || c == ']' || c == '(' || c == ')' || c == '\\' || c == '-'; -} - -static char * -safe(char* s) -{ - int i, len, safe_flag = 1; - char *t; - - i = 0; - while(s[i] != '\0') { - if(unsafe(s[i])) - safe_flag = 0; - i++; - } - - if(safe_flag) return s; - - len = i; - t = malloc(len + 1); - if(t == NULL) { - perror("Couldn't allocate string"); - exit(1); - } - - for(i = 0; i < len; i++) { - if(unsafe(s[i])) - t[i] = ' '; - else - t[i] = s[i]; - } - t[i] = '\0'; - return t; -} - -ListPtr -makeXLFD(char *filename, FT_Face face, int isBitmap) -{ - ListPtr xlfd = NULL; - char *foundry, *family, *weight, *slant, *sWidth, *adstyle, - *spacing, *full_name; - TT_Header *head; - TT_HoriHeader *hhea; - TT_OS2 *os2; - TT_Postscript *post; - PS_FontInfoRec *t1info, t1info_rec; - int rc; - - foundry = NULL; - family = NULL; - weight = NULL; - slant = NULL; - sWidth = NULL; - adstyle = NULL; - spacing = NULL; - full_name = NULL; - - head = FT_Get_Sfnt_Table(face, ft_sfnt_head); - hhea = FT_Get_Sfnt_Table(face, ft_sfnt_hhea); - os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2); - post = FT_Get_Sfnt_Table(face, ft_sfnt_post); - - rc = FT_Get_PS_Font_Info(face, &t1info_rec); - if(rc == 0) - t1info = &t1info_rec; - else - t1info = NULL; - - if(!family) - family = getName(face, TT_NAME_ID_FONT_FAMILY); - if(!family) - family = getName(face, TT_NAME_ID_FULL_NAME); - if(!family) - family = getName(face, TT_NAME_ID_PS_NAME); - - if(!full_name) - full_name = getName(face, TT_NAME_ID_FULL_NAME); - if(!full_name) - full_name = getName(face, TT_NAME_ID_PS_NAME); - - if(os2 && os2->version != 0xFFFF) { - if(!weight) - weight = os2Weight(os2->usWeightClass); - if(!sWidth) - sWidth = os2Width(os2->usWidthClass); - if(!foundry) - foundry = vendor_foundry(os2->achVendID); - if(!slant) - slant = os2->fsSelection & 1 ? "i" : "r"; - } - - if(post) { - if(!spacing) { - if(post->isFixedPitch) { - if(hhea->min_Left_Side_Bearing >= 0 && - hhea->xMax_Extent <= hhea->advance_Width_Max) { - spacing = "c"; - } else { - spacing = "m"; - } - } else { - spacing = "p"; - } - } - } - - if(t1info) { - if(!family) - family = t1info->family_name; - if(!family) - family = t1info->full_name; - if(!full_name) - full_name = t1info->full_name; - if(!foundry) - foundry = notice_foundry(t1info->notice); - if(!weight) - weight = t1Weight(t1info->weight); - if(!spacing) - spacing = t1info->is_fixed_pitch ? "m" : "p"; - if(!slant) { - /* Bitstream fonts have positive italic angle. */ - slant = - t1info->italic_angle <= -4 || t1info->italic_angle >= 4 ? - "i" : "r"; - } - } - - if(!full_name) { - fprintf(stderr, "Couldn't determine full name for %s\n", filename); - full_name = filename; - } - - if(head) { - if(!slant) - slant = head->Mac_Style & 2 ? "i" : "r"; - if(!weight) - weight = head->Mac_Style & 1 ? "bold" : "medium"; - } - - if(!slant) { - fprintf(stderr, "Couldn't determine slant for %s\n", filename); - slant = "r"; - } - - if(!weight) { - fprintf(stderr, "Couldn't determine weight for %s\n", filename); - weight = "medium"; - } - - if(!foundry) { - char *notice; - notice = getName(face, TT_NAME_ID_TRADEMARK); - if(notice) { - foundry = notice_foundry(notice); - } - if(!foundry) { - notice = getName(face, TT_NAME_ID_MANUFACTURER); - if(notice) { - foundry = notice_foundry(notice); - } - } - } - - if(strcmp(slant, "i") == 0) { - if(strstr(full_name, "Oblique")) - slant = "o"; - if(strstr(full_name, "Slanted")) - slant = "o"; - } - - if(!sWidth) - sWidth = nameWidth(full_name); - - if(!foundry) foundry = "misc"; - if(!family) { - fprintf(stderr, "Couldn't get family name for %s\n", filename); - family = filename; - } - - if(!weight) weight = "medium"; - if(!slant) slant = "r"; - if(!sWidth) sWidth = "normal"; - if(!adstyle) adstyle = ""; - if(!spacing) spacing = "p"; - - /* Yes, it's a memory leak. */ - foundry = safe(foundry); - family = safe(family); - - if(!isBitmap) { - xlfd = listConsF(xlfd, - "-%s-%s-%s-%s-%s-%s-0-0-0-0-%s-0", - foundry, family, - weight, slant, sWidth, adstyle, spacing); - } else { - int i, w, h, xres, yres; - for(i = 0; i < face->num_fixed_sizes; i++) { - w = face->available_sizes[i].width; - h = face->available_sizes[i].height; - xres = 75; - yres = (double)h / w * xres; - xlfd = listConsF(xlfd, - "-%s-%s-%s-%s-%s-%s-%d-%d-%d-%d-%s-%d", - foundry, family, - weight, slant, sWidth, adstyle, - h, (int)(h / (double)yres * 72.27 * 10 + 0.5), - xres, yres, - spacing, 60); - } - } - return xlfd; -} - -static int -readFontScale(HashTablePtr entries, char *dirname) -{ - int n = strlen(dirname); - char *filename; - FILE *in; - int rc, count, i; - char file[MAXFONTFILENAMELEN+1], font[MAXFONTNAMELEN+1]; - - if(dirname[n - 1] == '/') - filename = dsprintf("%sfonts.scale", dirname); - else - filename = dsprintf("%s/fonts.scale", dirname); - if(filename == NULL) - return -1; - - in = fopen(filename, "r"); - free(filename); - if(in == NULL) { - if(errno != ENOENT) - perror("open(fonts.scale)"); - return -1; - } - - rc = fscanf(in, "%d\n", &count); - if(rc != 1) { - fprintf(stderr, "Invalid fonts.scale in %s.\n", dirname); - fclose(in); - return -1; - } - - for(i = 0; i < count; i++) { - rc = fscanf(in, - "%" STRINGIFY(MAXFONTFILENAMELEN) "s " - "%" STRINGIFY(MAXFONTNAMELEN) "[^\n]\n", - file, font); - if(rc != 2) - break; - putHash(entries, font, file, 100); - } - fclose(in); - return 1; -} - -static int -filePrio(char *filename) -{ - int n = strlen(filename); - if(n < 4) - return 0; - if(strcmp(filename + n - 4, ".otf") == 0) - return 6; - if(strcmp(filename + n - 4, ".OTF") == 0) - return 6; - if(strcmp(filename + n - 4, ".ttf") == 0) - return 5; - if(strcmp(filename + n - 4, ".TTF") == 0) - return 5; - if(strcmp(filename + n - 4, ".pcf") == 0) - return 4; - if(strcmp(filename + n - 4, ".PCF") == 0) - return 4; - if(strcmp(filename + n - 3, ".gz") == 0) - return 3; -#ifdef X_BZIP2_FONT_COMPRESSION - if(strcmp(filename + n - 4, ".bz2") == 0) - return 2; -#endif - if(strcmp(filename + n - 2, ".Z") == 0) - return 2; - if(strcmp(filename + n - 4, ".bdf") == 0) - return 1; - if(strcmp(filename + n - 4, ".BDF") == 0) - return 1; - return 0; -} - -static int -doDirectory(char *dirname_given, int numEncodings, ListPtr encodingsToDo) -{ - char *dirname, *fontscale_name, *filename, *encdir; - FILE *fontscale, *encfile; - DIR *dirp; - struct dirent *entry; - FT_Error ftrc; - FT_Face face; - ListPtr encoding, xlfd, lp; - HashTablePtr entries; - HashBucketPtr *array; - int i, n, found, rc; - int isBitmap=0,xl=0; - - if (exclusionSuffix) - xl = strlen (exclusionSuffix); - - i = strlen(dirname_given); - if(i == 0) - dirname = dsprintf("./"); - else if(dirname_given[i - 1] != '/') - dirname = dsprintf("%s/", dirname_given); - else - dirname = dsprintf("%s", dirname_given); - - if(dirname == NULL) { - perror("dirname"); - exit(1); - } - - if (onlyEncodings) - goto encodings; - - entries = makeHashTable(); - if(doBitmaps && !doScalable) { - readFontScale(entries, dirname); - } - - if(strcmp(outfilename, "-") == 0) - fontscale_name = NULL; - else { - if(outfilename[0] == '/') - fontscale_name = dsprintf("%s", outfilename); - else - fontscale_name = dsprintf("%s%s", dirname, outfilename); - if(fontscale_name == NULL) { - perror("fontscale_name"); - exit(1); - } - } - - dirp = opendir(dirname); - if(dirp == NULL) { - fprintf(stderr, "%s: ", dirname); - perror("opendir"); - return 0; - } - - if(fontscale_name == NULL) - fontscale = stdout; - else - fontscale = fopen(fontscale_name, "wb"); - - if(fontscale == NULL) { - fprintf(stderr, "%s: ", fontscale_name); - perror("fopen(w)"); - return 0; - } - - while((entry = readdir(dirp)) != NULL) { - int have_face = 0; - char *xlfd_name = NULL; - xlfd = NULL; - - if (xl) { - int dl = strlen (entry->d_name); - if (strcmp (entry->d_name + dl - xl, exclusionSuffix) == 0) - continue; - } - - filename = dsprintf("%s%s", dirname, entry->d_name); - - if(doBitmaps) - rc = bitmapIdentify(filename, &xlfd_name); - else - rc = 0; - - if(rc < 0) - goto done; - - if(rc == 0) { - ftrc = FT_New_Face(ft_library, filename, 0, &face); - if(ftrc) - goto done; - have_face = 1; - - isBitmap = ((face->face_flags & FT_FACE_FLAG_SCALABLE) == 0); - - if(!isBitmap) { - /* Workaround for bitmap-only SFNT fonts */ - if(FT_IS_SFNT(face) && face->num_fixed_sizes > 0 && - strcmp(FT_Get_X11_Font_Format(face), "TrueType") == 0) { - TT_MaxProfile *maxp; - maxp = FT_Get_Sfnt_Table(face, ft_sfnt_maxp); - if(maxp != NULL && maxp->maxContours == 0) - isBitmap = 1; - } - } - - if(isBitmap) { - if(!doBitmaps) - goto done; - } else { - if(!doScalable) - goto done; - } - - if(isBitmap) { - BDF_PropertyRec prop; - rc = FT_Get_BDF_Property(face, "FONT", &prop); - if(rc == 0 && prop.type == BDF_PROPERTY_TYPE_ATOM) { - xlfd_name = malloc(strlen(prop.u.atom) + 1); - if(xlfd_name == NULL) - goto done; - strcpy(xlfd_name, prop.u.atom); - } - } - } - - if(xlfd_name) { - /* We know it's a bitmap font, and we know its XLFD */ - int n = strlen(xlfd_name); - if(reencodeLegacy && - n >= 12 && strcasecmp(xlfd_name + n - 11, "-iso10646-1") == 0) { - char *s; - - s = malloc(n - 10); - memcpy(s, xlfd_name, n - 11); - s[n - 11] = '\0'; - xlfd = listCons(s, xlfd); - } else { - /* Not a reencodable font -- skip all the rest of the loop body */ - putHash(entries, xlfd_name, entry->d_name, filePrio(entry->d_name)); - goto done; - } - } - - if(!have_face) { - ftrc = FT_New_Face(ft_library, filename, 0, &face); - if(ftrc) - goto done; - have_face = 1; - isBitmap = ((face->face_flags & FT_FACE_FLAG_SCALABLE) == 0); - - if(!isBitmap) { - if(face->num_fixed_sizes > 0) { - TT_MaxProfile *maxp; - maxp = FT_Get_Sfnt_Table(face, ft_sfnt_maxp); - if(maxp != NULL && maxp->maxContours == 0) - isBitmap = 1; - } - } - } - - if(xlfd == NULL) - xlfd = makeXLFD(entry->d_name, face, isBitmap); - - found = 0; - - for(lp = xlfd; lp; lp = lp->next) { - char buf[MAXFONTNAMELEN]; - for(encoding = encodings; encoding; encoding = encoding->next) { - if(checkEncoding(face, encoding->value)) { - found = 1; - snprintf(buf, MAXFONTNAMELEN, "%s-%s", - lp->value, encoding->value); - putHash(entries, buf, entry->d_name, filePrio(entry->d_name)); - } - } - for(encoding = extra_encodings; encoding; - encoding = encoding->next) { - if(checkExtraEncoding(face, encoding->value, found)) { - /* Do not set found! */ - snprintf(buf, MAXFONTNAMELEN, "%s-%s", - lp->value, encoding->value); - putHash(entries, buf, entry->d_name, filePrio(entry->d_name)); - } - } - } - done: - if(have_face) - FT_Done_Face(face); - deepDestroyList(xlfd); - xlfd = NULL; - free(filename); - } - - closedir(dirp); - n = hashElements(entries); - fprintf(fontscale, "%d\n", n); - array = hashArray(entries, 1); - for(i = 0; i < n; i++) - fprintf(fontscale, "%s %s\n", array[i]->value, array[i]->key); - destroyHashArray(array); - entries = NULL; - if(fontscale_name) { - fclose(fontscale); - free(fontscale_name); - } - - encodings: - encdir = dsprintf("%s%s", dirname, "encodings.dir"); - - if(encdir == NULL) { - perror("encodings"); - exit(1); - } - unlink(encdir); - - if (numEncodings) { - encfile = fopen(encdir, "w"); - if(encfile == NULL) { - perror("open(encodings.dir)"); - exit(1); - } - fprintf(encfile, "%d\n", numEncodings); - encodingsToDo = sortList(encodingsToDo); - for(lp = encodingsToDo; lp; lp = lp->next) { - fprintf(encfile, "%s\n", lp->value); - } - fclose (encfile); - } - - free(dirname); - return 1; -} - -#define CODE_IGNORED(c) ((c) < 0x20 || \ - ((c) >= 0x7F && (c) <= 0xA0) || \ - (c) == 0xAD || (c) == 0xF71B) - -static int -checkEncoding(FT_Face face, char *encoding_name) -{ - FontEncPtr encoding; - FontMapPtr mapping; - int i, j, c, koi8; - char *n; - - encoding = FontEncFind(encoding_name, NULL); - if(!encoding) - return 0; - - /* An encoding is ``small'' if one of the following is true: - - it is linear and has no more than 256 codepoints; or - - it is a matrix encoding and has no more than one column. - - For small encodings using Unicode indices, we require perfect - coverage except for CODE_IGNORED and KOI-8 IBM-PC compatibility. - - For large encodings, we require coverage up to bigEncodingFuzz. - - For encodings using PS names (currently Adobe Standard and - Adobe Symbol only), we require perfect coverage. */ - - - if(FT_Has_PS_Glyph_Names(face)) { - for(mapping = encoding->mappings; mapping; mapping = mapping->next) { - if(mapping->type == FONT_ENCODING_POSTSCRIPT) { - if(encoding->row_size > 0) { - for(i = encoding->first; i < encoding->size; i++) { - for(j = encoding->first_col; - j < encoding->row_size; - j++) { - n = FontEncName((i<<8) | j, mapping); - if(n && FT_Get_Name_Index(face, n) == 0) { - return 0; - } - } - } - return 1; - } else { - for(i = encoding->first; i < encoding->size; i++) { - n = FontEncName(i, mapping); - if(n && FT_Get_Name_Index(face, n) == 0) { - return 0; - } - } - return 1; - } - } - } - } - - for(mapping = encoding->mappings; mapping; mapping = mapping->next) { - if(find_cmap(mapping->type, mapping->pid, mapping->eid, face)) { - int total = 0, failed = 0; - if(encoding->row_size > 0) { - int estimate = - (encoding->size - encoding->first) * - (encoding->row_size - encoding->first_col); - for(i = encoding->first; i < encoding->size; i++) { - for(j = encoding->first_col; - j < encoding->row_size; - j++) { - c = FontEncRecode((i<<8) | j, mapping); - if(CODE_IGNORED(c)) { - continue; - } else { - if(FT_Get_Char_Index(face, c) == 0) { - failed++; - } - total++; - if((encoding->size <= 1 && failed > 0) || - ((float)failed >= bigEncodingFuzz * estimate)) { - return 0; - } - } - } - } - if((float)failed >= total * bigEncodingFuzz) - return 0; - else - return 1; - } else { - int estimate = encoding->size - encoding->first; - /* For the KOI8 encodings, we ignore the lack of - linedrawing and pseudo-math characters */ - if(strncmp(encoding->name, "koi8-", 5) == 0) - koi8 = 1; - else - koi8 = 0; - for(i = encoding->first; i < encoding->size; i++) { - c = FontEncRecode(i, mapping); - if(CODE_IGNORED(c) || - (koi8 && ((c >= 0x2200 && c < 0x2600) || c == 0x00b2))) { - continue; - } else { - if(FT_Get_Char_Index(face, c) == 0) { - failed++; - } - total++; - if((encoding->size <= 256 && failed > 0) || - ((float)failed >= bigEncodingFuzz * estimate)) { - return 0; - } - } - } - if((float)failed >= total * bigEncodingFuzz) - return 0; - else - return 1; - } - } - } - return 0; -} - -static int -find_cmap(int type, int pid, int eid, FT_Face face) -{ - int i, n, rc; - FT_CharMap cmap = NULL; - - n = face->num_charmaps; - - switch(type) { - case FONT_ENCODING_TRUETYPE: /* specific cmap */ - for(i=0; icharmaps[i]; - if(cmap->platform_id == pid && cmap->encoding_id == eid) { - rc = FT_Set_Charmap(face, cmap); - if(rc == 0) - return 1; - } - } - break; - case FONT_ENCODING_UNICODE: /* any Unicode cmap */ - /* prefer Microsoft Unicode */ - for(i=0; icharmaps[i]; - if(cmap->platform_id == TT_PLATFORM_MICROSOFT && - cmap->encoding_id == TT_MS_ID_UNICODE_CS) { - rc = FT_Set_Charmap(face, cmap); - if(rc == 0) - return 1; - } - } - /* Try Apple Unicode */ - for(i=0; icharmaps[i]; - if(cmap->platform_id == TT_PLATFORM_APPLE_UNICODE) { - rc = FT_Set_Charmap(face, cmap); - if(rc == 0) - return 1; - } - } - /* ISO Unicode? */ - for(i=0; icharmaps[i]; - if(cmap->platform_id == TT_PLATFORM_ISO) { - rc = FT_Set_Charmap(face, cmap); - if(rc == 0) - return 1; - } - } - break; - default: - return 0; - } - return 0; -} - -static int -checkExtraEncoding(FT_Face face, char *encoding_name, int found) -{ - int c; - - if(strcasecmp(encoding_name, "iso10646-1") == 0) { - if(doISO10646_1_encoding && find_cmap(FONT_ENCODING_UNICODE, -1, -1, face)) { - int found = 0; - /* Export as Unicode if there are at least 15 BMP - characters that are not a space or ignored. */ - for(c = 0x21; c < 0x10000; c++) { - if(CODE_IGNORED(c)) - continue; - if(FT_Get_Char_Index(face, c) > 0) - found++; - if(found >= 15) - return 1; - } - return 0; - } else - return 0; - } else if(strcasecmp(encoding_name, "microsoft-symbol") == 0) { - if(find_cmap(FONT_ENCODING_TRUETYPE, - TT_PLATFORM_MICROSOFT, TT_MS_ID_SYMBOL_CS, - face)) - return 1; - else - return 0; - } else if(strcasecmp(encoding_name, "adobe-fontspecific") == 0) { - if(!found) { - if(FT_Has_PS_Glyph_Names(face)) - return 1; - else - return 0; - } else - return 0; - } else { - fprintf(stderr, "Unknown extra encoding %s\n", encoding_name); - return 0; - } -} - -static char* -notice_foundry(char *notice) -{ - int i; - for(i = 0; i < countof(notice_foundries); i++) - if(notice && strstr(notice, notice_foundries[i][0])) - return notice_foundries[i][1]; - return NULL; -} - -static int -vendor_match(signed char *vendor, char *vendor_string) -{ - /* vendor is not necessarily NUL-terminated. */ - int i, len; - len = strlen(vendor_string); - if(memcmp(vendor, vendor_string, len) != 0) - return 0; - for(i = len; i < 4; i++) - if(vendor[i] != ' ' && vendor[i] != '\0') - return 0; - return 1; -} - -static char* -vendor_foundry(signed char *vendor) -{ - int i; - for(i = 0; i < countof(vendor_foundries); i++) - if(vendor_match(vendor, vendor_foundries[i][0])) - return vendor_foundries[i][1]; - return NULL; -} - -static int -readEncodings(ListPtr encodings, char *dirname) -{ - char *fullname; - DIR *dirp; - struct dirent *file; - char **names, **name; - - if(strlen(dirname) > 1 && dirname[strlen(dirname) - 1] == '/') - dirname[strlen(dirname) - 1] = '\0'; - - dirp = opendir(dirname); - if(dirp == NULL) { - perror("opendir"); - return -1; - } - - while((file = readdir(dirp)) != NULL) { - fullname = dsprintf("%s/%s", dirname, file->d_name); - if(fullname == NULL) { - fprintf(stderr, "Couldn't allocate fullname\n"); - closedir(dirp); - return -1; - } - - names = FontEncIdentify(fullname); - if(!names) - continue; - - for(name = names; *name; name++) { - if(fullname[0] != '/' && !relative) { - char *n; - n = dsprintf("%s%s", encodingPrefix, fullname); - if(n == NULL) { - fprintf(stderr, "Couldn't allocate name\n"); - closedir(dirp); - return -1; - } - encodingsToDo = listConsF(encodingsToDo, "%s %s", *name, n); - free(n); - } else { - encodingsToDo = - listConsF(encodingsToDo, "%s %s", *name, fullname); - } - if(encodingsToDo == NULL) { - fprintf(stderr, "Couldn't allocate encodings\n"); - closedir(dirp); - return -1; - } - } - free(names); /* only the spine */ - } - closedir(dirp); - return 0; -} +/* + Copyright (c) 2002-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. +*/ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include FT_FREETYPE_H +#include FT_SFNT_NAMES_H +#include FT_TRUETYPE_TABLES_H +#include FT_TRUETYPE_IDS_H +#include FT_TYPE1_TABLES_H +#include FT_BDF_H +#include FT_XFREE86_H + +#include "list.h" +#include "hash.h" +#include "data.h" +#include "ident.h" + +#define NPREFIX 1024 + +#ifndef MAXFONTFILENAMELEN +#define MAXFONTFILENAMELEN 1024 +#endif +#ifndef MAXFONTNAMELEN +#define MAXFONTNAMELEN 1024 +#endif + +/* Two levels of macro calls are needed so that we stringify the value + of MAXFONT... and not the string "MAXFONT..." */ +#define QUOTE(x) #x +#define STRINGIFY(x) QUOTE(x) + +static char *encodings_array[] = + { "ascii-0", + "iso8859-1", "iso8859-2", "iso8859-3", "iso8859-4", "iso8859-5", + "iso8859-6", "iso8859-6.8", "iso8859-6.8x", "iso8859-6.16", + "iso8859-7", "iso8859-8", "iso8859-9", "iso8859-10", + "iso8859-11", "iso8859-12", "iso8859-13", "iso8859-14", + "iso8859-15", "iso8859-16", + "ansi-1251", "koi8-r", "koi8-u", "koi8-ru", "koi8-e", "koi8-uni", + "tis620-2", + "sun.unicode.india-0", "suneu-greek", + "adobe-standard", "adobe-symbol", + "ibm-cp437", "ibm-cp850", "ibm-cp852", "ibm-cp866", "microsoft-cp1252", + /* But not "adobe-dingbats", as it uses generic glyph names. */ + "cns11643-1", "cns11643-2", "cns11643-3", + "jisx0201.1976-0", "jisx0208.1983-0", "jisx0208.1990-0", + "jisx0212.1990-0", "big5-0", "big5.eten-0", "big5hkscs-0", + "gb2312.1980-0", "gb18030.2000-0", "gb18030.2000-1", + "ksc5601.1987-0", "ksc5601.1992-3"}; + +static char *extra_encodings_array[] = + { "iso10646-1", "adobe-fontspecific", "microsoft-symbol" }; + +static ListPtr encodings, extra_encodings; +static char *outfilename; + +#define countof(_a) (sizeof(_a)/sizeof((_a)[0])) + +static int doDirectory(char*, int, ListPtr); +static int checkEncoding(FT_Face face, char *encoding_name); +static int checkExtraEncoding(FT_Face face, char *encoding_name, int found); +static int find_cmap(int type, int pid, int eid, FT_Face face); +static char* notice_foundry(char *notice); +static char* vendor_foundry(signed char *vendor); +static int readFontScale(HashTablePtr entries, char *dirname); +ListPtr makeXLFD(char *filename, FT_Face face, int); +static int readEncodings(ListPtr encodings, char *dirname); + +static FT_Library ft_library; +static float bigEncodingFuzz = 0.02; + +static int relative; +static int doScalable; +static int doBitmaps; +static int doISO10646_1_encoding; +static int onlyEncodings; +static ListPtr encodingsToDo; +static int reencodeLegacy; +static char *encodingPrefix; +static char *exclusionSuffix; + +static void +usage(void) +{ + fprintf(stderr, + "mkfontscale [ -b ] [ -s ] [ -o filename ] [-x suffix ]\n" + " [ -a encoding ] [ -f fuzz ] [ -l ] " + " [ -e directory ] [ -p prefix ] [ -n ] [ -r ] \n" + " [-u] [-U] [ directory ]...\n"); +} + +int +main(int argc, char **argv) +{ + int argn; + FT_Error ftrc; + int rc, ll = 0; + char prefix[NPREFIX]; + + encodingPrefix = NULL; + exclusionSuffix = NULL; + + if(getcwd(prefix, NPREFIX - 1) == NULL) { + perror("Couldn't get cwd"); + exit(1); + } + if(prefix[strlen(prefix) - 1] != '/') + strcat(prefix, "/"); + encodingPrefix = dsprintf("%s", prefix); + + outfilename = NULL; + + encodings = makeList(encodings_array, countof(encodings_array), NULL, 0); + + extra_encodings = makeList(extra_encodings_array, + countof(extra_encodings_array), + NULL, 0); + doBitmaps = 0; + doISO10646_1_encoding = 1; + doScalable = 1; + onlyEncodings = 0; + relative = 0; + reencodeLegacy = 1; + encodingsToDo = NULL; + + argn = 1; + while(argn < argc) { + if(argv[argn][0] == '\0' || argv[argn][0] != '-') + break; + if(argv[argn][1] == '-') { + argn++; + break; + } else if (strcmp(argv[argn], "-x") == 0) { + if(argn >= argc - 1) { + usage(); + exit(1); + } + exclusionSuffix = argv[argn + 1]; + argn += 2; + } else if(strcmp(argv[argn], "-a") == 0) { + if(argn >= argc - 1) { + usage(); + exit(1); + } + makeList(&argv[argn + 1], 1, encodings, 0); + argn += 2; + } else if(strcmp(argv[argn], "-p") == 0) { + if(argn >= argc - 1) { + usage(); + exit(1); + } + if(strlen(argv[argn + 1]) > NPREFIX - 1) { + usage(); + exit(1); + } + free(encodingPrefix); + encodingPrefix = dsprintf("%s", argv[argn + 1]); + argn += 2; + } else if(strcmp(argv[argn], "-e") == 0) { + if(argn >= argc - 1) { + usage(); + exit(1); + } + rc = readEncodings(encodingsToDo, argv[argn + 1]); + if(rc < 0) + exit(1); + argn += 2; + } else if(strcmp(argv[argn], "-b") == 0) { + doBitmaps = 1; + argn++; + } else if(strcmp(argv[argn], "-u") == 0) { + doISO10646_1_encoding = 0; + argn++; + } else if(strcmp(argv[argn], "-U") == 0) { + doISO10646_1_encoding = 1; + argn++; + } else if(strcmp(argv[argn], "-s") == 0) { + doScalable = 0; + argn++; + } else if(strcmp(argv[argn], "-n") == 0) { + onlyEncodings = 1; + argn++; + } else if(strcmp(argv[argn], "-r") == 0) { + relative = 1; + argn++; + } else if(strcmp(argv[argn], "-l") == 0) { + reencodeLegacy = !reencodeLegacy; + argn++; + } else if(strcmp(argv[argn], "-o") == 0) { + if(argn >= argc - 1) { + usage(); + exit(1); + } + outfilename = argv[argn + 1]; + argn += 2; + } else if(strcmp(argv[argn], "-f") == 0) { + if(argn >= argc - 1) { + usage(); + exit(1); + } + bigEncodingFuzz = atof(argv[argn + 1]) / 100.0; + argn += 2; + } else if (strcmp(argv[argn], "-r") == 0) { /* ignore for now */ + argn++; + } else if (strcmp(argv[argn], "-n") == 0) { + argn++; + } else { + usage(); + exit(1); + } + } + + if(outfilename == NULL) { + if(doBitmaps) + outfilename = "fonts.dir"; + else + outfilename = "fonts.scale"; + } + + ftrc = FT_Init_FreeType(&ft_library); + if(ftrc) { + fprintf(stderr, "Could not initialise FreeType library: %d\n", ftrc); + exit(1); + } + + ll = listLength(encodingsToDo); + + if (argn == argc) + doDirectory(".", ll, encodingsToDo); + else + while(argn < argc) { + doDirectory(argv[argn], ll, encodingsToDo); + argn++; + } + return 0; +} + +static int +getNameHelper(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) + continue; + break; + default: + continue; + } + if(name.string_len > 0) { + *name_return = name; + return 1; + } + } + } + return 0; +} + +static char * +getName(FT_Face face, int nid) +{ + FT_SfntName name; + char *string; + int i; + + if(getNameHelper(face, nid, + TT_PLATFORM_MICROSOFT, TT_MS_ID_UNICODE_CS, &name) || + getNameHelper(face, nid, + TT_PLATFORM_APPLE_UNICODE, -1, &name)) { + string = malloc(name.string_len / 2 + 1); + if(string == NULL) { + fprintf(stderr, "Couldn't allocate name\n"); + exit(1); + } + for(i = 0; i < name.string_len / 2; i++) { + if(name.string[2 * i] != 0) + string[i] = '?'; + else + string[i] = name.string[2 * i + 1]; + } + string[i] = '\0'; + return string; + } + + /* Pretend that Apple Roman is ISO 8859-1. */ + if(getNameHelper(face, nid, TT_PLATFORM_MACINTOSH, TT_MAC_ID_ROMAN, + &name)) { + string = malloc(name.string_len + 1); + if(string == NULL) { + fprintf(stderr, "Couldn't allocate name\n"); + exit(1); + } + memcpy(string, name.string, name.string_len); + string[name.string_len] = '\0'; + return string; + } + + return NULL; +} + +static char* +os2Weight(int weight) +{ + if(weight < 150) + return "thin"; + else if(weight < 250) + return "extralight"; + else if(weight < 350) + return "light"; + else if(weight < 450) + return "medium"; /* officially "normal" */ + else if(weight < 550) + return "medium"; + else if(weight < 650) + return "semibold"; + else if(weight < 750) + return "bold"; + else if(weight < 850) + return "extrabold"; + else + return "black"; +} + +static char* +os2Width(int width) +{ + if(width <= 1) + return "ultracondensed"; + else if(width <= 2) + return "extracondensed"; + else if(width <= 3) + return "condensed"; + else if(width <= 4) + return "semicondensed"; + else if(width <= 5) + return "normal"; + else if(width <= 6) + return "semiexpanded"; + else if(width <= 7) + return "expanded"; + else if(width <= 8) + return "extraexpanded"; + else + return "ultraexpanded"; +} + +static char *widths[] = { + "ultracondensed", "extracondensed", "condensed", "semicondensed", + "normal", "semiexpanded", "expanded", "extraexpanded", "ultraexpanded" +}; + +#define NUMWIDTHS (sizeof(widths) / sizeof(widths[0])) + +static char* +nameWidth(char *name) +{ + char buf[500]; + int i; + int n = strlen(name); + + if(n >= 499) return NULL; + for(i = 0; i < n; i++) + buf[i] = tolower(name[i]); + buf[i] = '\0'; + + for(i = 0; i < NUMWIDTHS; i++) + if(strstr(buf, widths[i])) + return widths[i]; + return NULL; +} + +static char* +t1Weight(char *weight) +{ + if(!weight) + return NULL; + if(strcmp(weight, "Thin") == 0) + return "thin"; + if(strcmp(weight, "Light") == 0) + return "light"; + if(strcmp(weight, "Regular") == 0) + return "medium"; + if(strcmp(weight, "Normal") == 0) + return "medium"; + if(strcmp(weight, "Medium") == 0) + return "medium"; + if(strcmp(weight, "Book") == 0) + return "medium"; + if(strcmp(weight, "Roman") == 0) /* Some URW++ fonts do that! */ + return "medium"; + if(strcmp(weight, "Demi") == 0) + return "semibold"; + if(strcmp(weight, "DemiBold") == 0) + return "semibold"; + if(strcmp(weight, "SemiBold") == 0) /* some TeX fonts apparently do that */ + return "semibold"; + else if(strcmp(weight, "Bold") == 0) + return "bold"; + else if(strcmp(weight, "Black") == 0) + return "black"; + else { + fprintf(stderr, "Unknown Type 1 weight \"%s\"\n", weight); + return NULL; + } +} + +static int +unsafe(char c) +{ + return + c < 0x20 || c > 0x7E || + c == '[' || c == ']' || c == '(' || c == ')' || c == '\\' || c == '-'; +} + +static char * +safe(char* s) +{ + int i, len, safe_flag = 1; + char *t; + + i = 0; + while(s[i] != '\0') { + if(unsafe(s[i])) + safe_flag = 0; + i++; + } + + if(safe_flag) return s; + + len = i; + t = malloc(len + 1); + if(t == NULL) { + perror("Couldn't allocate string"); + exit(1); + } + + for(i = 0; i < len; i++) { + if(unsafe(s[i])) + t[i] = ' '; + else + t[i] = s[i]; + } + t[i] = '\0'; + return t; +} + +ListPtr +makeXLFD(char *filename, FT_Face face, int isBitmap) +{ + ListPtr xlfd = NULL; + char *foundry, *family, *weight, *slant, *sWidth, *adstyle, + *spacing, *full_name; + TT_Header *head; + TT_HoriHeader *hhea; + TT_OS2 *os2; + TT_Postscript *post; + PS_FontInfoRec *t1info, t1info_rec; + int rc; + + foundry = NULL; + family = NULL; + weight = NULL; + slant = NULL; + sWidth = NULL; + adstyle = NULL; + spacing = NULL; + full_name = NULL; + + head = FT_Get_Sfnt_Table(face, ft_sfnt_head); + hhea = FT_Get_Sfnt_Table(face, ft_sfnt_hhea); + os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2); + post = FT_Get_Sfnt_Table(face, ft_sfnt_post); + + rc = FT_Get_PS_Font_Info(face, &t1info_rec); + if(rc == 0) + t1info = &t1info_rec; + else + t1info = NULL; + + if(!family) + family = getName(face, TT_NAME_ID_FONT_FAMILY); + if(!family) + family = getName(face, TT_NAME_ID_FULL_NAME); + if(!family) + family = getName(face, TT_NAME_ID_PS_NAME); + + if(!full_name) + full_name = getName(face, TT_NAME_ID_FULL_NAME); + if(!full_name) + full_name = getName(face, TT_NAME_ID_PS_NAME); + + if(os2 && os2->version != 0xFFFF) { + if(!weight) + weight = os2Weight(os2->usWeightClass); + if(!sWidth) + sWidth = os2Width(os2->usWidthClass); + if(!foundry) + foundry = vendor_foundry(os2->achVendID); + if(!slant) + slant = os2->fsSelection & 1 ? "i" : "r"; + } + + if(post) { + if(!spacing) { + if(post->isFixedPitch) { + if(hhea->min_Left_Side_Bearing >= 0 && + hhea->xMax_Extent <= hhea->advance_Width_Max) { + spacing = "c"; + } else { + spacing = "m"; + } + } else { + spacing = "p"; + } + } + } + + if(t1info) { + if(!family) + family = t1info->family_name; + if(!family) + family = t1info->full_name; + if(!full_name) + full_name = t1info->full_name; + if(!foundry) + foundry = notice_foundry(t1info->notice); + if(!weight) + weight = t1Weight(t1info->weight); + if(!spacing) + spacing = t1info->is_fixed_pitch ? "m" : "p"; + if(!slant) { + /* Bitstream fonts have positive italic angle. */ + slant = + t1info->italic_angle <= -4 || t1info->italic_angle >= 4 ? + "i" : "r"; + } + } + + if(!full_name) { + fprintf(stderr, "Couldn't determine full name for %s\n", filename); + full_name = filename; + } + + if(head) { + if(!slant) + slant = head->Mac_Style & 2 ? "i" : "r"; + if(!weight) + weight = head->Mac_Style & 1 ? "bold" : "medium"; + } + + if(!slant) { + fprintf(stderr, "Couldn't determine slant for %s\n", filename); + slant = "r"; + } + + if(!weight) { + fprintf(stderr, "Couldn't determine weight for %s\n", filename); + weight = "medium"; + } + + if(!foundry) { + char *notice; + notice = getName(face, TT_NAME_ID_TRADEMARK); + if(notice) { + foundry = notice_foundry(notice); + } + if(!foundry) { + notice = getName(face, TT_NAME_ID_MANUFACTURER); + if(notice) { + foundry = notice_foundry(notice); + } + } + } + + if(strcmp(slant, "i") == 0) { + if(strstr(full_name, "Oblique")) + slant = "o"; + if(strstr(full_name, "Slanted")) + slant = "o"; + } + + if(!sWidth) + sWidth = nameWidth(full_name); + + if(!foundry) foundry = "misc"; + if(!family) { + fprintf(stderr, "Couldn't get family name for %s\n", filename); + family = filename; + } + + if(!weight) weight = "medium"; + if(!slant) slant = "r"; + if(!sWidth) sWidth = "normal"; + if(!adstyle) adstyle = ""; + if(!spacing) spacing = "p"; + + /* Yes, it's a memory leak. */ + foundry = safe(foundry); + family = safe(family); + + if(!isBitmap) { + xlfd = listConsF(xlfd, + "-%s-%s-%s-%s-%s-%s-0-0-0-0-%s-0", + foundry, family, + weight, slant, sWidth, adstyle, spacing); + } else { + int i, w, h, xres, yres; + for(i = 0; i < face->num_fixed_sizes; i++) { + w = face->available_sizes[i].width; + h = face->available_sizes[i].height; + xres = 75; + yres = (double)h / w * xres; + xlfd = listConsF(xlfd, + "-%s-%s-%s-%s-%s-%s-%d-%d-%d-%d-%s-%d", + foundry, family, + weight, slant, sWidth, adstyle, + h, (int)(h / (double)yres * 72.27 * 10 + 0.5), + xres, yres, + spacing, 60); + } + } + return xlfd; +} + +static int +readFontScale(HashTablePtr entries, char *dirname) +{ + int n = strlen(dirname); + char *filename; + FILE *in; + int rc, count, i; + char file[MAXFONTFILENAMELEN+1], font[MAXFONTNAMELEN+1]; + + if(dirname[n - 1] == '/') + filename = dsprintf("%sfonts.scale", dirname); + else + filename = dsprintf("%s/fonts.scale", dirname); + if(filename == NULL) + return -1; + + in = fopen(filename, "r"); + free(filename); + if(in == NULL) { + if(errno != ENOENT) + perror("open(fonts.scale)"); + return -1; + } + + rc = fscanf(in, "%d\n", &count); + if(rc != 1) { + fprintf(stderr, "Invalid fonts.scale in %s.\n", dirname); + fclose(in); + return -1; + } + + for(i = 0; i < count; i++) { + rc = fscanf(in, + "%" STRINGIFY(MAXFONTFILENAMELEN) "s " + "%" STRINGIFY(MAXFONTNAMELEN) "[^\n]\n", + file, font); + if(rc != 2) + break; + putHash(entries, font, file, 100); + } + fclose(in); + return 1; +} + +static int +filePrio(char *filename) +{ + int n = strlen(filename); + if(n < 4) + return 0; + if(strcmp(filename + n - 4, ".otf") == 0) + return 6; + if(strcmp(filename + n - 4, ".OTF") == 0) + return 6; + if(strcmp(filename + n - 4, ".ttf") == 0) + return 5; + if(strcmp(filename + n - 4, ".TTF") == 0) + return 5; + if(strcmp(filename + n - 4, ".pcf") == 0) + return 4; + if(strcmp(filename + n - 4, ".PCF") == 0) + return 4; + if(strcmp(filename + n - 3, ".gz") == 0) + return 3; +#ifdef X_BZIP2_FONT_COMPRESSION + if(strcmp(filename + n - 4, ".bz2") == 0) + return 2; +#endif + if(strcmp(filename + n - 2, ".Z") == 0) + return 2; + if(strcmp(filename + n - 4, ".bdf") == 0) + return 1; + if(strcmp(filename + n - 4, ".BDF") == 0) + return 1; + return 0; +} + +static int +doDirectory(char *dirname_given, int numEncodings, ListPtr encodingsToDo) +{ + char *dirname, *fontscale_name, *filename, *encdir; + FILE *fontscale, *encfile; + DIR *dirp; + struct dirent *entry; + FT_Error ftrc; + FT_Face face; + ListPtr encoding, xlfd, lp; + HashTablePtr entries; + HashBucketPtr *array; + int i, n, found, rc; + int isBitmap=0,xl=0; + + if (exclusionSuffix) + xl = strlen (exclusionSuffix); + + i = strlen(dirname_given); + if(i == 0) + dirname = dsprintf("./"); + else if(dirname_given[i - 1] != '/') + dirname = dsprintf("%s/", dirname_given); + else + dirname = dsprintf("%s", dirname_given); + + if(dirname == NULL) { + perror("dirname"); + exit(1); + } + + if (onlyEncodings) + goto encodings; + + entries = makeHashTable(); + if(doBitmaps && !doScalable) { + readFontScale(entries, dirname); + } + + if(strcmp(outfilename, "-") == 0) + fontscale_name = NULL; + else { + if(outfilename[0] == '/') + fontscale_name = dsprintf("%s", outfilename); + else + fontscale_name = dsprintf("%s%s", dirname, outfilename); + if(fontscale_name == NULL) { + perror("fontscale_name"); + exit(1); + } + } + + dirp = opendir(dirname); + if(dirp == NULL) { + fprintf(stderr, "%s: ", dirname); + perror("opendir"); + return 0; + } + + if(fontscale_name == NULL) + fontscale = stdout; + else + fontscale = fopen(fontscale_name, "wb"); + + if(fontscale == NULL) { + fprintf(stderr, "%s: ", fontscale_name); + perror("fopen(w)"); + return 0; + } + + while((entry = readdir(dirp)) != NULL) { + int have_face = 0; + char *xlfd_name = NULL; + xlfd = NULL; + + if (xl) { + int dl = strlen (entry->d_name); + if (strcmp (entry->d_name + dl - xl, exclusionSuffix) == 0) + continue; + } + + filename = dsprintf("%s%s", dirname, entry->d_name); + + if(doBitmaps) + rc = bitmapIdentify(filename, &xlfd_name); + else + rc = 0; + + if(rc < 0) + goto done; + + if(rc == 0) { + ftrc = FT_New_Face(ft_library, filename, 0, &face); + if(ftrc) + goto done; + have_face = 1; + + isBitmap = ((face->face_flags & FT_FACE_FLAG_SCALABLE) == 0); + + if(!isBitmap) { + /* Workaround for bitmap-only SFNT fonts */ + if(FT_IS_SFNT(face) && face->num_fixed_sizes > 0 && + strcmp(FT_Get_X11_Font_Format(face), "TrueType") == 0) { + TT_MaxProfile *maxp; + maxp = FT_Get_Sfnt_Table(face, ft_sfnt_maxp); + if(maxp != NULL && maxp->maxContours == 0) + isBitmap = 1; + } + } + + if(isBitmap) { + if(!doBitmaps) + goto done; + } else { + if(!doScalable) + goto done; + } + + if(isBitmap) { + BDF_PropertyRec prop; + rc = FT_Get_BDF_Property(face, "FONT", &prop); + if(rc == 0 && prop.type == BDF_PROPERTY_TYPE_ATOM) { + xlfd_name = malloc(strlen(prop.u.atom) + 1); + if(xlfd_name == NULL) + goto done; + strcpy(xlfd_name, prop.u.atom); + } + } + } + + if(xlfd_name) { + /* We know it's a bitmap font, and we know its XLFD */ + int n = strlen(xlfd_name); + if(reencodeLegacy && + n >= 12 && strcasecmp(xlfd_name + n - 11, "-iso10646-1") == 0) { + char *s; + + s = malloc(n - 10); + memcpy(s, xlfd_name, n - 11); + s[n - 11] = '\0'; + xlfd = listCons(s, xlfd); + } else { + /* Not a reencodable font -- skip all the rest of the loop body */ + putHash(entries, xlfd_name, entry->d_name, filePrio(entry->d_name)); + goto done; + } + } + + if(!have_face) { + ftrc = FT_New_Face(ft_library, filename, 0, &face); + if(ftrc) + goto done; + have_face = 1; + isBitmap = ((face->face_flags & FT_FACE_FLAG_SCALABLE) == 0); + + if(!isBitmap) { + if(face->num_fixed_sizes > 0) { + TT_MaxProfile *maxp; + maxp = FT_Get_Sfnt_Table(face, ft_sfnt_maxp); + if(maxp != NULL && maxp->maxContours == 0) + isBitmap = 1; + } + } + } + + if(xlfd == NULL) + xlfd = makeXLFD(entry->d_name, face, isBitmap); + + found = 0; + + for(lp = xlfd; lp; lp = lp->next) { + char buf[MAXFONTNAMELEN]; + for(encoding = encodings; encoding; encoding = encoding->next) { + if(checkEncoding(face, encoding->value)) { + found = 1; + snprintf(buf, MAXFONTNAMELEN, "%s-%s", + lp->value, encoding->value); + putHash(entries, buf, entry->d_name, filePrio(entry->d_name)); + } + } + for(encoding = extra_encodings; encoding; + encoding = encoding->next) { + if(checkExtraEncoding(face, encoding->value, found)) { + /* Do not set found! */ + snprintf(buf, MAXFONTNAMELEN, "%s-%s", + lp->value, encoding->value); + putHash(entries, buf, entry->d_name, filePrio(entry->d_name)); + } + } + } + done: + if(have_face) + FT_Done_Face(face); + deepDestroyList(xlfd); + xlfd = NULL; + free(filename); + } + + closedir(dirp); + n = hashElements(entries); + fprintf(fontscale, "%d\n", n); + array = hashArray(entries, 1); + for(i = 0; i < n; i++) + fprintf(fontscale, "%s %s\n", array[i]->value, array[i]->key); + destroyHashArray(array); + entries = NULL; + if(fontscale_name) { + fclose(fontscale); + free(fontscale_name); + } + + encodings: + encdir = dsprintf("%s%s", dirname, "encodings.dir"); + + if(encdir == NULL) { + perror("encodings"); + exit(1); + } + unlink(encdir); + + if (numEncodings) { + encfile = fopen(encdir, "w"); + if(encfile == NULL) { + perror("open(encodings.dir)"); + exit(1); + } + fprintf(encfile, "%d\n", numEncodings); + encodingsToDo = sortList(encodingsToDo); + for(lp = encodingsToDo; lp; lp = lp->next) { + fprintf(encfile, "%s\n", lp->value); + } + fclose (encfile); + } + + free(dirname); + return 1; +} + +#define CODE_IGNORED(c) ((c) < 0x20 || \ + ((c) >= 0x7F && (c) <= 0xA0) || \ + (c) == 0xAD || (c) == 0xF71B) + +static int +checkEncoding(FT_Face face, char *encoding_name) +{ + FontEncPtr encoding; + FontMapPtr mapping; + int i, j, c, koi8; + char *n; + + encoding = FontEncFind(encoding_name, NULL); + if(!encoding) + return 0; + + /* An encoding is ``small'' if one of the following is true: + - it is linear and has no more than 256 codepoints; or + - it is a matrix encoding and has no more than one column. + + For small encodings using Unicode indices, we require perfect + coverage except for CODE_IGNORED and KOI-8 IBM-PC compatibility. + + For large encodings, we require coverage up to bigEncodingFuzz. + + For encodings using PS names (currently Adobe Standard and + Adobe Symbol only), we require perfect coverage. */ + + + if(FT_Has_PS_Glyph_Names(face)) { + for(mapping = encoding->mappings; mapping; mapping = mapping->next) { + if(mapping->type == FONT_ENCODING_POSTSCRIPT) { + if(encoding->row_size > 0) { + for(i = encoding->first; i < encoding->size; i++) { + for(j = encoding->first_col; + j < encoding->row_size; + j++) { + n = FontEncName((i<<8) | j, mapping); + if(n && FT_Get_Name_Index(face, n) == 0) { + return 0; + } + } + } + return 1; + } else { + for(i = encoding->first; i < encoding->size; i++) { + n = FontEncName(i, mapping); + if(n && FT_Get_Name_Index(face, n) == 0) { + return 0; + } + } + return 1; + } + } + } + } + + for(mapping = encoding->mappings; mapping; mapping = mapping->next) { + if(find_cmap(mapping->type, mapping->pid, mapping->eid, face)) { + int total = 0, failed = 0; + if(encoding->row_size > 0) { + int estimate = + (encoding->size - encoding->first) * + (encoding->row_size - encoding->first_col); + for(i = encoding->first; i < encoding->size; i++) { + for(j = encoding->first_col; + j < encoding->row_size; + j++) { + c = FontEncRecode((i<<8) | j, mapping); + if(CODE_IGNORED(c)) { + continue; + } else { + if(FT_Get_Char_Index(face, c) == 0) { + failed++; + } + total++; + if((encoding->size <= 1 && failed > 0) || + ((float)failed >= bigEncodingFuzz * estimate)) { + return 0; + } + } + } + } + if((float)failed >= total * bigEncodingFuzz) + return 0; + else + return 1; + } else { + int estimate = encoding->size - encoding->first; + /* For the KOI8 encodings, we ignore the lack of + linedrawing and pseudo-math characters */ + if(strncmp(encoding->name, "koi8-", 5) == 0) + koi8 = 1; + else + koi8 = 0; + for(i = encoding->first; i < encoding->size; i++) { + c = FontEncRecode(i, mapping); + if(CODE_IGNORED(c) || + (koi8 && ((c >= 0x2200 && c < 0x2600) || c == 0x00b2))) { + continue; + } else { + if(FT_Get_Char_Index(face, c) == 0) { + failed++; + } + total++; + if((encoding->size <= 256 && failed > 0) || + ((float)failed >= bigEncodingFuzz * estimate)) { + return 0; + } + } + } + if((float)failed >= total * bigEncodingFuzz) + return 0; + else + return 1; + } + } + } + return 0; +} + +static int +find_cmap(int type, int pid, int eid, FT_Face face) +{ + int i, n, rc; + FT_CharMap cmap = NULL; + + n = face->num_charmaps; + + switch(type) { + case FONT_ENCODING_TRUETYPE: /* specific cmap */ + for(i=0; icharmaps[i]; + if(cmap->platform_id == pid && cmap->encoding_id == eid) { + rc = FT_Set_Charmap(face, cmap); + if(rc == 0) + return 1; + } + } + break; + case FONT_ENCODING_UNICODE: /* any Unicode cmap */ + /* prefer Microsoft Unicode */ + for(i=0; icharmaps[i]; + if(cmap->platform_id == TT_PLATFORM_MICROSOFT && + cmap->encoding_id == TT_MS_ID_UNICODE_CS) { + rc = FT_Set_Charmap(face, cmap); + if(rc == 0) + return 1; + } + } + /* Try Apple Unicode */ + for(i=0; icharmaps[i]; + if(cmap->platform_id == TT_PLATFORM_APPLE_UNICODE) { + rc = FT_Set_Charmap(face, cmap); + if(rc == 0) + return 1; + } + } + /* ISO Unicode? */ + for(i=0; icharmaps[i]; + if(cmap->platform_id == TT_PLATFORM_ISO) { + rc = FT_Set_Charmap(face, cmap); + if(rc == 0) + return 1; + } + } + break; + default: + return 0; + } + return 0; +} + +static int +checkExtraEncoding(FT_Face face, char *encoding_name, int found) +{ + int c; + + if(strcasecmp(encoding_name, "iso10646-1") == 0) { + if(doISO10646_1_encoding && find_cmap(FONT_ENCODING_UNICODE, -1, -1, face)) { + int found = 0; + /* Export as Unicode if there are at least 15 BMP + characters that are not a space or ignored. */ + for(c = 0x21; c < 0x10000; c++) { + if(CODE_IGNORED(c)) + continue; + if(FT_Get_Char_Index(face, c) > 0) + found++; + if(found >= 15) + return 1; + } + return 0; + } else + return 0; + } else if(strcasecmp(encoding_name, "microsoft-symbol") == 0) { + if(find_cmap(FONT_ENCODING_TRUETYPE, + TT_PLATFORM_MICROSOFT, TT_MS_ID_SYMBOL_CS, + face)) + return 1; + else + return 0; + } else if(strcasecmp(encoding_name, "adobe-fontspecific") == 0) { + if(!found) { + if(FT_Has_PS_Glyph_Names(face)) + return 1; + else + return 0; + } else + return 0; + } else { + fprintf(stderr, "Unknown extra encoding %s\n", encoding_name); + return 0; + } +} + +static char* +notice_foundry(char *notice) +{ + int i; + for(i = 0; i < countof(notice_foundries); i++) + if(notice && strstr(notice, notice_foundries[i][0])) + return notice_foundries[i][1]; + return NULL; +} + +static int +vendor_match(signed char *vendor, char *vendor_string) +{ + /* vendor is not necessarily NUL-terminated. */ + int i, len; + len = strlen(vendor_string); + if(memcmp(vendor, vendor_string, len) != 0) + return 0; + for(i = len; i < 4; i++) + if(vendor[i] != ' ' && vendor[i] != '\0') + return 0; + return 1; +} + +static char* +vendor_foundry(signed char *vendor) +{ + int i; + for(i = 0; i < countof(vendor_foundries); i++) + if(vendor_match(vendor, vendor_foundries[i][0])) + return vendor_foundries[i][1]; + return NULL; +} + +static int +readEncodings(ListPtr encodings, char *dirname) +{ + char *fullname; + DIR *dirp; + struct dirent *file; + char **names, **name; + + if(strlen(dirname) > 1 && dirname[strlen(dirname) - 1] == '/') + dirname[strlen(dirname) - 1] = '\0'; + + dirp = opendir(dirname); + if(dirp == NULL) { + perror("opendir"); + return -1; + } + + while((file = readdir(dirp)) != NULL) { + fullname = dsprintf("%s/%s", dirname, file->d_name); + if(fullname == NULL) { + fprintf(stderr, "Couldn't allocate fullname\n"); + closedir(dirp); + return -1; + } + + names = FontEncIdentify(fullname); + if(!names) + continue; + + for(name = names; *name; name++) { + if(fullname[0] != '/' && !relative) { + char *n; + n = dsprintf("%s%s", encodingPrefix, fullname); + if(n == NULL) { + fprintf(stderr, "Couldn't allocate name\n"); + closedir(dirp); + return -1; + } + encodingsToDo = listConsF(encodingsToDo, "%s %s", *name, n); + free(n); + } else { + encodingsToDo = + listConsF(encodingsToDo, "%s %s", *name, fullname); + } + if(encodingsToDo == NULL) { + fprintf(stderr, "Couldn't allocate encodings\n"); + closedir(dirp); + return -1; + } + } + free(names); /* only the spine */ + } + closedir(dirp); + return 0; +} -- cgit v1.2.3