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

📄 ttsbit.c

📁 一个类似windows
💻 C
📖 第 1 页 / 共 4 页
字号:
      break;

    default:
      error = SFNT_Err_Invalid_File_Format;
    }

  Exit:
    return error;
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    tt_face_load_sbit_strikes                                          */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Loads the table of embedded bitmap sizes for this face.            */
  /*                                                                       */
  /* <Input>                                                               */
  /*    face   :: The target face object.                                  */
  /*                                                                       */
  /*    stream :: The input stream.                                        */
  /*                                                                       */
  /* <Return>                                                              */
  /*    FreeType error code.  0 means success.                             */
  /*                                                                       */
  FT_LOCAL_DEF( FT_Error )
  tt_face_load_sbit_strikes( TT_Face    face,
                             FT_Stream  stream )
  {
    FT_Error   error  = 0;
    FT_Memory  memory = stream->memory;
    FT_Fixed   version;
    FT_ULong   num_strikes;
    FT_ULong   table_base;

    static const FT_Frame_Field  sbit_line_metrics_fields[] =
    {
#undef  FT_STRUCTURE
#define FT_STRUCTURE  TT_SBit_LineMetricsRec

      /* no FT_FRAME_START */
        FT_FRAME_CHAR( ascender ),
        FT_FRAME_CHAR( descender ),
        FT_FRAME_BYTE( max_width ),

        FT_FRAME_CHAR( caret_slope_numerator ),
        FT_FRAME_CHAR( caret_slope_denominator ),
        FT_FRAME_CHAR( caret_offset ),

        FT_FRAME_CHAR( min_origin_SB ),
        FT_FRAME_CHAR( min_advance_SB ),
        FT_FRAME_CHAR( max_before_BL ),
        FT_FRAME_CHAR( min_after_BL ),
        FT_FRAME_CHAR( pads[0] ),
        FT_FRAME_CHAR( pads[1] ),
      FT_FRAME_END
    };

    static const FT_Frame_Field  strike_start_fields[] =
    {
#undef  FT_STRUCTURE
#define FT_STRUCTURE  TT_SBit_StrikeRec

      /* no FT_FRAME_START */
        FT_FRAME_ULONG( ranges_offset ),
        FT_FRAME_SKIP_LONG,
        FT_FRAME_ULONG( num_ranges ),
        FT_FRAME_ULONG( color_ref ),
      FT_FRAME_END
    };

    static const FT_Frame_Field  strike_end_fields[] =
    {
      /* no FT_FRAME_START */
        FT_FRAME_USHORT( start_glyph ),
        FT_FRAME_USHORT( end_glyph ),
        FT_FRAME_BYTE  ( x_ppem ),
        FT_FRAME_BYTE  ( y_ppem ),
        FT_FRAME_BYTE  ( bit_depth ),
        FT_FRAME_CHAR  ( flags ),
      FT_FRAME_END
    };


    face->num_sbit_strikes = 0;

    /* this table is optional */
    error = face->goto_table( face, TTAG_EBLC, stream, 0 );
    if ( error )
      error = face->goto_table( face, TTAG_bloc, stream, 0 );
    if ( error )
      goto Exit;

    table_base = FT_STREAM_POS();
    if ( FT_FRAME_ENTER( 8L ) )
      goto Exit;

    version     = FT_GET_LONG();
    num_strikes = FT_GET_ULONG();

    FT_FRAME_EXIT();

    /* check version number and strike count */
    if ( version     != 0x00020000L ||
         num_strikes >= 0x10000L    )
    {
      FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version!\n" ));
      error = SFNT_Err_Invalid_File_Format;

      goto Exit;
    }

    /* allocate the strikes table */
    if ( FT_NEW_ARRAY( face->sbit_strikes, num_strikes ) )
      goto Exit;

    face->num_sbit_strikes = num_strikes;

    /* now read each strike table separately */
    {
      TT_SBit_Strike  strike = face->sbit_strikes;
      FT_ULong        count  = num_strikes;


      if ( FT_FRAME_ENTER( 48L * num_strikes ) )
        goto Exit;

      while ( count > 0 )
      {
        if ( FT_STREAM_READ_FIELDS( strike_start_fields, strike )             ||
             FT_STREAM_READ_FIELDS( sbit_line_metrics_fields, &strike->hori ) ||
             FT_STREAM_READ_FIELDS( sbit_line_metrics_fields, &strike->vert ) ||
             FT_STREAM_READ_FIELDS( strike_end_fields, strike )               )
          break;

        count--;
        strike++;
      }

      FT_FRAME_EXIT();
    }

    /* allocate the index ranges for each strike table */
    {
      TT_SBit_Strike  strike = face->sbit_strikes;
      FT_ULong        count  = num_strikes;


      while ( count > 0 )
      {
        TT_SBit_Range  range;
        FT_ULong       count2 = strike->num_ranges;


        /* read each range */
        if ( FT_STREAM_SEEK( table_base + strike->ranges_offset ) ||
             FT_FRAME_ENTER( strike->num_ranges * 8L )            )
          goto Exit;

        if ( FT_NEW_ARRAY( strike->sbit_ranges, strike->num_ranges ) )
          goto Exit;

        range = strike->sbit_ranges;
        while ( count2 > 0 )
        {
          range->first_glyph  = FT_GET_USHORT();
          range->last_glyph   = FT_GET_USHORT();
          range->table_offset = table_base + strike->ranges_offset +
                                  FT_GET_ULONG();
          count2--;
          range++;
        }

        FT_FRAME_EXIT();

        /* Now, read each index table */
        count2 = strike->num_ranges;
        range  = strike->sbit_ranges;
        while ( count2 > 0 )
        {
          /* Read the header */
          if ( FT_STREAM_SEEK( range->table_offset ) ||
               FT_FRAME_ENTER( 8L )                  )
            goto Exit;

          range->index_format = FT_GET_USHORT();
          range->image_format = FT_GET_USHORT();
          range->image_offset = FT_GET_ULONG();

          FT_FRAME_EXIT();

          error = Load_SBit_Range( range, stream );
          if ( error )
            goto Exit;

          count2--;
          range++;
        }

        count--;
        strike++;
      }
    }

    /* now set up the root fields to indicate the strikes */
    if ( face->num_sbit_strikes )
    {
      FT_ULong  n;
      FT_Face   root = FT_FACE( face );


      if ( FT_NEW_ARRAY( root->available_sizes, face->num_sbit_strikes ) )
        goto Exit;

      for ( n = 0 ; n < face->num_sbit_strikes ; n++ )
      {
        FT_Bitmap_Size*  bsize  = root->available_sizes + n;
        TT_SBit_Strike   strike = face->sbit_strikes + n;
        FT_UShort        fupem  = face->header.Units_Per_EM;
        FT_Short         height = (FT_Short)( face->horizontal.Ascender -
                                              face->horizontal.Descender +
                                              face->horizontal.Line_Gap );
        FT_Short         avg    = face->os2.xAvgCharWidth;


        /* assume 72dpi */
        bsize->height =
          (FT_Short)( ( height * strike->y_ppem + fupem / 2 ) / fupem );
        bsize->width  =
          (FT_Short)( ( avg * strike->y_ppem + fupem / 2 ) / fupem );
        bsize->size   = strike->y_ppem << 6;
        bsize->x_ppem = strike->x_ppem << 6;
        bsize->y_ppem = strike->y_ppem << 6;
      }

      root->face_flags     |= FT_FACE_FLAG_FIXED_SIZES;
      root->num_fixed_sizes = (FT_Int)face->num_sbit_strikes;
    }

  Exit:
    return error;
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    tt_face_free_sbit_strikes                                          */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Releases the embedded bitmap tables.                               */
  /*                                                                       */
  /* <Input>                                                               */
  /*    face :: The target face object.                                    */
  /*                                                                       */
  FT_LOCAL_DEF( void )
  tt_face_free_sbit_strikes( TT_Face  face )
  {
    FT_Memory       memory       = face->root.memory;
    TT_SBit_Strike  strike       = face->sbit_strikes;
    TT_SBit_Strike  strike_limit = strike + face->num_sbit_strikes;


    if ( strike )
    {
      for ( ; strike < strike_limit; strike++ )
      {
        TT_SBit_Range  range       = strike->sbit_ranges;
        TT_SBit_Range  range_limit = range + strike->num_ranges;


        if ( range )
        {
          for ( ; range < range_limit; range++ )
          {
            /* release the glyph offsets and codes tables */
            /* where appropriate                          */
            FT_FREE( range->glyph_offsets );
            FT_FREE( range->glyph_codes );
          }
        }
        FT_FREE( strike->sbit_ranges );
        strike->num_ranges = 0;
      }
      FT_FREE( face->sbit_strikes );
    }
    face->num_sbit_strikes = 0;
  }


  FT_LOCAL_DEF( FT_Error )
  tt_face_set_sbit_strike( TT_Face    face,
                           FT_UInt    x_ppem,
                           FT_UInt    y_ppem,
                           FT_ULong  *astrike_index )
  {
    FT_ULong  i;


    if ( x_ppem > 255 ||
         y_ppem < 1 || y_ppem > 255 )
      return SFNT_Err_Invalid_PPem;

    for ( i = 0; i < face->num_sbit_strikes; i++ )
    {
      if ( ( (FT_UInt)face->sbit_strikes[i].y_ppem == y_ppem )     &&
           ( ( x_ppem == 0 )                                     ||
             ( (FT_UInt)face->sbit_strikes[i].x_ppem == x_ppem ) ) )
      {
        *astrike_index = i;
        return SFNT_Err_Ok;
      }
    }

    return SFNT_Err_Invalid_PPem;
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    find_sbit_range                                                    */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Scans a given strike's ranges and return, for a given glyph        */
  /*    index, the corresponding sbit range, and `EBDT' offset.            */
  /*                                                                       */
  /* <Input>                                                               */
  /*    glyph_index   :: The glyph index.                                  */
  /*                                                                       */
  /*    strike        :: The source/current sbit strike.                   */
  /*                                                                       */
  /* <Output>                                                              */
  /*    arange        :: The sbit range containing the glyph index.        */
  /*                                                                       */
  /*    aglyph_offset :: The offset of the glyph data in `EBDT' table.     */
  /*                                                                       */
  /* <Return>                                                              */
  /*    FreeType error code.  0 means the glyph index was found.           */
  /*                                                                       */
  static FT_Error
  find_sbit_range( FT_UInt          glyph_index,
                   TT_SBit_Strike   strike,
                   TT_SBit_Range   *arange,
                   FT_ULong        *aglyph_offset )
  {
    TT_SBit_RangeRec  *range, *range_limit;


    /* check whether the glyph index is within this strike's */
    /* glyph range                                           */
    if ( glyph_index < (FT_UInt)strike->start_glyph ||
         glyph_index > (FT_UInt)strike->end_glyph   )
      goto Fail;

    /* scan all ranges in strike */
    range       = strike->sbit_ranges;
    range_limit = range + strike->num_ranges;
    if ( !range )
      goto Fail;

    for ( ; range < range_limit; range++ )
    {
      if ( glyph_index >= (FT_UInt)range->first_glyph &&
           glyph_index <= (FT_UInt)range->last_glyph  )
      {
        FT_UShort  delta = (FT_UShort)( glyph_index - range->first_glyph );


        switch ( range->index_format )
        {
        case 1:
        case 3:
          *aglyph_offset = range->glyph_offsets[delta];
          break;

        case 2:
          *aglyph_offset = range->image_offset +

⌨️ 快捷键说明

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