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

📄 ttgxvar.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 4 页
字号:
      FT_FRAME_START( 20 ),
        FT_FRAME_LONG  ( version ),
        FT_FRAME_USHORT( axisCount ),
        FT_FRAME_USHORT( globalCoordCount ),
        FT_FRAME_ULONG ( offsetToCoord ),
        FT_FRAME_USHORT( glyphCount ),
        FT_FRAME_USHORT( flags ),
        FT_FRAME_ULONG ( offsetToData ),
      FT_FRAME_END
    };

    if ( (error = face->goto_table( face, TTAG_gvar, stream, &table_len )) != 0 )
      goto Exit;

    gvar_start = FT_STREAM_POS( );
    if ( FT_STREAM_READ_FIELDS( gvar_fields, &gvar_head ) )
      goto Exit;

    blend->tuplecount  = gvar_head.globalCoordCount;
    blend->gv_glyphcnt = gvar_head.glyphCount;
    offsetToData       = gvar_start + gvar_head.offsetToData;

    if ( gvar_head.version   != (FT_Long)0x00010000L              ||
         gvar_head.axisCount != (FT_UShort)blend->mmvar->num_axis )
    {
      error = TT_Err_Invalid_Table;
      goto Exit;
    }

    if ( FT_NEW_ARRAY( blend->glyphoffsets, blend->gv_glyphcnt + 1 ) )
      goto Exit;

    if ( gvar_head.flags & 1 )
    {
      /* long offsets (one more offset than glyphs, to mark size of last) */
      if ( FT_FRAME_ENTER( ( blend->gv_glyphcnt + 1 ) * 4L ) )
        goto Exit;

      for ( i = 0; i <= blend->gv_glyphcnt; ++i )
        blend->glyphoffsets[i] = offsetToData + FT_GET_LONG();

      FT_FRAME_EXIT();
    }
    else
    {
      /* short offsets (one more offset than glyphs, to mark size of last) */
      if ( FT_FRAME_ENTER( ( blend->gv_glyphcnt + 1 ) * 2L ) )
        goto Exit;

      for ( i = 0; i <= blend->gv_glyphcnt; ++i )
        blend->glyphoffsets[i] = offsetToData + FT_GET_USHORT() * 2;
                                              /* XXX: Undocumented: `*2'! */

      FT_FRAME_EXIT();
    }

    if ( blend->tuplecount != 0 )
    {
      if ( FT_NEW_ARRAY( blend->tuplecoords,
                         gvar_head.axisCount * blend->tuplecount ) )
        goto Exit;

      if ( FT_STREAM_SEEK( gvar_start + gvar_head.offsetToCoord )       ||
           FT_FRAME_ENTER( blend->tuplecount * gvar_head.axisCount * 2L )                   )
        goto Exit;

      for ( i = 0; i < blend->tuplecount; ++i )
        for ( j = 0 ; j < (FT_UInt)gvar_head.axisCount; ++j )
          blend->tuplecoords[i * gvar_head.axisCount + j] =
            FT_GET_SHORT() << 2;                /* convert to FT_Fixed */

      FT_FRAME_EXIT();
    }

  Exit:
    return error;
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    ft_var_apply_tuple                                                 */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Figure out whether a given tuple (design) applies to the current   */
  /*    blend, and if so, what is the scaling factor.                      */
  /*                                                                       */
  /* <Input>                                                               */
  /*    blend           :: The current blend of the font.                  */
  /*                                                                       */
  /*    tupleIndex      :: A flag saying whether this is an intermediate   */
  /*                       tuple or not.                                   */
  /*                                                                       */
  /*    tuple_coords    :: The coordinates of the tuple in normalized axis */
  /*                       units.                                          */
  /*                                                                       */
  /*    im_start_coords :: The initial coordinates where this tuple starts */
  /*                       to apply (for intermediate coordinates).        */
  /*                                                                       */
  /*    im_end_coords   :: The final coordinates after which this tuple no */
  /*                       longer applies (for intermediate coordinates).  */
  /*                                                                       */
  /* <Return>                                                              */
  /*    An FT_Fixed value containing the scaling factor.                   */
  /*                                                                       */
  static FT_Fixed
  ft_var_apply_tuple( GX_Blend   blend,
                      FT_UShort  tupleIndex,
                      FT_Fixed*  tuple_coords,
                      FT_Fixed*  im_start_coords,
                      FT_Fixed*  im_end_coords )
  {
    FT_UInt   i;
    FT_Fixed  apply;
    FT_Fixed  temp;


    apply = 0x10000L;
    for ( i = 0; i < blend->num_axis; ++i )
    {
      if ( tuple_coords[i] == 0 )
        /* It's not clear why (for intermediate tuples) we don't need     */
        /* to check against start/end -- the documentation says we don't. */
        /* Similarly, it's unclear why we don't need to scale along the   */
        /* axis.                                                          */
        continue;

      else if ( blend->normalizedcoords[i] == 0                           ||
                ( blend->normalizedcoords[i] < 0 && tuple_coords[i] > 0 ) ||
                ( blend->normalizedcoords[i] > 0 && tuple_coords[i] < 0 ) )
      {
        apply = 0;
        break;
      }

      else if ( !( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) )
        /* not an intermediate tuple */
        apply = FT_MulDiv( apply,
                           blend->normalizedcoords[i] > 0
                             ? blend->normalizedcoords[i]
                             : -blend->normalizedcoords[i],
                           0x10000L );

      else if ( blend->normalizedcoords[i] <= im_start_coords[i] ||
                blend->normalizedcoords[i] >= im_end_coords[i]   )
      {
        apply = 0;
        break;
      }

      else if ( blend->normalizedcoords[i] < tuple_coords[i] )
      {
        temp = FT_MulDiv( blend->normalizedcoords[i] - im_start_coords[i],
                          0x10000L,
                          tuple_coords[i] - im_start_coords[i]);
        apply = FT_MulDiv( apply, temp, 0x10000L );
      }

      else
      {
        temp = FT_MulDiv( im_end_coords[i] - blend->normalizedcoords[i],
                          0x10000L,
                          im_end_coords[i] - tuple_coords[i] );
        apply = FT_MulDiv( apply, temp, 0x10000L );
      }
    }

    return apply;
  }


  /*************************************************************************/
  /*************************************************************************/
  /*****                                                               *****/
  /*****               MULTIPLE MASTERS SERVICE FUNCTIONS              *****/
  /*****                                                               *****/
  /*************************************************************************/
  /*************************************************************************/


  typedef struct  GX_FVar_Head_ {
    FT_Long    version;
    FT_UShort  offsetToData;
    FT_UShort  countSizePairs;
    FT_UShort  axisCount;
    FT_UShort  axisSize;
    FT_UShort  instanceCount;
    FT_UShort  instanceSize;

  } GX_FVar_Head;


  typedef struct  fvar_axis {
    FT_ULong   axisTag;
    FT_ULong   minValue;
    FT_ULong   defaultValue;
    FT_ULong   maxValue;
    FT_UShort  flags;
    FT_UShort  nameID;

  } GX_FVar_Axis;


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    TT_Get_MM_Var                                                      */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Check that the font's `fvar' table is valid, parse it, and return  */
  /*    those data.                                                        */
  /*                                                                       */
  /* <InOut>                                                               */
  /*    face   :: The font face.                                           */
  /*              TT_Get_MM_Var initializes the blend structure.           */
  /*                                                                       */
  /* <Output>                                                              */
  /*    master :: The `fvar' data (must be freed by caller).               */
  /*                                                                       */
  /* <Return>                                                              */
  /*    FreeType error code.  0 means success.                             */
  /*                                                                       */
  FT_LOCAL_DEF( FT_Error )
  TT_Get_MM_Var( TT_Face      face,
                 FT_MM_Var*  *master )
  {
    FT_Stream            stream = face->root.stream;
    FT_Memory            memory = face->root.memory;
    FT_ULong             table_len;
    FT_Error             error  = TT_Err_Ok;
    FT_ULong             fvar_start;
    FT_Int               i, j;
    FT_MM_Var*           mmvar;
    FT_Fixed*            next_coords;
    FT_String*           next_name;
    FT_Var_Axis*         a;
    FT_Var_Named_Style*  ns;
    GX_FVar_Head         fvar_head;

    static const FT_Frame_Field  fvar_fields[] =
    {

#undef  FT_STRUCTURE
#define FT_STRUCTURE  GX_FVar_Head

      FT_FRAME_START( 16 ),
        FT_FRAME_LONG  ( version ),
        FT_FRAME_USHORT( offsetToData ),
        FT_FRAME_USHORT( countSizePairs ),
        FT_FRAME_USHORT( axisCount ),
        FT_FRAME_USHORT( axisSize ),
        FT_FRAME_USHORT( instanceCount ),
        FT_FRAME_USHORT( instanceSize ),
      FT_FRAME_END
    };

    static const FT_Frame_Field  fvaraxis_fields[] =
    {

#undef  FT_STRUCTURE
#define FT_STRUCTURE  GX_FVar_Axis

      FT_FRAME_START( 20 ),
        FT_FRAME_ULONG ( axisTag ),
        FT_FRAME_ULONG ( minValue ),
        FT_FRAME_ULONG ( defaultValue ),
        FT_FRAME_ULONG ( maxValue ),
        FT_FRAME_USHORT( flags ),
        FT_FRAME_USHORT( nameID ),
      FT_FRAME_END
    };


    if ( face->blend == NULL )
    {
      /* both `fvar' and `gvar' must be present */
      if ( (error = face->goto_table( face, TTAG_gvar,
                                      stream, &table_len )) != 0 )
        goto Exit;

      if ( (error = face->goto_table( face, TTAG_fvar,
                                      stream, &table_len )) != 0 )
        goto Exit;

      fvar_start = FT_STREAM_POS( );

      if ( FT_STREAM_READ_FIELDS( fvar_fields, &fvar_head ) )
        goto Exit;

      if ( fvar_head.version != (FT_Long)0x00010000L                      ||
           fvar_head.countSizePairs != 2                                  ||
           fvar_head.axisSize != 20                                       ||
           fvar_head.instanceSize != 4 + 4 * fvar_head.axisCount          ||
           fvar_head.offsetToData + fvar_head.axisCount * 20U +
             fvar_head.instanceCount * fvar_head.instanceSize > table_len )
      {
        error = TT_Err_Invalid_Table;
        goto Exit;
      }

      if ( FT_NEW( face->blend ) )
        goto Exit;

      /* XXX: TODO - check for overflows */
      face->blend->mmvar_len =
        sizeof ( FT_MM_Var ) +
        fvar_head.axisCount * sizeof ( FT_Var_Axis ) +
        fvar_head.instanceCount * sizeof ( FT_Var_Named_Style ) +
        fvar_head.instanceCount * fvar_head.axisCount * sizeof ( FT_Fixed ) +
        5 * fvar_head.axisCount;

      if ( FT_ALLOC( mmvar, face->blend->mmvar_len ) )
        goto Exit;
      face->blend->mmvar = mmvar;

      mmvar->num_axis =
        fvar_head.axisCount;
      mmvar->num_designs =
        (FT_UInt)-1;           /* meaningless in this context; each glyph */
                               /* may have a different number of designs  */
                               /* (or tuples, as called by Apple)         */
      mmvar->num_namedstyles =
        fvar_head.instanceCount;
      mmvar->axis =
        (FT_Var_Axis*)&(mmvar[1]);
      mmvar->namedstyle =
        (FT_Var_Named_Style*)&(mmvar->axis[fvar_head.axisCount]);

      next_coords =
        (FT_Fixed*)&(mmvar->namedstyle[fvar_head.instanceCount]);
      for ( i = 0; i < fvar_head.instanceCount; ++i )
      {
        mmvar->namedstyle[i].coords  = next_coords;
        next_coords                 += fvar_head.axisCount;
      }

      next_name = (FT_String*)next_coords;
      for ( i = 0; i < fvar_head.axisCount; ++i )
      {
        mmvar->axis[i].name  = next_name;
        next_name           += 5;
      }

      if ( FT_STREAM_SEEK( fvar_start + fvar_head.offsetToData ) )
        goto Exit;

      a = mmvar->axis;
      for ( i = 0; i < fvar_head.axisCount; ++i )
      {
        GX_FVar_Axis  axis_rec;


        if ( FT_STREAM_READ_FIELDS( fvaraxis_fields, &axis_rec ) )
          goto Exit;
        a->tag     = axis_rec.axisTag;
        a->minimum = axis_rec.minValue;     /* A Fixed */
        a->def     = axis_rec.defaultValue; /* A Fixed */
        a->maximum = axis_rec.maxValue;     /* A Fixed */
        a->strid   = axis_rec.nameID;

        a->name[0] = (FT_String)(   a->tag >> 24 );
        a->name[1] = (FT_String)( ( a->tag >> 16 ) & 0xFF );
        a->name[2] = (FT_String)( ( a->tag >>  8 ) & 0xFF );
        a->name[3] = (FT_String)( ( a->tag       ) & 0xFF );
        a->name[4] = 0;

        ++a;
      }

      ns = mmvar->namedstyle;
      for ( i = 0; i < fvar_head.instanceCount; ++i )
      {
        if ( FT_FRAME_ENTER( 4L + 4L * fvar_head.axisCount ) )
          goto Exit;

        ns->strid       =    FT_GET_USHORT();
        (void) /* flags = */ FT_GET_USHORT();

        for ( j = 0; j < fvar_head.axisCount; ++j )
          ns->coords[j] = FT_GET_ULONG();     /* A Fixed */

        FT_FRAME_EXIT();
      }
    }

⌨️ 快捷键说明

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