📄 ftmulti.c
字号:
/****************************************************************************//* *//* The FreeType project -- a free and portable quality TrueType renderer. *//* *//* Copyright 1996-2000, 2003, 2004, 2005 by *//* D. Turner, R.Wilhelm, and W. Lemberg *//* *//* *//* FTMulti- a simple multiple masters font viewer *//* *//* Press F1 when running this program to have a list of key-bindings *//* *//****************************************************************************/#include <ft2build.h>#include FT_FREETYPE_H#include FT_MULTIPLE_MASTERS_H#include "common.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <stdarg.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 */ char Header[128]; char* new_header = 0; const unsigned char* Text = (unsigned char*) "The quick brown fox jumps over the lazy dog 0123456789 " "\342\352\356\373\364\344\353\357\366\374\377\340\371\351\350\347 " "&#~\"\'(-`_^@)=+\260 ABCDEFGHIJKLMNOPQRSTUVWXYZ " "$\243^\250*\265\371%!\247:/;.,?<>"; FT_Library library; /* the FreeType library */ FT_Face face; /* the font face */ FT_Size size; /* the font size */ FT_GlyphSlot glyph; /* the glyph slot */ FT_Encoding encoding = FT_ENCODING_NONE; FT_Error error; /* error returned by FreeType? */ grSurface* surface; /* current display surface */ grBitmap bit; /* current display bitmap */ int num_glyphs; /* number of glyphs */ int ptsize; /* current point size */ int hinted = 1; /* is glyph hinting active? */ int antialias = 1; /* is anti-aliasing active? */ int use_sbits = 1; /* do we use embedded bitmaps? */ int low_prec = 0; /* force low precision */ int Num; /* current first glyph index */ int res = 72; static grColor fore_color = { 255 }; int Fail; unsigned char autorun; int graph_init = 0; int render_mode = 1; int use_grays = 1; FT_MM_Var *multimaster = NULL; FT_Fixed design_pos [T1_MAX_MM_AXIS]; FT_Fixed requested_pos[T1_MAX_MM_AXIS]; int requested_cnt = 0;#define RASTER_BUFF_SIZE 32768 char raster_buff[RASTER_BUFF_SIZE];#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; } static void parse_design_coords( char *s ) { for ( requested_cnt = 0; requested_cnt < T1_MAX_MM_AXIS && *s; requested_cnt++ ) { requested_pos[requested_cnt] = (FT_Fixed)( strtod( s, &s ) * 65536.0 ); while ( *s==' ' ) ++s; } } /* Clears the Bit bitmap/pixmap */ static void Clear_Display( void ) { long bitmap_size = (long)bit.pitch * bit.rows; if ( bitmap_size < 0 ) bitmap_size = -bitmap_size; memset( bit.buffer, 0, bitmap_size ); } /* Initialize the display bitmap named `bit' */ static void 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; }#define FLOOR( x ) ( (x) & -64 )#define CEIL( x ) ( ( (x) + 63 ) & -64 )#define TRUNC( x ) ( (x) >> 6 ) /* Render a single glyph with the `grays' component */ static FT_Error Render_Glyph( int x_offset, int y_offset ) { grBitmap bit3; FT_Pos x_top, y_top; /* first, render the glyph image into a bitmap */ if ( glyph->format != FT_GLYPH_FORMAT_BITMAP ) { error = FT_Render_Glyph( glyph, antialias ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO ); if ( error ) return error; } /* now blit it to our display screen */ bit3.rows = glyph->bitmap.rows; bit3.width = glyph->bitmap.width; bit3.pitch = glyph->bitmap.pitch; bit3.buffer = glyph->bitmap.buffer; switch ( glyph->bitmap.pixel_mode ) { case FT_PIXEL_MODE_MONO: bit3.mode = gr_pixel_mode_mono; bit3.grays = 0; break; case FT_PIXEL_MODE_GRAY: bit3.mode = gr_pixel_mode_gray; bit3.grays = glyph->bitmap.num_grays; } /* Then, blit the image to the target surface */ x_top = x_offset + glyph->bitmap_left; y_top = y_offset - glyph->bitmap_top; grBlitGlyphToBitmap( &bit, &bit3, x_top, y_top, fore_color ); return 0; } static void Reset_Scale( int pointSize ) { (void)FT_Set_Char_Size( face, pointSize << 6, pointSize << 6, res, res ); } static FT_Error LoadChar( int idx, int hint ) { int flags; flags = FT_LOAD_DEFAULT | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH; if ( !hint ) flags |= FT_LOAD_NO_HINTING; if ( !use_sbits ) flags |= FT_LOAD_NO_BITMAP; return FT_Load_Glyph( face, idx, flags ); } static FT_Error Render_All( int first_glyph, int pt_size ) { FT_F26Dot6 start_x, start_y, step_x, step_y, x, y; int i; start_x = 4; start_y = 36 + pt_size; step_x = size->metrics.x_ppem + 4; step_y = size->metrics.y_ppem + 10; x = start_x; y = start_y; i = first_glyph;#if 0 while ( i < first_glyph + 1 )#else while ( i < num_glyphs )#endif { if ( !( error = LoadChar( i, hinted ) ) ) {#ifdef DEBUG if ( i <= first_glyph + 6 ) { LOG(( "metrics[%02d] = [%x %x]\n", i, glyph->metrics.horiBearingX, glyph->metrics.horiAdvance )); if ( i == first_glyph + 6 ) LOG(( "-------------------------\n" )); }#endif Render_Glyph( x, y ); x += ( glyph->metrics.horiAdvance >> 6 ) + 1; if ( x + size->metrics.x_ppem > bit.width ) { x = start_x; y += step_y; if ( y >= bit.rows ) return FT_Err_Ok; } } else Fail++; i++; } return FT_Err_Ok; } static FT_Error Render_Text( int first_glyph ) { FT_F26Dot6 start_x, start_y, step_x, step_y, x, y; int i; const unsigned char* p; start_x = 4; start_y = 32 + size->metrics.y_ppem; step_x = size->metrics.x_ppem + 4; step_y = size->metrics.y_ppem + 10; x = start_x; y = start_y; i = first_glyph; p = Text; while ( i > 0 && *p ) { p++; i--; } while ( *p ) { if ( !( error = LoadChar( FT_Get_Char_Index( face, (unsigned char)*p ), hinted ) ) ) {#ifdef DEBUG if ( i <= first_glyph + 6 ) { LOG(( "metrics[%02d] = [%x %x]\n", i, glyph->metrics.horiBearingX, glyph->metrics.horiAdvance )); if ( i == first_glyph + 6 ) LOG(( "-------------------------\n" )); }#endif Render_Glyph( x, y ); x += ( glyph->metrics.horiAdvance >> 6 ) + 1; if ( x + size->metrics.x_ppem > bit.width ) { x = start_x; y += step_y; if ( y >= bit.rows ) return FT_Err_Ok; } } else Fail++; i++; p++; } return FT_Err_Ok; } static void Help( void ) { grEvent dummy_event; Clear_Display(); grGotoxy( 0, 0 ); grSetMargin( 2, 1 ); grGotobitmap( &bit ); grWriteln( "FreeType Multiple Masters Glyph Viewer - part of the FreeType test suite" ); grLn(); grWriteln( "This program is used to display all glyphs from one or" ); grWriteln( "several Multiple Masters font files, with the FreeType library."); grLn(); grWriteln( "Use the following keys:"); grLn(); grWriteln( " F1 or ? : display this help screen" ); grWriteln( " a : toggle anti-aliasing" ); grWriteln( " h : toggle outline hinting" ); grWriteln( " b : toggle embedded bitmaps" ); grWriteln( " l : toggle low precision rendering" ); grWriteln( " space : toggle rendering mode" ); grLn(); grWriteln( " n : next font" ); grWriteln( " p : previous font" ); grLn(); grWriteln( " Up : increase pointsize by 1 unit" ); grWriteln( " Down : decrease pointsize by 1 unit" ); grWriteln( " Page Up : increase pointsize by 10 units" ); grWriteln( " Page Down : decrease pointsize by 10 units" ); grLn(); grWriteln( " Right : increment first glyph index" ); grWriteln( " Left : decrement first glyph index" ); grLn(); grWriteln( " F3 : decrement first axis pos by 1/50th of its range" ); grWriteln( " F4 : increment first axis pos by 1/50th of its range" ); grWriteln( " F5 : decrement second axis pos by 1/50th of its range" ); grWriteln( " F6 : increment second axis pos by 1/50th of its range" ); grWriteln( " F7 : decrement third axis pos by 1/50th of its range" ); grWriteln( " F8 : increment third axis pos by 1/50th of its range" ); grWriteln( " F9 : decrement index by 100" ); grWriteln( " F10 : increment index by 100" ); grWriteln( " F11 : decrement index by 1000" ); grWriteln( " F12 : increment index by 1000" ); grLn(); grWriteln( "press any key to exit this help screen" ); grRefreshSurface( surface ); grListenSurface( surface, gr_event_key, &dummy_event ); } static int
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -