void CCharShape::RefreshNode (int idx) { if (idx < 0 || idx >= numNodes) return; //TMatrix TempMatrix; char caxis; double angle; TCharNode *node = Nodes[idx]; TCharAction *act = Actions[idx]; if (act == NULL) return; if (act->num < 1) return; MakeIdentityMatrix (node->trans); MakeIdentityMatrix (node->invtrans); int type; TVector3 vec; double dval; for (int i=0; i<act->num; i++) { type = act->type[i]; vec = act->vec[i]; dval = act->dval[i]; switch (type) { case 0: MultiplyTranslationMatrices (node->trans, node->invtrans, vec.x, vec.y, vec.z); break; case 1: caxis = 'x'; angle = dval; MultiplyRotationMatrices (node->trans, node->invtrans, angle, caxis); break; case 2: caxis = 'y'; angle = dval; MultiplyRotationMatrices (node->trans, node->invtrans, angle, caxis); break; case 3: caxis = 'z'; angle = dval; MultiplyRotationMatrices (node->trans, node->invtrans, angle, caxis); break; case 4: //MakeIdentityMatrix (TempMatrix); //MultiplyMatrices (node->trans, node->trans, TempMatrix); //MakeIdentityMatrix (TempMatrix); //MultiplyMatrices (node->invtrans, TempMatrix, node->invtrans); MultiplyScalingMatrices (node->trans, node->invtrans, vec.x, vec.y, vec.z); //MakeIdentityMatrix (TempMatrix); //MultiplyMatrices (node->trans, node->trans, TempMatrix); //MakeIdentityMatrix (TempMatrix); //MultiplyMatrices (node->invtrans, TempMatrix, node->invtrans); break; case 5: VisibleNode (node->node_name, dval); break; default: break; } } }
bool CCharShape::ResetNode (size_t node_name) { TCharNode *node = GetNode(node_name); if (node == NULL) return false; MakeIdentityMatrix (node->trans); MakeIdentityMatrix (node->invtrans); return true; }
bool CCharShape::ResetNode (int node_name) { TCharNode *node; if (GetNode (node_name, &node) == false) return false; MakeIdentityMatrix (node->trans); MakeIdentityMatrix (node->invtrans); return true; }
bool CCharShape::CheckCollision (const TPolyhedron& ph) { TMatrix mat, invmat; MakeIdentityMatrix (mat); MakeIdentityMatrix (invmat); TCharNode *node = GetNode(0); if (node == NULL) return false; return CheckPolyhedronCollision (node, mat, invmat, ph); }
bool CCharShape::CheckCollision (TPolyhedron ph) { TCharNode *node; TMatrix mat, invmat; MakeIdentityMatrix (mat); MakeIdentityMatrix (invmat); if (GetNode (0, &node) == false) return false; return CheckPolyhedronCollision (node, mat, invmat, ph); }
bool CCharShape::CreateCharNode (int parent_name, size_t node_name, const string& joint, const string& name, const string& order, bool shadow) { TCharNode *parent = GetNode (parent_name); if (parent == NULL) { Message ("wrong parent node"); return false; } TCharNode *node = new TCharNode; node->node_name = node_name; node->parent = parent; node->parent_name = parent_name; node->next = NULL; node->next_name = 99; node->child = NULL; node->child_name = 99; if (useActions) { node->action = new TCharAction; node->action->num = 0; node->action->name = name; node->action->order = order; node->action->mat = ""; } else node->action = NULL; node->mat = NULL; node->node_idx = numNodes; node->visible = false; node->render_shadow = shadow; node->joint = joint; MakeIdentityMatrix (node->trans); MakeIdentityMatrix (node->invtrans); if (!joint.empty()) NodeIndex[joint] = node_name; Nodes[numNodes] = node; Index[node_name] = numNodes; /// ------------------------------------------------------------------- if (parent->child == NULL) { parent->child = node; parent->child_name = node_name; } else { for (parent = parent->child; parent->next != NULL; parent = parent->next) {} parent->next = node; parent->next_name = node_name; } /// ------------------------------------------------------------------- numNodes++; return true; }
bool CCharShape::CreateCharNode (int parent_name, int node_name, const string joint, string name, string order, bool shadow) { TCharNode *parent = GetNode (parent_name); if (parent == NULL) { Message ("wrong parent node"); return false; } TCharNode *node = new TCharNode; node->node_name = node_name; node->parent = parent; node->parent_name = parent_name; node->next = NULL; node->next_name = 99; node->child = NULL; node->child_name = 99; node->mat = NULL; node->node_idx = numNodes; node->visible = false; node->render_shadow = shadow; node->joint = joint; MakeIdentityMatrix (node->trans); MakeIdentityMatrix (node->invtrans); if (joint.size() > 0) SPAddIntN (NodeIndex, joint, node_name); Nodes[numNodes] = node; Index[node_name] = numNodes; /// ------------------------------------------------------------------- if (parent->child == NULL) { parent->child = node; parent->child_name = node_name; } else { for (parent = parent->child; parent->next != NULL; parent = parent->next) {} parent->next = node; parent->next_name = node_name; } /// ------------------------------------------------------------------- if (useActions) { Actions[numNodes] = new TCharAction; Actions[numNodes]->num = 0; Actions[numNodes]->name = name; Actions[numNodes]->order = order; Actions[numNodes]->mat = ""; } numNodes++; return true; }
void RotateAboutVectorMatrix (TMatrix mat, TVector3 u, double angle) { TMatrix rx, irx, ry, iry; double a, b, c, d; a = u.x; b = u.y; c = u.z; d = sqrt (b*b + c*c); if (d < EPS) { if (a < 0) MakeRotationMatrix (mat, -angle, 'x'); else MakeRotationMatrix (mat, angle, 'x'); return; } MakeIdentityMatrix (rx); MakeIdentityMatrix (irx); MakeIdentityMatrix (ry); MakeIdentityMatrix (iry); rx[1][1] = c/d; rx[2][1] = -b/d; rx[1][2] = b/d; rx[2][2] = c/d; irx[1][1] = c/d; irx[2][1] = b/d; irx[1][2] = -b/d; irx[2][2] = c/d; ry[0][0] = d; ry[2][0] = -a; ry[0][2] = a; ry[2][2] = d; iry[0][0] = d; iry[2][0] = a; iry[0][2] = -a; iry[2][2] = d; MakeRotationMatrix (mat, angle, 'z'); MultiplyMatrices (mat, mat, ry); MultiplyMatrices (mat, mat, rx); MultiplyMatrices (mat, iry, mat); MultiplyMatrices (mat, irx, mat); }
void MakeRotationMatrix (TMatrix mat, double angle, char axis) { double sinv, cosv; sinv = sin (ANGLES_TO_RADIANS (angle)); cosv = cos (ANGLES_TO_RADIANS (angle)); MakeIdentityMatrix (mat); switch (axis) { case 'x': mat[1][1] = cosv; mat[2][1] = -sinv; mat[1][2] = sinv; mat[2][2] = cosv; break; case 'y': mat[0][0] = cosv; mat[2][0] = sinv; mat[0][2] = -sinv; mat[2][2] = cosv; break; case 'z': mat[0][0] = cosv; mat[1][0] = -sinv; mat[0][1] = sinv; mat[1][1] = cosv; break; } }
void MakeBasisMat (TMatrix mat, const TVector3& w1, const TVector3& w2, const TVector3& w3) { MakeIdentityMatrix (mat); mat[0][0] = w1.x; mat[0][1] = w1.y; mat[0][2] = w1.z; mat[1][0] = w2.x; mat[1][1] = w2.y; mat[1][2] = w2.z; mat[2][0] = w3.x; mat[2][1] = w3.y; mat[2][2] = w3.z; }
void CCharShape::CreateRootNode () { TCharNode *node = new TCharNode; node->node_name = 0; node->parent = NULL; node->parent_name = 99; node->next = NULL; node->next_name = 99; node->child = NULL; node->child_name = 99; node->mat = NULL; node->joint = "root"; node->render_shadow = false; node->visible = false; MakeIdentityMatrix (node->trans); MakeIdentityMatrix (node->invtrans); NodeIndex = "[root]0"; Index[0] = 0; Nodes[0] = node; numNodes = 1; }
void CCharShape::ScaleNode (size_t node_name, const TVector3& vec) { TCharNode *node = GetNode(node_name); if (node == NULL) return; TMatrix matrix; MakeIdentityMatrix (matrix); MultiplyMatrices (node->trans, node->trans, matrix); MakeIdentityMatrix (matrix); MultiplyMatrices (node->invtrans, matrix, node->invtrans); MakeScalingMatrix (matrix, vec.x, vec.y, vec.z); MultiplyMatrices (node->trans, node->trans, matrix); MakeScalingMatrix (matrix, 1.0 / vec.x, 1.0 / vec.y, 1.0 / vec.z); MultiplyMatrices (node->invtrans, matrix, node->invtrans); MakeIdentityMatrix (matrix); MultiplyMatrices (node->trans, node->trans, matrix); MakeIdentityMatrix (matrix); MultiplyMatrices (node->invtrans, matrix, node->invtrans); if (newActions && useActions) AddAction (node_name, 4, vec, 0); }
void MakeBasismatrix_Inv (TMatrix mat, TMatrix invMat, const TVector3& w1, const TVector3& w2, const TVector3& w3) { MakeIdentityMatrix (mat); mat[0][0] = w1.x; mat[0][1] = w1.y; mat[0][2] = w1.z; mat[1][0] = w2.x; mat[1][1] = w2.y; mat[1][2] = w2.z; mat[2][0] = w3.x; mat[2][1] = w3.y; mat[2][2] = w3.z; MakeIdentityMatrix (invMat); invMat[0][0] = w1.x; invMat[1][0] = w1.y; invMat[2][0] = w1.z; invMat[0][1] = w2.x; invMat[1][1] = w2.y; invMat[2][1] = w2.z; invMat[0][2] = w3.x; invMat[1][2] = w3.y; invMat[2][2] = w3.z; }
void CCharShape::DrawShadow () { TMatrix model_matrix; if (g_game.light_id == 1 || g_game.light_id == 3) return; ScopedRenderMode rm(TUX_SHADOW); glColor4f (shad_col.r, shad_col.g, shad_col.b, shad_col.a); MakeIdentityMatrix (model_matrix); TCharNode *node = GetNode(0); if (node == NULL) { Message ("couldn't find tux's root node", ""); return; } TraverseDagForShadow (node, model_matrix); }
void CCharShape::DrawShadow () { TMatrix model_matrix; TCharNode *node; if (g_game.light_id == 1 || g_game.light_id == 3) return; set_gl_options (TUX_SHADOW); glColor4f (shad_col.r, shad_col.g, shad_col.b, shad_col.a); MakeIdentityMatrix (model_matrix); if (GetNode (0, &node) == false) { Message ("couldn't find tux's root node", ""); return; } TraverseDagForShadow (node, model_matrix); }
void MakeScalingMatrix (TMatrix mat, double x, double y, double z) { MakeIdentityMatrix (mat); mat[0][0] = x; mat[1][1] = y; mat[2][2] = z; }
void MakeTranslationMatrix (TMatrix mat, double x, double y, double z) { MakeIdentityMatrix (mat); mat[3][0] = x; mat[3][1] = y; mat[3][2] = z; }
void CCharShape::RefreshNode (size_t idx) { if (idx >= numNodes) return; TMatrix TempMatrix; char caxis; double angle; TCharNode *node = Nodes[idx]; TCharAction *act = node->action; if (act == NULL) return; if (act->num < 1) return; MakeIdentityMatrix (node->trans); MakeIdentityMatrix (node->invtrans); for (size_t i=0; i<act->num; i++) { int type = act->type[i]; const TVector3& vec = act->vec[i]; double dval = act->dval[i]; switch (type) { case 0: MakeTranslationMatrix (TempMatrix, vec.x, vec.y, vec.z); MultiplyMatrices (node->trans, node->trans, TempMatrix); MakeTranslationMatrix (TempMatrix, -vec.x, -vec.y, -vec.z); MultiplyMatrices (node->invtrans, TempMatrix, node->invtrans); break; case 1: caxis = 'x'; angle = dval; MakeRotationMatrix (TempMatrix, angle, caxis); MultiplyMatrices (node->trans, node->trans, TempMatrix); MakeRotationMatrix (TempMatrix, -angle, caxis); MultiplyMatrices (node->invtrans, TempMatrix, node->invtrans); break; case 2: caxis = 'y'; angle = dval; MakeRotationMatrix (TempMatrix, angle, caxis); MultiplyMatrices (node->trans, node->trans, TempMatrix); MakeRotationMatrix (TempMatrix, -angle, caxis); MultiplyMatrices (node->invtrans, TempMatrix, node->invtrans); break; case 3: caxis = 'z'; angle = dval; MakeRotationMatrix (TempMatrix, angle, caxis); MultiplyMatrices (node->trans, node->trans, TempMatrix); MakeRotationMatrix (TempMatrix, -angle, caxis); MultiplyMatrices (node->invtrans, TempMatrix, node->invtrans); break; case 4: MakeIdentityMatrix (TempMatrix); MultiplyMatrices (node->trans, node->trans, TempMatrix); MakeIdentityMatrix (TempMatrix); MultiplyMatrices (node->invtrans, TempMatrix, node->invtrans); MakeScalingMatrix (TempMatrix, vec.x, vec.y, vec.z); MultiplyMatrices (node->trans, node->trans, TempMatrix); MakeScalingMatrix (TempMatrix, 1.0 / vec.x, 1.0 / vec.y, 1.0 / vec.z); MultiplyMatrices (node->invtrans, TempMatrix, node->invtrans); MakeIdentityMatrix (TempMatrix); MultiplyMatrices (node->trans, node->trans, TempMatrix); MakeIdentityMatrix (TempMatrix); MultiplyMatrices (node->invtrans, TempMatrix, node->invtrans); break; case 5: VisibleNode (node->node_name, dval); break; default: break; } } }
// **************************************************************************** // // Function Name: RTrueTypeFont::ExtractCharacterOutline( ) // // Description: Retrieve a glyph outline and parse it into segment records // in the global buffer // // Returns: Boolean indicating successful completion // // Exceptions: Memory // // **************************************************************************** // BOOLEAN RTrueTypeFont::ExtractCharacterOutline( int character, uLONG cookie ) { YTTSegmentInfoRecord* pSegments = (YTTSegmentInfoRecord *)( cookie + sizeof(uLONG) ); const YFontInfo fontInfo = GetInfo(); GlyphOutline glyph; Matrix matrix; long glyphIndex = 0; // zero is the missing character // retrieve font resource if ( m_hSfnt == NULL ) { short rId; ResType rType; Str255 rName; m_hSfnt = GetSfntHandle( (const LPSZ)fontInfo.sbName, RFont::GetMacStyleBits( fontInfo.attributes ) ); GetResInfo( m_hSfnt, &rId, &rType, rName); m_sSfntId = rId; } else if ( *m_hSfnt == NULL ) { ::LoadResource( m_hSfnt ); // m_hSfnt = ::GetResource( 'sfnt', m_sSfntId ); } if ( m_hSfnt == NULL || *m_hSfnt == NULL ) return FALSE; ::HNoPurge( m_hSfnt ); // extract character outline InitMatrix( matrix ); InitGlyphOutline( &glyph ); MakeIdentityMatrix( matrix ); try { glyphIndex = GetCharGlyphIndex( m_hSfnt, character ); GetGlyphOutline( m_hSfnt, glyphIndex, &glyph, matrix ); ScaleGlyphOutline( &glyph, ::Long2Fix( fontInfo.height ), ::Long2Fix( fontInfo.height ) ); } catch ( YException except ) { ::HPurge( m_hSfnt ); KillGlyphOutline( &glyph ); switch ( except ) { case kResource: return FALSE; break; default: throw; break; } } catch ( ... ) { ::HPurge( m_hSfnt ); KillGlyphOutline( &glyph ); throw; } // loop thru the contours LockGlyphOutline( &glyph ); { long nrSegments = 0; long sp = 0; Fixed* x = *glyph.x; Fixed* y = *glyph.y; short* ep = *glyph.endPoints; Byte* onCurve = *glyph.onCurve; RIntPoint ptStart; for ( int i = 0; i < glyph.contourCount; i++ ) { long pts = *ep - sp + 1; // nr pts in contour // contour start point if ( *onCurve != 0 ) // 1st point on curve { ptStart.m_x = RoundFixed( *x ); ptStart.m_y = -RoundFixed( *y ); x++; y++; onCurve++; pts--; } else if ( *((*glyph.onCurve) + *ep) != 0 ) // use end point { ptStart.m_x = RoundFixed( *((*glyph.x) + *ep) ); ptStart.m_y = -RoundFixed( *((*glyph.y) + *ep) ); } else // compute midpoint between 1st and last curve points { Fixed x2 = ::FixDiv( (*x + *((*glyph.x) + *ep)), ::Long2Fix( 2 ) ); Fixed y2 = ::FixDiv( (*y + *((*glyph.y) + *ep)), ::Long2Fix( 2 ) ); ptStart.m_x = RoundFixed( x2 ); ptStart.m_y = -RoundFixed( y2 ); } // initial move to pSegments->opCode = MOVE_TO; pSegments->pt1 = ptStart; nrSegments++; pSegments++; // load segments of contour while ( pts-- > 0 ) { Fixed x0 = *x; Fixed y0 = *y; Byte onCurve0 = *onCurve; x++; y++; onCurve++; pSegments->pt1.m_x = RoundFixed( x0 ); pSegments->pt1.m_y = -RoundFixed( y0 ); if ( onCurve0 != 0 ) pSegments->opCode = LINE_TO; else if ( pts < 1 ) // quadratic w/ contour start point as end { pSegments->opCode = QUADRATIC_TO; pSegments->pt2 = ptStart; } else if ( *onCurve != 0 ) // quadratic w/ end point next line to { pSegments->opCode = QUADRATIC_TO; pSegments->pt2.m_x = RoundFixed( *x ); pSegments->pt2.m_y = -RoundFixed( *y ); x++; y++; onCurve++; pts--; } else // compute end point of quadratic as midpoint to next curve { Fixed x2 = ::FixDiv( (x0 + *x), ::Long2Fix( 2 ) ); Fixed y2 = ::FixDiv( (y0 + *y), ::Long2Fix( 2 ) ); pSegments->opCode = QUADRATIC_TO; pSegments->pt2.m_x = RoundFixed( x2 ); pSegments->pt2.m_y = -RoundFixed( y2 ); } nrSegments++; pSegments++; } pSegments->opCode = CLOSE_PATH; // end of contour pSegments->pt1.m_x = pSegments->pt2.m_x = 0; pSegments->pt1.m_y = pSegments->pt2.m_y = 0; nrSegments++; pSegments++; sp = *ep++ + 1; } pSegments->opCode = 0; // end of glyph pSegments->pt1.m_x = pSegments->pt2.m_x = 0; pSegments->pt1.m_y = pSegments->pt2.m_y = 0; *(uLONG *)cookie = nrSegments; } UnlockGlyphOutline( &glyph ); // cleanup ::HPurge( m_hSfnt ); KillGlyphOutline( &glyph ); return TRUE; }
// **************************************************************************** // // 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 ); }