📄 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 + -