FontCache Class Reference

The FontCache maps a character description to a path for that character. There only ever needs to be a single instance of the FontCache so all data and methods are static. More...

#include <fntcache.h>

List of all members.

Static Public Member Functions

static BOOL Init ()
 Initialises the FontCache. This function must be called before the cache can be used.
static void DeInit ()
 Deinitialises the font cache.
static BOOL GetPath (CharDescription &ChDesc, INT32 **Points, BYTE **Types, UINT32 *Length)
static BOOL GetBounds (DocRect *pBounds, CharDescription &CharDesc)
static BOOL CalcDefaultCharBounds (DocRect *pRect, CharDescription &CharDesc)
 Calculate the bounding box of the specified char at default size Note: Always uses zero line width (LineCapButt and BevelledJoin).
static PathCreateDefaultCharPath (CharDescription &CharDesc)
 Create a path of the specified char at the default height Note: The caller is resposible for initialising the path's flags if required.

Static Public Attributes

static BOOL InitCalled = FALSE
static CamCachepPathCache

Static Private Attributes

static INT32 BoundsEntries = 0


Detailed Description

The FontCache maps a character description to a path for that character. There only ever needs to be a single instance of the FontCache so all data and methods are static.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
16/1/95
Documentation: specs.doc

See also:
CharDescription

PathHandleItem

Definition at line 138 of file fntcache.h.


Member Function Documentation

BOOL FontCache::CalcDefaultCharBounds DocRect pRect,
CharDescription CharDesc
[static]
 

Calculate the bounding box of the specified char at default size Note: Always uses zero line width (LineCapButt and BevelledJoin).

Author:
Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/3/95
Parameters:
CharDesc - description of char (charcode/bold/italic/font handle) [INPUTS]
pRect - bounding box of char [OUTPUTS]
Returns:
FALSE if fails

Definition at line 375 of file fntcache.cpp.

00376 {
00377     #ifdef RALPH
00378     RalphCriticalSection RalphCS;
00379     #endif
00380 
00381     ERROR2IF(pRect==NULL,FALSE,"FontCache::CalcCharBounds() - pRect==NULL");
00382 
00383     // create the char's default path
00384     Path* pCharPath=FontCache::CreateDefaultCharPath(CharDesc);
00385     if (pCharPath==NULL)
00386         return FALSE;
00387 
00388     // calculate the path's bounds
00389     BOOL    ok=TRUE;
00390     RECT    DrawRect = {0, 0, 0, 0};
00391     DocRect TempRect(0,0,0,0);
00392     INT32    points=pCharPath->GetNumCoords();
00393     if (points!=0)
00394     {
00395         DocCoord* pCoords=pCharPath->GetCoordArray();
00396         PathVerb* pVerbs =pCharPath->GetVerbArray();
00397 
00398         if (ok) ok=(pCoords!=NULL && pVerbs!=NULL);
00399         if (ok)
00400         {
00401             // Get hold of the default GDraw context.
00402             GDrawContext* pGDC = GRenderRegion::GetStaticDrawContext();
00403 
00404             if (pGDC == NULL)
00405                 ok = FALSE;
00406             else
00407                 ok = !pGDC->CalcStrokeBBox((POINT*)pCoords, pVerbs, points, &DrawRect, pCharPath->IsFilled, 0, CAPS_BUTT, JOIN_BEVEL, NULL);
00408             // TRACEUSER("wuerthne", _T("CDraw returned %d bbox from CDraw is %d, %d, %d, %d"), ok, DrawRect.left, DrawRect.top, DrawRect.right, DrawRect.bottom);
00409 
00410             // if the call to GDraw failed then we fall back to calculating the bounds from the points bounding box.
00411             if (ok)
00412             {
00413                 // GDraw did the job, so copy over the result from its RECT structure
00414                 // NB: The following assignment *looks* wrong because top and bottom seem to be swapped over,
00415                 //     but it is correct! The fields in RECT are just named in a strange way - GDraw certainly
00416                 //     has the same view of the structure as DocRect, so we only need to copy the fields over
00417                 //     in the order as they are defined and things are OK. Alternatively, we could pass a pointer
00418                 //     to a DocRect to GDraw but this would break things if ever someone changed the representation
00419                 //     of DocRect. I hope noone changes the field names in RECT - the ENSURE protects us:
00420                 ENSURE(&DrawRect.bottom > &DrawRect.right && &DrawRect.right > &DrawRect.top && &DrawRect.top > &DrawRect.left,
00421                        "Incompatible change of RECT structure");
00422                 TempRect = DocRect(DrawRect.left, DrawRect.top, DrawRect.right, DrawRect.bottom);
00423             }
00424             else
00425             {
00426                 // GDraw failed, so scan the coordinates
00427                 // pCharPath->DumpPath();
00428                 TempRect = pCharPath->GetBoundingRect();
00429                 ok = TRUE; // Well not really !
00430             }
00431         }
00432     }
00433 
00434     // tidy up, set output and return
00435     delete pCharPath;
00436     if (ok) *pRect=TempRect;
00437     return ok;
00438 }

