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

📄 ftstring.c

📁 freetype库的应用demo,里面包含freetype的很多实例
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************//*                                                                          *//*  The FreeType project -- a free and portable quality TrueType renderer.  *//*                                                                          *//*  Copyright 1996-2002, 2003, 2004 by                                      *//*  D. Turner, R.Wilhelm, and W. Lemberg                                    *//*                                                                          *//*                                                                          *//*  ftstring.c - simple text string display                                 *//*                                                                          *//****************************************************************************/#include <ft2build.h>#include FT_FREETYPE_H#include FT_GLYPH_H#include "common.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <stdarg.h>#include <math.h>#include "graph.h"#include "grfont.h"#define DIM_X  500#define DIM_Y  400#define CENTER_X  ( bit.width / 2 )#define CENTER_Y  ( bit.rows  / 2 )#define MAXPTSIZE  500                 /* dtp */  static char   Header[128];  static char*  new_header = 0;  static char*  Text = (char *)"The quick brown fox jumps over the lazy dog";  static FT_Library   library;      /* the FreeType library            */  static FT_Face      face;         /* the font face                   */  static FT_Error     error;        /* error returned by FreeType?     */  static FT_Encoding  encoding = FT_ENCODING_UNICODE;  static grSurface*   surface;      /* current display surface         */  static grBitmap     bit;          /* current display bitmap          */  static int  ptsize;               /* current point size */  static int  Num;  static int  Rotation = 0;  static int  Fail;  static int  hinted    = 1;        /* is glyph hinting active?        */  static int  antialias = 1;        /* is anti-aliasing active?        */  static int  use_sbits = 0;        /* do we use embedded bitmaps?     */  static int  kerning   = 2;        /* 0: no kerning;                  */                                    /* 1: `kern' values                */                                    /* 2: `kern' + side bearing errors */  static int  autohint  = 0;        /* is forced hinting active?       */  static int  use_gamma = 0;  static int  res = 72;             /* default resolution in dpi */  static grColor  fore_color = { 255 };  static int  graph_init  = 0;  static FT_Matrix  trans_matrix;  static int        transform = 0;  static FT_Vector  string_center;  typedef struct  TGlyph_  {    FT_UInt    glyph_index;         /* glyph index in face      */    FT_Vector  pos;                 /* position of glyph origin */    FT_Glyph   image;               /* glyph image              */  } TGlyph, *PGlyph;#define FLOOR( x )  ( (x) & -64 )#define CEIL( x )   ( ( (x) + 63 ) & -64 )#define TRUNC ( x)  ( (x) >> 6 )/****************************************************************************//****************************************************************************//****************************************************************************//****                                                                    ****//****                 U T I L I T Y   F U N C T I O N S                  ****//****                                                                    ****//****************************************************************************//****************************************************************************//****************************************************************************/#define DEBUGxxx#ifdef DEBUG#define LOG( x )  LogMessage##x#else#define LOG( x )  /* empty */#endif#ifdef DEBUG  static void  LogMessage( const char*  fmt, ... )  {    va_list  ap;    va_start( ap, fmt );    vfprintf( stderr, fmt, ap );    va_end( ap );  }#endif  /* PanicZ */  static void  PanicZ( const char* message )  {    fprintf( stderr, "%s\n  error = 0x%04x\n", message, error );    exit( 1 );  }  static unsigned long  make_tag( char  *s )  {    int            i;    unsigned long  l = 0;    for ( i = 0; i < 4; i++ )    {      if ( !s[i] )        break;      l <<= 8;      l  += (unsigned long)s[i];    }    return l;  }/****************************************************************************//****************************************************************************//****************************************************************************//****                                                                    ****//****                D I S P L A Y   M A N A G E M E N T                 ****//****                                                                    ****//****************************************************************************//****************************************************************************//****************************************************************************/#define MAX_GLYPHS 512  /*************************************************************************/  /*                                                                       */  /*  The following arrays are used to store the glyph set that makes      */  /*  up a string of text.                                                 */  /*                                                                       */  /*                                                                       */  static TGlyph  glyphs[MAX_GLYPHS];  static int     num_glyphs;  /*************************************************************************/  /*                                                                       */  /* Gamma correction.                                                     */  /*                                                                       */  /*                                                                       */  static double  gamma_value = 2.0f;  static FT_Byte gamma_ramp[256];  static void  init_gamma( void )  {    int i;    double gamma_inv = 1.0f / gamma_value;    for (i = 0; i < 256; i++)      gamma_ramp[i] = (FT_Byte)( pow((double)i / 255.0f, gamma_inv) * 255.0f );  }  static void  apply_gamma( grBitmap* bmp )  {    int       i, j;    FT_Byte*  buffer = (FT_Byte*) bmp->buffer;    for (i = 0; i < bmp->rows; i++)    {      for (j = 0; j < bmp->width; j++)        buffer[j] = (FT_Byte) gamma_ramp[buffer[j]];      buffer += bmp->pitch;    }  }  static void  draw_gamma_ramp( void )  {    int   i, x, y;    long  pitch = bit.pitch;    long  start = 0;    if ( pitch < 0 )      start = -pitch*(bit.rows-1);    x = (bit.width - 256) / 2;    y = (bit.rows + 256) / 2;    for (i = 0; i < 256; i++, x++)    {      bit.buffer[start + pitch*(y - gamma_ramp[i]) + x ] = 80;    }  }  /*************************************************************************/  /*                                                                       */  /* Initialize the display surface.                                       */  /*                                                                       */  /*                                                                       */  static int  init_display( void )  {    grInitDevices();    bit.mode  = gr_pixel_mode_gray;    bit.width = DIM_X;    bit.rows  = DIM_Y;    bit.grays = 256;    surface = grNewSurface( 0, &bit );    if ( !surface )      PanicZ( "could not allocate display surface\n" );    graph_init = 1;    return 0;  }  /*************************************************************************/  /*                                                                       */  /*  Clear the display surface.                                           */  /*                                                                       */  /*                                                                       */  static void  clear_display( void )  {    long  size = (long)bit.pitch * bit.rows;    if ( size < 0 )      size = -size;    memset( bit.buffer, 0, size );  }  static void  reset_scale( int  pointSize )  {    (void)FT_Set_Char_Size( face,                            pointSize << 6,                            pointSize << 6,                            res,                            res );  }  /*************************************************************************/  /*                                                                       */  /*  Layout a string of glyphs.  The glyphs are untransformed.            */  /*                                                                       */  /*                                                                       */  static void  layout_glyphs( void )  {    PGlyph     glyph = glyphs;    int        n;    FT_Vector  origin;    FT_Pos     origin_x       = 0;    FT_UInt    load_flags;    FT_UInt    prev_index     = 0;    FT_Pos     prev_rsb_delta = 0;    load_flags = FT_LOAD_DEFAULT | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;    if ( !hinted )      load_flags |= FT_LOAD_NO_HINTING;    if ( !use_sbits )      load_flags |= FT_LOAD_NO_BITMAP;    if ( autohint )      load_flags |= FT_LOAD_FORCE_AUTOHINT;    for ( n = 0; n < num_glyphs; n++, glyph++ )    {      /* compute glyph origin */      if ( kerning )      {        if ( prev_index )        {          FT_Vector  kern;          FT_Get_Kerning( face, prev_index, glyph->glyph_index,                          hinted ? FT_KERNING_DEFAULT : FT_KERNING_UNFITTED,                          &kern );          origin_x += kern.x;        }        prev_index = glyph->glyph_index;      }      /* clear existing image if there is one */      if ( glyph->image )        FT_Done_Glyph( glyph->image );      /* load the glyph image (in its native format) */      error = FT_Load_Glyph( face, glyph->glyph_index, load_flags );      if ( error )        continue;      if ( n && kerning > 1 )      {        if ( prev_rsb_delta - face->glyph->lsb_delta >= 32 )          origin_x -= 64;        else if ( prev_rsb_delta - face->glyph->lsb_delta < -32 )          origin_x += 64;      }      origin.x = origin_x;      origin.y = 0;      prev_rsb_delta = face->glyph->rsb_delta;      error = FT_Get_Glyph( face->glyph, &glyph->image );      if ( error )        continue;      glyph->pos = origin;      origin_x += face->glyph->advance.x;    }    string_center.x = ( origin_x / 2 ) & -64;    string_center.y = 0;    if ( transform && FT_IS_SCALABLE( face ) )      FT_Vector_Transform( &string_center, &trans_matrix );  }  /*************************************************************************/  /*                                                                       */  /* Render a given glyph vector set.                                      */  /*                                                                       */  /*                                                                       */  static void  render_string( FT_Pos  x, FT_Pos  y )  {    PGlyph     glyph = glyphs;    grBitmap   bit3;    int        n;    FT_Vector  delta;    /* first of all, we must compute the general delta for the glyph set */    delta.x = ( x << 6 ) - string_center.x;    delta.y = ( ( bit.rows - y ) << 6 ) - string_center.y;    for ( n = 0; n < num_glyphs; n++, glyph++ )    {      FT_Glyph   image;      FT_Vector  vec;      if ( !glyph->image )        continue;      /* copy image */      error = FT_Glyph_Copy( glyph->image, &image );      if ( error )        continue;      /* transform it */      vec = glyph->pos;      if ( FT_IS_SCALABLE( face ) )        FT_Vector_Transform( &vec, &trans_matrix );      vec.x += delta.x;      vec.y += delta.y;      if ( FT_IS_SCALABLE( face ) )        error = FT_Glyph_Transform( image, &trans_matrix, &vec );      if ( !error )      {        FT_BBox  bbox;        /* check bounding box; if it is not within the display surface, */        /* we don't need to render it                                   */        FT_Glyph_Get_CBox( image, FT_GLYPH_BBOX_PIXELS, &bbox );        if ( !FT_IS_SCALABLE( face ) )        {          vec.x = vec.x >> 6;          vec.y = vec.y >> 6;          bbox.xMin += vec.x;          bbox.xMax += vec.x;          bbox.yMin += vec.y;          bbox.yMax += vec.y;        }#if 0        if ( n == 0 )        {          fprintf( stderr, "bbox = [%ld %ld %ld %ld]\n",                    bbox.xMin, bbox.yMin, bbox.xMax, bbox.yMax );        }#endif        if ( bbox.xMax > 0         && bbox.yMax > 0        &&             bbox.xMin < bit.width && bbox.yMin < bit.rows )        {          /* convert to a bitmap -- destroy native image */          error = FT_Glyph_To_Bitmap( &image,                                      antialias ? FT_RENDER_MODE_NORMAL                                                : FT_RENDER_MODE_MONO,                                      0, 1 );          if ( !error )          {            FT_BitmapGlyph  bitmap = (FT_BitmapGlyph)image;            FT_Bitmap*      source = &bitmap->bitmap;            FT_Pos          x_top, y_top;#if 0            if ( n == 0 )            {              fprintf( stderr, "bearing = [%d %d] dims = [%d %d]\n",                       bitmap->left, bitmap->top, source->width, source->rows );            }#endif            bit3.rows   = source->rows;            bit3.width  = source->width;            bit3.pitch  = source->pitch;            bit3.buffer = source->buffer;            switch ( source->pixel_mode )            {            case FT_PIXEL_MODE_MONO:              bit3.mode = gr_pixel_mode_mono;              break;            case FT_PIXEL_MODE_GRAY:              bit3.mode  = gr_pixel_mode_gray;              bit3.grays = source->num_grays;              if (use_gamma)                apply_gamma(&bit3);              break;            default:              continue;            }            /* now render the bitmap into the display surface */            if ( FT_IS_SCALABLE( face ) )            {              x_top = bitmap->left;              y_top = bit.rows - bitmap->top;            }            else            {              x_top = vec.x - bitmap->left;              y_top = vec.y - bitmap->top;            }            grBlitGlyphToBitmap( &bit, &bit3, x_top, y_top, fore_color );          }        }      }      FT_Done_Glyph( image );    }  }  /*************************************************************************/  /*                                                                       */  /*  Convert a string of text into a glyph vector.                        */  /*                                                                       */  /*  XXX: For now, we perform a trivial conversion.                       */  /*                                                                       */  /*                                                                       */  static void  prepare_text( const unsigned char*  string )  {    const unsigned char*  p     = (const unsigned char*)string;    PGlyph                glyph = glyphs;    FT_UInt               glyph_index;    unsigned char         in_code;    unsigned long         codepoint = 0;    int                   expect;    if ( encoding )    {      error = FT_Select_Charmap( face, encoding );      if ( error )        PanicZ( "invalid charmap\n" );    }

⌨️ 快捷键说明

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