supermario/base/SuperMarioProj.1994-02-09/Toolbox/FontMgr/DiskCache/Source/DiskCacheMap.c
2019-06-29 23:17:50 +08:00

485 lines
15 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
File: DiskCacheMap.c
Contains: Code for maintaining a disk cache map.
Written by: John Farmer
Copyright: © 1991-1992 by Apple Computer, Inc., all rights reserved.
Change History (most recent first):
<4> 4/14/92 DTY #1027094,<BBM>: Do some stripping of pointers before doing any
pointer arithmetic in FontNameToFontNameIndex. Because this
routine doesnt move memory, its OK to dereference the handle
and strip it once and use this value without having to
constantly dereference the handle.
<3> 3/27/92 DTY #1024868: Remove calls to Assert since it doesnt do anything
any more.
<2> 1/3/92 JSM Roll-in changes from Sakura: Use squashed and fSquashed in
search routines.
<1> 7/17/91 jlf Split these routines out of DiskCacheExtensions.c
*/
// Include Statements
#include "BaseIncludes.h"
#include "Assertion.h"
#include "Errors.h"
#include "Files.h"
#include "Fonts.h"
#include "StringUtility.proto"
#include "DoubleByteBassCache.h"
#include "FSCdefs.h"
#include "MapString.h"
#include "PartialFontExtensions.proto"
#include "sfnt.h"
#include "sfnt_enum.h"
#include "FontScaler.h"
#include "Bass_Cache.h"
#include "DiskCacheMap.proto"
/* --------------------------------------------------------------------------------------
Routine: error = LoadDiskCacheMap( &diskCacheMapHandle, fileRefNum )
Purpose: Read the disk cache map into the system heap. The read takes place in two
parts: the first reads in the map header; the second reads in the cache
data.
Warnings: None
----------------------------------------------------------------------------------- */
OSErr LoadDiskCacheMap( DiskCacheMapStructureHandle* diskCacheMapHandlePointer, Integer fileRefNum )
{
// Locals
OSErr error;
THz savedZone;
DiskCacheMapStructureHandle diskCacheMapHandle;
DiskCacheMapStructure diskCacheMapHeader;
ParamBlockRec parameterBlock;
error = noErr;
diskCacheMapHandle = nil;
*diskCacheMapHandlePointer = nil;
savedZone = GetZone( );
SetZone( SystemZone( ) );
parameterBlock.ioParam.ioRefNum = fileRefNum;
parameterBlock.ioParam.ioBuffer = (Ptr) &diskCacheMapHeader;
parameterBlock.ioParam.ioReqCount = sizeof( DiskCacheMapStructure );
parameterBlock.ioParam.ioPosMode = fsFromStart;
parameterBlock.ioParam.ioPosOffset = 0;
error = PBRead( &parameterBlock, false );
if ( error == noErr ) {
if ( diskCacheMapHeader.fFileVersion != kCurrentDiskCacheFileVersion ) {
error = kUnknownDiskCacheFileVersion;
} else {
diskCacheMapHandle = (DiskCacheMapStructureHandle) NewHandle( (Size) diskCacheMapHeader.fDiskCacheMapSize );
if ( (error = MemError( )) == noErr ) {
parameterBlock.ioParam.ioRefNum = fileRefNum;
parameterBlock.ioParam.ioBuffer = StripAddress( (Ptr) *diskCacheMapHandle );
parameterBlock.ioParam.ioReqCount = diskCacheMapHeader.fDiskCacheMapSize;
parameterBlock.ioParam.ioPosMode = fsFromStart;
parameterBlock.ioParam.ioPosOffset = 0;
error = PBRead( &parameterBlock, false );
if ( error == noErr ) {
(*diskCacheMapHandle)->fFileRefNum = fileRefNum;
*diskCacheMapHandlePointer = diskCacheMapHandle;
}
}
}
}
if ( (error != noErr) && (diskCacheMapHandle != nil) ) {
DisposHandle( (Handle) diskCacheMapHandle );
}
SetZone( savedZone );
return( error );
}
/* --------------------------------------------------------------------------------------
Routine: error = DumpDiskCacheMap( diskCacheMapHandle )
Purpose: Write the disk cache map to disk.
Warnings: None
----------------------------------------------------------------------------------- */
OSErr DumpDiskCacheMap( DiskCacheMapStructureHandle diskCacheMapHandle )
{
// Locals
OSErr error;
Integer fileRefNum;
DiskCacheOffset diskCacheMapSize;
error = noErr;
fileRefNum = (*diskCacheMapHandle)->fFileRefNum;
diskCacheMapSize = (*diskCacheMapHandle)->fDiskCacheMapSize;
error = SetFPos( fileRefNum, fsFromStart, 0 );
if ( error == noErr ) {
error = FSWrite( fileRefNum, &diskCacheMapSize, (Ptr) *diskCacheMapHandle );
}
return( error );
}
/* --------------------------------------------------------------------------------------
Routine: MapFontNameToFontNumber( &fontExists, &fontNumber, fontName )
Purpose: Map a font name to a font number. If the fontName maps to the system font
a second check is made to see if the fontName is equal to the system font
name. If they aren't equal substituion occured and the font doesn't exist.
Warnings: None
----------------------------------------------------------------------------------- */
void MapFontNameToFontNumber( Boolean* fontExistsPointer, Integer* fontNumberPointer, StringPtr fontName )
{
// Locals
OSErr error;
Str255 systemFontName;
error = noErr;
*fontExistsPointer = true;
GetFNum( fontName, fontNumberPointer );
if ( *fontNumberPointer == systemFont ) {
GetFontName( systemFont, systemFontName );
*fontExistsPointer = ComparePascalString( systemFontName, fontName );
}
}
/* --------------------------------------------------------------------------------------
Routine: FontNameIndexToFontName( &fontName[0], fontNameIndex, diskCacheMapHandle )
Purpose: Nasty routine to traverse a string list structure and return a copy of
a string giving a string index. By the way, the ugly phrase:
(((stringEntryPointer->fString[0] + 1) + 1) & ~1)
is used to compute the word aligned, physical length (logical length plus
the string's length byte) of a string. My apologies in advance for it's
extreme nastiness.
The string list area is a fixed amount of space reserved at the end of
the disk cache map.
Warnings: None
----------------------------------------------------------------------------------- */
void FontNameIndexToFontName( StringPtr fontNamePointer, Integer fontNameIndex, DiskCacheMapStructureHandle diskCacheMapHandle )
{
// Locals
Integer stringIndex, roundedStringLength;
StringListEntryStructure *stringEntryPointer;
StringListStructure *stringListPointer;
stringListPointer = (StringListStructure*) ((Ptr) *diskCacheMapHandle + (*diskCacheMapHandle)->fFontNameListOffset);
stringEntryPointer = &stringListPointer->fStringList[0];
for ( stringIndex = 0; stringIndex < fontNameIndex; stringIndex++ ) {
roundedStringLength = (((stringEntryPointer->fString[0] + 1) + 1) & ~1);
stringEntryPointer = (StringListEntryStructure*) ((Ptr) stringEntryPointer + sizeof( StringListEntryStructure ) + roundedStringLength);
}
BlockMove( (Ptr) stringEntryPointer->fString, (Ptr) fontNamePointer, stringEntryPointer->fString[0] + 1 );
}
/* --------------------------------------------------------------------------------------
Routine: FontNameToFontNameIndex( &fontNameIndex, fontNamePointer, diskCacheMapHandle )
Purpose: Search through a nasty string list - itexists in a fixed area at the end
of the disk cache map - looking for a font name that matches the fontNamePointer
parameter. If the font name is found we return the list index. Otherwise,
the string is added to the string list.
Warnings: None
----------------------------------------------------------------------------------- */
OSErr FontNameToFontNameIndex( Integer *fontNameIndexPointer, StringPtr fontNamePointer, DiskCacheMapStructureHandle diskCacheMapHandle )
{
// Locals
OSErr error;
Integer stringIndex, stringCount, roundedStringLength,
sizeOfNewFontNameStructure;
DiskCacheOffset stringListOffset;
StringListEntryStructure *stringEntryPointer;
StringListStructure *stringListPointer;
DiskCacheMapStructurePointer strippedDiskCachePointer = StripAddress((Ptr) *diskCacheMapHandle); // We can dereference this once and use it because this routine doesnt move memory.
error = noErr;
*fontNameIndexPointer = kFontNameNotFound;
stringListPointer = (StringListStructure*) ((Ptr) strippedDiskCachePointer + strippedDiskCachePointer->fFontNameListOffset);
stringCount = stringListPointer->fStringCount;
stringEntryPointer = &stringListPointer->fStringList[0];
for ( stringIndex = 0; (*fontNameIndexPointer == kFontNameNotFound) && (stringIndex < stringCount); stringIndex++ ) {
if ( ComparePascalString( stringEntryPointer->fString, fontNamePointer ) ) {
*fontNameIndexPointer = stringIndex;
stringEntryPointer->fReferenceCount++;
} else {
roundedStringLength = (((stringEntryPointer->fString[0] + 1) + 1) & ~1);
stringEntryPointer = (StringListEntryStructure*) ((Ptr) stringEntryPointer + sizeof( StringListEntryStructure ) + roundedStringLength);
}
}
if ( *fontNameIndexPointer == kFontNameNotFound ) {
roundedStringLength = (((fontNamePointer[0] + 1) + 1) & ~1);
sizeOfNewFontNameStructure = sizeof( StringListEntryStructure ) + roundedStringLength;
stringListOffset = (Ptr) stringEntryPointer - strippedDiskCachePointer;
if ( stringListOffset + sizeOfNewFontNameStructure > strippedDiskCachePointer->fDiskCacheMapSize ) {
error = memFullErr;
} else {
stringEntryPointer->fReferenceCount = 1;
BlockMove( (Ptr) fontNamePointer, (Ptr) stringEntryPointer->fString, fontNamePointer[0] + 1 );
*fontNameIndexPointer = stringListPointer->fStringCount++;
}
}
return( error );
}
/* --------------------------------------------------------------------------------------
Routine: doesMatch = CompareDiskCacheEntry( searchTemplate, cacheIndex, diskCacheMapHandle )
Purpose: Compare a search template against a cacheEntry specified by cacheIndex.
Return true if they match. The fontName index field of the searchTemplate contains
the fontID to be compared. Since the disk cache stores font names to avoid
font renumbering madness, we use the fontID to get the font name and compare
that to the cache's font name. If the font doesn't exist we have severe problems
and return immediately.
Warnings: None
----------------------------------------------------------------------------------- */
Boolean CompareDiskCacheEntry( DiskCacheEntryStructure searchTemplate, DiskCacheIndex cacheIndex, DiskCacheMapStructureHandle diskCacheMapHandle )
{
// Locals
Boolean found, fontExists;
Integer diskCacheFontNumber;
DiskCacheEntryStructurePointer diskCacheEntryPointer;
Str255 diskCacheFontName, searchFontName;
found = false;
FontNameIndexToFontName( diskCacheFontName, (*diskCacheMapHandle)->fDiskCache[cacheIndex].fFontNameIndex, diskCacheMapHandle );
MapFontNameToFontNumber( &fontExists, &diskCacheFontNumber, diskCacheFontName );
if ( fontExists ) {
GetFontName( searchTemplate.fFontNameIndex, searchFontName );
diskCacheEntryPointer = &(*diskCacheMapHandle)->fDiskCache[cacheIndex];
found = ComparePascalString( diskCacheFontName, searchFontName ) &&
(diskCacheEntryPointer->fPointSize == searchTemplate.fPointSize) &&
(diskCacheEntryPointer->fStyle == searchTemplate.fStyle) &&
(diskCacheEntryPointer->fHorizontalScale == searchTemplate.fHorizontalScale) &&
(diskCacheEntryPointer->fVerticalScale == searchTemplate.fVerticalScale) &&
(diskCacheEntryPointer->fSkewTransform == searchTemplate.fSkewTransform) &&
(diskCacheEntryPointer->fSquashed == searchTemplate.fSquashed);
}
return( found );
}
/* --------------------------------------------------------------------------------------
Routine: error = SearchForDiskCache( &cacheIndex, searchTemplate, diskCacheMapHandle )
Purpose: Cycle through the disk cache comparing searchTemplate to each entry until
a match is found. Return a valid cacheIndex if found or kDiskCacheNotFound
if not found. This routine cycles through the offset list although the date
list would also work.
Warnings: None
----------------------------------------------------------------------------------- */
OSErr SearchForDiskCache( DiskCacheIndex* cacheIndexPointer, DiskCacheEntryStructure searchTemplate, DiskCacheMapStructureHandle diskCacheMapHandle )
{
// Locals
OSErr error;
DiskCacheIndex cacheIndex;
error = noErr;
*cacheIndexPointer = kDiskCacheNotFound;
cacheIndex = (*diskCacheMapHandle)->fFirstOffsetIndex;
while ( (*cacheIndexPointer == kDiskCacheNotFound) && (cacheIndex != kDiskCacheNotFound)) {
if ( CompareDiskCacheEntry( searchTemplate, cacheIndex, diskCacheMapHandle ) ) {
*cacheIndexPointer = cacheIndex;
} else {
cacheIndex = (*diskCacheMapHandle)->fDiskCache[cacheIndex].fNextOffsetIndex;
}
}
return( error );
}
/* --------------------------------------------------------------------------------------
Routine: error = SearchForDiskCacheUsingWidthTable( &cacheIndex, widthTableHandle, diskCacheMapHandle )
Purpose: Setup a search template based on information from the widthTableHandle parameter
and call SearchForDiskCache.
Warnings: None
----------------------------------------------------------------------------------- */
OSErr SearchForDiskCacheUsingWidthTable( DiskCacheIndex* cacheIndexPointer, widthTableHdl widthTableHandle,
DiskCacheMapStructureHandle diskCacheMapHandle, Boolean squashed )
{
// Locals
widthTablePtr widthTablePointer;
DiskCacheEntryStructure searchTemplate;
widthTablePointer = *widthTableHandle;
searchTemplate.fFontNameIndex = widthTablePointer->fID;
searchTemplate.fPointSize = widthTablePointer->fSize;
searchTemplate.fStyle = IntrinsicStyle( *widthTableHandle );
searchTemplate.fHorizontalScale = widthTablePointer->trans00;
searchTemplate.fVerticalScale = widthTablePointer->trans11;
searchTemplate.fSkewTransform = widthTablePointer->trans10;
searchTemplate.fSquashed = squashed;
return( SearchForDiskCache( cacheIndexPointer, searchTemplate, diskCacheMapHandle ) );
}
/* --------------------------------------------------------------------------------------
Routine: error = SearchForDiskCacheUsingCache( &cacheIndex, cacheHandle, diskCacheMapHandle )
Purpose: Setup a search template based on information from the cacheHandle parameter
and call SearchForDiskCache.
Warnings: None
----------------------------------------------------------------------------------- */
OSErr SearchForDiskCacheUsingCache( DiskCacheIndex* cacheIndexPointer, sb_CacheHeadHdl cacheHandle, DiskCacheMapStructureHandle diskCacheMapHandle )
{
// Locals
sb_CacheHeadPtr cachePointer;
DiskCacheEntryStructure searchTemplate;
cachePointer = *cacheHandle;
searchTemplate.fFontNameIndex = cachePointer->familyID;
searchTemplate.fPointSize = cachePointer->ptSize;
searchTemplate.fStyle = cachePointer->face;
searchTemplate.fHorizontalScale = cachePointer->trans00;
searchTemplate.fVerticalScale = cachePointer->trans11;
searchTemplate.fSkewTransform = cachePointer->trans10;
searchTemplate.fSquashed = cachePointer->squashed;;
return( SearchForDiskCache( cacheIndexPointer, searchTemplate, diskCacheMapHandle ) );
}