Esempio n. 1
0
  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;
  }
Esempio n. 2
0
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;
}
Esempio n. 3
0
  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;
  }
Esempio n. 4
0
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;
}