Logo Search packages:      
Sourcecode: wine-unstable version File versions  Download package

glyphlist.c

/*******************************************************************************
 *
 *    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;
}

Generated by  Doxygen 1.6.0   Back to index