コード例 #1
0
  static FT_Error
  RunIns( TT_ExecContext  exc )
  {
    FT_Int   A, diff, key;
    FT_Long  next_IP;

    FT_String  ch, oldch = '\0';

    TT_GlyphZoneRec  save;
    TT_GlyphZoneRec  pts;

    const FT_String*  code_range;

    const FT_String*  round_str[8] =
    {
      "to half-grid",
      "to grid",
      "to double grid",
      "down to grid",
      "up to grid",
      "off",
      "super",
      "super 45"
    };


    error = FT_Err_Ok;

    CUR.pts.n_points   = CUR.zp0.n_points;
    CUR.pts.n_contours = CUR.zp0.n_contours;

    pts = CUR.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 );

    CUR.instruction_trap = 1;

    switch ( CUR.curRange )
    {
    case tt_coderange_glyph:
      code_range = "glyf";
      break;

    case tt_coderange_cvt:
      code_range = "prep";
      break;

    default:
      code_range = "fpgm";
    }

    printf( "Entering `%s' table.\n"
            "\n", code_range );

    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 an 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;

          /* special case for IP */
          if ( CUR.opcode == 0x39 )
            pop = CUR.GS.loop;

          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
      {
        if ( CUR.curRange == tt_coderange_glyph )
          printf( "End of program reached.\n" );
        else
        {
          printf( "\n" );
          goto LErrorLabel_;
        }
      }

      key = 0;
      do
      {
        /* read keyboard */
        ch = getch();

        switch ( ch )
        {
        /* Help - show keybindings */
        case '?':
          printf( "\n"
                  "ttdebug Help\n"
                  "\n"
                  "?   show this page\n"
                  "q   quit debugger\n"
                  "c   continue to next code range\n"
                  "n   skip to next instruction\n"
                  "s   step into\n"
                  "v   show vector info\n"
                  "g   show graphics state\n"
                  "p   show points zone\n"
                  "f   toggle between floating and fixed point number format\n"
                  "l   show last bytecode instruction\n"
                  "\n"
                  "\n"
                  "  Format of point changes:\n"
                  "\n"
                  "    idx   orus.x  orus.y  tags  org.x  org.y  cur.x  cur.y\n"
                  "\n"
                  "  The first line gives the values before the instruction,\n"
                  "  the second line the changes after the instruction,\n"
                  "  indicated by parentheses and brackets for emphasis.\n"
                  "\n"
                  "  Tag values (which are ORed):\n"
                  "\n"
                  "    1 on curve\n"
                  "    2 touched along the X axis\n"
                  "    4 touched along the Y axis\n"
                  "\n" );
          break;

        /* Toggle between floating and fixed point format */
        case 'f':
          use_float = !use_float;
          printf( "use %s point format for displaying values\n",
                  use_float ? "floating" : "fixed" );
          printf( "\n" );
          break;

        /* Show vectors */
        case 'v':
          if ( use_float )
          {
            /* 2.14 numbers */
            printf( "freedom    (%.5f, %.5f)\n",
                    CUR.GS.freeVector.x / 16384.0,
                    CUR.GS.freeVector.y / 16384.0 );
            printf( "projection (%.5f, %.5f)\n",
                    CUR.GS.projVector.x / 16384.0,
                    CUR.GS.projVector.y / 16384.0 );
            printf( "dual       (%.5f, %.5f)\n",
                    CUR.GS.dualVector.x / 16384.0,
                    CUR.GS.dualVector.y / 16384.0 );
            printf( "\n" );
          }
          else
          {
            printf( "freedom    ($%04hx, $%04hx)\n",
                    CUR.GS.freeVector.x,
                    CUR.GS.freeVector.y );
            printf( "projection ($%04hx, $%04hx)\n",
                    CUR.GS.projVector.x,
                    CUR.GS.projVector.y );
            printf( "dual       ($%04hx, $%04hx)\n",
                    CUR.GS.dualVector.x,
                    CUR.GS.dualVector.y );
            printf( "\n" );
          }
          break;

        /* Show graphics state */
        case 'g':
          printf( "rounding state      %s\n",
                  round_str[CUR.GS.round_state] );
          if ( use_float )
          {
            /* 26.6 numbers */
            printf( "minimum distance    %.2f\n",
                    CUR.GS.minimum_distance / 64.0 );
            printf( "CVT cut-in          %.2f\n",
                    CUR.GS.control_value_cutin / 64.0 );
          }
          else
          {
            printf( "minimum distance    $%04lx\n",
                    CUR.GS.minimum_distance );
            printf( "CVT cut-in          $%04lx\n",
                    CUR.GS.control_value_cutin );
          }
          printf( "ref. points 0,1,2   %d, %d, %d\n",
                  CUR.GS.rp0, CUR.GS.rp1, CUR.GS.rp2 );
          printf( "\n" );
          break;

        /* Show points table */
        case 'p':
          if ( CUR.pts.n_points )
          {
            printf( "idx  "
                    "orig. unscaled  - "
                    "orig. scaled        - "
                    "current scaled     \n" );
            printf( "-----"
                    "------------------"
                    "----------------------"
                    "-------------------\n" );
          }
          else
            printf( "not yet in `glyf' program\n" );

          for ( A = 0; A < CUR.pts.n_points; A++ )
          {
            printf( "%3d  ",
                    A );
            printf( "(%6ld,%6ld) - ",
                    pts.orus[A].x, pts.orus[A].y );
            if ( use_float )
            {
              printf( "(%8.2f,%8.2f) - ",
                      pts.org[A].x / 64.0, pts.org[A].y / 64.0 );
              printf( "(%8.2f,%8.2f)\n",
                      pts.cur[A].x / 64.0, pts.cur[A].y / 64.0 );
            }
            else
            {
              printf( "(%8ld,%8ld) - ",
                      pts.org[A].x, pts.org[A].y );
              printf( "(%8ld,%8ld)\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 indicates the last command */
      if ( ch == '\r' )
        ch = oldch;

      switch ( ch )
      {
      /* quit debugger */
      case 'q':
        error = Quit;
        goto LErrorLabel_;

      /* continue */
      case 'c':
        if ( CUR.IP < CUR.codeSize )
        {
          /* loop execution until we reach end of current code range */
          while ( CUR.IP < CUR.codeSize )
          {
            if ( ( error = TT_RunIns( exc ) ) != 0 )
              goto LErrorLabel_;
          }
        }

      /* step over */
      case 'n':
        if ( CUR.IP < CUR.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 ( CUR.IP != next_IP )
          {
            if ( ( error = TT_RunIns( exc ) ) != 0 )
              goto LErrorLabel_;
          }
        }

        oldch = ch;
        break;

      /* step into */
      case 's':
        if ( CUR.IP < CUR.codeSize )

      Step_into:
          if ( ( error = TT_RunIns( exc ) ) != 0 )
            goto LErrorLabel_;

        oldch = ch;
        break;

      /* show last bytecode instruction */
      case 'l':
        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 )
        {
          const FT_String*  temp;


          printf( "%3d  ", A );
          printf( "%6ld,%6ld  ", pts.orus[A].x, pts.orus[A].y );

          if ( diff & 16 )
            temp = "(%01hx)";
          else
            temp = " %01hx ";
          printf( temp, old_tag_to_new( save.tags[A] ) );

          if ( diff & 1 )
            temp = use_float ? "(%8.2f)" : "(%8ld)";
          else
            temp = use_float ? " %8.2f " : " %8ld ";
          if ( use_float )
            printf( temp, save.org[A].x / 64.0 );
          else
            printf( temp, save.org[A].x );

          if ( diff & 2 )
            temp = use_float ? "(%8.2f)" : "(%8ld)";
          else
            temp = use_float ? " %8.2f " : " %8ld ";
          if ( use_float )
            printf( temp, save.org[A].y / 64.0 );
          else
            printf( temp, save.org[A].y );

          if ( diff & 4 )
            temp = use_float ? "(%8.2f)" : "(%8ld)";
          else
            temp = use_float ? " %8.2f " : " %8ld ";
          if ( use_float )
            printf( temp, save.cur[A].x / 64.0 );
          else
            printf( temp, save.cur[A].x );

          if ( diff & 8 )
            temp = use_float ? "(%8.2f)" : "(%8ld)";
          else
            temp = use_float ? " %8.2f " : " %8ld ";
          if ( use_float )
            printf( temp, save.cur[A].y / 64.0 );
          else
            printf( temp, save.cur[A].y );

          printf( "\n" );

          printf( "                    " );

          if ( diff & 16 )
            temp = "[%01hx]";
          else
            temp = "   ";
          printf( temp, old_tag_to_new( pts.tags[A] ) );

          if ( diff & 1 )
            temp = use_float ? "[%8.2f]" : "[%8ld]";
          else
            temp = "          ";
          if ( use_float )
            printf( temp, pts.org[A].x / 64.0 );
          else
            printf( temp, pts.org[A].x );

          if ( diff & 2 )
            temp = use_float ? "[%8.2f]" : "[%8ld]";
          else
            temp = "          ";
          if ( use_float )
            printf( temp, pts.org[A].y / 64.0 );
          else
            printf( temp, pts.org[A].y );

          if ( diff & 4 )
            temp = use_float ? "[%8.2f]" : "[%8ld]";
          else
            temp = "          ";
          if ( use_float )
            printf( temp, pts.cur[A].x / 64.0 );
          else
            printf( temp, pts.cur[A].x );

          if ( diff & 8 )
            temp = use_float ? "[%8.2f]" : "[%8ld]";
          else
            temp = "          ";
          if ( use_float )
            printf( temp, pts.cur[A].y / 64.0 );
          else
            printf( temp, pts.cur[A].y );

          printf( "\n" );
        }
      }
    } while ( TRUE );
コード例 #2
0
ファイル: ttdebug.c プロジェクト: xahgo/tama
  static
  FT_Error  RunIns( TT_ExecContext  exc )
  {
    FT_Int    A, diff, key;
    FT_Long   next_IP;
    FT_String ch, oldch = '\0', *temp;

    FT_Error  error = 0;

    TT_GlyphZoneRec  save;
    TT_GlyphZoneRec  pts;

    const FT_String*  round_str[8] =
    {
      "to half-grid",
      "to grid",
      "to double grid",
      "down to grid",
      "up to grid",
      "off",
      "super",
      "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;

          /* special case for IP */
          if (CUR.opcode == 0x39)
              pop = exc->GS.loop;

          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 );
          printf( "RP 0,1,2   %4x %4x %4x\n", exc->GS.rp0, exc->GS.rp1, exc->GS.rp2 );
          break;

        /* Show points table */
        case 'p':
          for ( A = 0; A < exc->pts.n_points; A++ )
          {
            printf( "%3hd  ", A );
            printf( "(%6d,%6d) - ", pts.orus[A].x, pts.orus[A].y );
            printf( "(%8ld,%8ld) - ", pts.org[A].x, pts.org[A].y );
            printf( "(%8ld,%8ld)\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( "%3hd  ", A );
          printf( "%6d,%6d  ", pts.orus[A].x, pts.orus[A].y );

          if ( diff & 16 ) temp = "(%01hx)"; else temp = " %01hx ";
          printf( temp, old_tag_to_new(save.tags[A]) );

          if ( diff & 1 ) temp = "(%8ld)"; else temp = " %8ld ";
          printf( temp, save.org[A].x );

          if ( diff & 2 ) temp = "(%8ld)"; else temp = " %8ld ";
          printf( temp, save.org[A].y );

          if ( diff & 4 ) temp = "(%8ld)"; else temp = " %8ld ";
          printf( temp, save.cur[A].x );

          if ( diff & 8 ) temp = "(%8ld)"; else temp = " %8ld ";
          printf( temp, save.cur[A].y );

          printf( "\n" );

          printf( "                    " );

          if ( diff & 16 ) temp = "[%01hx]"; else temp = "  ";
          printf( temp, old_tag_to_new(pts.tags[A]) );

          if ( diff & 1 ) temp = "[%8ld]"; else temp = "          ";
          printf( temp, pts.org[A].x );

          if ( diff & 2 ) temp = "[%8ld]"; else temp = "          ";
          printf( temp, pts.org[A].y );

          if ( diff & 4 ) temp = "[%8ld]"; else temp = "          ";
          printf( temp, pts.cur[A].x );

          if ( diff & 8 ) temp = "[%8ld]"; else temp = "          ";
          printf( temp, pts.cur[A].y );

          printf( "\n" );
        }
      }
    } while ( TRUE );