Ejemplo n.º 1
0
void	oldsetmacro(short n, char *s)			/* Set macro number <n> to the value of s */
{
	unsigned char	*p;
	short	num, pos, escape;
	short	len;
	OSErr 	memError;
	
	if (n<0  || n>9)
		return;

	// Restrict the maximum length of macros to MACRO_MAX_LEN bytes
	len = strlen(s)+1;
	if (len > (MACRO_MAX_LEN - 1)) {
		len = MACRO_MAX_LEN;
		s[MACRO_MAX_LEN - 1] = 0;
		}
	
	// If this is an empty string, remove whatever storage might have been used previously
	// by this macro.
	if (len == 1) {
		if (gMacros[n] != nil) {
			DisposeHandle(gMacros[n]);
			gMacros[n] = nil;
			}
		return;
		}
		
	// If neccessary, create storage for the macro
	if (gMacros[n] == nil) {
		gMacros[n] = myNewHandle(len);
		if (gMacros[n] == nil) {		// Memory error
			return;
			}
		}

	// Adjust the handle to the proper size (may be making an existing macro longer)
	memError = mySetHandleSize(gMacros[n], len);
	if (memError != noErr) {
		return;
		}
	
	HLock(gMacros[n]);
	p = (unsigned char *)*gMacros[n];

	num = 0;
	pos = 0;
	escape = 0;
	
	while ( *s) {
		if (escape) {
			escape = 0;
			switch (*s) {
				case 'i':
					if ( pos >0) {
						*p++=num;
						*p++=*s;
						pos=0;
						}
					*p++=MACRO_IP;
					break;
				case '#':
					if ( pos >0) {
						*p++=num;
						*p++=*s;
						pos=0;
						}
					*p++=MACRO_LINES;
					break;
				case 'n':
					if ( pos >0) {
						*p++=num;
						*p++=*s;
						pos=0;
						}
					*p++='\012';
					break;
				case 'r':
					if ( pos >0) {
						*p++=num;
						*p++=*s;
						pos=0;
						}
					*p++='\015';
					break;
				case 't':
					if ( pos >0) {
						*p++=num;
						*p++=*s;
						pos=0;
						}
					*p++='\t';
					break;
				case '"':
					if ( pos >0) {
						*p++=num;
						*p++=*s;
						pos=0;
						}
					*p++='\"';
					break;

						
				case '\\':
					if ( pos >0) {
						*p++=num;
						escape=1;
						pos=0;
						num=0;
						}
					else
						*p++='\\';
					break;
				default:
					if (*s <='9' && *s >='0' && pos <3) {
						num= num*8+( *s -'0');
						pos++;
						escape=1;
						}
					else {
						if (pos ==0 && num==0) {
							*p++='\\';
							*p++=*s;
							}
						else {
							*p++=num;
							pos= 0;
							s--;			/* back up the buffer. */
							}
						}
					break;
				}
			}
		else {
			if (*s=='\\') {
				num=0;
				pos=0;
				escape=1;
				}
			else
				*p++=*s;
			}
		s++;
		}

	if (pos >0) *p++=num;
	
	*p=0;
	
	// The resultant macro may be shorter than the input string due to escaped characters.
	// So, recalculate the length of the macro and resize than handle if neccessary.
	len = strlen(*gMacros[n])+1;
	
	HUnlock(gMacros[n]);
	mySetHandleSize(gMacros[n], len);
} /* setmacro */
Ejemplo n.º 2
0
// ****************************************************************************
//
//  Function Name:	RTrueTypeFont::GetGlyphOutline( )
//
//  Description:		
//
//  Returns:			Nothing
//
//  Exceptions:		Memory, Font
//
// ****************************************************************************
//
void RTrueTypeFont::GetGlyphOutline( Handle sfnt, long glyphIndex, GlyphOutline* pOutline, Matrix xform )
{
short 						state = GetFontState( sfnt );
short 						upem, sideBearing, adjustToLsb;
short* 						glyph;
sfnt_FontHeader* 			head;
sfnt_HorizontalHeader*	hhea;
sfnt_HorizontalMetrics*	hori;
long 							length;
long 							longMetrics;

	try
	{
		::HLock( sfnt );
		head = (sfnt_FontHeader *)GetSfntTablePtr( sfnt, tag_FontHeader );
		hhea = (sfnt_HorizontalHeader *)GetSfntTablePtr( sfnt, tag_HoriHeader );
		hori = (sfnt_HorizontalMetrics *)GetSfntTablePtr( sfnt, tag_HorizontalMetrics );
		if ( head == NULL || hhea == NULL || hori == NULL )
			throw fontNotOutlineErr;
	
		upem = head->unitsPerEm;
		longMetrics = hhea->numberLongMetrics;
		if ( glyphIndex < longMetrics )
		{	
			pOutline->advance.x = ::FixRatio( hori[glyphIndex].advance, upem );
			sideBearing = hori[glyphIndex].sideBearing;
		}
		else
		{	
			short *lsb = (short *)&hori[longMetrics]; 		// first entry after[AW,LSB] array 
			pOutline->advance.x = ::FixRatio( hori[longMetrics-1].advance, upem );
			sideBearing = hori[glyphIndex - longMetrics].sideBearing;
		}
		pOutline->advance.y = 0;
	
		pOutline->origin.x = pOutline->origin.y = 0;
	
		if ( (glyph = (short *)GetSfntGlyphPtr(sfnt, glyphIndex, &length)) == 0 )
			throw fontNotOutlineErr;
	
		if ( length == 0 )
		{	
			pOutline->contourCount = pOutline->pointCount = 0;
			SetFontState( sfnt, state );
			return;
		}
	
		pOutline->contourCount = *glyph++;
		adjustToLsb = *glyph - sideBearing;			// xmin - lsb 
		glyph += 4;											// skip bounds rect 
	
		if ( pOutline->contourCount == 0 )
			pOutline->pointCount = 0;
		else if ( pOutline->contourCount == -1 )
		{	
			short	flags, index, newMatrix;
			pOutline->contourCount = pOutline->pointCount = 0;
			mySetHandleSize( (Handle)pOutline->endPoints, 0 );
			mySetHandleSize( (Handle)pOutline->onCurve, 0 );
			mySetHandleSize( (Handle)pOutline->x, 0 );
			mySetHandleSize( (Handle)pOutline->y, 0 );
			do
			{	
				Matrix compXform;
				short arg1, arg2;
				
				flags = *glyph++;
				index = *glyph++;
				newMatrix = false;
	
				if ( flags & ARG_1_AND_2_ARE_WORDS )
				{	
					arg1 = *glyph++;
					arg2 = *glyph++;
				}
				else
				{	
					char* byteP = (char*)glyph;
					if ( flags & ARGS_ARE_XY_VALUES )
					{									// offsets are signed 
						arg1 = *byteP++;
						arg2 = *byteP;
					}
					else
					{									// anchor points are unsigned 
						arg1 = (unsigned char)*byteP++;
						arg2 = (unsigned char)*byteP;
					}
					++glyph;
				}
#if IMPLEMENT_SCALED_COMPONENTS
				if ( flags & (WE_HAVE_A_SCALE | WE_HAVE_AN_X_AND_Y_SCALE | WE_HAVE_A_TWO_BY_TWO) )
				{	
					Matrix subXform;
					MakeIdentityMatrix( subXform );
					if ( flags & WE_HAVE_A_TWO_BY_TWO )
					{	compXform[0][0] = (Fixed)*glyph++ << 2;
						compXform[0][1] = (Fixed)*glyph++ << 2;
						compXform[1][0] = (Fixed)*glyph++ << 2;
						compXform[1][1] = (Fixed)*glyph++ << 2;
					}
					else if ( flags & WE_HAVE_AN_X_AND_Y_SCALE )
					{	compXform[0][0] = (Fixed)*glyph++ << 2;
						compXform[1][1] = (Fixed)*glyph++ << 2;
					}
					else
						compXform[0][0] = compXform[1][1] = (Fixed)*glyph++ << 2;
					PostMulMatrix (compXform, xform );
					newMatrix = true;
				}
#endif			
				{	
					GlyphOutline out;
					InitGlyphOutline( &out );
					GetGlyphOutline( sfnt, index, &out, newMatrix ? compXform : xform );
					{	
						Fixed dx, dy;
						if ( flags & ARGS_ARE_XY_VALUES )
						{	dx = ::FixRatio(arg1, upem);
							dy = -::FixRatio(arg2, upem);
						}
						else
						{	
							dx = (*pOutline->x)[arg1] - (*out.x)[arg2];
							dy = (*pOutline->y)[arg1] - (*out.y)[arg2];
						}
						MoveGlyphOutline( &out, dx, dy );
					}
					AppendGlyphOutline( pOutline, &out );
					KillGlyphOutline( &out );
				}
			} while ( flags & MORE_COMPONENTS );
		}
		else if ( pOutline->contourCount > 0 )
		{																			//	Load in the end points.
			{	
				long size = pOutline->contourCount * sizeof(short);
	
				mySetHandleSize( (Handle)pOutline->endPoints, size );
				BlockMove( (Ptr)glyph, (Ptr)*pOutline->endPoints, size );
				glyph += pOutline->contourCount;
			}
	
			pOutline->pointCount = (*pOutline->endPoints)[pOutline->contourCount - 1] + 1;
			mySetHandleSize( (Handle)pOutline->onCurve, pOutline->pointCount * sizeof(char) );
			mySetHandleSize( (Handle)pOutline->x, pOutline->pointCount * sizeof(Fixed) );
			mySetHandleSize( (Handle)pOutline->y, pOutline->pointCount * sizeof(Fixed) );
	
			//	Skip the word for instruction count + the instructions.
			// Then load in the onCurve bytes.
			{	
				Byte* p = (Byte*)glyph + sizeof(short) + *glyph;
				Byte* onCurve = *pOutline->onCurve;
				Byte* stop = onCurve + pOutline->pointCount;
				Byte flag;
	
				while ( onCurve < stop )
				{	
					*onCurve++ = flag = GetUnsignedByte( p );
					if ( flag & REPEAT_FLAGS ) 
					{
						short count = GetUnsignedByte( p );
						for ( --count; count >= 0; --count )
							*onCurve++ = flag;
					}
				}
				//	Lets do X
				{	
					short coord = adjustToLsb;
					Fixed* x = *pOutline->x;
	
					onCurve = *pOutline->onCurve;
					while ( onCurve < stop )
					{	
						if ( (flag = *onCurve++) & XSHORT ) 
						{
							if ( flag & SHORT_X_IS_POS )
								coord += GetUnsignedByte( p );
							else
								coord -= GetUnsignedByte( p );
						}
						else if ( !(flag & NEXT_X_IS_ZERO) )
						{	
							coord += (short)(*p++) << 8;
							coord += (Byte)*p++;
						}
						*x = ::FixRatio( coord, upem );
						x++;
					}
				}
				//	Lets do Y
				{	
					short coord = 0;
					Fixed* y = *pOutline->y;
	
					onCurve = *pOutline->onCurve;
					while ( onCurve < stop )
					{	
						if ( (flag = *onCurve) & YSHORT ) 
						{
							if ( flag & SHORT_Y_IS_POS )
								coord += GetUnsignedByte( p );
							else
								coord -= GetUnsignedByte( p );
						}
						else if ( !(flag & NEXT_Y_IS_ZERO) )
						{	
							coord += (short)(*p++) << 8;
							coord += (Byte)*p++;
						}
						*y = -::FixRatio( coord, upem );
						y++;
						
						//	Filter off the extra bits
						*onCurve++ = flag & ONCURVE;
					}
				}
			}
		}
		else
			throw fontNotOutlineErr;
	}
	catch ( OSErr osErr )
	{
		SetFontState( sfnt, state );
		switch ( osErr ) 
		{
			case memFullErr :																// out of memeory
				SetFontState( sfnt, state );
				throw kMemory;
				break;
			case fontNotOutlineErr :		 											// bad font
				SetFontState( sfnt, state );
				throw kResource;
				break;
			default:
				TpsAssertAlways( "Bad exception" ); 
				throw;
				break;
		}
	}
	catch ( ... )
	{
		SetFontState( sfnt, state );
		throw;
	}

	SetFontState( sfnt, state );
}