Path * FontCache::CreateDefaultCharPath CharDescription CharDesc  )  [static]
 

Create a path of the specified char at the default height Note: The caller is resposible for initialising the path's flags if required.

Author:
Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/3/95
Parameters:
CharDesc - description of char (charcode/bold/italic/font handle) [INPUTS]
Returns:
pointer to new path (else NULL if fails)

Definition at line 452 of file fntcache.cpp.

00453 {
00454     #ifdef RALPH
00455     RalphCriticalSection RalphCS;
00456     #endif
00457 
00458     // get pointers to the char's path data
00459     DocCoord* pCoords=NULL;
00460     PathVerb* pVerbs=NULL;
00461     UINT32 points=0;
00462     if (FontCache::GetPath(CharDesc, (INT32**)&pCoords, &pVerbs, &points)==FALSE)
00463         return FALSE;
00464 
00465     // put path data into a Path structure
00466     Path* pPath=new Path(); 
00467     ERROR2IF(pPath==NULL,NULL,"FontCache::CreateDefaultCharPath() - failed to create path");
00468     BOOL ok=pPath->Initialise(points,12);
00469     if (ok) ok=pPath->CopyPathDataFrom(pCoords,pVerbs,points,TRUE);
00470 
00471     // if not OK, delete any path that exists and set returned path pointer to NULL
00472     if (!ok)
00473     {
00474         delete pPath;
00475         pPath=NULL;
00476     }
00477 
00478     return pPath;
00479 }

void FontCache::DeInit  )  [static]
 

Deinitialises the font cache.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
16/1/95
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-
Scope: public

See also:
-

Definition at line 198 of file fntcache.cpp.

00199 {
00200     BoundsEntries = 0;  // reset number of char bounds cached
00201 
00202     // Only DeInit if Init was called
00203     if (InitCalled)
00204     {
00205         // Delete the PathCache if one exists
00206         if (pPathCache)
00207         {
00208             delete (pPathCache);
00209             pPathCache = NULL;
00210         }
00211     }
00212 }

BOOL FontCache::GetBounds DocRect pBounds,
CharDescription CharDesc
[static]
 

Definition at line 324 of file fntcache.cpp.

00325 {
00326     #ifdef RALPH
00327     RalphCriticalSection RalphCS;
00328     #endif
00329 
00330     ERROR2IF(pBounds==NULL,FALSE,"FontCache::GetBounds() - pBounds==NULL");
00331 
00332     // static cache
00333     const  INT32 MaxBoundsEntries = 128;
00334     static AttrdCharBoundsCacheEntry entry[MaxBoundsEntries];
00335 
00336     // search cache for desired char
00337     INT32 i=0;
00338     while (i<BoundsEntries)
00339     {
00340         if (entry[i].desc==CharDesc)
00341             break;
00342         i+=1;
00343     }
00344 
00345     // if not found, either add to end of cache or replace a random entry
00346     if (i==BoundsEntries)
00347     {
00348         if (BoundsEntries<MaxBoundsEntries)
00349             i=BoundsEntries++;
00350         else
00351             i = rand() % MaxBoundsEntries;
00352         entry[i].desc=CharDesc;
00353         if (FontCache::CalcDefaultCharBounds(&(entry[i].bounds),CharDesc)==FALSE)
00354             return FALSE;
00355     }
00356 
00357     // set output and return
00358     *pBounds=entry[i].bounds;
00359     return TRUE;
00360 }

