Improved word wrapping and tab key handling.
[wine/multimedia.git] / dlls / wineps / glyphlist.c
blobbec7189ecf6b7a0578e592a5c5d942af87ef2972
1 /*******************************************************************************
3 * Functions and data structures used to maintain a single list of glyph
4 * names. The list is sorted alphabetically and each name appears only
5 * once. After all font information has been read, the 'index' field of
6 * each GLYPHNAME structure is initialized, so future sorts/searches can
7 * be done without comparing strings.
9 * Copyright 2001 Ian Pilcher
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include <string.h>
27 #include "psdrv.h"
28 #include "wine/debug.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(psdrv);
32 #define GLYPHLIST_ALLOCSIZE 1024
34 static GLYPHNAME **glyphList = NULL;
35 static INT glyphListSize = 0;
36 static BOOL glyphNamesIndexed = TRUE;
38 /*******************************************************************************
39 * PSDRV_GlyphListInit
41 * Allocates initial block of memory for the glyph list and copies pointers to
42 * the AGL glyph names into it; returns 0 on success, 1 on failure
45 INT PSDRV_GlyphListInit()
47 INT i;
50 * Compute the smallest multiple of GLYPHLIST_ALLOCSIZE that is
51 * greater than or equal to PSDRV_AGLGlyphNamesSize
54 glyphListSize = PSDRV_AGLGlyphNamesSize;
55 i = ((glyphListSize + GLYPHLIST_ALLOCSIZE - 1) / GLYPHLIST_ALLOCSIZE) *
56 GLYPHLIST_ALLOCSIZE;
58 TRACE("glyphList will initially hold %i glyph names\n", i);
60 glyphList = HeapAlloc(PSDRV_Heap, 0, i * sizeof(GLYPHNAME *));
61 if (glyphList == NULL)
63 ERR("Failed to allocate %i bytes of memory\n", i * sizeof(GLYPHNAME *));
64 return 1;
67 for (i = 0; i < glyphListSize; ++i)
68 glyphList[i] = PSDRV_AGLGlyphNames + i;
70 return 0;
73 /*******************************************************************************
74 * GlyphListInsert
76 * Inserts a copy of the glyph name into the list at the index, growing the
77 * list if necessary; returns index on success (-1 on failure)
80 inline static INT GlyphListInsert(LPCSTR szName, INT index)
82 GLYPHNAME *g;
84 g = HeapAlloc(PSDRV_Heap, 0, sizeof(GLYPHNAME) + strlen(szName) + 1);
85 if (g == NULL)
87 ERR("Failed to allocate %i bytes of memory\n",
88 sizeof(GLYPHNAME) + strlen(szName) + 1);
89 return -1;
92 g->index = -1;
93 g->sz = (LPSTR)(g + 1);
94 strcpy((LPSTR)g->sz, szName);
96 if (glyphListSize % GLYPHLIST_ALLOCSIZE == 0) /* grow the list? */
98 GLYPHNAME **newGlyphList;
100 newGlyphList = HeapReAlloc(PSDRV_Heap, 0, glyphList,
101 (glyphListSize + GLYPHLIST_ALLOCSIZE) * sizeof(GLYPHNAME *));
102 if (newGlyphList == NULL)
104 ERR("Failed to allocate %i bytes of memory\n", (glyphListSize +
105 GLYPHLIST_ALLOCSIZE) * sizeof (GLYPHNAME *));
106 HeapFree(PSDRV_Heap, 0, g);
107 return -1;
110 glyphList = newGlyphList;
112 TRACE("glyphList will now hold %i glyph names\n",
113 glyphListSize + GLYPHLIST_ALLOCSIZE);
116 if (index < glyphListSize)
118 memmove(glyphList + (index + 1), glyphList + index,
119 (glyphListSize - index) * sizeof(GLYPHNAME *));
122 glyphList[index] = g;
123 ++glyphListSize;
124 glyphNamesIndexed = FALSE;
126 #if 0
127 TRACE("Added '%s' at glyphList[%i] (glyphListSize now %i)\n",
128 glyphList[index]->sz, index, glyphListSize);
129 #endif
130 return index;
133 /*******************************************************************************
134 * GlyphListSearch
136 * Searches the specified portion of the list for the glyph name and inserts it
137 * in the list if necessary; returns the index at which the name (now) resides
138 * (-1 if unable to insert it)
141 static INT GlyphListSearch(LPCSTR szName, INT loIndex, INT hiIndex)
143 INT midIndex, cmpResult;
145 while (1)
147 if (loIndex > hiIndex)
148 return GlyphListInsert(szName, loIndex);
150 midIndex = (loIndex + hiIndex) >> 1;
152 cmpResult = strcmp(szName, glyphList[midIndex]->sz);
154 if (cmpResult == 0)
156 #if 0
157 TRACE("Found '%s' at glyphList[%i]\n", glyphList[midIndex]->sz,
158 midIndex);
159 #endif
160 return midIndex;
163 if (cmpResult < 0)
164 hiIndex = midIndex - 1;
165 else
166 loIndex = midIndex + 1;
170 /*******************************************************************************
171 * PSDRV_GlyphName
173 * Searches the glyph name list for the provided name, adds it to the list if
174 * necessary, and returns a pointer to it (NULL if unable to add it)
177 const GLYPHNAME *PSDRV_GlyphName(LPCSTR szName)
179 INT index;
181 index = GlyphListSearch(szName, 0, glyphListSize - 1);
182 if (index < 0)
183 return NULL;
185 return glyphList[index];
188 /*******************************************************************************
189 * PSDRV_IndexGlyphList
191 * Initializes index member of all GLYPHNAME structures
194 VOID PSDRV_IndexGlyphList()
196 INT i;
198 if (glyphNamesIndexed)
199 return;
201 TRACE("%i glyph names:\n", glyphListSize);
203 for (i = 0; i < glyphListSize; ++i)
205 glyphList[i]->index = i;
206 #if 0
207 TRACE(" glyphList[%i] -> '%s'\n", i, glyphList[i]->sz);
208 #endif
211 glyphNamesIndexed = TRUE;