EXPORT_FUNC
  TT_Error  TT_Load_Kerning_Table( TT_Face    face,
                                   TT_UShort  kern_index )
  {
    TT_Error   error;
    TT_Stream  stream;

    TT_Kerning*        kern;
    TT_Kern_Subtable*  sub;


    PFace  faze = HANDLE_Face( face );

    if ( !faze )
      return TT_Err_Invalid_Face_Handle;

    error = TT_Extension_Get( faze, KERNING_ID, (void**)&kern );
    if ( error )
      return error;

    if ( kern->nTables == 0 )
      return TT_Err_Table_Missing;

    if ( kern_index >= kern->nTables )
      return TT_Err_Invalid_Argument;

    sub = kern->tables + kern_index;

    if ( sub->format != 0 && sub->format != 2 )
      return TT_Err_Invalid_Kerning_Table_Format;

    /* now access stream */
    if ( USE_Stream( faze->stream, stream ) )
      return error;

    if ( FILE_Seek( sub->offset ) )
      goto Fail;

    if ( sub->format == 0 )
      error = Subtable_Load_0( &sub->t.kern0, faze );
    else if ( sub->format == 2 )
      error = Subtable_Load_2( &sub->t.kern2, faze );

    if ( !error )
      sub->loaded = TRUE;

  Fail:
    /* release stream */
    DONE_Stream( stream );

    return error;
  }
示例#2
0
  TT_Get_Kerning_Directory( TT_Face      face,
                            TT_Kerning*  directory )
  {
    PFace        faze = HANDLE_Face( face );
    TT_Error     error;
    TT_Kerning*  kerning;


    if ( !faze )
      return TT_Err_Invalid_Face_Handle;

    /* copy directory header */
    error = TT_Extension_Get( faze, KERNING_ID, (void**)&kerning );
    if ( !error )
      *directory = *kerning;

    return error;
  }
示例#3
0
  EXPORT_FUNC
  TT_Error  TT_Get_Face_Gasp_Flags( TT_Face    face,
                                    TT_UShort  point_size,
                                    TT_Bool*   grid_fit,
                                    TT_Bool*   smooth_font )
  {
    PFace   faze = HANDLE_Face( face );
    UShort  i, flag;


    if ( !faze )
      return TT_Err_Invalid_Face_Handle;

    if ( faze->gasp.numRanges == 0 || !faze->gasp.gaspRanges )
      return TT_Err_Table_Missing;

    for ( i = 0; i < faze->gasp.numRanges; i++ )
    {
      if ( point_size <= faze->gasp.gaspRanges[i].maxPPEM )
      {
        flag = faze->gasp.gaspRanges[i].gaspFlag;

        *grid_fit    = ( (flag & GASP_GRIDFIT) != 0 );
        *smooth_font = ( (flag & GASP_DOGRAY ) != 0 );

        return TT_Err_Ok;
      }
    }

    /* for very large fonts we enable font smoothing and discard */
    /* grid fitting                                              */

    *grid_fit    = 0;
    *smooth_font = 1;

    return TT_Err_Ok;
  }
示例#4
0
  TT_Get_Face_Widths( TT_Face     face,
                      TT_UShort   first_glyph,
                      TT_UShort   last_glyph,
                      TT_UShort*  widths,
                      TT_UShort*  heights )
  {
    DEFINE_ALL_LOCALS;

    PFace     faze = HANDLE_Face(face);
    UShort    n;
    Long      table;

    ULong     glyf_offset;      /* offset of glyph table in file */
    UShort    zero_width  = 0;  /* width of glyph 0  */
    UShort    zero_height = 0;  /* height of glyph 0 */

    Bool      zero_loaded = 0;

#ifndef TT_HUGE_PTR
    PStorage  locations;
#else
    Storage TT_HUGE_PTR * locations;
#endif
    TT_BBox   bbox;


    if ( !faze )
      return TT_Err_Invalid_Face_Handle;

    if ( last_glyph >= faze->numGlyphs ||
         first_glyph > last_glyph      )
      return TT_Err_Invalid_Argument;

    /* find "glyf" table */
    table = TT_LookUp_Table( faze, TTAG_glyf );
    if ( table < 0 )
    {
      PERROR(( "ERROR: there is no glyph table in this font file!\n" ));
      return TT_Err_Glyf_Table_Missing;
    }
    glyf_offset = faze->dirTables[table].Offset;

    /* now access stream */
    if ( USE_Stream( faze->stream, stream ) )
      return error;

    locations = faze->glyphLocations + first_glyph;

    /* loop to load each glyph in the range */
    for ( n = first_glyph; n <= last_glyph; n++ )
    {
      if ( n + 1 < faze->numGlyphs &&
           locations[0] == locations[1] )
      {
        /* Note : Glyph 0 is always used to indicate a missing glyph   */
        /*        in a range. We must thus return its width and height */
        /*        where appropriate when we find an undefined glyph.   */
        if ( zero_loaded == 0 )
        {
          if ( FILE_Seek( glyf_offset + faze->glyphLocations[0] ) ||
               ACCESS_Frame( 10L ) )
            goto Fail;

          (void)GET_Short();   /* skip number of contours */

          bbox.xMin = GET_Short();
          bbox.yMin = GET_Short();
          bbox.xMax = GET_Short();
          bbox.yMax = GET_Short();

          FORGET_Frame();

          zero_width  = (UShort)(bbox.xMax - bbox.xMin);
          zero_height = (UShort)(bbox.yMax - bbox.yMin);
          zero_loaded = 1;
        }

        if ( widths )
          *widths++  = zero_width;

        if ( heights )
          *heights++ = zero_height;
      }
      else
      {
        /* normal glyph, read header */
        if ( FILE_Seek( glyf_offset + locations[0] ) ||
             ACCESS_Frame( 10L ) )
          goto Fail;

        (void)GET_Short();  /* skip number of contours */

        bbox.xMin = GET_Short();
        bbox.yMin = GET_Short();
        bbox.xMax = GET_Short();
        bbox.yMax = GET_Short();

        FORGET_Frame();

        if ( widths )
          *widths++  = (UShort)(bbox.xMax - bbox.xMin);

        if ( heights )
          *heights++ = (UShort)(bbox.yMax - bbox.yMin);
      }
    }

  Fail:
    DONE_Stream( stream );
    return error;
  }