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
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
|