TT_Error Instance_Reset( PInstance ins, Bool debug ) { TT_Error error; Int i; PFace face; PExecution_Context exec; if ( !ins ) return TT_Err_Invalid_Instance_Handle; if ( ins->valid ) return TT_Err_Ok; face = ins->face; exec = face->font->exec; if ( ins->metrics.x_ppem < 1 || ins->metrics.y_ppem < 1 ) return TT_Err_Invalid_PPem; /* compute new transformation */ if ( ins->metrics.x_ppem >= ins->metrics.y_ppem ) { ins->metrics.scale1 = ins->metrics.x_scale1; ins->metrics.scale2 = ins->metrics.x_scale2; ins->metrics.ppem = ins->metrics.x_ppem; ins->metrics.x_ratio = 1 << 16; ins->metrics.y_ratio = MulDiv_Round( ins->metrics.y_ppem, 0x10000, ins->metrics.x_ppem ); } else { ins->metrics.scale1 = ins->metrics.y_scale1; ins->metrics.scale2 = ins->metrics.y_scale2; ins->metrics.ppem = ins->metrics.y_ppem; ins->metrics.x_ratio = MulDiv_Round( ins->metrics.x_ppem, 0x10000, ins->metrics.y_ppem ); ins->metrics.y_ratio = 1 << 16; } /* Scale the cvt values to the new ppem. */ /* We use by default the y ppem to scale the CVT. */ for ( i = 0; i < ins->cvtSize; i++ ) ins->cvt[i] = MulDiv_Round( face->cvt[i], ins->metrics.scale1, ins->metrics.scale2 ); ins->GS = Default_GraphicsState; /* get execution context and run prep program */ Context_Load( exec, ins ); Set_CodeRange( exec, TT_CodeRange_Cvt, face->cvtProgram, face->cvtPgmSize ); Clear_CodeRange( exec, TT_CodeRange_Glyph ); for ( i = 0; i < exec->storeSize; i++ ) exec->storage[i] = 0; exec->instruction_trap = FALSE; exec->top = 0; exec->callTop = 0; /* All twilight points are originally zero */ for ( i = 0; i < exec->twilight.n_points; i++ ) { exec->twilight.org_x[i] = 0; exec->twilight.org_y[i] = 0; exec->twilight.cur_x[i] = 0; exec->twilight.cur_y[i] = 0; } if ( face->cvtPgmSize > 0 ) { error = Goto_CodeRange( exec, TT_CodeRange_Cvt, 0 ); if (error) goto Fin; error = RunIns( exec ); Unset_CodeRange(exec); } else error = TT_Err_Ok; ins->GS = exec->GS; /* save default graphics state */ Fin: Context_Save( exec, ins ); if ( !error ) ins->valid = TRUE; return error; }
static TT_Error Load_Composite_End( UShort n_points, Short n_contours, PExecution_Context exec, PSubglyph_Record subg, UShort load_flags, TT_Stream input ) { DEFINE_LOAD_LOCALS( input ); UShort k, n_ins; PGlyph_Zone pts; if ( subg->is_hinted && subg->element_flag & WE_HAVE_INSTR ) { if ( ACCESS_Frame( 2L ) ) return error; n_ins = GET_UShort(); /* read size of instructions */ FORGET_Frame(); PTRACE4(( " Instructions size: %d\n", n_ins )); if ( n_ins > exec->face->maxProfile.maxSizeOfInstructions ) { PTRACE0(( "ERROR: Too many instructions in composite glyph %ld\n", subg->index )); return TT_Err_Too_Many_Ins; } if ( FILE_Read( exec->glyphIns, n_ins ) ) return error; error = Set_CodeRange( exec, TT_CodeRange_Glyph, exec->glyphIns, n_ins ); if ( error ) return error; } else n_ins = 0; /* prepare the execution context */ n_points += 2; exec->pts = subg->zone; pts = &exec->pts; pts->n_points = n_points; pts->n_contours = n_contours; /* add phantom points */ pts->cur[n_points - 2] = subg->pp1; pts->cur[n_points - 1] = subg->pp2; pts->touch[n_points - 1] = 0; pts->touch[n_points - 2] = 0; /* if hinting, round the phantom points */ if ( subg->is_hinted ) { pts->cur[n_points - 2].x = (subg->pp1.x + 32) & -64; pts->cur[n_points - 1].x = (subg->pp2.x + 32) & -64; } for ( k = 0; k < n_points; k++ ) pts->touch[k] &= TT_Flag_On_Curve; cur_to_org( n_points, pts ); /* now consider hinting */ if ( subg->is_hinted && n_ins > 0 ) { exec->is_composite = TRUE; exec->pedantic_hinting = load_flags & TTLOAD_PEDANTIC; error = Context_Run( exec, FALSE ); if (error && exec->pedantic_hinting) return error; } /* save glyph origin and advance points */ subg->pp1 = pts->cur[n_points - 2]; subg->pp2 = pts->cur[n_points - 1]; return TT_Err_Ok; }
TT_Error Instance_Init( PInstance ins ) { PExecution_Context exec; TT_Error error; PFace face = ins->face; exec = ins->face->font->exec; /* debugging instances have their own context */ ins->GS = Default_GraphicsState; Context_Load( exec, ins ); exec->callTop = 0; exec->top = 0; exec->period = 64; exec->phase = 0; exec->threshold = 0; exec->metrics.x_ppem = 0; exec->metrics.y_ppem = 0; exec->metrics.pointSize = 0; exec->metrics.x_scale1 = 0; exec->metrics.x_scale2 = 1; exec->metrics.y_scale1 = 0; exec->metrics.y_scale2 = 1; exec->metrics.ppem = 0; exec->metrics.scale1 = 0; exec->metrics.scale2 = 1; exec->metrics.ratio = 1 << 16; exec->instruction_trap = FALSE; exec->cvtSize = ins->cvtSize; exec->cvt = ins->cvt; exec->F_dot_P = 0x10000; /* allow font program execution */ Set_CodeRange( exec, TT_CodeRange_Font, face->fontProgram, face->fontPgmSize ); /* disable CVT and glyph programs coderange */ Clear_CodeRange( exec, TT_CodeRange_Cvt ); Clear_CodeRange( exec, TT_CodeRange_Glyph ); if ( face->fontPgmSize > 0 ) { error = Goto_CodeRange( exec, TT_CodeRange_Font, 0 ); if ( error ) goto Fin; error = RunIns( exec ); Unset_CodeRange(exec); } else error = TT_Err_Ok; Fin: Context_Save( exec, ins ); ins->valid = FALSE; return error; }
static TT_Error Load_Simple_Glyph( PExecution_Context exec, TT_Stream input, Short n_contours, Short left_contours, UShort left_points, UShort load_flags, PSubglyph_Record subg ) { DEFINE_LOAD_LOCALS( input ); PGlyph_Zone pts; Short k; UShort j; UShort n_points, n_ins; PFace face; Byte* flag; TT_Vector* vec; TT_F26Dot6 x, y; face = exec->face; /* simple check */ if ( n_contours > left_contours ) { PTRACE0(( "ERROR: Glyph index %ld has %d contours > left %d\n", subg->index, n_contours, left_contours )); return TT_Err_Too_Many_Contours; } /* preparing the execution context */ mount_zone( &subg->zone, &exec->pts ); /* reading the contours endpoints */ if ( ACCESS_Frame( (n_contours + 1) * 2L ) ) return error; PTRACE4(( " Contour endpoints:" )); for ( k = 0; k < n_contours; k++ ) { exec->pts.contours[k] = GET_UShort(); PTRACE4(( " %d", exec->pts.contours[k] )); } PTRACE4(( "\n" )); if ( n_contours > 0 ) n_points = exec->pts.contours[n_contours - 1] + 1; else n_points = 0; n_ins = GET_UShort(); FORGET_Frame(); if ( n_points > left_points ) { PTRACE0(( "ERROR: Too many points in glyph %ld\n", subg->index )); return TT_Err_Too_Many_Points; } /* loading instructions */ PTRACE4(( " Instructions size: %d\n", n_ins )); if ( n_ins > face->maxProfile.maxSizeOfInstructions ) { PTRACE0(( "ERROR: Too many instructions!\n" )); return TT_Err_Too_Many_Ins; } if ( FILE_Read( exec->glyphIns, n_ins ) ) return error; if ( (error = Set_CodeRange( exec, TT_CodeRange_Glyph, exec->glyphIns, n_ins )) != TT_Err_Ok ) return error; /* read the flags */ if ( CHECK_AND_ACCESS_Frame( n_points * 5L ) ) return error; j = 0; flag = exec->pts.touch; while ( j < n_points ) { Byte c, cnt; flag[j] = c = GET_Byte(); j++; if ( c & 8 ) { cnt = GET_Byte(); while( cnt > 0 ) { flag[j++] = c; cnt--; } } } /* read the X */ x = 0; vec = exec->pts.org; for ( j = 0; j < n_points; j++ ) { if ( flag[j] & 2 ) { if ( flag[j] & 16 ) x += GET_Byte(); else x -= GET_Byte(); } else { if ( (flag[j] & 16) == 0 ) x += GET_Short(); } vec[j].x = x; } /* read the Y */ y = 0; for ( j = 0; j < n_points; j++ ) { if ( flag[j] & 4 ) { if ( flag[j] & 32 ) y += GET_Byte(); else y -= GET_Byte(); } else { if ( (flag[j] & 32) == 0 ) y += GET_Short(); } vec[j].y = y; } FORGET_Frame(); /* Now add the two shadow points at n and n + 1. */ /* We need the left side bearing and advance width. */ /* pp1 = xMin - lsb */ vec[n_points].x = subg->metrics.bbox.xMin - subg->metrics.horiBearingX; vec[n_points].y = 0; /* pp2 = pp1 + aw */ vec[n_points+1].x = vec[n_points].x + subg->metrics.horiAdvance; vec[n_points+1].y = 0; /* clear the touch flags */ for ( j = 0; j < n_points; j++ ) exec->pts.touch[j] &= TT_Flag_On_Curve; exec->pts.touch[n_points ] = 0; exec->pts.touch[n_points + 1] = 0; /* Note that we return two more points that are not */ /* part of the glyph outline. */ n_points += 2; /* now eventually scale and hint the glyph */ pts = &exec->pts; pts->n_points = n_points; pts->n_contours = n_contours; if ( (load_flags & TTLOAD_SCALE_GLYPH) == 0 ) { /* no scaling, just copy the orig arrays into the cur ones */ org_to_cur( n_points, pts ); } else { /* first scale the glyph points */ for ( j = 0; j < n_points; j++ ) { pts->org[j].x = Scale_X( &exec->metrics, pts->org[j].x ); pts->org[j].y = Scale_Y( &exec->metrics, pts->org[j].y ); } /* if hinting, round pp1, and shift the glyph accordingly */ if ( subg->is_hinted ) { x = pts->org[n_points - 2].x; x = ((x+32) & -64) - x; translate_array( n_points, pts->org, x, 0 ); org_to_cur( n_points, pts ); pts->cur[n_points - 1].x = (pts->cur[n_points - 1].x + 32) & -64; /* now consider hinting */ if ( n_ins > 0 ) { exec->is_composite = FALSE; exec->pedantic_hinting = load_flags & TTLOAD_PEDANTIC; error = Context_Run( exec, FALSE ); if (error && exec->pedantic_hinting) return error; } } else org_to_cur( n_points, pts ); } /* save glyph phantom points */ if (!subg->preserve_pps) { subg->pp1 = pts->cur[n_points - 2]; subg->pp2 = pts->cur[n_points - 1]; } return TT_Err_Ok; }