mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-09-07 09:54:37 +00:00
3093 lines
107 KiB
C
3093 lines
107 KiB
C
|
/*
|
|||
|
File: Bass_Cache.c
|
|||
|
|
|||
|
Contains: Interfaces between Font Scaler code, QuickDraw and the Font Manager. Retrieves
|
|||
|
and caches glyphs. Initializes spline state variables.
|
|||
|
|
|||
|
Written by: Charlton E. Lui
|
|||
|
|
|||
|
Date: May 8, 1988
|
|||
|
|
|||
|
Revision: 1.0
|
|||
|
|
|||
|
Copyright: <EFBFBD> 1988-1992 by Apple Computer, Inc., all rights reserved.
|
|||
|
|
|||
|
Change History (most recent first):
|
|||
|
|
|||
|
<23> 6/22/92 JH #1033107 <AMW>: Changed call to GetEncodingTable to
|
|||
|
Font2RealScript.
|
|||
|
<22> 5/3/92 JH #1028023 <AMW>: Changing straight jump to fs_NewSfnt to the trap
|
|||
|
version. This enables our Korean subsidiary and potentially
|
|||
|
other non U.S distributors to patch the NewSfnt trap and look
|
|||
|
for a dongle.
|
|||
|
<21> 1/3/92 JSM Roll-in changes from Sakura: sb_CheckCache() can return NO_BITS
|
|||
|
from sb_RenderGlyph() (seems to only happen when printing with
|
|||
|
the StyleWriter), check for this and call
|
|||
|
CheckForMaximumDiskCacheSize() in sb_RetrieveGlyph() anyway. We
|
|||
|
need to understand this better. Call
|
|||
|
DumpFontCacheToDiskIfNotTooBig(), not DumpFontCacheToDisk(), in
|
|||
|
sb_DisposeCacheHandle(). Pass squashed to
|
|||
|
LoadFontCacheFromDisk(). If banding in TrueType, don't
|
|||
|
AddGlyphOffset table more than once in sb_RetrieveGlyph.
|
|||
|
<20> 12/9/91 JH #1017215,Fixing problem in sb_SetFontMemory... where if
|
|||
|
fs_NewSfnt fails it just bails (calls sb_Debug). The thing about
|
|||
|
this is that we (whose we) have released about 16 international
|
|||
|
fonts that actually have a specificID of Roman for their CMAP
|
|||
|
despite being fonts for scripts other than Roman. These fonts
|
|||
|
work on 7.0, but since we now do the right thing in
|
|||
|
sb_SetFontMemory (figure out which script the font should belong
|
|||
|
to and then use that script for specificID) they won't work for
|
|||
|
7.1 (cubee) so to fix that we try again with the Roman platform
|
|||
|
ID if the first call to sb_SetFontMemory fails.
|
|||
|
<19> 10/23/91 DTY Flush the FOND candidate cache in sb_KillSomeCaches when
|
|||
|
everything else is being flushed.
|
|||
|
<18> 10/22/91 RB Add support for sfnt-embedded-bitmaps
|
|||
|
<17> 9/25/91 jlf Rolled in modifications from Pacific TrueType project and rolled out
|
|||
|
DOUBLE_BYTE conditional code.
|
|||
|
|
|||
|
Added support for double-byte bass caches. The glyphArray field of a
|
|||
|
cache is not compatible with double-byte operating systems. Use the
|
|||
|
routines in DoubleByteBassCache.c for international support. Added
|
|||
|
support for disk caching code through the LoadFontCacheFromDisk and
|
|||
|
CheckForMaximumDiskCacheSize routines. The spline directory of a
|
|||
|
TrueType font is now appended to it's global width table for partial
|
|||
|
font support. sb_SetMemPtrs now accepts a widthTable handle instead of
|
|||
|
an sfnt handle in order to initialize the spline sfntDirectory field
|
|||
|
of the Scaler input parameter block. Call GetResInfo to obtain the sfntID
|
|||
|
in FillPrinterWidths instead of hacking it to zero - it would be nice if
|
|||
|
the printer driver passed the sfntID value in, but, that means we would
|
|||
|
have to rev all printer drivers that use this call. Added partial font
|
|||
|
support. Added disposecachehandle routine to support disk caching (routine
|
|||
|
calls DumpFontCacheToDisk before calling disposezonehandle). Call
|
|||
|
sb_DisposeCacheHandle in sb_KillSomeCaches instead of letting the cache
|
|||
|
handles die through a heap reformat. Replaced calls to sb_DisposeZoneHandle
|
|||
|
with cache handle arguments with calls to sb_DisposeCacheHandle. Call
|
|||
|
KillApplicationHeapFragmentTableCaches in flush fonts to flush partial
|
|||
|
font fragments. Removed static qualifier in front of sb_ShrinkCacheToMin.
|
|||
|
Initialize familyID field of a cache in sb_InitCacheHead to the new spline
|
|||
|
key global fLastSwapFontFamilyID since the font manager has the obnoxious
|
|||
|
habit of setting the fID field of a width table and certain low memory
|
|||
|
globals to -1 when the width table is invalidated. This caused major
|
|||
|
problems with cmap lookup when using Asian fonts. Added widthTable parameter
|
|||
|
to SetFontMemory since it calls SetMemPtrs. Initialized specificID field
|
|||
|
of newsfnt input parameter block to the proper script number instead of
|
|||
|
hard-coding it to Roman. Always maintain the cache list in the system heap.
|
|||
|
sb_NewZoneHandle no longer assumes that the current heap is always the
|
|||
|
application heap (this previously caused major heap trashes when the
|
|||
|
system font was an outline font). Rolled back in code for MultiFinder
|
|||
|
memory allocation (this code relies on a bug fix in 6.x MultiFinder
|
|||
|
where the current zone is set to the MultiFinder heap before calling
|
|||
|
TempDisposHandle on a purged handle. 7.x systems shouldn't be affected).
|
|||
|
Rolled in fixes for bugs found during the development of the background
|
|||
|
Tabasco driver (Charlton Lui via Allen Cronce). I friggin' hate this file.
|
|||
|
|
|||
|
<16> 3/5/91 CL (RB)#82681. Needed to make one more change to sb_searchforcache.
|
|||
|
The cache needed to be set to nil to when a cache was
|
|||
|
purged.
|
|||
|
<15> 2/28/91 CL (KON)(RB)#82681. Making current cache purgeable.
|
|||
|
<14> 2/11/91 RB MR, CL,CC,: Fix dropouts when squashing by trying twice to
|
|||
|
squash rather than once.
|
|||
|
<11> 1/22/91 CL (RB) #81198, #81199. Fixing large glyph crash (ptsize 22,000
|
|||
|
pt). Need to pass on error codes.
|
|||
|
<10> 12/11/90 MR Improve squishing math, use leading from cache for fmLeading.
|
|||
|
Low mem hack. [rb]
|
|||
|
<9> 11/27/90 MR Change ByteMax() to return an unsigned char, stop caching
|
|||
|
algo-styles [rb]
|
|||
|
<8> 11/21/90 CL (RB)Adding in scan converter runInMinMode operations. Broke
|
|||
|
sb_renderglyph into smaller subroutines.
|
|||
|
<7> 10/29/90 CL (RB)if fs_OpenFonts fails we need to get rid of the workhandle
|
|||
|
since it is only partially set up for use. Needed to call
|
|||
|
sb_setmemptrs before settting the clientid.
|
|||
|
<6> 10/23/90 CL (MR)Making the preflight call work better.
|
|||
|
<5> 10/23/90 CL Somehow this file got corrupt by either BBS, projector or the
|
|||
|
compare file tool??? Fixed it back up!!!
|
|||
|
<4> 10/22/90 CL (BKR)Adding runInMinMode code. This will run in a minimal memory
|
|||
|
space when memory is very low. Added in banding of character for
|
|||
|
low memory situations.
|
|||
|
<3> 10/20/90 MR Change transform[2][2] from a fix_one to frac_one
|
|||
|
<2+> 10/20/90 MR,rb Change transform[2][2] from a fix_one to frac_one
|
|||
|
<2> 10/11/90 CL Set ENTRY_ERROR to skip glyphs with zero scan lines.
|
|||
|
<34> 10/9/90 CL Added preflight routine to see if there seems to be enough
|
|||
|
room to render the glyphs.
|
|||
|
<33> 10/2/90 CL Fixing up memory error handling.
|
|||
|
<32> 9/24/90 CL Fixing error handling in sb_renderglyph. Needed to check
|
|||
|
the result after sb_renderglyphinfo call.
|
|||
|
<31> 9/10/90 CL Added in a shrinkTest to sb_SizeTheBlock to see whether a block
|
|||
|
should be resized down. This is good for sizing down the extra
|
|||
|
scan converter space needed for large chars and for large bitmapHands.
|
|||
|
<30> 9/10/90 CL Now checking if system and app heap is full. If so purge will
|
|||
|
be left on. When both heaps are full it will switch back
|
|||
|
and forth to try to get the memory. Conditional is in for
|
|||
|
Multi-Finder or system memory.
|
|||
|
<29> 9/5/90 CL Getting rid of call to sb_Debug in sb_newZoneHandle since it
|
|||
|
really is not an error but just a possible temporary failure.
|
|||
|
Bug in sb_FlushFonts<EFBFBD> needed to zero out the cacheListHand.
|
|||
|
<28> 9/4/90 CL Fixing up memory allocations<EFBFBD> Bug in sb_GrowZoneHandle - Assigned
|
|||
|
new zone before DiposeZoneHandle giving this function possibly
|
|||
|
the wrong zone. Reworked sb_GrowZoneHandle, sb_NewZoneHandle
|
|||
|
logic. Added in sb_SetCachesNoPurge, sb_SetCachesPurge so caches
|
|||
|
would not unneccessarily get purged. Took out splineKeyPtr param
|
|||
|
out of sb_DisposeWorkHandle to make code consistent. Took out
|
|||
|
extra call to sb_PrepareWorkHandle from sb_CheckCache. Bug in
|
|||
|
original sb_GrowZoneHandle code now in sb_SizeTheBlock fix. When
|
|||
|
a disposeZoneHandle was called the current cache was not cleared
|
|||
|
so it would be used and blamo the heap free list would get
|
|||
|
corrupt. Bug in sb_SearchForCache<EFBFBD> Must make the font non-purgeable
|
|||
|
before calling sb_PrepareWorkHandle and sb_SetNewSFNT. Font got
|
|||
|
purged when it should not have. Got rid of the now unneeded
|
|||
|
call to sb_initmemory. Major bug in the sb_GrowZoneHandle that
|
|||
|
is now in the sb_SizeTheBlock routine. This routine would
|
|||
|
dispose a handle without being able to update the variables
|
|||
|
from the calling routine. Therefore you could dispose the
|
|||
|
handle, try to get a new handle and fail, then try to use the
|
|||
|
disposed handle which would of course corrupt the free list
|
|||
|
eventually causing major havoc in the system. Bug when calling
|
|||
|
sb_shrinkbitmap on a cached contour. Since the scan lines
|
|||
|
could be less than the full height the shrink bitmap call would
|
|||
|
go to far since it used the full scan height that is cached
|
|||
|
in the font cache. Bug when allocating with the new memory
|
|||
|
routines the bitmapHand needs to be disposed and cleared if
|
|||
|
it is in the quiting apps heap space. Terrible bug in living
|
|||
|
in the MultiFinder temp memory and being purgeable. There is
|
|||
|
no way to know the zone and we would die if we dipose the handle
|
|||
|
not knowing the true zone if it is in the Multi_Finder heap. Fixed
|
|||
|
by living only in the system heap and application heap as we did before
|
|||
|
just like the init code does now.
|
|||
|
<27> 9/4/90 KSM Fix Begin/EndSystem mode bug in sb_NewZoneHandle.
|
|||
|
<26> 8/28/90 MR Change SetHandleSize calls to set the correct zone by using
|
|||
|
common routines (NewZoneHandle, GrowZoneHandle,
|
|||
|
DisposeZoneHandle). Changed WorkHandMem to ResizeWorkHandle.
|
|||
|
Added calls to PrepareWorkHandle to pascal routines that use
|
|||
|
fsWorkHand but didn't first check it. Moved bitmapHand and
|
|||
|
fsWorkHand to use same memory routines as caches.
|
|||
|
<25> 8/27/90 MR Fix uninitialized zone in SearchForCache, added call to gestalt
|
|||
|
to NOT use system heap if it is not growable.
|
|||
|
<24> 8/22/90 MR Change calls to FillWidthTable to pass sfnt handle and rsrc ID
|
|||
|
<23> 8/21/90 MR More consistant checking of fsWorkHand for purginess. Still not
|
|||
|
completely confident I<EFBFBD>ve caught every case.
|
|||
|
<22> 8/20/90 MR Restructure memory allocation across heaps. New routines:
|
|||
|
NewCacheHandle, NewWorkHandle, sb_DisposeZoneHandle. Conditional
|
|||
|
code for system_7 and init.
|
|||
|
<21> 8/11/90 MR Use splineKey as global instead of passing it as a parameter
|
|||
|
<20> 8/10/90 MR Removed conditional MIKE code
|
|||
|
<19> 8/10/90 MR Remove disk_cache code, Removed call to ReallocHandle in
|
|||
|
SearchForCache (cross-zone bug)
|
|||
|
<18> 8/1/90 gbm rid file of vile warnings
|
|||
|
<17> 7/20/90 MR change NewHandleSys to NewHandleSys
|
|||
|
<16> 7/20/90 MR Remove warnings, cache optimizations, found cacheHand-purge bug
|
|||
|
<15> 7/18/90 MR Add Fonts.h to include file list (to define FMOutput since it
|
|||
|
was removed from bass_cache.h
|
|||
|
<14> 7/16/90 CL Made Finder compatible for the Goudy init.
|
|||
|
<13> 7/14/90 MR changed reference from SQRT2 to FIXEDSQRT2
|
|||
|
<12> 7/13/90 MR Changed to use union in FSInput
|
|||
|
<11> 7/2/90 RB No change, just get comments synched
|
|||
|
<9+> 7/2/90 RB bbs screwup
|
|||
|
<9> 7/2/90 CL Fixed runtime conditional to make sure it clips when needed.
|
|||
|
<8> 7/2/90 CL Reworked sb_renderGlyph<EFBFBD> Now clips the character if squishing
|
|||
|
was not enough. Took out encryption.
|
|||
|
<7> 5/29/90 CL Took out cache references from the widthtables. Fixed printer
|
|||
|
Font Scaler reset bug.
|
|||
|
<6> 5/3/90 CL Adding shutdown proc for bass clean up. More work on disk
|
|||
|
caching. Removed extra part of transform matrix not needed by
|
|||
|
system. In sb_FlushFonts got rid disposed of Handles that had
|
|||
|
nil pointers. Adding support for new encryption scheme and scan
|
|||
|
converter. Added new memory area
|
|||
|
<5> 4/10/90 CL Added support for double byte codes. Worked on disk caching.
|
|||
|
Fixed squishing routine.
|
|||
|
<4> 3/24/90 CL Font Scaler is returning totally bogus values causing terrible
|
|||
|
stack corruption. Added range checking so we can handle these
|
|||
|
values.
|
|||
|
<3> 3/20/90 CL Adding Disk Cache<EFBFBD> Support for the tag format
|
|||
|
<2> 2/27/90 CL Added lots of support for DrText<EFBFBD>s optimizations. Added a
|
|||
|
routine to shrink bitmaps after the Font Scaler call and save a
|
|||
|
possible 2x in memory usage. Re-wrote renderglyph.
|
|||
|
<2.0> 11/16/89 CEL Fix in sb_fillprinterwidths. Bad assign from ReallocHandle.
|
|||
|
<1.9> 11/15/89 CEL Oops forgot to check memerr in sb_fillprinterwidths.
|
|||
|
<1.8> 11/14/89 CEL Added device metrics. Added device capabilities.
|
|||
|
<1.7> 9/28/89 CEL KillSomeCaches now make sure to get rid of purged font handles
|
|||
|
also.
|
|||
|
<1.6> 9/25/89 CEL Was setting numer and denom back to identity for splines since
|
|||
|
splines do the stretch but this would cause bad font manager
|
|||
|
matching. Let the v and h factors to be set back to 1. Added
|
|||
|
back in rounding of widths for width table when fractenable is
|
|||
|
off.
|
|||
|
<1.5> 9/15/89 CEL Checking in just in case something changed that reflects the
|
|||
|
Bass_Cache.h file.
|
|||
|
<1.4> 8/28/89 CEL Put in conditional for debugger state. Only drops into debugger
|
|||
|
if flag is set by hacker.
|
|||
|
<1.3> 8/14/89 CEL Added in new encryption checks. Looks in more places for bitmap
|
|||
|
temp memory.
|
|||
|
<1.2> 8/1/89 CEL Fixed EASE<EFBFBD>s <EFBFBD>C<EFBFBD> comment brackets. On check in they were wrong!
|
|||
|
<1.1> 8/1/89 CEL Fixed the include file buffer.h to be Bass_Cache.h
|
|||
|
<1.0> 8/1/89 CEL Adding into Bass build for the first time<EFBFBD>
|
|||
|
<1.9> 8/1/89 CEL Fixed over-run array bug. Re-worked data structures.
|
|||
|
<1.8> 6/13/89 CEL Integrated Sampo<EFBFBD>s changes to the GlyphInputType<EFBFBD>
|
|||
|
<1.7> 6/10/89 CEL Moved Private.a QuickDraw Equates into proper QuickDraw private
|
|||
|
file (colorequ.a), got rid of QuickDraw nFiles dependencies and
|
|||
|
fixed up necessary files<EFBFBD>
|
|||
|
<1.6> 6/2/89 CEL Took out hard coded ascent, descent, leading calculations<EFBFBD>
|
|||
|
<1.5> 5/26/89 CEL Integrated the new Font Scaler 1.0 into Spline Fonts
|
|||
|
<1.4> 5/15/89 CEL Bug in sb_SearchForCache - compared purged cache
|
|||
|
<1.3> 5/3/89 CEL Comment brackets were previously messed up from override
|
|||
|
<<EFBFBD>1.2> 5/3/89 CEL All kinks worked out, Blasting in bass files<EFBFBD>
|
|||
|
<<EFBFBD>1.1> 5/2/89 CEL Changed glue.h include file to BassGlue.h
|
|||
|
<1.0> 5/1/89 cel Adding Bass for first time<EFBFBD>
|
|||
|
|
|||
|
To Do:
|
|||
|
*/
|
|||
|
/*********************/
|
|||
|
/** System Includes **/
|
|||
|
/*********************/
|
|||
|
#include "BaseIncludes.h"
|
|||
|
#include <types.h>
|
|||
|
#include <Errors.h>
|
|||
|
#include <memory.h>
|
|||
|
#include <MFPrivate.h>
|
|||
|
#include <QuickDraw.h>
|
|||
|
#include <FixMath.h>
|
|||
|
#include "ToolUtils.h"
|
|||
|
#include <resources.h>
|
|||
|
#include <Script.h>
|
|||
|
#include <ShutDown.h>
|
|||
|
#include <Fonts.h>
|
|||
|
#include <GestaltEqu.h>
|
|||
|
#include <SysEqu.h>
|
|||
|
#include <ScriptPriv.h>
|
|||
|
|
|||
|
/*********************/
|
|||
|
/** BASS<53>s Includes **/
|
|||
|
/*********************/
|
|||
|
#include "FSCdefs.h"
|
|||
|
#include "FontScaler.h"
|
|||
|
#include "MacExtra.h"
|
|||
|
#include "FragmentTable.proto"
|
|||
|
#include "PartialFontExtensions.proto"
|
|||
|
#include "Bass_Cache.h"
|
|||
|
#include "SplineError.h"
|
|||
|
#include "FontMath.h"
|
|||
|
#include "sfnt.h"
|
|||
|
|
|||
|
#include "DoubleByteBassCache.h"
|
|||
|
#include "DiskCacheExtensions.proto"
|
|||
|
|
|||
|
/* prototypes for DoubleByteBassCache.c routines */
|
|||
|
|
|||
|
OSErr AddLowByteGlyphOffsetTable( uint16 glyphID, sb_SplineKeyHdl splineKey );
|
|||
|
uint32 GetSingleOrDoubleByteGlyphEntryOffset( uint16 glyphID, sb_CacheHeadPtr cachePointer );
|
|||
|
extern pascal EncodingTablePointer GetEncodingTable( short fondID, uint16 *scriptCodePointer );
|
|||
|
|
|||
|
//
|
|||
|
//The trap version of this trap is deffed out unless MACINIT is true
|
|||
|
//so just define a new constant here, FS_NEWSFNT is defined in FontScaler.h <22>
|
|||
|
//
|
|||
|
pascal int32 __NewSfntTrap(fs_GlyphInputType *inputPtr, fs_GlyphInfoType *outputPtr)
|
|||
|
= {0x303C,FS_NEWSFNT,0xA854};
|
|||
|
|
|||
|
|
|||
|
#ifndef INITVERSION
|
|||
|
#define SYSTEM_7
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
|
|||
|
#ifdef DEBUG
|
|||
|
N2S(unsigned long n, Str255 s)
|
|||
|
{
|
|||
|
short i;
|
|||
|
for (i = 10; i > 0; i--)
|
|||
|
{
|
|||
|
char c = n % 10;
|
|||
|
s[i] = '0' + c;
|
|||
|
n /= 10;
|
|||
|
}
|
|||
|
s[0] = 10;
|
|||
|
}
|
|||
|
|
|||
|
HeapCheck()
|
|||
|
{
|
|||
|
Str255 s;
|
|||
|
s[0] = 0;
|
|||
|
s[++s[0]] = ';';
|
|||
|
s[++s[0]] = 'h';
|
|||
|
s[++s[0]] = 'c';
|
|||
|
s[++s[0]] = ';';
|
|||
|
s[++s[0]] = 'g';
|
|||
|
s[++s[0]] = ';';
|
|||
|
DebugStr(s);
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
extern Boolean MultiFinderExist();
|
|||
|
extern long PurgeSpaceSysTotal();
|
|||
|
long sb_SetUpWorkHand();
|
|||
|
|
|||
|
/***********************************************************************************************/
|
|||
|
/***********************************************************************************************/
|
|||
|
/***********/
|
|||
|
/** DEBUG **/
|
|||
|
/***********/
|
|||
|
|
|||
|
|
|||
|
static void sb_Debug()
|
|||
|
{
|
|||
|
sb_SplineKeyHdl splineKey = SPLINE_KEY_HAND;
|
|||
|
|
|||
|
if ((*splineKey)->callDebug) Debugger();
|
|||
|
} /* End sb_Debug */
|
|||
|
|
|||
|
|
|||
|
static char *sb_ReturnDataPointer ( sfntHand, offset, length )
|
|||
|
Handle sfntHand;
|
|||
|
long offset, length;
|
|||
|
{
|
|||
|
int i = length;
|
|||
|
return( *sfntHand + offset );
|
|||
|
}
|
|||
|
|
|||
|
static long LONG_WORD_ALIGN ( long n )
|
|||
|
{
|
|||
|
return( (n + 3) & ~3 );
|
|||
|
}
|
|||
|
|
|||
|
static unsigned char ByteMax ( Fixed n )
|
|||
|
{
|
|||
|
register short shortVal = FixRound(n); /* get rid of low bits */
|
|||
|
|
|||
|
if (shortVal > 255) shortVal = 255;
|
|||
|
|
|||
|
return(shortVal );
|
|||
|
}
|
|||
|
|
|||
|
static char ByteRange ( Fixed n )
|
|||
|
{
|
|||
|
register short shortVal = FixRound(n); /* get rid of low bits */
|
|||
|
|
|||
|
if (shortVal > 127) shortVal = 127;
|
|||
|
else if (shortVal < -127) shortVal = -127;
|
|||
|
|
|||
|
return(shortVal);
|
|||
|
}
|
|||
|
|
|||
|
/***********************************************************************************************/
|
|||
|
/******************/
|
|||
|
/** MEMORY CALLS **/
|
|||
|
/******************/
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_DisposeZoneHandle
|
|||
|
**
|
|||
|
** Allocations are made in different zones and a handle may be purged. When this is the case
|
|||
|
** the memory manager does not have the ptr to figure out what zone it is coming from so it
|
|||
|
** can not hook the memory links up correctly.
|
|||
|
**
|
|||
|
** Switch to the correct zone and dipose the handle and then return back to the previous zone.
|
|||
|
**
|
|||
|
** <28-CEL> added some comments
|
|||
|
**
|
|||
|
*/
|
|||
|
void sb_DisposeZoneHandle(Handle h, THz zonePtr)
|
|||
|
{
|
|||
|
THz prevZone = GetZone();
|
|||
|
OSErr error = noErr;
|
|||
|
|
|||
|
if (zonePtr) {
|
|||
|
SetZone(zonePtr);
|
|||
|
DisposHandle(h);
|
|||
|
SetZone(prevZone);
|
|||
|
} else MFTempDisposHandle(h, &error);
|
|||
|
|
|||
|
} /* End sb_DisposeZoneHandle */
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_SetCachesNoPurge <28-CEL>
|
|||
|
**
|
|||
|
** Run through the caches which have not been purged and make them non-purgeable
|
|||
|
**
|
|||
|
** WHEN TO CALL: System heap allocation
|
|||
|
** WHY: System heap only guestimates when to grow which can cause purgeability or caches.
|
|||
|
**
|
|||
|
*/
|
|||
|
void sb_SetCachesNoPurge()
|
|||
|
{
|
|||
|
sb_SplineKeyHdl splineKey = SPLINE_KEY_HAND;
|
|||
|
register sb_SplineKeyPtr splineKeyPtr = *splineKey;
|
|||
|
|
|||
|
if (splineKeyPtr->cacheListHandle) {
|
|||
|
register short fontCount = splineKeyPtr->fontCount;
|
|||
|
register CacheReference* cacheRef = *splineKeyPtr->cacheListHandle;
|
|||
|
|
|||
|
for (--fontCount; fontCount >= 0; --fontCount) {
|
|||
|
if (cacheRef->cache && *cacheRef->cache) /* have a ptr??? */
|
|||
|
HNoPurge(cacheRef->cache);
|
|||
|
cacheRef++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
} /* End sb_SetCachesNoPurge */
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_SetCachesPurge <28-CEL>
|
|||
|
**
|
|||
|
** Run through the caches which have not been purged and make them purgeable
|
|||
|
**
|
|||
|
** WHEN TO CALL: After system heap memory allocations have been made,
|
|||
|
** if sb_SetCachesNoPurge was called.
|
|||
|
**
|
|||
|
*/
|
|||
|
void sb_SetCachesPurge()
|
|||
|
{
|
|||
|
sb_SplineKeyHdl splineKey = SPLINE_KEY_HAND;
|
|||
|
register sb_SplineKeyPtr splineKeyPtr = *splineKey;
|
|||
|
register Handle curCacheHand = splineKeyPtr->cacheHand;
|
|||
|
|
|||
|
if (splineKeyPtr->cacheListHandle) {
|
|||
|
register short fontCount = splineKeyPtr->fontCount;
|
|||
|
register CacheReference* cacheRef = *splineKeyPtr->cacheListHandle;
|
|||
|
|
|||
|
for (--fontCount; fontCount >= 0; --fontCount) {
|
|||
|
if (cacheRef->cache && *cacheRef->cache) /* have a ptr??? */
|
|||
|
HPurge(cacheRef->cache);
|
|||
|
cacheRef++;
|
|||
|
}
|
|||
|
}
|
|||
|
if (curCacheHand && *curCacheHand) HNoPurge(curCacheHand); /* Keep current cache non-purgeable */
|
|||
|
|
|||
|
} /* End sb_SetCachesPurge */
|
|||
|
|
|||
|
#ifndef USE_SYSTEM_HEAP
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_MultiFinderHandle <30-CEL>
|
|||
|
**
|
|||
|
** Call the Mutlifinder memory manager.
|
|||
|
** Since this is system type memory make sure to turn on BeginSystem mode to make
|
|||
|
** sure Multifinder does not release the memory when the application quits!
|
|||
|
**
|
|||
|
*/
|
|||
|
Handle sb_MultiFinderHandle(long blockSize)
|
|||
|
{
|
|||
|
register Handle h;
|
|||
|
OSErr resultCode;
|
|||
|
|
|||
|
BeginSystemMode();
|
|||
|
h = MFTempNewHandle((Size)blockSize, &resultCode);
|
|||
|
EndSystemMode();
|
|||
|
|
|||
|
if (resultCode) return nil;
|
|||
|
else return h;
|
|||
|
|
|||
|
} /* End sb_MultiFinderHandle */
|
|||
|
#endif
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_GetSysHandle <30-CEL>
|
|||
|
**
|
|||
|
**
|
|||
|
*/
|
|||
|
Handle sb_GetSysHandle(long size)
|
|||
|
{
|
|||
|
register Handle h = nil;
|
|||
|
|
|||
|
#ifdef USE_SYSTEM_HEAP
|
|||
|
h = NewHandleSys(size); /* system heap mem */
|
|||
|
#else
|
|||
|
h = MultiFinderExist( ) ? sb_MultiFinderHandle( size ) : NewHandleSys( size );
|
|||
|
#endif
|
|||
|
|
|||
|
return h;
|
|||
|
} /* End sb_GetSysHandle */
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_GetSysHandleZone <30-CEL>
|
|||
|
**
|
|||
|
**
|
|||
|
*/
|
|||
|
Handle sb_GetSysHandleZone(long size, THz* zone)
|
|||
|
{
|
|||
|
register Handle h = nil;
|
|||
|
|
|||
|
#ifdef USE_SYSTEM_HEAP
|
|||
|
h = NewHandleSys(size); /* system heap mem */
|
|||
|
*zone = SystemZone(); /* <30-CEL> */
|
|||
|
#else
|
|||
|
if ( MultiFinderExist( ) ) {
|
|||
|
|
|||
|
h = sb_MultiFinderHandle( size );
|
|||
|
*zone = 0;
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
h = NewHandleSys(size);
|
|||
|
*zone = SystemZone( );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
#endif
|
|||
|
|
|||
|
return h;
|
|||
|
} /* End sb_GetSysHandleZone */
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_GetAppHandleZone <30-CEL>
|
|||
|
**
|
|||
|
**
|
|||
|
*/
|
|||
|
Handle sb_GetAppHandleZone(long size, THz* zone)
|
|||
|
{
|
|||
|
register Handle h;
|
|||
|
register THz curZone = GetZone();
|
|||
|
register GrowZoneProcPtr growZonePtr = curZone->gzProc;
|
|||
|
|
|||
|
curZone->gzProc = nil;
|
|||
|
h = NewHandle(size); /* <30-CEL> Try the App Heap */
|
|||
|
curZone->gzProc = growZonePtr; /* restore the grow zone proc ptr */
|
|||
|
*zone = curZone;
|
|||
|
|
|||
|
return h;
|
|||
|
|
|||
|
} /* End sb_GetAppHandleZone */
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_GetAppHandle <30-CEL>
|
|||
|
**
|
|||
|
**
|
|||
|
*/
|
|||
|
Handle sb_GetAppHandle(long size)
|
|||
|
{
|
|||
|
register Handle h;
|
|||
|
register THz curZone = GetZone();
|
|||
|
register GrowZoneProcPtr growZonePtr = curZone->gzProc;
|
|||
|
|
|||
|
curZone->gzProc = nil;
|
|||
|
h = NewHandle(size); /* <30-CEL> Try the App Heap */
|
|||
|
curZone->gzProc = growZonePtr; /* restore the grow zone proc ptr */
|
|||
|
|
|||
|
return h;
|
|||
|
|
|||
|
} /* End sb_GetAppHandle */
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_GrowAppHandle <30-CEL>
|
|||
|
**
|
|||
|
**
|
|||
|
*/
|
|||
|
long sb_GrowAppHandle(Handle h, long size)
|
|||
|
{
|
|||
|
THz curZone = GetZone();
|
|||
|
GrowZoneProcPtr growZonePtr = curZone->gzProc;
|
|||
|
|
|||
|
curZone->gzProc = nil;
|
|||
|
SetHandleSize(h, size); /* <30-CEL> took out set and restore zone for sethandlesize */
|
|||
|
curZone->gzProc = growZonePtr; /* restore the grow zone proc ptr */
|
|||
|
return MemError(); /* <30-CEL> */
|
|||
|
|
|||
|
} /* End sb_GrowAppHandle */
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_NewZoneHandle
|
|||
|
**
|
|||
|
** BEHAVIOR: <28-CEL> some logic
|
|||
|
** 7.0 -
|
|||
|
** <EFBFBD> Make caches non-purgeable
|
|||
|
** <EFBFBD> Try for Multi-Finder temp memory.
|
|||
|
** <EFBFBD> Failure: Try for Application memory.
|
|||
|
** <EFBFBD> Failure: Make caches purgeable and try again from the top.
|
|||
|
** (Better)Selectively choose caches for purgeability.
|
|||
|
** 6.0 -
|
|||
|
** Multi-Finder
|
|||
|
** <EFBFBD> Make caches non-purgeable
|
|||
|
** <EFBFBD> Try for System Heap
|
|||
|
** <EFBFBD> Failure: Try for Application memory.
|
|||
|
** <EFBFBD> Failure: Make caches purgeable and try again from the top.
|
|||
|
** (Better)Selectively choose caches for purgeability.
|
|||
|
** Finder
|
|||
|
** <EFBFBD> Make caches non-purgeable
|
|||
|
** <EFBFBD> Try for Application memory.
|
|||
|
** <EFBFBD> Failure: Make caches purgeable and try again from the top.
|
|||
|
** (Better)Selectively choose caches for purgeability.
|
|||
|
** No luck -
|
|||
|
** <EFBFBD> Return nil
|
|||
|
**
|
|||
|
** Under 7.0 NCH looks in temp mem first, bracketing the call with sysmode
|
|||
|
** What is this bracketing magic???
|
|||
|
**
|
|||
|
** Allocate in non app heap with no purge
|
|||
|
** Allocate in App heap with purge
|
|||
|
** Allocate in Multi heap with purge
|
|||
|
**
|
|||
|
** New stuff:
|
|||
|
** <EFBFBD> Allocate in non-app heap (sys or multi) until full with no purge
|
|||
|
** <EFBFBD> Allocate in app heap until full with no purge
|
|||
|
** <EFBFBD> Switch back and forth with purge on
|
|||
|
*/
|
|||
|
Handle sb_NewZoneHandle(sb_SplineKeyHdl splineKey, long size, THz* zone)
|
|||
|
{
|
|||
|
register sb_SplineKeyPtr splineKeyPtr = *splineKey; /* <28-CEL> */
|
|||
|
register Handle h = nil;
|
|||
|
THz curZone = GetZone();
|
|||
|
THz savedZone;
|
|||
|
Boolean sameAppZone;
|
|||
|
|
|||
|
savedZone = curZone;
|
|||
|
|
|||
|
if ( splineKeyPtr->curAppZone == SystemZone( ) )
|
|||
|
splineKeyPtr->curAppZone = nil;
|
|||
|
|
|||
|
if ( curZone == SystemZone( ) ) {
|
|||
|
|
|||
|
curZone = splineKeyPtr->curAppZone;
|
|||
|
if ( curZone == nil )
|
|||
|
curZone = ApplicZone( );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
SetZone( curZone );
|
|||
|
sameAppZone = (splineKeyPtr->curAppZone == curZone);
|
|||
|
if (!sameAppZone){
|
|||
|
splineKeyPtr->curAppZone = curZone; /* log current zone */
|
|||
|
splineKeyPtr->appFull = false; /* Reset for different zone */
|
|||
|
}
|
|||
|
if (!splineKeyPtr->appFull) { /* <30-CEL> */
|
|||
|
sb_SetCachesNoPurge();
|
|||
|
if (splineKeyPtr->mfExists && !splineKeyPtr->sysFull) {
|
|||
|
h = sb_GetSysHandleZone(size, zone);
|
|||
|
if (!h) {
|
|||
|
splineKeyPtr = *splineKey;
|
|||
|
splineKeyPtr->sysFull = true;
|
|||
|
}
|
|||
|
}
|
|||
|
if (!h) {
|
|||
|
h = sb_GetAppHandleZone(size, zone);
|
|||
|
if (!h) {
|
|||
|
splineKeyPtr = *splineKey;
|
|||
|
splineKeyPtr->appFull = true;
|
|||
|
}
|
|||
|
}
|
|||
|
sb_SetCachesPurge();
|
|||
|
}
|
|||
|
if (!h) { /* Full with no purge on so try without it */
|
|||
|
if (splineKeyPtr->useHeap == useApp) {
|
|||
|
h = sb_GetAppHandleZone(size, zone);
|
|||
|
if (!h) h = sb_GetSysHandleZone(size, zone);
|
|||
|
splineKeyPtr = *splineKey;
|
|||
|
splineKeyPtr->useHeap = useSys;
|
|||
|
} else {
|
|||
|
h = sb_GetSysHandleZone(size, zone);
|
|||
|
if (!h) h = sb_GetAppHandleZone(size, zone);
|
|||
|
splineKeyPtr = *splineKey;
|
|||
|
splineKeyPtr->useHeap = useApp;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
SetZone( savedZone );
|
|||
|
return h;
|
|||
|
|
|||
|
} /* End sb_NewZoneHandle */
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_NewSharedHandle <30-CEL> new routine
|
|||
|
**
|
|||
|
** This data will be shared across heaps in Multi-Finder mode so it must be in the system heap.
|
|||
|
** Otherwise under finder just put it in the app heap since it will not be multiply shared.
|
|||
|
** Finder Mode: Application Heap
|
|||
|
** Multi Finder: System Heap (Shared)
|
|||
|
**
|
|||
|
*/
|
|||
|
Handle sb_NewSharedHandle(sb_SplineKeyHdl splineKey, long cacheSize)
|
|||
|
{
|
|||
|
register sb_SplineKeyPtr splineKeyPtr = *splineKey; /* <28-CEL> */
|
|||
|
register Handle h = nil;
|
|||
|
|
|||
|
if (splineKeyPtr->mfExists) {
|
|||
|
if (!splineKeyPtr->appFull && !splineKeyPtr->sysFull) {
|
|||
|
sb_SetCachesNoPurge(); /* <30-CEL> */
|
|||
|
h = sb_GetSysHandle(cacheSize); /* system heap mem */
|
|||
|
sb_SetCachesPurge();
|
|||
|
if (!h) {
|
|||
|
splineKeyPtr = *splineKey;
|
|||
|
splineKeyPtr->sysFull = true;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (!h) h = sb_GetSysHandle(cacheSize); /* system heap mem */
|
|||
|
} else {
|
|||
|
THz curZone = GetZone();
|
|||
|
Boolean sameAppZone = (splineKeyPtr->curAppZone == curZone);
|
|||
|
|
|||
|
if (!sameAppZone){
|
|||
|
splineKeyPtr->curAppZone = curZone; /* log current zone */
|
|||
|
splineKeyPtr->appFull = false; /* Reset for different zone */
|
|||
|
}
|
|||
|
if (!splineKeyPtr->appFull) {
|
|||
|
sb_SetCachesNoPurge(); /* <30-CEL> */
|
|||
|
h = sb_GetAppHandle(cacheSize); /* <28-CEL> Try the App Heap */
|
|||
|
sb_SetCachesPurge();
|
|||
|
if (!h) {
|
|||
|
splineKeyPtr = *splineKey;
|
|||
|
splineKeyPtr->appFull = true;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (!h) h = sb_GetAppHandle(cacheSize); /* app heap mem */
|
|||
|
}
|
|||
|
|
|||
|
return h;
|
|||
|
} /* End sb_NewSharedHandle */
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_GrowHandle <28-CEL> new routine
|
|||
|
**
|
|||
|
** Grow the current shared data block handle<EFBFBD>
|
|||
|
** If this is in the App heap make sure there is enough space before requesting
|
|||
|
** the memory. Otherwise this could cause the Application purge proc to be called
|
|||
|
** and the App might exit with an out of memory.
|
|||
|
**
|
|||
|
** If in the Multi Heap try with no purgeability.
|
|||
|
** Fails: try with purgeability
|
|||
|
**
|
|||
|
** App heap always try with purgeability.
|
|||
|
**
|
|||
|
*/
|
|||
|
long sb_GrowHandle(sb_SplineKeyHdl splineKey, Handle h, long size)
|
|||
|
{
|
|||
|
register sb_SplineKeyPtr splineKeyPtr = *splineKey; /* <28-CEL> */
|
|||
|
register long result = NO_ERR;
|
|||
|
THz curZone = GetZone();
|
|||
|
Boolean sameAppZone = (splineKeyPtr->curAppZone == curZone);
|
|||
|
|
|||
|
if (!sameAppZone) {
|
|||
|
splineKeyPtr->curAppZone = curZone; /* log current zone */
|
|||
|
splineKeyPtr->appFull = false; /* Reset for different zone */
|
|||
|
}
|
|||
|
|
|||
|
if (HandleZone(h) != curZone) { /* <30-CEL> sys heap */
|
|||
|
if (!splineKeyPtr->appFull) { /* <30-CEL> */
|
|||
|
sb_SetCachesNoPurge(); /* <30-CEL> */
|
|||
|
SetHandleSize(h, size); /* <30-CEL> took out set and restore zone for sethandlesize */
|
|||
|
result = MemError(); /* <30-CEL> */
|
|||
|
sb_SetCachesPurge(); /* <30-CEL> */
|
|||
|
if (result) {
|
|||
|
SetHandleSize(h, size); /* <30-CEL> took out set and restore zone for sethandlesize */
|
|||
|
result = MemError(); /* <30-CEL> */
|
|||
|
}
|
|||
|
} else {
|
|||
|
SetHandleSize(h, size); /* <30-CEL> took out set and restore zone for sethandlesize */
|
|||
|
result = MemError(); /* <30-CEL> */
|
|||
|
}
|
|||
|
} else { /* <30-CEL> app heap */
|
|||
|
if (!splineKeyPtr->appFull) {
|
|||
|
sb_SetCachesNoPurge(); /* <30-CEL> */
|
|||
|
result = sb_GrowAppHandle(h, size);
|
|||
|
sb_SetCachesPurge();
|
|||
|
if (result) {
|
|||
|
result = sb_GrowAppHandle(h, size);
|
|||
|
splineKeyPtr = *splineKey;
|
|||
|
splineKeyPtr->appFull = true;
|
|||
|
}
|
|||
|
} else result = sb_GrowAppHandle(h, size);
|
|||
|
}
|
|||
|
|
|||
|
return result;
|
|||
|
} /* End sb_GrowHandle */
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_SizeTheBlock <28-CEL> some logic
|
|||
|
**
|
|||
|
** Block exist: Resize handle<EFBFBD> if this fails, get new one, copy over data if needed, and dipose old one.
|
|||
|
** Empty or purged Handle: Dipose if handle is purged but exists and then get brand new one.
|
|||
|
**
|
|||
|
** Upfront we will try to keep existing caches. If memory allocations fail try again with purgeable
|
|||
|
** caches.
|
|||
|
**
|
|||
|
** If it is the App heap, make sure there is enough contiguous space to make the request.
|
|||
|
** If this is not done, it could cause the applicaton purge proc to be called and it could
|
|||
|
** cause a out of memory error.
|
|||
|
**
|
|||
|
** MERGE comments from sb_GrowZoneHandle<EFBFBD>
|
|||
|
** Block exist: Resize handle<EFBFBD> if this fails, get new one, copy over data if needed, and dipose old one.
|
|||
|
** Empty or purged Handle: Dispose if handle is purged but exists and then get brand new one.
|
|||
|
**
|
|||
|
** Upfront we will try to keep existing caches. If memory allocations fail try again with purgeable
|
|||
|
** caches.
|
|||
|
**
|
|||
|
** CachePlace:
|
|||
|
** <EFBFBD> When a cacheHandle is moved via a newHandle of somekind the cacheHandle inside the
|
|||
|
** cacheList must be updated. Use CachePlace to find the correct cache info inside the
|
|||
|
** the cache list.
|
|||
|
** <EFBFBD> if cachePlace == -1, ignore the update. This means it is not a cacheChunk.
|
|||
|
**
|
|||
|
*/
|
|||
|
Handle sb_SizeTheBlock(sb_SplineKeyHdl splineKey, Handle inputH, THz* inputZone, long inputSize,
|
|||
|
ZoneHandleOptions options, short cachePlace, ShrinkOptions shrinkTest)
|
|||
|
{
|
|||
|
register Handle h = inputH; /* <28-CEL> */
|
|||
|
register THz *zone = inputZone; /* <28-CEL> */
|
|||
|
register long size = inputSize; /* <28-CEL> */
|
|||
|
Boolean room = true;
|
|||
|
|
|||
|
if (h) { /* <28-CEL> */
|
|||
|
if (*h) { /* <28-CEL> */
|
|||
|
if (shrinkTest == noShrink && size <= GetHandleSize(h)) return h; /* <30-CEL> Right size<7A> leave it alone */
|
|||
|
if (!sb_GrowHandle(splineKey, h, size)) return h; /* <30-CEL> */
|
|||
|
|
|||
|
/* THIS SHOULD BE A RARE CASE!!! */
|
|||
|
/* If we get this far, growing the existing handle failed, so allocate a new one */
|
|||
|
if (options & kKeepContents) {
|
|||
|
register long origSize = GetHandleSize(h); /* <28-CEL> */
|
|||
|
THz newZ;
|
|||
|
Handle newH;
|
|||
|
short handState = HGetState(h);
|
|||
|
|
|||
|
if (newH = sb_NewZoneHandle(splineKey, size, &newZ)) {
|
|||
|
|
|||
|
BlockMove( *h, *newH, origSize );
|
|||
|
sb_DisposeZoneHandle( h, *zone ); /* <28-CEL> assigned zone before disposing caused problems */
|
|||
|
|
|||
|
if (cachePlace != -1) { /* <28-CEL> Need to update cache info in cacheList */
|
|||
|
register sb_SplineKeyPtr splineKeyPtr = *splineKey; /* <28-CEL> */
|
|||
|
register CacheReference *cacheR = *splineKeyPtr->cacheListHandle + splineKeyPtr->cachePlace; /* <28-CEL> */
|
|||
|
|
|||
|
cacheR->cache = newH; /* <28-CEL> */
|
|||
|
cacheR->zone = newZ; /* <28-CEL> */
|
|||
|
}
|
|||
|
*zone = newZ; /* <28-CEL> */
|
|||
|
HSetState(newH,handState); /* <31-CEL> set to original state */
|
|||
|
return newH;
|
|||
|
} else return nil;
|
|||
|
}
|
|||
|
} else { /* ERROR!!!: This routine should never be called with a purged handle!!! */
|
|||
|
sb_Debug(); /* <27-CEL> */
|
|||
|
return nil; /* <27-CEL> */
|
|||
|
}
|
|||
|
}
|
|||
|
return(sb_NewZoneHandle( splineKey, size, zone ));
|
|||
|
|
|||
|
} /* End sb_SizeTheBlock */
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_ModCacheList
|
|||
|
**
|
|||
|
** sb_ModCacheList increases the number of nil cache_head entries in the cacheListHandle.
|
|||
|
** either it grows cacheListHandle by GROW_CACHE_NUM
|
|||
|
** or if cacheListHandle is nil, it allocates INITIAL_CACHES entries
|
|||
|
**
|
|||
|
** Finder Mode:
|
|||
|
** CacheListHand lives in the App Heap
|
|||
|
** Multi Mode:
|
|||
|
** CacheListHand lives in the Sys Heap
|
|||
|
**
|
|||
|
*/
|
|||
|
static long sb_ModCacheList(sb_SplineKeyHdl splineKey)
|
|||
|
{
|
|||
|
register sb_SplineKeyPtr splineKeyPtr = *splineKey;
|
|||
|
register short newFontCount;
|
|||
|
register long cacheSize;
|
|||
|
register short initCount;
|
|||
|
long result = NO_ERR;
|
|||
|
register Handle tempHand = nil;
|
|||
|
|
|||
|
if (splineKeyPtr->cacheListHandle) {
|
|||
|
register Handle h = splineKeyPtr->cacheListHandle;
|
|||
|
THz zone = HandleZone(h);
|
|||
|
|
|||
|
newFontCount = splineKeyPtr->fontCount + GROW_CACHE_NUM;
|
|||
|
initCount = GROW_CACHE_NUM;
|
|||
|
cacheSize = GetHandleSize(h) + GROW_CACHE_NUM * sizeof(CacheReference);
|
|||
|
|
|||
|
result = sb_GrowHandle(splineKey, h, cacheSize); /* <30-CEL> */
|
|||
|
} else {
|
|||
|
splineKeyPtr->fontCount = 0;
|
|||
|
newFontCount = initCount = INITIAL_CACHES;
|
|||
|
cacheSize = INITIAL_CACHES * sizeof(CacheReference);
|
|||
|
|
|||
|
tempHand = NewHandleSys( cacheSize );
|
|||
|
if (tempHand) { /* <30-CEL> */
|
|||
|
splineKeyPtr = *splineKey;
|
|||
|
splineKeyPtr->cacheListHandle = (CacheReference**)tempHand; /* <30-CEL> */
|
|||
|
} else
|
|||
|
result = NEWCACHELIST_HANDLE_ERR; /* <30-CEL> */
|
|||
|
} /* End If */
|
|||
|
|
|||
|
if (!result) {
|
|||
|
register CacheReference* cacheR; /* <28-CEL> */
|
|||
|
register Handle zero = 0;
|
|||
|
|
|||
|
splineKeyPtr = *splineKey;
|
|||
|
cacheR = *splineKeyPtr->cacheListHandle + splineKeyPtr->fontCount;
|
|||
|
|
|||
|
for (--initCount; initCount >= 0; --initCount) { /* begin new caches as nil */
|
|||
|
cacheR->cache = zero;
|
|||
|
cacheR++;
|
|||
|
}
|
|||
|
splineKeyPtr->fontCount = newFontCount;
|
|||
|
}
|
|||
|
|
|||
|
return result; /* <27-CEL */
|
|||
|
|
|||
|
} /* End sb_ModCacheList */
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*******************************/
|
|||
|
/** WRAPPERS For memory calls **/
|
|||
|
/*******************************/
|
|||
|
|
|||
|
void sb_DisposeCacheHandle( Handle cacheHandle, THz cacheZone )
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
DumpFontCacheToDiskIfNotTooBig( (sb_CacheHeadHdl) cacheHandle );
|
|||
|
sb_DisposeZoneHandle( cacheHandle, cacheZone );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_DisposeWorkHandle <28-CEL> a little comment
|
|||
|
**
|
|||
|
** If a handle is purged and the zone from which the handle came from is not the current zone,
|
|||
|
** the memory manager does not know where to link the free handle. This is bad news unless
|
|||
|
** we switch to the correct zone and then dispose of the handle!
|
|||
|
**
|
|||
|
*/
|
|||
|
void sb_DisposeWorkHandle() /* <28-CEL> took out splineKeyPtr param to make code consistent */
|
|||
|
{
|
|||
|
sb_SplineKeyHdl splineKey = SPLINE_KEY_HAND;
|
|||
|
register sb_SplineKeyPtr splineKeyPtr = *splineKey;
|
|||
|
|
|||
|
if (splineKeyPtr->fsWorkHand) { /* <28-CEL> */
|
|||
|
sb_DisposeZoneHandle(splineKeyPtr->fsWorkHand, splineKeyPtr->fsWorkZone);
|
|||
|
splineKeyPtr->fsWorkHand = 0;
|
|||
|
splineKeyPtr->fsWorkZone = 0; /* <28-CEL> */
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_SizeWorkHandle <28-CEL>
|
|||
|
**
|
|||
|
** Size the Font Scaler work space. If it does not exist it will
|
|||
|
** create one.
|
|||
|
**
|
|||
|
** ZoneHandleOptions: Sets state if the memory needs to be preserved.
|
|||
|
** letShrink: Set if memory should be shrunk.
|
|||
|
**
|
|||
|
*/
|
|||
|
long sb_SizeWorkHandle( long size, ZoneHandleOptions zOptions, ShrinkOptions shrinkTest )
|
|||
|
{
|
|||
|
sb_SplineKeyHdl splineKey = SPLINE_KEY_HAND;
|
|||
|
register sb_SplineKeyPtr splineKeyPtr = *splineKey; /* <28-CEL> */
|
|||
|
register Handle h = splineKeyPtr->fsWorkHand; /* <28-CEL> */
|
|||
|
THz z; /* <28-CEL> */
|
|||
|
register long result = NO_ERR; /* <28-CEL> */
|
|||
|
|
|||
|
if (h && !*h) sb_DisposeWorkHandle(); /* <31-CEL> */
|
|||
|
|
|||
|
z = splineKeyPtr->fsWorkZone; /* <28-CEL> */
|
|||
|
h = splineKeyPtr->fsWorkHand; /* <28-CEL> */
|
|||
|
|
|||
|
if (h = sb_SizeTheBlock( splineKey, h, &z, size, zOptions, -1, shrinkTest )) {
|
|||
|
splineKeyPtr = *splineKey; /* <28-CEL> */
|
|||
|
splineKeyPtr->fsWorkHand = h; /* <28-CEL> */
|
|||
|
splineKeyPtr->fsWorkZone = z; /* <28-CEL> */
|
|||
|
} else {
|
|||
|
result = MEM_ERR;
|
|||
|
}
|
|||
|
|
|||
|
return result;
|
|||
|
} /* End sb_SizeWorkHandle */
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_GetBitMapSpace <28-CEL> rewrote
|
|||
|
**
|
|||
|
** This is a temporary bitmap to blit in when the glyph is not cached.
|
|||
|
**
|
|||
|
*/
|
|||
|
static Handle sb_GetBitMapSpace(register long bmSize)
|
|||
|
{
|
|||
|
sb_SplineKeyHdl splineKey = SPLINE_KEY_HAND;
|
|||
|
register sb_SplineKeyPtr splineKeyPtr = *splineKey; /* <28-CEL> */
|
|||
|
register Handle h = splineKeyPtr->bitmapHand; /* <28-CEL> */
|
|||
|
THz z;
|
|||
|
register long result = NO_ERR;
|
|||
|
|
|||
|
if (h && !*h) { /* purged so get rid of it and start over */ /* <28-CEL> */
|
|||
|
sb_DisposeZoneHandle(h, splineKeyPtr->bitmapZone); /* <28-CEL> */
|
|||
|
splineKeyPtr->bitmapHand = 0; /* <28-CEL> */
|
|||
|
splineKeyPtr->bitmapZone = 0; /* <28-CEL> */
|
|||
|
}
|
|||
|
z = splineKeyPtr->bitmapZone; /* <28-CEL> */
|
|||
|
if (h = sb_SizeTheBlock( splineKey, splineKeyPtr->bitmapHand, &z, bmSize, kNoOptions, -1, doShrink )) { /* <28-CEL> */
|
|||
|
splineKeyPtr = *splineKey; /* <28-CEL> */
|
|||
|
splineKeyPtr->bitmapZone = z; /* <28-CEL> */
|
|||
|
splineKeyPtr->bitmapHand = h;
|
|||
|
}
|
|||
|
|
|||
|
return h; /* <28-CEL> */
|
|||
|
|
|||
|
} /* End sb_GetBitMapSpace */
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_BandChar
|
|||
|
**
|
|||
|
**
|
|||
|
*/
|
|||
|
Handle sb_BandChar(sb_SplineKeyHdl splineKey, short *scan, short byteWidth, long memForScanLine)
|
|||
|
{
|
|||
|
register sb_SplineKeyPtr splineKeyPtr = *splineKey;
|
|||
|
register Handle tempHand;
|
|||
|
long sizeOfMem6;
|
|||
|
|
|||
|
for ((*scan) >>= 1;*scan >= 1;(*scan) >>= 1) {
|
|||
|
sizeOfMem6 = (long)LONG_WORD_ALIGN((*scan * memForScanLine)); /* divide by 2 */
|
|||
|
|
|||
|
if (!sb_SizeWorkHandle((*splineKey)->rowArrayOffset6+sizeOfMem6, kKeepContents, doShrink)) {
|
|||
|
if (tempHand = sb_GetBitMapSpace(*scan * byteWidth))
|
|||
|
return tempHand;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return 0;
|
|||
|
|
|||
|
} /* End sb_BandChar */
|
|||
|
/**********************/
|
|||
|
/** END MEMORY CALLS **/
|
|||
|
/**********************/
|
|||
|
/***********************************************************************************************/
|
|||
|
|
|||
|
|
|||
|
/***********************************************************************************************/
|
|||
|
/***********************************************************************************************/
|
|||
|
/********************/
|
|||
|
/* SET UP AND CACHE */
|
|||
|
/********************/
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_ResetFSWorkState
|
|||
|
**
|
|||
|
** Reset the SplineKey Font Scaler state.
|
|||
|
**
|
|||
|
**
|
|||
|
*/
|
|||
|
sb_ResetFSWorkState(sb_SplineKeyPtr splineKeyPtr)
|
|||
|
{
|
|||
|
register sb_SplineKeyPtr skPtr = splineKeyPtr;
|
|||
|
|
|||
|
skPtr->StrikeID = -1;
|
|||
|
skPtr->ptSize = 0;
|
|||
|
skPtr->device = 0;
|
|||
|
skPtr->face = 0;
|
|||
|
skPtr->trans00 = -1;
|
|||
|
skPtr->trans11 = -1;
|
|||
|
skPtr->trans10 = -1;
|
|||
|
|
|||
|
} /* End sb_ResetFSWorkState */
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_SetMemPtrs
|
|||
|
**
|
|||
|
** sb_SetMemPtrs
|
|||
|
**
|
|||
|
** Usage: Called once to set up spline package vectors and init the workspace.
|
|||
|
**
|
|||
|
** Notes: memory [5] points to bitmap hand
|
|||
|
*
|
|||
|
* Assumes that fsWorkHand is NOT purged or empty
|
|||
|
**
|
|||
|
*/
|
|||
|
|
|||
|
static void sb_SetMemPtrs( widthTableHdl widthTableHandle )
|
|||
|
{
|
|||
|
|
|||
|
register sb_SplineKeyPtr splineKeyPtr = *(SPLINE_KEY_HAND);
|
|||
|
char *memoryPtr = *splineKeyPtr->fsWorkHand;
|
|||
|
register char** memBase; /*<16> increment ptr instead of array */
|
|||
|
|
|||
|
splineKeyPtr->inPtr = (fs_GlyphInputType *)(memoryPtr + splineKeyPtr->inputOffset);
|
|||
|
splineKeyPtr->outPtr = (fs_GlyphInfoType *)(memoryPtr + splineKeyPtr->infoOffset);
|
|||
|
memBase = (*splineKeyPtr->inPtr).memoryBases;
|
|||
|
*memBase++ = memoryPtr + splineKeyPtr->globalOffset0; /* memoryBases[0] */
|
|||
|
*memBase++ = memoryPtr + splineKeyPtr->globalOffset1; /* memoryBases[1] */
|
|||
|
*memBase++ = memoryPtr + splineKeyPtr->globalOffset2; /* memoryBases[2] */
|
|||
|
*memBase++ = memoryPtr + splineKeyPtr->sfntDataOffset3; /* memoryBases[3] */
|
|||
|
*memBase++ = memoryPtr + splineKeyPtr->sfntDataOffset4; /* memoryBases[4] */
|
|||
|
memBase++; /* memoryBases[5] */
|
|||
|
*memBase++ = memoryPtr + splineKeyPtr->rowArrayOffset6; /* memoryBases[6] */
|
|||
|
*memBase = memoryPtr + splineKeyPtr->columnArrayOffset7; /* memoryBases[7] */
|
|||
|
(*splineKeyPtr->inPtr).sfntDirectory = (widthTableHandle == nil) ? nil : (int32*) (*widthTableHandle)->fSplineDirectory;
|
|||
|
|
|||
|
} /* End sb_SetMemPtrs */
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_CheckWorkHandle <28-CEL> new routine
|
|||
|
**
|
|||
|
** Check to see if the workhandle exists. If it does then just return, otherwise re-establish.
|
|||
|
**
|
|||
|
*/
|
|||
|
long sb_CheckWorkHandle()
|
|||
|
{
|
|||
|
sb_SplineKeyHdl splineKey = SPLINE_KEY_HAND;
|
|||
|
register sb_SplineKeyPtr splineKeyPtr = *splineKey;
|
|||
|
register Handle h = splineKeyPtr->fsWorkHand;
|
|||
|
register long result = NO_ERR;
|
|||
|
|
|||
|
if (!h || !*h) {
|
|||
|
long position = 0;
|
|||
|
short splineKeyState = HGetState((Handle)splineKey);
|
|||
|
register char *memoryPtr;
|
|||
|
|
|||
|
HLock((Handle)splineKey);
|
|||
|
|
|||
|
splineKeyPtr->inputOffset = position;
|
|||
|
position += LONG_WORD_ALIGN(sizeof(fs_GlyphInputType));
|
|||
|
splineKeyPtr->infoOffset = position;
|
|||
|
position += LONG_WORD_ALIGN( sizeof(fs_GlyphInfoType));
|
|||
|
|
|||
|
if (!(result = sb_SizeWorkHandle(position, kNoOptions, noShrink))) {
|
|||
|
memoryPtr = *splineKeyPtr->fsWorkHand;
|
|||
|
splineKeyPtr->inPtr = (fs_GlyphInputType *)(memoryPtr + splineKeyPtr->inputOffset);
|
|||
|
splineKeyPtr->outPtr = (fs_GlyphInfoType *)(memoryPtr + splineKeyPtr->infoOffset);
|
|||
|
(*splineKeyPtr->inPtr).GetSfntFragmentPtr = (GetSFNTFunc)QDGetFontFrag;
|
|||
|
(*splineKeyPtr->inPtr).ReleaseSfntFrag = (ReleaseSFNTFunc)QDUngetFontFrag;
|
|||
|
|
|||
|
/* reinitialize the state to make sure the FS gets ran through */
|
|||
|
sb_ResetFSWorkState(splineKeyPtr);
|
|||
|
|
|||
|
if (!(result = fs_OpenFonts( splineKeyPtr->inPtr, splineKeyPtr->outPtr ))) {
|
|||
|
/*******************/
|
|||
|
/* SETTING OFFSETS */
|
|||
|
/*******************/
|
|||
|
splineKeyPtr->globalOffset0 = position;
|
|||
|
position += LONG_WORD_ALIGN((*splineKeyPtr->outPtr).memorySizes[0]);
|
|||
|
|
|||
|
splineKeyPtr->globalOffset1 = position;
|
|||
|
position += LONG_WORD_ALIGN((*splineKeyPtr->outPtr).memorySizes[1]);
|
|||
|
|
|||
|
splineKeyPtr->globalOffset2 = position;
|
|||
|
position += LONG_WORD_ALIGN((*splineKeyPtr->outPtr).memorySizes[2]);
|
|||
|
splineKeyPtr->sfntDataOffset3 = position;
|
|||
|
/*******************/
|
|||
|
|
|||
|
/***********************/
|
|||
|
/** FSWorkHand HANDLE **/
|
|||
|
/***********************/
|
|||
|
if (!(result = sb_SizeWorkHandle( position, kKeepContents, noShrink ))) {
|
|||
|
sb_SetMemPtrs(0);
|
|||
|
if (result = fs_Initialize( splineKeyPtr->inPtr, splineKeyPtr->outPtr ))
|
|||
|
sb_Debug();
|
|||
|
}
|
|||
|
} else sb_Debug();
|
|||
|
if (result) sb_DisposeWorkHandle(); /* failed so get rid of state */
|
|||
|
}
|
|||
|
HSetState((Handle)splineKey, splineKeyState);
|
|||
|
}
|
|||
|
return result;
|
|||
|
} /* End sb_CheckWorkHandle */
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_ShrinkBitmap
|
|||
|
**
|
|||
|
** The scan converted bitmap can have extra space at the end of it so shrink down to get rid
|
|||
|
** of the excess.
|
|||
|
**
|
|||
|
**
|
|||
|
*/
|
|||
|
static void sb_ShrinkBitmap( sb_GlyphData *glyphDataPtr, long *bitMapPtr, short inputScan )
|
|||
|
{
|
|||
|
register short bitWidth = glyphDataPtr->bitWidth;
|
|||
|
register short scan = inputScan - 1;
|
|||
|
short scanByteWidth = glyphDataPtr->scanByteWidth;
|
|||
|
|
|||
|
/*************************/
|
|||
|
/* Shrinking down the bitmap
|
|||
|
** 16-bit or less -> word
|
|||
|
** 32-bit or less -> long
|
|||
|
** > 32-bit -> multiple of longs
|
|||
|
*/
|
|||
|
if (bitWidth <= 16) { /*<16> fast scan-loop */
|
|||
|
register short *src, *dest;
|
|||
|
|
|||
|
src = dest = (short *)bitMapPtr;
|
|||
|
for (; scan >= 0; --scan) {
|
|||
|
*dest++ = *src++;
|
|||
|
src++; /* next src row */
|
|||
|
}
|
|||
|
glyphDataPtr->byteWidth = 2;
|
|||
|
} else { /*<16> fast scan-loops, set src and dest once */
|
|||
|
register long *src, *dest;
|
|||
|
|
|||
|
src = dest = (long *)bitMapPtr;
|
|||
|
if (bitWidth <= 32) {
|
|||
|
if (scanByteWidth > 4) { /* Sampo uses two longs even though bitwidth is only 32 */
|
|||
|
for (; scan >= 0; --scan) {
|
|||
|
*dest++ = *src++;
|
|||
|
src++; /* next src row */
|
|||
|
}
|
|||
|
glyphDataPtr->byteWidth = 4;
|
|||
|
}
|
|||
|
} else { /*<16> fast j-loop */
|
|||
|
register short numOfLongs = ((bitWidth + 31) >> 5); /* number of longs truely needed */
|
|||
|
|
|||
|
if (numOfLongs > (scanByteWidth >> 2)) { /* Sampo uses an extra long if last whole long is used */
|
|||
|
register short j;
|
|||
|
--numOfLongs; /* save decrement in j-loop */
|
|||
|
for (; scan >= 0; --scan) {
|
|||
|
for (j = numOfLongs; j >= 0; --j)
|
|||
|
*dest++ = *src++;
|
|||
|
src++; /* next src row */
|
|||
|
}
|
|||
|
numOfLongs++; /* restore to orig value */
|
|||
|
glyphDataPtr->byteWidth = numOfLongs << 2; /* turn to bytes */
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
} /* End sb_ShrinkBitmap */
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_SetFontMemory
|
|||
|
**
|
|||
|
** Note on 6/19/92 change. This routine formerly called GetEncodingTable to get the script.
|
|||
|
** the funny thing about that is that GetEncodingTable's primary raison d'etre is to return
|
|||
|
** a table of booleans used to distinguish high and low bytes in a CJK font. It also
|
|||
|
** happened to return the script of the encoding table returned. Well, until now if
|
|||
|
** the FOND ID being passed in wasn't an ID for a CJK font then GetEncodingTable returned
|
|||
|
** roman. This tended to make international fonts with correctly coded cmap tables not
|
|||
|
** work at all. The first thing I did was change GetEncodingTable to return the correct value
|
|||
|
** However, I've rethought the wisdom of calling a routine primarily designed for CJK and have
|
|||
|
** changed this routine (which never really cared about encoding tables) to call the more generic
|
|||
|
** script manager trap Font2RealScript. The change to GetEncodingTable was left in though.
|
|||
|
*/
|
|||
|
static long sb_SetFontMemory(sb_SplineKeyHdl splineKey, widthTableHdl widthTableHandle )
|
|||
|
{
|
|||
|
register sb_SplineKeyPtr splineKeyPtr = *splineKey;
|
|||
|
register long result = NO_ERR;
|
|||
|
register long position;
|
|||
|
uint16 scriptID;
|
|||
|
|
|||
|
sb_SetMemPtrs(widthTableHandle);
|
|||
|
//GetEncodingTable( splineKeyPtr->fLastSwapFontFamilyID, &scriptID );
|
|||
|
scriptID = Font2RealScript( splineKeyPtr->fLastSwapFontFamilyID );
|
|||
|
(*splineKeyPtr->inPtr).param.newsfnt.platformID = 1;
|
|||
|
(*splineKeyPtr->inPtr).param.newsfnt.specificID = scriptID;
|
|||
|
result = __NewSfntTrap(splineKeyPtr->inPtr, splineKeyPtr->outPtr); //<22>
|
|||
|
if ( result ) {
|
|||
|
|
|||
|
if ( scriptID != smRoman ) { //we tried for a script this might be an old font so let's try Roman
|
|||
|
|
|||
|
(*splineKeyPtr->inPtr).param.newsfnt.platformID = 1;
|
|||
|
(*splineKeyPtr->inPtr).param.newsfnt.specificID = smRoman;
|
|||
|
result = __NewSfntTrap(splineKeyPtr->inPtr, splineKeyPtr->outPtr); //<22>
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
//test result again, if still non-zero that is it for us, if it is 0 we fall throught and set up
|
|||
|
//memory.
|
|||
|
//
|
|||
|
if ( result ) {
|
|||
|
sb_Debug();
|
|||
|
return result;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
position = splineKeyPtr->sfntDataOffset3;
|
|||
|
position += LONG_WORD_ALIGN( (*splineKeyPtr->outPtr).memorySizes[3]);
|
|||
|
splineKeyPtr->sfntDataOffset4 = position;
|
|||
|
position += LONG_WORD_ALIGN((*splineKeyPtr->outPtr).memorySizes[4]);
|
|||
|
splineKeyPtr->rowArrayOffset6 = position;
|
|||
|
splineKeyPtr->columnArrayOffset7 = position;
|
|||
|
|
|||
|
if (result = sb_SizeWorkHandle( position, kKeepContents, noShrink )) return MEM_ERR;
|
|||
|
|
|||
|
return result;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_SetNewSFNT
|
|||
|
**
|
|||
|
** If the sfnt has changed, reset the FontScaler environment.
|
|||
|
**
|
|||
|
** Logic:
|
|||
|
** <EFBFBD> Font change: run fs_NewSfnt and fs_NewTransformation
|
|||
|
** <EFBFBD> ptSize or transformation changed : run fs_NewTransformation
|
|||
|
**
|
|||
|
**
|
|||
|
*/
|
|||
|
static long sb_SetNewSFNT( widthTableHdl widTabHand )
|
|||
|
{
|
|||
|
sb_SplineKeyHdl splineKey = SPLINE_KEY_HAND;
|
|||
|
register sb_SplineKeyPtr splineKeyPtr = *splineKey;
|
|||
|
register widthTablePtr widTabPtr = *widTabHand;
|
|||
|
register long result = NO_ERR;
|
|||
|
short doNewTrans = false;
|
|||
|
|
|||
|
sb_SetMemPtrs(widTabHand);
|
|||
|
(*splineKeyPtr->inPtr).clientID = widTabPtr->tabFont; /* Always reset because the memory environment may have changed */
|
|||
|
|
|||
|
if ( splineKeyPtr->StrikeID != widTabPtr->StrikeID ) {
|
|||
|
if (result = sb_SetFontMemory(splineKey, widTabHand)) return MEM_ERR;
|
|||
|
splineKeyPtr = *splineKey;
|
|||
|
widTabPtr = *widTabHand;
|
|||
|
doNewTrans = true;
|
|||
|
splineKeyPtr->StrikeID = widTabPtr->StrikeID;
|
|||
|
}
|
|||
|
|
|||
|
if ( doNewTrans ||
|
|||
|
splineKeyPtr->ptSize != widTabPtr->fSize ||
|
|||
|
splineKeyPtr->trans00 != widTabPtr->trans00 ||
|
|||
|
splineKeyPtr->trans11 != widTabPtr->trans11 ||
|
|||
|
splineKeyPtr->trans10 != widTabPtr->trans10
|
|||
|
) {
|
|||
|
register fs_GlyphInputType* fsInput;
|
|||
|
transMatrix matrix; /* this could be a global matrix */
|
|||
|
|
|||
|
matrix.transform[2][0] = 0;
|
|||
|
matrix.transform[0][1] = 0;
|
|||
|
matrix.transform[2][1] = 0;
|
|||
|
matrix.transform[0][2] = 0;
|
|||
|
matrix.transform[1][2] = 0;
|
|||
|
matrix.transform[2][2] = (1L << 30);
|
|||
|
|
|||
|
matrix.transform[0][0] = widTabPtr->trans00;
|
|||
|
matrix.transform[1][1] = widTabPtr->trans11;
|
|||
|
matrix.transform[1][0] = widTabPtr->trans10;
|
|||
|
|
|||
|
sb_SetMemPtrs(widTabHand);
|
|||
|
fsInput = splineKeyPtr->inPtr;
|
|||
|
fsInput->param.newtrans.transformMatrix = &matrix;
|
|||
|
fsInput->param.newtrans.pointSize = (Fixed)widTabPtr->fSize << 16;
|
|||
|
fsInput->param.newtrans.xResolution = POINTSPERINCH;
|
|||
|
fsInput->param.newtrans.yResolution = POINTSPERINCH;
|
|||
|
fsInput->param.newtrans.pixelDiameter = FIXEDSQRT2;
|
|||
|
fsInput->param.newtrans.traceFunc = 0;
|
|||
|
#if TheFuture /* <18 > EBITMAP */
|
|||
|
fsInput->param.newtrans.bitmapMethodPreferences = 1;
|
|||
|
fsInput->param.newtrans.scalingPreference = 0;
|
|||
|
#endif
|
|||
|
if ( result = fs_NewTransformation( splineKeyPtr->inPtr, splineKeyPtr->outPtr ) ) {
|
|||
|
splineKeyPtr->ptSize = 0;
|
|||
|
splineKeyPtr->trans00 = 0;
|
|||
|
splineKeyPtr->trans11 = 0;
|
|||
|
splineKeyPtr->trans10 = 0;
|
|||
|
sb_Debug();
|
|||
|
return result;
|
|||
|
}
|
|||
|
splineKeyPtr->ptSize = widTabPtr->fSize;
|
|||
|
splineKeyPtr->trans00 = widTabPtr->trans00;
|
|||
|
splineKeyPtr->trans11 = widTabPtr->trans11;
|
|||
|
splineKeyPtr->trans10 = widTabPtr->trans10;
|
|||
|
|
|||
|
} /* End If */
|
|||
|
|
|||
|
return NO_ERR;
|
|||
|
|
|||
|
} /* End sb_SetNewSFNT */
|
|||
|
|
|||
|
/*
|
|||
|
* Returns the font's real style, ignoring any algorithmic effects
|
|||
|
*/
|
|||
|
short IntrinsicStyle(widthTablePtr w)
|
|||
|
{
|
|||
|
return (w->face >> 8) & ~w->aFace;
|
|||
|
}
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_InitCacheHead
|
|||
|
**
|
|||
|
** Initialize the cacheHead with the widthTable information.
|
|||
|
**
|
|||
|
**
|
|||
|
**
|
|||
|
*/
|
|||
|
static long sb_InitCacheHead(widthTableHdl widthTabHand, sb_CacheHeadHdl cacheHand )
|
|||
|
{
|
|||
|
sb_SplineKeyHdl splineKey = SPLINE_KEY_HAND;
|
|||
|
register widthTablePtr widTabPtr = *widthTabHand;
|
|||
|
sb_SplineKeyPtr splineKeyPtr = *splineKey; /*<16> removed register */
|
|||
|
register sb_CacheHeadPtr cachePtr = *cacheHand;
|
|||
|
char *hiliteModePtr = HILITEMODE;
|
|||
|
long result = NO_ERR;
|
|||
|
|
|||
|
cachePtr->familyID = (*splineKey)->fLastSwapFontFamilyID;
|
|||
|
cachePtr->StrikeID = widTabPtr->StrikeID;
|
|||
|
cachePtr->ptSize = widTabPtr->fSize;
|
|||
|
cachePtr->face = IntrinsicStyle(widTabPtr);
|
|||
|
cachePtr->squashed = !(*hiliteModePtr & PRESERVE_GLYPH);
|
|||
|
cachePtr->trans00 = widTabPtr->trans00;
|
|||
|
cachePtr->trans11 = widTabPtr->trans11;
|
|||
|
cachePtr->trans10 = widTabPtr->trans10;
|
|||
|
cachePtr->bitsCached = widTabPtr->aSize <= MAX_PPEM_CACHED;
|
|||
|
cachePtr->addEntryOffset = (GLYPH_COUNT * sizeof(long)) + sizeof(sb_CacheHead);
|
|||
|
cachePtr->fEncodingTablePointer = (Ptr) GetEncodingTable( (*splineKey)->fLastSwapFontFamilyID, &cachePtr->fScriptNumber );
|
|||
|
|
|||
|
sb_SetMemPtrs(widthTabHand);
|
|||
|
|
|||
|
result = fs_FillLayoutInfo( splineKeyPtr->inPtr, splineKeyPtr->outPtr, (fs_LayoutInfo *)&cachePtr->ascent );
|
|||
|
if (!result) {
|
|||
|
if (cachePtr->trans10 /*OBLIQUE*/) { /* If oblique changes change this slop adjust */
|
|||
|
if (widTabPtr->aSize <= 8) {
|
|||
|
cachePtr->rightItalicSlop = (cachePtr->ascent / 2);
|
|||
|
cachePtr->leftItalicSlop = (cachePtr->descent / 2);
|
|||
|
} else if (widTabPtr->aSize <= 16) {
|
|||
|
cachePtr->rightItalicSlop = (cachePtr->ascent / 3);
|
|||
|
cachePtr->leftItalicSlop = (cachePtr->descent / 3);
|
|||
|
} else if (widTabPtr->aSize <= 22) {
|
|||
|
cachePtr->rightItalicSlop = (cachePtr->ascent / 4);
|
|||
|
cachePtr->leftItalicSlop = (cachePtr->descent / 4);
|
|||
|
} else {
|
|||
|
cachePtr->rightItalicSlop = (cachePtr->ascent / 5);
|
|||
|
cachePtr->leftItalicSlop = (cachePtr->descent / 5);
|
|||
|
}
|
|||
|
} else {
|
|||
|
cachePtr->rightItalicSlop = 0;
|
|||
|
cachePtr->leftItalicSlop = 0;
|
|||
|
}
|
|||
|
/********************/
|
|||
|
/* Round to ceiling */
|
|||
|
/********************/
|
|||
|
/*<16> put masks into registers */
|
|||
|
{
|
|||
|
Fixed lowordmask = 0x0000FFFF;
|
|||
|
Fixed hiwordmask = 0xFFFF0000;
|
|||
|
cachePtr->ascent = (cachePtr->ascent + lowordmask) & hiwordmask;
|
|||
|
cachePtr->descent = (-cachePtr->descent + lowordmask) & hiwordmask;
|
|||
|
if ( (*hiliteModePtr & PRESERVE_GLYPH) ) {
|
|||
|
cachePtr->yMax = (cachePtr->yMax + lowordmask) & hiwordmask;
|
|||
|
cachePtr->yMin = (cachePtr->yMin - lowordmask) & hiwordmask;
|
|||
|
} else {
|
|||
|
cachePtr->yMax = cachePtr->ascent;
|
|||
|
cachePtr->yMin = -cachePtr->descent;
|
|||
|
}
|
|||
|
cachePtr->height = (short)((cachePtr->yMax - cachePtr->yMin) >> 16);
|
|||
|
cachePtr->widMax = (cachePtr->widMax + lowordmask) & hiwordmask;
|
|||
|
cachePtr->leading = (cachePtr->leading + lowordmask) & hiwordmask;
|
|||
|
cachePtr->lOverHMax = (cachePtr->lOverHMax + lowordmask) & hiwordmask;
|
|||
|
cachePtr->rOverHMax = (cachePtr->rOverHMax + lowordmask) & hiwordmask;
|
|||
|
cachePtr->leftItalicSlop = -((cachePtr->leftItalicSlop + lowordmask) & hiwordmask);
|
|||
|
cachePtr->rightItalicSlop = (cachePtr->rightItalicSlop + lowordmask) & hiwordmask;
|
|||
|
|
|||
|
|
|||
|
cachePtr->fmAscent = ByteMax(cachePtr->ascent);
|
|||
|
cachePtr->fmDescent = ByteMax(cachePtr->descent);
|
|||
|
cachePtr->fmWidMax = ByteMax(cachePtr->widMax);
|
|||
|
cachePtr->fmLeading = ByteRange(cachePtr->leading);
|
|||
|
|
|||
|
}
|
|||
|
/********************/
|
|||
|
}
|
|||
|
|
|||
|
/*<16> fast loop, local i, initArrayPtr */
|
|||
|
{
|
|||
|
register long* initArrayPtr = (long*)cachePtr->glyphArray;
|
|||
|
register short i = GLYPH_COUNT - 1;
|
|||
|
for (; i >= 0; --i)
|
|||
|
*initArrayPtr++ = EMPTY;
|
|||
|
}
|
|||
|
|
|||
|
return result;
|
|||
|
|
|||
|
} /* End sb_InitCacheHead */
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_ShrinkCacheToMin <3-CEL>
|
|||
|
**
|
|||
|
** Low on memory so shrink the cache to a minimum and initialize new state.
|
|||
|
**
|
|||
|
**
|
|||
|
** AddEntryOffset = 0: Do not copy glyph entry.
|
|||
|
**
|
|||
|
*/
|
|||
|
long sb_ShrinkCacheToMin(sb_CacheHeadHdl cacheHand, long addEntryOffset)
|
|||
|
{
|
|||
|
sb_SplineKeyHdl splineKey = SPLINE_KEY_HAND;
|
|||
|
sb_SplineKeyPtr splineKeyPtr = *splineKey;
|
|||
|
sb_CacheHeadPtr cachePtr = *cacheHand;
|
|||
|
register long entryArraySize = (GLYPH_COUNT * sizeof(long));
|
|||
|
register long* initArrayPtr = cachePtr->glyphArray;
|
|||
|
long result = NO_ERR;
|
|||
|
register short i;
|
|||
|
register long *oldGDataPtr;
|
|||
|
register long *newGDataPtr;
|
|||
|
|
|||
|
/* new start for add entry */
|
|||
|
cachePtr->addEntryOffset = entryArraySize + sizeof(sb_CacheHead);
|
|||
|
if (addEntryOffset) {
|
|||
|
oldGDataPtr = (long *)((char *)cachePtr + addEntryOffset);
|
|||
|
newGDataPtr = (long *)((char *)cachePtr + cachePtr->addEntryOffset);
|
|||
|
i = (GLYPH_HEAD_BYTES>>2); /* longs to copy */
|
|||
|
for (--i; i >= 0; --i)
|
|||
|
*newGDataPtr++ = *oldGDataPtr++;
|
|||
|
}
|
|||
|
|
|||
|
for (i=GLYPH_COUNT-1; i >= 0; --i)
|
|||
|
*initArrayPtr++ = EMPTY;
|
|||
|
|
|||
|
SetHandleSize((Handle)cacheHand, sizeof(sb_CacheHead) + entryArraySize + GLYPH_HEAD_BYTES);
|
|||
|
if (!(result = MemError()))
|
|||
|
result = sb_SizeWorkHandle((*splineKey)->rowArrayOffset6, kKeepContents, doShrink); /* <8-CEL,RB> */
|
|||
|
|
|||
|
return result;
|
|||
|
|
|||
|
} /* End sb_ShrinkCacheToMin */
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_FigureCacheSize
|
|||
|
**
|
|||
|
** Takes the current WidthTable and calculates the initial cache size needed.
|
|||
|
**
|
|||
|
** Make it the minimum of the cache header and enough room for one entry header.
|
|||
|
**
|
|||
|
*/
|
|||
|
static long sb_FigureCacheSize(widthTableHdl widthTabHand)
|
|||
|
{
|
|||
|
register widthTablePtr widTabPtr = *widthTabHand;
|
|||
|
register long entryArraySize = (GLYPH_COUNT * sizeof(long));
|
|||
|
register long cacheSize = 0;
|
|||
|
Boolean bitsCached = widTabPtr->aSize < MAX_PPEM_CACHED;
|
|||
|
|
|||
|
cacheSize = sizeof(sb_CacheHead) + GLYPH_HEAD_BYTES; /* <34-CEL> */
|
|||
|
|
|||
|
#ifdef LEAVE_OUT /* <33-CEL> forget about room for characters for now */
|
|||
|
if ( bitsCached )
|
|||
|
cacheSize += (widTabPtr->aSize / 8) * widTabPtr->aSize * INITIAL_CHAR_COUNT;
|
|||
|
else cacheSize += AVG_CONTOUR_SIZE * INITIAL_CHAR_COUNT;
|
|||
|
#endif
|
|||
|
|
|||
|
cacheSize += entryArraySize; /* Add glyph array */
|
|||
|
cacheSize += 3; cacheSize &= ~3; /* Start Long word aligned */
|
|||
|
|
|||
|
return cacheSize;
|
|||
|
|
|||
|
} /* End sb_FigureCacheSize */
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_ResetHeapState
|
|||
|
**
|
|||
|
**
|
|||
|
**
|
|||
|
*/
|
|||
|
void sb_ResetHeapState( sb_SplineKeyPtr splineKeyPtr )
|
|||
|
{
|
|||
|
register sb_SplineKeyPtr sPtr = splineKeyPtr;
|
|||
|
|
|||
|
sPtr->curAppZone = 0; /* <30-CEL> */
|
|||
|
sPtr->appFull = false; /* <30-CEL> */
|
|||
|
sPtr->sysFull = false; /* <30-CEL> */
|
|||
|
sPtr->useHeap = useApp; /* <30-CEL> */
|
|||
|
|
|||
|
} /* End sb_ResetHeapState */
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_FlushFonts
|
|||
|
**
|
|||
|
** sb_FlushFonts
|
|||
|
**
|
|||
|
**
|
|||
|
*/
|
|||
|
pascal OSErr sb_FlushFonts()
|
|||
|
{
|
|||
|
sb_SplineKeyHdl splineKey = SPLINE_KEY_HAND;
|
|||
|
sb_SplineKeyPtr splineKeyPtr = *splineKey;
|
|||
|
long* lastSpExtrPtr = LASTSPEXTRA;
|
|||
|
|
|||
|
*lastSpExtrPtr = 0xFFFFFFFF;
|
|||
|
|
|||
|
if (splineKeyPtr->cacheListHandle) {
|
|||
|
register short fontCount = splineKeyPtr->fontCount;
|
|||
|
register CacheReference* cacheRef = *splineKeyPtr->cacheListHandle;
|
|||
|
register Handle zero = 0;
|
|||
|
for (--fontCount; fontCount >= 0; --fontCount) {
|
|||
|
if (cacheRef->cache) {
|
|||
|
sb_DisposeCacheHandle(cacheRef->cache, cacheRef->zone);
|
|||
|
cacheRef->cache = zero;
|
|||
|
}
|
|||
|
cacheRef++;
|
|||
|
}
|
|||
|
splineKeyPtr->cacheHand = 0; /* <28-CEL> */
|
|||
|
splineKeyPtr->cacheZone = 0; /* <28-CEL> */
|
|||
|
splineKeyPtr->cachePlace = 0; /* <28-CEL> */
|
|||
|
|
|||
|
sb_DisposeZoneHandle((Handle)splineKeyPtr->cacheListHandle, /* <28-CEL> start over */
|
|||
|
HandleZone((Handle)splineKeyPtr->cacheListHandle));
|
|||
|
splineKeyPtr->cacheListHandle = 0;
|
|||
|
}
|
|||
|
|
|||
|
sb_DisposeWorkHandle(); /* <28-CEL> */
|
|||
|
|
|||
|
/* Dispose of all fragment table caches */
|
|||
|
KillApplicationHeapFragmentTableCaches( (Handle) 0, (Handle) 0x7fffffff );
|
|||
|
|
|||
|
/* Reset since the heaps have changed */
|
|||
|
sb_ResetHeapState(splineKeyPtr);
|
|||
|
|
|||
|
return NO_ERR;
|
|||
|
} /* End sb_FlushFonts */
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_KillSomeCaches
|
|||
|
**
|
|||
|
** Clean up caches in the current heap that is going away. If the cachelisthandle is going
|
|||
|
** away, throw away the caches and get rid of the cachelisthandle. Make sure to get rid of
|
|||
|
** any blocks that are in this heap also like the fsWorkHand.
|
|||
|
**
|
|||
|
**
|
|||
|
*/
|
|||
|
pascal long sb_KillSomeCaches( Handle inputStartAddr, Handle inputEndAddr )
|
|||
|
{
|
|||
|
register sb_SplineKeyPtr splineKeyPtr = *(SPLINE_KEY_HAND); /* <28-CEL> register */
|
|||
|
register CacheReference* cacheR; /* <28-CEL> */
|
|||
|
register short fontCount = splineKeyPtr->fontCount;
|
|||
|
register Handle startAddr = inputStartAddr; /* <28-CEL> */
|
|||
|
register Handle endAddr = inputEndAddr; /* <28-CEL> */
|
|||
|
register Handle h; /* <28-CEL> */
|
|||
|
|
|||
|
if (splineKeyPtr->cacheListHandle) { /* <28-CEL> make sure it even exists */
|
|||
|
cacheR = *splineKeyPtr->cacheListHandle; /* <28-CEL> */
|
|||
|
h = (Handle)splineKeyPtr->cacheListHandle; /* <28-CEL> */
|
|||
|
if (h >= startAddr && h < endAddr) { /* <28-CEL> cacheListHand in this heap clean all caches */
|
|||
|
for (--fontCount; fontCount >= 0; --fontCount) { /* <28-CEL> */
|
|||
|
if (cacheR->cache) sb_DisposeCacheHandle(cacheR->cache, cacheR->zone); /* <28-CEL> */
|
|||
|
cacheR++; /* <28-CEL> */
|
|||
|
}
|
|||
|
sb_DisposeZoneHandle(h, HandleZone(h));
|
|||
|
splineKeyPtr->cacheListHandle = 0; /* <28-CEL> */
|
|||
|
splineKeyPtr->cacheHand = 0; /* <28-CEL> */
|
|||
|
splineKeyPtr->cacheZone = 0; /* <28-CEL> */
|
|||
|
splineKeyPtr->cachePlace = 0; /* <28-CEL> */
|
|||
|
sb_ResetFSWorkState(splineKeyPtr);
|
|||
|
} else {
|
|||
|
for (--fontCount; fontCount >= 0; --fontCount) {
|
|||
|
h = cacheR->cache; /* <28-CEL> */
|
|||
|
|
|||
|
if (h >= startAddr && h < endAddr) { /* <28-CEL> */
|
|||
|
if (splineKeyPtr->cacheHand == h) { /* <28-CEL> */
|
|||
|
splineKeyPtr->cacheHand = 0; /* <28-CEL> */
|
|||
|
splineKeyPtr->cacheZone = 0; /* <28-CEL> */
|
|||
|
splineKeyPtr->cachePlace = 0; /* <28-CEL> */
|
|||
|
}
|
|||
|
|
|||
|
sb_DisposeCacheHandle( cacheR->cache, cacheR->zone );
|
|||
|
cacheR->cache = 0;
|
|||
|
cacheR->zone = 0; /* <28-CEL> */
|
|||
|
}
|
|||
|
cacheR++;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
KillApplicationHeapFragmentTableCaches( startAddr, endAddr );
|
|||
|
|
|||
|
if ((h = splineKeyPtr->bitmapHand) && (h >= startAddr && h < endAddr)) { /* <28-CEL> */
|
|||
|
sb_DisposeZoneHandle(h, splineKeyPtr->bitmapZone); /* <28-CEL> */
|
|||
|
splineKeyPtr->bitmapHand = 0; /* <28-CEL> */
|
|||
|
splineKeyPtr->bitmapZone = 0; /* <28-CEL> */
|
|||
|
}
|
|||
|
|
|||
|
if ((h = splineKeyPtr->fsWorkHand) && (h >= startAddr && h < endAddr)) /* <28-CEL> */ /* <28-CEL> */
|
|||
|
sb_DisposeWorkHandle(); /* <28-CEL> */
|
|||
|
|
|||
|
// <19> If FOND candidate lists are cached, flush them out too.
|
|||
|
|
|||
|
h = splineKeyPtr->fondCache[0]; // <19>
|
|||
|
if (h) { // <19>
|
|||
|
DisposeHandle(h); // <19>
|
|||
|
splineKeyPtr->fondCache[0] = nil; // <19>
|
|||
|
}
|
|||
|
h = splineKeyPtr->fondCache[1]; // <19>
|
|||
|
if (h) { // <19>
|
|||
|
DisposeHandle(h); // <19>
|
|||
|
splineKeyPtr->fondCache[1] = nil; // <19>
|
|||
|
}
|
|||
|
|
|||
|
/* Reset since the heaps have changed */
|
|||
|
sb_ResetHeapState(splineKeyPtr);
|
|||
|
|
|||
|
return NO_ERR;
|
|||
|
} /* End sb_KillSomeCaches */
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_CacheSFNTMatch
|
|||
|
**
|
|||
|
** Simply checks to see if the current widthtable request matches the cache found.
|
|||
|
**
|
|||
|
**
|
|||
|
*/
|
|||
|
Boolean sb_CacheSFNTMatch( sb_CacheHeadPtr cachePtr, widthTablePtr widTabPtr )
|
|||
|
{
|
|||
|
register sb_CacheHeadPtr cPtr = cachePtr; /* registers */
|
|||
|
register widthTablePtr wtPtr = widTabPtr;
|
|||
|
|
|||
|
return(cPtr->StrikeID == wtPtr->StrikeID &&
|
|||
|
cPtr->ptSize == wtPtr->fSize &&
|
|||
|
cPtr->face == IntrinsicStyle(wtPtr) &&
|
|||
|
cPtr->trans00 == wtPtr->trans00 &&
|
|||
|
cPtr->trans11 == wtPtr->trans11 &&
|
|||
|
cPtr->trans10 == wtPtr->trans10);
|
|||
|
} /* End sb_CacheSFNTMatch */
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_LoadNewCache
|
|||
|
**
|
|||
|
** On entry
|
|||
|
** splineKeyPtr is locked
|
|||
|
**
|
|||
|
**
|
|||
|
*/
|
|||
|
long sb_LoadNewCache( sb_SplineKeyHdl splineKey, widthTableHdl widthTabHand, Boolean squashed )
|
|||
|
{
|
|||
|
register sb_SplineKeyPtr splineKeyPtr = *splineKey; /* <28-CEL> */
|
|||
|
register CacheReference* cacheR = *splineKeyPtr->cacheListHandle;
|
|||
|
register short i, fontCount = splineKeyPtr->fontCount;
|
|||
|
register short cachePlace = -1;
|
|||
|
long result = NO_ERR;
|
|||
|
|
|||
|
/* Search through the list of caches to see if we have a match */
|
|||
|
for (i = 0; i < fontCount; i++) {
|
|||
|
if (cacheR->cache && *cacheR->cache) {
|
|||
|
sb_CacheHeadPtr cachePtr = (sb_CacheHeadPtr)*cacheR->cache;
|
|||
|
if (sb_CacheSFNTMatch(cachePtr, *widthTabHand) && cachePtr->squashed == squashed) {
|
|||
|
splineKeyPtr->cacheHand = (sb_CacheHeadHdl)cacheR->cache; /* <28-CEL> */
|
|||
|
splineKeyPtr->cacheZone = cacheR->zone; /* <28-CEL> */
|
|||
|
splineKeyPtr->cachePlace = i; /* <28-CEL> */
|
|||
|
HNoPurge((Handle)splineKeyPtr->cacheHand); /* Current one is non-purgable */
|
|||
|
break;
|
|||
|
} /* End If */
|
|||
|
} else if (cachePlace == -1)
|
|||
|
cachePlace = i; /* remember first available (purged or gone) */
|
|||
|
cacheR++;
|
|||
|
} /* End For */
|
|||
|
|
|||
|
if (!splineKeyPtr->cacheHand) { /* no match, use cachePlace if valid */
|
|||
|
THz zone; /* <28-CEL> just moved this above */
|
|||
|
Handle cache; /* <28-CEL> just moved this above */
|
|||
|
|
|||
|
if (cachePlace == -1) { /* -1 means grow the cache */
|
|||
|
cachePlace = splineKeyPtr->fontCount; /* first available of new caches */
|
|||
|
if ( sb_ModCacheList(splineKey) ) { /* add more cache heads if needed */
|
|||
|
cachePlace = 1;
|
|||
|
}
|
|||
|
} /* End If */
|
|||
|
|
|||
|
cacheR = *splineKeyPtr->cacheListHandle + cachePlace; /* <28-CEL> */
|
|||
|
zone = cacheR->zone;
|
|||
|
|
|||
|
if (cacheR->cache && !*cacheR->cache) { /* <28-CEL> been purged so get rid of it and start over */
|
|||
|
sb_DisposeZoneHandle( cacheR->cache, zone );
|
|||
|
cacheR->cache = 0;
|
|||
|
cacheR->zone = 0;
|
|||
|
}
|
|||
|
|
|||
|
result = LoadFontCacheFromDisk( (sb_CacheHeadHdl*) &cache, &zone, widthTabHand, squashed );
|
|||
|
cacheR = *splineKeyPtr->cacheListHandle + cachePlace;
|
|||
|
if ( (result == noErr) && (cache != nil) ) {
|
|||
|
|
|||
|
cacheR->cache = cache;
|
|||
|
cacheR->zone = zone;
|
|||
|
splineKeyPtr->cacheHand = (sb_CacheHeadHdl) cache;
|
|||
|
splineKeyPtr->cacheZone = zone;
|
|||
|
splineKeyPtr->cachePlace = cachePlace;
|
|||
|
HNoPurge( cache );
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
if (cache = sb_SizeTheBlock( splineKey, cacheR->cache, &zone, sb_FigureCacheSize(widthTabHand),
|
|||
|
kKeepContents, cachePlace, doShrink )) {
|
|||
|
if (!(result = sb_SetNewSFNT(widthTabHand))) {
|
|||
|
if (!(result = sb_InitCacheHead(widthTabHand, (sb_CacheHeadHdl)cache))) {
|
|||
|
cacheR = *splineKeyPtr->cacheListHandle + cachePlace; /* <34> */
|
|||
|
cacheR->cache = cache; /* <34> */
|
|||
|
cacheR->zone = zone; /* <34> */
|
|||
|
splineKeyPtr->cacheHand = (sb_CacheHeadHdl)cacheR->cache; /* <34> */
|
|||
|
splineKeyPtr->cacheZone = cacheR->zone; /* <34> */
|
|||
|
splineKeyPtr->cachePlace = cachePlace; /* <34> */
|
|||
|
HNoPurge(cache);
|
|||
|
}
|
|||
|
}
|
|||
|
if (result) { /* <34> */
|
|||
|
cacheR = *splineKeyPtr->cacheListHandle + cachePlace; /* <34> */
|
|||
|
cacheR->cache = 0;
|
|||
|
cacheR->zone = 0;
|
|||
|
DisposHandle(cache); /* Get rid of cachehandle */
|
|||
|
sb_Debug();
|
|||
|
}
|
|||
|
} else result = GROWZONE_HANDLE_ERR;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
} /* End If */
|
|||
|
|
|||
|
return result;
|
|||
|
|
|||
|
} /* End sb_LoadNewCache */
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_SearchForCache
|
|||
|
**
|
|||
|
** Find the cache that matches the width table request<EFBFBD>
|
|||
|
** <EFBFBD> Check if the current one is okay - FAST CASE
|
|||
|
** <EFBFBD> NOT FOUND: Check through the list of caches to see if one exists
|
|||
|
** <EFBFBD><EFBFBD>NOT FOUND: Get a brand new one
|
|||
|
** <EFBFBD> NOT FOUND: re-use a cache
|
|||
|
**
|
|||
|
*/
|
|||
|
pascal long sb_SearchForCache( widthTableHdl widthTabHand )
|
|||
|
{
|
|||
|
sb_SplineKeyHdl splineKey = SPLINE_KEY_HAND; /* <28-CEL> */
|
|||
|
register sb_SplineKeyPtr splineKeyPtr = *splineKey; /* <28-CEL> */
|
|||
|
register widthTablePtr widTabPtr = *widthTabHand; /* <27-CEL> */
|
|||
|
long result = NO_ERR;
|
|||
|
char* hiliteModePtr = HILITEMODE;
|
|||
|
register Boolean squashed = !(*hiliteModePtr & PRESERVE_GLYPH);
|
|||
|
short splineKeyState, fontState, workHandState;
|
|||
|
register Handle aCacheHand = splineKeyPtr->cacheHand;
|
|||
|
|
|||
|
if (aCacheHand && *aCacheHand) { /* Current cache okay??? Fast case */
|
|||
|
sb_CacheHeadPtr cachePtr = (sb_CacheHeadPtr)*aCacheHand;
|
|||
|
if ( sb_CacheSFNTMatch(cachePtr, widTabPtr) && cachePtr->squashed == squashed)
|
|||
|
return NO_ERR;
|
|||
|
else HPurge((Handle)aCacheHand); /* <16-CEL> */
|
|||
|
}
|
|||
|
splineKeyPtr->cacheHand = 0; /* we need a new current cache */
|
|||
|
splineKeyPtr->cacheZone = 0; /* <16-CEL> */
|
|||
|
splineKeyPtr->cachePlace = 0; /* <16-CEL> */
|
|||
|
|
|||
|
widTabPtr = *widthTabHand;
|
|||
|
splineKeyPtr = *splineKey;
|
|||
|
splineKeyState = HGetState ((Handle)splineKey);
|
|||
|
fontState = HGetState ((Handle)widTabPtr->tabFont);
|
|||
|
HLock((Handle)splineKey); /* <32-CEL> */
|
|||
|
HNoPurge(widTabPtr->tabFont);
|
|||
|
|
|||
|
if (!(result = sb_CheckWorkHandle())) { /* <32-CEL> */
|
|||
|
workHandState = HGetState ((Handle)splineKeyPtr->fsWorkHand);
|
|||
|
HNoPurge(splineKeyPtr->fsWorkHand); /* <32-CEL> */
|
|||
|
if (splineKeyPtr->cacheListHandle || !(result = sb_ModCacheList(splineKey)))
|
|||
|
result = sb_LoadNewCache(splineKey, widthTabHand, squashed);
|
|||
|
HSetState((Handle)splineKeyPtr->fsWorkHand, workHandState);
|
|||
|
}
|
|||
|
|
|||
|
HPurge((Handle)(*splineKey)->cacheHand); /* 15-CEL */
|
|||
|
HSetState((Handle)splineKey, splineKeyState);
|
|||
|
HSetState((*widthTabHand)->tabFont, fontState);
|
|||
|
return result;
|
|||
|
|
|||
|
} /* End sb_SearchForCache */
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/***************************************************************************************************/
|
|||
|
/***************************************************************************************************/
|
|||
|
/**********************************/
|
|||
|
/* ROUTINES THAT CALL FONT SCALER */
|
|||
|
/**********************************/
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_SetUpWorkHand
|
|||
|
**
|
|||
|
** sb_SetUpWorkHand
|
|||
|
**
|
|||
|
**
|
|||
|
*/
|
|||
|
static long sb_SetUpWorkHand()
|
|||
|
{
|
|||
|
sb_SplineKeyHdl splineKey = SPLINE_KEY_HAND;
|
|||
|
long position = 0;
|
|||
|
register sb_SplineKeyPtr splineKeyPtr = *splineKey;
|
|||
|
short splineKeyState = HGetState ((Handle)splineKey);
|
|||
|
long result;
|
|||
|
register char *memoryPtr;
|
|||
|
|
|||
|
HLock((Handle)splineKey);
|
|||
|
|
|||
|
splineKeyPtr->inputOffset = position;
|
|||
|
position += LONG_WORD_ALIGN(sizeof(fs_GlyphInputType));
|
|||
|
splineKeyPtr->infoOffset = position;
|
|||
|
position += LONG_WORD_ALIGN( sizeof(fs_GlyphInfoType));
|
|||
|
|
|||
|
if (result = sb_SizeWorkHandle(position, kNoOptions, noShrink)) goto EXIT; /* Error so can not continue */
|
|||
|
|
|||
|
memoryPtr = *splineKeyPtr->fsWorkHand;
|
|||
|
splineKeyPtr->inPtr = (fs_GlyphInputType *)(memoryPtr + splineKeyPtr->inputOffset);
|
|||
|
splineKeyPtr->outPtr = (fs_GlyphInfoType *)(memoryPtr + splineKeyPtr->infoOffset);
|
|||
|
(*splineKeyPtr->inPtr).GetSfntFragmentPtr = (GetSFNTFunc)QDGetFontFrag;
|
|||
|
(*splineKeyPtr->inPtr).ReleaseSfntFrag = (ReleaseSFNTFunc)QDUngetFontFrag;;
|
|||
|
|
|||
|
/* reinitialize the state to make sure the FS gets ran through */
|
|||
|
sb_ResetFSWorkState(splineKeyPtr);
|
|||
|
|
|||
|
if (!(result = fs_OpenFonts( splineKeyPtr->inPtr, splineKeyPtr->outPtr ))) {
|
|||
|
/*******************/
|
|||
|
/* SETTING OFFSETS */
|
|||
|
/*******************/
|
|||
|
splineKeyPtr->globalOffset0 = position;
|
|||
|
position += LONG_WORD_ALIGN((*splineKeyPtr->outPtr).memorySizes[0]);
|
|||
|
|
|||
|
splineKeyPtr->globalOffset1 = position;
|
|||
|
position += LONG_WORD_ALIGN((*splineKeyPtr->outPtr).memorySizes[1]);
|
|||
|
|
|||
|
splineKeyPtr->globalOffset2 = position;
|
|||
|
position += LONG_WORD_ALIGN((*splineKeyPtr->outPtr).memorySizes[2]);
|
|||
|
splineKeyPtr->sfntDataOffset3 = position;
|
|||
|
/*******************/
|
|||
|
|
|||
|
/***********************/
|
|||
|
/** FSWorkHand HANDLE **/
|
|||
|
/***********************/
|
|||
|
if (!(result = sb_SizeWorkHandle( position, kKeepContents, noShrink ))) {
|
|||
|
sb_SetMemPtrs(0);
|
|||
|
if (result = fs_Initialize( splineKeyPtr->inPtr, splineKeyPtr->outPtr ))
|
|||
|
sb_Debug();
|
|||
|
}
|
|||
|
} /* End if */
|
|||
|
|
|||
|
EXIT:
|
|||
|
HSetState((Handle)splineKey, splineKeyState);
|
|||
|
return result;
|
|||
|
} /* End sb_SetUpWorkHand */
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_SFNTMatchSize
|
|||
|
**
|
|||
|
** sb_SFNTMatchSize
|
|||
|
**
|
|||
|
**
|
|||
|
*/
|
|||
|
pascal Boolean sb_SFNTMatchSize(Handle /*sfntHand*/, short /*matchSize*/)
|
|||
|
{
|
|||
|
return true;
|
|||
|
|
|||
|
} /* End sb_SFNTMatchSize */
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** AppendSplineDirectoryToWidthTable
|
|||
|
**
|
|||
|
** AppendSplineDirectoryToWidthTable
|
|||
|
**
|
|||
|
** This routine appends the spline directory for the sfnt specified by the widthTableHandle's
|
|||
|
** tabFont field to the end of the widthTableHandle by resizing the widthTableHandle and
|
|||
|
** blockmoving the directory data.
|
|||
|
**
|
|||
|
*/
|
|||
|
|
|||
|
|
|||
|
long AppendSplineDirectoryToWidthTable( Handle splineHandle, widthTableHdl widthTableHandle )
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
// Locals
|
|||
|
|
|||
|
long error;
|
|||
|
Size splineDirectorySize;
|
|||
|
sfnt_OffsetTable* splineDirectoryPointer;
|
|||
|
|
|||
|
error = memFullErr;
|
|||
|
splineDirectoryPointer = (sfnt_OffsetTable*) QDGetFontFrag( splineHandle, 0, OFFSETTABLESIZE );
|
|||
|
if ( splineDirectoryPointer != nil ) {
|
|||
|
|
|||
|
splineDirectorySize = OFFSETTABLESIZE + (splineDirectoryPointer->numOffsets * sizeof(sfnt_DirectoryEntry));
|
|||
|
QDUngetFontFrag( splineHandle, splineDirectoryPointer );
|
|||
|
|
|||
|
splineDirectoryPointer = (sfnt_OffsetTable*) QDGetFontFrag( splineHandle, 0, splineDirectorySize );
|
|||
|
if ( splineDirectoryPointer != nil ) {
|
|||
|
|
|||
|
SetHandleSize( (Handle) widthTableHandle, sizeof( widthTable ) + splineDirectorySize );
|
|||
|
if ( (error = MemError( )) == noErr ) {
|
|||
|
|
|||
|
BlockMove( (Ptr) splineDirectoryPointer, (Ptr) (*widthTableHandle)->fSplineDirectory, splineDirectorySize );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
QDUngetFontFrag( splineHandle, splineDirectoryPointer );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
return( error );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_FillWidthTab
|
|||
|
**
|
|||
|
** sb_FillWidthTab
|
|||
|
**
|
|||
|
** This routine is called by the Font Manager when a new font width table needs to be filled
|
|||
|
** out with the proper metrics for spline fonts.
|
|||
|
**
|
|||
|
*/
|
|||
|
pascal long sb_FillWidthTab(widthTableHdl widthTabHand, Boolean fractEnable)
|
|||
|
{
|
|||
|
register sb_SplineKeyHdl splineKey = SPLINE_KEY_HAND;
|
|||
|
register sb_SplineKeyPtr splineKeyPtr = *splineKey;
|
|||
|
register widthTablePtr widTabPtr = *widthTabHand;
|
|||
|
short FontHandState = HGetState (widTabPtr->tabFont);
|
|||
|
FMOutput *fmRecPtr = &FMOUTPUT_PTR;
|
|||
|
register long result = NO_ERR;
|
|||
|
Boolean runInMinMode = false;
|
|||
|
|
|||
|
#ifndef SYSTEM_7
|
|||
|
if (!splineKeyPtr->mfExists) /* If it's not already running, check */
|
|||
|
splineKeyPtr->mfExists = MultiFinderExist();
|
|||
|
#endif
|
|||
|
|
|||
|
HNoPurge(widTabPtr->tabFont);
|
|||
|
|
|||
|
widTabPtr->vOutput = 1 << 8; /* reset to no factor */
|
|||
|
widTabPtr->hOutput = 1 << 8;
|
|||
|
widTabPtr->vFactor = 1 << 8;
|
|||
|
widTabPtr->hFactor = 1 << 8;
|
|||
|
widTabPtr->notFast = (fmRecPtr->boldPixels || fmRecPtr->ulThick || fmRecPtr->shadowPixels);
|
|||
|
widTabPtr->trans00 = FixDiv(widTabPtr->inNumer.h, widTabPtr->inDenom.h);
|
|||
|
widTabPtr->trans11 = FixDiv(widTabPtr->inNumer.v, widTabPtr->inDenom.v);
|
|||
|
|
|||
|
if (widTabPtr->aFace & OBLIQUE_BIT) {
|
|||
|
if (widTabPtr->aSize <= 8) {
|
|||
|
widTabPtr->trans10 = (widTabPtr->trans00) / 2;
|
|||
|
} else if (widTabPtr->aSize <= 16) {
|
|||
|
widTabPtr->trans10 = (widTabPtr->trans00) / 3;
|
|||
|
} else if (widTabPtr->aSize <= 22) {
|
|||
|
widTabPtr->trans10 = (widTabPtr->trans00) / 4;
|
|||
|
} else {
|
|||
|
widTabPtr->trans10 = (widTabPtr->trans00) / 5;
|
|||
|
}
|
|||
|
} else widTabPtr->trans10 = 0L;
|
|||
|
|
|||
|
result = AppendSplineDirectoryToWidthTable( widTabPtr->tabFont, widthTabHand );
|
|||
|
if ( result == noErr ) {
|
|||
|
|
|||
|
widTabPtr = *widthTabHand;
|
|||
|
|
|||
|
if ((result = sb_CheckWorkHandle()) == MEM_ERR) {
|
|||
|
splineKeyPtr = *splineKey;
|
|||
|
if (!(result = sb_ShrinkCacheToMin(splineKeyPtr->cacheHand, 0))) {
|
|||
|
runInMinMode = true;
|
|||
|
result = sb_CheckWorkHandle();
|
|||
|
}
|
|||
|
}
|
|||
|
if (!result) {
|
|||
|
splineKeyPtr = *splineKey;
|
|||
|
HNoPurge(splineKeyPtr->fsWorkHand); /* <30-CEL> */
|
|||
|
if (((result = sb_SetNewSFNT(widthTabHand)) == MEM_ERR) && !runInMinMode) {
|
|||
|
splineKeyPtr = *splineKey;
|
|||
|
if (!(result = sb_ShrinkCacheToMin(splineKeyPtr->cacheHand, 0)))
|
|||
|
result = sb_SetNewSFNT(widthTabHand);
|
|||
|
}
|
|||
|
splineKeyPtr = *splineKey;
|
|||
|
if (!result) {
|
|||
|
widTabPtr = *widthTabHand;
|
|||
|
sb_SetMemPtrs(widthTabHand);
|
|||
|
|
|||
|
result = fs_FillWidthTable(splineKeyPtr->inPtr, (Fixed*)widTabPtr, widTabPtr->tabFont, widTabPtr->style, widTabPtr->fID, !fractEnable);
|
|||
|
if (result)
|
|||
|
sb_Debug();
|
|||
|
}
|
|||
|
HPurge(splineKeyPtr->fsWorkHand); /* <30-CEL> */
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
HSetState((**widthTabHand).tabFont, FontHandState);
|
|||
|
return (**widthTabHand).badFontFlag = result;
|
|||
|
|
|||
|
} /* End sb_FillWidthTab */
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_FillPrinterWidths
|
|||
|
**
|
|||
|
** sb_FillPrinterWidths
|
|||
|
**
|
|||
|
** This routine is called by the Font Manager when a new font width table needs to be filled
|
|||
|
** out with the proper metrics for spline fonts.
|
|||
|
**
|
|||
|
*/
|
|||
|
pascal long sb_FillPrinterWidths(Fixed *widthsArrayPtr, Handle sfntHand)
|
|||
|
{
|
|||
|
sb_SplineKeyHdl splineKey = SPLINE_KEY_HAND; /*<16> removed register */
|
|||
|
register sb_SplineKeyPtr splineKeyPtr = *splineKey;
|
|||
|
register long result = NO_ERR;
|
|||
|
register widthTablePtr widTabPtr;
|
|||
|
|
|||
|
#ifndef SYSTEM_7
|
|||
|
if (!splineKeyPtr->mfExists) /* If it's not already running, check */
|
|||
|
splineKeyPtr->mfExists = MultiFinderExist();
|
|||
|
#endif
|
|||
|
|
|||
|
HLock( (Handle)splineKey );
|
|||
|
|
|||
|
if (result = sb_CheckWorkHandle()) goto CLEANUP;
|
|||
|
HNoPurge(splineKeyPtr->fsWorkHand); /* <28-CEL> */
|
|||
|
|
|||
|
if (!splineKeyPtr->tempWidthTabHand) {
|
|||
|
splineKeyPtr->tempWidthTabHand = (widthTableHdl)NewHandleSys(sizeof(widthTable));
|
|||
|
result = MemError();
|
|||
|
} else if (!*splineKeyPtr->tempWidthTabHand) {
|
|||
|
THz prevZone = GetZone();
|
|||
|
|
|||
|
SetZone(SystemZone());
|
|||
|
ReallocHandle((Handle)splineKeyPtr->tempWidthTabHand, sizeof(widthTable));
|
|||
|
result = MemError();
|
|||
|
SetZone(prevZone);
|
|||
|
}
|
|||
|
|
|||
|
if (!result) {
|
|||
|
widTabPtr = *splineKeyPtr->tempWidthTabHand;
|
|||
|
widTabPtr->tabFont = sfntHand;
|
|||
|
widTabPtr->fSize = 1;
|
|||
|
widTabPtr->inNumer.h = 1;
|
|||
|
widTabPtr->inNumer.v = 1;
|
|||
|
widTabPtr->inDenom.h = 1;
|
|||
|
widTabPtr->inDenom.v = 1;
|
|||
|
widTabPtr->face = 0;
|
|||
|
widTabPtr->aFace = 0;
|
|||
|
widTabPtr->aSize = 1;
|
|||
|
widTabPtr->trans00 = 1L << 16;
|
|||
|
widTabPtr->trans11 = 1L << 16;
|
|||
|
widTabPtr->trans10 = 0;
|
|||
|
|
|||
|
result = AppendSplineDirectoryToWidthTable( sfntHand, splineKeyPtr->tempWidthTabHand );
|
|||
|
if ( result == noErr ) {
|
|||
|
|
|||
|
if (result = sb_SetNewSFNT ( splineKeyPtr->tempWidthTabHand ))
|
|||
|
sb_Debug();
|
|||
|
else {
|
|||
|
short sfntID; /* hack, should be id of this sfnt (passed in by caller) */
|
|||
|
ResType sfntType;
|
|||
|
Str255 sfntName;
|
|||
|
|
|||
|
GetResInfo( sfntHand, &sfntID, &sfntType, &sfntName[0] );
|
|||
|
sb_SetMemPtrs(splineKeyPtr->tempWidthTabHand);
|
|||
|
if (result = fs_FillWidthTable(splineKeyPtr->inPtr, widthsArrayPtr, sfntHand, 0, sfntID, 0))
|
|||
|
sb_Debug();
|
|||
|
}
|
|||
|
}
|
|||
|
} else sb_Debug();
|
|||
|
|
|||
|
HPurge(splineKeyPtr->fsWorkHand); /* <28-CEL> */
|
|||
|
CLEANUP:
|
|||
|
HPurge((Handle)(splineKeyPtr->tempWidthTabHand)); /* Do not need if memory is needed */
|
|||
|
HUnlock((Handle)splineKey);
|
|||
|
return result;
|
|||
|
|
|||
|
} /* End sb_FillPrinterWidths */
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_PreFlightFontMem
|
|||
|
**
|
|||
|
** sb_PreFlightFontMem
|
|||
|
**
|
|||
|
** LONG_WORD_ALIGN((ppem+8) >> 3) == scan bytes long aligned.
|
|||
|
**
|
|||
|
** Called by: DrText, FMSwapFont
|
|||
|
**
|
|||
|
** This preflighting will get better!!!
|
|||
|
*/
|
|||
|
#define CACHE_ARRAY_SIZE 1024
|
|||
|
pascal long sb_PreFlightFontMem ( widthTableHdl widTabHand, Handle fontHandle, short scanLines, short ppem )
|
|||
|
{
|
|||
|
sb_SplineKeyHdl splineKey = SPLINE_KEY_HAND;
|
|||
|
register sb_SplineKeyPtr splineKeyPtr = *splineKey;
|
|||
|
register long result = NO_ERR;
|
|||
|
Handle tempHand;
|
|||
|
register long bitAndSlopSpace;
|
|||
|
register widthTablePtr widTabPtr = *widTabHand;
|
|||
|
short fontHandState;
|
|||
|
|
|||
|
#ifndef SYSTEM_7
|
|||
|
if (!splineKeyPtr->mfExists) /* If it's not already running, check */
|
|||
|
splineKeyPtr->mfExists = MultiFinderExist();
|
|||
|
#endif
|
|||
|
|
|||
|
fontHandState = HGetState(fontHandle);
|
|||
|
HNoPurge(fontHandle);
|
|||
|
|
|||
|
result = AppendSplineDirectoryToWidthTable( fontHandle, widTabHand );
|
|||
|
if ( result == noErr ) {
|
|||
|
|
|||
|
if (!(result = sb_CheckWorkHandle())) {
|
|||
|
splineKeyPtr = *splineKey;
|
|||
|
sb_ResetFSWorkState(splineKeyPtr);
|
|||
|
HNoPurge(splineKeyPtr->fsWorkHand);
|
|||
|
|
|||
|
sb_SetMemPtrs(widTabHand);
|
|||
|
(*splineKeyPtr->inPtr).clientID = fontHandle;
|
|||
|
if (!(result = sb_SetFontMemory(splineKey, widTabHand))) {
|
|||
|
register short calcRowBytes = (LONG_WORD_ALIGN((ppem+8) >> 3));
|
|||
|
|
|||
|
scanLines = 4; /* Hard code minumum band */
|
|||
|
bitAndSlopSpace = scanLines * calcRowBytes;
|
|||
|
bitAndSlopSpace += (sizeof(sb_CacheHead) + CACHE_ARRAY_SIZE);
|
|||
|
/* bitAndSlopSpace += (ppem * calcRowBytes); */ /* for scan converter extra */
|
|||
|
|
|||
|
if (!(tempHand = sb_GetBitMapSpace(bitAndSlopSpace))) {
|
|||
|
result = PRE_FLIGHT_ERR;
|
|||
|
} else HPurge(tempHand);
|
|||
|
}
|
|||
|
HPurge((*splineKey)->fsWorkHand);
|
|||
|
}
|
|||
|
}
|
|||
|
HSetState(fontHandle, fontHandState);
|
|||
|
return result;
|
|||
|
|
|||
|
} /* End sb_PreFlightFontMem */
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_RenderGlyphInfo
|
|||
|
**
|
|||
|
** sb_RenderGlyphInfo
|
|||
|
**
|
|||
|
*/
|
|||
|
static long sb_RenderGlyphInfo ( sb_SplineKeyHdl splineKey, widthTableHdl widTabHand, long addEntryOffset )
|
|||
|
{
|
|||
|
register sb_SplineKeyPtr splineKeyPtr;
|
|||
|
register widthTablePtr widTabPtr;
|
|||
|
register sb_CacheHeadPtr cachePtr;
|
|||
|
register fs_GlyphInfoType *infoPtr;
|
|||
|
register sb_GlyphData *glyphDataPtr;
|
|||
|
char *hiliteModePtr = HILITEMODE;
|
|||
|
long result;
|
|||
|
BitMap *bitMapPtr;
|
|||
|
int16 ascent, descent, yMax, yMin;
|
|||
|
Fixed newTrans11 = (*widTabHand)->trans11;
|
|||
|
unsigned char resetTrans = 0; /* <14> */
|
|||
|
|
|||
|
SQUASH:
|
|||
|
if (result = sb_SetNewSFNT ( widTabHand )) return result;
|
|||
|
|
|||
|
/* re-estab ptrs */
|
|||
|
splineKeyPtr = *splineKey;
|
|||
|
widTabPtr = *widTabHand;
|
|||
|
cachePtr = *splineKeyPtr->cacheHand;
|
|||
|
glyphDataPtr = (sb_GlyphData *)((char *)cachePtr + addEntryOffset);
|
|||
|
|
|||
|
sb_SetMemPtrs(widTabHand);
|
|||
|
#if TheFuture /* <18 > EBITMAP */
|
|||
|
(*splineKeyPtr->inPtr).param.newglyph.bitmapMethodPreferences = 1;
|
|||
|
(*splineKeyPtr->inPtr).param.newglyph.scalingPreference = 0;
|
|||
|
#endif
|
|||
|
(*splineKeyPtr->inPtr).param.newglyph.characterCode = glyphDataPtr->glyphID;
|
|||
|
if (result = fs_NewGlyph( splineKeyPtr->inPtr, splineKeyPtr->outPtr )) {
|
|||
|
sb_Debug();
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
(*splineKeyPtr->inPtr).param.gridfit.styleFunc = 0;
|
|||
|
(*splineKeyPtr->inPtr).param.gridfit.traceFunc = 0;
|
|||
|
|
|||
|
#if TheFuture /* <18 > EBITMAP */
|
|||
|
if (result = fs_GetGlyphInfo( splineKeyPtr->inPtr, splineKeyPtr->outPtr )) {
|
|||
|
sb_Debug();
|
|||
|
return result;
|
|||
|
}
|
|||
|
if (!(*splineKeyPtr->outPtr).outlinesExist) {
|
|||
|
return SKIP_CHAR; /* really means char is ok, but has no contours */
|
|||
|
}
|
|||
|
#endif
|
|||
|
#if !TheFuture /* <18 > EBITMAP */
|
|||
|
if (result = fs_ContourGridFit( splineKeyPtr->inPtr, splineKeyPtr->outPtr )) {
|
|||
|
sb_Debug();
|
|||
|
return result;
|
|||
|
}
|
|||
|
if (!(*splineKeyPtr->outPtr).outlinesExist) {
|
|||
|
return SKIP_CHAR; /* really means char is ok, but has no contours */
|
|||
|
}
|
|||
|
if (result = fs_FindBitMapSize( splineKeyPtr->inPtr, splineKeyPtr->outPtr )) {
|
|||
|
sb_Debug();
|
|||
|
return result;
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
ascent = (cachePtr->ascent >> 16);
|
|||
|
descent = -(cachePtr->descent >> 16); /* turn back into it<69>s true sign */
|
|||
|
|
|||
|
infoPtr = (fs_GlyphInfoType *)splineKeyPtr->outPtr;
|
|||
|
bitMapPtr = &(infoPtr->bitMapInfo);
|
|||
|
glyphDataPtr->yMin = yMin = bitMapPtr->bounds.top;
|
|||
|
glyphDataPtr->yMax = yMax = bitMapPtr->bounds.bottom;
|
|||
|
|
|||
|
/* Squashing */
|
|||
|
if ( !(*hiliteModePtr & PRESERVE_GLYPH) && (resetTrans<2) && (yMax > ascent || yMin < descent)) /* <14> */
|
|||
|
{
|
|||
|
Fixed maxTrans11, minTrans11; /* <14> */
|
|||
|
++resetTrans; /* <14> */
|
|||
|
|
|||
|
if (yMax > ascent && ascent > 0) /* <14> */
|
|||
|
maxTrans11 = ShortMulDiv(widTabPtr->trans11, ascent, yMax); /* <14> */
|
|||
|
else maxTrans11 = widTabPtr->trans11; /* <14> */
|
|||
|
if (yMin < descent && descent < 0) /* <14> */
|
|||
|
minTrans11 = ShortMulDiv(widTabPtr->trans11, descent, yMin); /* <14> */
|
|||
|
else minTrans11 = widTabPtr->trans11; /* <14> */
|
|||
|
|
|||
|
widTabPtr->trans11 = (maxTrans11 < minTrans11) ? maxTrans11 : minTrans11;/* <14> */
|
|||
|
|
|||
|
goto SQUASH;
|
|||
|
} /* End Testing no line height */
|
|||
|
|
|||
|
glyphDataPtr->lsb = infoPtr->metricInfo.leftSideBearing.x;
|
|||
|
glyphDataPtr->devLSB = infoPtr->metricInfo.devLeftSideBearing.x >> 16;
|
|||
|
glyphDataPtr->xMin = infoPtr->bitMapInfo.bounds.left;
|
|||
|
glyphDataPtr->bitWidth = bitMapPtr->bounds.right - bitMapPtr->bounds.left;
|
|||
|
glyphDataPtr->scan = yMax - yMin;
|
|||
|
glyphDataPtr->byteWidth = glyphDataPtr->scanByteWidth = (uint32)bitMapPtr->rowBytes;
|
|||
|
|
|||
|
widTabPtr->trans11 = newTrans11; /* <14> */
|
|||
|
|
|||
|
return NO_ERR;
|
|||
|
} /* End sb_RenderGlyphInfo */
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_RenderMemShrink
|
|||
|
**
|
|||
|
**
|
|||
|
**
|
|||
|
*/
|
|||
|
long sb_RenderMemShrink(sb_SplineKeyHdl splineKey, long *addEntryOffset, Boolean *runInMinMode)
|
|||
|
{
|
|||
|
register sb_SplineKeyPtr splineKeyPtr = *splineKey;
|
|||
|
register sb_CacheHeadPtr cachePtr;
|
|||
|
long result;
|
|||
|
|
|||
|
if (result = sb_ShrinkCacheToMin(splineKeyPtr->cacheHand, *addEntryOffset)) {
|
|||
|
sb_Debug();
|
|||
|
return result;
|
|||
|
} else {
|
|||
|
*runInMinMode = true;
|
|||
|
cachePtr = *splineKeyPtr->cacheHand;
|
|||
|
*addEntryOffset = cachePtr->addEntryOffset;
|
|||
|
}
|
|||
|
return NO_ERR;
|
|||
|
} /* End sb_RenderMemShrink */
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_RoomForHead
|
|||
|
** Make room for the header
|
|||
|
**
|
|||
|
** MOVES MEMORY
|
|||
|
**
|
|||
|
*/
|
|||
|
long sb_RoomForHead(sb_SplineKeyHdl splineKey, long *addEntryOffset, Boolean *runInMinMode)
|
|||
|
{
|
|||
|
register sb_SplineKeyPtr splineKeyPtr = *splineKey;
|
|||
|
long cacheSize;
|
|||
|
register Handle tempHand;
|
|||
|
|
|||
|
/**************************
|
|||
|
** Make room for the header
|
|||
|
**
|
|||
|
** MOVES MEMORY
|
|||
|
*/
|
|||
|
cacheSize = GetHandleSize((Handle)splineKeyPtr->cacheHand);
|
|||
|
if (GLYPH_HEAD_BYTES > ( cacheSize - *addEntryOffset )) {
|
|||
|
THz zone = splineKeyPtr->cacheZone;
|
|||
|
|
|||
|
if (tempHand = sb_SizeTheBlock(splineKey, (Handle)splineKeyPtr->cacheHand, &zone,
|
|||
|
*addEntryOffset + GLYPH_HEAD_BYTES, kKeepContents,
|
|||
|
splineKeyPtr->cachePlace, noShrink)) {
|
|||
|
splineKeyPtr = *splineKey;
|
|||
|
splineKeyPtr->cacheHand = (sb_CacheHeadHdl)tempHand;
|
|||
|
splineKeyPtr->cacheZone = zone;
|
|||
|
} else return(sb_RenderMemShrink(splineKey, addEntryOffset, runInMinMode));
|
|||
|
}
|
|||
|
return NO_ERR;
|
|||
|
} /* End sb_RoomForHead */
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_RangeCheck
|
|||
|
**
|
|||
|
**
|
|||
|
**
|
|||
|
*/
|
|||
|
long sb_RangeCheck(sb_CacheHeadPtr cachePtr, sb_GlyphData *glyphDataPtr,
|
|||
|
short yMin16, short yMax16, long addEntryOffset, long glyphEntryOffset)
|
|||
|
{
|
|||
|
/****** Font Scaler may return completely bogus values because of a bad font *******/
|
|||
|
/***** is the font bad???? do some range checking ******/
|
|||
|
if (!glyphDataPtr->scan ||
|
|||
|
glyphDataPtr->yMax < yMin16 ||
|
|||
|
glyphDataPtr->yMin > yMax16 ||
|
|||
|
glyphDataPtr->bitWidth == 0 ||
|
|||
|
glyphDataPtr->bitWidth > ((short)(cachePtr->widMax >> 16) * 2) ||
|
|||
|
(glyphDataPtr->yMax - glyphDataPtr->yMin) > ((yMax16 << 1) - yMin16)) {
|
|||
|
*(uint32*) ((Ptr) cachePtr + glyphEntryOffset) = (addEntryOffset | ERROR_ENTRY_BIT);
|
|||
|
sb_Debug( );
|
|||
|
return ENTRY_ERROR;
|
|||
|
}
|
|||
|
return NO_ERR;
|
|||
|
} /* End sb_RangeCheck */
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_SquishFailAdjust
|
|||
|
**
|
|||
|
** Squish Failure Adjustment
|
|||
|
**
|
|||
|
** If squishing was not enough, then clip away to
|
|||
|
** keep in range
|
|||
|
**
|
|||
|
**
|
|||
|
**
|
|||
|
*/
|
|||
|
sb_SquishFailAdjust(sb_GlyphData *glyphDataPtr, sb_Glyph *glyphPtr,
|
|||
|
short yMin16, short yMax16, Boolean *doBits, Boolean bitsCached)
|
|||
|
{
|
|||
|
if (glyphDataPtr->yMax > yMax16) glyphDataPtr->yMax = yMax16;
|
|||
|
if (glyphDataPtr->yMin < yMin16) glyphDataPtr->yMin = yMin16;
|
|||
|
glyphDataPtr->scan = glyphDataPtr->yMax - glyphDataPtr->yMin;
|
|||
|
glyphDataPtr->adjustTop = yMax16 - glyphDataPtr->yMax;
|
|||
|
glyphPtr->yMin = glyphDataPtr->yMin;
|
|||
|
glyphPtr->yMax = glyphDataPtr->yMax;
|
|||
|
glyphPtr->scan = glyphDataPtr->scan;
|
|||
|
|
|||
|
if (!bitsCached || glyphPtr->clipVert) {
|
|||
|
if (glyphPtr->topClip < glyphDataPtr->yMax) glyphPtr->yMax = glyphPtr->topClip;
|
|||
|
if (glyphPtr->botClip > glyphDataPtr->yMin) glyphPtr->yMin = glyphPtr->botClip;
|
|||
|
glyphPtr->scan = glyphPtr->yMax - glyphPtr->yMin;
|
|||
|
|
|||
|
if (glyphPtr->scan <= 0) *doBits = false;
|
|||
|
}
|
|||
|
return;
|
|||
|
|
|||
|
} /* End sb_SquishFailAdjust */
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_GrowForGlyphData
|
|||
|
**
|
|||
|
**
|
|||
|
**
|
|||
|
*/
|
|||
|
long sb_GrowForGlyphData(sb_SplineKeyHdl splineKey, widthTableHdl widTabHand, sb_GlyphData *glyphDataPtr,
|
|||
|
long *addEntryOffset, Boolean *runInMinMode, Boolean bitsCached,
|
|||
|
long *dataByteSize)
|
|||
|
{
|
|||
|
register sb_SplineKeyPtr splineKeyPtr = *splineKey;
|
|||
|
widthTablePtr widTabPtr = *widTabHand;
|
|||
|
register Handle tempHand;
|
|||
|
long result;
|
|||
|
long cacheSize;
|
|||
|
|
|||
|
/***********************
|
|||
|
** CALC THE DATA SIZE
|
|||
|
*/
|
|||
|
if (bitsCached) {
|
|||
|
*dataByteSize = ((glyphDataPtr->scanByteWidth * glyphDataPtr->scan) + 3) & ~3;
|
|||
|
} else {
|
|||
|
sb_SetMemPtrs(widTabHand);
|
|||
|
fs_SizeOfOutlines( splineKeyPtr->inPtr, splineKeyPtr->outPtr );
|
|||
|
*dataByteSize = ((*splineKeyPtr->outPtr).outlineCacheSize + 3) & ~3;
|
|||
|
}
|
|||
|
|
|||
|
/************************************
|
|||
|
** Check CACHE size - MOVES MEMORY
|
|||
|
*/
|
|||
|
cacheSize = GetHandleSize((Handle)splineKeyPtr->cacheHand);
|
|||
|
if (*dataByteSize + GLYPH_HEAD_BYTES > cacheSize - *addEntryOffset) {
|
|||
|
THz zone = splineKeyPtr->cacheZone;
|
|||
|
|
|||
|
if (!(tempHand = sb_SizeTheBlock( splineKey, (Handle)splineKeyPtr->cacheHand, &zone,
|
|||
|
*addEntryOffset + *dataByteSize + GLYPH_HEAD_BYTES + INCREASE_CACHE,
|
|||
|
kKeepContents, splineKeyPtr->cachePlace, noShrink))) {
|
|||
|
splineKeyPtr = *splineKey; /* Try for minimum chunk */
|
|||
|
tempHand = sb_SizeTheBlock( splineKey, (Handle)splineKeyPtr->cacheHand, &zone,
|
|||
|
*addEntryOffset + GLYPH_HEAD_BYTES + *dataByteSize,
|
|||
|
kKeepContents, splineKeyPtr->cachePlace, noShrink);
|
|||
|
}
|
|||
|
if (tempHand) {
|
|||
|
splineKeyPtr = *splineKey;
|
|||
|
splineKeyPtr->cacheHand = (sb_CacheHeadHdl)tempHand;
|
|||
|
splineKeyPtr->cacheZone = zone;
|
|||
|
} else if (!*runInMinMode) {
|
|||
|
if (result = sb_RenderMemShrink(splineKey, addEntryOffset, runInMinMode))
|
|||
|
return result;
|
|||
|
} else return GROWZONE_HANDLE_ERR;
|
|||
|
}
|
|||
|
return NO_ERR;
|
|||
|
|
|||
|
} /* End sb_GrowForGlyphData */
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_GrowWork6and7
|
|||
|
**
|
|||
|
**
|
|||
|
**
|
|||
|
*/
|
|||
|
long sb_GrowWork6and7(sb_SplineKeyHdl splineKey, widthTableHdl widTabHand,
|
|||
|
long *addEntryOffset, Boolean *runInMinMode)
|
|||
|
{
|
|||
|
register sb_SplineKeyPtr splineKeyPtr = *splineKey;
|
|||
|
widthTablePtr widTabPtr = *widTabHand;
|
|||
|
long result, position;
|
|||
|
|
|||
|
/*********************************************
|
|||
|
** Do the clipping dance - CAN MOVE MEMORY
|
|||
|
**
|
|||
|
** <6> new memory for the scan converter
|
|||
|
*/
|
|||
|
sb_SetMemPtrs(widTabHand);
|
|||
|
position = splineKeyPtr->rowArrayOffset6 + LONG_WORD_ALIGN(splineKeyPtr->outPtr->memorySizes[6]);
|
|||
|
|
|||
|
if (!*runInMinMode) {
|
|||
|
splineKeyPtr->columnArrayOffset7 = position;
|
|||
|
position += LONG_WORD_ALIGN(splineKeyPtr->outPtr->memorySizes[7]);
|
|||
|
}
|
|||
|
|
|||
|
if ((result = sb_SizeWorkHandle( position, kKeepContents, doShrink )) && !*runInMinMode)
|
|||
|
if (!(result = sb_RenderMemShrink(splineKey, addEntryOffset, runInMinMode)))
|
|||
|
result = sb_SizeWorkHandle( position, kKeepContents, doShrink );
|
|||
|
|
|||
|
return result;
|
|||
|
|
|||
|
|
|||
|
} /* End sb_GrowWork6and7 */
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_GetMemForBits
|
|||
|
**
|
|||
|
**
|
|||
|
**
|
|||
|
*/
|
|||
|
long sb_GetMemForBits(sb_SplineKeyHdl splineKey, widthTableHdl widTabHand,
|
|||
|
sb_Glyph *glyphPtr, Boolean *runInMinMode, long *addEntryOffset,
|
|||
|
short yMax16, long memForScanLine)
|
|||
|
{
|
|||
|
register sb_SplineKeyPtr splineKeyPtr = *splineKey;
|
|||
|
register widthTablePtr widTabPtr = *widTabHand;
|
|||
|
register sb_CacheHeadPtr cachePtr = *splineKeyPtr->cacheHand;
|
|||
|
register sb_GlyphData *glyphDataPtr = (char *)cachePtr + *addEntryOffset;
|
|||
|
short scanBytes = glyphDataPtr->scanByteWidth;
|
|||
|
Handle tempHand;
|
|||
|
long bmSize;
|
|||
|
long result, position;
|
|||
|
Boolean bandGlyph = false;
|
|||
|
|
|||
|
if (glyphPtr->nextBand) {
|
|||
|
glyphDataPtr->yMax = glyphPtr->yMax = glyphPtr->nextTopBand;
|
|||
|
if (glyphPtr->nextTopBand - glyphPtr->nextBotBand <= glyphPtr->bandScan) {
|
|||
|
glyphDataPtr->yMin = glyphPtr->yMin = glyphPtr->nextBotBand;
|
|||
|
} else {
|
|||
|
glyphDataPtr->yMin = glyphPtr->yMin = glyphPtr->yMax - glyphPtr->scan;
|
|||
|
glyphPtr->nextTopBand = glyphPtr->yMin;
|
|||
|
}
|
|||
|
glyphDataPtr->scan = glyphPtr->scan = glyphPtr->yMax - glyphPtr->yMin;
|
|||
|
glyphDataPtr->adjustTop = yMax16 - glyphDataPtr->yMax;
|
|||
|
}
|
|||
|
|
|||
|
bmSize = glyphPtr->scan * scanBytes;
|
|||
|
if (*runInMinMode && !glyphPtr->nextBand) {
|
|||
|
sb_SetMemPtrs(widTabHand);
|
|||
|
position = splineKeyPtr->rowArrayOffset6 + LONG_WORD_ALIGN(memForScanLine*glyphPtr->scan);
|
|||
|
if (result = sb_SizeWorkHandle( position, kKeepContents, doShrink ))
|
|||
|
bandGlyph = true;
|
|||
|
}
|
|||
|
|
|||
|
tempHand = nil; /* init to nil */
|
|||
|
if (!bandGlyph || glyphPtr->nextBand) {
|
|||
|
if (!(tempHand = sb_GetBitMapSpace(bmSize))) {
|
|||
|
if (!glyphPtr->nextBand) {
|
|||
|
if (!*runInMinMode) {
|
|||
|
if (result = sb_RenderMemShrink(splineKey, addEntryOffset, runInMinMode))
|
|||
|
return result;
|
|||
|
}
|
|||
|
bandGlyph = true;
|
|||
|
} else {
|
|||
|
glyphPtr->nextBand = false; /* second time so we are in trouble */
|
|||
|
sb_Debug();
|
|||
|
return MEM_ERR;
|
|||
|
}
|
|||
|
} else if (glyphPtr->yMin == glyphPtr->nextBotBand)
|
|||
|
glyphPtr->nextBand = false; /* finished char loop */
|
|||
|
}
|
|||
|
|
|||
|
if (bandGlyph) { /* could still not get the bitmap */
|
|||
|
if (tempHand = sb_BandChar(splineKey, &glyphPtr->scan, scanBytes, memForScanLine)) {
|
|||
|
splineKeyPtr = *splineKey;
|
|||
|
cachePtr = (sb_CacheHead *)*splineKeyPtr->cacheHand;
|
|||
|
glyphDataPtr = (sb_GlyphData *)((char *)cachePtr + *addEntryOffset);
|
|||
|
|
|||
|
glyphPtr->nextBand = true;
|
|||
|
glyphPtr->nextBotBand = glyphPtr->yMin;
|
|||
|
glyphDataPtr->yMin = glyphPtr->yMin = glyphPtr->yMax - glyphPtr->scan;
|
|||
|
glyphPtr->nextTopBand = glyphPtr->yMin;
|
|||
|
glyphDataPtr->scan = glyphPtr->bandScan = glyphPtr->scan;
|
|||
|
glyphDataPtr->yMax = glyphPtr->yMax;
|
|||
|
} else {
|
|||
|
sb_Debug();
|
|||
|
return MEM_ERR;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* This is a temporary hack!!! This fixes the problem with low memory banding */
|
|||
|
if (glyphPtr->topClip - glyphPtr->botClip == 0 && glyphPtr->nextBand)
|
|||
|
glyphPtr->nextBand = false;
|
|||
|
|
|||
|
glyphPtr->bitMapPtr = (uint32 *)*tempHand;
|
|||
|
HPurge(tempHand);
|
|||
|
return NO_ERR;
|
|||
|
|
|||
|
} /* End sb_GetMemForBits */
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_DoTheBits
|
|||
|
**
|
|||
|
**
|
|||
|
**
|
|||
|
*/
|
|||
|
long sb_DoTheBits(sb_SplineKeyHdl splineKey, widthTableHdl widTabHand, register sb_Glyph *glyphPtr,
|
|||
|
short topClip, short bottomClip, Boolean bitsCached, Boolean runInMinMode,
|
|||
|
long addEntryOffset, long glyphEntryOffset)
|
|||
|
{
|
|||
|
register sb_SplineKeyPtr splineKeyPtr = *splineKey;
|
|||
|
register widthTablePtr widTabPtr = *widTabHand;
|
|||
|
register sb_CacheHeadPtr cachePtr = *splineKeyPtr->cacheHand;
|
|||
|
register sb_GlyphData *glyphDataPtr = (char *)cachePtr + addEntryOffset;
|
|||
|
long result;
|
|||
|
|
|||
|
sb_SetMemPtrs(widTabHand);
|
|||
|
(*splineKeyPtr->inPtr).memoryBases[5] = (char *)glyphPtr->bitMapPtr; /* bitmap space */
|
|||
|
(*splineKeyPtr->inPtr).param.scan.topClip = topClip;
|
|||
|
(*splineKeyPtr->inPtr).param.scan.bottomClip = bottomClip;
|
|||
|
if (runInMinMode) (*splineKeyPtr->inPtr).memoryBases[7] = 0;
|
|||
|
#if TheFuture /* <18 > EBITMAP */
|
|||
|
if (result = fs_GetGlyphData( splineKeyPtr->inPtr, splineKeyPtr->outPtr )) {
|
|||
|
*(uint32*) ((Ptr) cachePtr + glyphEntryOffset) |= ERROR_ENTRY_BIT;
|
|||
|
sb_Debug();
|
|||
|
return result;
|
|||
|
}
|
|||
|
#endif
|
|||
|
#if !TheFuture /* <18 > EBITMAP */
|
|||
|
if (result = fs_ContourScan( splineKeyPtr->inPtr, splineKeyPtr->outPtr )) {
|
|||
|
*(uint32*) ((Ptr) cachePtr + glyphEntryOffset) |= ERROR_ENTRY_BIT;
|
|||
|
sb_Debug();
|
|||
|
return result;
|
|||
|
}
|
|||
|
#endif
|
|||
|
if ((bitsCached && !runInMinMode) || !glyphPtr->clipVert) { /* <3-CEL> */
|
|||
|
sb_ShrinkBitmap( glyphDataPtr, (long *)glyphPtr->bitMapPtr, topClip-bottomClip);
|
|||
|
}
|
|||
|
|
|||
|
glyphPtr->byteWidth = glyphDataPtr->byteWidth;
|
|||
|
|
|||
|
if (bitsCached && !runInMinMode) { /* <3-CEL> */
|
|||
|
int16 sourceYMaxAdjust = glyphDataPtr->yMax - glyphPtr->topClip;
|
|||
|
|
|||
|
cachePtr->addEntryOffset += (((glyphDataPtr->byteWidth * glyphDataPtr->scan) + 3) & ~3);
|
|||
|
if (sourceYMaxAdjust > 0)
|
|||
|
glyphPtr->bitMapPtr = (uint32 *)((char *)glyphPtr->bitMapPtr + (sourceYMaxAdjust * glyphDataPtr->byteWidth));
|
|||
|
}
|
|||
|
return NO_ERR;
|
|||
|
|
|||
|
} /* End sb_DoTheBits */
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_RenderGlyph
|
|||
|
**
|
|||
|
**
|
|||
|
**
|
|||
|
*/
|
|||
|
static long sb_RenderGlyph( sb_SplineKeyHdl splineKey, widthTableHdl widTabHand, register sb_Glyph *glyphPtr )
|
|||
|
{
|
|||
|
register sb_SplineKeyPtr splineKeyPtr = *splineKey;
|
|||
|
register widthTablePtr widTabPtr = *widTabHand;
|
|||
|
register sb_CacheHeadPtr cachePtr = *splineKeyPtr->cacheHand;
|
|||
|
Boolean bitsCached = cachePtr->bitsCached;
|
|||
|
long addEntryOffset = cachePtr->addEntryOffset;
|
|||
|
register sb_GlyphData *glyphDataPtr = (char *)cachePtr + addEntryOffset;
|
|||
|
uint16 yMinAdjust = 0; /* adjust for scan lines out of bounds */
|
|||
|
Boolean doBits = true;
|
|||
|
short yMax16 = (cachePtr->yMax >> 16);
|
|||
|
short yMin16 = (cachePtr->yMin >> 16);
|
|||
|
Boolean runInMinMode = false; /* <3-CEL> */
|
|||
|
long dataByteSize;
|
|||
|
long glyphEntryOffset;
|
|||
|
long result;
|
|||
|
int16 topClip, bottomClip;
|
|||
|
long memForScanLine;
|
|||
|
|
|||
|
|
|||
|
glyphPtr->entryOffset = 0;
|
|||
|
if (glyphPtr->nextBand) {
|
|||
|
glyphEntryOffset = GetSingleOrDoubleByteGlyphEntryOffset( glyphPtr->glyphID, cachePtr );
|
|||
|
runInMinMode = true;
|
|||
|
goto DO_NEXT_BAND;
|
|||
|
} else if (result = sb_RoomForHead(splineKey, &addEntryOffset, &runInMinMode))
|
|||
|
return result;
|
|||
|
|
|||
|
/************************************
|
|||
|
** Re-Establish pointers
|
|||
|
*/
|
|||
|
splineKeyPtr = *splineKey;
|
|||
|
cachePtr = *splineKeyPtr->cacheHand;
|
|||
|
glyphDataPtr = (sb_GlyphData *)((char *)cachePtr + addEntryOffset);
|
|||
|
glyphDataPtr->glyphID = glyphPtr->glyphID;
|
|||
|
|
|||
|
if (!runInMinMode) { /* <3-CEL> */
|
|||
|
cachePtr->addEntryOffset += GLYPH_HEAD_BYTES; /* For next entry */
|
|||
|
}
|
|||
|
|
|||
|
if ((result = sb_RenderGlyphInfo(splineKey, widTabHand, addEntryOffset)) == MEM_ERR) {
|
|||
|
if (!runInMinMode) {
|
|||
|
if (result = sb_RenderMemShrink(splineKey, &addEntryOffset, &runInMinMode))
|
|||
|
return result;
|
|||
|
if (result = sb_RenderGlyphInfo(splineKey, widTabHand, addEntryOffset))
|
|||
|
return result;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/***********************
|
|||
|
** Re-establish pointers
|
|||
|
*/
|
|||
|
splineKeyPtr = *splineKey;
|
|||
|
widTabPtr = *widTabHand;
|
|||
|
cachePtr = *splineKeyPtr->cacheHand;
|
|||
|
glyphDataPtr = (sb_GlyphData *)((char *)cachePtr + addEntryOffset);
|
|||
|
|
|||
|
/************************************
|
|||
|
** Determine glyph position in array
|
|||
|
*/
|
|||
|
|
|||
|
glyphEntryOffset = GetSingleOrDoubleByteGlyphEntryOffset( glyphDataPtr->glyphID, cachePtr );
|
|||
|
|
|||
|
if (result) {
|
|||
|
*(uint32*) ((Ptr) cachePtr + glyphEntryOffset) = ERROR_ENTRY_BIT;
|
|||
|
return ENTRY_ERROR;
|
|||
|
}
|
|||
|
if (glyphDataPtr->scan)
|
|||
|
memForScanLine = LONG_WORD_ALIGN(splineKeyPtr->outPtr->memorySizes[6])/glyphDataPtr->scan;
|
|||
|
|
|||
|
if (result = sb_RangeCheck(cachePtr, glyphDataPtr, yMin16, yMax16, addEntryOffset, glyphEntryOffset))
|
|||
|
return result;
|
|||
|
|
|||
|
/**********************************************
|
|||
|
** Figure out the bottom and top scan lines
|
|||
|
*/
|
|||
|
if (!runInMinMode) { /* <3-CEL> */
|
|||
|
if (bitsCached)
|
|||
|
*(uint32*) ((Ptr) cachePtr + glyphEntryOffset) = addEntryOffset;
|
|||
|
else
|
|||
|
*(uint32*) ((Ptr) cachePtr + glyphEntryOffset) = (addEntryOffset | CONTOUR_ENTRY_BIT);
|
|||
|
}
|
|||
|
|
|||
|
sb_SquishFailAdjust(glyphDataPtr, glyphPtr, yMin16, yMax16, &doBits, bitsCached);
|
|||
|
|
|||
|
if (!glyphDataPtr->scan) { /* <2-CEL> if no scan lines, skip char */
|
|||
|
*(uint32*) ((Ptr) cachePtr + glyphEntryOffset) = ERROR_ENTRY_BIT;
|
|||
|
return ENTRY_ERROR;
|
|||
|
}
|
|||
|
|
|||
|
if (!runInMinMode) {
|
|||
|
if (result = sb_GrowForGlyphData(splineKey, widTabHand, glyphDataPtr, &addEntryOffset,
|
|||
|
&runInMinMode, bitsCached, &dataByteSize)) {
|
|||
|
sb_Debug();
|
|||
|
return result;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (result = sb_GrowWork6and7(splineKey, widTabHand, &addEntryOffset, &runInMinMode)) {
|
|||
|
sb_Debug();
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
/************************************
|
|||
|
** Re-Establish pointers
|
|||
|
*/
|
|||
|
splineKeyPtr = *splineKey;
|
|||
|
widTabPtr = *widTabHand;
|
|||
|
cachePtr = (sb_CacheHead *)*splineKeyPtr->cacheHand;
|
|||
|
glyphDataPtr = (sb_GlyphData *)((char *)cachePtr + addEntryOffset);
|
|||
|
sb_SetMemPtrs(widTabHand);
|
|||
|
|
|||
|
/************************************
|
|||
|
** Make space at tail and init pointers
|
|||
|
*/
|
|||
|
if (bitsCached) {
|
|||
|
glyphPtr->bitMapPtr = (uint32 *)&glyphDataPtr->cacheData[0];
|
|||
|
topClip = glyphDataPtr->yMax;
|
|||
|
bottomClip = glyphDataPtr->yMin;
|
|||
|
} else if (!runInMinMode) {
|
|||
|
(*splineKeyPtr->inPtr).param.scan.outlineCache = (long *)&glyphDataPtr->cacheData[0];
|
|||
|
if (result = fs_SaveOutlines( splineKeyPtr->inPtr, splineKeyPtr->outPtr )) {
|
|||
|
*(uint32*) ((Ptr) cachePtr + glyphEntryOffset) |= ERROR_ENTRY_BIT;
|
|||
|
sb_Debug();
|
|||
|
return result;
|
|||
|
}
|
|||
|
cachePtr->addEntryOffset += dataByteSize;
|
|||
|
}
|
|||
|
DO_NEXT_BAND:
|
|||
|
if (doBits && (runInMinMode || !bitsCached)) { /* <3-CEL> */
|
|||
|
if (result = sb_GetMemForBits(splineKey, widTabHand, glyphPtr, &runInMinMode,
|
|||
|
&addEntryOffset, yMax16, memForScanLine))
|
|||
|
return result;
|
|||
|
bottomClip = glyphPtr->yMin;
|
|||
|
topClip = glyphPtr->yMax;
|
|||
|
}
|
|||
|
|
|||
|
if (doBits || (bitsCached && !runInMinMode)) {
|
|||
|
if (result = sb_DoTheBits(splineKey, widTabHand, glyphPtr, topClip, bottomClip, bitsCached,
|
|||
|
runInMinMode, addEntryOffset, glyphEntryOffset)) /* 11-CEL assign result */
|
|||
|
return result;
|
|||
|
}
|
|||
|
glyphPtr->entryOffset = addEntryOffset;
|
|||
|
if (!doBits) return NO_BITS;
|
|||
|
|
|||
|
return NO_ERR;
|
|||
|
} /* sb_RenderGlyph */
|
|||
|
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_CheckCache
|
|||
|
**
|
|||
|
** sb_CheckCache
|
|||
|
**
|
|||
|
**
|
|||
|
*/
|
|||
|
pascal long sb_CheckCache( sb_SplineKeyHdl splineKey, widthTableHdl widthTabHand, register sb_Glyph *glyphPtr )
|
|||
|
{
|
|||
|
register sb_SplineKeyPtr splineKeyPtr;
|
|||
|
register widthTablePtr widTabPtr = *widthTabHand;
|
|||
|
register sb_CacheHead *cachePtr;
|
|||
|
register sb_GlyphData *glyphDataPtr;
|
|||
|
long glyphEntryOffset;
|
|||
|
register long cacheDataOffset;
|
|||
|
Handle tempHand;
|
|||
|
long result;
|
|||
|
Boolean runInMinMode = false;
|
|||
|
|
|||
|
if (glyphPtr->nextBand) goto MIN_MODE;
|
|||
|
|
|||
|
widTabPtr = *widthTabHand;
|
|||
|
splineKeyPtr = *splineKey;
|
|||
|
cachePtr = *splineKeyPtr->cacheHand;
|
|||
|
glyphPtr->entryOffset = 0;
|
|||
|
|
|||
|
/*********************************************/
|
|||
|
/** FIND THE POSITION, OFFSET, AND DATA PTR **/
|
|||
|
/*********************************************/
|
|||
|
|
|||
|
glyphEntryOffset = GetSingleOrDoubleByteGlyphEntryOffset( glyphPtr->glyphID, cachePtr );
|
|||
|
cacheDataOffset = (*(uint32*) ((Ptr) cachePtr + glyphEntryOffset)) & ENTRY_MASK;
|
|||
|
|
|||
|
/********************/
|
|||
|
/** FIND THE ENTRY **/
|
|||
|
/********************/
|
|||
|
if (cacheDataOffset) {
|
|||
|
long bmSize;
|
|||
|
long position;
|
|||
|
|
|||
|
glyphDataPtr = (sb_GlyphData *)((char *)cachePtr + cacheDataOffset);
|
|||
|
glyphPtr->yMin = glyphDataPtr->yMin;
|
|||
|
glyphPtr->yMax = glyphDataPtr->yMax;
|
|||
|
glyphPtr->scan = glyphDataPtr->scan;
|
|||
|
glyphPtr->byteWidth = glyphDataPtr->scanByteWidth;
|
|||
|
if (glyphPtr->clipVert) {
|
|||
|
if (glyphPtr->topClip < glyphDataPtr->yMax) glyphPtr->yMax = glyphPtr->topClip;
|
|||
|
if (glyphPtr->botClip > glyphDataPtr->yMin) glyphPtr->yMin = glyphPtr->botClip;
|
|||
|
|
|||
|
glyphPtr->scan = glyphPtr->yMax - glyphPtr->yMin;
|
|||
|
if (glyphPtr->scan <= 0) return CLIPPED_OUT;
|
|||
|
}
|
|||
|
|
|||
|
sb_SetMemPtrs(widthTabHand);
|
|||
|
(*splineKeyPtr->inPtr).param.scan.outlineCache = (long *)&glyphDataPtr->cacheData[0];
|
|||
|
if (result = fs_RestoreOutlines( splineKeyPtr->inPtr, splineKeyPtr->outPtr )) {
|
|||
|
sb_Debug();
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
/* <6> new memory for the scan converter */
|
|||
|
position = splineKeyPtr->rowArrayOffset6 + LONG_WORD_ALIGN((*splineKeyPtr->outPtr).memorySizes[6]);
|
|||
|
splineKeyPtr->columnArrayOffset7 = position;
|
|||
|
position += LONG_WORD_ALIGN((*splineKeyPtr->outPtr).memorySizes[7]);
|
|||
|
|
|||
|
bmSize = glyphPtr->scan * glyphDataPtr->scanByteWidth;
|
|||
|
|
|||
|
/****************/
|
|||
|
/* MOVES MEMORY */
|
|||
|
/****************/
|
|||
|
if (result = sb_SizeWorkHandle( position, kKeepContents, doShrink )) {
|
|||
|
splineKeyPtr = *splineKey;
|
|||
|
if (result = sb_ShrinkCacheToMin(splineKeyPtr->cacheHand, cacheDataOffset)) {
|
|||
|
sb_Debug();
|
|||
|
return result;
|
|||
|
} else {
|
|||
|
goto MIN_MODE; /* must rerun since data is lost */
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/****************/
|
|||
|
/* MOVES MEMORY */
|
|||
|
/****************/
|
|||
|
if (!(tempHand = sb_GetBitMapSpace(bmSize))) {
|
|||
|
splineKeyPtr = *splineKey;
|
|||
|
if (result = sb_ShrinkCacheToMin(splineKeyPtr->cacheHand, cacheDataOffset)) {
|
|||
|
sb_Debug();
|
|||
|
return result;
|
|||
|
} else {
|
|||
|
goto MIN_MODE; /* must rerun since data is lost */
|
|||
|
}
|
|||
|
}
|
|||
|
HPurge(tempHand);
|
|||
|
/****************/
|
|||
|
|
|||
|
/*************************************************/
|
|||
|
/* Re-establish pointers after memory allocation */
|
|||
|
splineKeyPtr = *splineKey;
|
|||
|
widTabPtr = *widthTabHand;
|
|||
|
cachePtr = (sb_CacheHead *)*splineKeyPtr->cacheHand;
|
|||
|
glyphDataPtr = (sb_GlyphData *)((char *)cachePtr + cacheDataOffset);
|
|||
|
glyphPtr->bitMapPtr = (uint32 *)*tempHand;
|
|||
|
|
|||
|
sb_SetMemPtrs(widthTabHand);
|
|||
|
(*splineKeyPtr->inPtr).memoryBases[5] = (char *)glyphPtr->bitMapPtr;
|
|||
|
(*splineKeyPtr->inPtr).param.scan.outlineCache = (long *)&glyphDataPtr->cacheData[0];
|
|||
|
(*splineKeyPtr->inPtr).param.scan.bottomClip = glyphPtr->yMin;
|
|||
|
(*splineKeyPtr->inPtr).param.scan.topClip = glyphPtr->yMax;
|
|||
|
#if TheFuture /* <18 > EBITMAP */
|
|||
|
if (result = fs_GetGlyphData( splineKeyPtr->inPtr, splineKeyPtr->outPtr )) {
|
|||
|
sb_Debug();
|
|||
|
*(uint32*) ((Ptr) cachePtr + glyphEntryOffset) |= ERROR_ENTRY_BIT;
|
|||
|
return result;
|
|||
|
}
|
|||
|
#endif
|
|||
|
#if !TheFuture /* <18 > EBITMAP */
|
|||
|
if (result = fs_ContourScan( splineKeyPtr->inPtr, splineKeyPtr->outPtr )) {
|
|||
|
sb_Debug();
|
|||
|
*(uint32*) ((Ptr) cachePtr + glyphEntryOffset) |= ERROR_ENTRY_BIT;
|
|||
|
return result;
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
if (!glyphPtr->clipVert) {
|
|||
|
sb_ShrinkBitmap( glyphDataPtr, (long *)glyphPtr->bitMapPtr, glyphPtr->yMax-glyphPtr->yMin);
|
|||
|
glyphPtr->byteWidth = glyphDataPtr->byteWidth;
|
|||
|
}
|
|||
|
glyphPtr->entryOffset = cacheDataOffset;
|
|||
|
return NO_ERR;
|
|||
|
|
|||
|
} /* End If */
|
|||
|
|
|||
|
MIN_MODE:
|
|||
|
return( sb_RenderGlyph(splineKey, widthTabHand, glyphPtr) );
|
|||
|
|
|||
|
} /* End sb_CheckCache */
|
|||
|
|
|||
|
/*********************************************************************************************
|
|||
|
** sb_RetrieveGlyph
|
|||
|
**
|
|||
|
** sb_RetrieveGlyph
|
|||
|
**
|
|||
|
**
|
|||
|
*/
|
|||
|
pascal long sb_RetrieveGlyph( widthTableHdl widthTabHand, sb_Glyph *glyphPtr )
|
|||
|
{
|
|||
|
sb_SplineKeyHdl splineKey = SPLINE_KEY_HAND;
|
|||
|
register sb_SplineKeyPtr splineKeyPtr = *splineKey;
|
|||
|
register widthTablePtr widTabPtr = *widthTabHand;
|
|||
|
short fontHandState = HGetState (widTabPtr->tabFont);
|
|||
|
short cacheHandState = HGetState ((Handle)splineKeyPtr->cacheHand); /* 15-CEL */
|
|||
|
long result;
|
|||
|
|
|||
|
#ifndef SYSTEM_7
|
|||
|
if (!splineKeyPtr->mfExists) /* If it's not already running, check */
|
|||
|
splineKeyPtr->mfExists = MultiFinderExist();
|
|||
|
#endif
|
|||
|
splineKeyPtr->glyphID = glyphPtr->glyphID; /* keep track in key which glyphid */
|
|||
|
|
|||
|
HNoPurge(widTabPtr->tabFont);
|
|||
|
HNoPurge((Handle)splineKeyPtr->cacheHand); /* 15-CEL */
|
|||
|
|
|||
|
if ((result = sb_CheckWorkHandle()) == MEM_ERR) {
|
|||
|
splineKeyPtr = *splineKey;
|
|||
|
if (!(result = sb_ShrinkCacheToMin(splineKeyPtr->cacheHand, 0)))
|
|||
|
result = sb_CheckWorkHandle();
|
|||
|
}
|
|||
|
if (!result) {
|
|||
|
HNoPurge(splineKeyPtr->fsWorkHand);
|
|||
|
|
|||
|
/* If banding in TrueType, don't AddGlyphOffset table more than once <KON Sakura2>*/
|
|||
|
if (!glyphPtr->nextBand)
|
|||
|
result = AddLowByteGlyphOffsetTable( glyphPtr->glyphID, splineKey );
|
|||
|
|
|||
|
if ( result == noErr ) {
|
|||
|
|
|||
|
result = sb_CheckCache( splineKey, widthTabHand, glyphPtr );
|
|||
|
if ((result == noErr) ||
|
|||
|
(result == NO_BITS)) // can be returned by sb_RenderGlyph for some reason
|
|||
|
// seems to only happen printing with the StyleWriter
|
|||
|
{
|
|||
|
|
|||
|
CheckForMaximumDiskCacheSize( (*splineKey)->cacheHand );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
HPurge((*splineKey)->fsWorkHand);
|
|||
|
}
|
|||
|
|
|||
|
HSetState((Handle)(*splineKey)->cacheHand, cacheHandState); /* 15-CEL */
|
|||
|
HSetState((*widthTabHand)->tabFont, fontHandState);
|
|||
|
return result;
|
|||
|
|
|||
|
|
|||
|
} /* End sb_RetrieveGlyph */
|
|||
|
|
|||
|
/****************************/
|
|||
|
/* END CALLS TO FONT SCALER */
|
|||
|
/****************************/
|
|||
|
/***************************************************************************************************/
|
|||
|
/***************************************************************************************************/
|