Technical Q&As
Changing Size of sfnt
Cache (12-April-98)
Q
I'm experiencing problems with some of my big sfnt
fonts (> 128k).
Text in these fonts often gets rendered in Geneva, or not at all. Do you
know something about this?
A
Yes, unfortunately. If a sfnt
resource is bigger than 128k, the
FontManager does not load it entirely, but only in pieces (as required by
the TrueType scaler) via ReadPartialResource
calls. For performance
reasons, the TrueType scaler uses a cache for the font fragments, which
gets allocated in the System heap at boot time. Before MacOS 8.0, the
cache size was 10k, which appeared to be enough for the TrueType fonts
known at the time when the cache size was determined (and when TrueType
fonts wanted to be supported on Macintoshes with 2MB of RAM). Meanwhile,
sfnt
fonts became more sophisticated, and their tables bigger and bigger,
and 10k just is not enough any more. Since MacOS 8.0, the cache size is
48k; but this still may not be enough for very special fonts (e.g.,
sfnts
for 2-byte scripts, when WorldScript II is not installed).
Fortunately, there is a way to fix the problem and change the size of
the sfnt
fragment cache. Ideally, this should happen as soon as possible
at system startup; so you may want to use the code below inside a little
extension that does the work.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// File: FontFix.c
//
// Calls InitializePartialFonts() with a more reasonable size.
//
// kMinimalPartialFontZoneSize in the system used to be 10 * 1024,
// which is not enough.
// On a system where the PartialFontZone already is big enough,
// InitializePartialFonts() doesn't do anything.
// Only if the existing PartialFontZone is smaller than our new
// kMinimalPartialFontZoneSize (or if there is none), the InitializePartialFonts
// routine allocates and initializes a new one, and properly disposes
// of the previous one (if there was one).
#include <Types.h>
#include <ConditionalMacros.h>
#include <Resources.h>
enum { kMinimalPartialFontZoneSize = 0x0000C000, // 48K
kMaximalPartialFontZoneSize = 0x00080000 // 512K
};
extern pascal OSErr InitializePartialFonts (UInt32 partialFontZoneSize)
THREEWORDINLINE(0x303C, 0x000F, 0xA854);
//-------------------------------------------
void main(void)
{
UInt32 size = kMinimalPartialFontZoneSize; // default
Handle h;
// Debugger();
h = GetResource('pfcs', 0);
if (h != NULL)
{
size = **(UInt32**)h;
if (size < kMinimalPartialFontZoneSize)
size = kMinimalPartialFontZoneSize;
else if (size > kMaximalPartialFontZoneSize)
size = kMaximalPartialFontZoneSize;
}
(void)InitializePartialFonts(size);
}
-- Ingrid Kelly
Worldwide Developer Technical Support
Technical Q&As
Previous Question | Contents | Next Question
To contact us, please use the Contact Us page.