Commit a59336bc authored by Piotr Caban's avatar Piotr Caban Committed by Alexandre Julliard

wineps: Remove dynamic glyph list.

We can't do much without unicode mapping.
parent 4ae4acca
...@@ -53,7 +53,6 @@ C_SRCS = \ ...@@ -53,7 +53,6 @@ C_SRCS = \
encode.c \ encode.c \
escape.c \ escape.c \
font.c \ font.c \
glyphlist.c \
graphics.c \ graphics.c \
init.c \ init.c \
pen.c \ pen.c \
......
...@@ -310,17 +310,12 @@ static BOOL AddBuiltinAFMs(void) ...@@ -310,17 +310,12 @@ static BOOL AddBuiltinAFMs(void)
BOOL PSDRV_GetFontMetrics(void) BOOL PSDRV_GetFontMetrics(void)
{ {
if (PSDRV_GlyphListInit() != 0)
return FALSE;
if (PSDRV_GetType1Metrics() == FALSE) if (PSDRV_GetType1Metrics() == FALSE)
return FALSE; return FALSE;
if (AddBuiltinAFMs() == FALSE) if (AddBuiltinAFMs() == FALSE)
return FALSE; return FALSE;
PSDRV_IndexGlyphList(); /* Enable fast searching of glyph names */
PSDRV_DumpFontList(); PSDRV_DumpFontList();
return TRUE; return TRUE;
......
/*******************************************************************************
*
* 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.
*
* 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
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <string.h>
#include "psdrv.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(psdrv);
#define GLYPHLIST_ALLOCSIZE 1024
static GLYPHNAME **glyphList = NULL;
static INT glyphListSize = 0;
static BOOL glyphNamesIndexed = TRUE;
/*******************************************************************************
* 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
*
*/
INT PSDRV_GlyphListInit(void)
{
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);
glyphList = HeapAlloc(PSDRV_Heap, 0, i * sizeof(GLYPHNAME *));
if (glyphList == NULL) return 1;
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)
*
*/
static inline INT GlyphListInsert(LPCSTR szName, INT index)
{
GLYPHNAME *g;
g = HeapAlloc(PSDRV_Heap, 0, sizeof(GLYPHNAME) + strlen(szName) + 1);
if (g == NULL) return -1;
g->index = -1;
g->sz = (LPSTR)(g + 1);
strcpy((LPSTR)g->sz, szName);
if (glyphListSize % GLYPHLIST_ALLOCSIZE == 0) /* grow the list? */
{
GLYPHNAME **newGlyphList;
newGlyphList = HeapReAlloc(PSDRV_Heap, 0, glyphList,
(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 *));
}
glyphList[index] = g;
++glyphListSize;
glyphNamesIndexed = FALSE;
#if 0
TRACE("Added '%s' at glyphList[%i] (glyphListSize now %i)\n",
glyphList[index]->sz, index, glyphListSize);
#endif
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)
{
#if 0
TRACE("Found '%s' at glyphList[%i]\n", glyphList[midIndex]->sz,
midIndex);
#endif
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)
*
*/
const GLYPHNAME *PSDRV_GlyphName(LPCSTR szName)
{
INT index;
index = GlyphListSearch(szName, 0, glyphListSize - 1);
if (index < 0)
return NULL;
return glyphList[index];
}
/*******************************************************************************
* PSDRV_IndexGlyphList
*
* Initializes index member of all GLYPHNAME structures
*
*/
VOID PSDRV_IndexGlyphList(void)
{
INT i;
if (glyphNamesIndexed)
return;
TRACE("%i glyph names:\n", glyphListSize);
for (i = 0; i < glyphListSize; ++i)
{
glyphList[i]->index = i;
#if 0
TRACE(" glyphList[%i] -> '%s'\n", i, glyphList[i]->sz);
#endif
}
glyphNamesIndexed = TRUE;
}
...@@ -508,9 +508,6 @@ extern BOOL PSDRV_WriteArrayDef(print_ctx *ctx, CHAR *pszArrayName, INT nSize); ...@@ -508,9 +508,6 @@ extern BOOL PSDRV_WriteArrayDef(print_ctx *ctx, CHAR *pszArrayName, INT nSize);
extern INT PSDRV_StartPage( print_ctx *ctx ); extern INT PSDRV_StartPage( print_ctx *ctx );
INT PSDRV_GlyphListInit(void);
const GLYPHNAME *PSDRV_GlyphName(LPCSTR szName);
VOID PSDRV_IndexGlyphList(void);
BOOL PSDRV_GetType1Metrics(void); BOOL PSDRV_GetType1Metrics(void);
SHORT PSDRV_CalcAvgCharWidth(const AFM *afm); SHORT PSDRV_CalcAvgCharWidth(const AFM *afm);
......
...@@ -725,9 +725,17 @@ static BOOL ParseB(LPSTR sz, OLD_AFMMETRICS *metrics) ...@@ -725,9 +725,17 @@ static BOOL ParseB(LPSTR sz, OLD_AFMMETRICS *metrics)
* Non-fatal error: leave metrics-> set to NULL * Non-fatal error: leave metrics-> set to NULL
* *
*/ */
static int __cdecl ug_name_cmp(const void *a, const void *b)
{
return strcmp(((const UNICODEGLYPH *)a)->name->sz,
((const UNICODEGLYPH *)b)->name->sz);
}
static BOOL ParseN(LPSTR sz, OLD_AFMMETRICS *metrics) static BOOL ParseN(LPSTR sz, OLD_AFMMETRICS *metrics)
{ {
CHAR save, *cp, *end_ptr; CHAR save, *cp, *end_ptr;
UNICODEGLYPH ug, *pug;
GLYPHNAME gn;
cp = sz + 1; cp = sz + 1;
...@@ -748,9 +756,21 @@ static BOOL ParseN(LPSTR sz, OLD_AFMMETRICS *metrics) ...@@ -748,9 +756,21 @@ static BOOL ParseN(LPSTR sz, OLD_AFMMETRICS *metrics)
save = *end_ptr; save = *end_ptr;
*end_ptr = '\0'; *end_ptr = '\0';
metrics->N = PSDRV_GlyphName(cp); ug.name = &gn;
if (metrics->N == NULL) gn.sz = cp;
return FALSE; pug = bsearch(&ug, PSDRV_AGLbyName, PSDRV_AGLbyNameSize,
sizeof(ug), ug_name_cmp);
if (!pug)
{
FIXME("unsupported glyph name: %s\n", cp);
metrics->N = NULL;
metrics->UV = -1;
}
else
{
metrics->N = pug->name;
metrics->UV = pug->UV;
}
*end_ptr = save; *end_ptr = save;
return TRUE; return TRUE;
...@@ -867,68 +887,32 @@ static inline BOOL IsWinANSI(LONG uv) ...@@ -867,68 +887,32 @@ static inline BOOL IsWinANSI(LONG uv)
* Also does some font metric calculations that require UVs to be known. * Also does some font metric calculations that require UVs to be known.
* *
*/ */
static int __cdecl UnicodeGlyphByNameIndex(const void *a, const void *b)
{
return ((const UNICODEGLYPH *)a)->name->index -
((const UNICODEGLYPH *)b)->name->index;
}
static VOID Unicodify(AFM *afm, OLD_AFMMETRICS *metrics) static VOID Unicodify(AFM *afm, OLD_AFMMETRICS *metrics)
{ {
INT i; INT i;
if (wcscmp(afm->EncodingScheme, L"FontSpecific") == 0) if (wcscmp(afm->EncodingScheme, L"FontSpecific") == 0)
{ {
for (i = 0; i < afm->NumofMetrics; ++i)
{
if (metrics[i].C >= 0x20 && metrics[i].C <= 0xff)
{
metrics[i].UV = metrics[i].C | 0xf000L;
}
else
{
TRACE("Unencoded glyph '%s'\n", metrics[i].N->sz);
metrics[i].UV = -1L;
}
}
afm->WinMetrics.sAscender = (SHORT)Round(afm->FontBBox.ury); afm->WinMetrics.sAscender = (SHORT)Round(afm->FontBBox.ury);
afm->WinMetrics.sDescender = (SHORT)Round(afm->FontBBox.lly); afm->WinMetrics.sDescender = (SHORT)Round(afm->FontBBox.lly);
} }
else /* non-FontSpecific encoding */ else /* non-FontSpecific encoding */
{ {
UNICODEGLYPH ug, *p_ug;
PSDRV_IndexGlyphList(); /* for fast searching of glyph names */
afm->WinMetrics.sAscender = afm->WinMetrics.sDescender = 0; afm->WinMetrics.sAscender = afm->WinMetrics.sDescender = 0;
for (i = 0; i < afm->NumofMetrics; ++i) for (i = 0; i < afm->NumofMetrics; ++i)
{ {
ug.name = metrics[i].N; if (IsWinANSI(metrics[i].UV))
p_ug = bsearch(&ug, PSDRV_AGLbyName, PSDRV_AGLbyNameSize, {
sizeof(ug), UnicodeGlyphByNameIndex); SHORT ury = (SHORT)Round(metrics[i].B.ury);
if (p_ug == NULL) SHORT lly = (SHORT)Round(metrics[i].B.lly);
{
TRACE("Glyph '%s' not in Adobe Glyph List\n", ug.name->sz);
metrics[i].UV = -1L;
}
else
{
metrics[i].UV = p_ug->UV;
if (IsWinANSI(p_ug->UV))
{
SHORT ury = (SHORT)Round(metrics[i].B.ury);
SHORT lly = (SHORT)Round(metrics[i].B.lly);
if (ury > afm->WinMetrics.sAscender) if (ury > afm->WinMetrics.sAscender)
afm->WinMetrics.sAscender = ury; afm->WinMetrics.sAscender = ury;
if (lly < afm->WinMetrics.sDescender) if (lly < afm->WinMetrics.sDescender)
afm->WinMetrics.sDescender = lly; afm->WinMetrics.sDescender = lly;
} }
} }
}
if (afm->WinMetrics.sAscender == 0) if (afm->WinMetrics.sAscender == 0)
afm->WinMetrics.sAscender = (SHORT)Round(afm->FontBBox.ury); afm->WinMetrics.sAscender = (SHORT)Round(afm->FontBBox.ury);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment