📄 ttdebug.c
字号:
"super 45"
};
/* only debug the requested code range */
if (exc->curRange != (FT_Int)debug_coderange)
return TT_RunIns(exc);
exc->pts.n_points = exc->zp0.n_points;
exc->pts.n_contours = exc->zp0.n_contours;
pts = exc->pts;
save.n_points = pts.n_points;
save.n_contours = pts.n_contours;
save.org = (FT_Vector*)malloc( 2 * sizeof( FT_F26Dot6 ) *
save.n_points );
save.cur = (FT_Vector*)malloc( 2 * sizeof( FT_F26Dot6 ) *
save.n_points );
save.tags = (FT_Byte*)malloc( save.n_points );
exc->instruction_trap = 1;
do
{
if ( CUR.IP < CUR.codeSize )
{
Calc_Length( exc );
CUR.args = CUR.top - (Pop_Push_Count[CUR.opcode] >> 4);
/* `args' is the top of the stack once arguments have been popped. */
/* One can also interpret it as the index of the last argument. */
/* Print the current line. We use a 80-columns console with the */
/* following formatting: */
/* */
/* [loc]:[addr] [opcode] [disassemby] [a][b]|[c][d] */
/* */
{
char temp[80];
int n, col, pop;
int args = CUR.args;
sprintf( temp, "%78c\n", ' ' );
/* first letter of location */
switch ( CUR.curRange )
{
case tt_coderange_glyph:
temp[0] = 'g';
break;
case tt_coderange_cvt:
temp[0] = 'c';
break;
default:
temp[0] = 'f';
}
/* current IP */
sprintf( temp+1, "%04lx: %02x %-36.36s",
CUR.IP,
CUR.opcode,
Cur_U_Line(&CUR) );
strncpy( temp+46, " (", 2 );
args = CUR.top - 1;
pop = Pop_Push_Count[CUR.opcode] >> 4;
col = 48;
for ( n = 6; n > 0; n-- )
{
if ( pop == 0 )
temp[col-1] = (temp[col-1] == '(' ? ' ' : ')' );
if ( args < CUR.top && args >= 0 )
sprintf( temp+col, "%04lx", CUR.stack[args] );
else
sprintf( temp+col, " " );
temp[col+4] = ' ';
col += 5;
pop--;
args--;
}
temp[78] = '\n';
temp[79] = '\0';
printf( "%s", temp );
}
/* First, check for empty stack and overflow */
if ( CUR.args < 0 )
{
printf( "ERROR : Too Few Arguments\n" );
CUR.error = TT_Err_Too_Few_Arguments;
goto LErrorLabel_;
}
CUR.new_top = CUR.args + (Pop_Push_Count[CUR.opcode] & 15);
/* new_top is the new top of the stack, after the instruction's */
/* execution. top will be set to new_top after the 'case' */
if ( CUR.new_top > CUR.stackSize )
{
printf( "ERROR : Stack overflow\n" );
CUR.error = TT_Err_Stack_Overflow;
goto LErrorLabel_;
}
}
else
printf( "End of program reached.\n" );
key = 0;
do
{
/* read keyboard */
ch = getch();
switch ( ch )
{
/* Help - show keybindings */
case '?':
printf( "TTDebug Help\n\n" );
printf( "? Show this page\n" );
printf( "q Quit debugger\n" );
printf( "n Skip to next instruction\n" );
printf( "s Step into\n" );
printf( "v Show vector info\n" );
printf( "g Show graphics state\n" );
printf( "p Show points zone\n\n" );
break;
/* Show vectors */
case 'v':
printf( "freedom (%04hx,%04hx)\n", exc->GS.freeVector.x,
exc->GS.freeVector.y );
printf( "projection (%04hx,%04hx)\n", exc->GS.projVector.x,
exc->GS.projVector.y );
printf( "dual (%04hx,%04hx)\n\n", exc->GS.dualVector.x,
exc->GS.dualVector.y );
break;
/* Show graphics state */
case 'g':
printf( "rounding %s\n", round_str[exc->GS.round_state] );
printf( "min dist %04lx\n", exc->GS.minimum_distance );
printf( "cvt_cutin %04lx\n", exc->GS.control_value_cutin );
break;
/* Show points table */
case 'p':
for ( A = 0; A < exc->pts.n_points; A++ )
{
printf( "%02hx ", A );
printf( "%08lx,%08lx - ", pts.org[A].x, pts.org[A].y );
printf( "%08lx,%08lx\n", pts.cur[A].x, pts.cur[A].y );
}
printf(( "\n" ));
break;
default:
key = 1;
}
} while ( !key );
FT_MEM_COPY( save.org, pts.org, pts.n_points * sizeof ( FT_Vector ) );
FT_MEM_COPY( save.cur, pts.cur, pts.n_points * sizeof ( FT_Vector ) );
FT_MEM_COPY( save.tags, pts.tags, pts.n_points );
/* a return indicate the last command */
if (ch == '\r')
ch = oldch;
switch ( ch )
{
/* Quit debugger */
case 'q':
goto LErrorLabel_;
/* Step over */
case 'n':
if ( exc->IP < exc->codeSize )
{
/* `step over' is equivalent to `step into' except if */
/* the current opcode is a CALL or LOOPCALL */
if ( CUR.opcode != 0x2a && CUR.opcode != 0x2b )
goto Step_into;
/* otherwise, loop execution until we reach the next opcode */
next_IP = CUR.IP + CUR.length;
while ( exc->IP != next_IP )
{
if ( ( error = TT_RunIns( exc ) ) != 0 )
goto LErrorLabel_;
}
}
oldch = ch;
break;
/* Step into */
case 's':
if ( exc->IP < exc->codeSize )
Step_into:
if ( ( error = TT_RunIns( exc ) ) != 0 )
goto LErrorLabel_;
oldch = ch;
break;
default:
printf( "unknown command. Press ? for help\n" );
oldch = '\0';
}
for ( A = 0; A < pts.n_points; A++ )
{
diff = 0;
if ( save.org[A].x != pts.org[A].x ) diff |= 1;
if ( save.org[A].y != pts.org[A].y ) diff |= 2;
if ( save.cur[A].x != pts.cur[A].x ) diff |= 4;
if ( save.cur[A].y != pts.cur[A].y ) diff |= 8;
if ( save.tags[A] != pts.tags[A] ) diff |= 16;
if ( diff )
{
printf( "%02hx ", A );
if ( diff & 16 ) temp = "(%01hx)"; else temp = " %01hx ";
printf( temp, old_tag_to_new(save.tags[A]) );
if ( diff & 1 ) temp = "(%08lx)"; else temp = " %08lx ";
printf( temp, save.org[A].x );
if ( diff & 2 ) temp = "(%08lx)"; else temp = " %08lx ";
printf( temp, save.org[A].y );
if ( diff & 4 ) temp = "(%08lx)"; else temp = " %08lx ";
printf( temp, save.cur[A].x );
if ( diff & 8 ) temp = "(%08lx)"; else temp = " %08lx ";
printf( temp, save.cur[A].y );
printf( "\n" );
printf( "%02hx ", A );
if ( diff & 16 ) temp = "[%01hx]"; else temp = " %01hx ";
printf( temp, old_tag_to_new(pts.tags[A]) );
if ( diff & 1 ) temp = "[%08lx]"; else temp = " %08lx ";
printf( temp, pts.org[A].x );
if ( diff & 2 ) temp = "[%08lx]"; else temp = " %08lx ";
printf( temp, pts.org[A].y );
if ( diff & 4 ) temp = "[%08lx]"; else temp = " %08lx ";
printf( temp, pts.cur[A].x );
if ( diff & 8 ) temp = "[%08lx]"; else temp = " %08lx ";
printf( temp, pts.cur[A].y );
printf( "\n\n" );
}
}
} while ( TRUE );
LErrorLabel_:
if (error)
Panic( "error during execution" );
return error;
}
static
void Usage()
{
fprintf( stderr, "ttdebug - a simply TrueType font debugger\n" );
fprintf( stderr, "(c) The FreeType project - www.freetype.org\n" );
fprintf( stderr, "-------------------------------------------\n\n" );
fprintf( stderr, "usage : ttdebug [options] glyph size fontfile[.ttf]\n\n" );
fprintf( stderr, " glyph - glyph index within the font file. Can be negative to query \n" );
fprintf( stderr, " the debugging of the font 'cvt' program\n\n" );
fprintf( stderr, " size - size of glyph in pixels\n\n" );
fprintf( stderr, " fontfile - a valid TrueType file.\n\n" );
fprintf( stderr, " valid options are:\n\n" );
fprintf( stderr, " -d : Dump mode. Shows the glyph program and exit immediately\n" );
fprintf( stderr, " -n : Non-interactive mode. Dumps the execution trace and exit\n" );
exit(1);
}
int dump_mode;
int non_interactive_mode;
char* file_name;
int glyph_index;
int glyph_size;
int main( int argc, char** argv )
{
char valid;
/* Check number of arguments */
if ( argc < 4 ) Usage();
/* Check options */
dump_mode = 0;
non_interactive_mode = 0;
argv++;
while (argv[0][0] == '-')
{
valid = 0;
switch (argv[0][1])
{
case 'd':
dump_mode = 1;
valid = 1;
break;
case 'n':
non_interactive_mode = 1;
valid = 1;
break;
default:
;
}
if (valid)
{
argv++;
argc--;
if (argc < 4) Usage();
}
else
break;
}
/* Get Glyph index */
if ( sscanf( argv[0], "%d", &glyph_index ) != 1 )
{
printf( "invalid glyph index = %s\n", argv[1] );
Usage();
}
/* Get Glyph size */
if ( sscanf( argv[1], "%d", &glyph_size ) != 1 )
{
printf( "invalid glyph size = %s\n", argv[1] );
Usage();
}
/* Get file name */
file_name = argv[2];
Init_Keyboard();
/* Init library, read face object, get driver, create size */
error = FT_Init_FreeType( &library );
if (error) Panic( "could not initialise FreeType library" );
memory = library->memory;
driver = (FT_Driver)FT_Get_Module( library, "truetype" );
if (!driver) Panic( "could not find the TrueType driver in FreeType 2\n" );
FT_Set_Debug_Hook( library,
FT_DEBUG_HOOK_TRUETYPE,
(FT_DebugHook_Func)RunIns );
error = FT_New_Face( library, file_name, 0, (FT_Face*)&face );
if (error) Panic( "could not open font resource" );
/* find driver and check format */
if ( face->root.driver != driver )
{
error = FT_Err_Invalid_File_Format;
Panic( "This is not a TrueType font" );
}
size = (TT_Size)face->root.size;
if (glyph_index < 0)
{
exec = TT_New_Context( face );
size->debug = 1;
size->context = exec;
error = FT_Set_Char_Size( (FT_Face)face, glyph_size << 6, glyph_size << 6, 72, 72 );
if (error) Panic( "could not set character sizes" );
}
else
{
error = FT_Set_Char_Size( (FT_Face)face, glyph_size << 6, glyph_size << 6, 72, 72 );
if (error) Panic( "could not set character sizes" );
glyph = (TT_GlyphSlot)face->root.glyph;
/* Now load glyph */
error = FT_Load_Glyph( (FT_Face)face, glyph_index, FT_LOAD_NO_BITMAP );
if (error) Panic( "could not load glyph" );
}
Reset_Keyboard();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -