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

📄 ftcommon.i

📁 Ftee type Demo for Linux open source
💻 I
📖 第 1 页 / 共 2 页
字号:
      {
        max_fonts *= 2;
        fonts      = (PFont*)realloc( fonts, max_fonts * sizeof ( PFont ) );

        memset( &fonts[num_fonts], 0,
                ( max_fonts - num_fonts ) * sizeof ( PFont ) );
      }

      fonts[num_fonts++] = font;
    }

    return 0;
  }


  /*************************************************************************/
  /*                                                                       */
  /* The face requester is a function provided by the client application   */
  /* to the cache manager, whose role is to translate an `abstract' face   */
  /* ID into a real FT_Face object.                                        */
  /*                                                                       */
  /* In this program, the face IDs are simply pointers to TFont objects.   */
  /*                                                                       */
  FT_CALLBACK_DEF( FT_Error )
  my_face_requester( FTC_FaceID  face_id,
                     FT_Library  lib,
                     FT_Pointer  request_data,
                     FT_Face*    aface )
  {
    PFont  font = (PFont)face_id;

    FT_UNUSED( request_data );


    error = FT_New_Face( lib,
                         font->filepathname,
                         font->face_index,
                         aface );
    if ( encoding == FT_ENCODING_NONE || error )
      goto Fail;

    error = FT_Select_Charmap( *aface, encoding );

  Fail:
    return error;
  }


  static void
  init_freetype( void )
  {
    error = FT_Init_FreeType( &library );
    if ( error )
      PanicZ( "could not initialize FreeType" );

    error = FTC_Manager_New( library, 0, 0, 0,
                             my_face_requester, 0, &cache_manager );
    if ( error )
      PanicZ( "could not initialize cache manager" );

    error = FTC_SBitCache_New( cache_manager, &sbits_cache );
    if ( error )
      PanicZ( "could not initialize small bitmaps cache" );

    error = FTC_ImageCache_New( cache_manager, &image_cache );
    if ( error )
      PanicZ( "could not initialize glyph image cache" );

    error = FTC_CMapCache_New( cache_manager, &cmap_cache );
    if ( error )
      PanicZ( "could not initialize charmap cache" );

    FT_Bitmap_New( &ft_bitmap );
  }


  static void
  done_freetype( void )
  {
    int  i;


    for ( i = 0; i < max_fonts; i++ )
    {
      if ( fonts[i] )
      {
        if ( fonts[i]->filepathname )
          free( (void*)fonts[i]->filepathname );
        free( fonts[i] );
      }
    }
    free( fonts );

    FTC_Manager_Done( cache_manager );
    FT_Bitmap_Done( library, &ft_bitmap );
    FT_Done_FreeType( library );
  }


  static void
  set_current_face( PFont  font )
  {
    current_font.face_id = (FTC_FaceID)font;
  }


  static void
  set_current_size( int  pixel_size )
  {
    if ( pixel_size > 0xFFFF )
      pixel_size = 0xFFFF;

    current_font.width  = (FT_UShort)pixel_size;
    current_font.height = (FT_UShort)pixel_size;
  }


  static void
  set_current_pointsize( int  point_size )
  {
    set_current_size( ( point_size * res + 36 ) / 72 );
  }


  static void
  set_current_image_type( void )
  {
    current_font.flags = antialias ? FT_LOAD_DEFAULT : FT_LOAD_TARGET_MONO;

    current_font.flags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;

    if ( !hinted )
      current_font.flags |= FT_LOAD_NO_HINTING;

    if ( autohint )
      current_font.flags |= FT_LOAD_FORCE_AUTOHINT;

    if ( !use_sbits )
      current_font.flags |= FT_LOAD_NO_BITMAP;

    if ( antialias && lcd_mode > 0 )
    {
      if ( lcd_mode <= 1 )
        current_font.flags |= FT_LOAD_TARGET_LIGHT;
      else if ( lcd_mode <= 3 )
        current_font.flags |= FT_LOAD_TARGET_LCD;
      else
        current_font.flags |= FT_LOAD_TARGET_LCD_V;
    }
  }


  static void
  done_glyph_bitmap( FT_Pointer  _glyf )
  {
    if ( _glyf )
    {
      FT_Glyph  glyf = (FT_Glyph)_glyf;


      FT_Done_Glyph( glyf );
    }
  }


  static FT_UInt
  get_glyph_index( FT_UInt32  charcode )
  {
    FTC_FaceID  face_id = current_font.face_id;
    PFont       font    = (PFont)face_id;


    return FTC_CMapCache_Lookup( cmap_cache, face_id,
                                 font->cmap_index, charcode );
  }


  static FT_Error
  glyph_to_bitmap( FT_Glyph    glyf,
                   grBitmap*   target,
                   int        *left,
                   int        *top,
                   int        *x_advance,
                   int        *y_advance,
                   FT_Pointer *aref )
  {
    FT_BitmapGlyph  bitmap;
    FT_Bitmap*      source;


    *aref = NULL;

    error = FT_Err_Ok;

    if ( glyf->format == FT_GLYPH_FORMAT_OUTLINE )
    {
      /* render the glyph to a bitmap, don't destroy original */
      error = FT_Glyph_To_Bitmap( &glyf,
                                  antialias ? FT_RENDER_MODE_NORMAL
                                            : FT_RENDER_MODE_MONO,
                                  NULL, 0 );
      if ( error )
        goto Exit;

      *aref = glyf;
    }

    if ( glyf->format != FT_GLYPH_FORMAT_BITMAP )
      PanicZ( "invalid glyph format returned!" );

    bitmap = (FT_BitmapGlyph)glyf;
    source = &bitmap->bitmap;

    target->rows   = source->rows;
    target->width  = source->width;
    target->pitch  = source->pitch;
    target->buffer = source->buffer;

    switch ( source->pixel_mode )
    {
    case FT_PIXEL_MODE_MONO:
      target->mode  = gr_pixel_mode_mono;
      target->grays = 2;
      break;

    case FT_PIXEL_MODE_GRAY:
      target->mode  = gr_pixel_mode_gray;
      target->grays = source->num_grays;
      break;

    case FT_PIXEL_MODE_GRAY2:
    case FT_PIXEL_MODE_GRAY4:
      (void)FT_Bitmap_Convert( library, source, &ft_bitmap, 1 );
      target->pitch  = ft_bitmap.pitch;
      target->buffer = ft_bitmap.buffer;
      target->mode   = gr_pixel_mode_gray;
      target->grays  = ft_bitmap.num_grays;
      break;

    case FT_PIXEL_MODE_LCD:
      target->mode  = lcd_mode == 2 ? gr_pixel_mode_lcd
                                    : gr_pixel_mode_lcd2;
      target->grays = source->num_grays;
      break;

    case FT_PIXEL_MODE_LCD_V:
      target->mode  = lcd_mode == 4 ? gr_pixel_mode_lcdv
                                    : gr_pixel_mode_lcdv2;
      target->grays = source->num_grays;
      break;

    default:
      return FT_Err_Invalid_Glyph_Format;
    }

    *left = bitmap->left;
    *top  = bitmap->top;

    *x_advance = ( glyf->advance.x + 0x8000 ) >> 16;
    *y_advance = ( glyf->advance.y + 0x8000 ) >> 16;

  Exit:
    return error;
  }


  static FT_Error
  get_glyph_bitmap( FT_ULong     Index,
                    grBitmap*    target,
                    int         *left,
                    int         *top,
                    int         *x_advance,
                    int         *y_advance,
                    FT_Pointer  *aglyf )
  {
    *aglyf = NULL;

    if ( encoding != FT_ENCODING_NONE )
      Index = get_glyph_index( Index );

    /* use the SBits cache to store small glyph bitmaps; this is a lot */
    /* more memory-efficient                                           */
    /*                                                                 */
    if ( use_sbits_cache          &&
         current_font.width  < 48 &&
         current_font.height < 48 )
    {
      FTC_SBit   sbit;
      FT_Bitmap  source;


      error = FTC_SBitCache_Lookup( sbits_cache,
                                    &current_font,
                                    Index,
                                    &sbit,
                                    NULL );
      if ( error )
        goto Exit;

      if ( sbit->buffer )
      {
        target->rows   = sbit->height;
        target->width  = sbit->width;
        target->pitch  = sbit->pitch;
        target->buffer = sbit->buffer;

        switch ( sbit->format )
        {
        case FT_PIXEL_MODE_MONO:
          target->mode  = gr_pixel_mode_mono;
          target->grays = 2;
          break;

        case FT_PIXEL_MODE_GRAY:
          target->mode  = gr_pixel_mode_gray;
          target->grays = sbit->max_grays + 1;
          break;

        case FT_PIXEL_MODE_GRAY2:
        case FT_PIXEL_MODE_GRAY4:
          source.rows       = sbit->height;
          source.width      = sbit->width;
          source.pitch      = sbit->pitch;
          source.buffer     = sbit->buffer;
          source.pixel_mode = sbit->format;
          (void)FT_Bitmap_Convert( library, &source, &ft_bitmap, 1 );

          target->pitch  = ft_bitmap.pitch;
          target->buffer = ft_bitmap.buffer;
          target->mode   = gr_pixel_mode_gray;
          target->grays  = ft_bitmap.num_grays;
          break;

        case FT_PIXEL_MODE_LCD:
          target->mode  = lcd_mode == 2 ? gr_pixel_mode_lcd
                                        : gr_pixel_mode_lcd2;
          target->grays = sbit->max_grays + 1;
          break;

        case FT_PIXEL_MODE_LCD_V:
          target->mode  = lcd_mode == 4 ? gr_pixel_mode_lcdv
                                        : gr_pixel_mode_lcdv2;
          target->grays = sbit->max_grays + 1;
          break;

        default:
          return FT_Err_Invalid_Glyph_Format;
        }

        *left      = sbit->left;
        *top       = sbit->top;
        *x_advance = sbit->xadvance;
        *y_advance = sbit->yadvance;

        goto Exit;
      }
    }

    /* otherwise, use an image cache to store glyph outlines, and render */
    /* them on demand. we can thus support very large sizes easily..     */
    {
      FT_Glyph   glyf;

      error = FTC_ImageCache_Lookup( image_cache,
                                     &current_font,
                                     Index,
                                     &glyf,
                                     NULL );

      if ( !error )
        error = glyph_to_bitmap( glyf, target, left, top, x_advance, y_advance, aglyf );
    }

  Exit:
    /* don't accept a `missing' character with zero or negative width */
    if ( Index == 0 && *x_advance <= 0 )
      *x_advance = 1;

    return error;
  }


/* End */

⌨️ 快捷键说明

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