⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ttdebug.c

📁 Demo for Free type 2.2.1
💻 C
📖 第 1 页 / 共 3 页
字号:
      "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 + -