mac-rom/Toolbox/FontMgr/MapString.c
Elliot Nunn 4325cdcc78 Bring in CubeE sources
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included.

The Tools directory, containing mostly junk, is also excluded.
2017-12-26 09:52:23 +08:00

245 lines
6.5 KiB
C

/*
File: MapString.c
Contains: Character to glyph mapping functions
Written by: Mike Reed
Copyright: © 1991 by Apple Computer, Inc., all rights reserved.
Change History (most recent first):
<3> 9/25/91 jlf Rolled in fix to MapString2.
<2> 11/16/90 MR Fix range field of cmap-4 (thanks Eric) [rb]
<3> 9/27/90 MR Change selector in ComputeIndex4 to be log2(range) instead of
2*log2(range), and fixed up comments
<2> 8/10/90 MR Add textLength field to MapString2
<1> 7/23/90 MR first checked in
7/23/90 MR xxx put comment here xxx
To Do:
*/
#include "FSCDefs.h"
#include "MapString.h"
/*
* These next 4 MapString functions map the charCodes into glyphs,
* returning the number of glyphs processed.
*/
long MapString0(uint8* map, register uint8* charCodes, register int16* glyphs, long glyphCount)
{
register int16 count = glyphCount;
for (--count; count >= 0; --count)
*glyphs++ = map[*charCodes++];
return glyphCount;
}
/*
* High byte mapping through table
*
* Useful for the national standards for Japanese, Chinese, and Korean characters.
*
* Dedicated in spirit and logic to Mark Davis and the International group.
*
* Algorithm: (I think)
* First byte indexes into KeyOffset table. If the offset is 0, keep going, else use second byte.
* That offset is from beginning of data into subHeader, which has 4 words per entry.
* entry, extent, delta, range
*
* textLength is optional. If it is nil, it is ignored.
*/
long MapString2(register uint16* map, uint8* charCodes, int16* glyphs, long glyphCount, long* textLength)
{
register short count = glyphCount;
register uint8* codeP = charCodes;
register uint16 mapMe;
int16* origGlyphs = glyphs;
for (--count; count >= 0; --count)
{
uint16 *temporaryMap = map;
uint16 highByte = *codeP++;
if ( temporaryMap[highByte] != 0 )
mapMe = *codeP++;
else
mapMe = highByte;
if (textLength && *textLength < codeP - charCodes)
{
--codeP;
if ( temporaryMap[highByte] )
--codeP;
break;
}
temporaryMap = ((uint16*)((int8*)temporaryMap + temporaryMap[highByte])) + 256; /* <4> bad mapping */
mapMe -= *temporaryMap++; /* Subtract first code. */
if ( mapMe < *temporaryMap++ ) { /* See if within range. */
uint16 idDelta;
idDelta = *temporaryMap++;
mapMe += mapMe; /* turn into word offset */
temporaryMap = (uint16*)((int32)temporaryMap + *temporaryMap + mapMe );
if ( *temporaryMap )
*glyphs++ = *temporaryMap + idDelta;
else
*glyphs++ = 0; /* missing */
} else
*glyphs++ = 0; /* missing */ /* <4> bad mapping */
}
if (textLength)
*textLength = codeP - charCodes; /* report # bytes eaten */
return glyphs - origGlyphs; /* return # glyphs processed */
}
#define maxLinearX2 16
#define BinaryIteration \
newP = (uint16 *) ((int8 *)tableP + (range >>= 1)); \
if ( charCode > *newP ) tableP = newP;
/*
* Segment mapping to delta values, Yack.. !
*
* In memory of Peter Edberg. Initial code taken from code example supplied by Peter.
*/
static uint16 ComputeIndex4(uint16* tableP, uint16 charCode)
{
register uint16 idDelta;
register uint16 offset, segCountX2, index;
index = 0; /* assume missing initially */
segCountX2 = *tableP++;
if ( segCountX2 < maxLinearX2 ) {
tableP += 3; /* skip binary search parameters */
} else {
/* start with unrolled binary search */
register uint16 *newP;
register int16 range; /* size of current search range */
register uint16 selector; /* where to jump into unrolled binary search */
register uint16 shift; /* for shifting of range */
range = *tableP++; /* == 2*(2**floor(log2(segCount))) == 2*largest power of two <= segCount */
selector = *tableP++; /* == log2(range/2) */
shift = *tableP++; /* == 2*segCount-range */
/* tableP points at endCount[] */
if ( charCode >= *((uint16 *)((int8 *)tableP + range)))
tableP = (uint16 *) ((int8 *)tableP + shift); /* range to low shift it up */
switch ( selector )
{
case 15: BinaryIteration;
case 14: BinaryIteration;
case 13: BinaryIteration;
case 12: BinaryIteration;
case 11: BinaryIteration;
case 10: BinaryIteration;
case 9: BinaryIteration;
case 8: BinaryIteration;
case 7: BinaryIteration;
case 6: BinaryIteration;
case 5: BinaryIteration;
case 4: BinaryIteration;
case 3:
case 2: /* drop through */
case 1:
case 0:
break;
}
}
/* Now do linear search */
while ( charCode > *tableP++) /* goes one to far, so we can skip the reservedPad */
;
/* End of search, now do mapping */
tableP = (uint16 *) ((int8 *)tableP + segCountX2); /* point at startCount[] */
if ( charCode >= *tableP ) {
offset = charCode - *tableP;
tableP = (uint16 *) ((int8 *)tableP + segCountX2); /* point to idDelta[] */
idDelta = *tableP;
tableP = (uint16 *) ((int8 *)tableP + segCountX2); /* point to idRangeOffset[] */
if ( *tableP == 0 ) {
index = charCode + idDelta;
} else {
offset += offset; /* make word offset */
tableP = (uint16 *) ((int8 *)tableP + *tableP + offset ); /* point to glyphIndexArray[] */
if (index = *tableP)
index += idDelta;
}
}
return index;
}
long MapString4_8(uint16* map, uint8* charCodes, int16* glyphs, long glyphCount)
{
register short count = glyphCount;
for (--count; count >= 0; --count)
*glyphs++ = ComputeIndex4( map, *charCodes++ );
return glyphCount;
}
long MapString4_16(uint16* map, uint16* charCodes, int16* glyphs, long glyphCount)
{
register short count = glyphCount;
for (--count; count >= 0; --count)
*glyphs++ = ComputeIndex4( map, *charCodes++ );
return glyphCount << 1;
}
/*
* Trimmed Table Mapping - 8 bit character codes
*/
long MapString6_8(register uint16* map, uint8* charCodes, register int16* glyphs, long glyphCount)
{
register short count = glyphCount - 1;
uint16 firstCode = *map++;
uint16 entryCount = *map++;
int16* origGlyphs = glyphs;
for (; count >= 0; --count)
{
uint16 charCode = *charCodes++ - firstCode;
if ( charCode < entryCount )
*glyphs++ = map[ charCode ];
else
*glyphs++ = 0; /* missing char */
}
return glyphs - origGlyphs;
}
/*
* Trimmed Table Mapping - 16 bit character codes
*/
long MapString6_16(register uint16* map, uint16* charCodes, register int16* glyphs, long glyphCount)
{
register short count = glyphCount - 1;
uint16 firstCode = *map++;
uint16 entryCount = *map++;
int16* origGlyphs = glyphs;
for (; count >= 0; --count)
{
uint16 charCode = *charCodes++ - firstCode;
if ( charCode < entryCount )
*glyphs++ = map[ charCode ];
else
*glyphs++ = 0; /* missing char */
}
return glyphs - origGlyphs;
}