summaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
authorKaleb Keithley <kaleb@freedesktop.org>2003-11-14 15:54:40 +0000
committerKaleb Keithley <kaleb@freedesktop.org>2003-11-14 15:54:40 +0000
commit153e8da44452905ae04a0e20ad0d85f40399b4ca (patch)
treeb4e614de58d4b596dab3dcc7fd4054ec96db592a /src/util
R6.6 is the Xorg base-lineXORG-MAIN
Diffstat (limited to 'src/util')
-rw-r--r--src/util/atom.c230
-rw-r--r--src/util/fontaccel.c102
-rw-r--r--src/util/fontnames.c124
-rw-r--r--src/util/fontutil.c416
-rw-r--r--src/util/fontxlfd.c587
-rw-r--r--src/util/format.c121
-rw-r--r--src/util/miscutil.c93
-rw-r--r--src/util/patcache.c224
-rw-r--r--src/util/private.c70
-rw-r--r--src/util/utilbitmap.c187
10 files changed, 2154 insertions, 0 deletions
diff --git a/src/util/atom.c b/src/util/atom.c
new file mode 100644
index 0000000..140d774
--- /dev/null
+++ b/src/util/atom.c
@@ -0,0 +1,230 @@
+/* $Xorg: atom.c,v 1.5 2001/02/09 02:04:04 xorgcvs Exp $ */
+
+/*
+
+Copyright 1990, 1994, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+/* lame atom replacement routines for font applications */
+
+#include "fontmisc.h"
+
+typedef struct _AtomList {
+ char *name;
+ int len;
+ int hash;
+ Atom atom;
+} AtomListRec, *AtomListPtr;
+
+static AtomListPtr *hashTable;
+
+static int hashSize, hashUsed;
+static int hashMask;
+static int rehash;
+
+static AtomListPtr *reverseMap;
+static int reverseMapSize;
+static Atom lastAtom;
+
+static int
+Hash(string, len)
+ char *string;
+{
+ int h;
+
+ h = 0;
+ while (len--)
+ h = (h << 3) ^ *string++;
+ if (h < 0)
+ return -h;
+ return h;
+}
+
+static int
+ResizeHashTable ()
+{
+ int newHashSize;
+ int newHashMask;
+ AtomListPtr *newHashTable;
+ int i;
+ int h;
+ int newRehash;
+ int r;
+
+ if (hashSize == 0)
+ newHashSize = 1024;
+ else
+ newHashSize = hashSize * 2;
+ newHashTable = (AtomListPtr *) xalloc (newHashSize * sizeof (AtomListPtr));
+ if (!newHashTable) {
+ fprintf(stderr, "ResizeHashTable(): Error: Couldn't allocate newHashTable (%d)\n", newHashSize * sizeof (AtomListPtr));
+ return FALSE;
+ }
+ bzero ((char *) newHashTable, newHashSize * sizeof (AtomListPtr));
+ newHashMask = newHashSize - 1;
+ newRehash = (newHashMask - 2);
+ for (i = 0; i < hashSize; i++)
+ {
+ if (hashTable[i])
+ {
+ h = (hashTable[i]->hash) & newHashMask;
+ if (newHashTable[h])
+ {
+ r = hashTable[i]->hash % newRehash | 1;
+ do {
+ h += r;
+ if (h >= newHashSize)
+ h -= newHashSize;
+ } while (newHashTable[h]);
+ }
+ newHashTable[h] = hashTable[i];
+ }
+ }
+ xfree (hashTable);
+ hashTable = newHashTable;
+ hashSize = newHashSize;
+ hashMask = newHashMask;
+ rehash = newRehash;
+ return TRUE;
+}
+
+static int
+ResizeReverseMap ()
+{
+ int ret = TRUE;
+ if (reverseMapSize == 0)
+ reverseMapSize = 1000;
+ else
+ reverseMapSize *= 2;
+ reverseMap = (AtomListPtr *) xrealloc (reverseMap, reverseMapSize * sizeof (AtomListPtr));
+ if (!reverseMap) {
+ fprintf(stderr, "ResizeReverseMap(): Error: Couldn't reallocate reverseMap (%d)\n", reverseMapSize * sizeof(AtomListPtr));
+ ret = FALSE;
+ }
+ return ret;
+}
+
+static int
+NameEqual (a, b, l)
+ char *a, *b;
+{
+ while (l--)
+ if (*a++ != *b++)
+ return FALSE;
+ return TRUE;
+}
+
+Atom
+MakeAtom(string, len, makeit)
+ char *string;
+ unsigned len;
+ int makeit;
+{
+ AtomListPtr a;
+ int hash;
+ int h;
+ int r;
+
+ hash = Hash (string, len);
+ if (hashTable)
+ {
+ h = hash & hashMask;
+ if (hashTable[h])
+ {
+ if (hashTable[h]->hash == hash && hashTable[h]->len == len &&
+ NameEqual (hashTable[h]->name, string, len))
+ {
+ return hashTable[h]->atom;
+ }
+ r = (hash % rehash) | 1;
+ for (;;)
+ {
+ h += r;
+ if (h >= hashSize)
+ h -= hashSize;
+ if (!hashTable[h])
+ break;
+ if (hashTable[h]->hash == hash && hashTable[h]->len == len &&
+ NameEqual (hashTable[h]->name, string, len))
+ {
+ return hashTable[h]->atom;
+ }
+ }
+ }
+ }
+ if (!makeit)
+ return None;
+ a = (AtomListPtr) xalloc (sizeof (AtomListRec) + len + 1);
+ if (a == NULL) {
+ fprintf(stderr, "MakeAtom(): Error: Couldn't allocate AtomListRec (%d)\n", sizeof (AtomListRec) + len + 1);
+ return None;
+ }
+ a->name = (char *) (a + 1);
+ a->len = len;
+ strncpy (a->name, string, len);
+ a->name[len] = '\0';
+ a->atom = ++lastAtom;
+ a->hash = hash;
+ if (hashUsed >= hashSize / 2)
+ {
+ ResizeHashTable ();
+ h = hash & hashMask;
+ if (hashTable[h])
+ {
+ r = (hash % rehash) | 1;
+ do {
+ h += r;
+ if (h >= hashSize)
+ h -= hashSize;
+ } while (hashTable[h]);
+ }
+ }
+ hashTable[h] = a;
+ hashUsed++;
+ if (reverseMapSize <= a->atom) {
+ if (!ResizeReverseMap())
+ return None;
+ }
+ reverseMap[a->atom] = a;
+ return a->atom;
+}
+
+int ValidAtom(atom)
+ Atom atom;
+{
+ return (atom != None) && (atom <= lastAtom);
+}
+
+char *
+NameForAtom(atom)
+ Atom atom;
+{
+ if (atom != None && atom <= lastAtom)
+ return reverseMap[atom]->name;
+ return 0;
+}
diff --git a/src/util/fontaccel.c b/src/util/fontaccel.c
new file mode 100644
index 0000000..b0e8b57
--- /dev/null
+++ b/src/util/fontaccel.c
@@ -0,0 +1,102 @@
+/* $Xorg: fontaccel.c,v 1.4 2001/02/09 02:04:04 xorgcvs Exp $ */
+
+/*
+
+Copyright 1990, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#include "fontmisc.h"
+#include "fontstruct.h"
+
+void FontComputeInfoAccelerators(pFontInfo)
+ FontInfoPtr pFontInfo;
+{
+ pFontInfo->noOverlap = FALSE;
+ if (pFontInfo->maxOverlap <= pFontInfo->minbounds.leftSideBearing)
+ pFontInfo->noOverlap = TRUE;
+
+ if ((pFontInfo->minbounds.ascent == pFontInfo->maxbounds.ascent) &&
+ (pFontInfo->minbounds.descent == pFontInfo->maxbounds.descent) &&
+ (pFontInfo->minbounds.leftSideBearing ==
+ pFontInfo->maxbounds.leftSideBearing) &&
+ (pFontInfo->minbounds.rightSideBearing ==
+ pFontInfo->maxbounds.rightSideBearing) &&
+ (pFontInfo->minbounds.characterWidth ==
+ pFontInfo->maxbounds.characterWidth) &&
+ (pFontInfo->minbounds.attributes == pFontInfo->maxbounds.attributes)) {
+ pFontInfo->constantMetrics = TRUE;
+ if ((pFontInfo->maxbounds.leftSideBearing == 0) &&
+ (pFontInfo->maxbounds.rightSideBearing ==
+ pFontInfo->maxbounds.characterWidth) &&
+ (pFontInfo->maxbounds.ascent == pFontInfo->fontAscent) &&
+ (pFontInfo->maxbounds.descent == pFontInfo->fontDescent))
+ pFontInfo->terminalFont = TRUE;
+ else
+ pFontInfo->terminalFont = FALSE;
+ } else {
+ pFontInfo->constantMetrics = FALSE;
+ pFontInfo->terminalFont = FALSE;
+ }
+ if (pFontInfo->minbounds.characterWidth == pFontInfo->maxbounds.characterWidth)
+ pFontInfo->constantWidth = TRUE;
+ else
+ pFontInfo->constantWidth = FALSE;
+
+ if ((pFontInfo->minbounds.leftSideBearing >= 0) &&
+ (pFontInfo->maxOverlap <= 0) &&
+ (pFontInfo->minbounds.ascent >= -pFontInfo->fontDescent) &&
+ (pFontInfo->maxbounds.ascent <= pFontInfo->fontAscent) &&
+ (-pFontInfo->minbounds.descent <= pFontInfo->fontAscent) &&
+ (pFontInfo->maxbounds.descent <= pFontInfo->fontDescent))
+ pFontInfo->inkInside = TRUE;
+ else
+ pFontInfo->inkInside = FALSE;
+}
+
+int FontCouldBeTerminal(pFontInfo)
+ FontInfoPtr pFontInfo;
+{
+ if ((pFontInfo->minbounds.leftSideBearing >= 0) &&
+ (pFontInfo->maxbounds.rightSideBearing <= pFontInfo->maxbounds.characterWidth) &&
+ (pFontInfo->minbounds.characterWidth == pFontInfo->maxbounds.characterWidth) &&
+ (pFontInfo->maxbounds.ascent <= pFontInfo->fontAscent) &&
+ (pFontInfo->maxbounds.descent <= pFontInfo->fontDescent) &&
+ (pFontInfo->maxbounds.leftSideBearing != 0 ||
+ pFontInfo->minbounds.rightSideBearing != pFontInfo->minbounds.characterWidth ||
+ pFontInfo->minbounds.ascent != pFontInfo->fontAscent ||
+ pFontInfo->minbounds.descent != pFontInfo->fontDescent)) {
+ /* blow off font with nothing but a SPACE */
+ if (pFontInfo->maxbounds.ascent == 0 &&
+ pFontInfo->maxbounds.descent == 0)
+ return FALSE;
+ return TRUE;
+ }
+ return FALSE;
+}
diff --git a/src/util/fontnames.c b/src/util/fontnames.c
new file mode 100644
index 0000000..939d531
--- /dev/null
+++ b/src/util/fontnames.c
@@ -0,0 +1,124 @@
+/* $Xorg: fontnames.c,v 1.4 2001/02/09 02:04:04 xorgcvs Exp $ */
+
+/*
+
+Copyright 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ *
+ * @(#)fontnames.c 3.1 91/04/10
+ */
+
+#include "fontmisc.h"
+#include "fontstruct.h"
+
+void
+FreeFontNames(pFN)
+ FontNamesPtr pFN;
+{
+ int i;
+
+ if (!pFN)
+ return;
+ for (i = 0; i < pFN->nnames; i++) {
+ xfree(pFN->names[i]);
+ }
+ xfree(pFN->names);
+ xfree(pFN->length);
+ xfree(pFN);
+}
+
+FontNamesPtr
+MakeFontNamesRecord(size)
+ unsigned size;
+{
+ FontNamesPtr pFN;
+
+ pFN = (FontNamesPtr) xalloc(sizeof(FontNamesRec));
+ if (pFN) {
+ pFN->nnames = 0;
+ pFN->size = size;
+ if (size)
+ {
+ pFN->length = (int *) xalloc(size * sizeof(int));
+ pFN->names = (char **) xalloc(size * sizeof(char *));
+ if (!pFN->length || !pFN->names) {
+ xfree(pFN->length);
+ xfree(pFN->names);
+ xfree(pFN);
+ pFN = (FontNamesPtr) 0;
+ }
+ }
+ else
+ {
+ pFN->length = 0;
+ pFN->names = 0;
+ }
+ }
+ return pFN;
+}
+
+int
+AddFontNamesName(names, name, length)
+ FontNamesPtr names;
+ char *name;
+ int length;
+{
+ int index = names->nnames;
+ char *nelt;
+
+ nelt = (char *) xalloc(length + 1);
+ if (!nelt)
+ return AllocError;
+ if (index >= names->size) {
+ int size = names->size << 1;
+ int *nlength;
+ char **nnames;
+
+ if (size == 0)
+ size = 8;
+ nlength = (int *) xrealloc(names->length, size * sizeof(int));
+ nnames = (char **) xrealloc(names->names, size * sizeof(char *));
+ if (nlength && nnames) {
+ names->size = size;
+ names->length = nlength;
+ names->names = nnames;
+ } else {
+ xfree(nelt);
+ xfree(nlength);
+ xfree(nnames);
+ return AllocError;
+ }
+ }
+ names->length[index] = length;
+ names->names[index] = nelt;
+ strncpy(nelt, name, length);
+ nelt[length] = '\0';
+ names->nnames++;
+ return Successful;
+}
diff --git a/src/util/fontutil.c b/src/util/fontutil.c
new file mode 100644
index 0000000..c67be62
--- /dev/null
+++ b/src/util/fontutil.c
@@ -0,0 +1,416 @@
+/* $Xorg: fontutil.c,v 1.4 2001/02/09 02:04:04 xorgcvs Exp $ */
+
+/*
+
+Copyright 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#include "fontmisc.h"
+#include "fontstruct.h"
+#include "FSproto.h"
+
+/* Define global here... doesn't hurt the servers, and avoids
+ unresolved references in font clients. */
+
+static int defaultGlyphCachingMode = DEFAULT_GLYPH_CACHING_MODE;
+int glyphCachingMode = DEFAULT_GLYPH_CACHING_MODE;
+
+void
+GetGlyphs(font, count, chars, fontEncoding, glyphcount, glyphs)
+ FontPtr font;
+ unsigned long count;
+ unsigned char *chars;
+ FontEncoding fontEncoding;
+ unsigned long *glyphcount; /* RETURN */
+ CharInfoPtr *glyphs; /* RETURN */
+{
+ (*font->get_glyphs) (font, count, chars, fontEncoding, glyphcount, glyphs);
+}
+
+#define MIN(a,b) ((a)<(b)?(a):(b))
+#define MAX(a,b) ((a)>(b)?(a):(b))
+
+void
+QueryGlyphExtents(pFont, charinfo, count, info)
+ FontPtr pFont;
+ CharInfoPtr *charinfo;
+ unsigned long count;
+ ExtentInfoRec *info;
+{
+ register unsigned long i;
+ xCharInfo *pCI;
+
+ info->drawDirection = pFont->info.drawDirection;
+
+ info->fontAscent = pFont->info.fontAscent;
+ info->fontDescent = pFont->info.fontDescent;
+
+ if (count != 0) {
+
+ pCI = &((*charinfo)->metrics); charinfo++;
+ /* ignore nonexisting characters when calculating text extents */
+ if ( !((pCI->characterWidth == 0)
+ && (pCI->rightSideBearing == 0)
+ && (pCI->leftSideBearing == 0)
+ && (pCI->ascent == 0)
+ && (pCI->descent == 0)) ) {
+ info->overallAscent = pCI->ascent;
+ info->overallDescent = pCI->descent;
+ info->overallLeft = pCI->leftSideBearing;
+ info->overallRight = pCI->rightSideBearing;
+ info->overallWidth = pCI->characterWidth;
+ }
+
+ if (pFont->info.constantMetrics && pFont->info.noOverlap) {
+ info->overallWidth *= count;
+ info->overallRight += (info->overallWidth -
+ pCI->characterWidth);
+ } else {
+ for (i = 1; i < count; i++) {
+ pCI = &((*charinfo)->metrics); charinfo++;
+ /* ignore nonexisting characters when calculating extents */
+ if ( !((pCI->characterWidth == 0)
+ && (pCI->rightSideBearing == 0)
+ && (pCI->leftSideBearing == 0)
+ && (pCI->ascent == 0)
+ && (pCI->descent == 0)) ) {
+ info->overallAscent = MAX(
+ info->overallAscent,
+ pCI->ascent);
+ info->overallDescent = MAX(
+ info->overallDescent,
+ pCI->descent);
+ info->overallLeft = MIN(
+ info->overallLeft,
+ info->overallWidth + pCI->leftSideBearing);
+ info->overallRight = MAX(
+ info->overallRight,
+ info->overallWidth + pCI->rightSideBearing);
+ /*
+ * yes, this order is correct; overallWidth IS incremented
+ * last
+ */
+ info->overallWidth += pCI->characterWidth;
+ }
+ }
+ }
+ } else {
+ info->overallAscent = 0;
+ info->overallDescent = 0;
+ info->overallWidth = 0;
+ info->overallLeft = 0;
+ info->overallRight = 0;
+ }
+}
+
+Bool
+QueryTextExtents(pFont, count, chars, info)
+ FontPtr pFont;
+ unsigned long count;
+ unsigned char *chars;
+ ExtentInfoRec *info;
+{
+ xCharInfo **charinfo;
+ unsigned long n;
+ FontEncoding encoding;
+ int cm;
+ int i;
+ unsigned long t;
+ xCharInfo *defaultChar = 0;
+ unsigned char defc[2];
+ int firstReal;
+
+ charinfo = (xCharInfo **) xalloc(count * sizeof(xCharInfo *));
+ if (!charinfo)
+ return FALSE;
+ encoding = TwoD16Bit;
+ if (pFont->info.lastRow == 0)
+ encoding = Linear16Bit;
+ (*pFont->get_metrics) (pFont, count, chars, encoding, &n, charinfo);
+
+ /* Do default character substitution as get_metrics doesn't */
+
+#define IsNonExistentChar(ci) (!(ci) || \
+ (ci)->ascent == 0 && \
+ (ci)->descent == 0 && \
+ (ci)->leftSideBearing == 0 && \
+ (ci)->rightSideBearing == 0 && \
+ (ci)->characterWidth == 0)
+
+ firstReal = n;
+ defc[0] = pFont->info.defaultCh >> 8;
+ defc[1] = pFont->info.defaultCh;
+ (*pFont->get_metrics) (pFont, 1, defc, encoding, &t, &defaultChar);
+ if ((IsNonExistentChar (defaultChar)))
+ defaultChar = 0;
+ for (i = 0; i < n; i++)
+ {
+ if ((IsNonExistentChar (charinfo[i])))
+ {
+ if (!defaultChar)
+ continue;
+ charinfo[i] = defaultChar;
+ }
+ if (firstReal == n)
+ firstReal = i;
+ }
+ cm = pFont->info.constantMetrics;
+ pFont->info.constantMetrics = FALSE;
+ QueryGlyphExtents(pFont, (CharInfoPtr*) charinfo + firstReal,
+ n - firstReal, info);
+ pFont->info.constantMetrics = cm;
+ xfree(charinfo);
+ return TRUE;
+}
+
+Bool
+ParseGlyphCachingMode(str)
+ char *str;
+{
+ if (!strcmp(str, "none")) defaultGlyphCachingMode = CACHING_OFF;
+ else if (!strcmp(str, "all")) defaultGlyphCachingMode = CACHE_ALL_GLYPHS;
+ else if (!strcmp(str, "16")) defaultGlyphCachingMode = CACHE_16_BIT_GLYPHS;
+ else return FALSE;
+ return TRUE;
+}
+
+void
+InitGlyphCaching()
+{
+ /* Set glyphCachingMode to the mode the server hopes to
+ support. DDX drivers that do not support the requested level
+ of glyph caching can call SetGlyphCachingMode to lower the
+ level of support.
+ */
+
+ glyphCachingMode = defaultGlyphCachingMode;
+}
+
+/* ddxen can call SetGlyphCachingMode to inform us of what level of glyph
+ * caching they can support.
+ */
+void
+SetGlyphCachingMode(newmode)
+ int newmode;
+{
+ if ( (glyphCachingMode > newmode) && (newmode >= 0) )
+ glyphCachingMode = newmode;
+}
+
+#define range_alloc_granularity 16
+#define mincharp(p) ((p)->min_char_low + ((p)->min_char_high << 8))
+#define maxcharp(p) ((p)->max_char_low + ((p)->max_char_high << 8))
+
+/* add_range(): Add range to a list of ranges, with coalescence */
+int
+add_range(newrange, nranges, range, charset_subset)
+fsRange *newrange;
+int *nranges;
+fsRange **range;
+Bool charset_subset;
+{
+ int first, last, middle;
+ unsigned long keymin, keymax;
+ unsigned long ptrmin, ptrmax;
+ fsRange *ptr, *ptr1, *ptr2, *endptr;
+
+ /* There are two different ways to treat ranges:
+
+ 1) Charset subsetting (support of the HP XLFD enhancements), in
+ which a range of 0x1234,0x3456 means all numbers between
+ 0x1234 and 0x3456, and in which min and max might be swapped.
+
+ 2) Row/column ranges, in which a range of 0x1234,0x3456 means the
+ ranges 0x1234-0x1256, 0x1334-0x1356, ... , 0x3434-0x3456.
+ This is for support of glyph caching.
+
+ The choice of treatment is selected with the "charset_subset"
+ flag */
+
+ /* If newrange covers multiple rows; break up the rows */
+ if (!charset_subset && newrange->min_char_high != newrange->max_char_high)
+ {
+ int i, err;
+ fsRange temprange;
+ for (i = newrange->min_char_high;
+ i <= newrange->max_char_high;
+ i++)
+ {
+ temprange.min_char_low = newrange->min_char_low;
+ temprange.max_char_low = newrange->max_char_low;
+ temprange.min_char_high = temprange.max_char_high = i;
+ err = add_range(&temprange, nranges, range, charset_subset);
+ if (err != Successful) break;
+ }
+ return err;
+ }
+
+ keymin = mincharp(newrange);
+ keymax = maxcharp(newrange);
+
+ if (charset_subset && keymin > keymax)
+ {
+ unsigned long temp = keymin;
+ keymin = keymax;
+ keymax = temp;
+ }
+
+ /* add_range() maintains a sorted list; this makes possible coalescence
+ and binary searches */
+
+ /* Binary search for a range with which the new range can merge */
+
+ first = middle = 0;
+ last = *nranges - 1;
+ while (last >= first)
+ {
+ middle = (first + last) / 2;
+ ptr = (*range) + middle;
+ ptrmin = mincharp(ptr);
+ ptrmax = maxcharp(ptr);
+
+ if (ptrmin > 0 && keymax < ptrmin - 1) last = middle - 1;
+ else if (keymin > ptrmax + 1) first = middle + 1;
+ else if (!charset_subset)
+ {
+ /* We might have a range with which to merge... IF the
+ result doesn't cross rows */
+ if (newrange->min_char_high != ptr->min_char_high)
+ last = first - 1; /* Force adding a new range */
+ break;
+ }
+ else break; /* We have at least one range with which we can merge */
+ }
+
+ if (last < first)
+ {
+ /* Search failed; we need to add a new range to the list. */
+
+ /* Grow the list if necessary */
+ if (*nranges == 0 || *range == (fsRange *)0)
+ {
+ *range = (fsRange *)xalloc(range_alloc_granularity *
+ SIZEOF(fsRange));
+ *nranges = 0;
+ }
+ else if (!(*nranges % range_alloc_granularity))
+ {
+ *range = (fsRange *)xrealloc((char *)*range,
+ (*nranges + range_alloc_granularity) *
+ SIZEOF(fsRange));
+ }
+
+ /* If alloc failed, just return a null list */
+ if (*range == (fsRange *)0)
+ {
+ *nranges = 0;
+ return AllocError;
+ }
+
+ /* Should new entry go *at* or *after* ptr? */
+ ptr = (*range) + middle;
+ if (middle < *nranges && keymin > ptrmin) ptr++; /* after */
+
+ /* Open up a space for our new range */
+ memmove((char *)(ptr + 1),
+ (char *)ptr,
+ (char *)(*range + *nranges) - (char *)ptr);
+
+ /* Insert the new range */
+ ptr->min_char_low = keymin & 0xff;
+ ptr->min_char_high = keymin >> 8;
+ ptr->max_char_low = keymax & 0xff;
+ ptr->max_char_high = keymax >> 8;
+
+ /* Update range count */
+ (*nranges)++;
+
+ /* Done */
+ return Successful;
+ }
+
+ /* Join our new range to that pointed to by "ptr" */
+ if (keymin < ptrmin)
+ {
+ ptr->min_char_low = keymin & 0xff;
+ ptr->min_char_high = keymin >> 8;
+ }
+ if (keymax > ptrmax)
+ {
+ ptr->max_char_low = keymax & 0xff;
+ ptr->max_char_high = keymax >> 8;
+ }
+
+ ptrmin = mincharp(ptr);
+ ptrmax = maxcharp(ptr);
+
+ endptr = *range + *nranges;
+
+ for (ptr1 = ptr; ptr1 >= *range; ptr1--)
+ {
+ if (ptrmin <= maxcharp(ptr1) + 1)
+ {
+ if (!charset_subset && ptr->min_char_high != ptr1->min_char_high)
+ break;
+ if (ptrmin >= mincharp(ptr1))
+ ptrmin = mincharp(ptr1);
+ }
+ else break;
+ }
+ for (ptr2 = ptr; ptr2 < endptr; ptr2++)
+ {
+ if ((ptr2->min_char_low == 0 && ptr2->min_char_high == 0) ||
+ ptrmax >= mincharp(ptr2) - 1)
+ {
+ if (!charset_subset && ptr->min_char_high != ptr2->min_char_high)
+ break;
+ if (ptrmax <= maxcharp(ptr2))
+ ptrmax = maxcharp(ptr2);
+ }
+ else break;
+ }
+
+ /* We need to coalesce ranges between ptr1 and ptr2 exclusive */
+ ptr1++;
+ ptr2--;
+ if (ptr1 != ptr2)
+ {
+ memmove(ptr1, ptr2, (char *)endptr - (char *)ptr2);
+ *nranges -= (ptr2 - ptr1);
+ }
+
+ /* Write the new range into the range list */
+ ptr1->min_char_low = ptrmin & 0xff;
+ ptr1->min_char_high = ptrmin >> 8;
+ ptr1->max_char_low = ptrmax & 0xff;
+ ptr1->max_char_high = ptrmax >> 8;
+
+ return Successful;
+}
diff --git a/src/util/fontxlfd.c b/src/util/fontxlfd.c
new file mode 100644
index 0000000..f1245f6
--- /dev/null
+++ b/src/util/fontxlfd.c
@@ -0,0 +1,587 @@
+/* $Xorg: fontxlfd.c,v 1.4 2001/02/09 02:04:04 xorgcvs Exp $ */
+
+/*
+
+Copyright 1990, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#include "fontmisc.h"
+#include "fontstruct.h"
+#include "fontxlfd.h"
+#include <X11/Xos.h>
+#include <math.h>
+#ifndef X_NOT_STDC_ENV
+#include <stdlib.h>
+#endif
+#if defined(X_NOT_STDC_ENV) || (defined(sony) && !defined(SYSTYPE_SYSV) && !defined(_SYSTYPE_SYSV))
+#define NO_LOCALE
+#endif
+#ifndef NO_LOCALE
+#include <locale.h>
+#endif
+#include <ctype.h>
+#include <stdio.h> /* for sprintf() */
+
+static char *
+GetInt(ptr, val)
+ char *ptr;
+ int *val;
+{
+ if (*ptr == '*') {
+ *val = -1;
+ ptr++;
+ } else
+ for (*val = 0; *ptr >= '0' && *ptr <= '9';)
+ *val = *val * 10 + *ptr++ - '0';
+ if (*ptr == '-')
+ return ptr;
+ return (char *) 0;
+}
+
+#define minchar(p) ((p).min_char_low + ((p).min_char_high << 8))
+#define maxchar(p) ((p).max_char_low + ((p).max_char_high << 8))
+
+
+#ifndef NO_LOCALE
+static struct lconv *locale = 0;
+#endif
+static char *radix = ".", *plus = "+", *minus = "-";
+
+static char *
+readreal(ptr, result)
+char *ptr;
+double *result;
+{
+ char buffer[80], *p1, *p2;
+
+#ifndef NO_LOCALE
+ /* Figure out what symbols apply in this locale */
+
+ if (!locale)
+ {
+ locale = localeconv();
+ if (locale->decimal_point && *locale->decimal_point)
+ radix = locale->decimal_point;
+ if (locale->positive_sign && *locale->positive_sign)
+ plus = locale->positive_sign;
+ if (locale->negative_sign && *locale->negative_sign)
+ minus = locale->negative_sign;
+ }
+#endif
+ /* Copy the first 80 chars of ptr into our local buffer, changing
+ symbols as needed. */
+ for (p1 = ptr, p2 = buffer;
+ *p1 && (p2 - buffer) < sizeof(buffer) - 1;
+ p1++, p2++)
+ {
+ switch(*p1)
+ {
+ case '~': *p2 = *minus; break;
+ case '+': *p2 = *plus; break;
+ case '.': *p2 = *radix; break;
+ default: *p2 = *p1;
+ }
+ }
+ *p2 = 0;
+
+ /* Now we have something that strtod() can interpret... do it. */
+#ifndef X_NOT_STDC_ENV
+ *result = strtod(buffer, &p1);
+ /* Return NULL if failure, pointer past number if success */
+ return (p1 == buffer) ? (char *)0 : (ptr + (p1 - buffer));
+#else
+ for (p1 = buffer; isspace(*p1); p1++)
+ ;
+ if (sscanf(p1, "%lf", result) != 1)
+ return (char *)0;
+ while (!isspace(*p1))
+ p1++;
+ return ptr + (p1 - buffer);
+#endif
+}
+
+static char *
+xlfd_double_to_text(value, buffer, space_required)
+double value;
+char *buffer;
+int space_required;
+{
+ char formatbuf[40];
+ register char *p1;
+ int ndigits, exponent;
+
+#ifndef NO_LOCALE
+ if (!locale)
+ {
+ locale = localeconv();
+ if (locale->decimal_point && *locale->decimal_point)
+ radix = locale->decimal_point;
+ if (locale->positive_sign && *locale->positive_sign)
+ plus = locale->positive_sign;
+ if (locale->negative_sign && *locale->negative_sign)
+ minus = locale->negative_sign;
+ }
+#endif
+ /* Compute a format to use to render the number */
+ sprintf(formatbuf, "%%.%dle", XLFD_NDIGITS);
+
+ if (space_required)
+ *buffer++ = ' ';
+
+ /* Render the number using printf's idea of formatting */
+ sprintf(buffer, formatbuf, value);
+
+ /* Find and read the exponent value */
+ for (p1 = buffer + strlen(buffer);
+ *p1-- != 'e' && p1[1] != 'E';);
+ exponent = atoi(p1 + 2);
+ if (value == 0.0) exponent = 0;
+
+ /* Figure out how many digits are significant */
+ while (p1 >= buffer && (!isdigit(*p1) || *p1 == '0')) p1--;
+ ndigits = 0;
+ while (p1 >= buffer) if (isdigit(*p1--)) ndigits++;
+
+ /* Figure out notation to use */
+ if (exponent >= XLFD_NDIGITS || ndigits - exponent > XLFD_NDIGITS + 1)
+ {
+ /* Scientific */
+ sprintf(formatbuf, "%%.%dle", ndigits - 1);
+ sprintf(buffer, formatbuf, value);
+ }
+ else
+ {
+ /* Fixed */
+ ndigits -= exponent + 1;
+ if (ndigits < 0) ndigits = 0;
+ sprintf(formatbuf, "%%.%dlf", ndigits);
+ sprintf(buffer, formatbuf, value);
+ if (exponent < 0)
+ {
+ p1 = buffer;
+ while (*p1 && *p1 != '0') p1++;
+ while (*p1++) p1[-1] = *p1;
+ }
+ }
+
+ /* Last step, convert the locale-specific sign and radix characters
+ to our own. */
+ for (p1 = buffer; *p1; p1++)
+ {
+ if (*p1 == *minus) *p1 = '~';
+ else if (*p1 == *plus) *p1 = '+';
+ else if (*p1 == *radix) *p1 = '.';
+ }
+
+ return buffer - space_required;
+}
+
+double
+xlfd_round_double(x)
+double x;
+{
+ /* Utility for XLFD users to round numbers to XLFD_NDIGITS
+ significant digits. How do you round to n significant digits on
+ a binary machine? Let printf() do it for you. */
+ char formatbuf[40], buffer[40];
+
+ sprintf(formatbuf, "%%.%dlg", XLFD_NDIGITS);
+ sprintf(buffer, formatbuf, x);
+ return atof(buffer);
+}
+
+static char *
+GetMatrix(ptr, vals, which)
+char *ptr;
+FontScalablePtr vals;
+int which;
+{
+ double *matrix;
+
+ if (which == PIXELSIZE_MASK)
+ matrix = vals->pixel_matrix;
+ else if (which == POINTSIZE_MASK)
+ matrix = vals->point_matrix;
+ else return (char *)0;
+
+ while (isspace(*ptr)) ptr++;
+ if (*ptr == '[')
+ {
+ /* This is a matrix containing real numbers. It would be nice
+ to use strtod() or sscanf() to read the numbers, but those
+ don't handle '~' for minus and we cannot force them to use a
+ "." for the radix. We'll have to do the hard work ourselves
+ (in readreal()). */
+
+ if ((ptr = readreal(++ptr, matrix + 0)) &&
+ (ptr = readreal(ptr, matrix + 1)) &&
+ (ptr = readreal(ptr, matrix + 2)) &&
+ (ptr = readreal(ptr, matrix + 3)))
+ {
+ while (isspace(*ptr)) ptr++;
+ if (*ptr != ']')
+ ptr = (char *)0;
+ else
+ {
+ ptr++;
+ while (isspace(*ptr)) ptr++;
+ if (*ptr == '-')
+ {
+ if (which == POINTSIZE_MASK)
+ vals->values_supplied |= POINTSIZE_ARRAY;
+ else
+ vals->values_supplied |= PIXELSIZE_ARRAY;
+ }
+ else ptr = (char *)0;
+ }
+ }
+ }
+ else
+ {
+ int value;
+ if ((ptr = GetInt(ptr, &value)))
+ {
+ vals->values_supplied &= ~which;
+ if (value > 0)
+ {
+ matrix[3] = (double)value;
+ if (which == POINTSIZE_MASK)
+ {
+ matrix[3] /= 10.0;
+ vals->values_supplied |= POINTSIZE_SCALAR;
+ }
+ else
+ vals->values_supplied |= PIXELSIZE_SCALAR;
+ /* If we're concocting the pixelsize array from a scalar,
+ we will need to normalize element 0 for the pixel shape.
+ This is done in FontFileCompleteXLFD(). */
+ matrix[0] = matrix[3];
+ matrix[1] = matrix[2] = 0.0;
+ }
+ else if (value < 0)
+ {
+ if (which == POINTSIZE_MASK)
+ vals->values_supplied |= POINTSIZE_WILDCARD;
+ else
+ vals->values_supplied |= PIXELSIZE_WILDCARD;
+ }
+ }
+ }
+ return ptr;
+}
+
+
+static void append_ranges(fname, nranges, ranges)
+char *fname;
+int nranges;
+fsRange *ranges;
+{
+ if (nranges)
+ {
+ int i;
+
+ strcat(fname, "[");
+ for (i = 0; i < nranges && strlen(fname) < 1010; i++)
+ {
+ if (i) strcat(fname, " ");
+ sprintf(fname + strlen(fname), "%d",
+ minchar(ranges[i]));
+ if (ranges[i].min_char_low ==
+ ranges[i].max_char_low &&
+ ranges[i].min_char_high ==
+ ranges[i].max_char_high) continue;
+ sprintf(fname + strlen(fname), "_%d",
+ maxchar(ranges[i]));
+ }
+ strcat(fname, "]");
+ }
+}
+
+Bool
+FontParseXLFDName(fname, vals, subst)
+ char *fname;
+ FontScalablePtr vals;
+ int subst;
+{
+ register char *ptr;
+ register char *ptr1,
+ *ptr2,
+ *ptr3,
+ *ptr4;
+ register char *ptr5;
+ FontScalableRec tmpvals;
+ char replaceChar = '0';
+ char tmpBuf[1024];
+ int spacingLen;
+ int l;
+ char *p;
+
+ bzero(&tmpvals, sizeof(tmpvals));
+ if (subst != FONT_XLFD_REPLACE_VALUE)
+ *vals = tmpvals;
+
+ if (!(*(ptr = fname) == '-' || (*ptr++ == '*' && *ptr == '-')) || /* fndry */
+ !(ptr = strchr(ptr + 1, '-')) || /* family_name */
+ !(ptr1 = ptr = strchr(ptr + 1, '-')) || /* weight_name */
+ !(ptr = strchr(ptr + 1, '-')) || /* slant */
+ !(ptr = strchr(ptr + 1, '-')) || /* setwidth_name */
+ !(ptr = strchr(ptr + 1, '-')) || /* add_style_name */
+ !(ptr = strchr(ptr + 1, '-')) || /* pixel_size */
+ !(ptr = GetMatrix(ptr + 1, &tmpvals, PIXELSIZE_MASK)) ||
+ !(ptr2 = ptr = GetMatrix(ptr + 1, &tmpvals, POINTSIZE_MASK)) ||
+ !(ptr = GetInt(ptr + 1, &tmpvals.x)) || /* resolution_x */
+ !(ptr3 = ptr = GetInt(ptr + 1, &tmpvals.y)) || /* resolution_y */
+ !(ptr4 = ptr = strchr(ptr + 1, '-')) || /* spacing */
+ !(ptr5 = ptr = GetInt(ptr + 1, &tmpvals.width)) || /* average_width */
+ !(ptr = strchr(ptr + 1, '-')) || /* charset_registry */
+ strchr(ptr + 1, '-'))/* charset_encoding */
+ return FALSE;
+
+ /* Lop off HP charset subsetting enhancement. Interpreting this
+ field requires allocating some space in which to return the
+ results. So, to prevent memory leaks, this procedure will simply
+ lop off and ignore charset subsetting, and initialize the
+ relevant vals fields to zero. It's up to the caller to make its
+ own call to FontParseRanges() if it's interested in the charset
+ subsetting. */
+
+ if (subst != FONT_XLFD_REPLACE_NONE &&
+ (p = strchr(strrchr(fname, '-'), '[')))
+ {
+ tmpvals.values_supplied |= CHARSUBSET_SPECIFIED;
+ *p = '\0';
+ }
+
+ /* Fill in deprecated fields for the benefit of rasterizers that care
+ about them. */
+ tmpvals.pixel = (tmpvals.pixel_matrix[3] >= 0) ?
+ (int)(tmpvals.pixel_matrix[3] + .5) :
+ (int)(tmpvals.pixel_matrix[3] - .5);
+ tmpvals.point = (tmpvals.point_matrix[3] >= 0) ?
+ (int)(tmpvals.point_matrix[3] * 10 + .5) :
+ (int)(tmpvals.point_matrix[3] * 10 - .5);
+
+ spacingLen = ptr4 - ptr3 + 1;
+
+ switch (subst) {
+ case FONT_XLFD_REPLACE_NONE:
+ *vals = tmpvals;
+ break;
+ case FONT_XLFD_REPLACE_STAR:
+ replaceChar = '*';
+ case FONT_XLFD_REPLACE_ZERO:
+ strcpy(tmpBuf, ptr2);
+ ptr5 = tmpBuf + (ptr5 - ptr2);
+ ptr3 = tmpBuf + (ptr3 - ptr2);
+ ptr2 = tmpBuf;
+ ptr = ptr1 + 1;
+
+ ptr = strchr(ptr, '-') + 1; /* skip weight */
+ ptr = strchr(ptr, '-') + 1; /* skip slant */
+ ptr = strchr(ptr, '-') + 1; /* skip setwidth_name */
+ ptr = strchr(ptr, '-') + 1; /* skip add_style_name */
+
+ if ((ptr - fname) + spacingLen + strlen(ptr5) + 10 >= (unsigned)1024)
+ return FALSE;
+ *ptr++ = replaceChar;
+ *ptr++ = '-';
+ *ptr++ = replaceChar;
+ *ptr++ = '-';
+ *ptr++ = '*';
+ *ptr++ = '-';
+ *ptr++ = '*';
+ if (spacingLen > 2)
+ {
+ memmove(ptr, ptr3, spacingLen);
+ ptr += spacingLen;
+ }
+ else
+ {
+ *ptr++ = '-';
+ *ptr++ = '*';
+ *ptr++ = '-';
+ }
+ *ptr++ = replaceChar;
+ strcpy(ptr, ptr5);
+ *vals = tmpvals;
+ break;
+ case FONT_XLFD_REPLACE_VALUE:
+ if (vals->values_supplied & PIXELSIZE_MASK)
+ {
+ tmpvals.values_supplied =
+ (tmpvals.values_supplied & ~PIXELSIZE_MASK) |
+ (vals->values_supplied & PIXELSIZE_MASK);
+ tmpvals.pixel_matrix[0] = vals->pixel_matrix[0];
+ tmpvals.pixel_matrix[1] = vals->pixel_matrix[1];
+ tmpvals.pixel_matrix[2] = vals->pixel_matrix[2];
+ tmpvals.pixel_matrix[3] = vals->pixel_matrix[3];
+ }
+ if (vals->values_supplied & POINTSIZE_MASK)
+ {
+ tmpvals.values_supplied =
+ (tmpvals.values_supplied & ~POINTSIZE_MASK) |
+ (vals->values_supplied & POINTSIZE_MASK);
+ tmpvals.point_matrix[0] = vals->point_matrix[0];
+ tmpvals.point_matrix[1] = vals->point_matrix[1];
+ tmpvals.point_matrix[2] = vals->point_matrix[2];
+ tmpvals.point_matrix[3] = vals->point_matrix[3];
+ }
+ if (vals->x >= 0)
+ tmpvals.x = vals->x;
+ if (vals->y >= 0)
+ tmpvals.y = vals->y;
+ if (vals->width >= 0)
+ tmpvals.width = vals->width;
+ else if (vals->width < -1) /* overload: -1 means wildcard */
+ tmpvals.width = -vals->width;
+
+
+ p = ptr1 + 1; /* weight field */
+ l = strchr(p, '-') - p;
+ sprintf(tmpBuf, "%*.*s", l, l, p);
+
+ p += l + 1; /* slant field */
+ l = strchr(p, '-') - p;
+ sprintf(tmpBuf + strlen(tmpBuf), "-%*.*s", l, l, p);
+
+ p += l + 1; /* setwidth_name */
+ l = strchr(p, '-') - p;
+ sprintf(tmpBuf + strlen(tmpBuf), "-%*.*s", l, l, p);
+
+ p += l + 1; /* add_style_name field */
+ l = strchr(p, '-') - p;
+ sprintf(tmpBuf + strlen(tmpBuf), "-%*.*s", l, l, p);
+
+ strcat(tmpBuf, "-");
+ if ((tmpvals.values_supplied & PIXELSIZE_MASK) == PIXELSIZE_ARRAY)
+ {
+ char buffer[80];
+ strcat(tmpBuf, "[");
+ strcat(tmpBuf, xlfd_double_to_text(tmpvals.pixel_matrix[0],
+ buffer, 0));
+ strcat(tmpBuf, xlfd_double_to_text(tmpvals.pixel_matrix[1],
+ buffer, 1));
+ strcat(tmpBuf, xlfd_double_to_text(tmpvals.pixel_matrix[2],
+ buffer, 1));
+ strcat(tmpBuf, xlfd_double_to_text(tmpvals.pixel_matrix[3],
+ buffer, 1));
+ strcat(tmpBuf, "]");
+ }
+ else
+ {
+ sprintf(tmpBuf + strlen(tmpBuf), "%d",
+ (int)(tmpvals.pixel_matrix[3] + .5));
+ }
+ strcat(tmpBuf, "-");
+ if ((tmpvals.values_supplied & POINTSIZE_MASK) == POINTSIZE_ARRAY)
+ {
+ char buffer[80];
+ strcat(tmpBuf, "[");
+ strcat(tmpBuf, xlfd_double_to_text(tmpvals.point_matrix[0],
+ buffer, 0));
+ strcat(tmpBuf, xlfd_double_to_text(tmpvals.point_matrix[1],
+ buffer, 1));
+ strcat(tmpBuf, xlfd_double_to_text(tmpvals.point_matrix[2],
+ buffer, 1));
+ strcat(tmpBuf, xlfd_double_to_text(tmpvals.point_matrix[3],
+ buffer, 1));
+ strcat(tmpBuf, "]");
+ }
+ else
+ {
+ sprintf(tmpBuf + strlen(tmpBuf), "%d",
+ (int)(tmpvals.point_matrix[3] * 10.0 + .5));
+ }
+ sprintf(tmpBuf + strlen(tmpBuf), "-%d-%d%*.*s%d%s",
+ tmpvals.x, tmpvals.y,
+ spacingLen, spacingLen, ptr3, tmpvals.width, ptr5);
+ strcpy(ptr1 + 1, tmpBuf);
+ if ((vals->values_supplied & CHARSUBSET_SPECIFIED) && !vals->nranges)
+ strcat(fname, "[]");
+ else
+ append_ranges(fname, vals->nranges, vals->ranges);
+ break;
+ }
+ return TRUE;
+}
+
+fsRange *FontParseRanges(name, nranges)
+char *name;
+int *nranges;
+{
+ int n;
+ unsigned long l;
+ char *p1, *p2;
+ fsRange *result = (fsRange *)0;
+ extern int add_range();
+
+ name = strchr(name, '-');
+ for (n = 1; name && n < 14; n++)
+ name = strchr(name + 1, '-');
+
+ *nranges = 0;
+ if (!name || !(p1 = strchr(name, '['))) return (fsRange *)0;
+ p1++;
+
+ while (*p1 && *p1 != ']')
+ {
+ fsRange thisrange;
+
+ l = strtol(p1, &p2, 0);
+ if (p2 == p1 || l > 0xffff) break;
+ thisrange.max_char_low = thisrange.min_char_low = l & 0xff;
+ thisrange.max_char_high = thisrange.min_char_high = l >> 8;
+
+ p1 = p2;
+ if (*p1 == ']' || *p1 == ' ')
+ {
+ while (*p1 == ' ') p1++;
+ if (add_range(&thisrange, nranges, &result, TRUE) != Successful)
+ break;
+ }
+ else if (*p1 == '_')
+ {
+ l = strtol(++p1, &p2, 0);
+ if (p2 == p1 || l > 0xffff) break;
+ thisrange.max_char_low = l & 0xff;
+ thisrange.max_char_high = l >> 8;
+ p1 = p2;
+ if (*p1 == ']' || *p1 == ' ')
+ {
+ while (*p1 == ' ') p1++;
+ if (add_range(&thisrange, nranges, &result, TRUE) != Successful)
+ break;
+ }
+ }
+ else break;
+ }
+
+ return result;
+}
diff --git a/src/util/format.c b/src/util/format.c
new file mode 100644
index 0000000..615f0ee
--- /dev/null
+++ b/src/util/format.c
@@ -0,0 +1,121 @@
+/* $Xorg: format.c,v 1.4 2001/02/09 02:04:04 xorgcvs Exp $ */
+/*
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Network Computing Devices or Digital
+ * not be used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. Network Computing
+ * Devices and Digital make no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * NETWORK COMPUTING DEVICES AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES OR DIGITAL BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+
+Copyright 1987, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+#include "FSproto.h"
+#include "font.h"
+
+int
+CheckFSFormat(format, fmask, bit_order, byte_order, scan, glyph, image)
+ fsBitmapFormat format;
+ fsBitmapFormatMask fmask;
+ int *bit_order,
+ *byte_order,
+ *scan,
+ *glyph,
+ *image;
+{
+ /* convert format to what the low levels want */
+ if (fmask & BitmapFormatMaskBit) {
+ *bit_order = format & BitmapFormatBitOrderMask;
+ *bit_order = (*bit_order == BitmapFormatBitOrderMSB)
+ ? MSBFirst : LSBFirst;
+ }
+ if (fmask & BitmapFormatMaskByte) {
+ *byte_order = format & BitmapFormatByteOrderMask;
+ *byte_order = (*byte_order == BitmapFormatByteOrderMSB)
+ ? MSBFirst : LSBFirst;
+ }
+ if (fmask & BitmapFormatMaskScanLineUnit) {
+ *scan = format & BitmapFormatScanlineUnitMask;
+ /* convert byte paddings into byte counts */
+ switch (*scan) {
+ case BitmapFormatScanlineUnit8:
+ *scan = 1;
+ break;
+ case BitmapFormatScanlineUnit16:
+ *scan = 2;
+ break;
+ case BitmapFormatScanlineUnit32:
+ *scan = 4;
+ break;
+ default:
+ return BadFontFormat;
+ }
+ }
+ if (fmask & BitmapFormatMaskScanLinePad) {
+ *glyph = format & BitmapFormatScanlinePadMask;
+ /* convert byte paddings into byte counts */
+ switch (*glyph) {
+ case BitmapFormatScanlinePad8:
+ *glyph = 1;
+ break;
+ case BitmapFormatScanlinePad16:
+ *glyph = 2;
+ break;
+ case BitmapFormatScanlinePad32:
+ *glyph = 4;
+ break;
+ default:
+ return BadFontFormat;
+ }
+ }
+ if (fmask & BitmapFormatMaskImageRectangle) {
+ *image = format & BitmapFormatImageRectMask;
+
+ if (*image != BitmapFormatImageRectMin &&
+ *image != BitmapFormatImageRectMaxWidth &&
+ *image != BitmapFormatImageRectMax)
+ return BadFontFormat;
+ }
+ return Successful;
+}
diff --git a/src/util/miscutil.c b/src/util/miscutil.c
new file mode 100644
index 0000000..5db04a1
--- /dev/null
+++ b/src/util/miscutil.c
@@ -0,0 +1,93 @@
+/* $Xorg: miscutil.c,v 1.4 2001/02/09 02:04:04 xorgcvs Exp $ */
+
+/*
+
+Copyright 1991, 1994, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+#include <X11/Xosdefs.h>
+#ifndef X_NOT_STDC_ENV
+#include <stdlib.h>
+#else
+char *malloc(), *realloc();
+#endif
+
+#define XK_LATIN1
+#include <X11/keysymdef.h>
+/* #include <X11/Xmu/CharSet.h> */
+
+/* make sure everything initializes themselves at least once */
+
+long serverGeneration = 1;
+
+unsigned long *
+Xalloc (m)
+{
+ return (unsigned long *) malloc (m);
+}
+
+unsigned long *
+Xrealloc (n,m)
+ unsigned long *n;
+{
+ if (!n)
+ return (unsigned long *) malloc (m);
+ else
+ return (unsigned long *) realloc ((char *) n, m);
+}
+
+void Xfree (n)
+ unsigned long *n;
+{
+ if (n)
+ free ((char *) n);
+}
+
+void CopyISOLatin1Lowered (dst, src, len)
+ char *dst, *src;
+ int len;
+{
+ register unsigned char *dest, *source;
+
+ for (dest = (unsigned char *)dst, source = (unsigned char *)src;
+ *source && len > 0;
+ source++, dest++, len--)
+ {
+ if ((*source >= XK_A) && (*source <= XK_Z))
+ *dest = *source + (XK_a - XK_A);
+ else if ((*source >= XK_Agrave) && (*source <= XK_Odiaeresis))
+ *dest = *source + (XK_agrave - XK_Agrave);
+ else if ((*source >= XK_Ooblique) && (*source <= XK_Thorn))
+ *dest = *source + (XK_oslash - XK_Ooblique);
+ else
+ *dest = *source;
+ }
+ *dest = '\0';
+}
+
+void register_fpe_functions ()
+{
+}
diff --git a/src/util/patcache.c b/src/util/patcache.c
new file mode 100644
index 0000000..824255c
--- /dev/null
+++ b/src/util/patcache.c
@@ -0,0 +1,224 @@
+/* $Xorg: patcache.c,v 1.4 2001/02/09 02:04:04 xorgcvs Exp $ */
+
+/*
+
+Copyright 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#include <fontmisc.h>
+#include <fontstruct.h>
+
+/*
+ * Static sized hash table for looking up font name patterns
+ *
+ * LRU entries, reusing old entries
+ */
+
+#define NBUCKETS 16
+#define NENTRIES 64
+
+#define UNSET (NENTRIES+1)
+
+typedef unsigned char EntryPtr;
+
+typedef struct _FontPatternCacheEntry {
+ struct _FontPatternCacheEntry *next, **prev;
+ short patlen;
+ char *pattern;
+ int hash;
+ FontPtr pFont; /* associated font */
+} FontPatternCacheEntryRec, *FontPatternCacheEntryPtr;
+
+typedef struct _FontPatternCache {
+ FontPatternCacheEntryPtr buckets[NBUCKETS];
+ FontPatternCacheEntryRec entries[NENTRIES];
+ FontPatternCacheEntryPtr free;
+} FontPatternCacheRec;
+
+/* Empty cache (for rehash) */
+void
+EmptyFontPatternCache (cache)
+ FontPatternCachePtr cache;
+{
+ int i;
+
+ for (i = 0; i < NBUCKETS; i++)
+ cache->buckets[i] = 0;
+ for (i = 0; i < NENTRIES; i++)
+ {
+ cache->entries[i].next = &cache->entries[i+1];
+ cache->entries[i].prev = 0;
+ cache->entries[i].pFont = 0;
+ xfree (cache->entries[i].pattern);
+ cache->entries[i].pattern = 0;
+ cache->entries[i].patlen = 0;
+ }
+ cache->free = &cache->entries[0];
+ cache->entries[NENTRIES - 1].next = 0;
+}
+
+/* Create and initialize cache */
+FontPatternCachePtr
+MakeFontPatternCache ()
+{
+ FontPatternCachePtr cache;
+ int i;
+ cache = (FontPatternCachePtr) xalloc (sizeof *cache);
+ if (!cache)
+ return 0;
+ for (i = 0; i < NENTRIES; i++) {
+ cache->entries[i].patlen = 0;
+ cache->entries[i].pattern = 0;
+ cache->entries[i].pFont = 0;
+ }
+ EmptyFontPatternCache (cache);
+ return cache;
+}
+
+/* toss cache */
+void
+FreeFontPatternCache (cache)
+ FontPatternCachePtr cache;
+{
+ int i;
+
+ for (i = 0; i < NENTRIES; i++)
+ xfree (cache->entries[i].pattern);
+ xfree (cache);
+}
+
+/* compute id for string */
+static int
+Hash (string, len)
+ char *string;
+ int len;
+{
+ int hash;
+
+ hash = 0;
+ while (len--)
+ hash = (hash << 1) ^ *string++;
+ if (hash < 0)
+ hash = -hash;
+ return hash;
+}
+
+/* add entry */
+void
+CacheFontPattern (cache, pattern, patlen, pFont)
+ FontPatternCachePtr cache;
+ char *pattern;
+ int patlen;
+ FontPtr pFont;
+{
+ FontPatternCacheEntryPtr e;
+ char *newpat;
+ int i;
+
+ newpat = (char *) xalloc (patlen);
+ if (!newpat)
+ return;
+ if (cache->free)
+ {
+ e = cache->free;
+ cache->free = e->next;
+ }
+ else
+ {
+ i = rand ();
+ if (i < 0)
+ i = -i;
+ i %= NENTRIES;
+ e = &cache->entries[i];
+ if (e->next)
+ e->next->prev = e->prev;
+ *e->prev = e->next;
+ xfree (e->pattern);
+ }
+ /* set pattern */
+ memcpy (newpat, pattern, patlen);
+ e->pattern = newpat;
+ e->patlen = patlen;
+ /* link to new hash chain */
+ e->hash = Hash (pattern, patlen);
+ i = e->hash % NBUCKETS;
+ e->next = cache->buckets[i];
+ if (e->next)
+ e->next->prev = &(e->next);
+ cache->buckets[i] = e;
+ e->prev = &(cache->buckets[i]);
+ e->pFont = pFont;
+}
+
+/* find matching entry */
+FontPtr
+FindCachedFontPattern (cache, pattern, patlen)
+ FontPatternCachePtr cache;
+ char *pattern;
+ int patlen;
+{
+ int hash;
+ int i;
+ FontPatternCacheEntryPtr e;
+
+ hash = Hash (pattern, patlen);
+ i = hash % NBUCKETS;
+ for (e = cache->buckets[i]; e; e = e->next)
+ {
+ if (e->patlen == patlen && e->hash == hash &&
+ !memcmp (e->pattern, pattern, patlen))
+ {
+ return e->pFont;
+ }
+ }
+ return 0;
+}
+
+void
+RemoveCachedFontPattern (cache, pFont)
+ FontPatternCachePtr cache;
+ FontPtr pFont;
+{
+ FontPatternCacheEntryPtr e;
+ int i;
+
+ for (i = 0; i < NENTRIES; i++)
+ {
+ if ((e = &cache->entries[i])->pFont == pFont)
+ {
+ e->pFont = 0;
+ if (e->next)
+ e->next->prev = e->prev;
+ *e->prev = e->next;
+ e->next = cache->free;
+ cache->free = e;
+ xfree (e->pattern);
+ e->pattern = 0;
+ }
+ }
+}
diff --git a/src/util/private.c b/src/util/private.c
new file mode 100644
index 0000000..9cb58c6
--- /dev/null
+++ b/src/util/private.c
@@ -0,0 +1,70 @@
+/* $Xorg: private.c,v 1.4 2001/02/09 02:04:04 xorgcvs Exp $ */
+
+/*
+
+Copyright 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#include "fontmisc.h"
+#include "fontstruct.h"
+
+int _FontPrivateAllocateIndex;
+
+int
+AllocateFontPrivateIndex ()
+{
+ return _FontPrivateAllocateIndex++;
+}
+
+void
+ResetFontPrivateIndex ()
+{
+ _FontPrivateAllocateIndex = 0;
+}
+
+Bool
+_FontSetNewPrivate (pFont, n, ptr)
+ FontPtr pFont;
+ int n;
+ pointer ptr;
+{
+ pointer *new;
+
+ if (n > pFont->maxPrivate)
+ {
+ new = (pointer *) xrealloc (pFont->devPrivates, (n + 1) * sizeof (pointer));
+ if (!new)
+ return FALSE;
+ pFont->devPrivates = new;
+ /* zero out new, uninitialized privates */
+ while(++pFont->maxPrivate < n)
+ pFont->devPrivates[pFont->maxPrivate] = (pointer)0;
+ }
+ pFont->devPrivates[n] = ptr;
+ return TRUE;
+}
diff --git a/src/util/utilbitmap.c b/src/util/utilbitmap.c
new file mode 100644
index 0000000..9842db1
--- /dev/null
+++ b/src/util/utilbitmap.c
@@ -0,0 +1,187 @@
+/* $Xorg: utilbitmap.c,v 1.4 2001/02/09 02:04:04 xorgcvs Exp $ */
+
+/*
+
+Copyright 1990, 1994, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+/* Utility functions for reformating font bitmaps */
+
+static unsigned char _reverse_byte[0x100] = {
+ 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+ 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+ 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+ 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+ 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+ 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+ 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+ 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+ 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+ 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+ 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+ 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+ 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+ 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+ 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+ 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+ 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+ 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+ 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+ 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+ 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+ 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+ 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+ 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+ 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+ 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+ 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+ 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+ 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+ 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+ 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+ 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
+};
+
+/*
+ * Invert bit order within each BYTE of an array.
+ */
+void
+BitOrderInvert(buf, nbytes)
+ register unsigned char *buf;
+ register int nbytes;
+{
+ register unsigned char *rev = _reverse_byte;
+
+ for (; --nbytes >= 0; buf++)
+ *buf = rev[*buf];
+}
+
+/*
+ * Invert byte order within each 16-bits of an array.
+ */
+void
+TwoByteSwap(buf, nbytes)
+ register unsigned char *buf;
+ register int nbytes;
+{
+ register unsigned char c;
+
+ for (; nbytes > 0; nbytes -= 2, buf += 2)
+ {
+ c = buf[0];
+ buf[0] = buf[1];
+ buf[1] = c;
+ }
+}
+
+/*
+ * Invert byte order within each 32-bits of an array.
+ */
+void
+FourByteSwap(buf, nbytes)
+ register unsigned char *buf;
+ register int nbytes;
+{
+ register unsigned char c;
+
+ for (; nbytes > 0; nbytes -= 4, buf += 4)
+ {
+ c = buf[0];
+ buf[0] = buf[3];
+ buf[3] = c;
+ c = buf[1];
+ buf[1] = buf[2];
+ buf[2] = c;
+ }
+}
+
+/*
+ * Repad a bitmap
+ */
+
+int
+RepadBitmap (pSrc, pDst, srcPad, dstPad, width, height)
+ char *pSrc, *pDst;
+ unsigned srcPad, dstPad;
+ int width, height;
+{
+ int srcWidthBytes,dstWidthBytes;
+ int row,col;
+ char *pTmpSrc,*pTmpDst;
+
+ switch (srcPad) {
+ case 1:
+ srcWidthBytes = (width+7)>>3;
+ break;
+ case 2:
+ srcWidthBytes = ((width+15)>>4)<<1;
+ break;
+ case 4:
+ srcWidthBytes = ((width+31)>>5)<<2;
+ break;
+ case 8:
+ srcWidthBytes = ((width+63)>>6)<<3;
+ break;
+ default:
+ return 0;
+ }
+ switch (dstPad) {
+ case 1:
+ dstWidthBytes = (width+7)>>3;
+ break;
+ case 2:
+ dstWidthBytes = ((width+15)>>4)<<1;
+ break;
+ case 4:
+ dstWidthBytes = ((width+31)>>5)<<2;
+ break;
+ case 8:
+ dstWidthBytes = ((width+63)>>6)<<3;
+ break;
+ default:
+ return 0;
+ }
+
+ width = srcWidthBytes;
+ if (width > dstWidthBytes)
+ width = dstWidthBytes;
+ pTmpSrc= pSrc;
+ pTmpDst= pDst;
+ for (row = 0; row < height; row++)
+ {
+ for (col = 0; col < width; col++)
+ *pTmpDst++ = *pTmpSrc++;
+ while (col < dstWidthBytes)
+ {
+ *pTmpDst++ = '\0';
+ col++;
+ }
+ pTmpSrc += srcWidthBytes - width;
+ }
+ return dstWidthBytes * height;
+}