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

📄 cffgload.c

📁 source code: Covert TXT to PDF
💻 C
📖 第 1 页 / 共 5 页
字号:
    if ( !builder->load_points )    {      outline->n_contours++;      return CFF_Err_Ok;    }    error = FT_GlyphLoader_Check_Points( builder->loader, 0, 1 );    if ( !error )    {      if ( outline->n_contours > 0 )        outline->contours[outline->n_contours - 1] =          (short)( outline->n_points - 1 );      outline->n_contours++;    }    return error;  }  /* if a path was begun, add its first on-curve point */  static FT_Error  start_point( CFF_Builder*  builder,               FT_Pos        x,               FT_Pos        y )  {    FT_Error  error = 0;    /* test whether we are building a new contour */    if ( !builder->path_begun )    {      builder->path_begun = 1;      error = add_contour( builder );      if ( !error )        error = add_point1( builder, x, y );    }    return error;  }  /* close the current contour */  static void  close_contour( CFF_Builder*  builder )  {    FT_Outline*  outline = builder->current;    /* XXXX: We must not include the last point in the path if it */    /*       is located on the first point.                       */    if ( outline->n_points > 1 )    {      FT_Int      first   = 0;      FT_Vector*  p1      = outline->points + first;      FT_Vector*  p2      = outline->points + outline->n_points - 1;      FT_Byte*    control = (FT_Byte*)outline->tags + outline->n_points - 1;      if ( outline->n_contours > 1 )      {        first = outline->contours[outline->n_contours - 2] + 1;        p1    = outline->points + first;      }      /* `delete' last point only if it coincides with the first */      /* point and it is not a control point (which can happen). */      if ( p1->x == p2->x && p1->y == p2->y )        if ( *control == FT_Curve_Tag_On )          outline->n_points--;    }    if ( outline->n_contours > 0 )      outline->contours[outline->n_contours - 1] =        (short)( outline->n_points - 1 );  }  static FT_Int  cff_lookup_glyph_by_stdcharcode( CFF_Font*  cff,                                   FT_Int     charcode )  {    FT_UInt    n;    FT_UShort  glyph_sid;    /* check range of standard char code */    if ( charcode < 0 || charcode > 255 )      return -1;    /* Get code to SID mapping from `cff_standard_encoding'. */    glyph_sid = CFF_Get_Standard_Encoding( (FT_UInt)charcode );    for ( n = 0; n < cff->num_glyphs; n++ )    {      if ( cff->charset.sids[n] == glyph_sid )        return n;    }    return -1;  }  static FT_Error  cff_operator_seac( CFF_Decoder*  decoder,                     FT_Pos        adx,                     FT_Pos        ady,                     FT_Int        bchar,                     FT_Int        achar )  {    FT_Error     error;    FT_Int       bchar_index, achar_index, n_base_points;    FT_Outline*  base = decoder->builder.base;    TT_Face      face = decoder->builder.face;    CFF_Font*    cff  = (CFF_Font*)(face->extra.data);    FT_Vector    left_bearing, advance;    FT_Byte*     charstring;    FT_ULong     charstring_len;    bchar_index = cff_lookup_glyph_by_stdcharcode( cff, bchar );    achar_index = cff_lookup_glyph_by_stdcharcode( cff, achar );    if ( bchar_index < 0 || achar_index < 0 )    {      FT_ERROR(( "cff_operator_seac:" ));      FT_ERROR(( " invalid seac character code arguments\n" ));      return CFF_Err_Syntax_Error;    }    /* If we are trying to load a composite glyph, do not load the */    /* accent character and return the array of subglyphs.         */    if ( decoder->builder.no_recurse )    {      FT_GlyphSlot     glyph  = (FT_GlyphSlot)decoder->builder.glyph;      FT_GlyphLoader*  loader = glyph->internal->loader;      FT_SubGlyph*     subg;      /* reallocate subglyph array if necessary */      error = FT_GlyphLoader_Check_Subglyphs( loader, 2 );      if ( error )        goto Exit;      subg = loader->current.subglyphs;      /* subglyph 0 = base character */      subg->index = bchar_index;      subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES |                    FT_SUBGLYPH_FLAG_USE_MY_METRICS;      subg->arg1  = 0;      subg->arg2  = 0;      subg++;      /* subglyph 1 = accent character */      subg->index = achar_index;      subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES;      subg->arg1  = adx;      subg->arg2  = ady;      /* set up remaining glyph fields */      glyph->num_subglyphs = 2;      glyph->subglyphs     = loader->base.subglyphs;      glyph->format        = ft_glyph_format_composite;      loader->current.num_subglyphs = 2;    }    /* First load `bchar' in builder */    error = CFF_Access_Element( &cff->charstrings_index, bchar_index,                                &charstring, &charstring_len );    if ( !error )    {      error = CFF_Parse_CharStrings( decoder, charstring, charstring_len );      if ( error )        goto Exit;      CFF_Forget_Element( &cff->charstrings_index, &charstring );    }    n_base_points = base->n_points;    /* Save the left bearing and width of the base character */    /* as they will be erased by the next load.              */    left_bearing = decoder->builder.left_bearing;    advance      = decoder->builder.advance;    decoder->builder.left_bearing.x = 0;    decoder->builder.left_bearing.y = 0;    /* Now load `achar' on top of the base outline. */    error = CFF_Access_Element( &cff->charstrings_index, achar_index,                                &charstring, &charstring_len );    if ( !error )    {      error = CFF_Parse_CharStrings( decoder, charstring, charstring_len );      if ( error )        goto Exit;      CFF_Forget_Element( &cff->charstrings_index, &charstring );    }    /* Restore the left side bearing and advance width */    /* of the base character.                          */    decoder->builder.left_bearing = left_bearing;    decoder->builder.advance      = advance;    /* Finally, move the accent. */    if ( decoder->builder.load_points )    {      FT_Outline  dummy;      dummy.n_points = (short)( base->n_points - n_base_points );      dummy.points   = base->points   + n_base_points;      FT_Outline_Translate( &dummy, adx, ady );    }  Exit:    return error;  }  /*************************************************************************/  /*                                                                       */  /* <Function>                                                            */  /*    CFF_Parse_CharStrings                                              */  /*                                                                       */  /* <Description>                                                         */  /*    Parses a given Type 2 charstrings program.                         */  /*                                                                       */  /* <InOut>                                                               */  /*    decoder         :: The current Type 1 decoder.                     */  /*                                                                       */  /* <Input>                                                               */  /*    charstring_base :: The base of the charstring stream.              */  /*                                                                       */  /*    charstring_len  :: The length in bytes of the charstring stream.   */  /*                                                                       */  /* <Return>                                                              */  /*    FreeType error code.  0 means success.                             */  /*                                                                       */  FT_LOCAL_DEF FT_Error  CFF_Parse_CharStrings( CFF_Decoder*  decoder,                         FT_Byte*      charstring_base,                         FT_Int        charstring_len )  {    FT_Error           error;    CFF_Decoder_Zone*  zone;    FT_Byte*           ip;    FT_Byte*           limit;    CFF_Builder*       builder = &decoder->builder;    FT_Pos             x, y;    FT_Fixed           seed;    FT_Fixed*          stack;    T2_Hints_Funcs     hinter;    /* set default width */    decoder->num_hints  = 0;    decoder->read_width = 1;    /* compute random seed from stack address of parameter */    seed = (FT_Fixed)(char*)&seed           ^           (FT_Fixed)(char*)&decoder        ^           (FT_Fixed)(char*)&charstring_base;    seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFF;    if ( seed == 0 )      seed = 0x7384;    /* initialize the decoder */    decoder->top  = decoder->stack;    decoder->zone = decoder->zones;    zone          = decoder->zones;    stack         = decoder->top;    hinter = (T2_Hints_Funcs) builder->hints_funcs;    builder->path_begun = 0;    zone->base           = charstring_base;    limit = zone->limit  = charstring_base + charstring_len;    ip    = zone->cursor = zone->base;    error = CFF_Err_Ok;    x = builder->pos_x;    y = builder->pos_y;    /* begin hints recording session, if any */    if ( hinter )      hinter->open( hinter->hints );    /* now, execute loop */    while ( ip < limit )    {      CFF_Operator  op;      FT_Byte       v;      /********************************************************************/      /*                                                                  */      /* Decode operator or operand                                       */      /*                                                                  */      v = *ip++;      if ( v >= 32 || v == 28 )      {        FT_Int    shift = 16;        FT_Int32  val;        /* this is an operand, push it on the stack */        if ( v == 28 )        {          if ( ip + 1 >= limit )            goto Syntax_Error;          val = (FT_Short)( ( (FT_Short)ip[0] << 8 ) | ip[1] );          ip += 2;        }        else if ( v < 247 )          val = (FT_Long)v - 139;        else if ( v < 251 )        {          if ( ip >= limit )            goto Syntax_Error;          val = ( (FT_Long)v - 247 ) * 256 + *ip++ + 108;        }        else if ( v < 255 )        {          if ( ip >= limit )            goto Syntax_Error;          val = -( (FT_Long)v - 251 ) * 256 - *ip++ - 108;        }        else        {          if ( ip + 3 >= limit )            goto Syntax_Error;          val = ( (FT_Int32)ip[0] << 24 ) |                ( (FT_Int32)ip[1] << 16 ) |                ( (FT_Int32)ip[2] <<  8 ) |                            ip[3];          ip    += 4;          shift  = 0;        }        if ( decoder->top - stack >= CFF_MAX_OPERANDS )          goto Stack_Overflow;        val           <<= shift;        *decoder->top++ = val;#ifdef FT_DEBUG_LEVEL_TRACE        if ( !( val & 0xFFFF ) )          FT_TRACE4(( " %d", (FT_Int32)( val >> 16 ) ));        else          FT_TRACE4(( " %.2f", val / 65536.0 ));#endif      }      else      {        FT_Fixed*  args     = decoder->top;        FT_Int     num_args = args - decoder->stack;        FT_Int     req_args;        /* find operator */        op = cff_op_unknown;        switch ( v )        {        case 1:          op = cff_op_hstem;          break;        case 3:          op = cff_op_vstem;          break;        case 4:          op = cff_op_vmoveto;          break;        case 5:          op = cff_op_rlineto;          break;        case 6:          op = cff_op_hlineto;          break;        case 7:          op = cff_op_vlineto;          break;        case 8:          op = cff_op_rrcurveto;          break;        case 10:          op = cff_op_callsubr;          break;        case 11:          op = cff_op_return;          break;        case 12:          {            if ( ip >= limit )              goto Syntax_Error;            v = *ip++;            switch ( v )            {            case 0:              op = cff_op_dotsection;              break;            case 3:              op = cff_op_and;              break;            case 4:              op = cff_op_or;              break;            case 5:              op = cff_op_not;              break;            case 8:              op = cff_op_store;              break;            case 9:              op = cff_op_abs;              break;            case 10:              op = cff_op_add;              break;            case 11:              op = cff_op_sub;              break;            case 12:              op = cff_op_div;              break;            case 13:              op = cff_op_load;              break;            case 14:              op = cff_op_neg;              break;            case 15:              op = cff_op_eq;              break;            case 18:              op = cff_op_drop;              break;            case 20:              op = cff_op_put;              break;            case 21:              op = cff_op_get;              break;            case 22:              op = cff_op_ifelse;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -