Updated Spanish translations.
[wine] / dlls / wineps / glyphlist.c
1 /*******************************************************************************
2  *
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.
8  *
9  * Copyright 2001 Ian Pilcher
10  *
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.
15  *
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.
20  *
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
24  */
25
26 #include <string.h>
27 #include "psdrv.h"
28 #include "wine/debug.h"
29
30 WINE_DEFAULT_DEBUG_CHANNEL(psdrv);
31
32 #define GLYPHLIST_ALLOCSIZE     1024
33
34 static GLYPHNAME    **glyphList = NULL;
35 static INT          glyphListSize = 0;
36 static BOOL         glyphNamesIndexed = TRUE;
37
38 /*******************************************************************************
39  *      PSDRV_GlyphListInit
40  *
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
43  *
44  */
45 INT PSDRV_GlyphListInit()
46 {
47     INT i;
48
49     /*
50      *  Compute the smallest multiple of GLYPHLIST_ALLOCSIZE that is
51      *  greater than or equal to PSDRV_AGLGlyphNamesSize
52      *
53      */
54     glyphListSize = PSDRV_AGLGlyphNamesSize;
55     i = ((glyphListSize + GLYPHLIST_ALLOCSIZE - 1) / GLYPHLIST_ALLOCSIZE) *
56             GLYPHLIST_ALLOCSIZE;
57
58     TRACE("glyphList will initially hold %i glyph names\n", i);
59
60     glyphList = (GLYPHNAME **) HeapAlloc(PSDRV_Heap, 0,
61             i * sizeof(GLYPHNAME *));
62     if (glyphList == NULL)
63     {
64         ERR("Failed to allocate %i bytes of memory\n", i * sizeof(GLYPHNAME *));
65         return 1;
66     }
67
68     for (i = 0; i < glyphListSize; ++i)
69         glyphList[i] = PSDRV_AGLGlyphNames + i;
70
71     return 0;
72 }
73
74 /*******************************************************************************
75  *      GlyphListInsert
76  *
77  *  Inserts a copy of the  glyph name into the list at the index, growing the
78  *  list if necessary; returns index on success (-1 on failure)
79  *
80  */
81 inline static INT GlyphListInsert(LPCSTR szName, INT index)
82 {
83     GLYPHNAME *g;
84
85     g = HeapAlloc(PSDRV_Heap, 0, sizeof(GLYPHNAME) + strlen(szName) + 1);
86     if (g == NULL)
87     {
88         ERR("Failed to allocate %i bytes of memory\n",
89                 sizeof(GLYPHNAME) + strlen(szName) + 1);
90         return -1;
91     }
92
93     g->index = -1;
94     g->sz = (LPSTR)(g + 1);
95     strcpy((LPSTR)g->sz, szName);
96
97     if (glyphListSize % GLYPHLIST_ALLOCSIZE == 0)       /* grow the list? */
98     {
99         GLYPHNAME   **newGlyphList;
100
101         newGlyphList = (GLYPHNAME **) HeapReAlloc(PSDRV_Heap, 0, glyphList,
102                 (glyphListSize + GLYPHLIST_ALLOCSIZE) * sizeof(GLYPHNAME *));
103         if (newGlyphList == NULL)
104         {
105             ERR("Failed to allocate %i bytes of memory\n", (glyphListSize +
106                     GLYPHLIST_ALLOCSIZE) * sizeof (GLYPHNAME *));
107             HeapFree(PSDRV_Heap, 0, g);
108             return -1;
109         }
110
111         glyphList = newGlyphList;
112
113         TRACE("glyphList will now hold %i glyph names\n",
114                 glyphListSize + GLYPHLIST_ALLOCSIZE);
115     }
116
117     if (index < glyphListSize)
118     {
119         memmove(glyphList + (index + 1), glyphList + index,
120                 (glyphListSize - index) * sizeof(GLYPHNAME *));
121     }
122
123     glyphList[index] = g;
124     ++glyphListSize;
125     glyphNamesIndexed = FALSE;
126
127 #if 0
128     TRACE("Added '%s' at glyphList[%i] (glyphListSize now %i)\n",
129             glyphList[index]->sz, index, glyphListSize);
130 #endif
131     return index;
132 }
133
134 /*******************************************************************************
135  *      GlyphListSearch
136  *
137  *  Searches the specified portion of the list for the glyph name and inserts it
138  *  in the list if necessary; returns the index at which the name (now) resides
139  *  (-1 if unable to insert it)
140  *
141  */
142 static INT GlyphListSearch(LPCSTR szName, INT loIndex, INT hiIndex)
143 {
144     INT midIndex, cmpResult;
145
146     while (1)
147     {
148         if (loIndex > hiIndex)
149             return GlyphListInsert(szName, loIndex);
150
151         midIndex = (loIndex + hiIndex) >> 1;
152
153         cmpResult = strcmp(szName, glyphList[midIndex]->sz);
154
155         if (cmpResult == 0)
156         {
157 #if 0
158             TRACE("Found '%s' at glyphList[%i]\n", glyphList[midIndex]->sz,
159                     midIndex);
160 #endif
161             return midIndex;
162         }
163
164         if (cmpResult < 0)
165             hiIndex = midIndex - 1;
166         else
167             loIndex = midIndex + 1;
168     }
169 }
170
171 /*******************************************************************************
172  *      PSDRV_GlyphName
173  *
174  *  Searches the glyph name list for the provided name, adds it to the list if
175  *  necessary, and returns a pointer to it (NULL if unable to add it)
176  *
177  */
178 const GLYPHNAME *PSDRV_GlyphName(LPCSTR szName)
179 {
180     INT index;
181
182     index = GlyphListSearch(szName, 0, glyphListSize - 1);
183     if (index < 0)
184         return NULL;
185
186     return glyphList[index];
187 }
188
189 /*******************************************************************************
190  *      PSDRV_IndexGlyphList
191  *
192  *  Initializes index member of all GLYPHNAME structures
193  *
194  */
195 VOID PSDRV_IndexGlyphList()
196 {
197     INT i;
198
199     if (glyphNamesIndexed == TRUE)
200         return;
201
202     TRACE("%i glyph names:\n", glyphListSize);
203
204     for (i = 0; i < glyphListSize; ++i)
205     {
206         glyphList[i]->index = i;
207 #if 0
208         TRACE("  glyphList[%i] -> '%s'\n", i, glyphList[i]->sz);
209 #endif
210     }
211
212     glyphNamesIndexed = TRUE;
213 }