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

📄 ftcommon.c

📁 Demo for Free type 2.2.1
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************/
/*                                                                          */
/*  The FreeType project -- a free and portable quality TrueType renderer.  */
/*                                                                          */
/*  Copyright 2005, 2006 by                                                 */
/*  D. Turner, R.Wilhelm, and W. Lemberg                                    */
/*                                                                          */
/*                                                                          */
/*  ftcommon.c - common routines for the FreeType demo programs.            */
/*                                                                          */
/****************************************************************************/


#include <ft2build.h>
#include FT_FREETYPE_H

#include FT_CACHE_H
#include FT_CACHE_MANAGER_H

#include FT_BITMAP_H

#include "ftcommon.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>

  FT_Error   error;


#undef  NODEBUG

#ifndef NODEBUG

  void
  LogMessage( const char*  fmt, ... )
  {
    va_list  ap;


    va_start( ap, fmt );
    vfprintf( stderr, fmt, ap );
    va_end( ap );
  }

#endif /* NODEBUG */


  /* PanicZ */
  void
  PanicZ( const char*  message )
  {
    fprintf( stderr, "%s\n  error = 0x%04x\n", message, error );
    exit( 1 );
  }



  /*************************************************************************/
  /*************************************************************************/
  /*****                                                               *****/
  /*****                 DISPLAY-SPECIFIC DEFINITIONS                  *****/
  /*****                                                               *****/
  /*************************************************************************/
  /*************************************************************************/


#define DIM_X      500
#define DIM_Y      400


  FTDemo_Display*
  FTDemo_Display_New( grPixelMode  mode )
  {
    FTDemo_Display*  display;
    grSurface*       surface;
    grBitmap         bit;


    display = (FTDemo_Display *)malloc( sizeof( FTDemo_Display ) );
    if ( !display )
      return NULL;

    if ( mode != gr_pixel_mode_gray  &&
         mode != gr_pixel_mode_rgb24 )
      return NULL;

    grInitDevices();

    bit.mode  = mode;
    bit.width = DIM_X;
    bit.rows  = DIM_Y;
    bit.grays = 256;

    surface = grNewSurface( 0, &bit );

    if ( !surface )
    {
      free( display );
      return NULL;
    }

    display->surface = surface;
    display->bitmap  = &surface->bitmap;

    grSetGlyphGamma( 1.0 );

    memset( &display->fore_color, 0, sizeof( grColor ) );
    memset( &display->back_color, 0xff, sizeof( grColor ) );

    return display;
  }


  void
  FTDemo_Display_Done( FTDemo_Display*  display )
  {
    grDoneBitmap( display->bitmap );
    grDoneSurface( display->surface );

    grDoneDevices();

    free( display );
  }


  void
  FTDemo_Display_Clear( FTDemo_Display*  display )
  {
    grBitmap*  bit   = display->bitmap;
    int        pitch = bit->pitch;


    if ( pitch < 0 )
      pitch = -pitch;

    if ( bit->mode == gr_pixel_mode_gray )
      memset( bit->buffer, display->back_color.value, pitch * bit->rows );
    else
    {
      unsigned char*  p = bit->buffer;
      int             i, j;


      for ( i = 0; i < bit->rows; i++ )
      {
        for ( j = 0; j < bit->width; j++ )
          memcpy( p + 3 * j, display->back_color.chroma, 3 );

        p += pitch;
      }
    }
  }


  /*************************************************************************/
  /*************************************************************************/
  /*****                                                               *****/
  /*****               FREETYPE-SPECIFIC DEFINITIONS                   *****/
  /*****                                                               *****/
  /*************************************************************************/
  /*************************************************************************/


