mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-11-29 20:49:19 +00:00
485 lines
15 KiB
C
485 lines
15 KiB
C
/*
|
||
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 doesn’t move memory, it’s 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 doesn’t 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( ¶meterBlock, 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( ¶meterBlock, 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 doesn’t 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 ) );
|
||
|
||
} |