BOOL FontCache::GetPath CharDescription ChDesc,
INT32 **  Points,
BYTE **  Types,
UINT32 Length
[static]
 

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
16/1/95
Parameters:
ChDesc,: A description of the character you want me to find a path for [INPUTS]
Points,: An array of path points [OUTPUTS] Types: An array of path types Length: The path length
After calling GetPath you should create a

Returns:
TRUE if we find the requested path FALSE if we run out of memory. An error is returned and the cache is left in a stable state. i.e GetPath can be called again and will succeed if the right amount of memory is available.

Errors: - Scope: public

See also:
-

Definition at line 242 of file fntcache.cpp.

00243 {
00244     #ifdef RALPH
00245     RalphCriticalSection RalphCS;
00246     #endif
00247 
00248     // Obtain the path associated with the path handle
00249     // ChDesc will only be required if the character does not exist in the cache
00250     // If the function runs out of memory then an error will be set.
00251 
00252     ERROR3IF(pPathCache == NULL, "The FontCache has not been initialised"); 
00253 
00254     if (!pPathCache->FindPath( ChDesc.charHandle, *Points, *Types, *Length ) )
00255     {
00256         // We need to generate the path here !
00258         if (FONTMANAGER->GetCharPath(ChDesc, (DocCoord**)Points, (PathVerb**)Types, Length))
00259         {
00260             #if CACHE_STATS
00261             Misses++;
00262             MinPathSize = (*Length < MinPathSize) ? *Length: MinPathSize;
00263             MaxPathSize = (*Length > MaxPathSize) ? *Length: MaxPathSize;
00264             AveragePathSize = (AveragePathSize + *Length) / 2;
00265             #endif
00266             pPathCache->AddPath( ChDesc.charHandle, *Points, *Types, *Length );
00267         }
00268         else
00269         {
00270             return FALSE; // Probably ran out of memory
00271         }
00272     }
00273     #if CACHE_STATS
00274     else
00275     {
00276         Hits++;
00277     }
00278 
00279     DisplayCnt++;
00280 
00281     if (DisplayCnt == DisplayRate)
00282     {
00283         DisplayCnt = 0;
00284         // Display stats
00285         TRACE( _T("---")); 
00286         TRACE( _T("Hits = %lu, Misses = %lu\n"), Hits, Misses);
00287         TRACE( _T("Average Path Size = %lu\n"), AveragePathSize*9); 
00288         TRACE( _T("Minimum Path Size = %lu\n"), MinPathSize*9);
00289         TRACE( _T("Maximum Path Size = %lu\n"), MaxPathSize*9);
00290         TRACE( _T("Hit ratio = %lu\n\n"), Hits/Misses); 
00291     }
00292 
00293 
00294     #endif
00295 
00296 
00297 
00298 #if CACHE_STATS
00299 static INT32 Hitpc;
00300 #endif
00301 
00302 
00303     return TRUE; 
00304 }

BOOL FontCache::Init void   )  [static]
 

Initialises the FontCache. This function must be called before the cache can be used.

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
16/1/95
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
FALSE if we run out of memory.
Scope: public

Returns:
Errors: If we run out of memory during initialisation then FALSE is returned and an error is set.
See also:
-

Definition at line 168 of file fntcache.cpp.

00169 {
00170     InitCalled = TRUE; 
00171     BoundsEntries = 0;  // reset number of char bounds cached
00172 
00173     // Try to allocate our path cache
00174     pPathCache = new CamCache(); 
00175     ERROR1IF(pPathCache == NULL, FALSE, _R(IDE_NOMORE_MEMORY));
00176     return TRUE; 
00177 }


Member Data Documentation

INT32 FontCache::BoundsEntries = 0 [static, private]
 

Definition at line 161 of file fntcache.h.

BOOL FontCache::InitCalled = FALSE [static]
 

Definition at line 146 of file fntcache.h.

CamCache * FontCache::pPathCache [static]
 

Definition at line 155 of file fntcache.h.


The documentation for this class was generated from the following files:
Generated on Sat Nov 10 03:54:27 2007 for Camelot by  doxygen 1.4.4