#define FLOOR( x )  (   (x)        & -64 )
#define CEIL( x )   ( ( (x) + 63 ) & -64 )
#define ROUND( x )  ( ( (x) + 32 ) & -64 )
#define TRUNC( x )  (   (x) >> 6 )



  static
  const char*  file_suffixes[] =
  {
    ".ttf",
    ".ttc",
    ".otf",
    ".pfa",
    ".pfb",
    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.   */
  /*                                                                       */
  static 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 );

    if ( font->file_address != NULL )
      error = FT_New_Memory_Face( lib, font->file_address, font->file_size,
                                  font->face_index, aface );
    else
      error = FT_New_Face( lib,
                           font->filepathname,
                           font->face_index,
                           aface );
    if ( !error )
    {
      char*  suffix;
      char   orig[4];


      suffix = strrchr( font->filepathname, '.' );
      if ( suffix && ( strcasecmp( suffix, ".pfa" ) == 0 ||
                       strcasecmp( suffix, ".pfb" ) == 0 ) )
      {
        suffix++;

        memcpy( orig, suffix, 4 );
        memcpy( suffix, "afm", 4 );
        FT_Attach_File( *aface, font->filepathname );

        memcpy( suffix, "pfm", 4 );
        FT_Attach_File( *aface, font->filepathname );
        memcpy( suffix, orig, 4 );
      }

      if ( (*aface)->charmaps )
        (*aface)->charmap = (*aface)->charmaps[font->cmap_index];
    }

    return error;
  }


  FTDemo_Handle*
  FTDemo_New( FT_Encoding encoding )
  {
    FTDemo_Handle*  handle;


    handle = (FTDemo_Handle *)malloc( sizeof( FTDemo_Handle ) );
    if ( !handle )
      return NULL;

    memset( handle, 0, sizeof( FTDemo_Handle ) );

    error = FT_Init_FreeType( &handle->library );
    if ( error )
      PanicZ( "could not initialize FreeType" );

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

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

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

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


    FT_Bitmap_New( &handle->bitmap );

    handle->encoding = encoding;

    handle->hinted    = 1;
    handle->antialias = 1;
    handle->use_sbits = 1;
    handle->low_prec  = 0;
    handle->autohint  = 0;
    handle->lcd_mode  = 0;

    handle->use_sbits_cache  = 1;

    /* string_init */
    memset( handle->string, 0, sizeof( TGlyph ) * MAX_GLYPHS );
    handle->string_length = 0;
    handle->string_reload = 1;

    return handle;
  }


  void
  FTDemo_Done( FTDemo_Handle*  handle )
  {
    int  i;


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

    /* string_done */
    for ( i = 0; i < MAX_GLYPHS; i++ )
    {
      PGlyph  glyph = handle->string + i;


      if ( glyph->image )
        FT_Done_Glyph( glyph->image );
    }

    FT_Bitmap_Done( handle->library, &handle->bitmap );
    FTC_Manager_Done( handle->cache_manager );
    FT_Done_FreeType( handle->library );

    free( handle );
  }


  FT_Error
  FTDemo_Install_Font( FTDemo_Handle*  handle,
                       const char*     filepath )
  {
    static char  filename[1024 + 5];
    int          i, len, num_faces;
    FT_Face      face;


    len = strlen( filepath );
    if ( len > 1024 )
      len = 1024;

    strncpy( filename, filepath, len );
    filename[len] = 0;

    error = FT_New_Face( handle->library, filename, 0, &face );

#ifndef macintosh
    /* could not open the file directly; we will now try various */
    /* suffixes like `.ttf' or `.pfb'                            */
    if ( error )
    {
      const char**  suffix;
      char*         p;
      int           found = 0;

      suffix = file_suffixes;
      p      = filename + len - 1;

      while ( p >= filename && *p != '\\' && *p != '/' )
      {
        if ( *p == '.' )
          break;

        p--;
      }

      /* no suffix found */
      if ( p < filename || *p != '.' )
        p = filename + len;

      for ( suffix = file_suffixes; suffix[0]; suffix++ )
      {
        /* try with current suffix */
        strcpy( p, suffix[0] );

        error = FT_New_Face( handle->library, filename, 0, &face );
        if ( !error )
        {
          found = 1;

          break;
        }
      }

      /* really couldn't open this file */
      if ( !found )
        return error;
    }
#endif /* !macintosh */

    /* allocate new font object */
    num_faces = face->num_faces;
    for ( i = 0; i < num_faces; i++ )
    {
      PFont  font;


      if ( i > 0 )
      {
        error = FT_New_Face( handle->library, filename, i, &face );
        if ( error )
          continue;
      }

      if ( handle->encoding != FT_ENCODING_NONE )
      {
        error = FT_Select_Charmap( face, handle->encoding );
        if ( error )
        {
          FT_Done_Face( face );
          return error;
        }
      }

      font = (PFont)malloc( sizeof ( *font ) );

      font->filepathname = (char*)malloc( strlen( filename ) + 1 );
      strcpy( (char*)font->filepathname, filename );

      font->face_index = i;
      font->cmap_index = face->charmap ? FT_Get_Charmap_Index( face->charmap )
                                       : 0;

      if ( handle->preload )
      {
        FILE*   file = fopen( filename, "rb" );
        size_t  file_size;

        if ( file == NULL )  /* shouldn't happen */
        {
          free( font );
          return FT_Err_Invalid_Argument;
        }

        fseek( file, 0, SEEK_END );
        file_size = ftell( file );
        fseek( file, 0, SEEK_SET );

        font->file_address = malloc( file_size );
        fread( font->file_address, 1, file_size, file );

        font->file_size    = file_size;

        fclose( file );
      }
      else
      {
        font->file_address = NULL;
        font->file_size    = 0;
      }

      switch ( handle->encoding )
      {
      case FT_ENCODING_NONE:
        font->num_indices = face->num_glyphs;
        break;

      case FT_ENCODING_UNICODE:
        font->num_indices = 0x110000L;
        break;

      case FT_ENCODING_MS_SYMBOL:
      case FT_ENCODING_ADOBE_LATIN_1:
      case FT_ENCODING_ADOBE_STANDARD:
      case FT_ENCODING_ADOBE_EXPERT:

⌨️ 快捷键说明

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