Al-Qurtas-Islamic-bank-The-.../src/sfnt/sfobjs.c

544 lines
17 KiB
C
Raw Normal View History

/***************************************************************************/
/* */
/* sfobjs.c */
/* */
/* SFNT object management (base). */
/* */
/* Copyright 1996-2000 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. */
/* */
/***************************************************************************/
#include <freetype/internal/ftobjs.h>
2000-05-28 19:15:37 +02:00
#include <freetype/internal/sfnt.h>
#include <freetype/internal/psnames.h>
#include <freetype/ttnameid.h>
2000-05-28 19:15:37 +02:00
/*************************************************************************/
/* */
/* <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> */
/* Character string. NULL if no name is present. */
2000-05-28 19:15:37 +02:00
/* */
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;
2000-05-28 19:15:37 +02:00
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 */
2000-05-28 19:15:37 +02:00
if ( rec->platformID == TT_PLATFORM_MICROSOFT &&
rec->encodingID <= TT_MS_ID_UNICODE_CS &&
( rec->languageID & 0x3FF ) == 0x009 )
2000-05-28 19:15:37 +02:00
found = 1;
/* test for Apple Unicode encoding */
2000-05-28 19:15:37 +02:00
else if ( rec->platformID == TT_PLATFORM_APPLE_UNICODE )
found = 1;
/* test for Apple Roman */
2000-05-28 19:15:37 +02:00
else if ( rec->platformID == TT_PLATFORM_MACINTOSH &&
rec->languageID == TT_MAC_ID_ROMAN )
{
found = 1;
wide_chars = 0;
}
/* found a Unicode name */
2000-05-28 19:15:37 +02:00
if ( found )
{
FT_String* string;
FT_UInt len;
2000-05-28 19:15:37 +02:00
if ( wide_chars )
{
TT_UInt m;
2000-05-28 19:15:37 +02:00
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];
2000-05-28 19:15:37 +02:00
}
else
{
len = rec->stringLength;
if ( MEM_Alloc( string, len + 1 ) )
return NULL;
MEM_Copy( string, rec->string, len );
}
string[len] = '\0';
return string;
}
}
}
2000-05-28 19:15:37 +02:00
return NULL;
}
static
FT_Encoding find_encoding( int platform_id,
int encoding_id )
2000-05-28 19:15:37 +02:00
{
typedef struct TEncoding
{
int platform_id;
int encoding_id;
FT_Encoding encoding;
} TEncoding;
static const TEncoding tt_encodings[] =
2000-05-28 19:15:37 +02:00
{
{ TT_PLATFORM_ISO, -1, ft_encoding_unicode },
2000-05-28 19:15:37 +02:00
{ TT_PLATFORM_APPLE_UNICODE, -1, ft_encoding_unicode },
2000-05-28 19:15:37 +02:00
{ TT_PLATFORM_MACINTOSH, TT_MAC_ID_ROMAN, ft_encoding_apple_roman },
2000-05-28 19:15:37 +02:00
{ 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_GB2312, ft_encoding_gb2312 },
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_BIG_5, ft_encoding_big5 },
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_WANSUNG, ft_encoding_wansung },
{ TT_PLATFORM_MICROSOFT, TT_MS_ID_JOHAB, ft_encoding_johab }
2000-05-28 19:15:37 +02:00
};
const TEncoding *cur, *limit;
2000-05-28 19:15:37 +02:00
cur = tt_encodings;
limit = cur + sizeof ( tt_encodings ) / sizeof ( tt_encodings[0] );
2000-05-28 19:15:37 +02:00
for ( ; cur < limit; cur++ )
{
if ( cur->platform_id == platform_id )
2000-05-28 19:15:37 +02:00
{
if ( cur->encoding_id == encoding_id ||
cur->encoding_id == -1 )
2000-05-28 19:15:37 +02:00
return cur->encoding;
}
}
2000-05-28 19:15:37 +02:00
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;
SFNT_Header sfnt_header;
2000-05-28 19:15:37 +02:00
/* for now, parameters are unused */
UNUSED( num_params );
UNUSED( params );
2000-05-28 19:15:37 +02:00
sfnt = (SFNT_Interface*)face->sfnt;
if ( !sfnt )
2000-05-28 19:15:37 +02:00
{
/* look-up the SFNT driver */
FT_Driver sfnt_driver;
2000-05-28 19:15:37 +02:00
sfnt_driver = FT_Get_Driver( face->root.driver->library, "sfnt" );
if ( !sfnt_driver )
2000-05-28 19:15:37 +02:00
{
error = FT_Err_Invalid_File_Format;
goto Exit;
}
sfnt = (SFNT_Interface*)( sfnt_driver->interface.format_interface );
if ( !sfnt )
2000-05-28 19:15:37 +02:00
{
error = FT_Err_Invalid_File_Format;
goto Exit;
}
face->sfnt = sfnt;
face->goto_table = sfnt->goto_table;
}
psnames = (PSNames_Interface*)face->psnames;
if ( !psnames )
2000-05-28 19:15:37 +02:00
{
/* look-up the PSNames driver */
FT_Driver psnames_driver;
2000-05-28 19:15:37 +02:00
psnames_driver = FT_Get_Driver( face->root.driver->library, "psnames" );
if ( psnames_driver )
2000-05-28 19:15:37 +02:00
face->psnames = (PSNames_Interface*)
( psnames_driver->interface.format_interface );
2000-05-28 19:15:37 +02:00
}
/* check that we have a valid TrueType file */
error = sfnt->load_sfnt_header( face, stream, face_index, &sfnt_header );
if ( error )
2000-06-05 16:32:32 +02:00
goto Exit;
2000-05-28 19:15:37 +02:00
face->format_tag = sfnt_header.format_tag;
face->num_tables = sfnt_header.num_tables;
2000-05-28 19:15:37 +02:00
/* Load font directory */
error = sfnt->load_directory( face, stream, &sfnt_header );
if ( error )
goto Exit;
2000-05-28 19:15:37 +02:00
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 )
2000-05-28 19:15:37 +02:00
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;
2000-05-28 19:15:37 +02:00
/* Load tables */
if ( LOAD_( header ) ||
LOAD_( max_profile ) ||
/* load the `hhea' & `hmtx' tables at once */
( error = sfnt->load_metrics( face, stream, 0 ) ) != FT_Err_Ok ||
2000-05-28 19:15:37 +02:00
/* try to load the `vhea' & `vmtx' at once if present */
( error = sfnt->load_metrics( face, stream, 1 ) ) != FT_Err_Ok ||
2000-05-28 19:15:37 +02:00
LOAD_( charmaps ) ||
LOAD_( names ) ||
LOAD_( os2 ) ||
LOAD_( psnames ) )
goto Exit;
/* the optional tables */
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
/* embedded bitmap support. */
if ( sfnt->load_sbits && LOAD_( sbits ) )
goto Exit;
#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
2000-05-28 19:15:37 +02:00
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;
2000-05-28 19:15:37 +02:00
memory = root->memory;
/*********************************************************************/
/* */
/* Compute face flags. */
/* */
2000-05-28 19:15:37 +02:00
flags = FT_FACE_FLAG_SCALABLE | /* scalable outlines */
FT_FACE_FLAG_SFNT | /* SFNT file format */
FT_FACE_FLAG_HORIZONTAL; /* horizontal data */
/* fixed width font? */
2000-05-28 19:15:37 +02:00
if ( face->postscript.isFixedPitch )
flags |= FT_FACE_FLAG_FIXED_WIDTH;
/* vertical information? */
2000-05-28 19:15:37 +02:00
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. */
/* */
2000-05-28 19:15:37 +02:00
flags = 0;
if ( face->os2.version != 0xFFFF )
{
/* we have an OS/2 table; use the `fsSelection' field */
2000-05-28 19:15:37 +02:00
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 */
2000-05-28 19:15:37 +02:00
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. */
/* */
2000-05-28 19:15:37 +02:00
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;
2000-05-28 19:15:37 +02:00
charmap->root.face = (FT_Face)face;
charmap->root.platform_id = platform;
charmap->root.encoding_id = encoding;
charmap->root.encoding = find_encoding( platform, encoding );
2000-05-28 19:15:37 +02:00
/* now, set root->charmap with a unicode charmap */
/* wherever available */
if ( !root->charmap &&
charmap->root.encoding == ft_encoding_unicode )
2000-05-28 19:15:37 +02:00
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;
}
2000-05-28 19:15:37 +02:00
}
else
#else /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
2000-05-28 19:15:37 +02:00
{
root->num_fixed_sizes = 0;
root->available_sizes = 0;
}
#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
/*********************************************************************/
/* */
/* Set up metrics. */
/* */
2000-05-28 19:15:37 +02:00
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. */
2000-05-28 19:15:37 +02:00
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;
2000-05-28 19:15:37 +02:00
root->max_advance_height = face->vertical_info
? face->vertical.advance_Height_Max
: root->height;
2000-05-28 19:15:37 +02:00
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 )
2000-05-28 19:15:37 +02:00
{
/* destroy the postscript names table if it is loaded */
if ( sfnt->free_psnames )
2000-05-28 19:15:37 +02:00
sfnt->free_psnames( face );
/* destroy the embedded bitmaps table if it is loaded */
if ( sfnt->free_sbits )
2000-05-28 19:15:37 +02:00
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;
2000-05-28 19:15:37 +02:00
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;
}
/* END */