Ejemplo n.º 1
0
Archivo: pfrobjs.c Proyecto: 8l/inferno
  pfr_face_get_kerning( PFR_Face    face,
                        FT_UInt     glyph1,
                        FT_UInt     glyph2,
                        FT_Vector*  kerning )
  {
    FT_Error      error;
    PFR_PhyFont   phy_font = &face->phy_font;
    PFR_KernItem  item     = phy_font->kern_items;
    FT_UInt32     idx      = PFR_KERN_INDEX( glyph1, glyph2 );


    kerning->x = 0;
    kerning->y = 0;

    /* find the kerning item containing our pair */
    while ( item )
    {
      if ( item->pair1 <= idx && idx <= item->pair2 )
        goto Found_Item;

      item = item->next;
    }

    /* not found */
    goto Exit;

  Found_Item:
    {
      /* perform simply binary search within the item */
      FT_UInt    min, mid, max;
      FT_Stream  stream = face->root.stream;
      FT_Byte*   p;


      if ( FT_STREAM_SEEK( item->offset )                       ||
           FT_FRAME_ENTER( item->pair_count * item->pair_size ) )
        goto Exit;

      min = 0;
      max = item->pair_count;
      while ( min < max )
      {
        FT_UInt  char1, char2, charcode;


        mid = ( min + max ) >> 1;
        p   = stream->cursor + mid*item->pair_size;

        if ( item->flags & PFR_KERN_2BYTE_CHAR )
        {
          char1 = FT_NEXT_USHORT( p );
          char2 = FT_NEXT_USHORT( p );
        }
        else
        {
          char1 = FT_NEXT_USHORT( p );
          char2 = FT_NEXT_USHORT( p );
        }
        charcode = PFR_KERN_INDEX( char1, char2 );

        if ( idx == charcode )
        {
          if ( item->flags & PFR_KERN_2BYTE_ADJ )
            kerning->x = item->base_adj + FT_NEXT_SHORT( p );
          else
            kerning->x = item->base_adj + FT_NEXT_CHAR( p );

          break;
        }
        if ( idx > charcode )
          min = mid + 1;
        else
          max = mid;
      }

      FT_FRAME_EXIT();
    }

  Exit:
    return 0;
  }
Ejemplo n.º 2
0
  static FT_Error
  pfr_sort_kerning_pairs( FT_Stream    stream,
                          PFR_PhyFont  phy_font )
  {
    FT_Error      error;
    FT_Memory     memory = stream->memory;
    PFR_KernPair  pairs;
    PFR_KernItem  item;
    PFR_Char      chars     = phy_font->chars;
    FT_UInt       num_chars = phy_font->num_chars;
    FT_UInt       count;


   /* create kerning pairs array
    */
    if ( FT_NEW_ARRAY( phy_font->kern_pairs, phy_font->num_kern_pairs ) )
      goto Exit;

   /* load all kerning items into the array,
    * converting character codes into glyph indices
    */
    pairs = phy_font->kern_pairs;
    item  = phy_font->kern_items;
    count = 0;

    for ( ; item; item = item->next )
    {
      FT_UInt   limit = count + item->pair_count;
      FT_Byte*  p;


      if ( limit > phy_font->num_kern_pairs )
      {
        error = PFR_Err_Invalid_Table;
        goto Exit;
      }

      if ( FT_STREAM_SEEK( item->offset )                       ||
           FT_FRAME_ENTER( item->pair_count * item->pair_size ) )
        goto Exit;

      p = stream->cursor;

      for ( ; count < limit; count++ )
      {
        PFR_KernPair  pair = pairs + count;
        FT_UInt       char1, char2;
        FT_Int        kerning;


        if ( item->flags & PFR_KERN_2BYTE_CHAR )
        {
          char1 = FT_NEXT_USHORT( p );
          char2 = FT_NEXT_USHORT( p );
        }
        else
        {
          char1 = FT_NEXT_BYTE( p );
          char2 = FT_NEXT_BYTE( p );
        }

        if ( item->flags & PFR_KERN_2BYTE_ADJ )
          kerning = item->base_adj + FT_NEXT_SHORT( p );
        else
          kerning = item->base_adj + FT_NEXT_CHAR( p );

        pair->glyph1  = pfr_get_gindex( chars, num_chars, char1 );
        pair->glyph2  = pfr_get_gindex( chars, num_chars, char2 );
        pair->kerning = kerning;
      }

      FT_FRAME_EXIT();
    }

   /* sort the resulting array
    */
    ft_qsort( pairs, count,
              sizeof ( PFR_KernPairRec ),
              pfr_compare_kern_pairs );

  Exit:
    if ( error )
    {
     /* disable kerning data in case of error
      */
      phy_font->num_kern_pairs = 0;
    }

    return error;
  }