oops, forgot to commit these files
This commit is contained in:
parent
2e421319fc
commit
241e151eb2
|
@ -0,0 +1,809 @@
|
||||||
|
/****************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* The FreeType project -- a free and portable quality TrueType renderer. */
|
||||||
|
/* */
|
||||||
|
/* Copyright 1996-1999 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 <freetype/freetype.h>
|
||||||
|
#include <freetype/ftraster.h>
|
||||||
|
#include <freetype/ftgrays.h>
|
||||||
|
#include <freetype/ftmm.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 jumped 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_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;
|
||||||
|
|
||||||
|
/* the standard raster's interface */
|
||||||
|
FT_Raster_Funcs std_raster;
|
||||||
|
|
||||||
|
FT_Multi_Master multimaster;
|
||||||
|
FT_Long design_pos[ T1_MAX_MM_AXIS ];
|
||||||
|
|
||||||
|
#define RASTER_BUFF_SIZE 32768
|
||||||
|
char raster_buff[ RASTER_BUFF_SIZE ];
|
||||||
|
|
||||||
|
#define DEBUGxxx
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
#define LOG(x) LogMessage##x
|
||||||
|
#else
|
||||||
|
#define LOG(x) /* rien */
|
||||||
|
#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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Clears the Bit bitmap/pixmap */
|
||||||
|
static void Clear_Display( void )
|
||||||
|
{
|
||||||
|
long size = (long)bit.pitch * bit.rows;
|
||||||
|
|
||||||
|
if (size < 0) size = -size;
|
||||||
|
memset( bit.buffer, 0, size );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Initialize the display bitmap named Bit */
|
||||||
|
static int Init_Display()
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define MAX_BUFFER 300000
|
||||||
|
|
||||||
|
#define FLOOR(x) ((x) & -64)
|
||||||
|
#define CEIL(x) (((x)+63) & -64)
|
||||||
|
#define TRUNC(x) ((x) >> 6)
|
||||||
|
|
||||||
|
static
|
||||||
|
char bit_buffer[ MAX_BUFFER ];
|
||||||
|
|
||||||
|
/* Render a single glyph with the "grays" component */
|
||||||
|
static FT_Error Render_Glyph( int x_offset,
|
||||||
|
int y_offset )
|
||||||
|
{
|
||||||
|
/* first, render the glyph into an intermediate buffer */
|
||||||
|
FT_Bitmap bit2;
|
||||||
|
grBitmap bit3;
|
||||||
|
int width, height, pitch, size;
|
||||||
|
int left, right, top, bottom;
|
||||||
|
int x_top, y_top;
|
||||||
|
|
||||||
|
left = FLOOR( glyph->metrics.horiBearingX );
|
||||||
|
right = CEIL( glyph->metrics.horiBearingX + glyph->metrics.width );
|
||||||
|
width = TRUNC(right - left);
|
||||||
|
|
||||||
|
top = CEIL( glyph->metrics.horiBearingY );
|
||||||
|
bottom = FLOOR( glyph->metrics.horiBearingY - glyph->metrics.height );
|
||||||
|
height = TRUNC( top - bottom );
|
||||||
|
|
||||||
|
if ( glyph->format == ft_glyph_format_outline )
|
||||||
|
{
|
||||||
|
pitch = ( antialias ? (width+3) & -4 : (width+7) >> 3 );
|
||||||
|
size = pitch*height;
|
||||||
|
|
||||||
|
if (size > MAX_BUFFER)
|
||||||
|
return FT_Err_Out_Of_Memory;
|
||||||
|
|
||||||
|
bit2.width = width;
|
||||||
|
bit2.rows = height;
|
||||||
|
bit2.pitch = pitch;
|
||||||
|
bit2.pixel_mode = antialias ? ft_pixel_mode_grays : ft_pixel_mode_mono;
|
||||||
|
bit2.buffer = bit_buffer;
|
||||||
|
|
||||||
|
bit3.rows = bit2.rows;
|
||||||
|
bit3.width = bit2.width;
|
||||||
|
bit3.pitch = bit2.pitch;
|
||||||
|
bit3.mode = antialias ? bit.mode : gr_pixel_mode_mono;
|
||||||
|
bit3.buffer = bit_buffer;
|
||||||
|
bit3.grays = 256;
|
||||||
|
|
||||||
|
FT_Outline_Translate( &glyph->outline, -left, -bottom );
|
||||||
|
memset( bit_buffer, 0, size );
|
||||||
|
|
||||||
|
if (low_prec)
|
||||||
|
glyph->outline.flags &= ~ft_outline_high_precision;
|
||||||
|
|
||||||
|
error = FT_Outline_Get_Bitmap( library, &glyph->outline, &bit2 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bit3.rows = glyph->bitmap.rows;
|
||||||
|
bit3.width = glyph->bitmap.width;
|
||||||
|
bit3.pitch = glyph->bitmap.pitch;
|
||||||
|
bit3.mode = gr_pixel_mode_mono;
|
||||||
|
bit3.buffer = glyph->bitmap.buffer;
|
||||||
|
bit3.grays = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Then, blit the image to the target surface */
|
||||||
|
x_top = x_offset + TRUNC(left);
|
||||||
|
y_top = y_offset - TRUNC(top);
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (bit.pitch < 0)
|
||||||
|
y_top = bit.rows - y_top;
|
||||||
|
*/
|
||||||
|
grBlitGlyphToBitmap( &bit, &bit3, x_top, y_top, fore_color );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FT_Error Reset_Scale( int pointSize )
|
||||||
|
{
|
||||||
|
FT_Error error;
|
||||||
|
|
||||||
|
error = FT_Set_Char_Size( face, pointSize << 6,
|
||||||
|
pointSize << 6,
|
||||||
|
res,
|
||||||
|
res );
|
||||||
|
if ( error )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return FT_Err_Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static FT_Error LoadChar( int idx, int hint )
|
||||||
|
{
|
||||||
|
int flags;
|
||||||
|
|
||||||
|
flags = FT_LOAD_DEFAULT;
|
||||||
|
|
||||||
|
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 ptsize )
|
||||||
|
{
|
||||||
|
FT_F26Dot6 start_x, start_y, step_x, step_y, x, y;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
FT_Error error;
|
||||||
|
|
||||||
|
start_x = 4;
|
||||||
|
start_y = 36 + ptsize ;
|
||||||
|
|
||||||
|
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, int ptsize )
|
||||||
|
{
|
||||||
|
FT_F26Dot6 start_x, start_y, step_x, step_y, x, y;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
FT_Error error;
|
||||||
|
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( )
|
||||||
|
{
|
||||||
|
grEvent dummy_event;
|
||||||
|
|
||||||
|
Clear_Display();
|
||||||
|
grGotoxy( 0, 0 );
|
||||||
|
grSetMargin( 2, 1 );
|
||||||
|
grGotobitmap( &bit );
|
||||||
|
|
||||||
|
grWriteln("FreeType Glyph Viewer - part of the FreeType test suite" );
|
||||||
|
grLn();
|
||||||
|
grWriteln("This program is used to display all glyphs from one or" );
|
||||||
|
grWriteln("several 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(" g : toggle between 'smooth' and 'standard' anti-aliaser" );
|
||||||
|
grWriteln(" space : toggle rendering mode" );
|
||||||
|
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 position by 20" );
|
||||||
|
grWriteln(" F4 : increment first axis position by 20" );
|
||||||
|
grWriteln(" F3 : decrement second axis position by 20" );
|
||||||
|
grWriteln(" F4 : increment second axis position by 20" );
|
||||||
|
grWriteln(" F3 : decrement third axis position by 20" );
|
||||||
|
grWriteln(" F4 : increment third axis position by 20" );
|
||||||
|
grLn();
|
||||||
|
grWriteln("press any key to exit this help screen");
|
||||||
|
|
||||||
|
grRefreshSurface( surface );
|
||||||
|
grListenSurface( surface, gr_event_key, &dummy_event );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void reset_raster( void )
|
||||||
|
{
|
||||||
|
if ( antialias && use_grays )
|
||||||
|
FT_Set_Raster( library, &ft_grays_raster );
|
||||||
|
else
|
||||||
|
FT_Set_Raster( library, &std_raster );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int Process_Event( grEvent* event )
|
||||||
|
{
|
||||||
|
int i, axis;
|
||||||
|
|
||||||
|
switch ( event->key )
|
||||||
|
{
|
||||||
|
case grKeyEsc: /* ESC or q */
|
||||||
|
case grKEY('q'):
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case grKEY('a'):
|
||||||
|
antialias = !antialias;
|
||||||
|
new_header = ( antialias
|
||||||
|
? "anti-aliasing is now on"
|
||||||
|
: "anti-aliasing is now off" );
|
||||||
|
reset_raster();
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case grKEY('b'):
|
||||||
|
use_sbits = !use_sbits;
|
||||||
|
new_header = ( use_sbits
|
||||||
|
? "embedded bitmaps are now used when available"
|
||||||
|
: "embedded bitmaps are now ignored" );
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case grKEY('n'):
|
||||||
|
case grKEY('p'):
|
||||||
|
return (int)event->key;
|
||||||
|
|
||||||
|
case grKEY('g'):
|
||||||
|
use_grays = !use_grays;
|
||||||
|
new_header = ( use_grays
|
||||||
|
? "now using the smooth anti-aliaser"
|
||||||
|
: "now using the standard anti-aliaser" );
|
||||||
|
reset_raster();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case grKEY('l'):
|
||||||
|
low_prec = !low_prec;
|
||||||
|
new_header = ( low_prec
|
||||||
|
? "rendering precision is now forced to low"
|
||||||
|
: "rendering precision is now normal" );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case grKEY('h'):
|
||||||
|
hinted = !hinted;
|
||||||
|
new_header = ( hinted
|
||||||
|
? "glyph hinting is now active"
|
||||||
|
: "glyph hinting is now ignored" );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case grKEY(' '):
|
||||||
|
render_mode ^= 1;
|
||||||
|
new_header = ( render_mode
|
||||||
|
? "rendering all glyphs in font"
|
||||||
|
: "rendering test text string" );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case grKeyF1:
|
||||||
|
case grKEY('?'):
|
||||||
|
Help();
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case grKeyF3: i = -20; axis = 0; goto Do_Axis;
|
||||||
|
case grKeyF4: i = 20; axis = 0; goto Do_Axis;
|
||||||
|
case grKeyF5: i = -20; axis = 1; goto Do_Axis;
|
||||||
|
case grKeyF6: i = 20; axis = 1; goto Do_Axis;
|
||||||
|
case grKeyF7: i = -20; axis = 2; goto Do_Axis;
|
||||||
|
case grKeyF8: i = 20; axis = 2; goto Do_Axis;
|
||||||
|
|
||||||
|
case grKeyPageUp: i = 10; goto Do_Scale;
|
||||||
|
case grKeyPageDown: i = -10; goto Do_Scale;
|
||||||
|
case grKeyUp: i = 1; goto Do_Scale;
|
||||||
|
case grKeyDown: i = -1; goto Do_Scale;
|
||||||
|
|
||||||
|
case grKeyLeft: i = -1; goto Do_Glyph;
|
||||||
|
case grKeyRight: i = 1; goto Do_Glyph;
|
||||||
|
case grKeyF9: i = -100; goto Do_Glyph;
|
||||||
|
case grKeyF10: i = 100; goto Do_Glyph;
|
||||||
|
case grKeyF11: i = -1000; goto Do_Glyph;
|
||||||
|
case grKeyF12: i = 1000; goto Do_Glyph;
|
||||||
|
default:
|
||||||
|
;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
Do_Axis:
|
||||||
|
if (axis < multimaster.num_axis)
|
||||||
|
{
|
||||||
|
FT_MM_Axis* a = multimaster.axis + axis;
|
||||||
|
FT_Long pos = design_pos[axis];
|
||||||
|
|
||||||
|
pos += i;
|
||||||
|
if (pos < a->minimum) pos = a->minimum;
|
||||||
|
if (pos > a->maximum) pos = a->maximum;
|
||||||
|
|
||||||
|
design_pos[axis] = pos;
|
||||||
|
|
||||||
|
FT_Set_MM_Design_Coordinates( face, multimaster.num_axis, design_pos );
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
Do_Scale:
|
||||||
|
ptsize += i;
|
||||||
|
if (ptsize < 1) ptsize = 1;
|
||||||
|
if (ptsize > MAXPTSIZE) ptsize = MAXPTSIZE;
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
Do_Glyph:
|
||||||
|
Num += i;
|
||||||
|
if (Num < 0) Num = 0;
|
||||||
|
if (Num >= num_glyphs) Num = num_glyphs-1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void usage( char* execname )
|
||||||
|
{
|
||||||
|
fprintf( stderr, "\n" );
|
||||||
|
fprintf( stderr, "ftmulti: multiple masters font viewer - part of FreeType\n" );
|
||||||
|
fprintf( stderr, "--------------------------------------------------------\n" );
|
||||||
|
fprintf( stderr, "\n" );
|
||||||
|
fprintf( stderr, "Usage: %s [options below] ppem fontname[.ttf|.ttc] ...\n",
|
||||||
|
execname );
|
||||||
|
fprintf( stderr, "\n" );
|
||||||
|
fprintf( stderr, " -r R use resolution R dpi (default: 72 dpi)\n" );
|
||||||
|
fprintf( stderr, " -f index specify first glyph index to display\n" );
|
||||||
|
fprintf( stderr, "\n" );
|
||||||
|
|
||||||
|
exit( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main( int argc, char** argv )
|
||||||
|
{
|
||||||
|
int i, old_ptsize, orig_ptsize, file;
|
||||||
|
int first_glyph = 0;
|
||||||
|
int XisSetup = 0;
|
||||||
|
char filename[128 + 4];
|
||||||
|
char alt_filename[128 + 4];
|
||||||
|
char* execname;
|
||||||
|
int option;
|
||||||
|
int file_loaded;
|
||||||
|
|
||||||
|
FT_Error error;
|
||||||
|
grEvent event;
|
||||||
|
|
||||||
|
execname = ft_basename( argv[0] );
|
||||||
|
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
option = getopt( argc, argv, "f:r:" );
|
||||||
|
|
||||||
|
if ( option == -1 )
|
||||||
|
break;
|
||||||
|
|
||||||
|
switch ( option )
|
||||||
|
{
|
||||||
|
case 'f':
|
||||||
|
first_glyph = atoi( optarg );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'r':
|
||||||
|
res = atoi( optarg );
|
||||||
|
if ( res < 1 )
|
||||||
|
usage( execname );
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
usage( execname );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
argc -= optind;
|
||||||
|
argv += optind;
|
||||||
|
|
||||||
|
if ( argc <= 1 )
|
||||||
|
usage( execname );
|
||||||
|
|
||||||
|
if ( sscanf( argv[0], "%d", &orig_ptsize ) != 1 )
|
||||||
|
orig_ptsize = 64;
|
||||||
|
|
||||||
|
file = 1;
|
||||||
|
|
||||||
|
/* Initialize engine */
|
||||||
|
error = FT_Init_FreeType( &library );
|
||||||
|
if (error) PanicZ( "Could not initialise FreeType library" );
|
||||||
|
|
||||||
|
/* retrieve the standard raster's interface */
|
||||||
|
(void)FT_Get_Raster( library, ft_glyph_format_outline, &std_raster );
|
||||||
|
reset_raster();
|
||||||
|
|
||||||
|
NewFile:
|
||||||
|
ptsize = orig_ptsize;
|
||||||
|
hinted = 1;
|
||||||
|
file_loaded = 0;
|
||||||
|
|
||||||
|
#ifndef macintosh
|
||||||
|
i = strlen( argv[file] );
|
||||||
|
while ( i > 0 && argv[file][i] != '\\' && argv[file][i] != '/' )
|
||||||
|
{
|
||||||
|
if ( argv[file][i] == '.' )
|
||||||
|
i = 0;
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
filename[128] = '\0';
|
||||||
|
alt_filename[128] = '\0';
|
||||||
|
|
||||||
|
strncpy( filename, argv[file], 128 );
|
||||||
|
strncpy( alt_filename, argv[file], 128 );
|
||||||
|
|
||||||
|
#ifndef macintosh
|
||||||
|
if ( i >= 0 )
|
||||||
|
{
|
||||||
|
strncpy( filename + strlen( filename ), ".ttf", 4 );
|
||||||
|
strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Load face */
|
||||||
|
error = FT_New_Face( library, filename, 0, &face );
|
||||||
|
if (error) goto Display_Font;
|
||||||
|
|
||||||
|
/* retrieve multiple master information */
|
||||||
|
error = FT_Get_Multi_Master( face, &multimaster );
|
||||||
|
if (error) goto Display_Font;
|
||||||
|
|
||||||
|
/* set the current position to the minimum of each axis */
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
|
for ( n = 0; n < multimaster.num_axis; n++ )
|
||||||
|
design_pos[n] =
|
||||||
|
(multimaster.axis[n].minimum + multimaster.axis[n].maximum)/2;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = FT_Set_MM_Design_Coordinates( face, multimaster.num_axis, design_pos );
|
||||||
|
if (error) goto Display_Font;
|
||||||
|
|
||||||
|
file_loaded++;
|
||||||
|
|
||||||
|
error = Reset_Scale( ptsize );
|
||||||
|
if (error) goto Display_Font;
|
||||||
|
|
||||||
|
num_glyphs = face->num_glyphs;
|
||||||
|
glyph = face->glyph;
|
||||||
|
size = face->size;
|
||||||
|
|
||||||
|
Display_Font:
|
||||||
|
/* initialise graphics if needed */
|
||||||
|
if ( !XisSetup )
|
||||||
|
{
|
||||||
|
XisSetup = 1;
|
||||||
|
Init_Display();
|
||||||
|
}
|
||||||
|
|
||||||
|
grSetTitle( surface, "FreeType Glyph Viewer - press F1 for help" );
|
||||||
|
old_ptsize = ptsize;
|
||||||
|
|
||||||
|
if ( file_loaded >= 1 )
|
||||||
|
{
|
||||||
|
Fail = 0;
|
||||||
|
Num = first_glyph;
|
||||||
|
|
||||||
|
if ( Num >= num_glyphs )
|
||||||
|
Num = num_glyphs-1;
|
||||||
|
|
||||||
|
if ( Num < 0 )
|
||||||
|
Num = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( ;; )
|
||||||
|
{
|
||||||
|
int key;
|
||||||
|
|
||||||
|
Clear_Display();
|
||||||
|
|
||||||
|
if ( file_loaded >= 1 )
|
||||||
|
{
|
||||||
|
switch (render_mode)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
Render_Text( Num, ptsize );
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Render_All( Num, ptsize );
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf( Header, "%s %s (file %s)",
|
||||||
|
face->family_name,
|
||||||
|
face->style_name,
|
||||||
|
ft_basename( filename ) );
|
||||||
|
|
||||||
|
if (!new_header)
|
||||||
|
new_header = Header;
|
||||||
|
|
||||||
|
grWriteCellString( &bit, 0, 0, new_header, fore_color );
|
||||||
|
new_header = 0;
|
||||||
|
|
||||||
|
sprintf( Header, "axis: " );
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
for ( n = 0; n < multimaster.num_axis; n++ )
|
||||||
|
{
|
||||||
|
char temp[32];
|
||||||
|
sprintf( temp, " %s:%ld", multimaster.axis[n].name, design_pos[n] );
|
||||||
|
strcat( Header, temp );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
grWriteCellString( &bit, 0, 16, Header, fore_color );
|
||||||
|
|
||||||
|
sprintf( Header, "at %d points, first glyph = %d",
|
||||||
|
ptsize,
|
||||||
|
Num );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sprintf( Header, "%s : is not a multiple masters font file or could not be opened",
|
||||||
|
ft_basename(filename) );
|
||||||
|
}
|
||||||
|
|
||||||
|
grWriteCellString( &bit, 0, 8, Header, fore_color );
|
||||||
|
grRefreshSurface( surface );
|
||||||
|
|
||||||
|
grListenSurface( surface, 0, &event );
|
||||||
|
if ( !( key = Process_Event( &event ) ) )
|
||||||
|
goto Fin;
|
||||||
|
|
||||||
|
if ( key == 'n' )
|
||||||
|
{
|
||||||
|
if (file_loaded >= 1)
|
||||||
|
FT_Done_Face( face );
|
||||||
|
|
||||||
|
if ( file < argc - 1 )
|
||||||
|
file++;
|
||||||
|
|
||||||
|
goto NewFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( key == 'p' )
|
||||||
|
{
|
||||||
|
if (file_loaded >= 1)
|
||||||
|
FT_Done_Face( face );
|
||||||
|
|
||||||
|
if ( file > 1 )
|
||||||
|
file--;
|
||||||
|
|
||||||
|
goto NewFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ptsize != old_ptsize )
|
||||||
|
{
|
||||||
|
if ( Reset_Scale( ptsize ) )
|
||||||
|
PanicZ( "Could not resize font." );
|
||||||
|
|
||||||
|
old_ptsize = ptsize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Fin:
|
||||||
|
#if 0
|
||||||
|
grDoneSurface(surface);
|
||||||
|
grDone();
|
||||||
|
#endif
|
||||||
|
printf( "Execution completed successfully.\n" );
|
||||||
|
printf( "Fails = %d\n", Fail );
|
||||||
|
|
||||||
|
exit( 0 ); /* for safety reasons */
|
||||||
|
return 0; /* never reached */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* End */
|
||||||
|
|
|
@ -0,0 +1,499 @@
|
||||||
|
#include <freetype/internal/sfnt.h>
|
||||||
|
#include <freetype/internal/psnames.h>
|
||||||
|
#include <freetype/ttnameid.h>
|
||||||
|
|
||||||
|
/*************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* <Function> */
|
||||||
|
/* Get_Name */
|
||||||
|
/* */
|
||||||
|
/* <Description> */
|
||||||
|
/* Returns a given ENGLISH name record in ASCII. */
|
||||||
|
/* */
|
||||||
|
/* <Input> */
|
||||||
|
/* face :: A handle to the source face object. */
|
||||||
|
/* */
|
||||||
|
/* nameid :: The name id of the name record to return. */
|
||||||
|
/* */
|
||||||
|
/* <Return> */
|
||||||
|
/* Char string. NULL if no name is present. */
|
||||||
|
/* */
|
||||||
|
static
|
||||||
|
FT_String* Get_Name( TT_Face face,
|
||||||
|
FT_UShort nameid )
|
||||||
|
{
|
||||||
|
FT_Memory memory = face->root.memory;
|
||||||
|
FT_UShort n;
|
||||||
|
TT_NameRec* rec;
|
||||||
|
FT_Bool wide_chars = 1;
|
||||||
|
|
||||||
|
/* first pass, look for a given name record */
|
||||||
|
rec = face->name_table.names;
|
||||||
|
for ( n = 0; n < face->name_table.numNameRecords; n++, rec++ )
|
||||||
|
{
|
||||||
|
if ( rec->nameID == nameid )
|
||||||
|
{
|
||||||
|
/* found the name - now create an ASCII string from it */
|
||||||
|
FT_Bool found = 0;
|
||||||
|
|
||||||
|
/* Test for Microsoft English language */
|
||||||
|
if ( rec->platformID == TT_PLATFORM_MICROSOFT &&
|
||||||
|
rec->encodingID <= TT_MS_ID_UNICODE_CS &&
|
||||||
|
(rec->languageID & 0x3FF) == 0x009 )
|
||||||
|
found = 1;
|
||||||
|
|
||||||
|
/* Test for Apple Unicode encoding */
|
||||||
|
else if ( rec->platformID == TT_PLATFORM_APPLE_UNICODE )
|
||||||
|
found = 1;
|
||||||
|
|
||||||
|
/* Test for Apple Roman */
|
||||||
|
else if ( rec->platformID == TT_PLATFORM_MACINTOSH &&
|
||||||
|
rec->languageID == TT_MAC_ID_ROMAN )
|
||||||
|
{
|
||||||
|
found = 1;
|
||||||
|
wide_chars = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Found a Unicode Name */
|
||||||
|
if ( found )
|
||||||
|
{
|
||||||
|
FT_String* string;
|
||||||
|
FT_UInt len;
|
||||||
|
|
||||||
|
if ( wide_chars )
|
||||||
|
{
|
||||||
|
TT_UInt m;
|
||||||
|
|
||||||
|
len = (TT_UInt)rec->stringLength / 2;
|
||||||
|
if ( MEM_Alloc( string, len + 1 ) )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for ( m = 0; m < len; m ++ )
|
||||||
|
string[m] = rec->string[2*m + 1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
len = rec->stringLength;
|
||||||
|
if ( MEM_Alloc( string, len + 1 ) )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
MEM_Copy( string, rec->string, len );
|
||||||
|
}
|
||||||
|
|
||||||
|
string[len] = '\0';
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
FT_Encoding find_encoding( int platform_id,
|
||||||
|
int encoding_id )
|
||||||
|
{
|
||||||
|
typedef struct TEncoding
|
||||||
|
{
|
||||||
|
int platform_id;
|
||||||
|
int encoding_id;
|
||||||
|
FT_Encoding encoding;
|
||||||
|
|
||||||
|
} TEncoding;
|
||||||
|
|
||||||
|
static
|
||||||
|
const TEncoding tt_encodings[] =
|
||||||
|
{
|
||||||
|
{ TT_PLATFORM_ISO, -1, ft_encoding_unicode },
|
||||||
|
|
||||||
|
{ TT_PLATFORM_APPLE_UNICODE, -1, ft_encoding_unicode },
|
||||||
|
|
||||||
|
{ TT_PLATFORM_MACINTOSH, TT_MAC_ID_ROMAN, ft_encoding_apple_roman },
|
||||||
|
|
||||||
|
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_UNICODE_CS, ft_encoding_unicode },
|
||||||
|
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_SJIS, ft_encoding_sjis },
|
||||||
|
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_BIG_5, ft_encoding_big5 }
|
||||||
|
};
|
||||||
|
|
||||||
|
const TEncoding *cur, *limit;
|
||||||
|
|
||||||
|
cur = tt_encodings;
|
||||||
|
limit = cur + sizeof(tt_encodings)/sizeof(tt_encodings[0]);
|
||||||
|
|
||||||
|
for ( ; cur < limit; cur++ )
|
||||||
|
{
|
||||||
|
if (cur->platform_id == platform_id)
|
||||||
|
{
|
||||||
|
if (cur->encoding_id == encoding_id ||
|
||||||
|
cur->encoding_id == -1 )
|
||||||
|
return cur->encoding;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ft_encoding_none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
LOCAL_FUNC
|
||||||
|
FT_Error SFNT_Init_Face( FT_Stream stream,
|
||||||
|
TT_Face face,
|
||||||
|
TT_Int face_index,
|
||||||
|
TT_Int num_params,
|
||||||
|
FT_Parameter* params )
|
||||||
|
{
|
||||||
|
FT_Error error;
|
||||||
|
SFNT_Interface* sfnt;
|
||||||
|
PSNames_Interface* psnames;
|
||||||
|
|
||||||
|
/* for now, parameters are unused */
|
||||||
|
UNUSED(num_params);
|
||||||
|
UNUSED(params);
|
||||||
|
|
||||||
|
sfnt = (SFNT_Interface*)face->sfnt;
|
||||||
|
if (!sfnt)
|
||||||
|
{
|
||||||
|
/* look-up the SFNT driver */
|
||||||
|
FT_Driver sfnt_driver;
|
||||||
|
|
||||||
|
sfnt_driver = FT_Get_Driver( face->root.driver->library, "sfnt" );
|
||||||
|
if (!sfnt_driver)
|
||||||
|
{
|
||||||
|
error = FT_Err_Invalid_File_Format;
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
sfnt = (SFNT_Interface*)(sfnt_driver->interface.format_interface);
|
||||||
|
if (!sfnt)
|
||||||
|
{
|
||||||
|
error = FT_Err_Invalid_File_Format;
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
face->sfnt = sfnt;
|
||||||
|
face->goto_table = sfnt->goto_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
psnames = (PSNames_Interface*)face->psnames;
|
||||||
|
if (!psnames)
|
||||||
|
{
|
||||||
|
/* look-up the PSNames driver */
|
||||||
|
FT_Driver psnames_driver;
|
||||||
|
|
||||||
|
psnames_driver = FT_Get_Driver( face->root.driver->library, "psnames" );
|
||||||
|
if (psnames_driver)
|
||||||
|
face->psnames = (PSNames_Interface*)
|
||||||
|
(psnames_driver->interface.format_interface);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check that we have a valid TrueType file */
|
||||||
|
error = sfnt->load_format_tag( face, stream, face_index,
|
||||||
|
&face->format_tag );
|
||||||
|
if (error) goto Exit;
|
||||||
|
|
||||||
|
/* Load font directory */
|
||||||
|
error = sfnt->load_directory( face, stream, face_index );
|
||||||
|
if ( error ) goto Exit;
|
||||||
|
|
||||||
|
face->root.num_faces = face->ttc_header.DirCount;
|
||||||
|
if ( face->root.num_faces < 1 )
|
||||||
|
face->root.num_faces = 1;
|
||||||
|
|
||||||
|
Exit:
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#undef LOAD_
|
||||||
|
#define LOAD_(x) ( (error = sfnt->load_##x( face, stream )) != FT_Err_Ok )
|
||||||
|
|
||||||
|
|
||||||
|
LOCAL_FUNC
|
||||||
|
TT_Error SFNT_Load_Face( FT_Stream stream,
|
||||||
|
TT_Face face,
|
||||||
|
TT_Int face_index,
|
||||||
|
TT_Int num_params,
|
||||||
|
FT_Parameter* params )
|
||||||
|
{
|
||||||
|
FT_Error error;
|
||||||
|
SFNT_Interface* sfnt = (SFNT_Interface*)face->sfnt;
|
||||||
|
|
||||||
|
/* Load tables */
|
||||||
|
if ( LOAD_( header ) ||
|
||||||
|
LOAD_( max_profile ) ||
|
||||||
|
|
||||||
|
(error = sfnt->load_metrics( face, stream, 0 )) != FT_Err_Ok ||
|
||||||
|
/* load the `hhea' & `hmtx' tables at once */
|
||||||
|
|
||||||
|
(error = sfnt->load_metrics( face, stream, 1 )) != FT_Err_Ok ||
|
||||||
|
/* try to load the `vhea' & `vmtx' at once if present */
|
||||||
|
|
||||||
|
LOAD_( charmaps ) ||
|
||||||
|
LOAD_( names ) ||
|
||||||
|
LOAD_( os2 ) ||
|
||||||
|
LOAD_( psnames ) )
|
||||||
|
goto Exit;
|
||||||
|
|
||||||
|
/* the optional tables */
|
||||||
|
|
||||||
|
/* embedded bitmap support. */
|
||||||
|
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
|
||||||
|
if (sfnt->load_sbits && LOAD_(sbits)) goto Exit;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ( LOAD_( hdmx ) ||
|
||||||
|
LOAD_( gasp ) ||
|
||||||
|
LOAD_( kerning ) ||
|
||||||
|
LOAD_( pclt ) )
|
||||||
|
goto Exit;
|
||||||
|
|
||||||
|
#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE
|
||||||
|
if ( ( error = TT_Extension_Create( face ) ) != FT_Err_Ok )
|
||||||
|
goto Exit;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
face->root.family_name = Get_Name( face, TT_NAME_ID_FONT_FAMILY );
|
||||||
|
face->root.style_name = Get_Name( face, TT_NAME_ID_FONT_SUBFAMILY );
|
||||||
|
|
||||||
|
/* now set up root fields */
|
||||||
|
{
|
||||||
|
FT_Face root = &face->root;
|
||||||
|
FT_Int flags;
|
||||||
|
TT_CharMap charmap;
|
||||||
|
TT_Int n;
|
||||||
|
FT_Memory memory;
|
||||||
|
|
||||||
|
memory = root->memory;
|
||||||
|
|
||||||
|
/*****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* Compute face flags. */
|
||||||
|
/* */
|
||||||
|
flags = FT_FACE_FLAG_SCALABLE | /* scalable outlines */
|
||||||
|
FT_FACE_FLAG_SFNT | /* SFNT file format */
|
||||||
|
FT_FACE_FLAG_HORIZONTAL; /* horizontal data */
|
||||||
|
|
||||||
|
/* fixed width font ? */
|
||||||
|
if ( face->postscript.isFixedPitch )
|
||||||
|
flags |= FT_FACE_FLAG_FIXED_WIDTH;
|
||||||
|
|
||||||
|
/* vertical information ? */
|
||||||
|
if ( face->vertical_info )
|
||||||
|
flags |= FT_FACE_FLAG_VERTICAL;
|
||||||
|
|
||||||
|
/* kerning available ? */
|
||||||
|
if ( face->kern_pairs )
|
||||||
|
flags |= FT_FACE_FLAG_KERNING;
|
||||||
|
|
||||||
|
root->face_flags = flags;
|
||||||
|
|
||||||
|
/*****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* Compute style flags. */
|
||||||
|
/* */
|
||||||
|
flags = 0;
|
||||||
|
|
||||||
|
if ( face->os2.version != 0xFFFF )
|
||||||
|
{
|
||||||
|
/* We have an OS/2 table, use the `fsSelection' field */
|
||||||
|
if ( face->os2.fsSelection & 1 )
|
||||||
|
flags |= FT_STYLE_FLAG_ITALIC;
|
||||||
|
|
||||||
|
if ( face->os2.fsSelection & 32 )
|
||||||
|
flags |= FT_STYLE_FLAG_BOLD;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* This is an old Mac font, use the header field */
|
||||||
|
if ( face->header.Mac_Style & 1 )
|
||||||
|
flags |= FT_STYLE_FLAG_BOLD;
|
||||||
|
|
||||||
|
if ( face->header.Mac_Style & 2 )
|
||||||
|
flags |= FT_STYLE_FLAG_ITALIC;
|
||||||
|
}
|
||||||
|
|
||||||
|
face->root.style_flags = flags;
|
||||||
|
|
||||||
|
/*****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* Polish the charmaps. */
|
||||||
|
/* */
|
||||||
|
/* Try to set the charmap encoding according to the platform & */
|
||||||
|
/* encoding ID of each charmap. */
|
||||||
|
/* */
|
||||||
|
charmap = face->charmaps;
|
||||||
|
root->num_charmaps = face->num_charmaps;
|
||||||
|
|
||||||
|
/* allocate table of pointers */
|
||||||
|
if ( ALLOC_ARRAY( root->charmaps, root->num_charmaps, FT_CharMap ) )
|
||||||
|
goto Exit;
|
||||||
|
|
||||||
|
for ( n = 0; n < root->num_charmaps; n++, charmap++ )
|
||||||
|
{
|
||||||
|
FT_Int platform = charmap->cmap.platformID;
|
||||||
|
FT_Int encoding = charmap->cmap.platformEncodingID;
|
||||||
|
|
||||||
|
charmap->root.face = (FT_Face)face;
|
||||||
|
charmap->root.platform_id = platform;
|
||||||
|
charmap->root.encoding_id = encoding;
|
||||||
|
charmap->root.encoding = find_encoding(platform,encoding);
|
||||||
|
|
||||||
|
/* now, set root->charmap with a unicode charmap wherever available */
|
||||||
|
if (!root->charmap && charmap->root.encoding == ft_encoding_unicode)
|
||||||
|
root->charmap = (FT_CharMap)charmap;
|
||||||
|
|
||||||
|
root->charmaps[n] = (FT_CharMap)charmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
|
||||||
|
if ( face->num_sbit_strikes )
|
||||||
|
{
|
||||||
|
face->root.num_fixed_sizes = face->num_sbit_strikes;
|
||||||
|
if ( ALLOC_ARRAY( face->root.available_sizes,
|
||||||
|
face->num_sbit_strikes,
|
||||||
|
FT_Bitmap_Size ) )
|
||||||
|
return error;
|
||||||
|
|
||||||
|
for ( n = 0 ; n < face->num_sbit_strikes ; n++ )
|
||||||
|
{
|
||||||
|
face->root.available_sizes[n].width =
|
||||||
|
face->sbit_strikes[n].x_ppem;
|
||||||
|
face->root.available_sizes[n].height =
|
||||||
|
face->sbit_strikes[n].y_ppem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
root->num_fixed_sizes = 0;
|
||||||
|
root->available_sizes = 0;
|
||||||
|
}
|
||||||
|
#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
|
||||||
|
|
||||||
|
/*****************************************************************/
|
||||||
|
/* */
|
||||||
|
/* Set up metrics. */
|
||||||
|
/* */
|
||||||
|
root->bbox.xMin = face->header.xMin;
|
||||||
|
root->bbox.yMin = face->header.yMin;
|
||||||
|
root->bbox.xMax = face->header.xMax;
|
||||||
|
root->bbox.yMax = face->header.yMax;
|
||||||
|
root->units_per_EM = face->header.Units_Per_EM;
|
||||||
|
|
||||||
|
/* The ascender/descender/height are computed from the OS/2 table */
|
||||||
|
/* when found. Otherwise, they're taken from the horizontal header */
|
||||||
|
if ( face->os2.version != 0xFFFF )
|
||||||
|
{
|
||||||
|
root->ascender = face->os2.sTypoAscender;
|
||||||
|
root->descender = -face->os2.sTypoDescender;
|
||||||
|
root->height = root->ascender + root->descender +
|
||||||
|
face->os2.sTypoLineGap;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
root->ascender = face->horizontal.Ascender;
|
||||||
|
root->descender = face->horizontal.Descender;
|
||||||
|
root->height = root->ascender + root->descender +
|
||||||
|
face->horizontal.Line_Gap;
|
||||||
|
}
|
||||||
|
|
||||||
|
root->max_advance_width = face->horizontal.advance_Width_Max;
|
||||||
|
|
||||||
|
root->max_advance_height = root->height;
|
||||||
|
if ( face->vertical_info )
|
||||||
|
root->max_advance_height = face->vertical.advance_Height_Max;
|
||||||
|
|
||||||
|
root->underline_position = face->postscript.underlinePosition;
|
||||||
|
root->underline_thickness = face->postscript.underlineThickness;
|
||||||
|
|
||||||
|
/* root->max_points - already set up */
|
||||||
|
/* root->max_contours - already set up */
|
||||||
|
}
|
||||||
|
|
||||||
|
Exit:
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#undef LOAD_
|
||||||
|
|
||||||
|
|
||||||
|
LOCAL_FUNC
|
||||||
|
void SFNT_Done_Face( TT_Face face )
|
||||||
|
{
|
||||||
|
FT_Memory memory = face->root.memory;
|
||||||
|
SFNT_Interface* sfnt = face->sfnt;
|
||||||
|
|
||||||
|
if (sfnt)
|
||||||
|
{
|
||||||
|
/* destroy the postscript names table if it is supported */
|
||||||
|
if (sfnt->free_psnames)
|
||||||
|
sfnt->free_psnames( face );
|
||||||
|
|
||||||
|
/* destroy the embedded bitmaps table if it is supported */
|
||||||
|
if (sfnt->free_sbits)
|
||||||
|
sfnt->free_sbits( face );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* freeing the kerning table */
|
||||||
|
FREE( face->kern_pairs );
|
||||||
|
face->num_kern_pairs = 0;
|
||||||
|
|
||||||
|
/* freeing the collection table */
|
||||||
|
FREE( face->ttc_header.TableDirectory );
|
||||||
|
face->ttc_header.DirCount = 0;
|
||||||
|
|
||||||
|
/* freeing table directory */
|
||||||
|
FREE( face->dir_tables );
|
||||||
|
face->num_tables = 0;
|
||||||
|
|
||||||
|
/* freeing the character mapping tables */
|
||||||
|
if (sfnt && sfnt->load_charmaps )
|
||||||
|
{
|
||||||
|
FT_UShort n;
|
||||||
|
for ( n = 0; n < face->num_charmaps; n++ )
|
||||||
|
sfnt->free_charmap( face, &face->charmaps[n].cmap );
|
||||||
|
}
|
||||||
|
|
||||||
|
FREE( face->charmaps );
|
||||||
|
face->num_charmaps = 0;
|
||||||
|
|
||||||
|
FREE( face->root.charmaps );
|
||||||
|
face->root.num_charmaps = 0;
|
||||||
|
face->root.charmap = 0;
|
||||||
|
|
||||||
|
/* freeing the horizontal metrics */
|
||||||
|
FREE( face->horizontal.long_metrics );
|
||||||
|
FREE( face->horizontal.short_metrics );
|
||||||
|
|
||||||
|
/* freeing the vertical ones, if any */
|
||||||
|
if ( face->vertical_info )
|
||||||
|
{
|
||||||
|
FREE( face->vertical.long_metrics );
|
||||||
|
FREE( face->vertical.short_metrics );
|
||||||
|
face->vertical_info = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* freeing the gasp table */
|
||||||
|
FREE( face->gasp.gaspRanges );
|
||||||
|
face->gasp.numRanges = 0;
|
||||||
|
|
||||||
|
/* freeing the name table */
|
||||||
|
sfnt->free_names( face );
|
||||||
|
|
||||||
|
/* freeing the hdmx table */
|
||||||
|
sfnt->free_hdmx( face );
|
||||||
|
|
||||||
|
/* freeing family and style name */
|
||||||
|
FREE( face->root.family_name );
|
||||||
|
FREE( face->root.style_name );
|
||||||
|
|
||||||
|
/* freeing sbit size table */
|
||||||
|
face->root.num_fixed_sizes = 0;
|
||||||
|
if ( face->root.available_sizes )
|
||||||
|
FREE( face->root.available_sizes );
|
||||||
|
|
||||||
|
face->sfnt = 0;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
/***************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* sfobjs.h */
|
||||||
|
/* */
|
||||||
|
/* SFNT object management */
|
||||||
|
/* */
|
||||||
|
/* Copyright 1996-1999 by */
|
||||||
|
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||||
|
/* */
|
||||||
|
/* This file is part of the FreeType project, and may only be used, */
|
||||||
|
/* modified, and distributed under the terms of the FreeType project */
|
||||||
|
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
|
||||||
|
/* this file you indicate that you have read the license and */
|
||||||
|
/* understand and accept it fully. */
|
||||||
|
/* */
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef SFOBJS_H
|
||||||
|
#define SFOBJS_H
|
||||||
|
|
||||||
|
#include <freetype/internal/sfnt.h>
|
||||||
|
#include <freetype/internal/ftobjs.h>
|
||||||
|
|
||||||
|
LOCAL_DEF
|
||||||
|
FT_Error SFNT_Init_Face( FT_Stream stream,
|
||||||
|
TT_Face face,
|
||||||
|
TT_Int face_index,
|
||||||
|
TT_Int num_params,
|
||||||
|
FT_Parameter* params );
|
||||||
|
|
||||||
|
LOCAL_DEF
|
||||||
|
FT_Error SFNT_Load_Face( FT_Stream stream,
|
||||||
|
TT_Face face,
|
||||||
|
TT_Int face_index,
|
||||||
|
TT_Int num_params,
|
||||||
|
FT_Parameter* params );
|
||||||
|
|
||||||
|
LOCAL_DEF
|
||||||
|
void SFNT_Done_Face( TT_Face face );
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* SFDRIVER_H */
|
||||||
|
|
||||||
|
|
||||||
|
/* END */
|
Loading…
Reference in New Issue