Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

659 lines
13 KiB

/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
glfcach.h
Abstract:
PCL XL glyph cache
Environment:
Windows Whistler
Revision History:
11/09/00
Created it.
--*/
#include "xlpdev.h"
#include "xldebug.h"
#include "glyfcach.h"
XLGlyphCache::
XLGlyphCache(VOID)
/*++
Routine Description:
Arguments:
Return Value:
Note:
--*/
{
XL_VERBOSE(("XLGlyphCache::Ctor entry.\n"));
m_ulNumberOfFonts = NULL;
m_ulNumberOfArray = NULL;
m_paulFontID = NULL;
m_ppGlyphTable = NULL;
#if DBG
m_dbglevel = GLYPHCACHE;
#endif
}
XLGlyphCache::
~XLGlyphCache(VOID)
/*++
Routine Description:
Arguments:
Return Value:
Note:
--*/
{
XL_VERBOSE(("XLGlyphCache::Dtor entry.\n"));
FreeAll();
}
VOID
XLGlyphCache::
FreeAll(VOID)
/*++
Routine Description:
Arguments:
Return Value:
Note:
--*/
{
XL_VERBOSE(("XLGlyphCache::FreeAll entry.\n"));
MemFree(m_paulFontID);
ULONG ulI;
PGLYPHTABLE *ppGlyphTable = m_ppGlyphTable;
PGLYPHTABLE pGlyphTable;
for (ulI = 0; ulI < m_ulNumberOfFonts; ulI++, ppGlyphTable++)
{
if (pGlyphTable = *ppGlyphTable)
{
if (pGlyphTable->pGlyphID)
{
MemFree(pGlyphTable->pGlyphID);
}
MemFree(pGlyphTable);
}
}
if (m_ppGlyphTable)
{
MemFree(m_ppGlyphTable);
}
}
HRESULT
XLGlyphCache::
XLCreateFont(
ULONG ulFontID)
/*++
Routine Description:
Arguments:
Return Value:
Note:
--*/
{
XL_VERBOSE(("XLGlyphCache::CreateFont(ulFontiD=%d) entry.\n", ulFontID));
HRESULT hResult;
ULONG ulI;
//
// Search font ID
//
ULONG ulArrayID = UlSearchFontID(ulFontID);
//
// New font ID
//
if (ulArrayID == 0xFFFF || ulArrayID == m_ulNumberOfFonts)
{
//
// Out of buffer. Increase array
//
if (m_ulNumberOfArray == m_ulNumberOfFonts)
{
if (S_OK != (hResult = IncreaseArray()))
{
XL_ERR(("XLGlyphCache::CreateFont IncreaseArray failed.\n"));
return hResult;
}
}
*(m_paulFontID + m_ulNumberOfFonts) = ulFontID;
PGLYPHTABLE pGlyphTable;
if (!(pGlyphTable = (PGLYPHTABLE)MemAllocZ(sizeof(GLYPHTABLE))))
{
XL_ERR(("XLGlyphCache::CreateFont MemAllocZ failed.\n"));
return E_UNEXPECTED;
}
pGlyphTable->wFontID = (WORD)ulFontID;
pGlyphTable->wGlyphNum = 0;
pGlyphTable->pFirstGID = NULL;
pGlyphTable->pGlyphID = NULL;
pGlyphTable->dwAvailableEntries = 0;
PGLYPHID pGlyphID;
if (!(pGlyphID = (PGLYPHID)MemAllocZ(INIT_GLYPH_ARRAY * sizeof(GLYPHID))))
{
XL_ERR(("XLGlyphCache::CreateFont MemAllocZ failed.\n"));
MemFree(pGlyphTable);
return E_UNEXPECTED;
}
pGlyphTable->pGlyphID = pGlyphID;
pGlyphTable->dwAvailableEntries = INIT_GLYPH_ARRAY;
*(m_ppGlyphTable + m_ulNumberOfFonts) = pGlyphTable;
m_ulNumberOfFonts ++;
XL_VERBOSE(("XLGlyphCache::CreateFont New font ID.\n"));
}
return S_OK;
}
HRESULT
XLGlyphCache::
IncreaseArray(
VOID)
/*++
Routine Description:
Arguments:
Return Value:
Note:
--*/
{
XL_VERBOSE(("XLGlyphCache::IncreaseArray entry.\n"));
if (NULL == m_paulFontID || NULL == m_ppGlyphTable)
{
if (NULL == m_paulFontID)
{
if (!(m_paulFontID = (PULONG)MemAllocZ(INIT_ARRAY * sizeof(ULONG))))
{
FreeAll();
XL_ERR(("XLGlyphCache::IncreaseArray MemAllocZ failed.\n"));
return E_UNEXPECTED;
}
}
if (NULL == m_ppGlyphTable)
{
if (!(m_ppGlyphTable = (GLYPHTABLE**)MemAllocZ(INIT_ARRAY * sizeof(GLYPHTABLE))))
{
FreeAll();
XL_ERR(("XLGlyphCache::IncreaseArray MemAllocZ failed.\n"));
return E_UNEXPECTED;
}
}
m_ulNumberOfArray = INIT_ARRAY;
m_ulNumberOfFonts = 0;
}
else if (m_ulNumberOfArray == m_ulNumberOfFonts)
{
ULONG ulArraySize = m_ulNumberOfArray + ADD_ARRAY;
PULONG paulTmpFontID;
PGLYPHTABLE *ppTmpGlyphTable;
//
// Allocate new buffer
//
if (!(paulTmpFontID = (PULONG)MemAllocZ(ulArraySize)))
{
XL_ERR(("XLGlyphCache::IncreaseArray MemAllocZ failed.\n"));
return E_UNEXPECTED;
}
if (!(ppTmpGlyphTable = (GLYPHTABLE**)MemAllocZ(ulArraySize * sizeof(GLYPHTABLE))))
{
MemFree(paulTmpFontID);
XL_ERR(("XLGlyphCache::IncreaseArray MemAllocZ failed.\n"));
return E_UNEXPECTED;
}
//
// Copy old one to new one
//
CopyMemory(paulTmpFontID,
m_paulFontID,
m_ulNumberOfArray * sizeof(ULONG));
CopyMemory(ppTmpGlyphTable,
m_ppGlyphTable,
m_ulNumberOfArray * sizeof(GLYPHTABLE));
//
// Free old buffer
//
MemFree(m_paulFontID);
MemFree(m_ppGlyphTable);
//
// Set new buffer
//
m_paulFontID = paulTmpFontID;
m_ppGlyphTable = ppTmpGlyphTable;
m_ulNumberOfArray = ulArraySize;
}
return S_OK;
}
ULONG
XLGlyphCache::
UlSearchFontID(
ULONG ulFontID)
/*++
Routine Description:
Arguments:
Return Value:
Note:
--*/
{
XL_VERBOSE(("XLGlyphCache::UlSearchFontID entry.\n"));
ULONG ulReturn, ulI;
BOOL bFound;
if (NULL == m_paulFontID)
{
//
// Error case. Returns 0xFFFF.
// Here is an assumption. The number of fonts in one document doesn't
// become larger than 65535.
//
XL_ERR(("XLGlyphCache::UlSearchFontID failed.\n"));
return 0xFFFF;
}
bFound = TRUE;
//
// Search font ID
//
ulI = m_ulNumberOfFonts / 2;
PULONG paulFontID = m_paulFontID + ulI;
while ( *paulFontID != ulFontID)
{
if (ulI == 0)
{
bFound = FALSE;
break;
}
ulI = ulI / 2;
if (ulI == 0)
{
ulI = 1;
}
if (*paulFontID < ulFontID)
{
paulFontID += ulI;
}
else
{
paulFontID -= ulI;
}
if (ulI == 1)
{
ulI = 0;
}
}
if (!bFound)
{
ulReturn = m_ulNumberOfFonts;
}
else
{
ulReturn = (ULONG)(paulFontID - m_paulFontID);
}
XL_VERBOSE(("XLGlyphCache::UlSearchFontID(ulFontID=%d, ulArrayID=%d).\n", ulFontID, ulReturn));
return ulReturn;
}
HRESULT
XLGlyphCache::
AddGlyphID(
ULONG ulFontID,
ULONG ulGlyphID)
/*++
Routine Description:
Arguments:
Return Value:
Note:
--*/
{
XL_VERBOSE(("XLGlyphCache::AddGlyphID entry (ulFontiD=%d, ulGlyphID=%d).\n", ulFontID, ulGlyphID));
ULONG ulArrayID;
//
// Get the pointer to GLYPYTABLE of this font.
//
if (0xFFFF == (ulArrayID = UlSearchFontID(ulFontID)))
{
XL_ERR(("XLGlyphCache::AddGlyphID UlSearchFontID failed.\n"));
return E_UNEXPECTED;
}
PGLYPHTABLE pGlyphTable = *(m_ppGlyphTable+ulArrayID);
PGLYPHID pGlyphID = pGlyphTable->pFirstGID;
BOOL bFound;
WORD wI, wSearchRange;
wSearchRange = pGlyphTable->wGlyphNum / 2;
pGlyphID = PSearchGlyph(wSearchRange, TRUE, pGlyphID);
bFound = TRUE;
if (pGlyphID)
{
while (pGlyphID->ulGlyphID != ulGlyphID)
{
if (wSearchRange == 0)
{
bFound = FALSE;
break;
}
wSearchRange = wSearchRange / 2;
if (wSearchRange == 0)
{
wSearchRange = 1;
}
if (pGlyphID->ulGlyphID > ulGlyphID)
{
pGlyphID = PSearchGlyph(wSearchRange, TRUE, pGlyphID);
}
else
{
pGlyphID = PSearchGlyph(wSearchRange, FALSE, pGlyphID);
}
if (wSearchRange == 1)
{
wSearchRange = 0;
}
if (NULL == pGlyphID)
{
bFound = FALSE;
break;
}
}
}
else
{
//
// PSearchGlyph failed. There is not glyph available in the cache.
//
bFound = FALSE;
}
if (bFound)
{
XL_VERBOSE(("XLGlyphCache::AddGlyphID FOUND glyph in the cache.\n"));
return S_FALSE;
}
else if (pGlyphID)
{
PGLYPHID pPrevGID = pGlyphID->pPrevGID;
PGLYPHID pNextGID = pGlyphID->pNextGID;
PGLYPHID pNewGID;
IncreaseGlyphArray(ulFontID);
pNewGID = pGlyphTable->pGlyphID + pGlyphTable->wGlyphNum;
if (pGlyphID->ulGlyphID < ulGlyphID && ulGlyphID < pNextGID->ulGlyphID)
{
pGlyphID->pNextGID = pNewGID;
pNewGID->pPrevGID = pGlyphID;
pNewGID->pNextGID = pNextGID;
pNextGID->pPrevGID = pNewGID;
}
else
if (pPrevGID->ulGlyphID < ulGlyphID && ulGlyphID < pGlyphID->ulGlyphID)
{
pPrevGID->pNextGID = pNewGID;
pNewGID->pPrevGID = pPrevGID;
pNewGID->pNextGID = pGlyphID;
pGlyphID->pPrevGID = pNewGID;
}
pNewGID->ulGlyphID = ulGlyphID;
pGlyphTable->wGlyphNum++;
XL_VERBOSE(("XLGlyphCache::AddGlyphID ADDED glyph in the cache.\n"));
return S_OK;
}
else
{
PGLYPHID pNewGID;
IncreaseGlyphArray(ulFontID);
pNewGID = pGlyphTable->pGlyphID + pGlyphTable->wGlyphNum;
pNewGID->ulGlyphID = ulGlyphID;
pNewGID->pPrevGID = NULL;
pNewGID->pNextGID = NULL;
pGlyphTable->wGlyphNum++;
XL_VERBOSE(("XLGlyphCache::AddGlyphID ADDED glyph in the cache.\n"));
return S_OK;
}
}
PGLYPHID
XLGlyphCache::
PSearchGlyph(
WORD wSearchRange,
BOOL bForward,
PGLYPHID pGlyphID)
/*++
Routine Description:
Arguments:
Return Value:
Note:
--*/
{
XL_VERBOSE(("XLGlyphCache::PSearchGlyph entry (wSearchRange=%d,bForward=%d).\n",wSearchRange, bForward));
WORD wI;
if (pGlyphID)
{
if (bForward)
{
for (wI = 0; wI < wSearchRange; wI++)
{
if (pGlyphID->pNextGID)
{
pGlyphID = pGlyphID->pNextGID;
}
else
{
pGlyphID = NULL;
break;
}
}
}
else
{
for (wI = 0; wI < wSearchRange; wI++)
{
if (pGlyphID->pNextGID)
{
pGlyphID = pGlyphID->pNextGID;
}
else
{
pGlyphID = NULL;
break;
}
}
}
}
XL_VERBOSE(("XLGlyphCache::PSearchGlyph pGlyphID = %0x.\n", pGlyphID));
return pGlyphID;
}
HRESULT
XLGlyphCache::
IncreaseGlyphArray(
ULONG ulFontID)
{
ULONG ulArrayID;
//
// Get the pointer to GLYPYTABLE of this font.
//
if (0xFFFF == (ulArrayID = UlSearchFontID(ulFontID)))
{
XL_ERR(("XLGlyphCache::AddGlyphID UlSearchFontID failed.\n"));
return E_UNEXPECTED;
}
PGLYPHTABLE pGlyphTable = *(m_ppGlyphTable+ulArrayID);
//
// Get the pointer to GLYPYTABLE of this font.
//
if (0xFFFF == (ulArrayID = UlSearchFontID(ulFontID)))
{
XL_ERR(("XLGlyphCache::AddGlyphID UlSearchFontID failed.\n"));
return E_UNEXPECTED;
}
if (pGlyphTable->wGlyphNum == pGlyphTable->dwAvailableEntries)
{
PGLYPHID pGlyphID;
if (!(pGlyphID = (PGLYPHID)MemAllocZ((pGlyphTable->dwAvailableEntries + ADD_GLYPH_ARRAY) * sizeof(GLYPHID))))
{
XL_ERR(("XLGlyphCache::AddGlyphID MemAllocZ failed.\n"));
return E_UNEXPECTED;
}
CopyMemory(pGlyphID, pGlyphTable->pGlyphID, pGlyphTable->dwAvailableEntries * sizeof(GLYPHID));
pGlyphTable->pFirstGID = pGlyphID + (pGlyphTable->pFirstGID - pGlyphTable->pGlyphID);
MemFree(pGlyphTable->pGlyphID);
pGlyphTable->pGlyphID = pGlyphID;
pGlyphTable->dwAvailableEntries += ADD_GLYPH_ARRAY;
}
return S_OK;
}
#if DBG
VOID
XLGlyphCache::
SetDbgLevel(
DWORD dwLevel)
/*++
Routine Description:
Arguments:
Return Value:
Note:
--*/
{
m_dbglevel = dwLevel;
}
#endif