glyphlist.c 5.29 KB
Newer Older
1 2 3 4 5 6 7 8
/*******************************************************************************
 *
 *	Functions and data structures used to maintain a single list of glyph
 *	names.  The list is sorted alphabetically and each name appears only
 *	once.  After all font information has been read, the 'index' field of
 *	each GLYPHNAME structure is initialized, so future sorts/searches can
 *	be done without comparing strings.
 *
9 10 11 12 13 14 15 16 17 18 19 20 21 22
 * Copyright 2001 Ian Pilcher
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
23
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 25 26 27
 */

#include <string.h>
#include "psdrv.h"
28
#include "wine/debug.h"
29

30
WINE_DEFAULT_DEBUG_CHANNEL(psdrv);
31 32 33 34 35

#define	GLYPHLIST_ALLOCSIZE	1024

static GLYPHNAME    **glyphList = NULL;
static INT	    glyphListSize = 0;
36
static BOOL 	    glyphNamesIndexed = TRUE;
37 38 39 40 41 42 43 44

/*******************************************************************************
 *	PSDRV_GlyphListInit
 *
 *  Allocates initial block of memory for the glyph list and copies pointers to
 *  the AGL glyph names into it; returns 0 on success, 1 on failure
 *
 */
45
INT PSDRV_GlyphListInit(void)
46 47 48 49 50 51 52 53 54 55 56 57 58 59
{
    INT i;

    /*
     *	Compute the smallest multiple of GLYPHLIST_ALLOCSIZE that is
     *	greater than or equal to PSDRV_AGLGlyphNamesSize
     *
     */
    glyphListSize = PSDRV_AGLGlyphNamesSize;
    i = ((glyphListSize + GLYPHLIST_ALLOCSIZE - 1) / GLYPHLIST_ALLOCSIZE) *
	    GLYPHLIST_ALLOCSIZE;

    TRACE("glyphList will initially hold %i glyph names\n", i);

60
    glyphList = HeapAlloc(PSDRV_Heap, 0, i * sizeof(GLYPHNAME *));
61
    if (glyphList == NULL) return 1;
62 63 64 65 66 67 68 69 70 71 72 73 74 75

    for (i = 0; i < glyphListSize; ++i)
	glyphList[i] = PSDRV_AGLGlyphNames + i;

    return 0;
}

/*******************************************************************************
 *	GlyphListInsert
 *
 *  Inserts a copy of the  glyph name into the list at the index, growing the
 *  list if necessary; returns index on success (-1 on failure)
 *
 */
76
static inline INT GlyphListInsert(LPCSTR szName, INT index)
77
{
78
    GLYPHNAME *g;
79

80
    g = HeapAlloc(PSDRV_Heap, 0, sizeof(GLYPHNAME) + strlen(szName) + 1);
81
    if (g == NULL) return -1;
82 83 84

    g->index = -1;
    g->sz = (LPSTR)(g + 1);
85
    strcpy((LPSTR)g->sz, szName);
86 87 88 89 90

    if (glyphListSize % GLYPHLIST_ALLOCSIZE == 0)	/* grow the list? */
    {
	GLYPHNAME   **newGlyphList;

91
	newGlyphList = HeapReAlloc(PSDRV_Heap, 0, glyphList,
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
		(glyphListSize + GLYPHLIST_ALLOCSIZE) * sizeof(GLYPHNAME *));
	if (newGlyphList == NULL)
	{
	    HeapFree(PSDRV_Heap, 0, g);
	    return -1;
	}

	glyphList = newGlyphList;

	TRACE("glyphList will now hold %i glyph names\n",
		glyphListSize + GLYPHLIST_ALLOCSIZE);
    }

    if (index < glyphListSize)
    {
	memmove(glyphList + (index + 1), glyphList + index,
		(glyphListSize - index) * sizeof(GLYPHNAME *));
    }

111
    glyphList[index] = g;
112
    ++glyphListSize;
113
    glyphNamesIndexed = FALSE;
114

115
#if 0
116 117
    TRACE("Added '%s' at glyphList[%i] (glyphListSize now %i)\n",
	    glyphList[index]->sz, index, glyphListSize);
118
#endif
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
    return index;
}

/*******************************************************************************
 *	GlyphListSearch
 *
 *  Searches the specified portion of the list for the glyph name and inserts it
 *  in the list if necessary; returns the index at which the name (now) resides
 *  (-1 if unable to insert it)
 *
 */
static INT GlyphListSearch(LPCSTR szName, INT loIndex, INT hiIndex)
{
    INT midIndex, cmpResult;

    while (1)
    {
	if (loIndex > hiIndex)
	    return GlyphListInsert(szName, loIndex);

	midIndex = (loIndex + hiIndex) >> 1;

	cmpResult = strcmp(szName, glyphList[midIndex]->sz);

	if (cmpResult == 0)
	{
145
#if 0
146 147
	    TRACE("Found '%s' at glyphList[%i]\n", glyphList[midIndex]->sz,
		    midIndex);
148
#endif
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
	    return midIndex;
	}

	if (cmpResult < 0)
	    hiIndex = midIndex - 1;
	else
	    loIndex = midIndex + 1;
    }
}

/*******************************************************************************
 *	PSDRV_GlyphName
 *
 *  Searches the glyph name list for the provided name, adds it to the list if
 *  necessary, and returns a pointer to it (NULL if unable to add it)
 *
 */
166
const GLYPHNAME *PSDRV_GlyphName(LPCSTR szName)
167 168 169 170 171 172 173 174 175 176 177
{
    INT index;

    index = GlyphListSearch(szName, 0, glyphListSize - 1);
    if (index < 0)
	return NULL;

    return glyphList[index];
}

/*******************************************************************************
178
 *	PSDRV_IndexGlyphList
179
 *
180
 *  Initializes index member of all GLYPHNAME structures
181 182
 *
 */
183
VOID PSDRV_IndexGlyphList(void)
184 185
{
    INT i;
186

187
    if (glyphNamesIndexed)
188
    	return;
189 190 191 192

    TRACE("%i glyph names:\n", glyphListSize);

    for (i = 0; i < glyphListSize; ++i)
193 194
    {
    	glyphList[i]->index = i;
195
#if 0
196
	TRACE("  glyphList[%i] -> '%s'\n", i, glyphList[i]->sz);
197
#endif
198
    }
199

200
    glyphNamesIndexed = TRUE;
201
}