From: Robert Roebling Date: Sun, 13 Jan 2002 14:44:42 +0000 (+0000) Subject: Remove FreeType. X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/9c135b1ec72a7f17ce46bd1b0861e89afa594679?ds=inline Remove FreeType. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@13538 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/src/freetype/ftconfig.h b/src/freetype/ftconfig.h deleted file mode 100644 index f21a164bdd..0000000000 --- a/src/freetype/ftconfig.h +++ /dev/null @@ -1,168 +0,0 @@ -/* ftconfig.h. Generated automatically by configure. */ -/***************************************************************************/ -/* */ -/* ftconfig.in */ -/* */ -/* UNIX-specific configuration file (specification only). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This header file contains a number of macro definitions that are used */ - /* by the rest of the engine. Most of the macros here are automatically */ - /* determined at compile time, and you should not need to change it to */ - /* port FreeType, except to compile the library with a non-ANSI */ - /* compiler. */ - /* */ - /* Note however that if some specific modifications are needed, we */ - /* advise you to place a modified copy in your build directory. */ - /* */ - /* The build directory is usually `freetype/builds/', and */ - /* contains system-specific files that are always included first when */ - /* building the library. */ - /* */ - /*************************************************************************/ - - -#ifndef FTCONFIG_H -#define FTCONFIG_H - - - /* Include the header file containing all developer build options */ -#include - - - /*************************************************************************/ - /* */ - /* PLATFORM-SPECIFIC CONFIGURATION MACROS */ - /* */ - /* These macros can be toggled to suit a specific system. The current */ - /* ones are defaults used to compile FreeType in an ANSI C environment */ - /* (16bit compilers are also supported). Copy this file to your own */ - /* `freetype/builds/' directory, and edit it to port the engine. */ - /* */ - /*************************************************************************/ - - -#include "wx/setup.h" - -#define FT_SIZEOF_INT SIZEOF_INT -#define FT_SIZEOF_LONG SIZEOF_LONG - - - /* Preferred alignment of data */ -#define FT_ALIGNMENT 8 - - - /* UNUSED is a macro used to indicate that a given parameter is not used */ - /* -- this is only used to get rid of unpleasant compiler warnings */ -#ifndef FT_UNUSED -#define FT_UNUSED( arg ) ( (arg) = (arg) ) -#endif - - - /*************************************************************************/ - /* */ - /* AUTOMATIC CONFIGURATION MACROS */ - /* */ - /* These macros are computed from the ones defined above. Don't touch */ - /* their definition, unless you know precisely what you are doing. No */ - /* porter should need to mess with them. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* IntN types */ - /* */ - /* Used to guarantee the size of some specific integers. */ - /* */ - typedef signed short FT_Int16; - typedef unsigned short FT_UInt16; - -#if FT_SIZEOF_INT == 4 - - typedef signed int FT_Int32; - typedef unsigned int FT_UInt32; - -#elif FT_SIZEOF_LONG == 4 - - typedef signed long FT_Int32; - typedef unsigned long FT_UInt32; - -#else -#error "no 32bit type found -- please check your configuration files" -#endif - -#if FT_SIZEOF_LONG == 8 - - /* FT_LONG64 must be defined if a 64-bit type is available */ -#define FT_LONG64 -#define FT_INT64 long - -#else - - - /*************************************************************************/ - /* */ - /* Many compilers provide the non-ANSI `long long' 64-bit type. You can */ - /* activate it by defining the FTCALC_USE_LONG_LONG macro in */ - /* `ftoption.h'. */ - /* */ - /* Note that this will produce many -ansi warnings during library */ - /* compilation, and that in many cases, the generated code will be */ - /* neither smaller nor faster! */ - /* */ -#ifdef FTCALC_USE_LONG_LONG - -#define FT_LONG64 -#define FT_INT64 long long - -#endif /* FTCALC_USE_LONG_LONG */ -#endif /* FT_SIZEOF_LONG == 8 */ - - -#ifdef FT_MAKE_OPTION_SINGLE_OBJECT -#define LOCAL_DEF static -#define LOCAL_FUNC static -#else -#define LOCAL_DEF extern -#define LOCAL_FUNC /* nothing */ -#endif - -#ifdef FT_MAKE_OPTION_SINGLE_LIBRARY_OBJECT -#define BASE_DEF( x ) static x -#define BASE_FUNC( x ) static x -#else -#define BASE_DEF( x ) extern x -#define BASE_FUNC( x ) extern x -#endif - -#ifndef FT_EXPORT_DEF -#define FT_EXPORT_DEF( x ) extern x -#endif - -#ifndef FT_EXPORT_FUNC -#define FT_EXPORT_FUNC( x ) extern x -#endif - -#ifndef FT_EXPORT_VAR -#define FT_EXPORT_VAR( x ) extern x -#endif - -#endif /* FTCONFIG_H */ - - -/* END */ diff --git a/src/freetype/macfond/fonddrvr.c b/src/freetype/macfond/fonddrvr.c deleted file mode 100644 index 45a9141649..0000000000 --- a/src/freetype/macfond/fonddrvr.c +++ /dev/null @@ -1,616 +0,0 @@ -/***************************************************************************/ -/* */ -/* fonddrvr.c */ -/* */ -/* Mac FOND font driver. Written by just@letterror.com. */ -/* */ -/* Copyright 1996-2000 by */ -/* Just van Rossum, 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. */ -/* */ -/***************************************************************************/ - - -/* - Notes - - Mac suitcase files can (and often do!) contain multiple fonts. To - support this I use the face_index argument of FT_(Open|New)_Face() - functions, and pretend the suitcase file is a collection. - Warning: although the FOND driver sets face->num_faces field to the - number of available fonts, but the Type 1 driver sets it to 1 anyway. - So this field is currently not reliable, and I don't see a clean way - to resolve that. The face_index argument translates to - Get1IndResource( 'FOND', face_index + 1 ); - so clients should figure out the resource index of the FOND. - (I'll try to provide some example code for this at some point.) - - The Mac FOND driver works roughly like this: - - - Check whether the offered stream points to a Mac suitcase file. - This is done by checking the file type: it has to be 'FFIL' or 'tfil'. - The stream that gets passed to our init_face() routine is a stdio - stream, which isn't usable for us, since the FOND resources live - in the resource fork. So we just grab the stream->pathname field. - - - Read the FOND resource into memory, then check whether there is - a TrueType font and/or (!) a Type 1 font available. - - - If there is a Type 1 font available (as a separate 'LWFN' file), - read its data into memory, massage it slightly so it becomes - PFB data, wrap it into a memory stream, load the Type 1 driver - and delegate the rest of the work to it, by calling the init_face() - method of the Type 1 driver. - (XXX TODO: after this has been done, the kerning data from the FOND - resource should be appended to the face: on the Mac there are usually - no AFM files available. However, this is tricky since we need to map - Mac char codes to ps glyph names to glyph ID's...) - - - If there is a TrueType font (an 'sfnt' resource), read it into - memory, wrap it into a memory stream, load the TrueType driver - and delegate the rest of the work to it, by calling the init_face() - method if the TrueType driver. - - - In both cases, the original stream gets closed and *reinitialized* - to become a memory stream. Additionally, the face->driver field -- - which is set to the FOND driver upon entering our init_face() -- - gets *reset* to either the TT or the T1 driver. I had to make a minor - change to ftobjs.c to make this work. - - - We might consider creating an FT_New_Face_Mac() API call, as this - would avoid some of the mess described above. -*/ - -#include -#include - -#include -#include -#include - -#include /* for isupper() and isalnum() */ -#include /* for malloc() and free() */ - - -/* set PREFER_LWFN to 1 if LWFN (Type 1) is preferred over - TrueType in case *both* are available */ -#ifndef PREFER_LWFN -#define PREFER_LWFN 1 -#endif - - - static - FT_Error init_driver( FT_Driver driver ) - { - /* we don't keep no stinkin' state ;-) */ - return FT_Err_Ok; - } - - static - FT_Error done_driver( FT_Driver driver ) - { - return FT_Err_Ok; - } - - - /* MacRoman glyph names, needed for FOND kerning support. */ - /* XXX which is not implemented yet! */ - static const char* mac_roman_glyph_names[256] = { - ".null", - }; - - - /* The FOND face object is just a union of TT and T1: both is possible, - and we don't need anything else. We still need to be able to hold - either, as the face object is not allocated by us. Again, creating - an FT_New_Face_Mac() would avoid this kludge. */ - typedef union FOND_FaceRec_ - { - TT_FaceRec tt; - T1_FaceRec t1; - } FOND_FaceRec, *FOND_Face; - - - /* given a pathname, fill in a File Spec */ - static - int make_file_spec( char* pathname, FSSpec *spec ) - { - Str255 p_path; - int path_len; - - /* convert path to a pascal string */ - path_len = strlen( pathname ); - if ( path_len > 255 ) - return -1; - p_path[0] = path_len; - strncpy( (char*)p_path+1, pathname, path_len ); - - if ( FSMakeFSSpec( 0, 0, p_path, spec ) != noErr ) - return -1; - else - return 0; - } - - - /* is_suitcase() returns true if the file specified by 'pathname' - is a Mac suitcase file, and false if it ain't. */ - static - int is_suitcase( FSSpec *spec ) - { - FInfo finfo; - - if ( FSpGetFInfo( spec, &finfo ) != noErr ) - return 0; - if ( finfo.fdType == 'FFIL' || finfo.fdType == 'tfil' ) - return 1; - else - return 0; - } - - - /* Quick 'n' Dirty Pascal string to C string converter. - Warning: this call is not thread safe! Use with caution. */ - static - char * p2c_str( unsigned char *pstr ) - { - static char cstr[256]; - - strncpy( cstr, (char*)pstr+1, pstr[0] ); - cstr[pstr[0]] = '\0'; - return cstr; - } - - - /* Given a PostScript font name, create the Macintosh LWFN file name */ - static - void create_lwfn_name( char* ps_name, Str255 lwfn_file_name ) - { - int max = 5, count = 0; - unsigned char* p = lwfn_file_name; - char* q = ps_name; - - lwfn_file_name[0] = 0; - - while ( *q ) - { - if ( isupper(*q) ) - { - if ( count ) - max = 3; - count = 0; - } - if ( count < max && (isalnum(*q) || *q == '_' ) ) - { - *++p = *q; - lwfn_file_name[0]++; - count++; - } - q++; - } - } - - - /* Suck the relevant info out of the FOND data */ - static - FT_Error parse_fond( char* fond_data, - short *have_sfnt, - short *sfnt_id, - Str255 lwfn_file_name ) - { - AsscEntry* assoc; - FamRec* fond; - - *sfnt_id = *have_sfnt = 0; - lwfn_file_name[0] = 0; - - fond = (FamRec*)fond_data; - assoc = (AsscEntry*)(fond_data + sizeof(FamRec) + 2); - - if ( assoc->fontSize == 0 ) - { - *have_sfnt = 1; - *sfnt_id = assoc->fontID; - } - - if ( fond->ffStylOff ) - { - unsigned char* p = (unsigned char*)fond_data; - StyleTable* style; - unsigned short string_count; - unsigned char* name_table = 0; - char ps_name[256]; - unsigned char* names[64]; - int i; - - p += fond->ffStylOff; - style = (StyleTable*)p; - p += sizeof(StyleTable); - string_count = *(unsigned short*)(p); - p += sizeof(short); - - for ( i=0 ; iindexes[0] > 1 ) - { - unsigned char* suffixes = names[style->indexes[0]-1]; - for ( i=1; i<=suffixes[0]; i++ ) - strcat( ps_name, p2c_str(names[suffixes[i]-1]) ); - } - create_lwfn_name( ps_name, lwfn_file_name ); - } - return FT_Err_Ok; - } - - - /* Read Type 1 data from the POST resources inside the LWFN file, return a - PFB buffer -- apparently FT doesn't like a pure binary T1 stream. */ - static - unsigned char* read_type1_data( FT_Memory memory, FSSpec* lwfn_spec, unsigned long *size ) - { - short res_ref, res_id; - unsigned char *buffer, *p, *size_p; - unsigned long total_size = 0; - unsigned long post_size, pfb_chunk_size; - Handle post_data; - char code, last_code; - - res_ref = FSpOpenResFile( lwfn_spec, fsRdPerm ); - if ( ResError() ) - return NULL; - UseResFile( res_ref ); - - /* first pass: load all POST resources, and determine the size of - the output buffer */ - res_id = 501; - last_code = -1; - for (;;) - { - post_data = Get1Resource( 'POST', res_id++ ); - if ( post_data == NULL ) - break; - code = (*post_data)[0]; - if ( code != last_code ) - { - if ( code == 5 ) - total_size += 2; /* just the end code */ - else - total_size += 6; /* code + 4 bytes chunk length */ - } - total_size += GetHandleSize( post_data ) - 2; - last_code = code; - } - - buffer = memory->alloc( memory, total_size ); - if ( !buffer ) - goto error; - - /* second pass: append all POST data to the buffer, add PFB fields */ - p = buffer; - res_id = 501; - last_code = -1; - pfb_chunk_size = 0; - for (;;) - { - post_data = Get1Resource( 'POST', res_id++ ); - if ( post_data == NULL ) - break; - post_size = GetHandleSize( post_data ) - 2; - code = (*post_data)[0]; - if ( code != last_code ) - { - if ( last_code != -1 ) - { - /* we're done adding a chunk, fill in the size field */ - *size_p++ = pfb_chunk_size & 0xFF; - *size_p++ = (pfb_chunk_size >> 8) & 0xFF; - *size_p++ = (pfb_chunk_size >> 16) & 0xFF; - *size_p++ = (pfb_chunk_size >> 24) & 0xFF; - pfb_chunk_size = 0; - } - *p++ = 0x80; - if ( code == 5 ) - *p++ = 0x03; /* the end */ - else if ( code == 2 ) - *p++ = 0x02; /* binary segment */ - else - *p++ = 0x01; /* ASCII segment */ - if ( code != 5 ) - { - size_p = p; /* save for later */ - p += 4; /* make space for size field */ - } - } - memcpy( p, *post_data + 2, post_size ); - pfb_chunk_size += post_size; - p += post_size; - last_code = code; - } - - CloseResFile( res_ref ); - - *size = total_size; -/* printf( "XXX %d %d\n", p - buffer, total_size ); */ - return buffer; - -error: - CloseResFile( res_ref ); - return NULL; - } - - - /* Finalizer for the sfnt stream */ - static - void sfnt_stream_close( FT_Stream stream ) - { - Handle sfnt_data = stream->descriptor.pointer; - HUnlock( sfnt_data ); - DisposeHandle( sfnt_data ); - - stream->descriptor.pointer = NULL; - stream->size = 0; - stream->base = 0; - stream->close = 0; - } - - - /* Finalizer for the LWFN stream */ - static - void lwfn_stream_close( FT_Stream stream ) - { - stream->memory->free( stream->memory, stream->base ); - stream->descriptor.pointer = NULL; - stream->size = 0; - stream->base = 0; - stream->close = 0; - } - - - /* Main entry point. Determine whether we're dealing with a Mac - suitcase or not; then determine if we're dealing with Type 1 - or TrueType; delegate the work to the proper driver. */ - static - FT_Error init_face( FT_Stream stream, - FT_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* parameters ) - { - FT_Error err; - FSSpec suit_spec, lwfn_spec; - short res_ref; - Handle fond_data, sfnt_data; - short res_index, sfnt_id, have_sfnt; - Str255 lwfn_file_name; - - if ( !stream->pathname.pointer ) - return FT_Err_Unknown_File_Format; - - if ( make_file_spec( stream->pathname.pointer, &suit_spec ) ) - return FT_Err_Invalid_Argument; - - if ( !is_suitcase( &suit_spec ) ) - return FT_Err_Unknown_File_Format; - - res_ref = FSpOpenResFile( &suit_spec, fsRdPerm ); - if ( ResError() ) - return FT_Err_Invalid_File_Format; - UseResFile( res_ref ); - - /* face_index may be -1, in which case we - just need to do a sanity check */ - if ( face_index < 0) - res_index = 1; - else - { - res_index = face_index + 1; - face_index = 0; - } - fond_data = Get1IndResource( 'FOND', res_index ); - if ( ResError() ) - { - CloseResFile( res_ref ); - return FT_Err_Invalid_File_Format; - } - /* Set the number of faces. Not that it helps much: the t1 driver - just sets it to 1 anyway :-( */ - face->num_faces = Count1Resources('FOND'); - - HLock( fond_data ); - err = parse_fond( *fond_data, &have_sfnt, &sfnt_id, lwfn_file_name ); - HUnlock( fond_data ); - if ( err ) - { - CloseResFile( res_ref ); - return FT_Err_Invalid_Handle; - } - - if ( lwfn_file_name[0] ) - { - /* We look for the LWFN file in the same directory as the suitcase - file. ATM would look in other places, too, but this is the usual - situation. */ - err = FSMakeFSSpec( suit_spec.vRefNum, suit_spec.parID, lwfn_file_name, &lwfn_spec ); - if ( err != noErr ) - lwfn_file_name[0] = 0; /* no LWFN file found */ - } - - if ( lwfn_file_name[0] && ( !have_sfnt || PREFER_LWFN ) ) - { - FT_Driver t1_driver; - unsigned char* type1_data; - unsigned long size; - - CloseResFile( res_ref ); /* XXX still need to read kerning! */ - - type1_data = read_type1_data( stream->memory, &lwfn_spec, &size ); - if ( !type1_data ) - { - return FT_Err_Out_Of_Memory; - } - -#if 0 - { - FILE* f; - char * path; - - path = p2c_str( lwfn_file_name ); - strcat( path, ".PFB" ); - f = fopen(path, "wb"); - if ( f ) - { - fwrite( type1_data, 1, size, f ); - fclose( f ); - } - } -#endif - - /* reinitialize the stream */ - if ( stream->close ) - stream->close( stream ); - stream->close = lwfn_stream_close; - stream->read = 0; /* it's now memory based */ - stream->base = type1_data; - stream->size = size; - stream->pos = 0; /* just in case */ - - /* delegate the work to the Type 1 module */ - t1_driver = (FT_Driver)FT_Get_Module( face->driver->root.library, "type1z" ); - if ( t1_driver ) - { - face->driver = t1_driver; - return t1_driver->clazz->init_face( stream, face, face_index, 0, NULL ); - } - else - return FT_Err_Invalid_Driver_Handle; - } - else if ( have_sfnt ) - { - FT_Driver tt_driver; - - sfnt_data = Get1Resource( 'sfnt', sfnt_id ); - if ( ResError() ) - { - CloseResFile( res_ref ); - return FT_Err_Invalid_Handle; - } - DetachResource( sfnt_data ); - CloseResFile( res_ref ); - HLockHi( sfnt_data ); - - /* reinitialize the stream */ - if ( stream->close ) - stream->close( stream ); - stream->close = sfnt_stream_close; - stream->descriptor.pointer = sfnt_data; - stream->read = 0; /* it's now memory based */ - stream->base = (unsigned char *)*sfnt_data; - stream->size = GetHandleSize( sfnt_data ); - stream->pos = 0; /* just in case */ - - /* delegate the work to the TrueType driver */ - tt_driver = (FT_Driver)FT_Get_Module( face->driver->root.library, "truetype" ); - if ( tt_driver ) - { - face->driver = tt_driver; - return tt_driver->clazz->init_face( stream, face, face_index, 0, NULL ); - } - else - return FT_Err_Invalid_Driver_Handle; - } - else - { - CloseResFile( res_ref ); - } - return FT_Err_Invalid_File_Format; - } - - - static - void done_face( FT_Face face ) - { - /* nothing to do */ - } - - /* The FT_DriverInterface structure is defined in ftdriver.h. */ - - const FT_Driver_Class fond_driver_class = - { - { - ft_module_font_driver | ft_module_driver_scalable, - sizeof ( FT_DriverRec ), - - "fond", /* driver name */ - 0x10000L, /* driver version == 1.0 */ - 0x20000L, /* driver requires FreeType 2.0 or above */ - - (void*)0, - - (FT_Module_Constructor) init_driver, - (FT_Module_Destructor) done_driver, - (FT_Module_Requester) 0 - }, - - sizeof ( FOND_FaceRec ), - 0, - 0, - - (FTDriver_initFace) init_face, - (FTDriver_doneFace) done_face, - (FTDriver_initSize) 0, - (FTDriver_doneSize) 0, - (FTDriver_initGlyphSlot) 0, - (FTDriver_doneGlyphSlot) 0, - - (FTDriver_setCharSizes) 0, - (FTDriver_setPixelSizes) 0, - (FTDriver_loadGlyph) 0, - (FTDriver_getCharIndex) 0, - - (FTDriver_getKerning) 0, - (FTDriver_attachFile) 0, - (FTDriver_getAdvances) 0 - }; - - - - /*************************************************************************/ - /* */ - /* */ - /* getDriverInterface */ - /* */ - /* */ - /* This function is used when compiling the FOND driver as a */ - /* shared library (`.DLL' or `.so'). It will be used by the */ - /* high-level library of FreeType to retrieve the address of the */ - /* driver's generic interface. */ - /* */ - /* It shouldn't be implemented in a static build, as each driver must */ - /* have the same function as an exported entry point. */ - /* */ - /* */ - /* The address of the TrueType's driver generic interface. The */ - /* format-specific interface can then be retrieved through the method */ - /* interface->get_format_interface. */ - /* */ -#ifdef FT_CONFIG_OPTION_DYNAMIC_DRIVERS - - FT_EXPORT_FUNC(const FT_Driver_Class*) getDriverClass( void ) - { - return &fond_driver_class; - } - -#endif /* CONFIG_OPTION_DYNAMIC_DRIVERS */ - - -/* END */ diff --git a/src/freetype/otlayout/oltypes.c b/src/freetype/otlayout/oltypes.c deleted file mode 100644 index bd2fa2204c..0000000000 --- a/src/freetype/otlayout/oltypes.c +++ /dev/null @@ -1,614 +0,0 @@ -#include - - LOCAL_FUNC - TT_Error OTL_Table_Init( OTL_Table* table, - FT_Memory memory ) - { - MEM_Set( table, 0, sizeof(*table) ); - table->memory = memory; - } - - /* read a script list table */ - /* use with any table */ - LOCAL_FUNC - TT_Error OTL_Table_Set_Scripts( OTL_Table* table, - TT_Byte* bytes, - TT_Long len, - OTL_Type otl_type ) - { - TT_Byte* p; - TT_Byte* start = bytes; - TT_UInt count, max_langs; - TT_Error error; - - /* skip version of the JSTF table */ - if (otl_type == otl_jstf) - start += 4; - - p = start; - - /* we must allocate the script_tags and language_tags arrays */ - /* this requires that we compute the maximum number of languages */ - /* per script.. */ - - count = table->num_scripts = OTL_UShort(p); - max_langs = 0; - for ( ; count > 0; count++ ) - { - TT_Byte* script; - TT_UInt num_langs; - - p += 4; /* skip tag */ - script = bytes + OTL_UShort(p); - - /* skip the baseValues or extenders field of the BASE and JSTF table */ - if (otl_type == otl_type_base || otl_type == otl_type_jstf) - script += 2; - - /* test if there is a default language system */ - if ( OTL_UShort(script) ) - num_langs++; - - /* test other language systems */ - num_langs += OTL_UShort(script); /* add other lang sys */ - - if (num_langs > max_langs) - max_langs = num_langs; - } - - /* good, now allocate the tag arrays */ - if ( !ALLOC_ARRAY( table->script_tags, - table->num_scripts + max_langs, - TT_ULong ) ) - { - table->language_tags = table->script_tags + table->num_scripts; - table->max_languages = max_langs; - table->num_languages = 0; - table->otl_type = otl_type; - - table->scripts_table = bytes; - table->scripts_len = len; - - /* fill the script_tags array */ - { - TT_UInt n; - TT_Byte* p = start + 2; /* skip count */ - - for ( n = 0; n < table->num_scripts; n++ ) - { - table->script_tags[n] = OTL_ULong(p); - p += 2; /* skip offset */ - } - } - } - return error; - } - - - - /* add a features list to the table */ - /* use only with a GSUB or GPOS table */ - LOCAL_FUNC - TT_Error OTL_Table_Set_Features( OTL_Table* table, - TT_Byte* bytes, - TT_Long len ) - { - TT_Error error; - TT_Byte* p = bytes; - TT_UInt count; - - table->max_features = count = OTL_UShort(p); - if ( !ALLOC_ARRAY( table->feature_tags, count, TT_ULong ) && - !ALLOC_ARRAY( table->features, count, TT_Bool ) ) - { - table->features_table = bytes; - table->features_len = len; - } - return error; - } - - - /* add a lookup list to the table */ - /* use only with a GSUB or GPOS table */ - LOCAL_FUNC - TT_Error OTL_Table_Set_Lookups( OTL_Table* table, - TT_Byte* bytes, - TT_Long len ) - { - TT_Error error; - TT_Byte* p = bytes; - TT_UInt count; - - table->max_lookups = count = OTL_UShort(p); - if ( !ALLOC_ARRAY( table->lookups, count, TT_Bool ) ) - { - table->lookups_table = bytes; - table->lookups_len = len; - } - return error; - } - - /* discard table arrays */ - LOCAL_FUNC - void OTL_Table_Done( OTL_Table* table ) - { - FREE( table->scrip_tags ); - FREE( table->language_tags ); - FREE( table->feature_tags ); - FREE( table->lookups ); - } - - - /* return the list of available languages for a given script */ - /* use with any table.. */ - LOCAL_FUNC - void OTL_Get_Languages_List( OTL_Table* table, - TT_ULong script_tag ) - { - TT_UInt n; - TT_Byte* p; - TT_Byte* script = 0; - TT_Byte* start = table->scripts_table; - - if ( table->otl_type == otl_type_jstf ) /* skip version for JSTF */ - start += 4; - - p = start + 6; /* skip count+first tag */ - - for ( n = 0; n < table->num_scripts; n++, p += 6 ) - { - if ( table->script_tags[n] == script_tag ) - { - script = table->scripts_table + OTL_UShort(p); - break; - } - } - - table->cur_script = script; - if (!script) - table->num_languages = 0; - else - { - /* now fill the language_tags array with the appropriate values */ - /* not that we put a '0' tag in front of the list to indicate that */ - /* there is a default language for this script.. */ - TT_ULong* tags = table->language_tags; - - switch (table->otl_type) - { - case otl_type_base: - case otl_type_jstf: - script += 2; /* skip basevalue or extenders */ - /* fall-through */ - - default: - if ( OTL_UShort(script) ) - *tags++ = 0; - } - - count = OTL_UShort(script); - for ( ; count > 0; count-- ) - { - *tags++ = OTL_ULong(script); - script += 2; /* skip offset */ - } - - table->num_langs = tags - table->language_tags; - } - } - - - /* return the list of available features for the current script/language */ - /* use with a GPOS or GSUB script table */ - LOCAL_FUNC - void OTL_Get_Features_List( OTL_Table* table, - TT_ULong language_tag ) - { - TT_UInt n; - TT_Byte* script = table->cur_script; - TT_Byte* language = 0; - TT_UShort offset; - - /* clear feature selection table */ - for ( n = 0; n < table->max_features; n++ ) - table->features[n] = 0; - - /* now, look for the current language */ - if ( language_tag == 0 ) - { - offset = OTL_UShort(script); - if (!offset) return; /* if there is no default language, exit */ - - language = script - 2 + offset; - } - else - { - TT_Byte* p = script + 8; /* skip default+count+1st tag */ - TT_UShort index; - - for ( n = 0; n < table->num_languages; n++, p+=6 ) - { - if ( table->language_tags[n] == language_tag ) - { - language = script + OTL_UShort(p); - break; - } - } - - table->cur_language = language; - if (!language) return; - - p = language + 2; /* skip lookup order */ - index = OTL_UShort(p); /* required feature index */ - if (index != 0xFFFF) - { - if (index < table->max_features) - table->features[index] = 1; - } - - count = OTL_UShort(p); - for ( ; count > 0; count-- ) - { - index = OTL_UShort(p); - if (index < table->max_features) - table->features[index] = 1; - } - } - } - - - /* return the list of lookups for the current features list */ - /* use only with a GSUB or GPOS table */ - LOCAL_FUNC - void OTL_Get_Lookups_List( OTL_Table* table ) - { - TT_UInt n; - TT_Byte* features = table->features_table; - TT_Byte* p = features + 6; /* skip count+1st tag */ - - /* clear lookup list */ - for ( n = 0; n < table->max_lookups; n++ ) - table->lookups[n] = 0; - - /* now, parse the features list */ - for ( n = 0; n < table->features; n++ ) - { - if (table->features[n]) - { - TT_UInt count; - TT_UShort index; - TT_Byte* feature; - - feature = features + OTL_UShort(p); - p += 4; /* skip tag */ - - /* now, select all lookups from this feature */ - count = OTL_UShort(feature); - for ( ; count > 0; count-- ) - { - index = OTL_UShort(feature); - if (index < table->max_lookups) - table->lookups[index] = 1; - } - } - } - } - - - /* find the basevalues and minmax for the current script/language */ - /* only use it with a BASE table.. */ - LOCAL_FUNC - void OTL_Get_Baseline_Values( OTL_Table* table, - TT_ULong language_tag ) - { - TT_Byte* script = table->cur_script; - TT_Byte* p = script; - TT_UShort offset, count; - - table->cur_basevalues = 0; - table->cur_minmax = 0; - - /* read basevalues */ - offset = OTL_UShort(p); - if (offset) - table->cur_basevalues = script + offset; - - offset = OTL_UShort(p); - if (offset) - table->cur_minmax = script + offset; - - count = OTL_UShort(p); - for ( ; count > 0; count-- ) - { - TT_ULong tag; - - tag = OTL_ULong(p); - if ( language_tag == tag ) - { - table->cur_minmax = script + OTL_UShort(p); - break; - } - p += 2; /* skip offset */ - } - } - - - /* compute the coverage value of a given glyph id */ - LOCAL_FUNC - TT_Long OTL_Get_Coverage_Index( TT_Byte* coverage, - TT_UInt glyph_id ) - { - TT_Long result = -1; - TT_UInt count, index, start, end; - TT_Byte* p = coverage; - - switch ( OTL_UShort(p) ) - { - case 1: /* coverage format 1 - array of glyph indices */ - { - count = OTL_UShort(p); - for ( index = 0; index < count; index++ ) - { - if ( OTL_UShort(p) == glyph_id ) - { - result = index; - break; - } - } - } - break; - - case 2: - { - count = OTL_UShort(p); - for ( ; count > 0; count-- ) - { - start = OTL_UShort(p); - end = OTL_UShort(p); - index = OTL_UShort(p); - if (start <= glyph_id && glyph_id <= end) - { - result = glyph_id - start + index; - break; - } - } - } - break; - } - return result; - } - - - /* compute the class value of a given glyph_id */ - LOCAL_FUNC - TT_UInt OTL_Get_Glyph_Class( TT_Byte* class_def, - TT_UInt glyph_id ) - { - TT_Byte* p = class_def; - TT_UInt result = 0; - TT_UInt start, end, count, index; - - switch ( OTL_UShort(p) ) - { - case 1: - { - start = OTL_UShort(p); - count = OTL_UShort(p); - - glyph_id -= start; - if (glyph_id < count) - { - p += 2*glyph_id; - result = OTL_UShort(p); - } - } - break; - - case 2: - { - count = OTL_UShort(p); - for ( ; count > 0; count-- ) - { - start = OTL_UShort(p); - end = OTL_UShort(p); - index = OTL_UShort(p); - if ( start <= glyph_id && glyph_id <= end ) - { - result = index; - break; - } - } - } - break; - } - return result; - } - - - /* compute the adjustement necessary for a given device size */ - LOCAL_FUNC - TT_Int OTL_Get_Device_Adjustment( TT_Byte* device, - TT_UInt size ) - { - TT_Byte* p = device; - TT_Int result = 0; - TT_UInt start, end; - TT_Short value; - - start = OTL_UShort(p); - end = OTL_UShort(p); - if (size >= start && size <= end) - { - /* I know we could do all of this without a switch, with */ - /* clever shifts and everything, but it makes the code */ - /* really difficult to understand.. */ - - size -= start; - switch ( OTL_UShort(p) ) - { - case 1: /* 2-bits per value */ - { - p += 2*(size >> 3); - size = (size & 7) << 1; - value = (TT_Short)((TT_Short)OTL_UShort(p) << size); - result = value >> 14; - } - break; - - case 2: /* 4-bits per value */ - { - p += 2*(size >> 2); - size = (size & 3) << 2; - value = (TT_Short)((TT_Short)OTL_UShort(p) << size); - result = value >> 12; - } - break; - - case 3: /* 8-bits per value */ - { - p += 2*(size >> 1); - size = (size & 1) << 3; - value = (TT_Short)((TT_Short)OTL_UShort(p) << size); - result = value >> 8; - } - break; - } - } - return result; - } - - /* extract a BaseCoord value */ - LOCAL_FUNC - void OTL_Get_Base_Coordinate( TT_Byte* base_coord, - OTL_ValueRecord* coord ) - { - TT_Byte* p = base_coord; - TT_Int result = 0; - - coord->format = OTL_UShort(p); - coord->coordinate = OTL_Short(p); - coord->device = 0; - - switch (coord->format) - { - case 2: /* format 2 */ - coord->ref_glyph = OTL_UShort(p); - coord->ref_point = OTL_UShort(p); - break; - - case 3: /* format 3 */ - coord->device = p - 4 + OTL_UShort(p); - break; - - default: - ; - } - } - - - /* compute size of ValueRecord */ - LOCAL_FUNC - TT_Int OTL_ValueRecord_Size( TT_UShort format ) - { - TT_Int count; - - /* each bit in the value format corresponds to a single ushort */ - /* we thus count the bits, and multiply the result by 2 */ - - count = (TT_Int)(format & 0xFF); - count = ((count & 0xAA) >> 1) + (count & 0x55); - count = ((count & 0xCC) >> 2) + (count & 0x33); - count = ((count & 0xF0) >> 4) + (count & 0x0F); - - return count*2; - } - - - - /* extract ValueRecord */ - LOCAL_FUNC - void OTL_Get_ValueRecord( TT_Byte* value_record, - TT_UShort value_format, - TT_Byte* pos_table, - OTL_ValueRecord* record ) - { - TT_Byte* p = value_record; - - /* clear vectors */ - record->placement.x = 0; - record->placement.y = 0; - record->advance.x = 0; - record->advance.y = 0; - - record->device_pla_x = 0; - record->device_pla_y = 0; - record->device_adv_x = 0; - record->device_adv_y = 0; - - if (value_format & 1) record->placement.x = NEXT_Short(p); - if (value_format & 2) record->placement.y = NEXT_Short(p); - if (value_format & 4) record->advance.x = NEXT_Short(p); - if (value_format & 8) record->advance.y = NEXT_Short(p); - - if (value_format & 16) record->device_pla_x = pos_table + NEXT_UShort(p); - if (value_format & 32) record->device_pla_y = pos_table + NEXT_UShort(p); - if (value_format & 64) record->device_adv_x = pos_table + NEXT_UShort(p); - if (value_format & 128) record->device_adv_y = pos_table + NEXT_UShort(p); - } - - - - /* extract Anchor */ - LOCAL_FUNC - void OTL_Get_Anchor( TT_Byte* anchor_table, - OTL_Anchor* anchor ) - { - TT_Byte* p = anchor_table; - - anchor->format = NEXT_UShort(p); - anchor->coord.x = NEXT_Short(p); - anchor->coord.y = NEXT_Short(p); - anchor->point = 0; - anchor->device_x = 0; - anchor->device_y = 0; - - switch (anchor->format) - { - case 2: - anchor->point = NEXT_UShort(p); - break; - - case 3: - anchor->device_x = anchor_table + NEXT_UShort(p); - anchor->device_y = anchor_table + NEXT_UShort(p); - break; - - default: - ; - } - } - - - - /* extract Mark from MarkArray */ - LOCAL_FUNC - void OTL_Get_Mark( TT_Byte* mark_array, - TT_UInt index, - TT_UShort* clazz, - OTL_Anchor* anchor ) - { - TT_Byte* p = mark_array; - TT_UInt count; - - *clazz = 0; - MEM_Set( anchor, 0, sizeof(*anchor) ); - - count = NEXT_UShort(p); - if (index < count) - { - p += 4*index; - *clazz = NEXT_UShort(p); - OTL_Get_Anchor( mark_array + NEXT_UShort(p), anchor ); - } - } - diff --git a/src/freetype/otlayout/oltypes.h b/src/freetype/otlayout/oltypes.h deleted file mode 100644 index b4a4d802eb..0000000000 --- a/src/freetype/otlayout/oltypes.h +++ /dev/null @@ -1,310 +0,0 @@ -#ifndef OLTYPES_H -#define OLTYPES_H - -#include -#include - - /************************************************************* - * - * OTL_Table - * - * - * The base table of most OpenType Layout sub-tables. - * Provides a simple way to scan a table for script, - * languages, features and lookups.. - * - * - * num_scripts :: number of scripts in table's script list - * script_tags :: array of tags for each table script - * - * max_languages :: max number of languages for any script in - * the table. - * num_languages :: number of languages available for current script - * language_tags :: tags of all languages available for current script. - * - * max_features :: total number of features in table - * feature_tags :: tags of all features for current script/language - * features :: selection flags for all features in current script/lang - * - * max_lookups :: total number of lookups in table - * lookups :: selection flags for all lookups for current - * feature list. - * - ****************************************************************/ - - typedef enum OTL_Type_ - { - otl_type_none = 0, - otl_type_base, - otl_type_gdef, - otl_type_gpos, - otl_type_gsub, - otl_type_jstf - - } OTL_Type; - - - typedef struct OTL_Table_ - { - FT_Memory memory; - - TT_Int num_scripts; - TT_Tag* script_tags; - - TT_Int max_languages; - TT_Int num_languages; - TT_Tag* language_tags; - - TT_Int max_features; - TT_Tag* feature_tags; - TT_Bool* features; - - TT_Int max_lookups; - TT_Bool* lookups; - - TT_Byte* scripts_table; - TT_Long scripts_len; - - TT_Byte* features_table; - TT_Long* features_len; - - TT_Byte* lookups_table; - TT_Byte* lookups_len; - - TT_Byte* cur_script; /* current script */ - TT_Byte* cur_language; /* current language */ - - TT_Byte* cur_base_values; - TT_Byte* cur_min_max; - - OTL_Type otl_type; - - } OTL_Table; - - - typedef struct OTL_BaseCoord_ - { - TT_UShort format; - TT_Short coordinate; - TT_UShort ref_glyph; - TT_UShort ref_point; - TT_Byte* device; - - } OTL_BaseCoord; - - - typedef struct OTL_ValueRecord_ - { - TT_Vector placement; - TT_Vector advance; - - TT_Byte* device_pla_x; - TT_Byte* device_pla_y; - TT_Byte* device_adv_x; - TT_Byte* device_adv_y; - - } OTL_ValueRecord; - - - typedef struct OTL_Anchor_ - { - TT_UInt format; - TT_Vector coord; - TT_UInt anchor_point; - TT_Byte* device_x; - TT_Byte* device_y; - - } OTL_Anchor; - - LOCAL_DEF - TT_Error OTL_Table_Init( OTL_Table* table, - FT_Memory memory ); - - LOCAL_DEF - TT_Error OTL_Table_Set_Scripts( OTL_Table* table, - TT_Byte* bytes, - TT_Long len, - OTL_Type otl_type ); - - LOCAL_DEF - TT_Error OTL_Table_Set_Features( OTL_Table* table, - TT_Byte* bytes, - TT_Long len ); - - LOCAL_DEF - TT_Error OTL_Table_Set_Lookups( OTL_Table* table, - TT_Byte* bytes, - TT_Long len ); - - LOCAL_DEF - void OTL_Table_Done( OTL_Table* table ); - - - -/***************************************************** - * - * Typical uses: - * - * - after OTL_Table_Set_Scripts have been called : - * - * table->script_tags contains the list of tags of all - * scripts defined for this table. - * - * table->num_scripts is the number of scripts - * - */ - -/******************************************************** - * - * - after calling OTL_Table_Set_Features: - * - * table->max_features is the number of all features - * in the table - * - * table->feature_tags is the list of tags of all - * features in the table - * - * table->features[] is an array of boolean used to - * indicate which feature is active for a given script/language - * it is empty (zero-filled) by default. - * - */ - -/******************************************************************* - * - * - after calling OTL_Get_Languages_List(script_tag): - * - * table->num_languages is the number of language systems - * available for the script, including the default - * langsys if there is one - * - * table->language_tags contains the list of tags of all - * languages for the script. Note that the default langsys - * has tag "0" and is always placed first in "language_tags". - * - * - * - */ - LOCAL_DEF - void OTL_Get_Languages_List( OTL_Table* table, - TT_ULong script_tag ); - - -/******************************************************************* - * - * - after calling OTL_Get_Features_List(language_tag): - * - * table->features[] is an array of booleans used to indicate - * which features are active for the current script/language - * - * note that this function must be called after OTL_Get_Languages - * which remembers the last "script_tag" used.. - * - * A client application can change the table->features[] array - * to add or remove features from the list. - * - * - * - */ - LOCAL_DEF - void OTL_Get_Features_List( OTL_Table* table, - TT_ULong language_tag ); - - LOCAL_DEF - void OTL_Get_Baseline_Values( OTL_Table* table, - TT_ULong language_tag ); - - LOCAL_DEF - void OTL_Get_Justification( OTL_Table* table, - TT_ULong language_tag ); - -/******************************************************************* - * - * - after calling OTL_Get_Lookups_List(): - * - * The function uses the table->features[] array of boolean - * to determine which lookups must be processed. - * - * It fills the table->lookups[] array accordingly. It is also - * an array of booleans (one for each lookup). - * - * - */ - - LOCAL_DEF - void OTL_Get_Lookups_List( OTL_Table* table ); - - -/*************************************************************** - * - * So the whole thing looks like: - * - * - * 1. A client specifies a given script and requests available - * language through OTL_Get_Languages_List() - * - * 2. It selects the language tag it needs, then calls - * OTL_Get_Features_List() - * - * 3. It updates the list of active features if it needs to - * - * 4. It calls OTL_Get_Lookups_List() - * It now has a list of active lookups in "table->lookups[]" - * - * 5. The lookups are processed according to the table's type.. - * - */ - - - - - LOCAL_DEF - TT_Long OTL_Get_Coverage_Index( TT_Byte* coverage, - TT_UInt glyph_id ); - - LOCAL_DEF - TT_UInt OTL_Get_Glyph_Class( TT_Byte* class_def, - TT_UInt glyph_id ); - - LOCAL_DEF - TT_Int OTL_Get_Device_Adjustment( TT_Byte* device, - TT_UInt size ); - - LOCAL_DEF - void OTL_Get_Base_Coordinate( TT_Byte* base_coord, - OTL_BaseCoord* coord ); - - - LOCAL_DEF - TT_Int OTL_ValueRecord_Size( TT_UShort value_format ); - - - LOCAL_DEF - void OTL_Get_ValueRecord( TT_Byte* value_record, - TT_UShort value_format, - TT_Byte* pos_table, - OTL_ValueRecord* record ); - - - LOCAL_DEF - void OTL_Get_Anchor( TT_Byte* anchor_table, - OTL_Anchor* anchor ); - - - LOCAL_DEF - void OTL_Get_Mark( TT_Byte* mark_array, - TT_UInt index, - TT_UShort* clazz, - OTL_Anchor* anchor ); - - - -#define OTL_Byte(p) (p++, p[-1]) - -#define OTL_UShort(p) (p+=2, ((TT_UShort)p[-2] << 8) | p[-1]) - -#define OTL_ULong(p) (p+=4, ((TT_ULong)p[-4] << 24) | \ - ((TT_ULong)p[-3] << 16) | \ - ((TT_ULong)p[-2] << 8 ) | p[-1] ) - -#endif /* OLTYPES_H */ diff --git a/src/freetype/psnames/module.mk b/src/freetype/psnames/module.mk deleted file mode 100644 index 3d33c120dd..0000000000 --- a/src/freetype/psnames/module.mk +++ /dev/null @@ -1,7 +0,0 @@ -make_module_list: add_psnames_module - -add_psnames_module: - $(OPEN_DRIVER)psnames_module_class$(CLOSE_DRIVER) - $(ECHO_DRIVER)psnames $(ECHO_DRIVER_DESC)Postscript & Unicode Glyph name handling$(ECHO_DRIVER_DONE) - -# EOF diff --git a/src/freetype/psnames/psmodule.c b/src/freetype/psnames/psmodule.c deleted file mode 100644 index 55ab5dfce0..0000000000 --- a/src/freetype/psnames/psmodule.c +++ /dev/null @@ -1,320 +0,0 @@ -/***************************************************************************/ -/* */ -/* psmodule.c */ -/* */ -/* PSNames module implementation (body). */ -/* */ -/* 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 -#include - - -#ifdef FT_FLAT_COMPILE - -#include "psmodule.h" -#include "pstables.h" - -#else - -#include -#include - -#endif - - -#include /* for qsort() */ -#include /* for strcmp(), strncpy() */ - - -#ifndef FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES - - - - -#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST - - - /* return the Unicode value corresponding to a given glyph. Note that */ - /* we do deal with glyph variants by detecting a non-initial dot in */ - /* the name, as in `A.swash' or `e.final', etc. */ - /* */ - static - FT_ULong PS_Unicode_Value( const char* glyph_name ) - { - FT_Int n; - char first = glyph_name[0]; - char temp[64]; - - - /* if the name begins with `uni', then the glyph name may be a */ - /* hard-coded unicode character code. */ - if ( glyph_name[0] == 'u' && - glyph_name[1] == 'n' && - glyph_name[2] == 'i' ) - { - /* determine whether the next four characters following are */ - /* hexadecimal. */ - - /* XXX: Add code to deal with ligatures, i.e. glyph names like */ - /* `uniXXXXYYYYZZZZ'... */ - - FT_Int count; - FT_ULong value = 0; - const char* p = glyph_name + 4; - - - for ( count = 4; count > 0; count--, p++ ) - { - char c = *p; - unsigned char d; - - - d = (unsigned char)c - '0'; - if ( d >= 10 ) - { - d = (unsigned char)c - 'A'; - if ( d >= 6 ) - d = 16; - else - d += 10; - } - - /* exit if a non-uppercase hexadecimal character was found */ - if ( d >= 16 ) - break; - - value = ( value << 4 ) + d; - - if ( count == 0 ) - return value; - } - } - - /* look for a non-initial dot in the glyph name in order to */ - /* sort-out variants like `A.swash', `e.final', etc. */ - { - const char* p; - int len; - - - p = glyph_name; - - while ( *p && *p != '.' ) - p++; - - len = p - glyph_name; - - if ( *p && len < 64 ) - { - strncpy( temp, glyph_name, len ); - temp[len] = 0; - glyph_name = temp; - } - } - - /* now, look up the glyph in the Adobe Glyph List */ - for ( n = 0; n < NUM_ADOBE_GLYPHS; n++ ) - { - const char* name = t1_standard_glyphs[n]; - - - if ( first == name[0] && strcmp( glyph_name, name ) == 0 ) - return names_to_unicode[n]; - } - - /* not found, there is probably no Unicode value for this glyph name */ - return 0; - } - - - /* qsort callback to sort the unicode map */ - static - int compare_uni_maps( const void* a, - const void* b ) - { - PS_UniMap* map1 = (PS_UniMap*)a; - PS_UniMap* map2 = (PS_UniMap*)b; - - - return ( map1->unicode - map2->unicode ); - } - - - /* Builds a table that maps Unicode values to glyph indices */ - static - FT_Error PS_Build_Unicode_Table( FT_Memory memory, - FT_UInt num_glyphs, - const char** glyph_names, - PS_Unicodes* table ) - { - FT_Error error; - - - /* we first allocate the table */ - table->num_maps = 0; - table->maps = 0; - - if ( !ALLOC_ARRAY( table->maps, num_glyphs, PS_UniMap ) ) - { - FT_UInt n; - FT_UInt count; - PS_UniMap* map; - FT_ULong uni_char; - - - map = table->maps; - - for ( n = 0; n < num_glyphs; n++ ) - { - const char* gname = glyph_names[n]; - - - if ( gname ) - { - uni_char = PS_Unicode_Value( gname ); - - if ( uni_char && uni_char != 0xFFFF ) - { - map->unicode = uni_char; - map->glyph_index = n; - map++; - } - } - } - - /* now, compress the table a bit */ - count = map - table->maps; - - if ( count > 0 && REALLOC( table->maps, - num_glyphs * sizeof ( PS_UniMap ), - count * sizeof ( PS_UniMap ) ) ) - count = 0; - - if ( count == 0 ) - { - FREE( table->maps ); - if ( !error ) - error = FT_Err_Invalid_Argument; /* no unicode chars here! */ - } - else - /* sort the table in increasing order of unicode values */ - qsort( table->maps, count, sizeof ( PS_UniMap ), compare_uni_maps ); - - table->num_maps = count; - } - - return error; - } - - - static - FT_UInt PS_Lookup_Unicode( PS_Unicodes* table, - FT_ULong unicode ) - { - PS_UniMap *min, *max, *mid; - - - /* perform a binary search on the table */ - - min = table->maps; - max = min + table->num_maps - 1; - - while ( min <= max ) - { - mid = min + ( max - min ) / 2; - if ( mid->unicode == unicode ) - return mid->glyph_index; - - if ( min == max ) - break; - - if ( mid->unicode < unicode ) - min = mid + 1; - else - max = mid - 1; - } - - return 0xFFFF; - } - - -#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ - - - static - const char* PS_Macintosh_Name( FT_UInt name_index ) - { - if ( name_index >= 258 ) - name_index = 0; - - return standard_glyph_names[mac_standard_names[name_index]]; - } - - - static - const char* PS_Standard_Strings( FT_UInt sid ) - { - return ( sid < NUM_STD_GLYPHS ? t1_standard_glyphs[sid] : 0 ); - } - - - static const PSNames_Interface psnames_interface = - { -#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST - - (PS_Unicode_Value_Func) PS_Unicode_Value, - (PS_Build_Unicodes_Func) PS_Build_Unicode_Table, - (PS_Lookup_Unicode_Func) PS_Lookup_Unicode, - -#else - - 0, - 0, - 0, - -#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ - - (PS_Macintosh_Name_Func) PS_Macintosh_Name, - (PS_Adobe_Std_Strings_Func)PS_Standard_Strings, - - t1_standard_encoding, - t1_expert_encoding - }; - - -#endif /* !FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES */ - - - const FT_Module_Class psnames_module_class = - { - 0, /* this is not a font driver, nor a renderer */ - sizeof( FT_ModuleRec ), - - "psnames", /* driver name */ - 0x10000L, /* driver version */ - 0x20000L, /* driver requires FreeType 2 or above */ - -#ifdef FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES - 0, -#else - (void*)&psnames_interface, /* module specific interface */ -#endif - - (FT_Module_Constructor)0, - (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 - }; - - -/* END */ diff --git a/src/freetype/psnames/psmodule.h b/src/freetype/psnames/psmodule.h deleted file mode 100644 index ff7ef06503..0000000000 --- a/src/freetype/psnames/psmodule.h +++ /dev/null @@ -1,29 +0,0 @@ -/***************************************************************************/ -/* */ -/* psmodule.h */ -/* */ -/* High-level PSNames module interface (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifndef PSDRIVER_H -#define PSDRIVER_H - -#include - - FT_EXPORT_VAR( const FT_Module_Class ) psnames_module_class; - -#endif /* PSDRIVER_H */ - - -/* END */ diff --git a/src/freetype/psnames/psnames.c b/src/freetype/psnames/psnames.c deleted file mode 100644 index 0491b4814e..0000000000 --- a/src/freetype/psnames/psnames.c +++ /dev/null @@ -1,24 +0,0 @@ -/***************************************************************************/ -/* */ -/* psnames.c */ -/* */ -/* FreeType PSNames module component (body only). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#define FT_MAKE_OPTION_SINGLE_OBJECT - -#include - - -/* END */ diff --git a/src/freetype/psnames/pstables.h b/src/freetype/psnames/pstables.h deleted file mode 100644 index 094bc27c33..0000000000 --- a/src/freetype/psnames/pstables.h +++ /dev/null @@ -1,2942 +0,0 @@ -/***************************************************************************/ -/* */ -/* pstables.h */ -/* */ -/* PostScript glyph names (specification only). */ -/* */ -/* Copyright 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. */ -/* */ -/***************************************************************************/ - - - /* this file has been generated automatically -- do not edit! */ - - - static const char* standard_glyph_names[] = - { - ".null", - "CR", - "notequal", - "infinity", - "lessequal", - "greaterequal", - "partialdiff", - "summation", - "product", - "pi", - "integral", - "Omega", - "radical", - "approxequal", - "Delta", - "nbspace", - "lozenge", - "periodcentered", - "apple", - "lslash", - "franc", - "Gbreve", - "gbreve", - "Idot", - "Scedilla", - "scedilla", - "Cacute", - "cacute", - "Ccaron", - "ccaron", - "dmacron", - ".notdef", - "space", - "exclam", - "quotedbl", - "numbersign", - "dollar", - "percent", - "ampersand", - "quoteright", - "parenleft", - "parenright", - "asterisk", - "plus", - "comma", - "hyphen", - "period", - "slash", - "zero", - "one", - "two", - "three", - "four", - "five", - "six", - "seven", - "eight", - "nine", - "colon", - "semicolon", - "less", - "equal", - "greater", - "question", - "at", - "A", - "B", - "C", - "D", - "E", - "F", - "G", - "H", - "I", - "J", - "K", - "L", - "M", - "N", - "O", - "P", - "Q", - "R", - "S", - "T", - "U", - "V", - "W", - "X", - "Y", - "Z", - "bracketleft", - "backslash", - "bracketright", - "asciicircum", - "underscore", - "quoteleft", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "braceleft", - "bar", - "braceright", - "asciitilde", - "exclamdown", - "cent", - "sterling", - "fraction", - "yen", - "florin", - "section", - "currency", - "quotesingle", - "quotedblleft", - "guillemotleft", - "guilsinglleft", - "guilsinglright", - "fi", - "fl", - "endash", - "dagger", - "daggerdbl", - "periodcenter", - "paragraph", - "bullet", - "quotesinglbase", - "quotedblbase", - "quotedblright", - "guillemotright", - "ellipsis", - "perthousand", - "questiondown", - "grave", - "acute", - "circumflex", - "tilde", - "macron", - "breve", - "dotaccent", - "dieresis", - "ring", - "cedilla", - "hungarumlaut", - "ogonek", - "caron", - "emdash", - "AE", - "ordfeminine", - "Lslash", - "Oslash", - "OE", - "ordmasculine", - "ae", - "dotlessi", - "Islash", - "oslash", - "oe", - "germandbls", - "onesuperior", - "logicalnot", - "mu", - "trademark", - "Eth", - "onehalf", - "plusminus", - "Thorn", - "onequarter", - "divide", - "brokenbar", - "degree", - "thorn", - "threequarters", - "twosuperior", - "registered", - "minus", - "eth", - "multiply", - "threesuperior", - "copyright", - "Aacute", - "Acircumflex", - "Adieresis", - "Agrave", - "Aring", - "Atilde", - "Ccedilla", - "Eacute", - "Ecircumflex", - "Edieresis", - "Egrave", - "Iacute", - "Icircumflex", - "Idieresis", - "Igrave", - "Ntilde", - "Oacute", - "Ocircumflex", - "Odieresis", - "Ograve", - "Otilde", - "Scaron", - "Uacute", - "Ucircumflex", - "Udieresis", - "Ugrave", - "Yacute", - "Ydieresis", - "Zcaron", - "aacute", - "acircumflex", - "adieresis", - "agrave", - "aring", - "atilde", - "ccedilla", - "eacute", - "ecircumflex", - "edieresis", - "egrave", - "iacute", - "icircumflex", - "idieresis", - "igrave", - "ntilde", - "oacute", - "ocircumflex", - "odieresis", - "ograve", - "otilde", - "scaron", - "uacute", - "ucircumflex", - "udieresis", - "ugrave", - "yacute", - "ydieresis", - "zcaron", - "exclamsmall", - "Hungarumlautsmall", - "dollaroldstyle", - "dollarsuperior", - "ampersandsmall", - "Acutesmall", - "parenleftsuperior", - "parenrightsuperior", - "twodotenleader", - "onedotenleader", - "zerooldstyle", - "oneoldstyle", - "twooldstyle", - "threeoldstyle", - "fouroldstyle", - "fiveoldstyle", - "sixoldstyle", - "sevenoldstyle", - "eightoldstyle", - "nineoldstyle", - "commasuperior", - "threequartersemdash", - "periodsuperior", - "questionsmall", - "asuperior", - "bsuperior", - "centsuperior", - "dsuperior", - "esuperior", - "isuperior", - "lsuperior", - "msuperior", - "nsuperior", - "osuperior", - "rsuperior", - "ssuperior", - "tsuperior", - "ff", - "ffi", - "ffl", - "parenleftinferior", - "parenrightinferior", - "Circumflexsmall", - "hyphensuperior", - "Gravesmall", - "Asmall", - "Bsmall", - "Csmall", - "Dsmall", - "Esmall", - "Fsmall", - "Gsmall", - "Hsmall", - "Ismall", - "Jsmall", - "Ksmall", - "Lsmall", - "Msmall", - "Nsmall", - "Osmall", - "Psmall", - "Qsmall", - "Rsmall", - "Ssmall", - "Tsmall", - "Usmall", - "Vsmall", - "Wsmall", - "Xsmall", - "Ysmall", - "Zsmall", - "colonmonetary", - "onefitted", - "rupiah", - "Tildesmall", - "exclamdownsmall", - "centoldstyle", - "Lslashsmall", - "Scaronsmall", - "Zcaronsmall", - "Dieresissmall", - "Brevesmall", - "Caronsmall", - "Dotaccentsmall", - "Macronsmall", - "figuredash", - "hypheninferior", - "Ogoneksmall", - "Ringsmall", - "Cedillasmall", - "questiondownsmall", - "oneeighth", - "threeeighths", - "fiveeighths", - "seveneighths", - "onethird", - "twothirds", - "zerosuperior", - "foursuperior", - "fivesuperior", - "sixsuperior", - "sevensuperior", - "eightsuperior", - "ninesuperior", - "zeroinferior", - "oneinferior", - "twoinferior", - "threeinferior", - "fourinferior", - "fiveinferior", - "sixinferior", - "seveninferior", - "eightinferior", - "nineinferior", - "centinferior", - "dollarinferior", - "periodinferior", - "commainferior", - "Agravesmall", - "Aacutesmall", - "Acircumflexsmall", - "Atildesmall", - "Adieresissmall", - "Aringsmall", - "AEsmall", - "Ccedillasmall", - "Egravesmall", - "Eacutesmall", - "Ecircumflexsmall", - "Edieresissmall", - "Igravesmall", - "Iacutesmall", - "Icircumflexsmall", - "Idieresissmall", - "Ethsmall", - "Ntildesmall", - "Ogravesmall", - "Oacutesmall", - "Ocircumflexsmall", - "Otildesmall", - "Odieresissmall", - "OEsmall", - "Oslashsmall", - "Ugravesmall", - "Uacautesmall", - "Ucircumflexsmall", - "Udieresissmall", - "Yacutesmall", - "Thornsmall", - "Ydieresissmall", - "001.000", - "001.001", - "001.002", - "001.003", - "Black", - "Bold", - "Book", - "Light", - "Medium", - "Regular", - "Roman", - "Semibold", - -#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST - - "AEacute", - "Abreve", - "Acute", - "Alpha", - "Alphatonos", - "Amacron", - "Aogonek", - "Aringacute", - "Beta", - "Caron", - "Ccircumflex", - "Cdotaccent", - "Chi", - "Dcaron", - "Dcroat", - "Dieresis", - "DieresisAcute", - "DieresisGrave", - "Ebreve", - "Ecaron", - "Edotaccent", - "Emacron", - "Eng", - "Eogonek", - "Epsilon", - "Epsilontonos", - "Eta", - "Etatonos", - "Euro", - "Gamma", - "Gcaron", - "Gcircumflex", - "Gcommaaccent", - "Gdotaccent", - "Grave", - "H18533", - "H18543", - "H18551", - "H22073", - "Hbar", - "Hcircumflex", - "Hungarumlaut", - "IJ", - "Ibreve", - "Idotaccent", - "Ifraktur", - "Imacron", - "Iogonek", - "Iota", - "Iotadieresis", - "Iotatonos", - "Itilde", - "Jcircumflex", - "Kappa", - "Kcommaaccent", - "LL", - "Lacute", - "Lambda", - "Lcaron", - "Lcommaaccent", - "Ldot", - "Macron", - "Mu", - "Nacute", - "Ncaron", - "Ncommaaccent", - "Nu", - "Obreve", - "Ohorn", - "Ohungarumlaut", - "Omacron", - "Omegatonos", - "Omicron", - "Omicrontonos", - "Oslashacute", - "Phi", - "Pi", - "Psi", - "Racute", - "Rcaron", - "Rcommaaccent", - "Rfraktur", - "Rho", - "SF010000", - "SF020000", - "SF030000", - "SF040000", - "SF050000", - "SF060000", - "SF070000", - "SF080000", - "SF090000", - "SF100000", - "SF110000", - "SF190000", - "SF200000", - "SF210000", - "SF220000", - "SF230000", - "SF240000", - "SF250000", - "SF260000", - "SF270000", - "SF280000", - "SF360000", - "SF370000", - "SF380000", - "SF390000", - "SF400000", - "SF410000", - "SF420000", - "SF430000", - "SF440000", - "SF450000", - "SF460000", - "SF470000", - "SF480000", - "SF490000", - "SF500000", - "SF510000", - "SF520000", - "SF530000", - "SF540000", - "Sacute", - "Scircumflex", - "Scommaaccent", - "Sigma", - "Tau", - "Tbar", - "Tcaron", - "Tcommaaccent", - "Tcommaaccent", - "Theta", - "Uacutesmall", - "Ubreve", - "Uhorn", - "Uhungarumlaut", - "Umacron", - "Uogonek", - "Upsilon", - "Upsilon1", - "Upsilondieresis", - "Upsilontonos", - "Uring", - "Utilde", - "Wacute", - "Wcircumflex", - "Wdieresis", - "Wgrave", - "Xi", - "Ycircumflex", - "Ygrave", - "Zacute", - "Zdotaccent", - "Zeta", - "abreve", - "acutecomb", - "aeacute", - "afii00208", - "afii10017", - "afii10018", - "afii10019", - "afii10020", - "afii10021", - "afii10022", - "afii10023", - "afii10024", - "afii10025", - "afii10026", - "afii10027", - "afii10028", - "afii10029", - "afii10030", - "afii10031", - "afii10032", - "afii10033", - "afii10034", - "afii10035", - "afii10036", - "afii10037", - "afii10038", - "afii10039", - "afii10040", - "afii10041", - "afii10042", - "afii10043", - "afii10044", - "afii10045", - "afii10046", - "afii10047", - "afii10048", - "afii10049", - "afii10050", - "afii10051", - "afii10052", - "afii10053", - "afii10054", - "afii10055", - "afii10056", - "afii10057", - "afii10058", - "afii10059", - "afii10060", - "afii10061", - "afii10062", - "afii10063", - "afii10064", - "afii10065", - "afii10066", - "afii10067", - "afii10068", - "afii10069", - "afii10070", - "afii10071", - "afii10072", - "afii10073", - "afii10074", - "afii10075", - "afii10076", - "afii10077", - "afii10078", - "afii10079", - "afii10080", - "afii10081", - "afii10082", - "afii10083", - "afii10084", - "afii10085", - "afii10086", - "afii10087", - "afii10088", - "afii10089", - "afii10090", - "afii10091", - "afii10092", - "afii10093", - "afii10094", - "afii10095", - "afii10096", - "afii10097", - "afii10098", - "afii10099", - "afii10100", - "afii10101", - "afii10102", - "afii10103", - "afii10104", - "afii10105", - "afii10106", - "afii10107", - "afii10108", - "afii10109", - "afii10110", - "afii10145", - "afii10146", - "afii10147", - "afii10148", - "afii10192", - "afii10193", - "afii10194", - "afii10195", - "afii10196", - "afii10831", - "afii10832", - "afii10846", - "afii299", - "afii300", - "afii301", - "afii57381", - "afii57388", - "afii57392", - "afii57393", - "afii57394", - "afii57395", - "afii57396", - "afii57397", - "afii57398", - "afii57399", - "afii57400", - "afii57401", - "afii57403", - "afii57407", - "afii57409", - "afii57410", - "afii57411", - "afii57412", - "afii57413", - "afii57414", - "afii57415", - "afii57416", - "afii57417", - "afii57418", - "afii57419", - "afii57420", - "afii57421", - "afii57422", - "afii57423", - "afii57424", - "afii57425", - "afii57426", - "afii57427", - "afii57428", - "afii57429", - "afii57430", - "afii57431", - "afii57432", - "afii57433", - "afii57434", - "afii57440", - "afii57441", - "afii57442", - "afii57443", - "afii57444", - "afii57445", - "afii57446", - "afii57448", - "afii57449", - "afii57450", - "afii57451", - "afii57452", - "afii57453", - "afii57454", - "afii57455", - "afii57456", - "afii57457", - "afii57458", - "afii57470", - "afii57505", - "afii57506", - "afii57507", - "afii57508", - "afii57509", - "afii57511", - "afii57512", - "afii57513", - "afii57514", - "afii57519", - "afii57534", - "afii57636", - "afii57645", - "afii57658", - "afii57664", - "afii57665", - "afii57666", - "afii57667", - "afii57668", - "afii57669", - "afii57670", - "afii57671", - "afii57672", - "afii57673", - "afii57674", - "afii57675", - "afii57676", - "afii57677", - "afii57678", - "afii57679", - "afii57680", - "afii57681", - "afii57682", - "afii57683", - "afii57684", - "afii57685", - "afii57686", - "afii57687", - "afii57688", - "afii57689", - "afii57690", - "afii57694", - "afii57695", - "afii57700", - "afii57705", - "afii57716", - "afii57717", - "afii57718", - "afii57723", - "afii57793", - "afii57794", - "afii57795", - "afii57796", - "afii57797", - "afii57798", - "afii57799", - "afii57800", - "afii57801", - "afii57802", - "afii57803", - "afii57804", - "afii57806", - "afii57807", - "afii57839", - "afii57841", - "afii57842", - "afii57929", - "afii61248", - "afii61289", - "afii61352", - "afii61573", - "afii61574", - "afii61575", - "afii61664", - "afii63167", - "afii64937", - "aleph", - "alpha", - "alphatonos", - "amacron", - "angle", - "angleleft", - "angleright", - "anoteleia", - "aogonek", - "aringacute", - "arrowboth", - "arrowdblboth", - "arrowdbldown", - "arrowdblleft", - "arrowdblright", - "arrowdblup", - "arrowdown", - "arrowhorizex", - "arrowleft", - "arrowright", - "arrowup", - "arrowupdn", - "arrowupdnbse", - "arrowvertex", - "asteriskmath", - "beta", - "block", - "braceex", - "braceleftbt", - "braceleftmid", - "bracelefttp", - "bracerightbt", - "bracerightmid", - "bracerighttp", - "bracketleftbt", - "bracketleftex", - "bracketlefttp", - "bracketrightbt", - "bracketrightex", - "bracketrighttp", - "carriagereturn", - "ccircumflex", - "cdotaccent", - "chi", - "circle", - "circlemultiply", - "circleplus", - "club", - "commaaccent", - "congruent", - "copyrightsans", - "copyrightserif", - "cyrBreve", - "cyrFlex", - "cyrbreve", - "cyrflex", - "dblGrave", - "dblgrave", - "dcaron", - "dcroat", - "delta", - "diamond", - "dieresisacute", - "dieresisgrave", - "dieresistonos", - "dkshade", - "dnblock", - "dong", - "dotbelowcomb", - "dotlessj", - "dotmath", - "ebreve", - "ecaron", - "edotaccent", - "element", - "emacron", - "emptyset", - "eng", - "eogonek", - "epsilon", - "epsilontonos", - "equivalence", - "estimated", - "eta", - "etatonos", - "exclamdbl", - "existential", - "female", - "filledbox", - "filledrect", - "gamma", - "gcaron", - "gcircumflex", - "gcommaaccent", - "gdotaccent", - "gradient", - "gravecomb", - "hbar", - "hcircumflex", - "heart", - "hookabovecomb", - "house", - "ibreve", - "ij", - "imacron", - "integralbt", - "integralex", - "integraltp", - "intersection", - "invbullet", - "invcircle", - "invsmileface", - "iogonek", - "iota", - "iotadieresis", - "iotadieresistonos", - "iotatonos", - "itilde", - "jcircumflex", - "kappa", - "kcommaaccent", - "kgreenlandic", - "lacute", - "lambda", - "lcaron", - "lcommaaccent", - "ldot", - "lfblock", - "lira", - "ll", - "logicaland", - "logicalor", - "longs", - "ltshade", - "male", - "minute", - "musicalnote", - "musicalnotedbl", - "nacute", - "napostrophe", - "ncaron", - "ncommaaccent", - "notelement", - "notsubset", - "nu", - "obreve", - "ohorn", - "ohungarumlaut", - "omacron", - "omega", - "omega1", - "omegatonos", - "omicron", - "omicrontonos", - "openbullet", - "orthogonal", - "oslashacute", - "parenleftbt", - "parenleftex", - "parenlefttp", - "parenrightbt", - "parenrightex", - "parenrighttp", - "perpendicular", - "peseta", - "phi", - "phi1", - "prescription", - "propersubset", - "propersuperset", - "proportional", - "psi", - "quotereversed", - "racute", - "radicalex", - "rcaron", - "rcommaaccent", - "reflexsubset", - "reflexsuperset", - "registersans", - "registerserif", - "revlogicalnot", - "rho", - "rtblock", - "sacute", - "scircumflex", - "scommaaccent", - "second", - "shade", - "sigma", - "sigma1", - "similar", - "smileface", - "spade", - "suchthat", - "sun", - "tau", - "tbar", - "tcaron", - "tcommaaccent", - "tcommaaccent", - "therefore", - "theta", - "theta1", - "tildecomb", - "tonos", - "trademarksans", - "trademarkserif", - "triagdn", - "triaglf", - "triagrt", - "triagup", - "ubreve", - "uhorn", - "uhungarumlaut", - "umacron", - "underscoredbl", - "union", - "universal", - "uogonek", - "upblock", - "upsilon", - "upsilondieresis", - "upsilondieresistonos", - "upsilontonos", - "uring", - "utilde", - "wacute", - "wcircumflex", - "wdieresis", - "weierstrass", - "wgrave", - "xi", - "ycircumflex", - "ygrave", - "zacute", - "zdotaccent", - "zeta", - -#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ - - 0 - }; - - - static const char** t1_standard_glyphs = standard_glyph_names + 31; - - -#define NUM_STD_GLYPHS 391 - -#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST -#define NUM_ADOBE_GLYPHS 1032 -#else -#define NUM_ADOBE_GLYPHS 391 -#endif - - - static const unsigned short mac_standard_names[259] = - { - 0, - 0, - 1, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 104, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31, - 32, - 33, - 34, - 35, - 36, - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52, - 53, - 54, - 55, - 56, - 57, - 58, - 59, - 60, - 61, - 62, - 63, - 64, - 124, - 66, - 67, - 68, - 69, - 70, - 71, - 72, - 73, - 74, - 75, - 76, - 77, - 78, - 79, - 80, - 81, - 82, - 83, - 84, - 85, - 86, - 87, - 88, - 89, - 90, - 91, - 92, - 93, - 94, - 95, - 173, - 175, - 177, - 178, - 186, - 189, - 195, - 200, - 203, - 201, - 202, - 205, - 204, - 206, - 207, - 210, - 208, - 209, - 211, - 214, - 212, - 213, - 215, - 216, - 219, - 217, - 218, - 220, - 222, - 225, - 223, - 224, - 112, - 161, - 97, - 98, - 102, - 116, - 115, - 149, - 165, - 170, - 153, - 125, - 131, - 2, - 138, - 141, - 3, - 156, - 4, - 5, - 100, - 152, - 6, - 7, - 8, - 9, - 10, - 139, - 143, - 11, - 144, - 147, - 123, - 96, - 151, - 12, - 101, - 13, - 14, - 106, - 120, - 121, - 15, - 174, - 176, - 191, - 142, - 148, - 111, - 137, - 105, - 119, - 65, - 8, - 159, - 16, - 227, - 198, - 99, - 103, - 107, - 108, - 109, - 110, - 113, - 17, - 117, - 118, - 122, - 172, - 179, - 171, - 180, - 181, - 182, - 183, - 184, - 185, - 187, - 188, - 18, - 190, - 193, - 194, - 196, - 145, - 126, - 127, - 128, - 129, - 130, - 132, - 133, - 134, - 135, - 136, - 140, - 19, - 192, - 221, - 199, - 228, - 160, - 154, - 167, - 197, - 226, - 157, - 162, - 166, - 168, - 150, - 164, - 169, - 155, - 158, - 163, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 0 - }; - - - - static const unsigned short names_to_unicode[1033] = - { - 0, - 0x0020, - 0x0021, - 0x0022, - 0x0023, - 0x0024, - 0x0025, - 0x0026, - 0x2019, - 0x0028, - 0x0029, - 0x002A, - 0x002B, - 0x002C, - 0x002D, - 0x002E, - 0x002F, - 0x0030, - 0x0031, - 0x0032, - 0x0033, - 0x0034, - 0x0035, - 0x0036, - 0x0037, - 0x0038, - 0x0039, - 0x003A, - 0x003B, - 0x003C, - 0x003D, - 0x003E, - 0x003F, - 0x0040, - 0x0041, - 0x0042, - 0x0043, - 0x0044, - 0x0045, - 0x0046, - 0x0047, - 0x0048, - 0x0049, - 0x004A, - 0x004B, - 0x004C, - 0x004D, - 0x004E, - 0x004F, - 0x0050, - 0x0051, - 0x0052, - 0x0053, - 0x0054, - 0x0055, - 0x0056, - 0x0057, - 0x0058, - 0x0059, - 0x005A, - 0x005B, - 0x005C, - 0x005D, - 0x005E, - 0x005F, - 0x2018, - 0x0061, - 0x0062, - 0x0063, - 0x0064, - 0x0065, - 0x0066, - 0x0067, - 0x0068, - 0x0069, - 0x006A, - 0x006B, - 0x006C, - 0x006D, - 0x006E, - 0x006F, - 0x0070, - 0x0071, - 0x0072, - 0x0073, - 0x0074, - 0x0075, - 0x0076, - 0x0077, - 0x0078, - 0x0079, - 0x007A, - 0x007B, - 0x007C, - 0x007D, - 0x007E, - 0x00A1, - 0x00A2, - 0x00A3, - 0x2044, - 0x00A5, - 0x0192, - 0x00A7, - 0x00A4, - 0x0027, - 0x201C, - 0x00AB, - 0x2039, - 0x203A, - 0xFB01, - 0xFB02, - 0x2013, - 0x2020, - 0x2021, - 0, - 0x00B6, - 0x2022, - 0x201A, - 0x201E, - 0x201D, - 0x00BB, - 0x2026, - 0x2030, - 0x00BF, - 0x0060, - 0x00B4, - 0x02C6, - 0x02DC, - 0x00AF, - 0x02D8, - 0x02D9, - 0x00A8, - 0x02DA, - 0x00B8, - 0x02DD, - 0x02DB, - 0x02C7, - 0x2014, - 0x00C6, - 0x00AA, - 0x0141, - 0x00D8, - 0x0152, - 0x00BA, - 0x00E6, - 0x0131, - 0, - 0x00F8, - 0x0153, - 0x00DF, - 0x00B9, - 0x00AC, - 0x00B5, - 0x2122, - 0x00D0, - 0x00BD, - 0x00B1, - 0x00DE, - 0x00BC, - 0x00F7, - 0x00A6, - 0x00B0, - 0x00FE, - 0x00BE, - 0x00B2, - 0x00AE, - 0x2212, - 0x00F0, - 0x00D7, - 0x00B3, - 0x00A9, - 0x00C1, - 0x00C2, - 0x00C4, - 0x00C0, - 0x00C5, - 0x00C3, - 0x00C7, - 0x00C9, - 0x00CA, - 0x00CB, - 0x00C8, - 0x00CD, - 0x00CE, - 0x00CF, - 0x00CC, - 0x00D1, - 0x00D3, - 0x00D4, - 0x00D6, - 0x00D2, - 0x00D5, - 0x0160, - 0x00DA, - 0x00DB, - 0x00DC, - 0x00D9, - 0x00DD, - 0x0178, - 0x017D, - 0x00E1, - 0x00E2, - 0x00E4, - 0x00E0, - 0x00E5, - 0x00E3, - 0x00E7, - 0x00E9, - 0x00EA, - 0x00EB, - 0x00E8, - 0x00ED, - 0x00EE, - 0x00EF, - 0x00EC, - 0x00F1, - 0x00F3, - 0x00F4, - 0x00F6, - 0x00F2, - 0x00F5, - 0x0161, - 0x00FA, - 0x00FB, - 0x00FC, - 0x00F9, - 0x00FD, - 0x00FF, - 0x017E, - 0xF721, - 0xF6F8, - 0xF724, - 0xF6E4, - 0xF726, - 0xF7B4, - 0x207D, - 0x207E, - 0x2025, - 0x2024, - 0xF730, - 0xF731, - 0xF732, - 0xF733, - 0xF734, - 0xF735, - 0xF736, - 0xF737, - 0xF738, - 0xF739, - 0xF6E2, - 0xF6DE, - 0xF6E8, - 0xF73F, - 0xF6E9, - 0xF6EA, - 0xF6E0, - 0xF6EB, - 0xF6EC, - 0xF6ED, - 0xF6EE, - 0xF6EF, - 0x207F, - 0xF6F0, - 0xF6F1, - 0xF6F2, - 0xF6F3, - 0xFB00, - 0xFB03, - 0xFB04, - 0x208D, - 0x208E, - 0xF6F6, - 0xF6E6, - 0xF760, - 0xF761, - 0xF762, - 0xF763, - 0xF764, - 0xF765, - 0xF766, - 0xF767, - 0xF768, - 0xF769, - 0xF76A, - 0xF76B, - 0xF76C, - 0xF76D, - 0xF76E, - 0xF76F, - 0xF770, - 0xF771, - 0xF772, - 0xF773, - 0xF774, - 0xF775, - 0xF776, - 0xF777, - 0xF778, - 0xF779, - 0xF77A, - 0x20A1, - 0xF6DC, - 0xF6DD, - 0xF6FE, - 0xF7A1, - 0xF7A2, - 0xF6F9, - 0xF6FD, - 0xF6FF, - 0xF7A8, - 0xF6F4, - 0xF6F5, - 0xF6F7, - 0xF7AF, - 0x2012, - 0xF6E5, - 0xF6FB, - 0xF6FC, - 0xF7B8, - 0xF7BF, - 0x215B, - 0x215C, - 0x215D, - 0x215E, - 0x2153, - 0x2154, - 0x2070, - 0x2074, - 0x2075, - 0x2076, - 0x2077, - 0x2078, - 0x2079, - 0x2080, - 0x2081, - 0x2082, - 0x2083, - 0x2084, - 0x2085, - 0x2086, - 0x2087, - 0x2088, - 0x2089, - 0xF6DF, - 0xF6E3, - 0xF6E7, - 0xF6E1, - 0xF7E0, - 0xF7E1, - 0xF7E2, - 0xF7E3, - 0xF7E4, - 0xF7E5, - 0xF7E6, - 0xF7E7, - 0xF7E8, - 0xF7E9, - 0xF7EA, - 0xF7EB, - 0xF7EC, - 0xF7ED, - 0xF7EE, - 0xF7EF, - 0xF7F0, - 0xF7F1, - 0xF7F2, - 0xF7F3, - 0xF7F4, - 0xF7F5, - 0xF7F6, - 0xF6FA, - 0xF7F8, - 0xF7F9, - 0, - 0xF7FB, - 0xF7FC, - 0xF7FD, - 0xF7FE, - 0xF7FF, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - -#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST - - 0x01FC, - 0x0102, - 0xF6C9, - 0x0391, - 0x0386, - 0x0100, - 0x0104, - 0x01FA, - 0x0392, - 0xF6CA, - 0x0108, - 0x010A, - 0x03A7, - 0x010E, - 0x0110, - 0xF6CB, - 0xF6CC, - 0xF6CD, - 0x0114, - 0x011A, - 0x0116, - 0x0112, - 0x014A, - 0x0118, - 0x0395, - 0x0388, - 0x0397, - 0x0389, - 0x20AC, - 0x0393, - 0x01E6, - 0x011C, - 0x0122, - 0x0120, - 0xF6CE, - 0x25CF, - 0x25AA, - 0x25AB, - 0x25A1, - 0x0126, - 0x0124, - 0xF6CF, - 0x0132, - 0x012C, - 0x0130, - 0x2111, - 0x012A, - 0x012E, - 0x0399, - 0x03AA, - 0x038A, - 0x0128, - 0x0134, - 0x039A, - 0x0136, - 0xF6BF, - 0x0139, - 0x039B, - 0x013D, - 0x013B, - 0x013F, - 0xF6D0, - 0x039C, - 0x0143, - 0x0147, - 0x0145, - 0x039D, - 0x014E, - 0x01A0, - 0x0150, - 0x014C, - 0x038F, - 0x039F, - 0x038C, - 0x01FE, - 0x03A6, - 0x03A0, - 0x03A8, - 0x0154, - 0x0158, - 0x0156, - 0x211C, - 0x03A1, - 0x250C, - 0x2514, - 0x2510, - 0x2518, - 0x253C, - 0x252C, - 0x2534, - 0x251C, - 0x2524, - 0x2500, - 0x2502, - 0x2561, - 0x2562, - 0x2556, - 0x2555, - 0x2563, - 0x2551, - 0x2557, - 0x255D, - 0x255C, - 0x255B, - 0x255E, - 0x255F, - 0x255A, - 0x2554, - 0x2569, - 0x2566, - 0x2560, - 0x2550, - 0x256C, - 0x2567, - 0x2568, - 0x2564, - 0x2565, - 0x2559, - 0x2558, - 0x2552, - 0x2553, - 0x256B, - 0x256A, - 0x015A, - 0x015C, - 0x0218, - 0x03A3, - 0x03A4, - 0x0166, - 0x0164, - 0x0162, - 0x0162, - 0x0398, - 0xF7FA, - 0x016C, - 0x01AF, - 0x0170, - 0x016A, - 0x0172, - 0x03A5, - 0x03D2, - 0x03AB, - 0x038E, - 0x016E, - 0x0168, - 0x1E82, - 0x0174, - 0x1E84, - 0x1E80, - 0x039E, - 0x0176, - 0x1EF2, - 0x0179, - 0x017B, - 0x0396, - 0x0103, - 0x0301, - 0x01FD, - 0x2015, - 0x0410, - 0x0411, - 0x0412, - 0x0413, - 0x0414, - 0x0415, - 0x0401, - 0x0416, - 0x0417, - 0x0418, - 0x0419, - 0x041A, - 0x041B, - 0x041C, - 0x041D, - 0x041E, - 0x041F, - 0x0420, - 0x0421, - 0x0422, - 0x0423, - 0x0424, - 0x0425, - 0x0426, - 0x0427, - 0x0428, - 0x0429, - 0x042A, - 0x042B, - 0x042C, - 0x042D, - 0x042E, - 0x042F, - 0x0490, - 0x0402, - 0x0403, - 0x0404, - 0x0405, - 0x0406, - 0x0407, - 0x0408, - 0x0409, - 0x040A, - 0x040B, - 0x040C, - 0x040E, - 0xF6C4, - 0xF6C5, - 0x0430, - 0x0431, - 0x0432, - 0x0433, - 0x0434, - 0x0435, - 0x0451, - 0x0436, - 0x0437, - 0x0438, - 0x0439, - 0x043A, - 0x043B, - 0x043C, - 0x043D, - 0x043E, - 0x043F, - 0x0440, - 0x0441, - 0x0442, - 0x0443, - 0x0444, - 0x0445, - 0x0446, - 0x0447, - 0x0448, - 0x0449, - 0x044A, - 0x044B, - 0x044C, - 0x044D, - 0x044E, - 0x044F, - 0x0491, - 0x0452, - 0x0453, - 0x0454, - 0x0455, - 0x0456, - 0x0457, - 0x0458, - 0x0459, - 0x045A, - 0x045B, - 0x045C, - 0x045E, - 0x040F, - 0x0462, - 0x0472, - 0x0474, - 0xF6C6, - 0x045F, - 0x0463, - 0x0473, - 0x0475, - 0xF6C7, - 0xF6C8, - 0x04D9, - 0x200E, - 0x200F, - 0x200D, - 0x066A, - 0x060C, - 0x0660, - 0x0661, - 0x0662, - 0x0663, - 0x0664, - 0x0665, - 0x0666, - 0x0667, - 0x0668, - 0x0669, - 0x061B, - 0x061F, - 0x0621, - 0x0622, - 0x0623, - 0x0624, - 0x0625, - 0x0626, - 0x0627, - 0x0628, - 0x0629, - 0x062A, - 0x062B, - 0x062C, - 0x062D, - 0x062E, - 0x062F, - 0x0630, - 0x0631, - 0x0632, - 0x0633, - 0x0634, - 0x0635, - 0x0636, - 0x0637, - 0x0638, - 0x0639, - 0x063A, - 0x0640, - 0x0641, - 0x0642, - 0x0643, - 0x0644, - 0x0645, - 0x0646, - 0x0648, - 0x0649, - 0x064A, - 0x064B, - 0x064C, - 0x064D, - 0x064E, - 0x064F, - 0x0650, - 0x0651, - 0x0652, - 0x0647, - 0x06A4, - 0x067E, - 0x0686, - 0x0698, - 0x06AF, - 0x0679, - 0x0688, - 0x0691, - 0x06BA, - 0x06D2, - 0x06D5, - 0x20AA, - 0x05BE, - 0x05C3, - 0x05D0, - 0x05D1, - 0x05D2, - 0x05D3, - 0x05D4, - 0x05D5, - 0x05D6, - 0x05D7, - 0x05D8, - 0x05D9, - 0x05DA, - 0x05DB, - 0x05DC, - 0x05DD, - 0x05DE, - 0x05DF, - 0x05E0, - 0x05E1, - 0x05E2, - 0x05E3, - 0x05E4, - 0x05E5, - 0x05E6, - 0x05E7, - 0x05E8, - 0x05E9, - 0x05EA, - 0xFB2A, - 0xFB2B, - 0xFB4B, - 0xFB1F, - 0x05F0, - 0x05F1, - 0x05F2, - 0xFB35, - 0x05B4, - 0x05B5, - 0x05B6, - 0x05BB, - 0x05B8, - 0x05B7, - 0x05B0, - 0x05B2, - 0x05B1, - 0x05B3, - 0x05C2, - 0x05C1, - 0x05B9, - 0x05BC, - 0x05BD, - 0x05BF, - 0x05C0, - 0x02BC, - 0x2105, - 0x2113, - 0x2116, - 0x202C, - 0x202D, - 0x202E, - 0x200C, - 0x066D, - 0x02BD, - 0x2135, - 0x03B1, - 0x03AC, - 0x0101, - 0x2220, - 0x2329, - 0x232A, - 0x0387, - 0x0105, - 0x01FB, - 0x2194, - 0x21D4, - 0x21D3, - 0x21D0, - 0x21D2, - 0x21D1, - 0x2193, - 0xF8E7, - 0x2190, - 0x2192, - 0x2191, - 0x2195, - 0x21A8, - 0xF8E6, - 0x2217, - 0x03B2, - 0x2588, - 0xF8F4, - 0xF8F3, - 0xF8F2, - 0xF8F1, - 0xF8FE, - 0xF8FD, - 0xF8FC, - 0xF8F0, - 0xF8EF, - 0xF8EE, - 0xF8FB, - 0xF8FA, - 0xF8F9, - 0x21B5, - 0x0109, - 0x010B, - 0x03C7, - 0x25CB, - 0x2297, - 0x2295, - 0x2663, - 0xF6C3, - 0x2245, - 0xF8E9, - 0xF6D9, - 0xF6D1, - 0xF6D2, - 0xF6D4, - 0xF6D5, - 0xF6D3, - 0xF6D6, - 0x010F, - 0x0111, - 0x03B4, - 0x2666, - 0xF6D7, - 0xF6D8, - 0x0385, - 0x2593, - 0x2584, - 0x20AB, - 0x0323, - 0xF6BE, - 0x22C5, - 0x0115, - 0x011B, - 0x0117, - 0x2208, - 0x0113, - 0x2205, - 0x014B, - 0x0119, - 0x03B5, - 0x03AD, - 0x2261, - 0x212E, - 0x03B7, - 0x03AE, - 0x203C, - 0x2203, - 0x2640, - 0x25A0, - 0x25AC, - 0x03B3, - 0x01E7, - 0x011D, - 0x0123, - 0x0121, - 0x2207, - 0x0300, - 0x0127, - 0x0125, - 0x2665, - 0x0309, - 0x2302, - 0x012D, - 0x0133, - 0x012B, - 0x2321, - 0xF8F5, - 0x2320, - 0x2229, - 0x25D8, - 0x25D9, - 0x263B, - 0x012F, - 0x03B9, - 0x03CA, - 0x0390, - 0x03AF, - 0x0129, - 0x0135, - 0x03BA, - 0x0137, - 0x0138, - 0x013A, - 0x03BB, - 0x013E, - 0x013C, - 0x0140, - 0x258C, - 0x20A4, - 0xF6C0, - 0x2227, - 0x2228, - 0x017F, - 0x2591, - 0x2642, - 0x2032, - 0x266A, - 0x266B, - 0x0144, - 0x0149, - 0x0148, - 0x0146, - 0x2209, - 0x2284, - 0x03BD, - 0x014F, - 0x01A1, - 0x0151, - 0x014D, - 0x03C9, - 0x03D6, - 0x03CE, - 0x03BF, - 0x03CC, - 0x25E6, - 0x221F, - 0x01FF, - 0xF8ED, - 0xF8EC, - 0xF8EB, - 0xF8F8, - 0xF8F7, - 0xF8F6, - 0x22A5, - 0x20A7, - 0x03C6, - 0x03D5, - 0x211E, - 0x2282, - 0x2283, - 0x221D, - 0x03C8, - 0x201B, - 0x0155, - 0xF8E5, - 0x0159, - 0x0157, - 0x2286, - 0x2287, - 0xF8E8, - 0xF6DA, - 0x2310, - 0x03C1, - 0x2590, - 0x015B, - 0x015D, - 0x0219, - 0x2033, - 0x2592, - 0x03C3, - 0x03C2, - 0x223C, - 0x263A, - 0x2660, - 0x220B, - 0x263C, - 0x03C4, - 0x0167, - 0x0165, - 0x0163, - 0x0163, - 0x2234, - 0x03B8, - 0x03D1, - 0x0303, - 0x0384, - 0xF8EA, - 0xF6DB, - 0x25BC, - 0x25C4, - 0x25BA, - 0x25B2, - 0x016D, - 0x01B0, - 0x0171, - 0x016B, - 0x2017, - 0x222A, - 0x2200, - 0x0173, - 0x2580, - 0x03C5, - 0x03CB, - 0x03B0, - 0x03CD, - 0x016F, - 0x0169, - 0x1E83, - 0x0175, - 0x1E85, - 0x2118, - 0x1E81, - 0x03BE, - 0x0177, - 0x1EF3, - 0x017A, - 0x017C, - 0x03B6, - -#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ - 0 - }; - - - - static const unsigned short t1_standard_encoding[257] = - { - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31, - 32, - 33, - 34, - 35, - 36, - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52, - 53, - 54, - 55, - 56, - 57, - 58, - 59, - 60, - 61, - 62, - 63, - 64, - 65, - 66, - 67, - 68, - 69, - 70, - 71, - 72, - 73, - 74, - 75, - 76, - 77, - 78, - 79, - 80, - 81, - 82, - 83, - 84, - 85, - 86, - 87, - 88, - 89, - 90, - 91, - 92, - 93, - 94, - 95, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 96, - 97, - 98, - 99, - 100, - 101, - 102, - 103, - 104, - 105, - 106, - 107, - 108, - 109, - 110, - 0, - 111, - 112, - 113, - 114, - 0, - 115, - 116, - 117, - 118, - 119, - 120, - 121, - 122, - 0, - 123, - 0, - 124, - 125, - 126, - 127, - 128, - 129, - 130, - 131, - 0, - 132, - 133, - 0, - 134, - 135, - 136, - 137, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 138, - 0, - 139, - 0, - 0, - 0, - 0, - 140, - 141, - 142, - 143, - 0, - 0, - 0, - 0, - 0, - 144, - 0, - 0, - 0, - 145, - 0, - 0, - 146, - 147, - 148, - 149, - 0, - 0, - 0, - 0, - 0 - }; - - - static const unsigned short t1_expert_encoding[257] = - { - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 229, - 230, - 0, - 231, - 232, - 233, - 234, - 235, - 236, - 237, - 238, - 13, - 14, - 15, - 99, - 239, - 240, - 241, - 242, - 243, - 244, - 245, - 246, - 247, - 248, - 27, - 28, - 249, - 250, - 251, - 252, - 0, - 253, - 254, - 255, - 256, - 257, - 0, - 0, - 0, - 258, - 0, - 0, - 259, - 260, - 261, - 262, - 0, - 0, - 263, - 264, - 265, - 0, - 266, - 109, - 110, - 267, - 268, - 269, - 0, - 270, - 271, - 272, - 273, - 274, - 275, - 276, - 277, - 278, - 279, - 280, - 281, - 282, - 283, - 284, - 285, - 286, - 287, - 288, - 289, - 290, - 291, - 292, - 293, - 294, - 295, - 296, - 297, - 298, - 299, - 300, - 301, - 302, - 303, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 304, - 305, - 306, - 0, - 0, - 307, - 308, - 309, - 310, - 311, - 0, - 312, - 0, - 0, - 312, - 0, - 0, - 314, - 315, - 0, - 0, - 316, - 317, - 318, - 0, - 0, - 0, - 158, - 155, - 163, - 319, - 320, - 321, - 322, - 323, - 324, - 325, - 0, - 0, - 326, - 150, - 164, - 169, - 327, - 328, - 329, - 330, - 331, - 332, - 333, - 334, - 335, - 336, - 337, - 338, - 339, - 340, - 341, - 342, - 343, - 344, - 345, - 346, - 347, - 348, - 349, - 350, - 351, - 352, - 353, - 354, - 355, - 356, - 357, - 358, - 359, - 360, - 361, - 362, - 363, - 364, - 365, - 366, - 367, - 368, - 369, - 370, - 371, - 372, - 373, - 374, - 375, - 376, - 377, - 378, - 0 - }; - - -/* END */ diff --git a/src/freetype/psnames/rules.mk b/src/freetype/psnames/rules.mk deleted file mode 100644 index 25552b2663..0000000000 --- a/src/freetype/psnames/rules.mk +++ /dev/null @@ -1,70 +0,0 @@ -# -# FreeType 2 PSNames driver configuration rules -# - - -# 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. - - -# PSNames driver directory -# -PSNAMES_DIR := $(SRC_)psnames -PSNAMES_DIR_ := $(PSNAMES_DIR)$(SEP) - - -# compilation flags for the driver -# -PSNAMES_COMPILE := $(FT_COMPILE) - - -# PSNames driver sources (i.e., C files) -# -PSNAMES_DRV_SRC := $(PSNAMES_DIR_)psmodule.c - - -# PSNames driver headers -# -PSNAMES_DRV_H := $(PSNAMES_DRV_SRC:%.c=%.h) \ - $(PSNAMES_DIR_)pstables.h - - -# PSNames driver object(s) -# -# PSNAMES_DRV_OBJ_M is used during `multi' builds -# PSNAMES_DRV_OBJ_S is used during `single' builds -# -PSNAMES_DRV_OBJ_M := $(PSNAMES_DRV_SRC:$(PSNAMES_DIR_)%.c=$(OBJ_)%.$O) -PSNAMES_DRV_OBJ_S := $(OBJ_)psnames.$O - -# PSNames driver source file for single build -# -PSNAMES_DRV_SRC_S := $(PSNAMES_DIR_)psmodule.c - - -# PSNames driver - single object -# -$(PSNAMES_DRV_OBJ_S): $(PSNAMES_DRV_SRC_S) $(PSNAMES_DRV_SRC) \ - $(FREETYPE_H) $(PSNAMES_DRV_H) - $(PSNAMES_COMPILE) $T$@ $(PSNAMES_DRV_SRC_S) - - -# PSNames driver - multiple objects -# -$(OBJ_)%.$O: $(PSNAMES_DIR_)%.c $(FREETYPE_H) $(PSNAMES_DRV_H) - $(PSNAMES_COMPILE) $T$@ $< - - -# update main driver object lists -# -DRV_OBJS_S += $(PSNAMES_DRV_OBJ_S) -DRV_OBJS_M += $(PSNAMES_DRV_OBJ_M) - - -# EOF diff --git a/src/freetype/raster1/ftraster.c b/src/freetype/raster1/ftraster.c deleted file mode 100644 index 65d04057d7..0000000000 --- a/src/freetype/raster1/ftraster.c +++ /dev/null @@ -1,3300 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftraster.c */ -/* */ -/* The FreeType glyph rasterizer (body). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - /*************************************************************************/ - /* */ - /* This is a rewrite of the FreeType 1.x scan-line converter */ - /* */ - /*************************************************************************/ - - -#include "ftraster.h" -#include /* for FT_MulDiv() only */ - - - /*************************************************************************/ - /* */ - /* A simple technical note on how the raster works */ - /* ----------------------------------------------- */ - /* */ - /* Converting an outline into a bitmap is achieved in several steps: */ - /* */ - /* 1 - Decomposing the outline into successive `profiles'. Each */ - /* profile is simply an array of scanline intersections on a given */ - /* dimension. A profile's main attributes are */ - /* */ - /* o its scanline position boundaries, i.e. `Ymin' and `Ymax'. */ - /* */ - /* o an array of intersection coordinates for each scanline */ - /* between `Ymin' and `Ymax'. */ - /* */ - /* o a direction, indicating whether it was built going `up' or */ - /* `down', as this is very important for filling rules. */ - /* */ - /* 2 - Sweeping the target map's scanlines in order to compute segment */ - /* `spans' which are then filled. Additionally, this pass */ - /* performs drop-out control. */ - /* */ - /* The outline data is parsed during step 1 only. The profiles are */ - /* built from the bottom of the render pool, used as a stack. The */ - /* following graphics shows the profile list under construction: */ - /* */ - /* ____________________________________________________________ _ _ */ - /* | | | | | */ - /* | profile | coordinates for | profile | coordinates for |--> */ - /* | 1 | profile 1 | 2 | profile 2 |--> */ - /* |_________|___________________|_________|_________________|__ _ _ */ - /* */ - /* ^ ^ */ - /* | | */ - /* start of render pool top */ - /* */ - /* The top of the profile stack is kept in the `top' variable. */ - /* */ - /* As you can see, a profile record is pushed on top of the render */ - /* pool, which is then followed by its coordinates/intersections. If */ - /* a change of direction is detected in the outline, a new profile is */ - /* generated until the end of the outline. */ - /* */ - /* Note that when all profiles have been generated, the function */ - /* Finalize_Profile_Table() is used to record, for each profile, its */ - /* bottom-most scanline as well as the scanline above its upmost */ - /* boundary. These positions are called `y-turns' because they (sort */ - /* of) correspond to local extrema. They are stored in a sorted list */ - /* built from the top of the render pool as a downwards stack: */ - /* */ - /* _ _ _______________________________________ */ - /* | | */ - /* <--| sorted list of | */ - /* <--| extrema scanlines | */ - /* _ _ __________________|____________________| */ - /* */ - /* ^ ^ */ - /* | | */ - /* maxBuff sizeBuff = end of pool */ - /* */ - /* This list is later used during the sweep phase in order to */ - /* optimize performance (see technical note on the sweep below). */ - /* */ - /* Of course, the raster detects whether the two stacks collide and */ - /* handles the situation propertly. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /*************************************************************************/ - /** **/ - /** CONFIGURATION MACROS **/ - /** **/ - /*************************************************************************/ - /*************************************************************************/ - - /* define DEBUG_RASTER if you want to compile a debugging version */ -#define xxxDEBUG_RASTER - - /* The default render pool size in bytes */ -#define RASTER_RENDER_POOL 8192 - - /* undefine FT_RASTER_OPTION_ANTI_ALIASING if you do not want to support */ - /* 5-levels anti-aliasing */ -#ifdef FT_CONFIG_OPTION_5_GRAY_LEVELS -#define FT_RASTER_OPTION_ANTI_ALIASING -#endif - - /* The size of the two-lines intermediate bitmap used */ - /* for anti-aliasing, in bytes. */ -#define RASTER_GRAY_LINES 2048 - - - /*************************************************************************/ - /*************************************************************************/ - /** **/ - /** OTHER MACROS (do not change) **/ - /** **/ - /*************************************************************************/ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_raster - - -#ifdef _STANDALONE_ - - - /* This macro is used to indicate that a function parameter is unused. */ - /* Its purpose is simply to reduce compiler warnings. Note also that */ - /* simply defining it as `(void)x' doesn't avoid warnings with certain */ - /* ANSI compilers (e.g. LCC). */ -#define FT_UNUSED( x ) (x) = (x) - - /* Disable the tracing mechanism for simplicity -- developers can */ - /* activate it easily by redefining these two macros. */ -#ifndef FT_ERROR -#define FT_ERROR( x ) do ; while ( 0 ) /* nothing */ -#endif - -#ifndef FT_TRACE -#define FT_TRACE( x ) do ; while ( 0 ) /* nothing */ -#endif - -#define Raster_Err_None 0 -#define Raster_Err_Not_Ini -1 -#define Raster_Err_Overflow -2 -#define Raster_Err_Neg_Height -3 -#define Raster_Err_Invalid -4 -#define Raster_Err_Unsupported -5 - - -#else /* _STANDALONE_ */ - - -#include -#include /* for FT_TRACE() and FT_ERROR() */ - -#define Raster_Err_None FT_Err_Ok -#define Raster_Err_Not_Ini FT_Err_Raster_Uninitialized -#define Raster_Err_Overflow FT_Err_Raster_Overflow -#define Raster_Err_Neg_Height FT_Err_Raster_Negative_Height -#define Raster_Err_Invalid FT_Err_Invalid_Outline -#define Raster_Err_Unsupported FT_Err_Unimplemented_Feature - - -#endif /* _STANDALONE_ */ - - - /* FMulDiv means `Fast MulDiv'; it is used in case where `b' is */ - /* typically a small value and the result of a*b is known to fit into */ - /* 32 bits. */ -#define FMulDiv( a, b, c ) ( (a) * (b) / (c) ) - - /* On the other hand, SMulDiv means `Slow MulDiv', and is used typically */ - /* for clipping computations. It simply uses the FT_MulDiv() function */ - /* defined in `ftcalc.h'. */ -#define SMulDiv FT_MulDiv - - /* The rasterizer is a very general purpose component; please leave */ - /* the following redefinitions there (you never know your target */ - /* environment). */ - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef NULL -#define NULL (void*)0 -#endif - -#ifndef SUCCESS -#define SUCCESS 0 -#endif - -#ifndef FAILURE -#define FAILURE 1 -#endif - - -#define MaxBezier 32 /* The maximum number of stacked Bezier curves. */ - /* Setting this constant to more than 32 is a */ - /* pure waste of space. */ - -#define Pixel_Bits 6 /* fractional bits of *input* coordinates */ - - - /*************************************************************************/ - /*************************************************************************/ - /** **/ - /** SIMPLE TYPE DECLARATIONS **/ - /** **/ - /*************************************************************************/ - /*************************************************************************/ - - typedef int Int; - typedef unsigned int UInt; - typedef short Short; - typedef unsigned short UShort, *PUShort; - typedef long Long, *PLong; - typedef unsigned long ULong; - - typedef unsigned char Byte, *PByte; - typedef char Bool; - - typedef struct TPoint_ - { - Long x; - Long y; - - } TPoint; - - - typedef enum TFlow_ - { - Flow_None = 0, - Flow_Up = 1, - Flow_Down = -1 - - } TFlow; - - - /* States of each line, arc, and profile */ - typedef enum TStates_ - { - Unknown, - Ascending, - Descending, - Flat - - } TStates; - - - typedef struct TProfile_ TProfile; - typedef TProfile* PProfile; - - struct TProfile_ - { - FT_F26Dot6 X; /* current coordinate during sweep */ - PProfile link; /* link to next profile - various purpose */ - PLong offset; /* start of profile's data in render pool */ - Int flow; /* Profile orientation: Asc/Descending */ - Long height; /* profile's height in scanlines */ - Long start; /* profile's starting scanline */ - - UShort countL; /* number of lines to step before this */ - /* profile becomes drawable */ - - PProfile next; /* next profile in same contour, used */ - /* during drop-out control */ - }; - - typedef PProfile TProfileList; - typedef PProfile* PProfileList; - - - /* Simple record used to implement a stack of bands, required */ - /* by the sub-banding mechanism */ - typedef struct TBand_ - { - Short y_min; /* band's minimum */ - Short y_max; /* band's maximum */ - - } TBand; - - -#define AlignProfileSize \ - ( ( sizeof ( TProfile ) + sizeof ( long ) - 1 ) / sizeof ( long ) ) - - -#ifdef TT_STATIC_RASTER - - -#define RAS_ARGS /* void */ -#define RAS_ARG /* void */ - -#define RAS_VARS /* void */ -#define RAS_VAR /* void */ - -#define FT_UNUSED_RASTER do ; while ( 0 ) - - -#else /* TT_STATIC_RASTER */ - - -#define RAS_ARGS TRaster_Instance* raster, -#define RAS_ARG TRaster_Instance* raster - -#define RAS_VARS raster, -#define RAS_VAR raster - -#define FT_UNUSED_RASTER FT_UNUSED( raster ) - - -#endif /* TT_STATIC_RASTER */ - - - typedef struct TRaster_Instance_ TRaster_Instance; - - - /* prototypes used for sweep function dispatch */ - typedef void Function_Sweep_Init( RAS_ARGS Short* min, - Short* max ); - - typedef void Function_Sweep_Span( RAS_ARGS Short y, - FT_F26Dot6 x1, - FT_F26Dot6 x2, - PProfile left, - PProfile right ); - - typedef void Function_Sweep_Step( RAS_ARG ); - - - /* NOTE: These operations are only valid on 2's complement processors */ - -#define FLOOR( x ) ( (x) & -ras.precision ) -#define CEILING( x ) ( ( (x) + ras.precision - 1 ) & -ras.precision ) -#define TRUNC( x ) ( (signed long)(x) >> ras.precision_bits ) -#define FRAC( x ) ( (x) & ( ras.precision - 1 ) ) -#define SCALED( x ) ( ( (x) << ras.scale_shift ) - ras.precision_half ) - - /* Note that I have moved the location of some fields in the */ - /* structure to ensure that the most used variables are used */ - /* at the top. Thus, their offset can be coded with less */ - /* opcodes, and it results in a smaller executable. */ - - struct TRaster_Instance_ - { - Int precision_bits; /* precision related variables */ - Int precision; - Int precision_half; - Long precision_mask; - Int precision_shift; - Int precision_step; - Int precision_jitter; - - Int scale_shift; /* == precision_shift for bitmaps */ - /* == precision_shift+1 for pixmaps */ - - PLong buff; /* The profiles buffer */ - PLong sizeBuff; /* Render pool size */ - PLong maxBuff; /* Profiles buffer size */ - PLong top; /* Current cursor in buffer */ - - FT_Error error; - - Int numTurns; /* number of Y-turns in outline */ - - TPoint* arc; /* current Bezier arc pointer */ - - UShort bWidth; /* target bitmap width */ - PByte bTarget; /* target bitmap buffer */ - PByte gTarget; /* target pixmap buffer */ - - Long lastX, lastY, minY, maxY; - - UShort num_Profs; /* current number of profiles */ - - Bool fresh; /* signals a fresh new profile which */ - /* 'start' field must be completed */ - Bool joint; /* signals that the last arc ended */ - /* exactly on a scanline. Allows */ - /* removal of doublets */ - PProfile cProfile; /* current profile */ - PProfile fProfile; /* head of linked list of profiles */ - PProfile gProfile; /* contour's first profile in case */ - /* of impact */ - - TStates state; /* rendering state */ - - FT_Bitmap target; /* description of target bit/pixmap */ - FT_Outline outline; - - Long traceOfs; /* current offset in target bitmap */ - Long traceG; /* current offset in target pixmap */ - - Short traceIncr; /* sweep's increment in target bitmap */ - - Short gray_min_x; /* current min x during gray rendering */ - Short gray_max_x; /* current max x during gray rendering */ - - /* dispatch variables */ - - Function_Sweep_Init* Proc_Sweep_Init; - Function_Sweep_Span* Proc_Sweep_Span; - Function_Sweep_Span* Proc_Sweep_Drop; - Function_Sweep_Step* Proc_Sweep_Step; - - Byte dropOutControl; /* current drop_out control method */ - - Bool second_pass; /* indicates wether a horizontal pass */ - /* should be performed to control */ - /* drop-out accurately when calling */ - /* Render_Glyph. Note that there is */ - /* no horizontal pass during gray */ - /* rendering. */ - - TPoint arcs[2 * MaxBezier + 1]; /* The Bezier stack */ - - TBand band_stack[16]; /* band stack used for sub-banding */ - Int band_top; /* band stack top */ - - Int count_table[256]; /* Look-up table used to quickly count */ - /* set bits in a gray 2x2 cell */ - - void* memory; - -#ifdef FT_RASTER_OPTION_ANTI_ALIASING - - Byte grays[5]; /* Palette of gray levels used for */ - /* render. */ - - Byte gray_lines[RASTER_GRAY_LINES]; - /* Intermediate table used to render the */ - /* graylevels pixmaps. */ - /* gray_lines is a buffer holding two */ - /* monochrome scanlines */ - - Short gray_width; /* width in bytes of one monochrome */ - /* intermediate scanline of gray_lines. */ - /* Each gray pixel takes 2 bits long there */ - - /* The gray_lines must hold 2 lines, thus with size */ - /* in bytes of at least `gray_width*2'. */ - -#endif /* FT_RASTER_ANTI_ALIASING */ - -#if 0 - PByte flags; /* current flags table */ - PUShort outs; /* current outlines table */ - FT_Vector* coords; - - UShort nPoints; /* number of points in current glyph */ - Short nContours; /* number of contours in current glyph */ -#endif - - }; - - -#ifdef FT_CONFIG_OPTION_STATIC_RASTER - - static TRaster_Instance cur_ras; -#define ras cur_ras - -#else - -#define ras (*raster) - -#endif /* FT_CONFIG_OPTION_STATIC_RASTER */ - - - /*************************************************************************/ - /*************************************************************************/ - /** **/ - /** PROFILES COMPUTATION **/ - /** **/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* Set_High_Precision */ - /* */ - /* */ - /* Sets precision variables according to param flag. */ - /* */ - /* */ - /* High :: Set to True for high precision (typically for ppem < 18), */ - /* false otherwise. */ - /* */ - static - void Set_High_Precision( RAS_ARGS Int High ) - { - if ( High ) - { - ras.precision_bits = 10; - ras.precision_step = 128; - ras.precision_jitter = 24; - } - else - { - ras.precision_bits = 6; - ras.precision_step = 32; - ras.precision_jitter = 2; - } - - FT_TRACE6(( "Set_High_Precision(%s)\n", High ? "true" : "false" )); - - ras.precision = 1L << ras.precision_bits; - ras.precision_half = ras.precision / 2; - ras.precision_shift = ras.precision_bits - Pixel_Bits; - ras.precision_mask = -ras.precision; - } - - - /*************************************************************************/ - /* */ - /* */ - /* New_Profile */ - /* */ - /* */ - /* Creates a new profile in the render pool. */ - /* */ - /* */ - /* aState :: The state/orientation of the new profile. */ - /* */ - /* */ - /* SUCCESS on success. FAILURE in case of overflow or of incoherent */ - /* profile. */ - /* */ - static - Bool New_Profile( RAS_ARGS TStates aState ) - { - if ( !ras.fProfile ) - { - ras.cProfile = (PProfile)ras.top; - ras.fProfile = ras.cProfile; - ras.top += AlignProfileSize; - } - - if ( ras.top >= ras.maxBuff ) - { - ras.error = Raster_Err_Overflow; - return FAILURE; - } - - switch ( aState ) - { - case Ascending: - ras.cProfile->flow = Flow_Up; - FT_TRACE6(( "New ascending profile = %lx\n", (long)ras.cProfile )); - break; - - case Descending: - ras.cProfile->flow = Flow_Down; - FT_TRACE6(( "New descending profile = %lx\n", (long)ras.cProfile )); - break; - - default: - FT_ERROR(( "New_Profile: invalid profile direction!\n" )); - ras.error = Raster_Err_Invalid; - return FAILURE; - } - - ras.cProfile->start = 0; - ras.cProfile->height = 0; - ras.cProfile->offset = ras.top; - ras.cProfile->link = (PProfile)0; - ras.cProfile->next = (PProfile)0; - - if ( !ras.gProfile ) - ras.gProfile = ras.cProfile; - - ras.state = aState; - ras.fresh = TRUE; - ras.joint = FALSE; - - return SUCCESS; - } - - - /*************************************************************************/ - /* */ - /* */ - /* End_Profile */ - /* */ - /* */ - /* Finalizes the current profile. */ - /* */ - /* */ - /* SUCCESS on success. FAILURE in case of overflow or incoherency. */ - /* */ - static - Bool End_Profile( RAS_ARG ) - { - Long h; - PProfile oldProfile; - - - h = ras.top - ras.cProfile->offset; - - if ( h < 0 ) - { - FT_ERROR(( "End_Profile: negative height encountered!\n" )); - ras.error = Raster_Err_Neg_Height; - return FAILURE; - } - - if ( h > 0 ) - { - FT_TRACE6(( "Ending profile %lx, start = %ld, height = %ld\n", - (long)ras.cProfile, ras.cProfile->start, h )); - - oldProfile = ras.cProfile; - ras.cProfile->height = h; - ras.cProfile = (PProfile)ras.top; - - ras.top += AlignProfileSize; - - ras.cProfile->height = 0; - ras.cProfile->offset = ras.top; - oldProfile->next = ras.cProfile; - ras.num_Profs++; - } - - if ( ras.top >= ras.maxBuff ) - { - FT_TRACE1(( "overflow in End_Profile\n" )); - ras.error = Raster_Err_Overflow; - return FAILURE; - } - - ras.joint = FALSE; - - return SUCCESS; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Insert_Y_Turn */ - /* */ - /* */ - /* Inserts a salient into the sorted list placed on top of the render */ - /* pool. */ - /* */ - /* */ - /* New y scanline position. */ - /* */ - /* */ - /* SUCCESS on success. FAILURE in case of overflow. */ - /* */ - static - Bool Insert_Y_Turn( RAS_ARGS Int y ) - { - PLong y_turns; - Int y2, n; - - - n = ras.numTurns - 1; - y_turns = ras.sizeBuff - ras.numTurns; - - /* look for first y value that is <= */ - while ( n >= 0 && y < y_turns[n] ) - n--; - - /* if it is <, simply insert it, ignore if == */ - if ( n >= 0 && y > y_turns[n] ) - while ( n >= 0 ) - { - y2 = y_turns[n]; - y_turns[n] = y; - y = y2; - n--; - } - - if ( n < 0 ) - { - if ( ras.maxBuff <= ras.top ) - { - ras.error = Raster_Err_Overflow; - return FAILURE; - } - ras.maxBuff--; - ras.numTurns++; - ras.sizeBuff[-ras.numTurns] = y; - } - - return SUCCESS; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Finalize_Profile_Table */ - /* */ - /* */ - /* Adjusts all links in the profiles list. */ - /* */ - /* */ - /* SUCCESS on success. FAILURE in case of overflow. */ - /* */ - static - Bool Finalize_Profile_Table( RAS_ARG ) - { - Int bottom, top; - UShort n; - PProfile p; - - - n = ras.num_Profs; - - if ( n > 1 ) - { - p = ras.fProfile; - while ( n > 0 ) - { - if ( n > 1 ) - p->link = (PProfile)( p->offset + p->height ); - else - p->link = NULL; - - switch ( p->flow ) - { - case Flow_Down: - bottom = p->start - p->height+1; - top = p->start; - p->start = bottom; - p->offset += p->height - 1; - break; - - case Flow_Up: - default: - bottom = p->start; - top = p->start + p->height - 1; - } - - if ( Insert_Y_Turn( RAS_VARS bottom ) || - Insert_Y_Turn( RAS_VARS top + 1 ) ) - return FAILURE; - - p = p->link; - n--; - } - } - else - ras.fProfile = NULL; - - return SUCCESS; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Split_Conic */ - /* */ - /* */ - /* Subdivides one conic Bezier into two joint sub-arcs in the Bezier */ - /* stack. */ - /* */ - /* */ - /* None (subdivided Bezier is taken from the top of the stack). */ - /* */ - /* */ - /* This routine is the `beef' of this component. It is _the_ inner */ - /* loop that should be optimized to hell to get the best performance. */ - /* */ - static - void Split_Conic( TPoint* base ) - { - Long a, b; - - - base[4].x = base[2].x; - b = base[1].x; - a = base[3].x = ( base[2].x + b ) / 2; - b = base[1].x = ( base[0].x + b ) / 2; - base[2].x = ( a + b ) / 2; - - base[4].y = base[2].y; - b = base[1].y; - a = base[3].y = ( base[2].y + b ) / 2; - b = base[1].y = ( base[0].y + b ) / 2; - base[2].y = ( a + b ) / 2; - - /* hand optimized. gcc doesn't seem to be too good at common */ - /* expression substitution and instruction scheduling ;-) */ - } - - - /*************************************************************************/ - /* */ - /* */ - /* Split_Cubic */ - /* */ - /* */ - /* Subdivides a third-order Bezier arc into two joint sub-arcs in the */ - /* Bezier stack. */ - /* */ - /* */ - /* This routine is the `beef' of the component. It is one of _the_ */ - /* inner loops that should be optimized like hell to get the best */ - /* performance. */ - /* */ - static - void Split_Cubic( TPoint* base ) - { - Long a, b, c, d; - - - base[6].x = base[3].x; - c = base[1].x; - d = base[2].x; - base[1].x = a = ( base[0].x + c + 1 ) >> 1; - base[5].x = b = ( base[3].x + d + 1 ) >> 1; - c = ( c + d + 1 ) >> 1; - base[2].x = a = ( a + c + 1 ) >> 1; - base[4].x = b = ( b + c + 1 ) >> 1; - base[3].x = ( a + b + 1 ) >> 1; - - base[6].y = base[3].y; - c = base[1].y; - d = base[2].y; - base[1].y = a = ( base[0].y + c + 1 ) >> 1; - base[5].y = b = ( base[3].y + d + 1 ) >> 1; - c = ( c + d + 1 ) >> 1; - base[2].y = a = ( a + c + 1 ) >> 1; - base[4].y = b = ( b + c + 1 ) >> 1; - base[3].y = ( a + b + 1 ) >> 1; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Line_Up */ - /* */ - /* */ - /* Computes the x-coordinates of an ascending line segment and stores */ - /* them in the render pool. */ - /* */ - /* */ - /* x1 :: The x-coordinate of the segment's start point. */ - /* */ - /* y1 :: The y-coordinate of the segment's start point. */ - /* */ - /* x2 :: The x-coordinate of the segment's end point. */ - /* */ - /* y2 :: The y-coordinate of the segment's end point. */ - /* */ - /* miny :: A lower vertical clipping bound value. */ - /* */ - /* maxy :: An upper vertical clipping bound value. */ - /* */ - /* */ - /* SUCCESS on success, FAILURE on render pool overflow. */ - /* */ - static - Bool Line_Up( RAS_ARGS Long x1, - Long y1, - Long x2, - Long y2, - Long miny, - Long maxy ) - { - Long Dx, Dy; - Int e1, e2, f1, f2, size; /* XXX: is `Short' sufficient? */ - Long Ix, Rx, Ax; - - PLong top; - - - Dx = x2 - x1; - Dy = y2 - y1; - - if ( Dy <= 0 || y2 < miny || y1 > maxy ) - return SUCCESS; - - if ( y1 < miny ) - { - /* Take care: miny-y1 can be a very large value; we use */ - /* a slow MulDiv function to avoid clipping bugs */ - x1 += SMulDiv( Dx, miny - y1, Dy ); - e1 = TRUNC( miny ); - f1 = 0; - } - else - { - e1 = TRUNC( y1 ); - f1 = FRAC( y1 ); - } - - if ( y2 > maxy ) - { - /* x2 += FMulDiv( Dx, maxy - y2, Dy ); UNNECESSARY */ - e2 = TRUNC( maxy ); - f2 = 0; - } - else - { - e2 = TRUNC( y2 ); - f2 = FRAC( y2 ); - } - - if ( f1 > 0 ) - { - if ( e1 == e2 ) - return SUCCESS; - else - { - x1 += FMulDiv( Dx, ras.precision - f1, Dy ); - e1 += 1; - } - } - else - if ( ras.joint ) - { - ras.top--; - ras.joint = FALSE; - } - - ras.joint = ( f2 == 0 ); - - if ( ras.fresh ) - { - ras.cProfile->start = e1; - ras.fresh = FALSE; - } - - size = e2 - e1 + 1; - if ( ras.top + size >= ras.maxBuff ) - { - ras.error = Raster_Err_Overflow; - return FAILURE; - } - - if ( Dx > 0 ) - { - Ix = ( ras.precision * Dx ) / Dy; - Rx = ( ras.precision * Dx ) % Dy; - Dx = 1; - } - else - { - Ix = -( ( ras.precision * -Dx ) / Dy ); - Rx = ( ras.precision * -Dx ) % Dy; - Dx = -1; - } - - Ax = -Dy; - top = ras.top; - - while ( size > 0 ) - { - *top++ = x1; - - x1 += Ix; - Ax += Rx; - if ( Ax >= 0 ) - { - Ax -= Dy; - x1 += Dx; - } - size--; - } - - ras.top = top; - return SUCCESS; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Line_Down */ - /* */ - /* */ - /* Computes the x-coordinates of an descending line segment and */ - /* stores them in the render pool. */ - /* */ - /* */ - /* x1 :: The x-coordinate of the segment's start point. */ - /* */ - /* y1 :: The y-coordinate of the segment's start point. */ - /* */ - /* x2 :: The x-coordinate of the segment's end point. */ - /* */ - /* y2 :: The y-coordinate of the segment's end point. */ - /* */ - /* miny :: A lower vertical clipping bound value. */ - /* */ - /* maxy :: An upper vertical clipping bound value. */ - /* */ - /* */ - /* SUCCESS on success, FAILURE on render pool overflow. */ - /* */ - static - Bool Line_Down( RAS_ARGS Long x1, - Long y1, - Long x2, - Long y2, - Long miny, - Long maxy ) - { - Bool result, fresh; - - - fresh = ras.fresh; - - result = Line_Up( RAS_VARS x1, -y1, x2, -y2, -maxy, -miny ); - - if ( fresh && !ras.fresh ) - ras.cProfile->start = -ras.cProfile->start; - - return result; - } - - - /* A function type describing the functions used to split Bezier arcs */ - typedef void (*TSplitter)( TPoint* base ); - - - /*************************************************************************/ - /* */ - /* */ - /* Bezier_Up */ - /* */ - /* */ - /* Computes the x-coordinates of an ascending Bezier arc and stores */ - /* them in the render pool. */ - /* */ - /* */ - /* degree :: The degree of the Bezier arc (either 2 or 3). */ - /* */ - /* splitter :: The function to split Bezier arcs. */ - /* */ - /* miny :: A lower vertical clipping bound value. */ - /* */ - /* maxy :: An upper vertical clipping bound value. */ - /* */ - /* */ - /* SUCCESS on success, FAILURE on render pool overflow. */ - /* */ - static - Bool Bezier_Up( RAS_ARGS Int degree, - TSplitter splitter, - Long miny, - Long maxy ) - { - Long y1, y2, e, e2, e0; - Short f1; - - TPoint* arc; - TPoint* start_arc; - - PLong top; - - - arc = ras.arc; - y1 = arc[degree].y; - y2 = arc[0].y; - top = ras.top; - - if ( y2 < miny || y1 > maxy ) - goto Fin; - - e2 = FLOOR( y2 ); - - if ( e2 > maxy ) - e2 = maxy; - - e0 = miny; - - if ( y1 < miny ) - e = miny; - else - { - e = CEILING( y1 ); - f1 = FRAC( y1 ); - e0 = e; - - if ( f1 == 0 ) - { - if ( ras.joint ) - { - top--; - ras.joint = FALSE; - } - - *top++ = arc[degree].x; - - e += ras.precision; - } - } - - if ( ras.fresh ) - { - ras.cProfile->start = TRUNC( e0 ); - ras.fresh = FALSE; - } - - if ( e2 < e ) - goto Fin; - - if ( ( top + TRUNC( e2 - e ) + 1 ) >= ras.maxBuff ) - { - ras.top = top; - ras.error = Raster_Err_Overflow; - return FAILURE; - } - - start_arc = arc; - - while ( arc >= start_arc && e <= e2 ) - { - ras.joint = FALSE; - - y2 = arc[0].y; - - if ( y2 > e ) - { - y1 = arc[degree].y; - if ( y2 - y1 >= ras.precision_step ) - { - splitter( arc ); - arc += degree; - } - else - { - *top++ = arc[degree].x + FMulDiv( arc[0].x-arc[degree].x, - e - y1, y2 - y1 ); - arc -= degree; - e += ras.precision; - } - } - else - { - if ( y2 == e ) - { - ras.joint = TRUE; - *top++ = arc[0].x; - - e += ras.precision; - } - arc -= degree; - } - } - - Fin: - ras.top = top; - ras.arc -= degree; - return SUCCESS; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Bezier_Down */ - /* */ - /* */ - /* Computes the x-coordinates of an descending Bezier arc and stores */ - /* them in the render pool. */ - /* */ - /* */ - /* degree :: The degree of the Bezier arc (either 2 or 3). */ - /* */ - /* splitter :: The function to split Bezier arcs. */ - /* */ - /* miny :: A lower vertical clipping bound value. */ - /* */ - /* maxy :: An upper vertical clipping bound value. */ - /* */ - /* */ - /* SUCCESS on success, FAILURE on render pool overflow. */ - /* */ - static - Bool Bezier_Down( RAS_ARGS Int degree, - TSplitter splitter, - Long miny, - Long maxy ) - { - TPoint* arc = ras.arc; - Bool result, fresh; - - - arc[0].y = -arc[0].y; - arc[1].y = -arc[1].y; - arc[2].y = -arc[2].y; - if ( degree > 2 ) - arc[3].y = -arc[3].y; - - fresh = ras.fresh; - - result = Bezier_Up( RAS_VARS degree, splitter, -maxy, -miny ); - - if ( fresh && !ras.fresh ) - ras.cProfile->start = -ras.cProfile->start; - - arc[0].y = -arc[0].y; - return result; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Line_To */ - /* */ - /* */ - /* Injects a new line segment and adjusts Profiles list. */ - /* */ - /* */ - /* x :: The x-coordinate of the segment's end point (its start point */ - /* is stored in `LastX'). */ - /* */ - /* y :: The y-coordinate of the segment's end point (its start point */ - /* is stored in `LastY'). */ - /* */ - /* */ - /* SUCCESS on success, FAILURE on render pool overflow or incorrect */ - /* profile. */ - /* */ - static - Bool Line_To( RAS_ARGS Long x, - Long y ) - { - /* First, detect a change of direction */ - - switch ( ras.state ) - { - case Unknown: - if ( y > ras.lastY ) - { - if ( New_Profile( RAS_VARS Ascending ) ) - return FAILURE; - } - else - { - if ( y < ras.lastY ) - if ( New_Profile( RAS_VARS Descending ) ) - return FAILURE; - } - break; - - case Ascending: - if ( y < ras.lastY ) - { - if ( End_Profile( RAS_VAR ) || - New_Profile( RAS_VARS Descending ) ) - return FAILURE; - } - break; - - case Descending: - if ( y > ras.lastY ) - { - if ( End_Profile( RAS_VAR ) || - New_Profile( RAS_VARS Ascending ) ) - return FAILURE; - } - break; - - default: - ; - } - - /* Then compute the lines */ - - switch ( ras.state ) - { - case Ascending: - if ( Line_Up( RAS_VARS ras.lastX, ras.lastY, - x, y, ras.minY, ras.maxY ) ) - return FAILURE; - break; - - case Descending: - if ( Line_Down( RAS_VARS ras.lastX, ras.lastY, - x, y, ras.minY, ras.maxY ) ) - return FAILURE; - break; - - default: - ; - } - - ras.lastX = x; - ras.lastY = y; - - return SUCCESS; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Conic_To */ - /* */ - /* */ - /* Injects a new conic arc and adjusts the profile list. */ - /* */ - /* */ - /* cx :: The x-coordinate of the arc's new control point. */ - /* */ - /* cy :: The y-coordinate of the arc's new control point. */ - /* */ - /* x :: The x-coordinate of the arc's end point (its start point is */ - /* stored in `LastX'). */ - /* */ - /* y :: The y-coordinate of the arc's end point (its start point is */ - /* stored in `LastY'). */ - /* */ - /* */ - /* SUCCESS on success, FAILURE on render pool overflow or incorrect */ - /* profile. */ - /* */ - static - Bool Conic_To( RAS_ARGS Long cx, - Long cy, - Long x, - Long y ) - { - Long y1, y2, y3, x3, ymin, ymax; - TStates state_bez; - - - ras.arc = ras.arcs; - ras.arc[2].x = ras.lastX; - ras.arc[2].y = ras.lastY; - ras.arc[1].x = cx; ras.arc[1].y = cy; - ras.arc[0].x = x; ras.arc[0].y = y; - - do - { - y1 = ras.arc[2].y; - y2 = ras.arc[1].y; - y3 = ras.arc[0].y; - x3 = ras.arc[0].x; - - /* first, categorize the Bezier arc */ - - if ( y1 <= y3 ) - { - ymin = y1; - ymax = y3; - } - else - { - ymin = y3; - ymax = y1; - } - - if ( y2 < ymin || y2 > ymax ) - { - /* this arc has no given direction, split it! */ - Split_Conic( ras.arc ); - ras.arc += 2; - } - else if ( y1 == y3 ) - { - /* this arc is flat, ignore it and pop it from the Bezier stack */ - ras.arc -= 2; - } - else - { - /* the arc is y-monotonous, either ascending or descending */ - /* detect a change of direction */ - state_bez = y1 < y3 ? Ascending : Descending; - if ( ras.state != state_bez ) - { - /* finalize current profile if any */ - if ( ras.state != Unknown && - End_Profile( RAS_VAR ) ) - goto Fail; - - /* create a new profile */ - if ( New_Profile( RAS_VARS state_bez ) ) - goto Fail; - } - - /* now call the appropriate routine */ - if ( state_bez == Ascending ) - { - if ( Bezier_Up( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) ) - goto Fail; - } - else - if ( Bezier_Down( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) ) - goto Fail; - } - - } while ( ras.arc >= ras.arcs ); - - ras.lastX = x3; - ras.lastY = y3; - - return SUCCESS; - - Fail: - return FAILURE; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Cubic_To */ - /* */ - /* */ - /* Injects a new cubic arc and adjusts the profile list. */ - /* */ - /* */ - /* cx1 :: The x-coordinate of the arc's first new control point. */ - /* */ - /* cy1 :: The y-coordinate of the arc's first new control point. */ - /* */ - /* cx2 :: The x-coordinate of the arc's second new control point. */ - /* */ - /* cy2 :: The y-coordinate of the arc's second new control point. */ - /* */ - /* x :: The x-coordinate of the arc's end point (its start point is */ - /* stored in `LastX'). */ - /* */ - /* y :: The y-coordinate of the arc's end point (its start point is */ - /* stored in `LastY'). */ - /* */ - /* */ - /* SUCCESS on success, FAILURE on render pool overflow or incorrect */ - /* profile. */ - /* */ - static - Bool Cubic_To( RAS_ARGS Long cx1, - Long cy1, - Long cx2, - Long cy2, - Long x, - Long y ) - { - Long y1, y2, y3, y4, x4, ymin1, ymax1, ymin2, ymax2; - TStates state_bez; - - - ras.arc = ras.arcs; - ras.arc[3].x = ras.lastX; - ras.arc[3].y = ras.lastY; - ras.arc[2].x = cx1; ras.arc[2].y = cy1; - ras.arc[1].x = cx2; ras.arc[1].y = cy2; - ras.arc[0].x = x; ras.arc[0].y = y; - - do - { - y1 = ras.arc[3].y; - y2 = ras.arc[2].y; - y3 = ras.arc[1].y; - y4 = ras.arc[0].y; - x4 = ras.arc[0].x; - - /* first, categorize the Bezier arc */ - - if ( y1 <= y4 ) - { - ymin1 = y1; - ymax1 = y4; - } - else - { - ymin1 = y4; - ymax1 = y1; - } - - if ( y2 <= y3 ) - { - ymin2 = y2; - ymax2 = y3; - } - else - { - ymin2 = y3; - ymax2 = y2; - } - - if ( ymin2 < ymin1 || ymax2 > ymax1 ) - { - /* this arc has no given direction, split it! */ - Split_Cubic( ras.arc ); - ras.arc += 3; - } - else if ( y1 == y4 ) - { - /* this arc is flat, ignore it and pop it from the Bezier stack */ - ras.arc -= 3; - } - else - { - state_bez = ( y1 <= y4 ) ? Ascending : Descending; - - /* detect a change of direction */ - if ( ras.state != state_bez ) - { - if ( ras.state != Unknown && - End_Profile( RAS_VAR ) ) - goto Fail; - - if ( New_Profile( RAS_VARS state_bez ) ) - goto Fail; - } - - /* compute intersections */ - if ( state_bez == Ascending ) - { - if ( Bezier_Up( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) ) - goto Fail; - } - else - if ( Bezier_Down( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) ) - goto Fail; - } - - } while ( ras.arc >= ras.arcs ); - - ras.lastX = x4; - ras.lastY = y4; - - return SUCCESS; - - Fail: - return FAILURE; - } - - -#undef SWAP_ -#define SWAP_( x, y ) do \ - { \ - Long swap = x; \ - \ - \ - x = y; \ - y = swap; \ - } while ( 0 ) - - - /*************************************************************************/ - /* */ - /* */ - /* Decompose_Curve */ - /* */ - /* */ - /* Scans the outline arays in order to emit individual segments and */ - /* Beziers by calling Line_To() and Bezier_To(). It handles all */ - /* weird cases, like when the first point is off the curve, or when */ - /* there are simply no `on' points in the contour! */ - /* */ - /* */ - /* first :: The index of the first point in the contour. */ - /* */ - /* last :: The index of the last point in the contour. */ - /* */ - /* flipped :: If set, flip the direction of the curve. */ - /* */ - /* */ - /* SUCCESS on success, FAILURE on error. */ - /* */ - static - Bool Decompose_Curve( RAS_ARGS UShort first, - UShort last, - int flipped ) - { - FT_Vector v_last; - FT_Vector v_control; - FT_Vector v_start; - - FT_Vector* points; - FT_Vector* point; - FT_Vector* limit; - char* tags; - - char tag; /* current point's state */ - - - points = ras.outline.points; - limit = points + last; - - v_start.x = SCALED( points[first].x ); - v_start.y = SCALED( points[first].y ); - v_last.x = SCALED( points[last].x ); - v_last.y = SCALED( points[last].y ); - - if ( flipped ) - { - SWAP_( v_start.x, v_start.y ); - SWAP_( v_last.x, v_last.y ); - } - - v_control = v_start; - - point = points + first; - tags = ras.outline.tags + first; - tag = FT_CURVE_TAG( tags[0] ); - - /* A contour cannot start with a cubic control point! */ - if ( tag == FT_Curve_Tag_Cubic ) - goto Invalid_Outline; - - /* check first point to determine origin */ - if ( tag == FT_Curve_Tag_Conic ) - { - /* first point is conic control. Yes, this happens. */ - if ( FT_CURVE_TAG( ras.outline.tags[last] ) == FT_Curve_Tag_On ) - { - /* start at last point if it is on the curve */ - v_start = v_last; - limit--; - } - else - { - /* if both first and last points are conic, */ - /* start at their middle and record its position */ - /* for closure */ - v_start.x = ( v_start.x + v_last.x ) / 2; - v_start.y = ( v_start.y + v_last.y ) / 2; - - v_last = v_start; - } - point--; - tags--; - } - - ras.lastX = v_start.x; - ras.lastY = v_start.y; - - while ( point < limit ) - { - point++; - tags++; - - tag = FT_CURVE_TAG( tags[0] ); - - switch ( tag ) - { - case FT_Curve_Tag_On: /* emit a single line_to */ - { - Long x, y; - - - x = SCALED( point->x ); - y = SCALED( point->y ); - if ( flipped ) - SWAP_( x, y ); - - if ( Line_To( RAS_VARS x, y ) ) - goto Fail; - continue; - } - - case FT_Curve_Tag_Conic: /* consume conic arcs */ - v_control.x = SCALED( point[0].x ); - v_control.y = SCALED( point[0].y ); - - if ( flipped ) - SWAP_( v_control.x, v_control.y ); - - Do_Conic: - if ( point < limit ) - { - FT_Vector v_middle; - Long x, y; - - - point++; - tags++; - tag = FT_CURVE_TAG( tags[0] ); - - x = SCALED( point[0].x ); - y = SCALED( point[0].y ); - - if ( flipped ) - SWAP_( x, y ); - - if ( tag == FT_Curve_Tag_On ) - { - if ( Conic_To( RAS_VARS v_control.x, v_control.y, x, y ) ) - goto Fail; - continue; - } - - if ( tag != FT_Curve_Tag_Conic ) - goto Invalid_Outline; - - v_middle.x = ( v_control.x + x ) / 2; - v_middle.y = ( v_control.y + y ) / 2; - - if ( Conic_To( RAS_VARS v_control.x, v_control.y, - v_middle.x, v_middle.y ) ) - goto Fail; - - v_control.x = x; - v_control.y = y; - - goto Do_Conic; - } - - if ( Conic_To( RAS_VARS v_control.x, v_control.y, - v_start.x, v_start.y ) ) - goto Fail; - - goto Close; - - default: /* FT_Curve_Tag_Cubic */ - { - Long x1, y1, x2, y2, x3, y3; - - - if ( point + 1 > limit || - FT_CURVE_TAG( tags[1] ) != FT_Curve_Tag_Cubic ) - goto Invalid_Outline; - - point += 2; - tags += 2; - - x1 = SCALED( point[-2].x ); - y1 = SCALED( point[-2].y ); - x2 = SCALED( point[-1].x ); - y2 = SCALED( point[-1].y ); - x3 = SCALED( point[ 0].x ); - y3 = SCALED( point[ 0].y ); - - if ( flipped ) - { - SWAP_( x1, y1 ); - SWAP_( x2, y2 ); - SWAP_( x3, y3 ); - } - - if ( point <= limit ) - { - if ( Cubic_To( RAS_VARS x1, y1, x2, y2, x3, y3 ) ) - goto Fail; - continue; - } - - if ( Cubic_To( RAS_VARS x1, y1, x2, y2, v_start.x, v_start.y ) ) - goto Fail; - goto Close; - } - } - } - - /* close the contour with a line segment */ - if ( Line_To( RAS_VARS v_start.x, v_start.y ) ) - goto Fail; - - Close: - return SUCCESS; - - Invalid_Outline: - ras.error = Raster_Err_Invalid; - - Fail: - return FAILURE; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Convert_Glyph */ - /* */ - /* */ - /* Converts a glyph into a series of segments and arcs and makes a */ - /* profiles list with them. */ - /* */ - /* */ - /* flipped :: If set, flip the direction of curve. */ - /* */ - /* */ - /* SUCCESS on success, FAILURE if any error was encountered during */ - /* rendering. */ - /* */ - static - Bool Convert_Glyph( RAS_ARGS int flipped ) - { - Short i; - UShort start; - - PProfile lastProfile; - - - ras.fProfile = NULL; - ras.joint = FALSE; - ras.fresh = FALSE; - - ras.maxBuff = ras.sizeBuff - AlignProfileSize; - - ras.numTurns = 0; - - ras.cProfile = (PProfile)ras.top; - ras.cProfile->offset = ras.top; - ras.num_Profs = 0; - - start = 0; - - for ( i = 0; i < ras.outline.n_contours; i++ ) - { - ras.state = Unknown; - ras.gProfile = NULL; - - if ( Decompose_Curve( RAS_VARS start, ras.outline.contours[i], flipped ) ) - return FAILURE; - - start = ras.outline.contours[i] + 1; - - /* We must now see whether the extreme arcs join or not */ - if ( FRAC( ras.lastY ) == 0 && - ras.lastY >= ras.minY && - ras.lastY <= ras.maxY ) - if ( ras.gProfile && ras.gProfile->flow == ras.cProfile->flow ) - ras.top--; - /* Note that ras.gProfile can be nil if the contour was too small */ - /* to be drawn. */ - - lastProfile = ras.cProfile; - if ( End_Profile( RAS_VAR ) ) - return FAILURE; - - /* close the `next profile in contour' linked list */ - if ( ras.gProfile ) - lastProfile->next = ras.gProfile; - } - - if ( Finalize_Profile_Table( RAS_VAR ) ) - return FAILURE; - - return ( ras.top < ras.maxBuff ? SUCCESS : FAILURE ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /** **/ - /** SCAN-LINE SWEEPS AND DRAWING **/ - /** **/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* Init_Linked */ - /* */ - /* Initializes an empty linked list. */ - /* */ - static - void Init_Linked( TProfileList* l ) - { - *l = NULL; - } - - - /*************************************************************************/ - /* */ - /* InsNew */ - /* */ - /* Inserts a new profile in a linked list. */ - /* */ - static - void InsNew( PProfileList list, - PProfile profile ) - { - PProfile *old, current; - Long x; - - - old = list; - current = *old; - x = profile->X; - - while ( current ) - { - if ( x < current->X ) - break; - old = ¤t->link; - current = *old; - } - - profile->link = current; - *old = profile; - } - - - /*************************************************************************/ - /* */ - /* DelOld */ - /* */ - /* Removes an old profile from a linked list. */ - /* */ - static - void DelOld( PProfileList list, - PProfile profile ) - { - PProfile *old, current; - - - old = list; - current = *old; - - while ( current ) - { - if ( current == profile ) - { - *old = current->link; - return; - } - - old = ¤t->link; - current = *old; - } - - /* we should never get there, unless the profile was not part of */ - /* the list. */ - } - - - /*************************************************************************/ - /* */ - /* Update */ - /* */ - /* Update all X offsets of a drawing list. */ - /* */ - static - void Update( PProfile first ) - { - PProfile current = first; - - - while ( current ) - { - current->X = *current->offset; - current->offset += current->flow; - current->height--; - current = current->link; - } - } - - - /*************************************************************************/ - /* */ - /* Sort */ - /* */ - /* Sorts a trace list. In 95%, the list is already sorted. We need */ - /* an algorithm which is fast in this case. Bubble sort is enough */ - /* and simple. */ - /* */ - static - void Sort( PProfileList list ) - { - PProfile *old, current, next; - - - /* First, set the new X coordinate of each profile */ - Update( *list ); - - /* Then sort them */ - old = list; - current = *old; - - if ( !current ) - return; - - next = current->link; - - while ( next ) - { - if ( current->X <= next->X ) - { - old = ¤t->link; - current = *old; - - if ( !current ) - return; - } - else - { - *old = next; - current->link = next->link; - next->link = current; - - old = list; - current = *old; - } - - next = current->link; - } - } - - - /*************************************************************************/ - /* */ - /* Vertical Sweep Procedure Set */ - /* */ - /* These four routines are used during the vertical black/white sweep */ - /* phase by the generic Draw_Sweep() function. */ - /* */ - /*************************************************************************/ - - static - void Vertical_Sweep_Init( RAS_ARGS Short* min, - Short* max ) - { - Long pitch = ras.target.pitch; - - FT_UNUSED( max ); - - - ras.traceIncr = (Short)-pitch; - ras.traceOfs = -*min * pitch; - if ( pitch > 0 ) - ras.traceOfs += ( ras.target.rows - 1 ) * pitch; - - ras.gray_min_x = 0; - ras.gray_max_x = 0; - } - - - static - void Vertical_Sweep_Span( RAS_ARGS Short y, - FT_F26Dot6 x1, - FT_F26Dot6 x2, - PProfile left, - PProfile right ) - { - Long e1, e2; - Short c1, c2; - Byte f1, f2; - Byte* target; - - FT_UNUSED( y ); - FT_UNUSED( left ); - FT_UNUSED( right ); - - - /* Drop-out control */ - - e1 = TRUNC( CEILING( x1 ) ); - - if ( x2 - x1 - ras.precision <= ras.precision_jitter ) - e2 = e1; - else - e2 = TRUNC( FLOOR( x2 ) ); - - if ( e2 >= 0 && e1 < ras.bWidth ) - { - if ( e1 < 0 ) - e1 = 0; - if ( e2 >= ras.bWidth ) - e2 = ras.bWidth - 1; - - c1 = (Short)( e1 >> 3 ); - c2 = (Short)( e2 >> 3 ); - - f1 = (unsigned char)0xFF >> ( e1 & 7 ); - f2 = ~( (unsigned char)0x7F >> ( e2 & 7 ) ); - - if ( ras.gray_min_x > c1 ) ras.gray_min_x = c1; - if ( ras.gray_max_x < c2 ) ras.gray_max_x = c2; - - target = ras.bTarget + ras.traceOfs + c1; - c2 -= c1; - - if ( c2 > 0 ) - { - target[0] |= f1; - - /* memset() is slower than the following code on many platforms. */ - /* This is due to the fact that, in the vast majority of cases, */ - /* the span length in bytes is relatively small. */ - c2--; - while ( c2 > 0 ) - { - *(++target) = 0xFF; - c2--; - } - target[1] |= f2; - } - else - *target |= ( f1 & f2 ); - } - } - - - static - void Vertical_Sweep_Drop( RAS_ARGS Short y, - FT_F26Dot6 x1, - FT_F26Dot6 x2, - PProfile left, - PProfile right ) - { - Long e1, e2; - Short c1, f1; - - - /* Drop-out control */ - - e1 = CEILING( x1 ); - e2 = FLOOR ( x2 ); - - if ( e1 > e2 ) - { - if ( e1 == e2 + ras.precision ) - { - switch ( ras.dropOutControl ) - { - case 1: - e1 = e2; - break; - - case 4: - e1 = CEILING( (x1 + x2 + 1) / 2 ); - break; - - case 2: - case 5: - /* Drop-out Control Rule #4 */ - - /* The spec is not very clear regarding rule #4. It */ - /* presents a method that is way too costly to implement */ - /* while the general idea seems to get rid of `stubs'. */ - /* */ - /* Here, we only get rid of stubs recognized if: */ - /* */ - /* upper stub: */ - /* */ - /* - P_Left and P_Right are in the same contour */ - /* - P_Right is the successor of P_Left in that contour */ - /* - y is the top of P_Left and P_Right */ - /* */ - /* lower stub: */ - /* */ - /* - P_Left and P_Right are in the same contour */ - /* - P_Left is the successor of P_Right in that contour */ - /* - y is the bottom of P_Left */ - /* */ - - /* FIXXXME: uncommenting this line solves the disappearing */ - /* bit problem in the `7' of verdana 10pts, but */ - /* makes a new one in the `C' of arial 14pts */ - -#if 0 - if ( x2 - x1 < ras.precision_half ) -#endif - { - /* upper stub test */ - if ( left->next == right && left->height <= 0 ) - return; - - /* lower stub test */ - if ( right->next == left && left->start == y ) - return; - } - - /* check that the rightmost pixel isn't set */ - - e1 = TRUNC( e1 ); - - c1 = (Short)( e1 >> 3 ); - f1 = e1 & 7; - - if ( e1 >= 0 && e1 < ras.bWidth && - ras.bTarget[ras.traceOfs + c1] & ( 0x80 >> f1 ) ) - return; - - if ( ras.dropOutControl == 2 ) - e1 = e2; - else - e1 = CEILING( ( x1 + x2 + 1 ) / 2 ); - - break; - - default: - return; /* unsupported mode */ - } - } - else - return; - } - - e1 = TRUNC( e1 ); - - if ( e1 >= 0 && e1 < ras.bWidth ) - { - c1 = (Short)( e1 >> 3 ); - f1 = e1 & 7; - - if ( ras.gray_min_x > c1 ) ras.gray_min_x = c1; - if ( ras.gray_max_x < c1 ) ras.gray_max_x = c1; - - ras.bTarget[ras.traceOfs + c1] |= (char)( 0x80 >> f1 ); - } - } - - - static - void Vertical_Sweep_Step( RAS_ARG ) - { - ras.traceOfs += ras.traceIncr; - } - - - /***********************************************************************/ - /* */ - /* Horizontal Sweep Procedure Set */ - /* */ - /* These four routines are used during the horizontal black/white */ - /* sweep phase by the generic Draw_Sweep() function. */ - /* */ - /***********************************************************************/ - - static - void Horizontal_Sweep_Init( RAS_ARGS Short* min, - Short* max ) - { - /* nothing, really */ - FT_UNUSED( raster ); - FT_UNUSED( min ); - FT_UNUSED( max ); - } - - - static - void Horizontal_Sweep_Span( RAS_ARGS Short y, - FT_F26Dot6 x1, - FT_F26Dot6 x2, - PProfile left, - PProfile right ) - { - Long e1, e2; - PByte bits; - Byte f1; - - FT_UNUSED( left ); - FT_UNUSED( right ); - - - if ( x2 - x1 < ras.precision ) - { - e1 = CEILING( x1 ); - e2 = FLOOR ( x2 ); - - if ( e1 == e2 ) - { - bits = ras.bTarget + ( y >> 3 ); - f1 = (Byte)( 0x80 >> ( y & 7 ) ); - - e1 = TRUNC( e1 ); - - if ( e1 >= 0 && e1 < ras.target.rows ) - { - PByte p; - - - p = bits - e1*ras.target.pitch; - if ( ras.target.pitch > 0 ) - p += ( ras.target.rows - 1 ) * ras.target.pitch; - - p[0] |= f1; - } - } - } - } - - - static - void Horizontal_Sweep_Drop( RAS_ARGS Short y, - FT_F26Dot6 x1, - FT_F26Dot6 x2, - PProfile left, - PProfile right ) - { - Long e1, e2; - PByte bits; - Byte f1; - - - /* During the horizontal sweep, we only take care of drop-outs */ - - e1 = CEILING( x1 ); - e2 = FLOOR ( x2 ); - - if ( e1 > e2 ) - { - if ( e1 == e2 + ras.precision ) - { - switch ( ras.dropOutControl ) - { - case 1: - e1 = e2; - break; - - case 4: - e1 = CEILING( ( x1 + x2 + 1 ) / 2 ); - break; - - case 2: - case 5: - - /* Drop-out Control Rule #4 */ - - /* The spec is not very clear regarding rule #4. It */ - /* presents a method that is way too costly to implement */ - /* while the general idea seems to get rid of `stubs'. */ - /* */ - - /* rightmost stub test */ - if ( left->next == right && left->height <= 0 ) - return; - - /* leftmost stub test */ - if ( right->next == left && left->start == y ) - return; - - /* check that the rightmost pixel isn't set */ - - e1 = TRUNC( e1 ); - - bits = ras.bTarget + ( y >> 3 ); - f1 = (Byte)( 0x80 >> ( y & 7 ) ); - - bits -= e1 * ras.target.pitch; - if ( ras.target.pitch > 0 ) - bits += ( ras.target.rows - 1 ) * ras.target.pitch; - - if ( e1 >= 0 && - e1 < ras.target.rows && - *bits & f1 ) - return; - - if ( ras.dropOutControl == 2 ) - e1 = e2; - else - e1 = CEILING( ( x1 + x2 + 1 ) / 2 ); - - break; - - default: - return; /* unsupported mode */ - } - } - else - return; - } - - bits = ras.bTarget + ( y >> 3 ); - f1 = (Byte)( 0x80 >> ( y & 7 ) ); - - e1 = TRUNC( e1 ); - - if ( e1 >= 0 && e1 < ras.target.rows ) - { - bits -= e1 * ras.target.pitch; - if ( ras.target.pitch > 0 ) - bits += ( ras.target.rows - 1 ) * ras.target.pitch; - - bits[0] |= f1; - } - } - - - static - void Horizontal_Sweep_Step( RAS_ARG ) - { - /* Nothing, really */ - FT_UNUSED( raster ); - } - - -#ifdef FT_RASTER_OPTION_ANTI_ALIASING - - - /*************************************************************************/ - /* */ - /* Vertical Gray Sweep Procedure Set */ - /* */ - /* These two routines are used during the vertical gray-levels sweep */ - /* phase by the generic Draw_Sweep() function. */ - /* */ - /* NOTES */ - /* */ - /* - The target pixmap's width *must* be a multiple of 4. */ - /* */ - /* - You have to use the function Vertical_Sweep_Span() for the gray */ - /* span call. */ - /* */ - /*************************************************************************/ - - static - void Vertical_Gray_Sweep_Init( RAS_ARGS Short* min, - Short* max ) - { - Long pitch, byte_len; - - - *min = *min & -2; - *max = ( *max + 3 ) & -2; - - ras.traceOfs = 0; - pitch = ras.target.pitch; - byte_len = -pitch; - ras.traceIncr = (Short)byte_len; - ras.traceG = ( *min / 2 ) * byte_len; - - if ( pitch > 0 ) - { - ras.traceG += ( ras.target.rows - 1 ) * pitch; - byte_len = -byte_len; - } - - ras.gray_min_x = (Short)byte_len; - ras.gray_max_x = -(Short)byte_len; - } - - - static - void Vertical_Gray_Sweep_Step( RAS_ARG ) - { - Int c1, c2; - PByte pix, bit, bit2; - Int* count = ras.count_table; - Byte* grays; - - - ras.traceOfs += ras.gray_width; - - if ( ras.traceOfs > ras.gray_width ) - { - pix = ras.gTarget + ras.traceG + ras.gray_min_x * 4; - grays = ras.grays; - - if ( ras.gray_max_x >= 0 ) - { - Long last_pixel = ras.target.width - 1; - Int last_cell = last_pixel >> 2; - Int last_bit = last_pixel & 3; - Bool over = 0; - - - if ( ras.gray_max_x >= last_cell && last_bit != 3 ) - { - ras.gray_max_x = last_cell - 1; - over = 1; - } - - if ( ras.gray_min_x < 0 ) - ras.gray_min_x = 0; - - bit = ras.bTarget + ras.gray_min_x; - bit2 = bit + ras.gray_width; - - c1 = ras.gray_max_x - ras.gray_min_x; - - while ( c1 >= 0 ) - { - c2 = count[*bit] + count[*bit2]; - - if ( c2 ) - { - pix[0] = grays[(c2 >> 12) & 0x000F]; - pix[1] = grays[(c2 >> 8 ) & 0x000F]; - pix[2] = grays[(c2 >> 4 ) & 0x000F]; - pix[3] = grays[ c2 & 0x000F]; - - *bit = 0; - *bit2 = 0; - } - - bit++; - bit2++; - pix += 4; - c1--; - } - - if ( over ) - { - c2 = count[*bit] + count[*bit2]; - if ( c2 ) - { - switch ( last_bit ) - { - case 2: - pix[2] = grays[(c2 >> 4 ) & 0x000F]; - case 1: - pix[1] = grays[(c2 >> 8 ) & 0x000F]; - default: - pix[0] = grays[(c2 >> 12) & 0x000F]; - } - - *bit = 0; - *bit2 = 0; - } - } - } - - ras.traceOfs = 0; - ras.traceG += ras.traceIncr; - - ras.gray_min_x = 32000; - ras.gray_max_x = -32000; - } - } - - - static - void Horizontal_Gray_Sweep_Span( RAS_ARGS Short y, - FT_F26Dot6 x1, - FT_F26Dot6 x2, - PProfile left, - PProfile right ) - { - /* nothing, really */ - FT_UNUSED( raster ); - FT_UNUSED( y ); - FT_UNUSED( x1 ); - FT_UNUSED( x2 ); - FT_UNUSED( left ); - FT_UNUSED( right ); - } - - - static - void Horizontal_Gray_Sweep_Drop( RAS_ARGS Short y, - FT_F26Dot6 x1, - FT_F26Dot6 x2, - PProfile left, - PProfile right ) - { - Long e1, e2; - PByte pixel; - Byte color; - - - /* During the horizontal sweep, we only take care of drop-outs */ - e1 = CEILING( x1 ); - e2 = FLOOR ( x2 ); - - if ( e1 > e2 ) - { - if ( e1 == e2 + ras.precision ) - { - switch ( ras.dropOutControl ) - { - case 1: - e1 = e2; - break; - - case 4: - e1 = CEILING( ( x1 + x2 + 1 ) / 2 ); - break; - - case 2: - case 5: - - /* Drop-out Control Rule #4 */ - - /* The spec is not very clear regarding rule #4. It */ - /* presents a method that is way too costly to implement */ - /* while the general idea seems to get rid of `stubs'. */ - /* */ - - /* rightmost stub test */ - if ( left->next == right && left->height <= 0 ) - return; - - /* leftmost stub test */ - if ( right->next == left && left->start == y ) - return; - - if ( ras.dropOutControl == 2 ) - e1 = e2; - else - e1 = CEILING( ( x1 + x2 + 1 ) / 2 ); - - break; - - default: - return; /* unsupported mode */ - } - } - else - return; - } - - if ( e1 >= 0 ) - { - if ( x2 - x1 >= ras.precision_half ) - color = ras.grays[2]; - else - color = ras.grays[1]; - - e1 = TRUNC( e1 ) / 2; - if ( e1 < ras.target.rows ) - { - pixel = ras.gTarget - e1 * ras.target.pitch + y / 2; - if ( ras.target.pitch > 0 ) - pixel += ( ras.target.rows - 1 ) * ras.target.pitch; - - if ( pixel[0] == ras.grays[0] ) - pixel[0] = color; - } - } - } - - -#endif /* FT_RASTER_OPTION_ANTI_ALIASING */ - - - /*************************************************************************/ - /* */ - /* Generic Sweep Drawing routine */ - /* */ - /*************************************************************************/ - - static - Bool Draw_Sweep( RAS_ARG ) - { - Short y, y_change, y_height; - - PProfile P, Q, P_Left, P_Right; - - Short min_Y, max_Y, top, bottom, dropouts; - - Long x1, x2, xs, e1, e2; - - TProfileList wait; - TProfileList draw_left, draw_right; - - - /* Init empty linked lists */ - - Init_Linked( &wait ); - - Init_Linked( &draw_left ); - Init_Linked( &draw_right ); - - /* first, compute min and max Y */ - - P = ras.fProfile; - max_Y = (Short)TRUNC( ras.minY ); - min_Y = (Short)TRUNC( ras.maxY ); - - while ( P ) - { - Q = P->link; - - bottom = (Short)P->start; - top = (Short)P->start + P->height - 1; - - if ( min_Y > bottom ) min_Y = bottom; - if ( max_Y < top ) max_Y = top; - - P->X = 0; - InsNew( &wait, P ); - - P = Q; - } - - /* Check the Y-turns */ - if ( ras.numTurns == 0 ) - { - ras.error = Raster_Err_Invalid; - return FAILURE; - } - - /* Now inits the sweep */ - - ras.Proc_Sweep_Init( RAS_VARS &min_Y, &max_Y ); - - /* Then compute the distance of each profile from min_Y */ - - P = wait; - - while ( P ) - { - P->countL = P->start - min_Y; - P = P->link; - } - - /* Let's go */ - - y = min_Y; - y_height = 0; - - if ( ras.numTurns > 0 && - ras.sizeBuff[-ras.numTurns] == min_Y ) - ras.numTurns--; - - while ( ras.numTurns > 0 ) - { - /* look in the wait list for new activations */ - - P = wait; - - while ( P ) - { - Q = P->link; - P->countL -= y_height; - if ( P->countL == 0 ) - { - DelOld( &wait, P ); - - switch ( P->flow ) - { - case Flow_Up: - InsNew( &draw_left, P ); - break; - - case Flow_Down: - InsNew( &draw_right, P ); - break; - } - } - - P = Q; - } - - /* Sort the drawing lists */ - - Sort( &draw_left ); - Sort( &draw_right ); - - y_change = (Short)ras.sizeBuff[-ras.numTurns--]; - y_height = y_change - y; - - while ( y < y_change ) - { - /* Let's trace */ - - dropouts = 0; - - P_Left = draw_left; - P_Right = draw_right; - - while ( P_Left ) - { - x1 = P_Left ->X; - x2 = P_Right->X; - - if ( x1 > x2 ) - { - xs = x1; - x1 = x2; - x2 = xs; - } - - if ( x2 - x1 <= ras.precision ) - { - e1 = FLOOR( x1 ); - e2 = CEILING( x2 ); - - if ( ras.dropOutControl != 0 && - ( e1 > e2 || e2 == e1 + ras.precision ) ) - { - /* a drop out was detected */ - - P_Left ->X = x1; - P_Right->X = x2; - - /* mark profile for drop-out processing */ - P_Left->countL = 1; - dropouts++; - - goto Skip_To_Next; - } - } - - ras.Proc_Sweep_Span( RAS_VARS y, x1, x2, P_Left, P_Right ); - - Skip_To_Next: - - P_Left = P_Left->link; - P_Right = P_Right->link; - } - - /* now perform the dropouts _after_ the span drawing -- */ - /* drop-outs processing has been moved out of the loop */ - /* for performance tuning */ - if ( dropouts > 0 ) - goto Scan_DropOuts; - - Next_Line: - - ras.Proc_Sweep_Step( RAS_VAR ); - - y++; - - if ( y < y_change ) - { - Sort( &draw_left ); - Sort( &draw_right ); - } - } - - /* Now finalize the profiles that needs it */ - - { - PProfile Q, P; - - - P = draw_left; - while ( P ) - { - Q = P->link; - if ( P->height == 0 ) - DelOld( &draw_left, P ); - P = Q; - } - } - - { - PProfile Q, P = draw_right; - - - while ( P ) - { - Q = P->link; - if ( P->height == 0 ) - DelOld( &draw_right, P ); - P = Q; - } - } - } - - /* for gray-scaling, flushes the bitmap scanline cache */ - while ( y <= max_Y ) - { - ras.Proc_Sweep_Step( RAS_VAR ); - y++; - } - - return SUCCESS; - - Scan_DropOuts: - - P_Left = draw_left; - P_Right = draw_right; - - while ( P_Left ) - { - if ( P_Left->countL ) - { - P_Left->countL = 0; -#if 0 - dropouts--; /* -- this is useful when debugging only */ -#endif - ras.Proc_Sweep_Drop( RAS_VARS y, - P_Left->X, - P_Right->X, - P_Left, - P_Right ); - } - - P_Left = P_Left->link; - P_Right = P_Right->link; - } - - goto Next_Line; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Render_Single_Pass */ - /* */ - /* */ - /* Performs one sweep with sub-banding. */ - /* */ - /* */ - /* flipped :: If set, flip the direction of the outline. */ - /* */ - /* */ - /* Renderer error code. */ - /* */ - static - int Render_Single_Pass( RAS_ARGS Bool flipped ) - { - Short i, j, k; - - - while ( ras.band_top >= 0 ) - { - ras.maxY = (Long)ras.band_stack[ras.band_top].y_max * ras.precision; - ras.minY = (Long)ras.band_stack[ras.band_top].y_min * ras.precision; - - ras.top = ras.buff; - - ras.error = Raster_Err_None; - - if ( Convert_Glyph( RAS_VARS flipped ) ) - { - if ( ras.error != Raster_Err_Overflow ) - return FAILURE; - - ras.error = Raster_Err_None; - - /* sub-banding */ - -#ifdef DEBUG_RASTER - ClearBand( RAS_VARS TRUNC( ras.minY ), TRUNC( ras.maxY ) ); -#endif - - i = ras.band_stack[ras.band_top].y_min; - j = ras.band_stack[ras.band_top].y_max; - - k = ( i + j ) / 2; - - if ( ras.band_top >= 7 || k < i ) - { - ras.band_top = 0; - ras.error = Raster_Err_Invalid; - - return ras.error; - } - - ras.band_stack[ras.band_top + 1].y_min = k; - ras.band_stack[ras.band_top + 1].y_max = j; - - ras.band_stack[ras.band_top].y_max = k - 1; - - ras.band_top++; - } - else - { - if ( ras.fProfile ) - if ( Draw_Sweep( RAS_VAR ) ) - return ras.error; - ras.band_top--; - } - } - - return SUCCESS; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Render_Glyph */ - /* */ - /* */ - /* Renders a glyph in a bitmap. Sub-banding if needed. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* XXX Fixme: ftraster's error codes don't harmonize with FT2's ones! */ - /* */ - LOCAL_FUNC - FT_Error Render_Glyph( RAS_ARG ) - { - FT_Error error; - - - Set_High_Precision( RAS_VARS ras.outline.flags & - ft_outline_high_precision ); - ras.scale_shift = ras.precision_shift; - ras.dropOutControl = 2; - ras.second_pass = !( ras.outline.flags & ft_outline_single_pass ); - - /* Vertical Sweep */ - ras.Proc_Sweep_Init = Vertical_Sweep_Init; - ras.Proc_Sweep_Span = Vertical_Sweep_Span; - ras.Proc_Sweep_Drop = Vertical_Sweep_Drop; - ras.Proc_Sweep_Step = Vertical_Sweep_Step; - - ras.band_top = 0; - ras.band_stack[0].y_min = 0; - ras.band_stack[0].y_max = ras.target.rows - 1; - - ras.bWidth = ras.target.width; - ras.bTarget = (Byte*)ras.target.buffer; - - if ( ( error = Render_Single_Pass( RAS_VARS 0 ) ) != 0 ) - return error; - - /* Horizontal Sweep */ - if ( ras.second_pass && ras.dropOutControl != 0 ) - { - ras.Proc_Sweep_Init = Horizontal_Sweep_Init; - ras.Proc_Sweep_Span = Horizontal_Sweep_Span; - ras.Proc_Sweep_Drop = Horizontal_Sweep_Drop; - ras.Proc_Sweep_Step = Horizontal_Sweep_Step; - - ras.band_top = 0; - ras.band_stack[0].y_min = 0; - ras.band_stack[0].y_max = ras.target.width - 1; - - if ( ( error = Render_Single_Pass( RAS_VARS 1 ) ) != 0 ) - return error; - } - - return FT_Err_Ok; - } - - -#ifdef FT_RASTER_OPTION_ANTI_ALIASING - - - /*************************************************************************/ - /* */ - /* */ - /* Render_Gray_Glyph */ - /* */ - /* */ - /* Renders a glyph with grayscaling. Sub-banding if needed. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error Render_Gray_Glyph( RAS_ARG ) - { - Long pixel_width; - FT_Error error; - - - Set_High_Precision( RAS_VARS ras.outline.flags & - ft_outline_high_precision ); - ras.scale_shift = ras.precision_shift + 1; - ras.dropOutControl = 2; - ras.second_pass = !( ras.outline.flags & ft_outline_single_pass ); - - /* Vertical Sweep */ - - ras.band_top = 0; - ras.band_stack[0].y_min = 0; - ras.band_stack[0].y_max = 2 * ras.target.rows - 1; - - ras.bWidth = ras.gray_width; - pixel_width = 2 * ( ( ras.target.width + 3 ) >> 2 ); - - if ( ras.bWidth > pixel_width ) - ras.bWidth = pixel_width; - - ras.bWidth = ras.bWidth * 8; - ras.bTarget = (Byte*)ras.gray_lines; - ras.gTarget = (Byte*)ras.target.buffer; - - ras.Proc_Sweep_Init = Vertical_Gray_Sweep_Init; - ras.Proc_Sweep_Span = Vertical_Sweep_Span; - ras.Proc_Sweep_Drop = Vertical_Sweep_Drop; - ras.Proc_Sweep_Step = Vertical_Gray_Sweep_Step; - - error = Render_Single_Pass( RAS_VARS 0 ); - if ( error ) - return error; - - /* Horizontal Sweep */ - if ( ras.second_pass && ras.dropOutControl != 0 ) - { - ras.Proc_Sweep_Init = Horizontal_Sweep_Init; - ras.Proc_Sweep_Span = Horizontal_Gray_Sweep_Span; - ras.Proc_Sweep_Drop = Horizontal_Gray_Sweep_Drop; - ras.Proc_Sweep_Step = Horizontal_Sweep_Step; - - ras.band_top = 0; - ras.band_stack[0].y_min = 0; - ras.band_stack[0].y_max = ras.target.width * 2 - 1; - - error = Render_Single_Pass( RAS_VARS 1 ); - if ( error ) - return error; - } - - return FT_Err_Ok; - } - -#else /* FT_RASTER_OPTION_ANTI_ALIASING */ - - LOCAL_FUNC - FT_Error Render_Gray_Glyph( RAS_ARG ) - { - FT_UNUSED_RASTER; - - return FT_Err_Cannot_Render_Glyph; - } - -#endif /* FT_RASTER_OPTION_ANTI_ALIASING */ - - - static - void ft_black_init( TRaster_Instance* raster ) - { - FT_UInt n; - FT_ULong c; - - - /* setup count table */ - for ( n = 0; n < 256; n++ ) - { - c = ( n & 0x55 ) + ( ( n & 0xAA ) >> 1 ); - - c = ( ( c << 6 ) & 0x3000 ) | - ( ( c << 4 ) & 0x0300 ) | - ( ( c << 2 ) & 0x0030 ) | - (c & 0x0003 ); - - raster->count_table[n] = c; - } - -#ifdef FT_RASTER_OPTION_ANTI_ALIASING - - /* set default 5-levels gray palette */ - for ( n = 0; n < 5; n++ ) - raster->grays[n] = n * 255 / 4; - - raster->gray_width = RASTER_GRAY_LINES / 2; - -#endif - } - - - /**** RASTER OBJECT CREATION: In standalone mode, we simply use *****/ - /**** a static object. *****/ - - -#ifdef _STANDALONE_ - - - static - int ft_black_new( void* memory, - FT_Raster *araster ) - { - static FT_RasterRec_ the_raster; - - - *araster = &the_raster; - memset( &the_raster, sizeof ( the_raster ), 0 ); - ft_black_init( &the_raster ); - - return 0; - } - - - static - void ft_black_done( FT_Raster raster ) - { - /* nothing */ - raster->init = 0; - } - - -#else /* _STANDALONE_ */ - - - static - int ft_black_new( FT_Memory memory, - TRaster_Instance** araster ) - { - FT_Error error; - TRaster_Instance* raster; - - - *araster = 0; - if ( !ALLOC( raster, sizeof ( *raster ) ) ) - { - raster->memory = memory; - ft_black_init( raster ); - - *araster = raster; - } - - return error; - } - - - static - void ft_black_done( TRaster_Instance* raster ) - { - FT_Memory memory = (FT_Memory)raster->memory; - FREE( raster ); - } - - -#endif /* _STANDALONE_ */ - - - static - void ft_black_reset( TRaster_Instance* raster, - const char* pool_base, - long pool_size ) - { - if ( raster && pool_base && pool_size >= 4096 ) - { - /* save the pool */ - raster->buff = (PLong)pool_base; - raster->sizeBuff = raster->buff + pool_size / sizeof ( Long ); - } - } - - - static - void ft_black_set_mode( TRaster_Instance* raster, - unsigned long mode, - const char* palette ) - { -#ifdef FT_RASTER_OPTION_ANTI_ALIASING - - if ( mode == FT_MAKE_TAG( 'p', 'a', 'l', '5' ) ) - { - /* set 5-levels gray palette */ - raster->grays[0] = palette[0]; - raster->grays[1] = palette[1]; - raster->grays[2] = palette[2]; - raster->grays[3] = palette[3]; - raster->grays[4] = palette[4]; - } - -#else - - FT_UNUSED( raster ); - FT_UNUSED( mode ); - FT_UNUSED( palette ); - -#endif - } - - - static - int ft_black_render( TRaster_Instance* raster, - FT_Raster_Params* params ) - { - FT_Outline* outline = (FT_Outline*)params->source; - FT_Bitmap* target_map = params->target; - - - if ( !raster || !raster->buff || !raster->sizeBuff ) - return Raster_Err_Not_Ini; - - if ( !outline || !outline->contours || !outline->points ) - return Raster_Err_Invalid; - - /* return immediately if the outline is empty */ - if ( outline->n_points == 0 || outline->n_contours <= 0 ) - return Raster_Err_None; - - if ( outline->n_points != outline->contours[outline->n_contours - 1] + 1 ) - return Raster_Err_Invalid; - - if ( !target_map || !target_map->buffer ) - return Raster_Err_Invalid; - - /* this version of the raster does not support direct rendering, sorry */ - if ( params->flags & ft_raster_flag_direct ) - return Raster_Err_Unsupported; - - ras.outline = *outline; - ras.target = *target_map; - - return ( ( params->flags & ft_raster_flag_aa ) - ? Render_Gray_Glyph( raster ) - : Render_Glyph( raster ) ); - } - - - FT_Raster_Funcs ft_standard_raster = - { - ft_glyph_format_outline, - (FT_Raster_New_Func) ft_black_new, - (FT_Raster_Reset_Func) ft_black_reset, - (FT_Raster_Set_Mode_Func)ft_black_set_mode, - (FT_Raster_Render_Func) ft_black_render, - (FT_Raster_Done_Func) ft_black_done - }; - - -/* END */ diff --git a/src/freetype/raster1/ftraster.h b/src/freetype/raster1/ftraster.h deleted file mode 100644 index 5c7faae5a2..0000000000 --- a/src/freetype/raster1/ftraster.h +++ /dev/null @@ -1,50 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftraster.h */ -/* */ -/* The FreeType glyph rasterizer (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifndef FTRASTER_H -#define FTRASTER_H - -#ifdef __cplusplus - extern "C" { -#endif - -#include - - - /*************************************************************************/ - /* */ - /* Uncomment the following line if you are using ftraster.c as a */ - /* standalone module, fully independent of FreeType. */ - /* */ -/* #define _STANDALONE_ */ - -#ifndef FT_EXPORT_VAR -#define FT_EXPORT_VAR( x ) extern x -#endif - - FT_EXPORT_VAR( FT_Raster_Funcs ) ft_standard_raster; - -#ifdef __cplusplus - } -#endif - - -#endif /* FTRASTER_H */ - - -/* END */ diff --git a/src/freetype/raster1/ftrend1.c b/src/freetype/raster1/ftrend1.c deleted file mode 100644 index d774cf1d40..0000000000 --- a/src/freetype/raster1/ftrend1.c +++ /dev/null @@ -1,275 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftrend1.c */ -/* */ -/* The FreeType glyph rasterizer interface (body). */ -/* */ -/* 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 -#include - - -#ifdef FT_FLAT_COMPILE - -#include "ftrend1.h" -#include "ftraster.h" - -#else - -#include -#include - -#endif - - - /* initialize renderer -- init its raster */ - static - FT_Error ft_raster1_init( FT_Renderer render ) - { - FT_Library library = FT_MODULE_LIBRARY( render ); - - - render->clazz->raster_class->raster_reset( render->raster, - library->raster_pool, - library->raster_pool_size ); - - return FT_Err_Ok; - } - - - /* set render-specific mode */ - static - FT_Error ft_raster1_set_mode( FT_Renderer render, - FT_ULong mode_tag, - FT_Pointer data ) - { - /* we simply pass it to the raster */ - return render->clazz->raster_class->raster_set_mode( render->raster, - mode_tag, - data ); - } - - - /* transform a given glyph image */ - static - FT_Error ft_raster1_transform( FT_Renderer render, - FT_GlyphSlot slot, - FT_Matrix* matrix, - FT_Vector* delta ) - { - FT_Error error = FT_Err_Ok; - - - if ( slot->format != render->glyph_format ) - { - error = FT_Err_Invalid_Argument; - goto Exit; - } - - if ( matrix ) - FT_Outline_Transform( &slot->outline, matrix ); - - if ( delta ) - FT_Outline_Translate( &slot->outline, delta->x, delta->y ); - - Exit: - return error; - } - - - /* return the glyph's control box */ - static - void ft_raster1_get_cbox( FT_Renderer render, - FT_GlyphSlot slot, - FT_BBox* cbox ) - { - MEM_Set( cbox, 0, sizeof ( *cbox ) ); - - if ( slot->format == render->glyph_format ) - FT_Outline_Get_CBox( &slot->outline, cbox ); - } - - - /* convert a slot's glyph image into a bitmap */ - static - FT_Error ft_raster1_render( FT_Renderer render, - FT_GlyphSlot slot, - FT_UInt mode, - FT_Vector* origin ) - { - FT_Error error; - FT_Outline* outline; - FT_BBox cbox; - FT_UInt width, height, pitch; - FT_Bitmap* bitmap; - FT_Memory memory; - - FT_Raster_Params params; - - - /* check glyph image format */ - if ( slot->format != render->glyph_format ) - { - error = FT_Err_Invalid_Argument; - goto Exit; - } - - /* check rendering mode */ - if ( mode != ft_render_mode_mono ) - { - /* raster1 is only capable of producing monochrome bitmaps */ - if ( render->clazz == &ft_raster1_renderer_class ) - return FT_Err_Cannot_Render_Glyph; - } - else - { - /* raster5 is only capable of producing 5-gray-levels bitmaps */ - if ( render->clazz == &ft_raster5_renderer_class ) - return FT_Err_Cannot_Render_Glyph; - } - - outline = &slot->outline; - - /* translate the outline to the new origin if needed */ - if ( origin ) - FT_Outline_Translate( outline, origin->x, origin->y ); - - /* compute the control box, and grid fit it */ - FT_Outline_Get_CBox( outline, &cbox ); - - cbox.xMin &= -64; - cbox.yMin &= -64; - cbox.xMax = ( cbox.xMax + 63 ) & -64; - cbox.yMax = ( cbox.yMax + 63 ) & -64; - - width = ( cbox.xMax - cbox.xMin ) >> 6; - height = ( cbox.yMax - cbox.yMin ) >> 6; - bitmap = &slot->bitmap; - memory = render->root.memory; - - /* release old bitmap buffer */ - if ( slot->flags & ft_glyph_own_bitmap ) - { - FREE( bitmap->buffer ); - slot->flags &= ~ft_glyph_own_bitmap; - } - - /* allocate new one, depends on pixel format */ - if ( !( mode & ft_render_mode_mono ) ) - { - /* we pad to 32 bits, only for backwards compatibility with FT 1.x */ - pitch = ( width + 3 ) & -4; - bitmap->pixel_mode = ft_pixel_mode_grays; - bitmap->num_grays = 256; - } - else - { - pitch = ( width + 7 ) >> 3; - bitmap->pixel_mode = ft_pixel_mode_mono; - } - - bitmap->width = width; - bitmap->rows = height; - bitmap->pitch = pitch; - - if ( ALLOC( bitmap->buffer, (FT_ULong)pitch * height ) ) - goto Exit; - - slot->flags |= ft_glyph_own_bitmap; - - /* translate outline to render it into the bitmap */ - FT_Outline_Translate( outline, -cbox.xMin, -cbox.yMin ); - - /* set up parameters */ - params.target = bitmap; - params.source = outline; - params.flags = 0; - - if ( bitmap->pixel_mode == ft_pixel_mode_grays ) - params.flags |= ft_raster_flag_aa; - - /* render outline into the bitmap */ - error = render->raster_render( render->raster, ¶ms ); - if ( error ) - goto Exit; - - slot->format = ft_glyph_format_bitmap; - slot->bitmap_left = cbox.xMin >> 6; - slot->bitmap_top = cbox.yMax >> 6; - - Exit: - return error; - } - - - const FT_Renderer_Class ft_raster1_renderer_class = - { - { - ft_module_renderer, - sizeof( FT_RendererRec ), - - "raster1", - 0x10000L, - 0x20000L, - - 0, /* module specific interface */ - - (FT_Module_Constructor)ft_raster1_init, - (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 - }, - - ft_glyph_format_outline, - - (FTRenderer_render) ft_raster1_render, - (FTRenderer_transform)ft_raster1_transform, - (FTRenderer_getCBox) ft_raster1_get_cbox, - (FTRenderer_setMode) ft_raster1_set_mode, - - (FT_Raster_Funcs*) &ft_standard_raster - }; - - - /* this renderer is _NOT_ part of the default modules, you'll need */ - /* to register it by hand in your application. It should only be */ - /* used for backwards-compatibility with FT 1.x anyway. */ - const FT_Renderer_Class ft_raster5_renderer_class = - { - { - ft_module_renderer, - sizeof( FT_RendererRec ), - - "raster5", - 0x10000L, - 0x20000L, - - 0, /* module specific interface */ - - (FT_Module_Constructor)ft_raster1_init, - (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 - }, - - ft_glyph_format_outline, - - (FTRenderer_render) ft_raster1_render, - (FTRenderer_transform)ft_raster1_transform, - (FTRenderer_getCBox) ft_raster1_get_cbox, - (FTRenderer_setMode) ft_raster1_set_mode, - - (FT_Raster_Funcs*) &ft_standard_raster - }; - - -/* END */ diff --git a/src/freetype/raster1/ftrend1.h b/src/freetype/raster1/ftrend1.h deleted file mode 100644 index b8fff83114..0000000000 --- a/src/freetype/raster1/ftrend1.h +++ /dev/null @@ -1,37 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftrend1.h */ -/* */ -/* The FreeType glyph rasterizer interface (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifndef FTREND1_H -#define FTREND1_H - -#include - - - FT_EXPORT_VAR( const FT_Renderer_Class ) ft_raster1_renderer_class; - - /* this renderer is _NOT_ part of the default modules, you'll need */ - /* to register it by hand in your application. It should only be */ - /* used for backwards-compatibility with FT 1.x anyway. */ - /* */ - FT_EXPORT_VAR( const FT_Renderer_Class ) ft_raster5_renderer_class; - - -#endif /* FTREND1_H */ - - -/* END */ diff --git a/src/freetype/raster1/module.mk b/src/freetype/raster1/module.mk deleted file mode 100644 index c1ceb21293..0000000000 --- a/src/freetype/raster1/module.mk +++ /dev/null @@ -1,7 +0,0 @@ -make_module_list: add_raster1_module - -add_raster1_module: - $(OPEN_DRIVER)ft_raster1_renderer_class$(CLOSE_DRIVER) - $(ECHO_DRIVER)raster1 $(ECHO_DRIVER_DESC)monochrome bitmap renderer$(ECHO_DRIVER_DONE) - -# EOF diff --git a/src/freetype/raster1/raster1.c b/src/freetype/raster1/raster1.c deleted file mode 100644 index cf2835abc5..0000000000 --- a/src/freetype/raster1/raster1.c +++ /dev/null @@ -1,35 +0,0 @@ -/***************************************************************************/ -/* */ -/* raster1.c */ -/* */ -/* FreeType monochrome rasterer module component (body only). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#define FT_MAKE_OPTION_SINGLE_OBJECT - - -#ifdef FT_FLAT_COMPILE - -#include "ftraster.c" -#include "ftrend1.c" - -#else - -#include -#include - -#endif - - -/* END */ diff --git a/src/freetype/raster1/rules.mk b/src/freetype/raster1/rules.mk deleted file mode 100644 index 38108450ef..0000000000 --- a/src/freetype/raster1/rules.mk +++ /dev/null @@ -1,69 +0,0 @@ -# -# FreeType 2 renderer module build rules -# - - -# 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. - - -# raster1 driver directory -# -RAS1_DIR := $(SRC_)raster1 -RAS1_DIR_ := $(RAS1_DIR)$(SEP) - -# compilation flags for the driver -# -RAS1_COMPILE := $(FT_COMPILE) - - -# raster1 driver sources (i.e., C files) -# -RAS1_DRV_SRC := $(RAS1_DIR_)ftraster.c \ - $(RAS1_DIR_)ftrend1.c - - -# raster1 driver headers -# -RAS1_DRV_H := $(RAS1_DRV_SRC:%.c=%.h) - - -# raster1 driver object(s) -# -# RAS1_DRV_OBJ_M is used during `multi' builds. -# RAS1_DRV_OBJ_S is used during `single' builds. -# -RAS1_DRV_OBJ_M := $(RAS1_DRV_SRC:$(RAS1_DIR_)%.c=$(OBJ_)%.$O) -RAS1_DRV_OBJ_S := $(OBJ_)raster1.$O - -# raster1 driver source file for single build -# -RAS1_DRV_SRC_S := $(RAS1_DIR_)raster1.c - - -# raster1 driver - single object -# -$(RAS1_DRV_OBJ_S): $(RAS1_DRV_SRC_S) $(RAS1_DRV_SRC) \ - $(FREETYPE_H) $(RAS1_DRV_H) - $(RAS1_COMPILE) $T$@ $(RAS1_DRV_SRC_S) - - -# raster1 driver - multiple objects -# -$(OBJ_)%.$O: $(RAS1_DIR_)%.c $(FREETYPE_H) $(RAS1_DRV_H) - $(RAS1_COMPILE) $T$@ $< - - -# update main driver object lists -# -DRV_OBJS_S += $(RAS1_DRV_OBJ_S) -DRV_OBJS_M += $(RAS1_DRV_OBJ_M) - - -# EOF diff --git a/src/freetype/sfnt/module.mk b/src/freetype/sfnt/module.mk deleted file mode 100644 index 48b494f4d2..0000000000 --- a/src/freetype/sfnt/module.mk +++ /dev/null @@ -1,7 +0,0 @@ -make_module_list: add_sfnt_module - -add_sfnt_module: - $(OPEN_DRIVER)sfnt_module_class$(CLOSE_DRIVER) - $(ECHO_DRIVER)sfnt $(ECHO_DRIVER_DESC)helper module for TrueType & OpenType formats$(ECHO_DRIVER_DONE) - -# EOF diff --git a/src/freetype/sfnt/rules.mk b/src/freetype/sfnt/rules.mk deleted file mode 100644 index 2255e6a087..0000000000 --- a/src/freetype/sfnt/rules.mk +++ /dev/null @@ -1,73 +0,0 @@ -# -# FreeType 2 SFNT driver configuration rules -# - - -# 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. - - -# SFNT driver directory -# -SFNT_DIR := $(SRC_)sfnt -SFNT_DIR_ := $(SFNT_DIR)$(SEP) - - -# compilation flags for the driver -# -SFNT_COMPILE := $(FT_COMPILE) - - -# SFNT driver sources (i.e., C files) -# -SFNT_DRV_SRC := $(SFNT_DIR_)ttload.c \ - $(SFNT_DIR_)ttcmap.c \ - $(SFNT_DIR_)ttsbit.c \ - $(SFNT_DIR_)ttpost.c \ - $(SFNT_DIR_)sfobjs.c \ - $(SFNT_DIR_)sfdriver.c - -# SFNT driver headers -# -SFNT_DRV_H := $(SFNT_DRV_SRC:%c=%h) - - -# SFNT driver object(s) -# -# SFNT_DRV_OBJ_M is used during `multi' builds. -# SFNT_DRV_OBJ_S is used during `single' builds. -# -SFNT_DRV_OBJ_M := $(SFNT_DRV_SRC:$(SFNT_DIR_)%.c=$(OBJ_)%.$O) -SFNT_DRV_OBJ_S := $(OBJ_)sfnt.$O - -# SFNT driver source file for single build -# -SFNT_DRV_SRC_S := $(SFNT_DIR_)sfnt.c - - -# SFNT driver - single object -# -$(SFNT_DRV_OBJ_S): $(SFNT_DRV_SRC_S) $(SFNT_DRV_SRC) \ - $(FREETYPE_H) $(SFNT_DRV_H) - $(SFNT_COMPILE) $T$@ $(SFNT_DRV_SRC_S) - - -# SFNT driver - multiple objects -# -$(OBJ_)%.$O: $(SFNT_DIR_)%.c $(FREETYPE_H) $(SFNT_DRV_H) - $(SFNT_COMPILE) $T$@ $< - - -# update main driver object lists -# -DRV_OBJS_S += $(SFNT_DRV_OBJ_S) -DRV_OBJS_M += $(SFNT_DRV_OBJ_M) - - -# EOF diff --git a/src/freetype/sfnt/sfdriver.c b/src/freetype/sfnt/sfdriver.c deleted file mode 100644 index 96a738b43c..0000000000 --- a/src/freetype/sfnt/sfdriver.c +++ /dev/null @@ -1,225 +0,0 @@ -/***************************************************************************/ -/* */ -/* sfdriver.c */ -/* */ -/* High-level SFNT driver interface (body). */ -/* */ -/* 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 -#include - - -#ifdef FT_FLAT_COMPILE - -#include "sfdriver.h" -#include "ttload.h" -#include "ttsbit.h" -#include "ttpost.h" -#include "ttcmap.h" -#include "sfobjs.h" - -#else - -#include -#include -#include -#include -#include -#include - -#endif - - -#include /* for strcmp() */ - - - static - void* get_sfnt_table( TT_Face face, - FT_Sfnt_Tag tag ) - { - void* table; - - - switch ( tag ) - { - case ft_sfnt_head: - table = &face->header; - break; - - case ft_sfnt_hhea: - table = &face->horizontal; - break; - - case ft_sfnt_vhea: - table = face->vertical_info ? &face->vertical : 0; - break; - - case ft_sfnt_os2: - table = face->os2.version == 0xFFFF ? 0 : &face->os2; - break; - - case ft_sfnt_post: - table = &face->postscript; - break; - - case ft_sfnt_maxp: - table = &face->max_profile; - break; - - case ft_sfnt_pclt: - table = face->pclt.Version ? &face->pclt : 0; - break; - - default: - table = 0; - } - - return table; - } - - -#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES - - - static - FT_Error get_sfnt_glyph_name( TT_Face face, - FT_UInt glyph_index, - FT_Pointer buffer, - FT_UInt buffer_max ) - { - FT_String* gname; - FT_Error error; - - - error = TT_Get_PS_Name( face, glyph_index, &gname ); - if ( !error && buffer_max > 0 ) - { - FT_UInt len = strlen( gname ); - - - if ( len >= buffer_max ) - len = buffer_max - 1; - - MEM_Copy( buffer, gname, len ); - ((FT_Byte*)buffer)[len] = 0; - } - - return error; - } - - -#endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */ - - - static - FT_Module_Interface SFNT_Get_Interface( FT_Module module, - const char* interface ) - { - FT_UNUSED( module ); - - if ( strcmp( interface, "get_sfnt" ) == 0 ) - return (FT_Module_Interface)get_sfnt_table; - -#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES - if ( strcmp( interface, "glyph_name" ) == 0 ) - return (FT_Module_Interface)get_sfnt_glyph_name; -#endif - return 0; - } - - - static - const SFNT_Interface sfnt_interface = - { - TT_Goto_Table, - - SFNT_Init_Face, - SFNT_Load_Face, - SFNT_Done_Face, - SFNT_Get_Interface, - - TT_Load_Any, - TT_Load_SFNT_Header, - TT_Load_Directory, - - TT_Load_Header, - TT_Load_Metrics_Header, - TT_Load_CMap, - TT_Load_MaxProfile, - TT_Load_OS2, - TT_Load_PostScript, - - TT_Load_Names, - TT_Free_Names, - - TT_Load_Hdmx, - TT_Free_Hdmx, - - TT_Load_Kern, - TT_Load_Gasp, - TT_Load_PCLT, - -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - - /* see `ttsbit.h' */ - TT_Load_SBit_Strikes, - TT_Load_SBit_Image, - TT_Free_SBit_Strikes, - -#else /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ - - 0, - 0, - 0, - -#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ - -#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES - - /* see `ttpost.h' */ - TT_Get_PS_Name, - TT_Free_Post_Names, - -#else /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */ - - 0, - 0, - -#endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */ - - /* see `ttcmap.h' */ - TT_CharMap_Load, - TT_CharMap_Free, - }; - - - const - FT_Module_Class sfnt_module_class = - { - 0, /* not a font driver or renderer */ - sizeof( FT_ModuleRec ), - - "sfnt", /* driver name */ - 0x10000L, /* driver version 1.0 */ - 0x20000L, /* driver requires FreeType 2.0 or higher */ - - (const void*)&sfnt_interface, /* module specific interface */ - - (FT_Module_Constructor)0, - (FT_Module_Destructor) 0, - (FT_Module_Requester) SFNT_Get_Interface - }; - - -/* END */ diff --git a/src/freetype/sfnt/sfdriver.h b/src/freetype/sfnt/sfdriver.h deleted file mode 100644 index 92c9c8129d..0000000000 --- a/src/freetype/sfnt/sfdriver.h +++ /dev/null @@ -1,29 +0,0 @@ -/***************************************************************************/ -/* */ -/* sfdriver.h */ -/* */ -/* High-level SFNT driver interface (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifndef SFDRIVER_H -#define SFDRIVER_H - -#include - - FT_EXPORT_VAR( const FT_Module_Class ) sfnt_module_class; - -#endif /* SFDRIVER_H */ - - -/* END */ diff --git a/src/freetype/sfnt/sfnt.c b/src/freetype/sfnt/sfnt.c deleted file mode 100644 index cca73425ce..0000000000 --- a/src/freetype/sfnt/sfnt.c +++ /dev/null @@ -1,57 +0,0 @@ -/***************************************************************************/ -/* */ -/* sfnt.c */ -/* */ -/* Single object library component. */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#define FT_MAKE_OPTION_SINGLE_OBJECT - - -#ifdef FT_FLAT_COMPILE - -#include "ttload.c" -#include "ttcmap.c" -#include "sfobjs.c" - -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS -#include "ttsbit.c" -#endif - -#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES -#include "ttpost.c" -#endif - -#include "sfdriver.c" - -#else /* FT_FLAT_COMPILE */ - -#include -#include -#include - -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS -#include -#endif - -#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES -#include -#endif - -#include - -#endif /* FT_FLAT_COMPILE */ - - -/* END */ diff --git a/src/freetype/sfnt/sfobjs.c b/src/freetype/sfnt/sfobjs.c deleted file mode 100644 index 4ae85022e8..0000000000 --- a/src/freetype/sfnt/sfobjs.c +++ /dev/null @@ -1,561 +0,0 @@ -/***************************************************************************/ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifdef FT_FLAT_COMPILE - -#include "sfobjs.h" - -#else - -#include - -#endif - - -#include -#include -#include -#include - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_sfobjs - - - /*************************************************************************/ - /* */ - /* */ - /* Get_Name */ - /* */ - /* */ - /* Returns a given ENGLISH name record in ASCII. */ - /* */ - /* */ - /* face :: A handle to the source face object. */ - /* */ - /* nameid :: The name id of the name record to return. */ - /* */ - /* */ - /* Character 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; - - - 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 ) - { - FT_UInt m; - - - len = (FT_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_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 } - }; - - 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, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ) - { - FT_Error error; - FT_Library library = face->root.driver->root.library; - SFNT_Interface* sfnt; - SFNT_Header sfnt_header; - - /* for now, parameters are unused */ - FT_UNUSED( num_params ); - FT_UNUSED( params ); - - sfnt = (SFNT_Interface*)face->sfnt; - if ( !sfnt ) - { - sfnt = (SFNT_Interface*)FT_Get_Module_Interface( library, "sfnt" ); - if ( !sfnt ) - { - error = FT_Err_Invalid_File_Format; - goto Exit; - } - - face->sfnt = sfnt; - face->goto_table = sfnt->goto_table; - } - - if ( !face->psnames ) - { - face->psnames = (PSNames_Interface*) - FT_Get_Module_Interface( library, "psnames" ); - } - - /* check that we have a valid TrueType file */ - error = sfnt->load_sfnt_header( face, stream, face_index, &sfnt_header ); - if ( error ) - goto Exit; - - face->format_tag = sfnt_header.format_tag; - face->num_tables = sfnt_header.num_tables; - - /* Load font directory */ - error = sfnt->load_directory( face, stream, &sfnt_header ); - if ( error ) - goto Exit; - - face->root.num_faces = face->ttc_header.count; - 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 ) ) \ - != TT_Err_Ok ) - - - LOCAL_FUNC - FT_Error SFNT_Load_Face( FT_Stream stream, - TT_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ) - { - FT_Error error; - SFNT_Interface* sfnt = (SFNT_Interface*)face->sfnt; - - FT_UNUSED( face_index ); - FT_UNUSED( num_params ); - FT_UNUSED( params ); - - - /* Load tables */ - if ( LOAD_( header ) || - LOAD_( max_profile ) || - - /* load the `hhea' & `hmtx' tables at once */ - ( error = sfnt->load_metrics( face, stream, 0 ) ) != TT_Err_Ok || - - /* try to load the `vhea' & `vmtx' at once if present */ - ( error = sfnt->load_metrics( face, stream, 1 ) ) != TT_Err_Ok || - - 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 */ - - if ( LOAD_( hdmx ) || - LOAD_( gasp ) || - LOAD_( kerning ) || - LOAD_( pclt ) ) - goto Exit; - -#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE - if ( ( error = TT_Extension_Create( face ) ) != TT_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; - FT_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 */ - -#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES - /* might need more polish to detect the presence of a Postscript */ - /* name table in the font */ - flags |= FT_FACE_FLAG_GLYPH_NAMES; -#endif - - /* 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; - } - - 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 ) - { - root->num_fixed_sizes = face->num_sbit_strikes; - if ( ALLOC_ARRAY( root->available_sizes, - face->num_sbit_strikes, - FT_Bitmap_Size ) ) - return error; - - for ( n = 0 ; n < face->num_sbit_strikes ; n++ ) - { - root->available_sizes[n].width = - face->sbit_strikes[n].x_ppem; - root->available_sizes[n].height = - face->sbit_strikes[n].y_ppem; - } - } - else - -#else /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ - - { - 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 = face->vertical_info - ? face->vertical.advance_Height_Max - : root->height; - - 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 = (SFNT_Interface*)face->sfnt; - - - if ( sfnt ) - { - /* destroy the postscript names table if it is loaded */ - if ( sfnt->free_psnames ) - sfnt->free_psnames( face ); - - /* destroy the embedded bitmaps table if it is loaded */ - 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.offsets ); - face->ttc_header.count = 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; - } - - -/* END */ diff --git a/src/freetype/sfnt/sfobjs.h b/src/freetype/sfnt/sfobjs.h deleted file mode 100644 index 35d92f9d19..0000000000 --- a/src/freetype/sfnt/sfobjs.h +++ /dev/null @@ -1,57 +0,0 @@ -/***************************************************************************/ -/* */ -/* sfobjs.h */ -/* */ -/* SFNT object management (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifndef SFOBJS_H -#define SFOBJS_H - -#include -#include - - -#ifdef __cplusplus - extern "C" { -#endif - - - LOCAL_DEF - FT_Error SFNT_Init_Face( FT_Stream stream, - TT_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ); - - LOCAL_DEF - FT_Error SFNT_Load_Face( FT_Stream stream, - TT_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ); - - LOCAL_DEF - void SFNT_Done_Face( TT_Face face ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* SFDRIVER_H */ - - -/* END */ diff --git a/src/freetype/sfnt/ttcmap.c b/src/freetype/sfnt/ttcmap.c deleted file mode 100644 index 87ad04f014..0000000000 --- a/src/freetype/sfnt/ttcmap.c +++ /dev/null @@ -1,550 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttcmap.c */ -/* */ -/* TrueType character mapping table (cmap) support (body). */ -/* */ -/* 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 -#include - - -#ifdef FT_FLAT_COMPILE - -#include "ttload.h" -#include "ttcmap.h" - -#else - -#include -#include - -#endif - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_ttcmap - - - static FT_UInt code_to_index0( TT_CMapTable* charmap, - FT_ULong char_code ); - static FT_UInt code_to_index2( TT_CMapTable* charmap, - FT_ULong char_code ); - static FT_UInt code_to_index4( TT_CMapTable* charmap, - FT_ULong char_code ); - static FT_UInt code_to_index6( TT_CMapTable* charmap, - FT_ULong char_code ); - - - /*************************************************************************/ - /* */ - /* */ - /* TT_CharMap_Load */ - /* */ - /* */ - /* Loads a given TrueType character map into memory. */ - /* */ - /* */ - /* face :: A handle to the parent face object. */ - /* stream :: A handle to the current stream object. */ - /* */ - /* */ - /* table :: A pointer to a cmap object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The function assumes that the stream is already in use (i.e., */ - /* opened). In case of error, all partially allocated tables are */ - /* released. */ - /* */ - LOCAL_FUNC - FT_Error TT_CharMap_Load( TT_Face face, - TT_CMapTable* cmap, - FT_Stream stream ) - { - FT_Error error; - FT_Memory memory; - FT_UShort num_SH, num_Seg, i; - - FT_UShort u, l; - - TT_CMap0* cmap0; - TT_CMap2* cmap2; - TT_CMap4* cmap4; - TT_CMap6* cmap6; - - TT_CMap2SubHeader* cmap2sub; - TT_CMap4Segment* segments; - - - if ( cmap->loaded ) - return TT_Err_Ok; - - memory = stream->memory; - - if ( FILE_Seek( cmap->offset ) ) - return error; - - switch ( cmap->format ) - { - case 0: - cmap0 = &cmap->c.cmap0; - - if ( ALLOC( cmap0->glyphIdArray, 256L ) || - FILE_Read( cmap0->glyphIdArray, 256L ) ) - goto Fail; - - cmap->get_index = code_to_index0; - break; - - case 2: - num_SH = 0; - cmap2 = &cmap->c.cmap2; - - /* allocate subheader keys */ - - if ( ALLOC_ARRAY( cmap2->subHeaderKeys, 256, FT_UShort ) || - ACCESS_Frame( 512L ) ) - goto Fail; - - for ( i = 0; i < 256; i++ ) - { - u = GET_UShort() / 8; - cmap2->subHeaderKeys[i] = u; - - if ( num_SH < u ) - num_SH = u; - } - - FORGET_Frame(); - - /* load subheaders */ - - cmap2->numGlyphId = l = - ( ( cmap->length - 2L * ( 256 + 3 ) - num_SH * 8L ) & 0xFFFF ) / 2; - - if ( ALLOC_ARRAY( cmap2->subHeaders, - num_SH + 1, - TT_CMap2SubHeader ) || - ACCESS_Frame( ( num_SH + 1 ) * 8L ) ) - goto Fail; - - cmap2sub = cmap2->subHeaders; - - for ( i = 0; i <= num_SH; i++ ) - { - cmap2sub->firstCode = GET_UShort(); - cmap2sub->entryCount = GET_UShort(); - cmap2sub->idDelta = GET_Short(); - /* we apply the location offset immediately */ - cmap2sub->idRangeOffset = GET_UShort() - ( num_SH - i ) * 8 - 2; - - cmap2sub++; - } - - FORGET_Frame(); - - /* load glyph IDs */ - - if ( ALLOC_ARRAY( cmap2->glyphIdArray, l, FT_UShort ) || - ACCESS_Frame( l * 2L ) ) - goto Fail; - - for ( i = 0; i < l; i++ ) - cmap2->glyphIdArray[i] = GET_UShort(); - - FORGET_Frame(); - - cmap->get_index = code_to_index2; - break; - - case 4: - cmap4 = &cmap->c.cmap4; - - /* load header */ - - if ( ACCESS_Frame( 8L ) ) - goto Fail; - - cmap4->segCountX2 = GET_UShort(); - cmap4->searchRange = GET_UShort(); - cmap4->entrySelector = GET_UShort(); - cmap4->rangeShift = GET_UShort(); - - num_Seg = cmap4->segCountX2 / 2; - - FORGET_Frame(); - - /* load segments */ - - if ( ALLOC_ARRAY( cmap4->segments, - num_Seg, - TT_CMap4Segment ) || - ACCESS_Frame( ( num_Seg * 4 + 1 ) * 2L ) ) - goto Fail; - - segments = cmap4->segments; - - for ( i = 0; i < num_Seg; i++ ) - segments[i].endCount = GET_UShort(); - - (void)GET_UShort(); - - for ( i = 0; i < num_Seg; i++ ) - segments[i].startCount = GET_UShort(); - - for ( i = 0; i < num_Seg; i++ ) - segments[i].idDelta = GET_Short(); - - for ( i = 0; i < num_Seg; i++ ) - segments[i].idRangeOffset = GET_UShort(); - - FORGET_Frame(); - - cmap4->numGlyphId = l = - ( ( cmap->length - ( 16L + 8L * num_Seg ) ) & 0xFFFF ) / 2; - - /* load IDs */ - - if ( ALLOC_ARRAY( cmap4->glyphIdArray, l, FT_UShort ) || - ACCESS_Frame( l * 2L ) ) - goto Fail; - - for ( i = 0; i < l; i++ ) - cmap4->glyphIdArray[i] = GET_UShort(); - - FORGET_Frame(); - - cmap->get_index = code_to_index4; - - cmap4->last_segment = cmap4->segments; - break; - - case 6: - cmap6 = &cmap->c.cmap6; - - if ( ACCESS_Frame( 4L ) ) - goto Fail; - - cmap6->firstCode = GET_UShort(); - cmap6->entryCount = GET_UShort(); - - FORGET_Frame(); - - l = cmap6->entryCount; - - if ( ALLOC_ARRAY( cmap6->glyphIdArray, - cmap6->entryCount, - FT_Short ) || - ACCESS_Frame( l * 2L ) ) - goto Fail; - - for ( i = 0; i < l; i++ ) - cmap6->glyphIdArray[i] = GET_UShort(); - - FORGET_Frame(); - cmap->get_index = code_to_index6; - break; - - default: /* corrupt character mapping table */ - return TT_Err_Invalid_CharMap_Format; - - } - - return TT_Err_Ok; - - Fail: - TT_CharMap_Free( face, cmap ); - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_CharMap_Free */ - /* */ - /* */ - /* Destroys a character mapping table. */ - /* */ - /* */ - /* face :: A handle to the parent face object. */ - /* cmap :: A handle to a cmap object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_CharMap_Free( TT_Face face, - TT_CMapTable* cmap ) - { - FT_Memory memory; - - - if ( !cmap ) - return TT_Err_Ok; - - memory = face->root.driver->root.memory; - - switch ( cmap->format ) - { - case 0: - FREE( cmap->c.cmap0.glyphIdArray ); - break; - - case 2: - FREE( cmap->c.cmap2.subHeaderKeys ); - FREE( cmap->c.cmap2.subHeaders ); - FREE( cmap->c.cmap2.glyphIdArray ); - break; - - case 4: - FREE( cmap->c.cmap4.segments ); - FREE( cmap->c.cmap4.glyphIdArray ); - cmap->c.cmap4.segCountX2 = 0; - break; - - case 6: - FREE( cmap->c.cmap6.glyphIdArray ); - cmap->c.cmap6.entryCount = 0; - break; - - default: - /* invalid table format, do nothing */ - ; - } - - cmap->loaded = FALSE; - return TT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* code_to_index0 */ - /* */ - /* */ - /* Converts the character code into a glyph index. Uses format 0. */ - /* `charCode' must be in the range 0x00-0xFF (otherwise 0 is */ - /* returned). */ - /* */ - /* */ - /* charCode :: The wanted character code. */ - /* cmap0 :: A pointer to a cmap table in format 0. */ - /* */ - /* */ - /* Glyph index into the glyphs array. 0 if the glyph does not exist. */ - /* */ - static - FT_UInt code_to_index0( TT_CMapTable* cmap, - FT_ULong charCode ) - { - TT_CMap0* cmap0 = &cmap->c.cmap0; - - - return ( charCode <= 0xFF ? cmap0->glyphIdArray[charCode] : 0 ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* code_to_index2 */ - /* */ - /* */ - /* Converts the character code into a glyph index. Uses format 2. */ - /* */ - /* */ - /* charCode :: The wanted character code. */ - /* cmap2 :: A pointer to a cmap table in format 2. */ - /* */ - /* */ - /* Glyph index into the glyphs array. 0 if the glyph does not exist. */ - /* */ - static - FT_UInt code_to_index2( TT_CMapTable* cmap, - FT_ULong charCode ) - { - FT_UInt result, index1, offset; - FT_UInt char_lo; - FT_ULong char_hi; - TT_CMap2SubHeader* sh2; - TT_CMap2* cmap2; - - - cmap2 = &cmap->c.cmap2; - result = 0; - char_lo = (FT_UInt)( charCode & 0xFF ); - char_hi = charCode >> 8; - - if ( char_hi == 0 ) - { - /* an 8-bit character code -- we use the subHeader 0 in this case */ - /* to test whether the character code is in the charmap */ - if ( cmap2->subHeaderKeys[char_lo] == 0 ) - result = cmap2->glyphIdArray[char_lo]; - } - else - { - /* a 16-bit character code */ - index1 = cmap2->subHeaderKeys[char_hi & 0xFF]; - if ( index1 ) - { - sh2 = cmap2->subHeaders + index1; - char_lo -= sh2->firstCode; - - if ( char_lo < sh2->entryCount ) - { - offset = sh2->idRangeOffset / 2 + char_lo; - if ( offset < cmap2->numGlyphId ) - { - result = cmap2->glyphIdArray[offset]; - if ( result ) - result = ( result + sh2->idDelta ) & 0xFFFF; - } - } - } - } - - return result; - } - - - /*************************************************************************/ - /* */ - /* */ - /* code_to_index4 */ - /* */ - /* */ - /* Converts the character code into a glyph index. Uses format 4. */ - /* */ - /* */ - /* charCode :: The wanted character code. */ - /* cmap4 :: A pointer to a cmap table in format 4. */ - /* */ - /* */ - /* Glyph index into the glyphs array. 0 if the glyph does not exist. */ - /* */ - static - FT_UInt code_to_index4( TT_CMapTable* cmap, - FT_ULong charCode ) - { - FT_UInt result, index1, segCount; - TT_CMap4* cmap4; - TT_CMap4Segment *seg4, *limit; - - - cmap4 = &cmap->c.cmap4; - result = 0; - segCount = cmap4->segCountX2 / 2; - seg4 = cmap4->segments; - limit = seg4 + segCount; - - /* check against the last segment */ - seg4 = cmap4->last_segment; - - /* the following is equivalent to performing two tests, as in */ - /* */ - /* if ( charCode >= seg4->startCount && charCode <= seg4->endCount ) */ - /* */ - /* Yes, that's a bit strange, but it's faster, and the idea behind */ - /* the cache is to significantly speed up charcode to glyph index */ - /* conversion. */ - - if ( (FT_ULong)(charCode - seg4->startCount) < - (FT_ULong)(seg4->endCount - seg4->startCount) ) - goto Found; - - for ( seg4 = cmap4->segments; seg4 < limit; seg4++ ) - { - /* the ranges are sorted in increasing order. If we are out of */ - /* the range here, the char code isn't in the charmap, so exit. */ - - if ( charCode > seg4->endCount ) - continue; - - if ( charCode >= seg4->startCount ) - goto Found; - } - return 0; - - Found: - cmap4->last_segment = seg4; - - /* if the idRangeOffset is 0, we can compute the glyph index */ - /* directly */ - - if ( seg4->idRangeOffset == 0 ) - result = ( charCode + seg4->idDelta ) & 0xFFFF; - else - { - /* otherwise, we must use the glyphIdArray to do it */ - index1 = seg4->idRangeOffset / 2 - + ( charCode - seg4->startCount ) - + ( seg4 - cmap4->segments ) - - segCount; - - if ( index1 < cmap4->numGlyphId && - cmap4->glyphIdArray[index1] != 0 ) - result = ( cmap4->glyphIdArray[index1] + seg4->idDelta ) & 0xFFFF; - } - - return result; - } - - - /*************************************************************************/ - /* */ - /* */ - /* code_to_index6 */ - /* */ - /* */ - /* Converts the character code into a glyph index. Uses format 6. */ - /* */ - /* */ - /* charCode :: The wanted character code. */ - /* cmap6 :: A pointer to a cmap table in format 6. */ - /* */ - /* */ - /* Glyph index into the glyphs array. 0 if the glyph does not exist. */ - /* */ - static - FT_UInt code_to_index6( TT_CMapTable* cmap, - FT_ULong charCode ) - { - TT_CMap6* cmap6; - FT_UInt result = 0; - - - cmap6 = &cmap->c.cmap6; - result = 0; - charCode -= cmap6->firstCode; - - if ( charCode < cmap6->entryCount ) - result = cmap6->glyphIdArray[charCode]; - - return result; - } - - -/* END */ diff --git a/src/freetype/sfnt/ttcmap.h b/src/freetype/sfnt/ttcmap.h deleted file mode 100644 index 609972a901..0000000000 --- a/src/freetype/sfnt/ttcmap.h +++ /dev/null @@ -1,45 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttcmap.h */ -/* */ -/* TrueType character mapping table (cmap) support (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifndef TTCMAP_H -#define TTCMAP_H - -#include - -#ifdef __cplusplus - extern "C" { -#endif - - - LOCAL_DEF - FT_Error TT_CharMap_Load( TT_Face face, - TT_CMapTable* cmap, - FT_Stream input ); - - LOCAL_DEF - FT_Error TT_CharMap_Free( TT_Face face, - TT_CMapTable* cmap ); - -#ifdef __cplusplus - } -#endif - -#endif /* TTCMAP_H */ - - -/* END */ diff --git a/src/freetype/sfnt/ttload.c b/src/freetype/sfnt/ttload.c deleted file mode 100644 index e7871874df..0000000000 --- a/src/freetype/sfnt/ttload.c +++ /dev/null @@ -1,1676 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttload.c */ -/* */ -/* Load the basic TrueType tables, i.e., tables that can be either in */ -/* TTF or OTF fonts (body). */ -/* */ -/* 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 -#include -#include - - -#ifdef FT_FLAT_COMPILE - -#include "ttload.h" -#include "ttcmap.h" - -#else - -#include -#include - -#endif - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_ttload - - - /*************************************************************************/ - /* */ - /* */ - /* TT_LookUp_Table */ - /* */ - /* */ - /* Looks for a TrueType table by name. */ - /* */ - /* */ - /* face :: A face object handle. */ - /* tag :: The searched tag. */ - /* */ - /* */ - /* A pointer to the table directory entry. 0 if not found. */ - /* */ - LOCAL_FUNC - TT_Table* TT_LookUp_Table( TT_Face face, - FT_ULong tag ) - { - TT_Table* entry; - TT_Table* limit; - - - FT_TRACE3(( "TT_LookUp_Table: %08p, `%c%c%c%c'\n", - face, - (FT_Char)( tag >> 24 ), - (FT_Char)( tag >> 16 ), - (FT_Char)( tag >> 8 ), - (FT_Char)( tag ) )); - - entry = face->dir_tables; - limit = entry + face->num_tables; - - for ( ; entry < limit; entry++ ) - { - if ( entry->Tag == tag ) - return entry; - } - - FT_TRACE3(( " Could not find table!\n" )); - return 0; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Goto_Table */ - /* */ - /* */ - /* Looks for a TrueType table by name, then seek a stream to it. */ - /* */ - /* */ - /* face :: A face object handle. */ - /* tag :: The searched tag. */ - /* stream :: The stream to seek when the table is found. */ - /* */ - /* */ - /* length :: The length of the table if found, undefined otherwise. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Goto_Table( TT_Face face, - FT_ULong tag, - FT_Stream stream, - FT_ULong* length ) - { - TT_Table* table; - FT_Error error; - - - table = TT_LookUp_Table( face, tag ); - if ( table ) - { - if ( length ) - *length = table->Length; - - (void)FILE_Seek( table->Offset ); - } - else - error = TT_Err_Table_Missing; - - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_SFNT_Header */ - /* */ - /* */ - /* Loads the header of a SFNT font file. Supports collections. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* stream :: The input stream. */ - /* face_index :: If the font is a collection, the number of the font */ - /* in the collection, ignored otherwise. */ - /* */ - /* */ - /* sfnt :: The SFNT header. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The stream cursor must be at the font file's origin. */ - /* */ - /* This function recognizes fonts embedded in a `TrueType collection' */ - /* */ - /* The header will be checked whether it is valid by looking at the */ - /* values of `search_range', `entry_selector', and `range_shift'. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_SFNT_Header( TT_Face face, - FT_Stream stream, - FT_Long face_index, - SFNT_Header* sfnt ) - { - FT_Error error; - FT_ULong format_tag; - FT_Memory memory = stream->memory; - - const FT_Frame_Field sfnt_header_fields[] = - { - FT_FRAME_START( 8 ), - FT_FRAME_USHORT( SFNT_Header, num_tables ), - FT_FRAME_USHORT( SFNT_Header, search_range ), - FT_FRAME_USHORT( SFNT_Header, entry_selector ), - FT_FRAME_USHORT( SFNT_Header, range_shift ), - FT_FRAME_END - }; - - const FT_Frame_Field ttc_header_fields[] = - { - FT_FRAME_START( 8 ), - FT_FRAME_LONG( TTC_Header, version ), - FT_FRAME_LONG( TTC_Header, count ), - FT_FRAME_END }; - - - FT_TRACE2(( "TT_Load_SFNT_Header: %08p, %ld\n", - face, face_index )); - - face->ttc_header.tag = 0; - face->ttc_header.version = 0; - face->ttc_header.count = 0; - - face->num_tables = 0; - - /* first of all, read the first 4 bytes. If it is `ttcf', then the */ - /* file is a TrueType collection, otherwise it can be any other */ - /* kind of font. */ - if ( READ_ULong( format_tag ) ) - goto Exit; - - if ( format_tag == TTAG_ttcf ) - { - FT_Int n; - - - FT_TRACE3(( "TT_Load_SFNT_Header: file is a collection\n" )); - - /* it's a TrueType collection, i.e. a file containing several */ - /* font files. Read the font directory now */ - if ( READ_Fields( ttc_header_fields, &face->ttc_header ) ) - goto Exit; - - /* now read the offsets of each font in the file */ - if ( ALLOC_ARRAY( face->ttc_header.offsets, - face->ttc_header.count, - FT_ULong ) || - ACCESS_Frame( face->ttc_header.count * 4L ) ) - goto Exit; - - for ( n = 0; n < face->ttc_header.count; n++ ) - face->ttc_header.offsets[n] = GET_ULong(); - - FORGET_Frame(); - - /* check face index */ - if ( face_index >= face->ttc_header.count ) - { - error = TT_Err_Bad_Argument; - goto Exit; - } - - /* seek to the appropriate TrueType file, then read tag */ - if ( FILE_Seek( face->ttc_header.offsets[face_index] ) || - READ_Long( format_tag ) ) - goto Exit; - } - - /* the format tag was read, now check the rest of the header */ - sfnt->format_tag = format_tag; - if ( READ_Fields( sfnt_header_fields, sfnt ) ) - goto Exit; - - /* now, check the values of `num_tables', `seach_range', etc. */ - { - FT_UInt num_tables = sfnt->num_tables; - FT_ULong entry_selector = 1L << sfnt->entry_selector; - - - /* IMPORTANT: Many fonts have an incorrect `search_range' value, so */ - /* we only check the `entry_selector' correctness here. */ - /* */ - if ( num_tables == 0 || - entry_selector > num_tables || - entry_selector * 2 <= num_tables ) - { - FT_TRACE2(( "TT_Load_SFNT_Header: file is not SFNT!\n" )); - error = FT_Err_Unknown_File_Format; - } - } - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Directory */ - /* */ - /* */ - /* Loads the table directory into a face object. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* */ - /* stream :: The input stream. */ - /* sfnt :: The SFNT directory header. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The stream cursor must be at the font file's origin. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_Directory( TT_Face face, - FT_Stream stream, - SFNT_Header* sfnt ) - { - FT_Error error; - FT_Memory memory = stream->memory; - - TT_Table *entry, *limit; - - - FT_TRACE2(( "TT_Load_Directory: %08p\n", face )); - - FT_TRACE2(( "-- Tables count: %12u\n", sfnt->num_tables )); - FT_TRACE2(( "-- Format version: %08lx\n", sfnt->format_tag )); - - face->num_tables = sfnt->num_tables; - - if ( ALLOC_ARRAY( face->dir_tables, - face->num_tables, - TT_Table ) ) - goto Exit; - - if ( ACCESS_Frame( face->num_tables * 16L ) ) - goto Exit; - - entry = face->dir_tables; - limit = entry + face->num_tables; - - for ( ; entry < limit; entry++ ) - { /* loop through the tables and get all entries */ - entry->Tag = GET_Tag4(); - entry->CheckSum = GET_ULong(); - entry->Offset = GET_Long(); - entry->Length = GET_Long(); - - FT_TRACE2(( " %c%c%c%c - %08lx - %08lx\n", - (FT_Char)( entry->Tag >> 24 ), - (FT_Char)( entry->Tag >> 16 ), - (FT_Char)( entry->Tag >> 8 ), - (FT_Char)( entry->Tag ), - entry->Offset, - entry->Length )); - } - - FORGET_Frame(); - - FT_TRACE2(( "Directory loaded\n\n" )); - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Any */ - /* */ - /* */ - /* Loads any font table into client memory. */ - /* */ - /* */ - /* face :: The face object to look for. */ - /* */ - /* tag :: The tag of table to load. Use the value 0 if you want */ - /* to access the whole font file, else set this parameter */ - /* to a valid TrueType table tag that you can forge with */ - /* the MAKE_TT_TAG macro. */ - /* */ - /* offset :: The starting offset in the table (or the file if */ - /* tag == 0). */ - /* */ - /* length :: The address of the decision variable: */ - /* */ - /* If length == NULL: */ - /* Loads the whole table. Returns an error if */ - /* `offset' == 0! */ - /* */ - /* If *length == 0: */ - /* Exits immediately; returning the length of the given */ - /* table or of the font file, depending on the value of */ - /* `tag'. */ - /* */ - /* If *length != 0: */ - /* Loads the next `length' bytes of table or font, */ - /* starting at offset `offset' (in table or font too). */ - /* */ - /* */ - /* buffer :: The address of target buffer. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_Any( TT_Face face, - FT_ULong tag, - FT_Long offset, - FT_Byte* buffer, - FT_ULong* length ) - { - FT_Error error; - FT_Stream stream; - TT_Table* table; - FT_ULong size; - - - if ( tag != 0 ) - { - /* look for tag in font directory */ - table = TT_LookUp_Table( face, tag ); - if ( !table ) - { - error = TT_Err_Table_Missing; - goto Exit; - } - - offset += table->Offset; - size = table->Length; - } - else - /* tag == 0 -- the user wants to access the font file directly */ - size = face->root.stream->size; - - if ( length && *length == 0 ) - { - *length = size; - - return TT_Err_Ok; - } - - if ( length ) - size = *length; - - stream = face->root.stream; - (void)FILE_Read_At( offset, buffer, size ); - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Header */ - /* */ - /* */ - /* Loads the TrueType font header. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* stream :: The input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_Header( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - TT_Header* header; - - static const FT_Frame_Field header_fields[] = - { - FT_FRAME_START( 54 ), - FT_FRAME_ULONG( TT_Header, Table_Version ), - FT_FRAME_ULONG( TT_Header, Font_Revision ), - FT_FRAME_LONG( TT_Header, CheckSum_Adjust ), - FT_FRAME_LONG( TT_Header, Magic_Number ), - FT_FRAME_USHORT( TT_Header, Flags ), - FT_FRAME_USHORT( TT_Header, Units_Per_EM ), - FT_FRAME_LONG( TT_Header, Created[0] ), - FT_FRAME_LONG( TT_Header, Created[1] ), - FT_FRAME_LONG( TT_Header, Modified[0] ), - FT_FRAME_LONG( TT_Header, Modified[1] ), - FT_FRAME_SHORT( TT_Header, xMin ), - FT_FRAME_SHORT( TT_Header, yMin ), - FT_FRAME_SHORT( TT_Header, xMax ), - FT_FRAME_SHORT( TT_Header, yMax ), - FT_FRAME_USHORT( TT_Header, Mac_Style ), - FT_FRAME_USHORT( TT_Header, Lowest_Rec_PPEM ), - FT_FRAME_SHORT( TT_Header, Font_Direction ), - FT_FRAME_SHORT( TT_Header, Index_To_Loc_Format ), - FT_FRAME_SHORT( TT_Header, Glyph_Data_Format ), - FT_FRAME_END - }; - - - FT_TRACE2(( "Load_TT_Header: %08p\n", face )); - - error = face->goto_table( face, TTAG_head, stream, 0 ); - if ( error ) - { - FT_TRACE0(( "Font Header is missing!\n" )); - goto Exit; - } - - header = &face->header; - - if ( READ_Fields( header_fields, header ) ) - goto Exit; - - FT_TRACE2(( " Units per EM: %8u\n", header->Units_Per_EM )); - FT_TRACE2(( " IndexToLoc: %8d\n", header->Index_To_Loc_Format )); - FT_TRACE2(( "Font Header Loaded.\n" )); - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_MaxProfile */ - /* */ - /* */ - /* Loads the maximum profile into a face object. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* stream :: The input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_MaxProfile( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - TT_MaxProfile* maxProfile = &face->max_profile; - - const FT_Frame_Field maxp_fields[] = - { - FT_FRAME_START( 32 ), - FT_FRAME_ULONG( TT_MaxProfile, version ), - FT_FRAME_USHORT( TT_MaxProfile, numGlyphs ), - FT_FRAME_USHORT( TT_MaxProfile, maxPoints ), - FT_FRAME_USHORT( TT_MaxProfile, maxContours ), - FT_FRAME_USHORT( TT_MaxProfile, maxCompositePoints ), - FT_FRAME_USHORT( TT_MaxProfile, maxCompositeContours ), - FT_FRAME_USHORT( TT_MaxProfile, maxZones ), - FT_FRAME_USHORT( TT_MaxProfile, maxTwilightPoints ), - FT_FRAME_USHORT( TT_MaxProfile, maxStorage ), - FT_FRAME_USHORT( TT_MaxProfile, maxFunctionDefs ), - FT_FRAME_USHORT( TT_MaxProfile, maxInstructionDefs ), - FT_FRAME_USHORT( TT_MaxProfile, maxStackElements ), - FT_FRAME_USHORT( TT_MaxProfile, maxSizeOfInstructions ), - FT_FRAME_USHORT( TT_MaxProfile, maxComponentElements ), - FT_FRAME_USHORT( TT_MaxProfile, maxComponentDepth ), - FT_FRAME_END }; - - - FT_TRACE2(( "Load_TT_MaxProfile: %08p\n", face )); - - error = face->goto_table( face, TTAG_maxp, stream, 0 ); - if ( error ) - goto Exit; - - if ( READ_Fields( maxp_fields, maxProfile ) ) - goto Exit; - - /* XXX: an adjustment that is necessary to load certain */ - /* broken fonts like `Keystrokes MT' :-( */ - /* */ - /* We allocate 64 function entries by default when */ - /* the maxFunctionDefs field is null. */ - - if ( maxProfile->maxFunctionDefs == 0 ) - maxProfile->maxFunctionDefs = 64; - - face->root.num_glyphs = maxProfile->numGlyphs; - - face->root.max_points = MAX( maxProfile->maxCompositePoints, - maxProfile->maxPoints ); - - face->root.max_contours = MAX( maxProfile->maxCompositeContours, - maxProfile->maxContours ); - - face->max_components = (FT_ULong)maxProfile->maxComponentElements + - maxProfile->maxComponentDepth; - - /* XXX: some fonts have maxComponents set to 0; we will */ - /* then use 16 of them by default. */ - if ( face->max_components == 0 ) - face->max_components = 16; - - /* We also increase maxPoints and maxContours in order to support */ - /* some broken fonts. */ - face->root.max_points += 8; - face->root.max_contours += 4; - - FT_TRACE2(( "MAXP loaded.\n" )); - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Metrics */ - /* */ - /* */ - /* Loads the horizontal or vertical metrics table into a face object. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* stream :: The input stream. */ - /* vertical :: A boolean flag. If set, load vertical metrics. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error TT_Load_Metrics( TT_Face face, - FT_Stream stream, - FT_Bool vertical ) - { - FT_Error error; - FT_Memory memory = stream->memory; - - FT_ULong table_len; - FT_Long num_shorts, num_longs, num_shorts_checked; - - TT_LongMetrics** longs; - TT_ShortMetrics** shorts; - - - FT_TRACE2(( "TT_Load_%s_Metrics: %08p\n", vertical ? "Vertical" - : "Horizontal", - face )); - - if ( vertical ) - { - /* The table is optional, quit silently if it wasn't found */ - /* XXX: Some fonts have a valid vertical header with a non-null */ - /* `number_of_VMetrics' fields, but no corresponding `vmtx' */ - /* table to get the metrics from (e.g. mingliu). */ - /* */ - /* For safety, we set the field to 0! */ - /* */ - error = face->goto_table( face, TTAG_vmtx, stream, &table_len ); - if ( error ) - { - /* Set number_Of_VMetrics to 0! */ - FT_TRACE2(( " no vertical header in file.\n" )); - face->vertical.number_Of_VMetrics = 0; - error = TT_Err_Ok; - goto Exit; - } - - num_longs = face->vertical.number_Of_VMetrics; - longs = (TT_LongMetrics**)&face->vertical.long_metrics; - shorts = (TT_ShortMetrics**)&face->vertical.short_metrics; - } - else - { - error = face->goto_table( face, TTAG_hmtx, stream, &table_len ); - if ( error ) - { - FT_ERROR(( " no horizontal metrics in file!\n" )); - error = TT_Err_Hmtx_Table_Missing; - goto Exit; - } - - num_longs = face->horizontal.number_Of_HMetrics; - longs = (TT_LongMetrics**)&face->horizontal.long_metrics; - shorts = (TT_ShortMetrics**)&face->horizontal.short_metrics; - } - - /* never trust derived values */ - - num_shorts = face->max_profile.numGlyphs - num_longs; - num_shorts_checked = ( table_len - num_longs * 4L ) / 2; - - if ( num_shorts < 0 ) - { - FT_ERROR(( "TT_Load_%s_Metrics: more metrics than glyphs!\n", - vertical ? "Vertical" - : "Horizontal" )); - - error = vertical ? TT_Err_Invalid_Vert_Metrics - : TT_Err_Invalid_Horiz_Metrics; - goto Exit; - } - - if ( ALLOC_ARRAY( *longs, num_longs, TT_LongMetrics ) || - ALLOC_ARRAY( *shorts, num_shorts, TT_ShortMetrics ) ) - goto Exit; - - if ( ACCESS_Frame( table_len ) ) - goto Exit; - - { - TT_LongMetrics* cur = *longs; - TT_LongMetrics* limit = cur + num_longs; - - - for ( ; cur < limit; cur++ ) - { - cur->advance = GET_UShort(); - cur->bearing = GET_Short(); - } - } - - /* do we have an inconsistent number of metric values? */ - { - TT_ShortMetrics* cur = *shorts; - TT_ShortMetrics* limit = cur + MIN( num_shorts, num_shorts_checked ); - - - for ( ; cur < limit; cur++ ) - *cur = GET_Short(); - - /* we fill up the missing left side bearings with the */ - /* last valid value. Since this will occur for buggy CJK */ - /* fonts usually only, nothing serious will happen */ - if ( num_shorts > num_shorts_checked && num_shorts_checked > 0 ) - { - FT_Short val = *(shorts)[num_shorts_checked - 1]; - - - limit = *shorts + num_shorts; - for ( ; cur < limit; cur++ ) - *cur = val; - } - } - - FORGET_Frame(); - - FT_TRACE2(( "loaded\n" )); - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Metrics_Header */ - /* */ - /* */ - /* Loads the horizontal or vertical header in a face object. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* stream :: The input stream. */ - /* vertical :: A boolean flag. If set, load vertical metrics. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_Metrics_Header( TT_Face face, - FT_Stream stream, - FT_Bool vertical ) - { - FT_Error error; - TT_HoriHeader* header; - - const FT_Frame_Field metrics_header_fields[] = - { - FT_FRAME_START( 36 ), - FT_FRAME_ULONG( TT_HoriHeader, Version ), - FT_FRAME_SHORT( TT_HoriHeader, Ascender ), - FT_FRAME_SHORT( TT_HoriHeader, Descender ), - FT_FRAME_SHORT( TT_HoriHeader, Line_Gap ), - FT_FRAME_USHORT( TT_HoriHeader, advance_Width_Max ), - FT_FRAME_SHORT( TT_HoriHeader, min_Left_Side_Bearing ), - FT_FRAME_SHORT( TT_HoriHeader, min_Right_Side_Bearing ), - FT_FRAME_SHORT( TT_HoriHeader, xMax_Extent ), - FT_FRAME_SHORT( TT_HoriHeader, caret_Slope_Rise ), - FT_FRAME_SHORT( TT_HoriHeader, caret_Slope_Run ), - FT_FRAME_SHORT( TT_HoriHeader, Reserved[0] ), - FT_FRAME_SHORT( TT_HoriHeader, Reserved[1] ), - FT_FRAME_SHORT( TT_HoriHeader, Reserved[2] ), - FT_FRAME_SHORT( TT_HoriHeader, Reserved[3] ), - FT_FRAME_SHORT( TT_HoriHeader, Reserved[4] ), - FT_FRAME_SHORT( TT_HoriHeader, metric_Data_Format ), - FT_FRAME_USHORT( TT_HoriHeader, number_Of_HMetrics ), - FT_FRAME_END - }; - - - FT_TRACE2(( vertical ? "Vertical header " : "Horizontal header " )); - - if ( vertical ) - { - face->vertical_info = 0; - - /* The vertical header table is optional, so return quietly if */ - /* we don't find it. */ - error = face->goto_table( face, TTAG_vhea, stream, 0 ); - if ( error ) - { - error = TT_Err_Ok; - goto Exit; - } - - face->vertical_info = 1; - header = (TT_HoriHeader*)&face->vertical; - } - else - { - /* The horizontal header is mandatory; return an error if we */ - /* don't find it. */ - error = face->goto_table( face, TTAG_hhea, stream, 0 ); - if ( error ) - { - error = TT_Err_Horiz_Header_Missing; - goto Exit; - } - - header = &face->horizontal; - } - - if ( READ_Fields( metrics_header_fields, header ) ) - goto Exit; - - header->long_metrics = NULL; - header->short_metrics = NULL; - - FT_TRACE2(( "loaded\n" )); - - /* Now try to load the corresponding metrics */ - - error = TT_Load_Metrics( face, stream, vertical ); - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Names */ - /* */ - /* */ - /* Loads the name records. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* stream :: The input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_Names( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - FT_Memory memory = stream->memory; - - FT_ULong table_pos, table_len; - FT_ULong storageSize; - - TT_NameTable* names; - - const FT_Frame_Field name_table_fields[] = - { - FT_FRAME_START( 6 ), - FT_FRAME_USHORT( TT_NameTable, format ), - FT_FRAME_USHORT( TT_NameTable, numNameRecords ), - FT_FRAME_USHORT( TT_NameTable, storageOffset ), - FT_FRAME_END - }; - - const FT_Frame_Field name_record_fields[] = - { - /* no FT_FRAME_START */ - FT_FRAME_USHORT( TT_NameRec, platformID ), - FT_FRAME_USHORT( TT_NameRec, encodingID ), - FT_FRAME_USHORT( TT_NameRec, languageID ), - FT_FRAME_USHORT( TT_NameRec, nameID ), - FT_FRAME_USHORT( TT_NameRec, stringLength ), - FT_FRAME_USHORT( TT_NameRec, stringOffset ), - FT_FRAME_END - }; - - - FT_TRACE2(( "Names " )); - - error = face->goto_table( face, TTAG_name, stream, &table_len ); - if ( error ) - { - /* The name table is required so indicate failure. */ - FT_TRACE2(( "is missing!\n" )); - error = TT_Err_Name_Table_Missing; - goto Exit; - } - - table_pos = FILE_Pos(); - - names = &face->name_table; - - if ( READ_Fields( name_table_fields, names ) ) - goto Exit; - - /* Allocate the array of name records. */ - if ( ALLOC_ARRAY( names->names, - names->numNameRecords, - TT_NameRec ) || - ACCESS_Frame( names->numNameRecords * 12L ) ) - goto Exit; - - /* Load the name records and determine how much storage is needed */ - /* to hold the strings themselves. */ - { - TT_NameRec* cur = names->names; - TT_NameRec* limit = cur + names->numNameRecords; - - - storageSize = 0; - - for ( ; cur < limit; cur ++ ) - { - FT_ULong upper; - - - (void)READ_Fields( name_record_fields, cur ); - - upper = (FT_ULong)( cur->stringOffset + cur->stringLength ); - if ( upper > storageSize ) - storageSize = upper; - } - } - - FORGET_Frame(); - - if ( storageSize > 0 ) - { - /* allocate the name storage area in memory, then read it */ - if ( ALLOC( names->storage, storageSize ) || - FILE_Read_At( table_pos + names->storageOffset, - names->storage, storageSize ) ) - goto Exit; - - /* Go through and assign the string pointers to the name records. */ - { - TT_NameRec* cur = names->names; - TT_NameRec* limit = cur + names->numNameRecords; - - - for ( ; cur < limit; cur++ ) - cur->string = names->storage + cur->stringOffset; - } - -#ifdef FT_DEBUG_LEVEL_TRACE - - /* Print Name Record Table in case of debugging */ - { - TT_NameRec* cur = names->names; - TT_NameRec* limit = cur + names->numNameRecords; - - - for ( ; cur < limit; cur++ ) - { - FT_UInt j; - - - FT_TRACE3(( "%d %d %x %d\n ", - cur->platformID, - cur->encodingID, - cur->languageID, - cur->nameID )); - - /* I know that M$ encoded strings are Unicode, */ - /* but this works reasonable well for debugging purposes. */ - if ( cur->string ) - for ( j = 0; j < cur->stringLength; j++ ) - { - FT_Char c = *( cur->string + j ); - - - if ( (FT_Byte)c < 128 ) - FT_TRACE3(( "%c", c )); - } - } - } - FT_TRACE3(( "\n" )); - -#endif /* FT_DEBUG_LEVEL_TRACE */ - - } - FT_TRACE2(( "loaded\n" )); - - /* everything went well, update face->num_names */ - face->num_names = names->numNameRecords; - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Free_Names */ - /* */ - /* */ - /* Frees the name records. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - LOCAL_FUNC - void TT_Free_Names( TT_Face face ) - { - FT_Memory memory = face->root.driver->root.memory; - TT_NameTable* names = &face->name_table; - - - /* free strings table */ - FREE( names->names ); - - /* free strings storage */ - FREE( names->storage ); - - names->numNameRecords = 0; - names->format = 0; - names->storageOffset = 0; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_CMap */ - /* */ - /* */ - /* Loads the cmap directory in a face object. The cmaps itselves are */ - /* loaded on demand in the `ttcmap.c' module. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* stream :: A handle to the input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_CMap( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - FT_Memory memory = stream->memory; - FT_Long table_start; - TT_CMapDir cmap_dir; - - const FT_Frame_Field cmap_fields[] = - { - FT_FRAME_START( 4 ), - FT_FRAME_USHORT( TT_CMapDir, tableVersionNumber ), - FT_FRAME_USHORT( TT_CMapDir, numCMaps ), - FT_FRAME_END - }; - - const FT_Frame_Field cmap_rec_fields[] = - { - FT_FRAME_START( 6 ), - FT_FRAME_USHORT( TT_CMapTable, format ), - FT_FRAME_USHORT( TT_CMapTable, length ), - FT_FRAME_USHORT( TT_CMapTable, version ), - FT_FRAME_END - }; - - - FT_TRACE2(( "CMaps " )); - - error = face->goto_table( face, TTAG_cmap, stream, 0 ); - if ( error ) - { - error = TT_Err_CMap_Table_Missing; - goto Exit; - } - - table_start = FILE_Pos(); - - if ( READ_Fields( cmap_fields, &cmap_dir ) ) - goto Exit; - - /* reserve space in face table for cmap tables */ - if ( ALLOC_ARRAY( face->charmaps, - cmap_dir.numCMaps, - TT_CharMapRec ) ) - goto Exit; - - face->num_charmaps = cmap_dir.numCMaps; - { - TT_CharMap charmap = face->charmaps; - TT_CharMap limit = charmap + face->num_charmaps; - - - /* read the header of each charmap first */ - if ( ACCESS_Frame( face->num_charmaps * 8L ) ) - goto Exit; - - for ( ; charmap < limit; charmap++ ) - { - TT_CMapTable* cmap; - - - charmap->root.face = (FT_Face)face; - cmap = &charmap->cmap; - - cmap->loaded = FALSE; - cmap->platformID = GET_UShort(); - cmap->platformEncodingID = GET_UShort(); - cmap->offset = (FT_ULong)GET_Long(); - } - - FORGET_Frame(); - - /* now read the rest of each table */ - for ( charmap = face->charmaps; charmap < limit; charmap++ ) - { - TT_CMapTable* cmap = &charmap->cmap; - - - if ( FILE_Seek( table_start + (FT_Long)cmap->offset ) || - READ_Fields( cmap_rec_fields, cmap ) ) - goto Exit; - - cmap->offset = FILE_Pos(); - } - } - - FT_TRACE2(( "loaded\n" )); - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_OS2 */ - /* */ - /* */ - /* Loads the OS2 table. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* stream :: A handle to the input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_OS2( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - TT_OS2* os2; - - const FT_Frame_Field os2_fields[] = - { - FT_FRAME_START( 78 ), - FT_FRAME_USHORT( TT_OS2, version ), - FT_FRAME_SHORT( TT_OS2, xAvgCharWidth ), - FT_FRAME_USHORT( TT_OS2, usWeightClass ), - FT_FRAME_USHORT( TT_OS2, usWidthClass ), - FT_FRAME_SHORT( TT_OS2, fsType ), - FT_FRAME_SHORT( TT_OS2, ySubscriptXSize ), - FT_FRAME_SHORT( TT_OS2, ySubscriptYSize ), - FT_FRAME_SHORT( TT_OS2, ySubscriptXOffset ), - FT_FRAME_SHORT( TT_OS2, ySubscriptYOffset ), - FT_FRAME_SHORT( TT_OS2, ySuperscriptXSize ), - FT_FRAME_SHORT( TT_OS2, ySuperscriptYSize ), - FT_FRAME_SHORT( TT_OS2, ySuperscriptXOffset ), - FT_FRAME_SHORT( TT_OS2, ySuperscriptYOffset ), - FT_FRAME_SHORT( TT_OS2, yStrikeoutSize ), - FT_FRAME_SHORT( TT_OS2, yStrikeoutPosition ), - FT_FRAME_SHORT( TT_OS2, sFamilyClass ), - FT_FRAME_BYTE( TT_OS2, panose[0] ), - FT_FRAME_BYTE( TT_OS2, panose[1] ), - FT_FRAME_BYTE( TT_OS2, panose[2] ), - FT_FRAME_BYTE( TT_OS2, panose[3] ), - FT_FRAME_BYTE( TT_OS2, panose[4] ), - FT_FRAME_BYTE( TT_OS2, panose[5] ), - FT_FRAME_BYTE( TT_OS2, panose[6] ), - FT_FRAME_BYTE( TT_OS2, panose[7] ), - FT_FRAME_BYTE( TT_OS2, panose[8] ), - FT_FRAME_BYTE( TT_OS2, panose[9] ), - FT_FRAME_ULONG( TT_OS2, ulUnicodeRange1 ), - FT_FRAME_ULONG( TT_OS2, ulUnicodeRange2 ), - FT_FRAME_ULONG( TT_OS2, ulUnicodeRange3 ), - FT_FRAME_ULONG( TT_OS2, ulUnicodeRange4 ), - FT_FRAME_BYTE( TT_OS2, achVendID[0] ), - FT_FRAME_BYTE( TT_OS2, achVendID[1] ), - FT_FRAME_BYTE( TT_OS2, achVendID[2] ), - FT_FRAME_BYTE( TT_OS2, achVendID[3] ), - - FT_FRAME_USHORT( TT_OS2, fsSelection ), - FT_FRAME_USHORT( TT_OS2, usFirstCharIndex ), - FT_FRAME_USHORT( TT_OS2, usLastCharIndex ), - FT_FRAME_SHORT( TT_OS2, sTypoAscender ), - FT_FRAME_SHORT( TT_OS2, sTypoDescender ), - FT_FRAME_SHORT( TT_OS2, sTypoLineGap ), - FT_FRAME_USHORT( TT_OS2, usWinAscent ), - FT_FRAME_USHORT( TT_OS2, usWinDescent ), - FT_FRAME_END - }; - - const FT_Frame_Field os2_fields_extra[] = - { - FT_FRAME_START( 8 ), - FT_FRAME_ULONG( TT_OS2, ulCodePageRange1 ), - FT_FRAME_ULONG( TT_OS2, ulCodePageRange2 ), - FT_FRAME_END - }; - - const FT_Frame_Field os2_fields_extra2[] = - { - FT_FRAME_START( 10 ), - FT_FRAME_SHORT( TT_OS2, sxHeight ), - FT_FRAME_SHORT( TT_OS2, sCapHeight ), - FT_FRAME_USHORT( TT_OS2, usDefaultChar ), - FT_FRAME_USHORT( TT_OS2, usBreakChar ), - FT_FRAME_USHORT( TT_OS2, usMaxContext ), - FT_FRAME_END - }; - - - FT_TRACE2(( "OS/2 Table " )); - - /* We now support old Mac fonts where the OS/2 table doesn't */ - /* exist. Simply put, we set the `version' field to 0xFFFF */ - /* and test this value each time we need to access the table. */ - error = face->goto_table( face, TTAG_OS2, stream, 0 ); - if ( error ) - { - FT_TRACE2(( "is missing!\n" )); - face->os2.version = 0xFFFF; - error = TT_Err_Ok; - goto Exit; - } - - os2 = &face->os2; - - if ( READ_Fields( os2_fields, os2 ) ) - goto Exit; - - os2->ulCodePageRange1 = 0; - os2->ulCodePageRange2 = 0; - - if ( os2->version >= 0x0001 ) - { - /* only version 1 tables */ - if ( READ_Fields( os2_fields_extra, os2 ) ) - goto Exit; - - if ( os2->version >= 0x0002 ) - { - /* only version 2 tables */ - if ( READ_Fields( os2_fields_extra2, os2 ) ) - goto Exit; - } - } - - FT_TRACE2(( "loaded\n" )); - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Postscript */ - /* */ - /* */ - /* Loads the Postscript table. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* stream :: A handle to the input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_PostScript( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - TT_Postscript* post = &face->postscript; - - static const FT_Frame_Field post_fields[] = - { - FT_FRAME_START( 32 ), - FT_FRAME_ULONG( TT_Postscript, FormatType ), - FT_FRAME_ULONG( TT_Postscript, italicAngle ), - FT_FRAME_SHORT( TT_Postscript, underlinePosition ), - FT_FRAME_SHORT( TT_Postscript, underlineThickness ), - FT_FRAME_ULONG( TT_Postscript, isFixedPitch ), - FT_FRAME_ULONG( TT_Postscript, minMemType42 ), - FT_FRAME_ULONG( TT_Postscript, maxMemType42 ), - FT_FRAME_ULONG( TT_Postscript, minMemType1 ), - FT_FRAME_ULONG( TT_Postscript, maxMemType1 ), - FT_FRAME_END - }; - - - FT_TRACE2(( "PostScript " )); - - error = face->goto_table( face, TTAG_post, stream, 0 ); - if ( error ) - return TT_Err_Post_Table_Missing; - - if ( READ_Fields( post_fields, post ) ) - return error; - - /* we don't load the glyph names, we do that in another */ - /* module (ttpost). */ - FT_TRACE2(( "loaded\n" )); - - return TT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_PCLT */ - /* */ - /* */ - /* Loads the PCL 5 Table. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* stream :: A handle to the input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_PCLT( TT_Face face, - FT_Stream stream ) - { - static const FT_Frame_Field pclt_fields[] = - { - FT_FRAME_START( 54 ), - FT_FRAME_ULONG ( TT_PCLT, Version ), - FT_FRAME_ULONG ( TT_PCLT, FontNumber ), - FT_FRAME_USHORT( TT_PCLT, Pitch ), - FT_FRAME_USHORT( TT_PCLT, xHeight ), - FT_FRAME_USHORT( TT_PCLT, Style ), - FT_FRAME_USHORT( TT_PCLT, TypeFamily ), - FT_FRAME_USHORT( TT_PCLT, CapHeight ), - FT_FRAME_BYTES ( TT_PCLT, TypeFace, 16 ), - FT_FRAME_BYTES ( TT_PCLT, CharacterComplement, 8 ), - FT_FRAME_BYTES ( TT_PCLT, FileName, 6 ), - FT_FRAME_CHAR ( TT_PCLT, StrokeWeight ), - FT_FRAME_CHAR ( TT_PCLT, WidthType ), - FT_FRAME_BYTE ( TT_PCLT, SerifStyle ), - FT_FRAME_BYTE ( TT_PCLT, Reserved ), - FT_FRAME_END - }; - - FT_Error error; - TT_PCLT* pclt = &face->pclt; - - - FT_TRACE2(( "PCLT " )); - - /* optional table */ - error = face->goto_table( face, TTAG_PCLT, stream, 0 ); - if ( error ) - { - FT_TRACE2(( "missing (optional)\n" )); - pclt->Version = 0; - return TT_Err_Ok; - } - - if ( READ_Fields( pclt_fields, pclt ) ) - goto Exit; - - FT_TRACE2(( "loaded\n" )); - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Gasp */ - /* */ - /* */ - /* Loads the `gasp' table into a face object. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* stream :: The input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_Gasp( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - FT_Memory memory = stream->memory; - - FT_UInt j,num_ranges; - TT_GaspRange* gaspranges; - - - FT_TRACE2(( "TT_Load_Gasp: %08p\n", face )); - - /* the gasp table is optional */ - error = face->goto_table( face, TTAG_gasp, stream, 0 ); - if ( error ) - return TT_Err_Ok; - - if ( ACCESS_Frame( 4L ) ) - goto Exit; - - face->gasp.version = GET_UShort(); - face->gasp.numRanges = GET_UShort(); - - FORGET_Frame(); - - num_ranges = face->gasp.numRanges; - FT_TRACE3(( "number of ranges = %d\n", num_ranges )); - - if ( ALLOC_ARRAY( gaspranges, num_ranges, TT_GaspRange ) || - ACCESS_Frame( num_ranges * 4L ) ) - goto Exit; - - face->gasp.gaspRanges = gaspranges; - - for ( j = 0; j < num_ranges; j++ ) - { - gaspranges[j].maxPPEM = GET_UShort(); - gaspranges[j].gaspFlag = GET_UShort(); - - FT_TRACE3(( " [max:%d flag:%d]", - gaspranges[j].maxPPEM, - gaspranges[j].gaspFlag )); - } - FT_TRACE3(( "\n" )); - - FORGET_Frame(); - FT_TRACE2(( "GASP loaded\n" )); - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Kern */ - /* */ - /* */ - /* Loads the first kerning table with format 0 in the font. Only */ - /* accepts the first horizontal kerning table. Developers should use */ - /* the `ftxkern' extension to access other kerning tables in the font */ - /* file, if they really want to. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* stream :: The input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_Kern( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - FT_Memory memory = stream->memory; - - FT_UInt n, num_tables, version; - - - /* the kern table is optional; exit silently if it is missing */ - error = face->goto_table( face, TTAG_kern, stream, 0 ); - if ( error ) - return TT_Err_Ok; - - if ( ACCESS_Frame( 4L ) ) - goto Exit; - - version = GET_UShort(); - num_tables = GET_UShort(); - - FORGET_Frame(); - - for ( n = 0; n < num_tables; n++ ) - { - FT_UInt coverage; - FT_UInt length; - - - if ( ACCESS_Frame( 6L ) ) - goto Exit; - - version = GET_UShort(); /* version */ - length = GET_UShort() - 6; /* substract header length */ - coverage = GET_UShort(); - - FORGET_Frame(); - - if ( coverage == 0x0001 ) - { - FT_UInt num_pairs; - TT_Kern_0_Pair* pair; - TT_Kern_0_Pair* limit; - - - /* found a horizontal format 0 kerning table! */ - if ( ACCESS_Frame( 8L ) ) - goto Exit; - - num_pairs = GET_UShort(); - - /* skip the rest */ - - FORGET_Frame(); - - /* allocate array of kerning pairs */ - if ( ALLOC_ARRAY( face->kern_pairs, num_pairs, TT_Kern_0_Pair ) || - ACCESS_Frame( 6L * num_pairs ) ) - goto Exit; - - pair = face->kern_pairs; - limit = pair + num_pairs; - for ( ; pair < limit; pair++ ) - { - pair->left = GET_UShort(); - pair->right = GET_UShort(); - pair->value = GET_UShort(); - } - - FORGET_Frame(); - - face->num_kern_pairs = num_pairs; - face->kern_table_index = n; - goto Exit; - } - - if ( FILE_Skip( length ) ) - goto Exit; - } - - /* no kern table found -- doesn't matter */ - face->kern_table_index = -1; - face->num_kern_pairs = 0; - face->kern_pairs = NULL; - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Hdmx */ - /* */ - /* */ - /* Loads the horizontal device metrics table. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* stream :: A handle to the input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_Hdmx( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - FT_Memory memory = stream->memory; - - TT_Hdmx* hdmx = &face->hdmx; - FT_Long num_glyphs; - FT_Long record_size; - - - hdmx->version = 0; - hdmx->num_records = 0; - hdmx->records = 0; - - /* this table is optional */ - error = face->goto_table( face, TTAG_hdmx, stream, 0 ); - if ( error ) - return TT_Err_Ok; - - if ( ACCESS_Frame( 8L ) ) - goto Exit; - - hdmx->version = GET_UShort(); - hdmx->num_records = GET_Short(); - record_size = GET_Long(); - - FORGET_Frame(); - - /* Only recognize format 0 */ - if ( hdmx->version != 0 ) - goto Exit; - - if ( ALLOC_ARRAY( hdmx->records, hdmx->num_records, TT_HdmxRec ) ) - goto Exit; - - num_glyphs = face->root.num_glyphs; - record_size -= num_glyphs + 2; - - { - TT_HdmxRec* cur = hdmx->records; - TT_HdmxRec* limit = cur + hdmx->num_records; - - - for ( ; cur < limit; cur++ ) - { - /* read record */ - if ( READ_Byte( cur->ppem ) || - READ_Byte( cur->max_width ) ) - goto Exit; - - if ( ALLOC( cur->widths, num_glyphs ) || - FILE_Read( cur->widths, num_glyphs ) ) - goto Exit; - - /* skip padding bytes */ - if ( record_size > 0 && FILE_Skip( record_size ) ) - goto Exit; - } - } - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Free_Hdmx */ - /* */ - /* */ - /* Frees the horizontal device metrics table. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - LOCAL_FUNC - void TT_Free_Hdmx( TT_Face face ) - { - if ( face ) - { - FT_Int n; - FT_Memory memory = face->root.driver->root.memory; - - - for ( n = 0; n < face->hdmx.num_records; n++ ) - FREE( face->hdmx.records[n].widths ); - - FREE( face->hdmx.records ); - face->hdmx.num_records = 0; - } - } - - -/* END */ diff --git a/src/freetype/sfnt/ttload.h b/src/freetype/sfnt/ttload.h deleted file mode 100644 index dd0de6a4f1..0000000000 --- a/src/freetype/sfnt/ttload.h +++ /dev/null @@ -1,132 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttload.h */ -/* */ -/* Load the basic TrueType tables, i.e., tables that can be either in */ -/* TTF or OTF fonts (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifndef TTLOAD_H -#define TTLOAD_H - - -#include -#include - - -#ifdef __cplusplus - extern "C" { -#endif - - - LOCAL_DEF - TT_Table* TT_LookUp_Table( TT_Face face, - FT_ULong tag ); - - LOCAL_DEF - FT_Error TT_Goto_Table( TT_Face face, - FT_ULong tag, - FT_Stream stream, - FT_ULong* length ); - - - LOCAL_DEF - FT_Error TT_Load_SFNT_Header( TT_Face face, - FT_Stream stream, - FT_Long face_index, - SFNT_Header* sfnt ); - LOCAL_DEF - FT_Error TT_Load_Directory( TT_Face face, - FT_Stream stream, - SFNT_Header* sfnt ); - - LOCAL_DEF - FT_Error TT_Load_Any( TT_Face face, - FT_ULong tag, - FT_Long offset, - FT_Byte* buffer, - FT_ULong* length ); - - - LOCAL_DEF - FT_Error TT_Load_Header( TT_Face face, - FT_Stream stream ); - - - LOCAL_DEF - FT_Error TT_Load_Metrics_Header( TT_Face face, - FT_Stream stream, - FT_Bool vertical ); - - - LOCAL_DEF - FT_Error TT_Load_CMap( TT_Face face, - FT_Stream stream ); - - - LOCAL_DEF - FT_Error TT_Load_MaxProfile( TT_Face face, - FT_Stream stream ); - - - LOCAL_DEF - FT_Error TT_Load_Names( TT_Face face, - FT_Stream stream ); - - - LOCAL_DEF - FT_Error TT_Load_OS2( TT_Face face, - FT_Stream stream ); - - - LOCAL_DEF - FT_Error TT_Load_PostScript( TT_Face face, - FT_Stream stream ); - - - LOCAL_DEF - FT_Error TT_Load_Hdmx( TT_Face face, - FT_Stream stream ); - - LOCAL_DEF - FT_Error TT_Load_PCLT( TT_Face face, - FT_Stream stream ); - - LOCAL_DEF - void TT_Free_Names( TT_Face face ); - - - LOCAL_DEF - void TT_Free_Hdmx ( TT_Face face ); - - - LOCAL_DEF - FT_Error TT_Load_Kern( TT_Face face, - FT_Stream stream ); - - - LOCAL_DEF - FT_Error TT_Load_Gasp( TT_Face face, - FT_Stream stream ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* TTLOAD_H */ - - -/* END */ diff --git a/src/freetype/sfnt/ttpost.c b/src/freetype/sfnt/ttpost.c deleted file mode 100644 index c83205baed..0000000000 --- a/src/freetype/sfnt/ttpost.c +++ /dev/null @@ -1,536 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttpost.c */ -/* */ -/* Postcript name table processing for TrueType and OpenType fonts */ -/* (body). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - /*************************************************************************/ - /* */ - /* The post table is not completely loaded by the core engine. This */ - /* file loads the missing PS glyph names and implements an API to access */ - /* them. */ - /* */ - /*************************************************************************/ - - -#include -#include -#include - - -#ifdef FT_FLAT_COMPILE - -#include "ttpost.h" -#include "ttload.h" - -#else - -#include -#include - -#endif - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_ttpost - - - /* If this configuration macro is defined, we rely on the `PSNames' */ - /* module to grab the glyph names. */ - -#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES - - -#include - -#define MAC_NAME( x ) ( (FT_String*)psnames->macintosh_name( x ) ) - - -#else /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */ - - - /* Otherwise, we ignore the `PSNames' module, and provide our own */ - /* table of Mac names. Thus, it is possible to build a version of */ - /* FreeType without the Type 1 driver & PSNames module. */ - -#define MAC_NAME( x ) TT_Post_Default_Names[x] - - /* the 258 default Mac PS glyph names */ - - FT_String* TT_Post_Default_Names[258] = - { - /* 0 */ - ".notdef", ".null", "CR", "space", "exclam", - "quotedbl", "numbersign", "dollar", "percent", "ampersand", - /* 10 */ - "quotesingle", "parenleft", "parenright", "asterisk", "plus", - "comma", "hyphen", "period", "slash", "zero", - /* 20 */ - "one", "two", "three", "four", "five", - "six", "seven", "eight", "nine", "colon", - /* 30 */ - "semicolon", "less", "equal", "greater", "question", - "at", "A", "B", "C", "D", - /* 40 */ - "E", "F", "G", "H", "I", - "J", "K", "L", "M", "N", - /* 50 */ - "O", "P", "Q", "R", "S", - "T", "U", "V", "W", "X", - /* 60 */ - "Y", "Z", "bracketleft", "backslash", "bracketright", - "asciicircum", "underscore", "grave", "a", "b", - /* 70 */ - "c", "d", "e", "f", "g", - "h", "i", "j", "k", "l", - /* 80 */ - "m", "n", "o", "p", "q", - "r", "s", "t", "u", "v", - /* 90 */ - "w", "x", "y", "z", "braceleft", - "bar", "braceright", "asciitilde", "Adieresis", "Aring", - /* 100 */ - "Ccedilla", "Eacute", "Ntilde", "Odieresis", "Udieresis", - "aacute", "agrave", "acircumflex", "adieresis", "atilde", - /* 110 */ - "aring", "ccedilla", "eacute", "egrave", "ecircumflex", - "edieresis", "iacute", "igrave", "icircumflex", "idieresis", - /* 120 */ - "ntilde", "oacute", "ograve", "ocircumflex", "odieresis", - "otilde", "uacute", "ugrave", "ucircumflex", "udieresis", - /* 130 */ - "dagger", "degree", "cent", "sterling", "section", - "bullet", "paragraph", "germandbls", "registered", "copyright", - /* 140 */ - "trademark", "acute", "dieresis", "notequal", "AE", - "Oslash", "infinity", "plusminus", "lessequal", "greaterequal", - /* 150 */ - "yen", "mu", "partialdiff", "summation", "product", - "pi", "integral", "ordfeminine", "ordmasculine", "Omega", - /* 160 */ - "ae", "oslash", "questiondown", "exclamdown", "logicalnot", - "radical", "florin", "approxequal", "Delta", "guillemotleft", - /* 170 */ - "guillemotright", "ellipsis", "nbspace", "Agrave", "Atilde", - "Otilde", "OE", "oe", "endash", "emdash", - /* 180 */ - "quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide", - "lozenge", "ydieresis", "Ydieresis", "fraction", "currency", - /* 190 */ - "guilsinglleft", "guilsinglright", "fi", "fl", "daggerdbl", - "periodcentered", "quotesinglbase", "quotedblbase", "perthousand", "Acircumflex", - /* 200 */ - "Ecircumflex", "Aacute", "Edieresis", "Egrave", "Iacute", - "Icircumflex", "Idieresis", "Igrave", "Oacute", "Ocircumflex", - /* 210 */ - "apple", "Ograve", "Uacute", "Ucircumflex", "Ugrave", - "dotlessi", "circumflex", "tilde", "macron", "breve", - /* 220 */ - "dotaccent", "ring", "cedilla", "hungarumlaut", "ogonek", - "caron", "Lslash", "lslash", "Scaron", "scaron", - /* 230 */ - "Zcaron", "zcaron", "brokenbar", "Eth", "eth", - "Yacute", "yacute", "Thorn", "thorn", "minus", - /* 240 */ - "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf", - "onequarter", "threequarters", "franc", "Gbreve", "gbreve", - /* 250 */ - "Idot", "Scedilla", "scedilla", "Cacute", "cacute", - "Ccaron", "ccaron", "dmacron", - }; - - -#endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */ - - - static - FT_Error Load_Format_20( TT_Face face, - FT_Stream stream ) - { - FT_Memory memory = stream->memory; - FT_Error error; - - FT_Int num_glyphs; - FT_Int num_names; - - FT_UShort* glyph_indices = 0; - FT_Char** name_strings = 0; - - - if ( READ_UShort( num_glyphs ) ) - goto Exit; - - /* UNDOCUMENTED! The number of glyphs in this table can be smaller */ - /* than the value in the maxp table (cf. cyberbit.ttf). */ - - /* There already exist fonts which have more than 32768 glyph names */ - /* in this table, so the test for this threshold has been dropped. */ - - if ( num_glyphs > face->root.num_glyphs ) - { - error = TT_Err_Invalid_File_Format; - goto Exit; - } - - /* load the indices */ - { - FT_Int n; - - - if ( ALLOC_ARRAY ( glyph_indices, num_glyphs, FT_UShort ) || - ACCESS_Frame( num_glyphs * 2L ) ) - goto Fail; - - for ( n = 0; n < num_glyphs; n++ ) - glyph_indices[n] = GET_UShort(); - - FORGET_Frame(); - } - - /* compute number of names stored in table */ - { - FT_Int n; - - - num_names = 0; - - for ( n = 0; n < num_glyphs; n++ ) - { - FT_Int index; - - - index = glyph_indices[n]; - if ( index >= 258 ) - { - index -= 257; - if ( index > num_names ) - num_names = index; - } - } - } - - /* now load the name strings */ - { - FT_Int n; - - - if ( ALLOC_ARRAY( name_strings, num_names, FT_Char* ) ) - goto Fail; - - for ( n = 0; n < num_names; n++ ) - { - FT_UInt len; - - - if ( READ_Byte ( len ) || - ALLOC_ARRAY( name_strings[n], len + 1, FT_Char ) || - FILE_Read ( name_strings[n], len ) ) - goto Fail1; - - name_strings[n][len] = '\0'; - } - } - - /* all right, set table fields and exit successfuly */ - { - TT_Post_20* table = &face->postscript_names.names.format_20; - - - table->num_glyphs = num_glyphs; - table->num_names = num_names; - table->glyph_indices = glyph_indices; - table->glyph_names = name_strings; - } - return TT_Err_Ok; - - - Fail1: - { - FT_Int n; - - - for ( n = 0; n < num_names; n++ ) - FREE( name_strings[n] ); - } - - Fail: - FREE( name_strings ); - FREE( glyph_indices ); - - Exit: - return error; - } - - - static - FT_Error Load_Format_25( TT_Face face, - FT_Stream stream ) - { - FT_Memory memory = stream->memory; - FT_Error error; - - FT_Int num_glyphs; - FT_Char* offset_table = 0; - - - /* UNDOCUMENTED! This value appears only in the Apple TT specs. */ - if ( READ_UShort( num_glyphs ) ) - goto Exit; - - /* check the number of glyphs */ - if ( num_glyphs > face->root.num_glyphs || num_glyphs > 258 ) - { - error = TT_Err_Invalid_File_Format; - goto Exit; - } - - if ( ALLOC ( offset_table, num_glyphs ) || - FILE_Read( offset_table, num_glyphs ) ) - goto Fail; - - /* now check the offset table */ - { - FT_Int n; - - - for ( n = 0; n < num_glyphs; n++ ) - { - FT_Long index = (FT_Long)n + offset_table[n]; - - - if ( index < 0 || index > num_glyphs ) - { - error = TT_Err_Invalid_File_Format; - goto Fail; - } - } - } - - /* OK, set table fields and exit successfuly */ - { - TT_Post_25* table = &face->postscript_names.names.format_25; - - - table->num_glyphs = num_glyphs; - table->offsets = offset_table; - } - - return TT_Err_Ok; - - Fail: - FREE( offset_table ); - - Exit: - return error; - } - - - static - FT_Error Load_Post_Names( TT_Face face ) - { - FT_Stream stream; - FT_Error error; - - /* get a stream for the face's resource */ - stream = face->root.stream; - - /* seek to the beginning of the PS names table */ - error = face->goto_table( face, TTAG_post, stream, 0 ); - if ( error ) - goto Exit; - - /* now read postscript table */ - switch ( face->postscript.FormatType ) - { - case 0x00020000L: - error = Load_Format_20( face, stream ); - break; - - case 0x00028000L: - error = Load_Format_25( face, stream ); - break; - - default: - error = TT_Err_Invalid_File_Format; - } - - face->postscript_names.loaded = 1; - - Exit: - return error; - } - - - LOCAL_FUNC - void TT_Free_Post_Names( TT_Face face ) - { - FT_Memory memory = face->root.memory; - TT_Post_Names* names = &face->postscript_names; - - - if ( names->loaded ) - { - switch ( face->postscript.FormatType ) - { - case 0x00020000L: - { - TT_Post_20* table = &names->names.format_20; - FT_UInt n; - - - FREE( table->glyph_indices ); - table->num_glyphs = 0; - - for ( n = 0; n < table->num_names; n++ ) - FREE( table->glyph_names[n] ); - - FREE( table->glyph_names ); - table->num_names = 0; - } - break; - - case 0x00028000L: - { - TT_Post_25* table = &names->names.format_25; - - - FREE( table->offsets ); - table->num_glyphs = 0; - } - break; - } - } - names->loaded = 0; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Get_PS_Name */ - /* */ - /* */ - /* Gets the PostScript glyph name of a glyph. */ - /* */ - /* */ - /* face :: A handle to the parent face. */ - /* */ - /* index :: The glyph index. */ - /* */ - /* PSname :: The address of a string pointer. Will be NULL in case */ - /* of error, otherwise it is a pointer to the glyph name. */ - /* */ - /* You must not modify the returned string! */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Get_PS_Name( TT_Face face, - FT_UInt index, - FT_String** PSname ) - { - FT_Error error; - TT_Post_Names* names; - -#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES - PSNames_Interface* psnames; -#endif - - - if ( !face ) - return TT_Err_Invalid_Face_Handle; - - if ( index >= (FT_UInt)face->root.num_glyphs ) - return TT_Err_Invalid_Glyph_Index; - -#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES - psnames = (PSNames_Interface*)face->psnames; - if ( !psnames ) - return TT_Err_Unimplemented_Feature; -#endif - - names = &face->postscript_names; - - /* `.notdef' by default */ - *PSname = MAC_NAME( 0 ); - - switch ( face->postscript.FormatType ) - { - case 0x00010000L: - if ( index < 258 ) /* paranoid checking */ - *PSname = MAC_NAME( index ); - break; - - case 0x00020000L: - { - TT_Post_20* table = &names->names.format_20; - - - if ( !names->loaded ) - { - error = Load_Post_Names( face ); - if ( error ) - break; - } - - if ( index < table->num_glyphs ) - { - FT_UShort name_index = table->glyph_indices[index]; - - - if ( name_index < 258 ) - *PSname = MAC_NAME( name_index ); - else - *PSname = (FT_String*)table->glyph_names[name_index - 258]; - } - } - break; - - case 0x00028000L: - { - TT_Post_25* table = &names->names.format_25; - - - if ( !names->loaded ) - { - error = Load_Post_Names( face ); - if ( error ) - break; - } - - if ( index < table->num_glyphs ) /* paranoid checking */ - { - index += table->offsets[index]; - *PSname = MAC_NAME( index ); - } - } - break; - - case 0x00030000L: - break; /* nothing to do */ - } - - return TT_Err_Ok; - } - - -/* END */ diff --git a/src/freetype/sfnt/ttpost.h b/src/freetype/sfnt/ttpost.h deleted file mode 100644 index e3da83606d..0000000000 --- a/src/freetype/sfnt/ttpost.h +++ /dev/null @@ -1,52 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttpost.h */ -/* */ -/* Postcript name table processing for TrueType and OpenType fonts */ -/* (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifndef TTPOST_H -#define TTPOST_H - -#include -#include - -#ifdef __cplusplus - extern "C" { -#endif - - -#define TT_Err_Invalid_Post_Table_Format 0x0B00 -#define TT_Err_Invalid_Post_Table 0x0B01 - - - LOCAL_DEF - FT_Error TT_Get_PS_Name( TT_Face face, - FT_UInt index, - FT_String** PSname ); - - LOCAL_DEF - void TT_Free_Post_Names( TT_Face face ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* TTPOST_H */ - - -/* END */ diff --git a/src/freetype/sfnt/ttsbit.c b/src/freetype/sfnt/ttsbit.c deleted file mode 100644 index 9a5455afb8..0000000000 --- a/src/freetype/sfnt/ttsbit.c +++ /dev/null @@ -1,1444 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttsbit.c */ -/* */ -/* TrueType and OpenType embedded bitmap support (body). */ -/* */ -/* 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 -#include -#include - - -#ifdef FT_FLAT_COMPILE - -#include "ttsbit.h" - -#else - -#include - -#endif - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_ttsbit - - - /*************************************************************************/ - /* */ - /* */ - /* blit_sbit */ - /* */ - /* */ - /* Blits a bitmap from an input stream into a given target. Supports */ - /* x and y offsets as well as byte padded lines. */ - /* */ - /* */ - /* target :: The target bitmap/pixmap. */ - /* */ - /* source :: The input packed bitmap data. */ - /* */ - /* line_bits :: The number of bits per line. */ - /* */ - /* byte_padded :: A flag which is true if lines are byte-padded. */ - /* */ - /* x_offset :: The horizontal offset. */ - /* */ - /* y_offset :: The vertical offset. */ - /* */ - /* */ - /* IMPORTANT: The x and y offsets are relative to the top corner of */ - /* the target bitmap (unlike the normal TrueType */ - /* convention). A positive y offset indicates a downwards */ - /* direction! */ - /* */ - static - void blit_sbit( FT_Bitmap* target, - FT_Byte* source, - FT_Int line_bits, - FT_Bool byte_padded, - FT_Int x_offset, - FT_Int y_offset ) - { - FT_Byte* line_buff; - FT_Int line_incr; - FT_Int height; - - FT_UShort acc; - FT_Byte loaded; - - - /* first of all, compute starting write position */ - line_incr = target->pitch; - line_buff = target->buffer; - - if ( line_incr < 0 ) - line_buff -= line_incr * ( target->rows - 1 ); - - line_buff += ( x_offset >> 3 ) + y_offset * line_incr; - - /***********************************************************************/ - /* */ - /* We use the extra-classic `accumulator' trick to extract the bits */ - /* from the source byte stream. */ - /* */ - /* Namely, the variable `acc' is a 16-bit accumulator containing the */ - /* last `loaded' bits from the input stream. The bits are shifted to */ - /* the upmost position in `acc'. */ - /* */ - /***********************************************************************/ - - acc = 0; /* clear accumulator */ - loaded = 0; /* no bits were loaded */ - - for ( height = target->rows; height > 0; height-- ) - { - FT_Byte* cur = line_buff; /* current write cursor */ - FT_Int count = line_bits; /* # of bits to extract per line */ - FT_Byte shift = x_offset & 7; /* current write shift */ - FT_Byte space = 8 - shift; - - - /* first of all, read individual source bytes */ - if ( count >= 8 ) - { - count -= 8; - { - do - { - FT_Byte val; - - - /* ensure that there are at least 8 bits in the accumulator */ - if ( loaded < 8 ) - { - acc |= (FT_UShort)*source++ << ( 8 - loaded ); - loaded += 8; - } - - /* now write one byte */ - val = (FT_Byte)( acc >> 8 ); - if ( shift ) - { - cur[0] |= val >> shift; - cur[1] |= val << space; - } - else - cur[0] |= val; - - cur++; - acc <<= 8; /* remove bits from accumulator */ - loaded -= 8; - count -= 8; - - } while ( count >= 0 ); - } - - /* restore `count' to correct value */ - count += 8; - } - - /* now write remaining bits (count < 8) */ - if ( count > 0 ) - { - FT_Byte val; - - - /* ensure that there are at least `count' bits in the accumulator */ - if ( loaded < count ) - { - acc |= (FT_UShort)*source++ << ( 8 - loaded ); - loaded += 8; - } - - /* now write remaining bits */ - val = ( (FT_Byte)( acc >> 8 ) ) & ~( 0xFF >> count ); - cur[0] |= val >> shift; - - if ( count > space ) - cur[1] |= val << space; - - acc <<= count; - loaded -= count; - } - - /* now, skip to next line */ - if ( byte_padded ) - acc = loaded = 0; /* clear accumulator on byte-padded lines */ - - line_buff += line_incr; - } - } - - - const FT_Frame_Field sbit_metrics_fields[] = - { - FT_FRAME_START( 8 ), - FT_FRAME_BYTE( TT_SBit_Metrics, height ), - FT_FRAME_BYTE( TT_SBit_Metrics, width ), - - FT_FRAME_CHAR( TT_SBit_Metrics, horiBearingX ), - FT_FRAME_CHAR( TT_SBit_Metrics, horiBearingY ), - FT_FRAME_BYTE( TT_SBit_Metrics, horiAdvance ), - - FT_FRAME_CHAR( TT_SBit_Metrics, vertBearingX ), - FT_FRAME_CHAR( TT_SBit_Metrics, vertBearingY ), - FT_FRAME_BYTE( TT_SBit_Metrics, vertAdvance ), - FT_FRAME_END - }; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_SBit_Const_Metrics */ - /* */ - /* */ - /* Loads the metrics for `EBLC' index tables format 2 and 5. */ - /* */ - /* */ - /* range :: The target range. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error Load_SBit_Const_Metrics( TT_SBit_Range* range, - FT_Stream stream ) - { - FT_Error error; - - - if ( READ_ULong( range->image_size ) ) - return error; - - return READ_Fields( sbit_metrics_fields, &range->metrics ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_SBit_Range_Codes */ - /* */ - /* */ - /* Loads the range codes for `EBLC' index tables format 4 and 5. */ - /* */ - /* */ - /* range :: The target range. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* load_offsets :: A flag whether to load the glyph offset table. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error Load_SBit_Range_Codes( TT_SBit_Range* range, - FT_Stream stream, - FT_Bool load_offsets ) - { - FT_Error error; - FT_ULong count, n, size; - FT_Memory memory = stream->memory; - - - if ( READ_ULong( count ) ) - goto Exit; - - range->num_glyphs = count; - - /* Allocate glyph offsets table if needed */ - if ( load_offsets ) - { - if ( ALLOC_ARRAY( range->glyph_offsets, count, FT_ULong ) ) - goto Exit; - - size = count * 4L; - } - else - size = count * 2L; - - /* Allocate glyph codes table and access frame */ - if ( ALLOC_ARRAY ( range->glyph_codes, count, FT_UShort ) || - ACCESS_Frame( size ) ) - goto Exit; - - for ( n = 0; n < count; n++ ) - { - range->glyph_codes[n] = GET_UShort(); - - if ( load_offsets ) - range->glyph_offsets[n] = (FT_ULong)range->image_offset + - GET_UShort(); - } - - FORGET_Frame(); - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_SBit_Range */ - /* */ - /* */ - /* Loads a given `EBLC' index/range table. */ - /* */ - /* */ - /* range :: The target range. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error Load_SBit_Range( TT_SBit_Range* range, - FT_Stream stream ) - { - FT_Error error; - FT_Memory memory = stream->memory; - - - switch( range->index_format ) - { - case 1: /* variable metrics with 4-byte offsets */ - case 3: /* variable metrics with 2-byte offsets */ - { - FT_ULong num_glyphs, n; - FT_Int size_elem; - FT_Bool large = ( range->index_format == 1 ); - - - num_glyphs = range->last_glyph - range->first_glyph + 1L; - range->num_glyphs = num_glyphs; - num_glyphs++; /* XXX: BEWARE - see spec */ - - size_elem = large ? 4 : 2; - - if ( ALLOC_ARRAY( range->glyph_offsets, - num_glyphs, FT_ULong ) || - ACCESS_Frame( num_glyphs * size_elem ) ) - goto Exit; - - for ( n = 0; n < num_glyphs; n++ ) - range->glyph_offsets[n] = (FT_ULong)( range->image_offset + - ( large ? GET_ULong() - : GET_UShort() ) ); - FORGET_Frame(); - } - break; - - case 2: /* all glyphs have identical metrics */ - error = Load_SBit_Const_Metrics( range, stream ); - break; - - case 4: - error = Load_SBit_Range_Codes( range, stream, 1 ); - break; - - case 5: - error = Load_SBit_Const_Metrics( range, stream ) || - Load_SBit_Range_Codes( range, stream, 0 ); - break; - - default: - error = TT_Err_Invalid_File_Format; - } - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_SBit_Strikes */ - /* */ - /* */ - /* Loads the table of embedded bitmap sizes for this face. */ - /* */ - /* */ - /* face :: The target face object. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_SBit_Strikes( TT_Face face, - FT_Stream stream ) - { - FT_Error error = 0; - FT_Memory memory = stream->memory; - FT_Fixed version; - FT_ULong num_strikes; - FT_ULong table_base; - - const FT_Frame_Field sbit_line_metrics_fields[] = - { - /* no FT_FRAME_START */ - FT_FRAME_CHAR( TT_SBit_Line_Metrics, ascender ), - FT_FRAME_CHAR( TT_SBit_Line_Metrics, descender ), - FT_FRAME_BYTE( TT_SBit_Line_Metrics, max_width ), - - FT_FRAME_CHAR( TT_SBit_Line_Metrics, caret_slope_numerator ), - FT_FRAME_CHAR( TT_SBit_Line_Metrics, caret_slope_denominator ), - FT_FRAME_CHAR( TT_SBit_Line_Metrics, caret_offset ), - - FT_FRAME_CHAR( TT_SBit_Line_Metrics, min_origin_SB ), - FT_FRAME_CHAR( TT_SBit_Line_Metrics, min_advance_SB ), - FT_FRAME_CHAR( TT_SBit_Line_Metrics, max_before_BL ), - FT_FRAME_CHAR( TT_SBit_Line_Metrics, min_after_BL ), - FT_FRAME_CHAR( TT_SBit_Line_Metrics, pads[0] ), - FT_FRAME_CHAR( TT_SBit_Line_Metrics, pads[1] ), - FT_FRAME_END - }; - - const FT_Frame_Field strike_start_fields[] = - { - /* no FT_FRAME_START */ - FT_FRAME_ULONG( TT_SBit_Strike, ranges_offset ), - FT_FRAME_SKIP_LONG, - FT_FRAME_ULONG( TT_SBit_Strike, num_ranges ), - FT_FRAME_ULONG( TT_SBit_Strike, color_ref ), - FT_FRAME_END - }; - - const FT_Frame_Field strike_end_fields[] = - { - /* no FT_FRAME_START */ - FT_FRAME_USHORT( TT_SBit_Strike, start_glyph ), - FT_FRAME_USHORT( TT_SBit_Strike, end_glyph ), - FT_FRAME_BYTE ( TT_SBit_Strike, x_ppem ), - FT_FRAME_BYTE ( TT_SBit_Strike, y_ppem ), - FT_FRAME_BYTE ( TT_SBit_Strike, bit_depth ), - FT_FRAME_CHAR ( TT_SBit_Strike, flags ), - FT_FRAME_END - }; - - - face->num_sbit_strikes = 0; - - /* this table is optional */ - error = face->goto_table( face, TTAG_EBLC, stream, 0 ); - if (error) - error = face->goto_table( face, TTAG_bloc, stream, 0 ); - if ( error ) - { - error = 0; - goto Exit; - } - - table_base = FILE_Pos(); - if ( ACCESS_Frame( 8L ) ) - goto Exit; - - version = GET_Long(); - num_strikes = GET_ULong(); - - FORGET_Frame(); - - /* check version number and strike count */ - if ( version != 0x00020000L || - num_strikes >= 0x10000L ) - { - FT_ERROR(( "TT_Load_SBit_Strikes: invalid table version!\n" )); - error = TT_Err_Invalid_File_Format; - - goto Exit; - } - - /* allocate the strikes table */ - if ( ALLOC_ARRAY( face->sbit_strikes, num_strikes, TT_SBit_Strike ) ) - goto Exit; - - face->num_sbit_strikes = num_strikes; - - /* now read each strike table separately */ - { - TT_SBit_Strike* strike = face->sbit_strikes; - FT_ULong count = num_strikes; - - - if ( ACCESS_Frame( 48L * num_strikes ) ) - goto Exit; - - while ( count > 0 ) - { - (void)READ_Fields( strike_start_fields, strike ); - - (void)READ_Fields( sbit_line_metrics_fields, &strike->hori ); - (void)READ_Fields( sbit_line_metrics_fields, &strike->vert ); - - (void)READ_Fields( strike_end_fields, strike ); - - count--; - strike++; - } - - FORGET_Frame(); - } - - /* allocate the index ranges for each strike table */ - { - TT_SBit_Strike* strike = face->sbit_strikes; - FT_ULong count = num_strikes; - - - while ( count > 0 ) - { - TT_SBit_Range* range; - FT_ULong count2 = strike->num_ranges; - - - if ( ALLOC_ARRAY( strike->sbit_ranges, - strike->num_ranges, - TT_SBit_Range ) ) - goto Exit; - - /* read each range */ - if ( FILE_Seek( table_base + strike->ranges_offset ) || - ACCESS_Frame( strike->num_ranges * 8L ) ) - goto Exit; - - range = strike->sbit_ranges; - while ( count2 > 0 ) - { - range->first_glyph = GET_UShort(); - range->last_glyph = GET_UShort(); - range->table_offset = table_base + strike->ranges_offset - + GET_ULong(); - count2--; - range++; - } - - FORGET_Frame(); - - /* Now, read each index table */ - count2 = strike->num_ranges; - range = strike->sbit_ranges; - while ( count2 > 0 ) - { - /* Read the header */ - if ( FILE_Seek( range->table_offset ) || - ACCESS_Frame( 8L ) ) - goto Exit; - - range->index_format = GET_UShort(); - range->image_format = GET_UShort(); - range->image_offset = GET_ULong(); - - FORGET_Frame(); - - error = Load_SBit_Range( range, stream ); - if ( error ) - goto Exit; - - count2--; - range++; - } - - count--; - strike++; - } - } - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Free_SBit_Strikes */ - /* */ - /* */ - /* Releases the embedded bitmap tables. */ - /* */ - /* */ - /* face :: The target face object. */ - /* */ - LOCAL_FUNC - void TT_Free_SBit_Strikes( TT_Face face ) - { - FT_Memory memory = face->root.memory; - TT_SBit_Strike* strike = face->sbit_strikes; - TT_SBit_Strike* strike_limit = strike + face->num_sbit_strikes; - - - if ( strike ) - { - for ( ; strike < strike_limit; strike++ ) - { - TT_SBit_Range* range = strike->sbit_ranges; - TT_SBit_Range* range_limit = range + strike->num_ranges; - - - if ( range ) - { - for ( ; range < range_limit; range++ ) - { - /* release the glyph offsets and codes tables */ - /* where appropriate */ - FREE( range->glyph_offsets ); - FREE( range->glyph_codes ); - } - } - FREE( strike->sbit_ranges ); - strike->num_ranges = 0; - } - FREE( face->sbit_strikes ); - } - face->num_sbit_strikes = 0; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Find_SBit_Range */ - /* */ - /* */ - /* Scans a given strike's ranges and return, for a given glyph */ - /* index, the corresponding sbit range, and `EBDT' offset. */ - /* */ - /* */ - /* glyph_index :: The glyph index. */ - /* strike :: The source/current sbit strike. */ - /* */ - /* */ - /* arange :: The sbit range containing the glyph index. */ - /* aglyph_offset :: The offset of the glyph data in `EBDT' table. */ - /* */ - /* */ - /* FreeType error code. 0 means the glyph index was found. */ - /* */ - static - FT_Error Find_SBit_Range( FT_UInt glyph_index, - TT_SBit_Strike* strike, - TT_SBit_Range** arange, - FT_ULong* aglyph_offset ) - { - TT_SBit_Range *range, *range_limit; - - - /* check whether the glyph index is within this strike's */ - /* glyph range */ - if ( glyph_index < strike->start_glyph || - glyph_index > strike->end_glyph ) - goto Fail; - - /* scan all ranges in strike */ - range = strike->sbit_ranges; - range_limit = range + strike->num_ranges; - if ( !range ) - goto Fail; - - for ( ; range < range_limit; range++ ) - { - if ( glyph_index >= range->first_glyph && - glyph_index <= range->last_glyph ) - { - FT_UShort delta = glyph_index - range->first_glyph; - - - switch ( range->index_format ) - { - case 1: - case 3: - *aglyph_offset = range->glyph_offsets[delta]; - break; - - case 2: - *aglyph_offset = range->image_offset + - range->image_size * delta; - break; - - case 4: - case 5: - { - FT_ULong n; - - - for ( n = 0; n < range->num_glyphs; n++ ) - { - if ( range->glyph_codes[n] == glyph_index ) - { - if ( range->index_format == 4 ) - *aglyph_offset = range->glyph_offsets[n]; - else - *aglyph_offset = range->image_offset + - n * range->image_size; - goto Found; - } - } - } - - /* fall-through */ - default: - goto Fail; - } - - Found: - /* return successfully! */ - *arange = range; - return 0; - } - } - - Fail: - *arange = 0; - *aglyph_offset = 0; - - return TT_Err_Invalid_Argument; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Find_SBit_Image */ - /* */ - /* */ - /* Checks whether an embedded bitmap (an `sbit') exists for a given */ - /* glyph, at given x and y ppems. */ - /* */ - /* */ - /* face :: The target face object. */ - /* glyph_index :: The glyph index. */ - /* x_ppem :: The horizontal resolution in points per EM. */ - /* y_ppem :: The vertical resolution in points per EM. */ - /* */ - /* */ - /* arange :: The SBit range containing the glyph index. */ - /* astrike :: The SBit strike containing the glyph index. */ - /* aglyph_offset :: The offset of the glyph data in `EBDT' table. */ - /* */ - /* */ - /* FreeType error code. 0 means success. Returns */ - /* TT_Err_Invalid_Argument if no sbit exists for the requested glyph. */ - /* */ - static - FT_Error Find_SBit_Image( TT_Face face, - FT_UInt glyph_index, - FT_Int x_ppem, - FT_Int y_ppem, - - TT_SBit_Range** arange, - TT_SBit_Strike** astrike, - FT_ULong* aglyph_offset ) - { - TT_SBit_Strike* strike = face->sbit_strikes; - TT_SBit_Strike* strike_limit = strike + face->num_sbit_strikes; - - - if ( !strike ) - goto Fail; - - for ( ; strike < strike_limit; strike++ ) - { - if ( strike->x_ppem == x_ppem && strike->y_ppem == y_ppem ) - { - FT_Error error; - - - error = Find_SBit_Range( glyph_index, strike, - arange, aglyph_offset ); - if ( error ) - goto Fail; - - *astrike = strike; - - return TT_Err_Ok; - } - } - - Fail: - /* no embedded bitmap for this glyph in face */ - *arange = 0; - *astrike = 0; - *aglyph_offset = 0; - - return TT_Err_Invalid_Argument; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Load_SBit_Metrics */ - /* */ - /* */ - /* Gets the big metrics for a given SBit. */ - /* */ - /* */ - /* stream :: The input stream. */ - /* */ - /* range :: The SBit range containing the glyph. */ - /* */ - /* */ - /* big_metrics :: A big SBit metrics structure for the glyph. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The stream cursor must be positioned at the glyph's offset within */ - /* the `EBDT' table before the call. */ - /* */ - /* If the image format uses variable metrics, the stream cursor is */ - /* positioned just after the metrics header in the `EBDT' table on */ - /* function exit. */ - /* */ - static - FT_Error Load_SBit_Metrics( FT_Stream stream, - TT_SBit_Range* range, - TT_SBit_Metrics* metrics ) - { - FT_Error error = TT_Err_Ok; - - - switch ( range->image_format ) - { - case 1: - case 2: - case 8: - /* variable small metrics */ - { - TT_SBit_Small_Metrics smetrics; - - const FT_Frame_Field sbit_small_metrics_fields[] = - { - FT_FRAME_START( 5 ), - FT_FRAME_BYTE( TT_SBit_Small_Metrics, height ), - FT_FRAME_BYTE( TT_SBit_Small_Metrics, width ), - FT_FRAME_CHAR( TT_SBit_Small_Metrics, bearingX ), - FT_FRAME_CHAR( TT_SBit_Small_Metrics, bearingY ), - FT_FRAME_BYTE( TT_SBit_Small_Metrics, advance ), - FT_FRAME_END - }; - - - /* read small metrics */ - if ( READ_Fields( sbit_small_metrics_fields, &smetrics ) ) - goto Exit; - - /* convert it to a big metrics */ - metrics->height = smetrics.height; - metrics->width = smetrics.width; - metrics->horiBearingX = smetrics.bearingX; - metrics->horiBearingY = smetrics.bearingY; - metrics->horiAdvance = smetrics.advance; - - /* these metrics are made up at a higher level when */ - /* needed. */ - metrics->vertBearingX = 0; - metrics->vertBearingY = 0; - metrics->vertAdvance = 0; - } - break; - - case 6: - case 7: - case 9: - /* variable big metrics */ - (void)READ_Fields( sbit_metrics_fields, metrics ); - break; - - case 5: - default: /* constant metrics */ - if ( range->index_format == 2 || range->index_format == 5 ) - *metrics = range->metrics; - else - return TT_Err_Invalid_File_Format; - } - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Crop_Bitmap */ - /* */ - /* */ - /* Crops a bitmap to its tightest bounding box, and adjusts its */ - /* metrics. */ - /* */ - /* */ - /* image :: The input glyph slot. */ - /* */ - /* metrics :: The corresponding metrics structure. */ - /* */ - static - void Crop_Bitmap( FT_Bitmap* map, - TT_SBit_Metrics* metrics ) - { - /***********************************************************************/ - /* */ - /* In this situation, some bounding boxes of embedded bitmaps are too */ - /* large. We need to crop it to a reasonable size. */ - /* */ - /* --------- */ - /* | | ----- */ - /* | *** | |***| */ - /* | * | | * | */ - /* | * | ------> | * | */ - /* | * | | * | */ - /* | * | | * | */ - /* | *** | |***| */ - /* --------- ----- */ - /* */ - /***********************************************************************/ - - FT_Int rows, count; - FT_Long line_len; - FT_Byte* line; - - - /***********************************************************************/ - /* */ - /* first of all, check the top-most lines of the bitmap, and remove */ - /* them if they're empty. */ - /* */ - { - line = (FT_Byte*)map->buffer; - rows = map->rows; - line_len = map->pitch; - - - for ( count = 0; count < rows; count++ ) - { - FT_Byte* cur = line; - FT_Byte* limit = line + line_len; - - - for ( ; cur < limit; cur++ ) - if ( cur[0] ) - goto Found_Top; - - /* the current line was empty - skip to next one */ - line = limit; - } - - Found_Top: - /* check that we have at least one filled line */ - if ( count >= rows ) - goto Empty_Bitmap; - - /* now, crop the empty upper lines */ - if ( count > 0 ) - { - line = (FT_Byte*)map->buffer; - - MEM_Move( line, line + count * line_len, - ( rows - count ) * line_len ); - - metrics->height -= count; - metrics->horiBearingY -= count; - metrics->vertBearingY -= count; - - map->rows -= count; - rows -= count; - } - } - - /***********************************************************************/ - /* */ - /* second, crop the lower lines */ - /* */ - { - line = (FT_Byte*)map->buffer + ( rows - 1 ) * line_len; - - for ( count = 0; count < rows; count++ ) - { - FT_Byte* cur = line; - FT_Byte* limit = line + line_len; - - - for ( ; cur < limit; cur++ ) - if ( cur[0] ) - goto Found_Bottom; - - /* the current line was empty - skip to previous one */ - line -= line_len; - } - - Found_Bottom: - if ( count > 0 ) - { - metrics->height -= count; - rows -= count; - map->rows -= count; - } - } - - /***********************************************************************/ - /* */ - /* third, get rid of the space on the left side of the glyph */ - /* */ - do - { - FT_Byte* limit; - - - line = (FT_Byte*)map->buffer; - limit = line + rows * line_len; - - for ( ; line < limit; line += line_len ) - if ( line[0] & 0x80 ) - goto Found_Left; - - /* shift the whole glyph one pixel to the left */ - line = (FT_Byte*)map->buffer; - limit = line + rows * line_len; - - for ( ; line < limit; line += line_len ) - { - FT_Int n, width = map->width; - FT_Byte old; - FT_Byte* cur = line; - - - old = cur[0] << 1; - for ( n = 8; n < width; n += 8 ) - { - FT_Byte val; - - - val = cur[1]; - cur[0] = old | ( val >> 7 ); - old = val << 1; - cur++; - } - cur[0] = old; - } - - map->width--; - metrics->horiBearingX++; - metrics->vertBearingX++; - metrics->width--; - - } while ( map->width > 0 ); - - Found_Left: - - /***********************************************************************/ - /* */ - /* finally, crop the bitmap width to get rid of the space on the right */ - /* side of the glyph. */ - /* */ - do - { - FT_Int right = map->width - 1; - FT_Byte* limit; - FT_Byte mask; - - - line = (FT_Byte*)map->buffer + ( right >> 3 ); - limit = line + rows * line_len; - mask = 0x80 >> ( right & 7 ); - - for ( ; line < limit; line += line_len ) - if ( line[0] & mask ) - goto Found_Right; - - /* crop the whole glyph to the right */ - map->width--; - metrics->width--; - - } while ( map->width > 0 ); - - Found_Right: - /* all right, the bitmap was cropped */ - return; - - Empty_Bitmap: - map->width = 0; - map->rows = 0; - map->pitch = 0; - map->pixel_mode = ft_pixel_mode_mono; - } - - - static - FT_Error Load_SBit_Single( FT_Bitmap* map, - FT_Int x_offset, - FT_Int y_offset, - FT_Int pix_bits, - FT_UShort image_format, - TT_SBit_Metrics* metrics, - FT_Stream stream ) - { - FT_Error error; - - - /* check that the source bitmap fits into the target pixmap */ - if ( x_offset < 0 || x_offset + metrics->width > map->width || - y_offset < 0 || y_offset + metrics->height > map->rows ) - { - error = TT_Err_Invalid_Argument; - - goto Exit; - } - - { - FT_Int glyph_width = metrics->width; - FT_Int glyph_height = metrics->height; - FT_Int glyph_size; - FT_Int line_bits = pix_bits * glyph_width; - FT_Bool pad_bytes = 0; - - - /* compute size of glyph image */ - switch ( image_format ) - { - case 1: /* byte-padded formats */ - case 6: - { - FT_Int line_length; - - - switch ( pix_bits ) - { - case 1: line_length = ( glyph_width + 7 ) >> 3; break; - case 2: line_length = ( glyph_width + 3 ) >> 2; break; - case 4: line_length = ( glyph_width + 1 ) >> 1; break; - default: line_length = glyph_width; - } - - glyph_size = glyph_height * line_length; - pad_bytes = 1; - } - break; - - case 2: - case 5: - case 7: - line_bits = glyph_width * pix_bits; - glyph_size = ( glyph_height * line_bits + 7 ) >> 3; - break; - - default: /* invalid format */ - return TT_Err_Invalid_File_Format; - } - - /* Now read data and draw glyph into target pixmap */ - if ( ACCESS_Frame( glyph_size ) ) - goto Exit; - - /* don't forget to multiply `x_offset' by `map->pix_bits' as */ - /* the sbit blitter doesn't make a difference between pixmap */ - /* depths. */ - blit_sbit( map, (FT_Byte*)stream->cursor, line_bits, pad_bytes, - x_offset * pix_bits, y_offset ); - - FORGET_Frame(); - } - - Exit: - return error; - } - - - static - FT_Error Load_SBit_Image( TT_SBit_Strike* strike, - TT_SBit_Range* range, - FT_ULong ebdt_pos, - FT_ULong glyph_offset, - FT_Bitmap* map, - FT_Int x_offset, - FT_Int y_offset, - FT_Stream stream, - TT_SBit_Metrics* metrics ) - { - FT_Memory memory = stream->memory; - FT_Error error; - - - /* place stream at beginning of glyph data and read metrics */ - if ( FILE_Seek( ebdt_pos + glyph_offset ) ) - goto Exit; - - error = Load_SBit_Metrics( stream, range, metrics ); - if ( error ) - goto Exit; - - /* this function is recursive. At the top-level call, the */ - /* field map.buffer is NULL. We thus begin by finding the */ - /* dimensions of the higher-level glyph to allocate the */ - /* final pixmap buffer */ - if ( map->buffer == 0 ) - { - FT_Long size; - - - map->width = metrics->width; - map->rows = metrics->height; - - switch ( strike->bit_depth ) - { - case 1: - map->pixel_mode = ft_pixel_mode_mono; - map->pitch = ( map->width + 7 ) >> 3; - break; - - case 2: - map->pixel_mode = ft_pixel_mode_pal2; - map->pitch = ( map->width + 3 ) >> 2; - break; - - case 4: - map->pixel_mode = ft_pixel_mode_pal4; - map->pitch = ( map->width + 1 ) >> 1; - break; - - case 8: - map->pixel_mode = ft_pixel_mode_grays; - map->pitch = map->width; - break; - - default: - return TT_Err_Invalid_File_Format; - } - - size = map->rows * map->pitch; - - /* check that there is no empty image */ - if ( size == 0 ) - goto Exit; /* exit successfully! */ - - if ( ALLOC( map->buffer, size ) ) - goto Exit; - } - - switch ( range->image_format ) - { - case 1: /* single sbit image - load it */ - case 2: - case 5: - case 6: - case 7: - return Load_SBit_Single( map, x_offset, y_offset, strike->bit_depth, - range->image_format, metrics, stream ); - - case 8: /* compound format */ - FT_Skip_Stream( stream, 1L ); - /* fallthrough */ - - case 9: - break; - - default: /* invalid image format */ - return TT_Err_Invalid_File_Format; - } - - /* All right, we have a compound format. First of all, read */ - /* the array of elements. */ - { - TT_SBit_Component* components; - TT_SBit_Component* comp; - FT_UShort num_components, count; - - - if ( READ_UShort( num_components ) || - ALLOC_ARRAY( components, num_components, TT_SBit_Component ) ) - goto Exit; - - count = num_components; - - if ( ACCESS_Frame( 4L * num_components ) ) - goto Fail_Memory; - - for ( comp = components; count > 0; count--, comp++ ) - { - comp->glyph_code = GET_UShort(); - comp->x_offset = GET_Char(); - comp->y_offset = GET_Char(); - } - - FORGET_Frame(); - - /* Now recursively load each element glyph */ - count = num_components; - comp = components; - for ( ; count > 0; count--, comp++ ) - { - TT_SBit_Range* elem_range; - TT_SBit_Metrics elem_metrics; - FT_ULong elem_offset; - - - /* find the range for this element */ - error = Find_SBit_Range( comp->glyph_code, - strike, - &elem_range, - &elem_offset ); - if ( error ) - goto Fail_Memory; - - /* now load the element, recursively */ - error = Load_SBit_Image( strike, - elem_range, - ebdt_pos, - elem_offset, - map, - x_offset + comp->x_offset, - y_offset + comp->y_offset, - stream, - &elem_metrics ); - if ( error ) - goto Fail_Memory; - } - - Fail_Memory: - FREE( components ); - } - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_SBit_Image */ - /* */ - /* */ - /* Loads a given glyph sbit image from the font resource. This also */ - /* returns its metrics. */ - /* */ - /* */ - /* face :: The target face object. */ - /* */ - /* x_ppem :: The horizontal resolution in points per EM. */ - /* */ - /* y_ppem :: The vertical resolution in points per EM. */ - /* */ - /* glyph_index :: The current glyph index. */ - /* */ - /* load_flags :: The glyph load flags (the code checks for the flag */ - /* FT_LOAD_CROP_BITMAP */ - /* */ - /* stream :: The input stream. */ - /* */ - /* */ - /* map :: The target pixmap. */ - /* */ - /* metrics :: A big sbit metrics structure for the glyph image. */ - /* */ - /* */ - /* FreeType error code. 0 means success. Returns an error if no */ - /* glyph sbit exists for the index. */ - /* */ - /* */ - /* The `map.buffer' field is always freed before the glyph is loaded. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_SBit_Image( TT_Face face, - FT_Int x_ppem, - FT_Int y_ppem, - FT_UInt glyph_index, - FT_UInt load_flags, - FT_Stream stream, - FT_Bitmap* map, - TT_SBit_Metrics* metrics ) - { - FT_Error error; - FT_Memory memory = stream->memory; - FT_ULong ebdt_pos, glyph_offset; - - TT_SBit_Strike* strike; - TT_SBit_Range* range; - - - /* Check whether there is a glyph sbit for the current index */ - error = Find_SBit_Image( face, glyph_index, x_ppem, y_ppem, - &range, &strike, &glyph_offset ); - if ( error ) - goto Exit; - - /* now, find the location of the `EBDT' table in */ - /* the font file */ - error = face->goto_table( face, TTAG_EBDT, stream, 0 ); - if ( error ) - error = face->goto_table( face, TTAG_bdat, stream, 0 ); - if (error) - goto Exit; - - ebdt_pos = FILE_Pos(); - - /* clear the bitmap & load the bitmap */ - if ( face->root.glyph->flags & ft_glyph_own_bitmap ) - FREE( map->buffer ); - - map->rows = map->pitch = map->width = 0; - - error = Load_SBit_Image( strike, range, ebdt_pos, glyph_offset, - map, 0, 0, stream, metrics ); - if ( error ) - goto Exit; - - /* the glyph slot owns this bitmap buffer */ - face->root.glyph->flags |= ft_glyph_own_bitmap; - - /* setup vertical metrics if needed */ - if ( strike->flags & 1 ) - { - /* in case of a horizontal strike only */ - FT_Int advance; - FT_Int top; - - - advance = strike->hori.ascender - strike->hori.descender; - top = advance / 10; - - /* some heuristic values */ - - metrics->vertBearingX = -metrics->width / 2; - metrics->vertBearingY = advance / 10; - metrics->vertAdvance = advance * 12 / 10; - } - - /* Crop the bitmap now, unless specified otherwise */ - if ( load_flags & FT_LOAD_CROP_BITMAP ) - Crop_Bitmap( map, metrics ); - - Exit: - return error; - } - - -/* END */ diff --git a/src/freetype/sfnt/ttsbit.h b/src/freetype/sfnt/ttsbit.h deleted file mode 100644 index e77de53872..0000000000 --- a/src/freetype/sfnt/ttsbit.h +++ /dev/null @@ -1,65 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttsbit.h */ -/* */ -/* TrueType and OpenType embedded bitmap support (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifndef TTSBIT_H -#define TTSBIT_H - - -#ifdef FT_FLAT_COMPILE - -#include "ttload.h" - -#else - -#include - -#endif - - -#ifdef __cplusplus - extern "C" { -#endif - - - LOCAL_DEF - FT_Error TT_Load_SBit_Strikes( TT_Face face, - FT_Stream stream ); - - LOCAL_DEF - void TT_Free_SBit_Strikes( TT_Face face ); - - LOCAL_DEF - FT_Error TT_Load_SBit_Image( TT_Face face, - FT_Int x_ppem, - FT_Int y_ppem, - FT_UInt glyph_index, - FT_UInt load_flags, - FT_Stream stream, - FT_Bitmap* map, - TT_SBit_Metrics* metrics ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* TTSBIT_H */ - - -/* END */ diff --git a/src/freetype/smooth/ftgrays.c b/src/freetype/smooth/ftgrays.c deleted file mode 100644 index 7ed0838850..0000000000 --- a/src/freetype/smooth/ftgrays.c +++ /dev/null @@ -1,1969 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftgrays.c */ -/* */ -/* A new `perfect' anti-aliasing renderer (body). */ -/* */ -/* Copyright 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. */ -/* */ -/***************************************************************************/ - - /*************************************************************************/ - /* */ - /* This file can be compiled without the rest of the FreeType engine, */ - /* by defining the _STANDALONE_ macro when compiling it. You also need */ - /* to put the files `ftgrays.h' and `ftimage.h' into the current */ - /* compilation directory. Typically, you could do something like */ - /* */ - /* - copy `src/base/ftgrays.c' to your current directory */ - /* */ - /* - copy `include/freetype/ftimage.h' and */ - /* `include/freetype/ftgrays.h' to the same directory */ - /* */ - /* - compile `ftgrays' with the _STANDALONE_ macro defined, as in */ - /* */ - /* cc -c -D_STANDALONE_ ftgrays.c */ - /* */ - /* The renderer can be initialized with a call to */ - /* `ft_grays_raster.grays_raster_new'; an anti-aliased bitmap can be */ - /* generated with a call to `ft_grays_raster.grays_raster_render'. */ - /* */ - /* See the comments and documentation in the file `ftimage.h' for */ - /* more details on how the raster works. */ - /* */ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* This is a new anti-aliasing scan-converter for FreeType 2. The */ - /* algorithm used here is _very_ different from the one in the standard */ - /* `ftraster' module. Actually, `ftgrays' computes the _exact_ */ - /* coverage of the outline on each pixel cell. */ - /* */ - /* It is based on ideas that I initially found in Raph Levien's */ - /* excellent LibArt graphics library (see http://www.levien.com/libart */ - /* for more information, though the web pages do not tell anything */ - /* about the renderer; you'll have to dive into the source code to */ - /* understand how it works). */ - /* */ - /* Note, however, that this is a _very_ different implementation */ - /* compared to Raph's. Coverage information is stored in a very */ - /* different way, and I don't use sorted vector paths. Also, it */ - /* doesn't use floating point values. */ - /* */ - /* This renderer has the following advantages: */ - /* */ - /* - It doesn't need an intermediate bitmap. Instead, one can supply */ - /* a callback function that will be called by the renderer to draw */ - /* gray spans on any target surface. You can thus do direct */ - /* composition on any kind of bitmap, provided that you give the */ - /* renderer the right callback. */ - /* */ - /* - A perfect anti-aliaser, i.e., it computes the _exact_ coverage on */ - /* each pixel cell */ - /* */ - /* - It performs a single pass on the outline (the `standard' FT2 */ - /* renderer makes two passes). */ - /* */ - /* - It can easily be modified to render to _any_ number of gray levels */ - /* cheaply. */ - /* */ - /* - For small (< 20) pixel sizes, it is faster than the standard */ - /* renderer. */ - /* */ - /*************************************************************************/ - - -#include /* for memcpy() */ - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_aaraster - - -#ifdef _STANDALONE_ - - -#define ErrRaster_Invalid_Mode -2 -#define ErrRaster_Invalid_Outline -1 - -#include "ftimage.h" -#include "ftgrays.h" - - /* This macro is used to indicate that a function parameter is unused. */ - /* Its purpose is simply to reduce compiler warnings. Note also that */ - /* simply defining it as `(void)x' doesn't avoid warnings with certain */ - /* ANSI compilers (e.g. LCC). */ -#define FT_UNUSED( x ) (x) = (x) - - /* Disable the tracing mechanism for simplicity -- developers can */ - /* activate it easily by redefining these two macros. */ -#ifndef FT_ERROR -#define FT_ERROR( x ) do ; while ( 0 ) /* nothing */ -#endif - -#ifndef FT_TRACE -#define FT_TRACE( x ) do ; while ( 0 ) /* nothing */ -#endif - - -#else /* _STANDALONE_ */ - - -#ifdef FT_FLAT_COMPILE - -#include "ftgrays.h" - -#else - -#include - -#endif - - -#include /* for FT_UNUSED() */ -#include /* for FT_TRACE() and FT_ERROR() */ -#include /* for FT_Outline_Decompose() */ - -#define ErrRaster_Invalid_Mode FT_Err_Cannot_Render_Glyph -#define ErrRaster_Invalid_Outline FT_Err_Invalid_Outline - - -#endif /* _STANDALONE_ */ - - - /* define this to dump debugging information */ -#define xxxDEBUG_GRAYS - - /* as usual, for the speed hungry :-) */ - -#ifndef FT_STATIC_RASTER - - -#define RAS_ARG PRaster raster -#define RAS_ARG_ PRaster raster, - -#define RAS_VAR raster -#define RAS_VAR_ raster, - -#define ras (*raster) - - -#else /* FT_STATIC_RASTER */ - - -#define RAS_ARG /* empty */ -#define RAS_ARG_ /* empty */ -#define RAS_VAR /* empty */ -#define RAS_VAR_ /* empty */ - - static TRaster ras; - - -#endif /* FT_STATIC_RASTER */ - - - /* must be at least 6 bits! */ -#define PIXEL_BITS 8 - -#define ONE_PIXEL ( 1L << PIXEL_BITS ) -#define PIXEL_MASK ( -1L << PIXEL_BITS ) -#define TRUNC( x ) ( (x) >> PIXEL_BITS ) -#define SUBPIXELS( x ) ( (x) << PIXEL_BITS ) -#define FLOOR( x ) ( (x) & -ONE_PIXEL ) -#define CEILING( x ) ( ( (x) + ONE_PIXEL - 1 ) & -ONE_PIXEL ) -#define ROUND( x ) ( ( (x) + ONE_PIXEL / 2 ) & -ONE_PIXEL ) - -#if PIXEL_BITS >= 6 -#define UPSCALE( x ) ( (x) << ( PIXEL_BITS - 6 ) ) -#define DOWNSCALE( x ) ( (x) >> ( PIXEL_BITS - 6 ) ) -#else -#define UPSCALE( x ) ( (x) >> ( 6 - PIXEL_BITS ) ) -#define DOWNSCALE( x ) ( (x) << ( 6 - PIXEL_BITS ) ) -#endif - - /* Define this if you want to use a more compact storage scheme. This */ - /* increases the number of cells available in the render pool but slows */ - /* down the rendering a bit. It is useful if you have a really tiny */ - /* render pool. */ -#define xxxGRAYS_COMPACT - - - /*************************************************************************/ - /* */ - /* TYPE DEFINITIONS */ - /* */ - typedef int TScan; /* integer scanline/pixel coordinate */ - typedef long TPos; /* sub-pixel coordinate */ - - /* maximal number of gray spans in a call to the span callback */ -#define FT_MAX_GRAY_SPANS 32 - - -#ifdef GRAYS_COMPACT - - typedef struct TCell_ - { - short x : 14; - short y : 14; - int cover : PIXEL_BITS + 2; - int area : PIXEL_BITS * 2 + 2; - - } TCell, *PCell; - -#else /* GRAYS_COMPACT */ - - typedef struct TCell_ - { - TScan x; - TScan y; - int cover; - int area; - - } TCell, *PCell; - -#endif /* GRAYS_COMPACT */ - - - typedef struct TRaster_ - { - PCell cells; - int max_cells; - int num_cells; - - TScan min_ex, max_ex; - TScan min_ey, max_ey; - - int area; - int cover; - int invalid; - - TScan ex, ey; - TScan cx, cy; - TPos x, y; - - TScan last_ey; - - FT_Vector bez_stack[32 * 3]; - int lev_stack[32]; - - FT_Outline outline; - FT_Bitmap target; - - FT_Span gray_spans[FT_MAX_GRAY_SPANS]; - int num_gray_spans; - - FT_Raster_Span_Func render_span; - void* render_span_data; - int span_y; - - int band_size; - int band_shoot; - int conic_level; - int cubic_level; - - void* memory; - - } TRaster, *PRaster; - - - /*************************************************************************/ - /* */ - /* Initialize the cells table. */ - /* */ - static - void init_cells( RAS_ARG_ void* buffer, - long byte_size ) - { - ras.cells = (PCell)buffer; - ras.max_cells = byte_size / sizeof ( TCell ); - ras.num_cells = 0; - ras.area = 0; - ras.cover = 0; - ras.invalid = 1; - } - - - /*************************************************************************/ - /* */ - /* Compute the outline bounding box. */ - /* */ - static - void compute_cbox( RAS_ARG_ FT_Outline* outline ) - { - FT_Vector* vec = outline->points; - FT_Vector* limit = vec + outline->n_points; - - - if ( outline->n_points <= 0 ) - { - ras.min_ex = ras.max_ex = 0; - ras.min_ey = ras.max_ey = 0; - return; - } - - ras.min_ex = ras.max_ex = vec->x; - ras.min_ey = ras.max_ey = vec->y; - - vec++; - - for ( ; vec < limit; vec++ ) - { - TPos x = vec->x; - TPos y = vec->y; - - - if ( x < ras.min_ex ) ras.min_ex = x; - if ( x > ras.max_ex ) ras.max_ex = x; - if ( y < ras.min_ey ) ras.min_ey = y; - if ( y > ras.max_ey ) ras.max_ey = y; - } - - /* truncate the bounding box to integer pixels */ - ras.min_ex = ras.min_ex >> 6; - ras.min_ey = ras.min_ey >> 6; - ras.max_ex = ( ras.max_ex + 63 ) >> 6; - ras.max_ey = ( ras.max_ey + 63 ) >> 6; - } - - - /*************************************************************************/ - /* */ - /* Record the current cell in the table. */ - /* */ - static - int record_cell( RAS_ARG ) - { - PCell cell; - - - if ( !ras.invalid && ( ras.area | ras.cover ) ) - { - if ( ras.num_cells >= ras.max_cells ) - return 1; - - cell = ras.cells + ras.num_cells++; - cell->x = ras.ex - ras.min_ex; - cell->y = ras.ey - ras.min_ey; - cell->area = ras.area; - cell->cover = ras.cover; - } - - return 0; - } - - - /*************************************************************************/ - /* */ - /* Set the current cell to a new position. */ - /* */ - static - int set_cell( RAS_ARG_ TScan ex, - TScan ey ) - { - int invalid, record, clean; - - - /* Move the cell pointer to a new position. We set the `invalid' */ - /* flag to indicate that the cell isn't part of those we're interested */ - /* in during the render phase. This means that: */ - /* */ - /* . the new vertical position must be within min_ey..max_ey-1. */ - /* . the new horizontal position must be strictly less than max_ex */ - /* */ - /* Note that if a cell is to the left of the clipping region, it is */ - /* actually set to the (min_ex-1) horizontal position. */ - - record = 0; - clean = 1; - - invalid = ( ey < ras.min_ey || ey >= ras.max_ey || ex >= ras.max_ex ); - if ( !invalid ) - { - /* All cells that are on the left of the clipping region go to the */ - /* min_ex - 1 horizontal position. */ - if ( ex < ras.min_ex ) - ex = ras.min_ex - 1; - - /* if our position is new, then record the previous cell */ - if ( ex != ras.ex || ey != ras.ey ) - record = 1; - else - clean = ras.invalid; /* do not clean if we didn't move from */ - /* a valid cell */ - } - - /* record the previous cell if needed (i.e., if we changed the cell */ - /* position, of changed the `invalid' flag) */ - if ( ( ras.invalid != invalid || record ) && record_cell( RAS_VAR ) ) - return 1; - - if ( clean ) - { - ras.area = 0; - ras.cover = 0; - } - - ras.invalid = invalid; - ras.ex = ex; - ras.ey = ey; - return 0; - } - - - /*************************************************************************/ - /* */ - /* Start a new contour at a given cell. */ - /* */ - static - void start_cell( RAS_ARG_ TScan ex, - TScan ey ) - { - if ( ex < ras.min_ex ) - ex = ras.min_ex - 1; - - ras.area = 0; - ras.cover = 0; - ras.ex = ex; - ras.ey = ey; - ras.last_ey = SUBPIXELS( ey ); - ras.invalid = 0; - - (void)set_cell( RAS_VAR_ ex, ey ); - } - - - /*************************************************************************/ - /* */ - /* Render a scanline as one or more cells. */ - /* */ - static - int render_scanline( RAS_ARG_ TScan ey, - TPos x1, - TScan y1, - TPos x2, - TScan y2 ) - { - TScan ex1, ex2, fx1, fx2, delta; - long p, first, dx; - int incr, lift, mod, rem; - - - dx = x2 - x1; - - ex1 = TRUNC( x1 ); /* if (ex1 >= ras.max_ex) ex1 = ras.max_ex-1; */ - ex2 = TRUNC( x2 ); /* if (ex2 >= ras.max_ex) ex2 = ras.max_ex-1; */ - fx1 = x1 - SUBPIXELS( ex1 ); - fx2 = x2 - SUBPIXELS( ex2 ); - - /* trivial case. Happens often */ - if ( y1 == y2 ) - return set_cell( RAS_VAR_ ex2, ey ); - - /* everything is located in a single cell. That is easy! */ - /* */ - if ( ex1 == ex2 ) - { - delta = y2 - y1; - ras.area += ( fx1 + fx2 ) * delta; - ras.cover += delta; - return 0; - } - - /* ok, we'll have to render a run of adjacent cells on the same */ - /* scanline... */ - /* */ - p = ( ONE_PIXEL - fx1 ) * ( y2 - y1 ); - first = ONE_PIXEL; - incr = 1; - - if ( dx < 0 ) - { - p = fx1 * ( y2 - y1 ); - first = 0; - incr = -1; - dx = -dx; - } - - delta = p / dx; - mod = p % dx; - if ( mod < 0 ) - { - delta--; - mod += dx; - } - - ras.area += ( fx1 + first ) * delta; - ras.cover += delta; - - ex1 += incr; - if ( set_cell( RAS_VAR_ ex1, ey ) ) - goto Error; - y1 += delta; - - if ( ex1 != ex2 ) - { - p = ONE_PIXEL * ( y2 - y1 ); - lift = p / dx; - rem = p % dx; - if ( rem < 0 ) - { - lift--; - rem += dx; - } - - mod -= dx; - - while ( ex1 != ex2 ) - { - delta = lift; - mod += rem; - if ( mod >= 0 ) - { - mod -= dx; - delta++; - } - - ras.area += ONE_PIXEL * delta; - ras.cover += delta; - y1 += delta; - ex1 += incr; - if ( set_cell( RAS_VAR_ ex1, ey ) ) - goto Error; - } - } - - delta = y2 - y1; - ras.area += ( fx2 + ONE_PIXEL - first ) * delta; - ras.cover += delta; - - return 0; - - Error: - return 1; - } - - - /*************************************************************************/ - /* */ - /* Render a given line as a series of scanlines. */ - /* */ - static - int render_line( RAS_ARG_ TPos to_x, - TPos to_y ) - { - TScan ey1, ey2, fy1, fy2; - TPos dx, dy, x, x2; - int p, rem, mod, lift, delta, first, incr; - - - ey1 = TRUNC( ras.last_ey ); - ey2 = TRUNC( to_y ); /* if (ey2 >= ras.max_ey) ey2 = ras.max_ey-1; */ - fy1 = ras.y - ras.last_ey; - fy2 = to_y - SUBPIXELS( ey2 ); - - dx = to_x - ras.x; - dy = to_y - ras.y; - - /* XXX: we should do something about the trivial case where dx == 0, */ - /* as it happens very often! */ - - /* perform vertical clipping */ - { - TScan min, max; - - - min = ey1; - max = ey2; - if ( ey1 > ey2 ) - { - min = ey2; - max = ey1; - } - if ( min >= ras.max_ey || max < ras.min_ey ) - goto End; - } - - /* everything is on a single scanline */ - if ( ey1 == ey2 ) - { - if ( render_scanline( RAS_VAR_ ey1, ras.x, fy1, to_x, fy2 ) ) - goto Error; - goto End; - } - - /* ok, we have to render several scanlines */ - p = ( ONE_PIXEL - fy1 ) * dx; - first = ONE_PIXEL; - incr = 1; - - if ( dy < 0 ) - { - p = fy1 * dx; - first = 0; - incr = -1; - dy = -dy; - } - - delta = p / dy; - mod = p % dy; - if ( mod < 0 ) - { - delta--; - mod += dy; - } - - x = ras.x + delta; - if ( render_scanline( RAS_VAR_ ey1, ras.x, fy1, x, first ) ) - goto Error; - - ey1 += incr; - if ( set_cell( RAS_VAR_ TRUNC( x ), ey1 ) ) - goto Error; - - if ( ey1 != ey2 ) - { - p = ONE_PIXEL * dx; - lift = p / dy; - rem = p % dy; - if ( rem < 0 ) - { - lift--; - rem += dy; - } - mod -= dy; - - while ( ey1 != ey2 ) - { - delta = lift; - mod += rem; - if ( mod >= 0 ) - { - mod -= dy; - delta++; - } - - x2 = x + delta; - if ( render_scanline( RAS_VAR_ ey1, - x, ONE_PIXEL - first, x2, first ) ) - goto Error; - x = x2; - ey1 += incr; - if ( set_cell( RAS_VAR_ TRUNC( x ), ey1 ) ) - goto Error; - } - } - - if ( render_scanline( RAS_VAR_ ey1, - x, ONE_PIXEL - first, to_x, fy2 ) ) - goto Error; - - End: - ras.x = to_x; - ras.y = to_y; - ras.last_ey = SUBPIXELS( ey2 ); - - return 0; - - Error: - return 1; - } - - - static - void split_conic( FT_Vector* base ) - { - TPos a, b; - - - base[4].x = base[2].x; - b = base[1].x; - a = base[3].x = ( base[2].x + b ) / 2; - b = base[1].x = ( base[0].x + b ) / 2; - base[2].x = ( a + b ) / 2; - - base[4].y = base[2].y; - b = base[1].y; - a = base[3].y = ( base[2].y + b ) / 2; - b = base[1].y = ( base[0].y + b ) / 2; - base[2].y = ( a + b ) / 2; - } - - - static - int render_conic( RAS_ARG_ FT_Vector* control, - FT_Vector* to ) - { - TPos dx, dy; - int top, level; - int* levels; - FT_Vector* arc; - - - dx = DOWNSCALE( ras.x ) + to->x - ( control->x << 1 ); - if ( dx < 0 ) - dx = -dx; - dy = DOWNSCALE( ras.y ) + to->y - ( control->y << 1 ); - if ( dy < 0 ) - dy = -dy; - if ( dx < dy ) - dx = dy; - - level = 1; - dx = dx / ras.conic_level; - while ( dx > 0 ) - { - dx >>= 1; - level++; - } - - /* a shortcut to speed things up */ - if ( level <= 1 ) - { - /* we compute the mid-point directly in order to avoid */ - /* calling split_conic() */ - TPos to_x, to_y, mid_x, mid_y; - - - to_x = UPSCALE( to->x ); - to_y = UPSCALE( to->y ); - mid_x = ( ras.x + to_x + 2 * UPSCALE( control->x ) ) / 4; - mid_y = ( ras.y + to_y + 2 * UPSCALE( control->y ) ) / 4; - - return render_line( RAS_VAR_ mid_x, mid_y ) || - render_line( RAS_VAR_ to_x, to_y ); - } - - arc = ras.bez_stack; - levels = ras.lev_stack; - top = 0; - levels[0] = level; - - arc[0].x = UPSCALE( to->x ); - arc[0].y = UPSCALE( to->y ); - arc[1].x = UPSCALE( control->x ); - arc[1].y = UPSCALE( control->y ); - arc[2].x = ras.x; - arc[2].y = ras.y; - - while ( top >= 0 ) - { - level = levels[top]; - if ( level > 1 ) - { - /* check that the arc crosses the current band */ - TPos min, max, y; - - - min = max = arc[0].y; - - y = arc[1].y; - if ( y < min ) min = y; - if ( y > max ) max = y; - - y = arc[2].y; - if ( y < min ) min = y; - if ( y > max ) max = y; - - if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < 0 ) - goto Draw; - - split_conic( arc ); - arc += 2; - top++; - levels[top] = levels[top - 1] = level - 1; - continue; - } - - Draw: - { - TPos to_x, to_y, mid_x, mid_y; - - - to_x = arc[0].x; - to_y = arc[0].y; - mid_x = ( ras.x + to_x + 2 * arc[1].x ) / 4; - mid_y = ( ras.y + to_y + 2 * arc[1].y ) / 4; - - if ( render_line( RAS_VAR_ mid_x, mid_y ) || - render_line( RAS_VAR_ to_x, to_y ) ) - return 1; - - top--; - arc -= 2; - } - } - return 0; - } - - - static - void split_cubic( FT_Vector* base ) - { - TPos a, b, c, d; - - - base[6].x = base[3].x; - c = base[1].x; - d = base[2].x; - base[1].x = a = ( base[0].x + c ) / 2; - base[5].x = b = ( base[3].x + d ) / 2; - c = ( c + d ) / 2; - base[2].x = a = ( a + c ) / 2; - base[4].x = b = ( b + c ) / 2; - base[3].x = ( a + b ) / 2; - - base[6].y = base[3].y; - c = base[1].y; - d = base[2].y; - base[1].y = a = ( base[0].y + c ) / 2; - base[5].y = b = ( base[3].y + d ) / 2; - c = ( c + d ) / 2; - base[2].y = a = ( a + c ) / 2; - base[4].y = b = ( b + c ) / 2; - base[3].y = ( a + b ) / 2; - } - - - static - int render_cubic( RAS_ARG_ FT_Vector* control1, - FT_Vector* control2, - FT_Vector* to ) - { - TPos dx, dy, da, db; - int top, level; - int* levels; - FT_Vector* arc; - - - dx = DOWNSCALE( ras.x ) + to->x - ( control1->x << 1 ); - if ( dx < 0 ) - dx = -dx; - dy = DOWNSCALE( ras.y ) + to->y - ( control1->y << 1 ); - if ( dy < 0 ) - dy = -dy; - if ( dx < dy ) - dx = dy; - da = dx; - - dx = DOWNSCALE( ras.x ) + to->x - 3 * ( control1->x + control2->x ); - if ( dx < 0 ) - dx = -dx; - dy = DOWNSCALE( ras.y ) + to->y - 3 * ( control1->x + control2->y ); - if ( dy < 0 ) - dy = -dy; - if ( dx < dy ) - dx = dy; - db = dx; - - level = 1; - da = da / ras.cubic_level; - db = db / ras.conic_level; - while ( da > 0 || db > 0 ) - { - da >>= 1; - db >>= 2; - level++; - } - - if ( level <= 1 ) - { - TPos to_x, to_y, mid_x, mid_y; - - - to_x = UPSCALE( to->x ); - to_y = UPSCALE( to->y ); - mid_x = ( ras.x + to_x + - 3 * UPSCALE( control1->x + control2->x ) ) / 8; - mid_y = ( ras.y + to_y + - 3 * UPSCALE( control1->y + control2->y ) ) / 8; - - return render_line( RAS_VAR_ mid_x, mid_y ) || - render_line( RAS_VAR_ to_x, to_y ); - } - - arc = ras.bez_stack; - arc[0].x = UPSCALE( to->x ); - arc[0].y = UPSCALE( to->y ); - arc[1].x = UPSCALE( control2->x ); - arc[1].y = UPSCALE( control2->y ); - arc[2].x = UPSCALE( control1->x ); - arc[2].y = UPSCALE( control1->y ); - arc[3].x = ras.x; - arc[3].y = ras.y; - - levels = ras.lev_stack; - top = 0; - levels[0] = level; - - while ( top >= 0 ) - { - level = levels[top]; - if ( level > 1 ) - { - /* check that the arc crosses the current band */ - TPos min, max, y; - - - min = max = arc[0].y; - y = arc[1].y; - if ( y < min ) min = y; - if ( y > max ) max = y; - y = arc[2].y; - if ( y < min ) min = y; - if ( y > max ) max = y; - y = arc[3].y; - if ( y < min ) min = y; - if ( y > max ) max = y; - if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < 0 ) - goto Draw; - split_cubic( arc ); - arc += 3; - top ++; - levels[top] = levels[top - 1] = level - 1; - continue; - } - - Draw: - { - TPos to_x, to_y, mid_x, mid_y; - - - to_x = arc[0].x; - to_y = arc[0].y; - mid_x = ( ras.x + to_x + 3 * ( arc[1].x + arc[2].x ) ) / 8; - mid_y = ( ras.y + to_y + 3 * ( arc[1].y + arc[2].y ) ) / 8; - - if ( render_line( RAS_VAR_ mid_x, mid_y ) || - render_line( RAS_VAR_ to_x, to_y ) ) - return 1; - top --; - arc -= 3; - } - } - return 0; - } - - - /* a macro comparing two cell pointers. Returns true if a <= b. */ -#if 1 - -#define PACK( a ) ( ( (long)(a)->y << 16 ) + (a)->x ) -#define LESS_THAN( a, b ) ( PACK( a ) < PACK( b ) ) - -#else /* 1 */ - -#define LESS_THAN( a, b ) ( (a)->y < (b)->y || \ - ( (a)->y == (b)->y && (a)->x < (b)->x ) ) - -#endif /* 1 */ - -#define SWAP_CELLS( a, b, temp ) do \ - { \ - temp = *(a); \ - *(a) = *(b); \ - *(b) = temp; \ - } while ( 0 ) -#define DEBUG_SORT -#define QUICK_SORT - -#ifdef SHELL_SORT - - /* a simple shell sort algorithm that works directly on our */ - /* cells table */ - static - void shell_sort ( PCell cells, - int count ) - { - PCell i, j, limit = cells + count; - TCell temp; - int gap; - - - /* compute initial gap */ - for ( gap = 0; ++gap < count; gap *= 3 ) - ; - - while ( gap /= 3 ) - { - for ( i = cells + gap; i < limit; i++ ) - { - for ( j = i - gap; ; j -= gap ) - { - PCell k = j + gap; - - - if ( LESS_THAN( j, k ) ) - break; - - SWAP_CELLS( j, k, temp ); - - if ( j < cells + gap ) - break; - } - } - } - } - -#endif /* SHELL_SORT */ - - -#ifdef QUICK_SORT - - /* This is a non-recursive quicksort that directly process our cells */ - /* array. It should be faster than calling the stdlib qsort(), and we */ - /* can even tailor our insertion threshold... */ - -#define QSORT_THRESHOLD 9 /* below this size, a sub-array will be sorted */ - /* through a normal insertion sort */ - - static - void quick_sort( PCell cells, - int count ) - { - PCell stack[40]; /* should be enough ;-) */ - PCell* top; /* top of stack */ - PCell base, limit; - TCell temp; - - - limit = cells + count; - base = cells; - top = stack; - - for (;;) - { - int len = limit - base; - PCell i, j, pivot; - - - if ( len > QSORT_THRESHOLD ) - { - /* we use base + len/2 as the pivot */ - pivot = base + len / 2; - SWAP_CELLS( base, pivot, temp ); - - i = base + 1; - j = limit - 1; - - /* now ensure that *i <= *base <= *j */ - if ( LESS_THAN( j, i ) ) - SWAP_CELLS( i, j, temp ); - - if ( LESS_THAN( base, i ) ) - SWAP_CELLS( base, i, temp ); - - if ( LESS_THAN( j, base ) ) - SWAP_CELLS( base, j, temp ); - - for (;;) - { - do i++; while ( LESS_THAN( i, base ) ); - do j--; while ( LESS_THAN( base, j ) ); - - if ( i > j ) - break; - - SWAP_CELLS( i, j, temp ); - } - - SWAP_CELLS( base, j, temp ); - - /* now, push the largest sub-array */ - if ( j - base > limit - i ) - { - top[0] = base; - top[1] = j; - base = i; - } - else - { - top[0] = i; - top[1] = limit; - limit = j; - } - top += 2; - } - else - { - /* the sub-array is small, perform insertion sort */ - j = base; - i = j + 1; - - for ( ; i < limit; j = i, i++ ) - { - for ( ; LESS_THAN( j + 1, j ); j-- ) - { - SWAP_CELLS( j + 1, j, temp ); - if ( j == base ) - break; - } - } - if ( top > stack ) - { - top -= 2; - base = top[0]; - limit = top[1]; - } - else - break; - } - } - } - -#endif /* QUICK_SORT */ - - -#ifdef DEBUG_GRAYS -#ifdef DEBUG_SORT - - static - int check_sort( PCell cells, - int count ) - { - PCell p, q; - - - for ( p = cells + count - 2; p >= cells; p-- ) - { - q = p + 1; - if ( !LESS_THAN( p, q ) ) - return 0; - } - return 1; - } - -#endif /* DEBUG_SORT */ -#endif /* DEBUG_GRAYS */ - - - static - int Move_To( FT_Vector* to, - FT_Raster raster ) - { - TPos x, y; - - - /* record current cell, if any */ - record_cell( (PRaster)raster ); - - /* start to a new position */ - x = UPSCALE( to->x ); - y = UPSCALE( to->y ); - start_cell( (PRaster)raster, TRUNC( x ), TRUNC( y ) ); - ((PRaster)raster)->x = x; - ((PRaster)raster)->y = y; - return 0; - } - - - static - int Line_To( FT_Vector* to, - FT_Raster raster ) - { - return render_line( (PRaster)raster, - UPSCALE( to->x ), UPSCALE( to->y ) ); - } - - - static - int Conic_To( FT_Vector* control, - FT_Vector* to, - FT_Raster raster ) - { - return render_conic( (PRaster)raster, control, to ); - } - - - static - int Cubic_To( FT_Vector* control1, - FT_Vector* control2, - FT_Vector* to, - FT_Raster raster ) - { - return render_cubic( (PRaster)raster, control1, control2, to ); - } - - - static - void grays_render_span( int y, - int count, - FT_Span* spans, - PRaster raster ) - { - unsigned char* p; - FT_Bitmap* map = &raster->target; - - - /* first of all, compute the scanline offset */ - p = (unsigned char*)map->buffer - y * map->pitch; - if ( map->pitch >= 0 ) - p += ( map->rows - 1 ) * map->pitch; - - for ( ; count > 0; count--, spans++ ) - { - if ( spans->coverage ) -#if 1 - memset( p + spans->x, (unsigned char)spans->coverage, spans->len ); -#else /* 1 */ - { - q = p + spans->x; - limit = q + spans->len; - for ( ; q < limit; q++ ) - q[0] = (unsigned char)spans->coverage; - } -#endif /* 1 */ - } - } - - -#ifdef DEBUG_GRAYS - -#include - - static - void dump_cells( RAS_ARG ) - { - PCell cell, limit; - int y = -1; - - - cell = ras.cells; - limit = cell + ras.num_cells; - - for ( ; cell < limit; cell++ ) - { - if ( cell->y != y ) - { - fprintf( stderr, "\n%2d: ", cell->y ); - y = cell->y; - } - fprintf( stderr, "[%d %d %d]", - cell->x, cell->area, cell->cover ); - } - fprintf(stderr, "\n" ); - } - -#endif /* DEBUG_GRAYS */ - - - static - void grays_hline( RAS_ARG_ TScan x, - TScan y, - TPos area, - int acount ) - { - FT_Span* span; - int count; - int coverage; - - - /* compute the coverage line's coverage, depending on the */ - /* outline fill rule */ - /* */ - /* the coverage percentage is area/(PIXEL_BITS*PIXEL_BITS*2) */ - /* */ - coverage = area >> ( PIXEL_BITS * 2 + 1 - 8); /* use range 0..256 */ - - if ( ras.outline.flags & ft_outline_even_odd_fill ) - { - if ( coverage < 0 ) - coverage = -coverage; - - while ( coverage >= 512 ) - coverage -= 512; - - if ( coverage > 256 ) - coverage = 512 - coverage; - else if ( coverage == 256 ) - coverage = 255; - } - else - { - /* normal non-zero winding rule */ - if ( coverage < 0 ) - coverage = -coverage; - - if ( coverage >= 256 ) - coverage = 255; - } - - y += ras.min_ey; - x += ras.min_ex; - - if ( coverage ) - { - /* see if we can add this span to the current list */ - count = ras.num_gray_spans; - span = ras.gray_spans + count - 1; - if ( count > 0 && - ras.span_y == y && - (int)span->x + span->len == (int)x && - span->coverage == coverage ) - { - span->len += acount; - return; - } - - if ( ras.span_y != y || count >= FT_MAX_GRAY_SPANS ) - { - if ( ras.render_span ) - ras.render_span( ras.span_y, count, ras.gray_spans, - ras.render_span_data ); - /* ras.render_span( span->y, ras.gray_spans, count ); */ - -#ifdef DEBUG_GRAYS - - if ( ras.span_y >= 0 ) - { - int n; - - - fprintf( stderr, "y=%3d ", ras.span_y ); - span = ras.gray_spans; - for ( n = 0; n < count; n++, span++ ) - fprintf( stderr, "[%d..%d]:%02x ", - span->x, span->x + span->len - 1, span->coverage ); - fprintf( stderr, "\n" ); - } - -#endif /* DEBUG_GRAYS */ - - ras.num_gray_spans = 0; - ras.span_y = y; - - count = 0; - span = ras.gray_spans; - } - else - span++; - - /* add a gray span to the current list */ - span->x = (short)x; - span->len = (unsigned short)acount; - span->coverage = (unsigned char)coverage; - ras.num_gray_spans++; - } - } - - - static - void grays_sweep( RAS_ARG_ FT_Bitmap* target ) - { - TScan x, y, cover, area; - PCell start, cur, limit; - - FT_UNUSED( target ); - - - cur = ras.cells; - limit = cur + ras.num_cells; - - cover = 0; - ras.span_y = -1; - ras.num_gray_spans = 0; - - for (;;) - { - start = cur; - y = start->y; - x = start->x; - - area = start->area; - cover += start->cover; - - /* accumulate all start cells */ - for (;;) - { - ++cur; - if ( cur >= limit || cur->y != start->y || cur->x != start->x ) - break; - - area += cur->area; - cover += cur->cover; - } - - /* if the start cell has a non-null area, we must draw an */ - /* individual gray pixel there */ - if ( area && x >= 0 ) - { - grays_hline( RAS_VAR_ x, y, cover * ( ONE_PIXEL * 2 ) - area, 1 ); - x++; - } - - if ( x < 0 ) - x = 0; - - if ( cur < limit && start->y == cur->y ) - { - /* draw a gray span between the start cell and the current one */ - if ( cur->x > x ) - grays_hline( RAS_VAR_ x, y, - cover * ( ONE_PIXEL * 2 ), cur->x - x ); - } - else - { - /* draw a gray span until the end of the clipping region */ - if ( cover && x < ras.max_ex - ras.min_ex ) - grays_hline( RAS_VAR_ x, y, - cover * ( ONE_PIXEL * 2 ), - ras.max_ex - x - ras.min_ex ); - cover = 0; - } - - if ( cur >= limit ) - break; - } - - if ( ras.render_span && ras.num_gray_spans > 0 ) - ras.render_span( ras.span_y, ras.num_gray_spans, - ras.gray_spans, ras.render_span_data ); - -#ifdef DEBUG_GRAYS - - { - int n; - FT_Span* span; - - - fprintf( stderr, "y=%3d ", ras.span_y ); - span = ras.gray_spans; - for ( n = 0; n < ras.num_gray_spans; n++, span++ ) - fprintf( stderr, "[%d..%d]:%02x ", - span->x, span->x + span->len - 1, span->coverage ); - fprintf( stderr, "\n" ); - } - -#endif /* DEBUG_GRAYS */ - - } - - -#ifdef _STANDALONE_ - - /*************************************************************************/ - /* */ - /* The following function should only compile in stand_alone mode, */ - /* i.e., when building this component without the rest of FreeType. */ - /* */ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_Decompose */ - /* */ - /* */ - /* Walks over an outline's structure to decompose it into individual */ - /* segments and Bezier arcs. This function is also able to emit */ - /* `move to' and `close to' operations to indicate the start and end */ - /* of new contours in the outline. */ - /* */ - /* */ - /* outline :: A pointer to the source target. */ - /* */ - /* interface :: A table of `emitters', i.e,. function pointers called */ - /* during decomposition to indicate path operations. */ - /* */ - /* user :: A typeless pointer which is passed to each emitter */ - /* during the decomposition. It can be used to store */ - /* the state during the decomposition. */ - /* */ - /* */ - /* Error code. 0 means sucess. */ - /* */ - static - int FT_Outline_Decompose( FT_Outline* outline, - FT_Outline_Funcs* interface, - void* user ) - { -#undef SCALED -#define SCALED( x ) ( ( (x) << shift ) - delta ) - - FT_Vector v_last; - FT_Vector v_control; - FT_Vector v_start; - - FT_Vector* point; - FT_Vector* limit; - char* tags; - - int n; /* index of contour in outline */ - int first; /* index of first point in contour */ - int error; - char tag; /* current point's state */ - - int shift = interface->shift; - FT_Pos delta = interface->delta; - - - first = 0; - - for ( n = 0; n < outline->n_contours; n++ ) - { - int last; /* index of last point in contour */ - - - last = outline->contours[n]; - limit = outline->points + last; - - v_start = outline->points[first]; - v_last = outline->points[last]; - - v_start.x = SCALED( v_start.x ); v_start.y = SCALED( v_start.y ); - v_last.x = SCALED( v_last.x ); v_last.y = SCALED( v_last.y ); - - v_control = v_start; - - point = outline->points + first; - tags = outline->tags + first; - tag = FT_CURVE_TAG( tags[0] ); - - /* A contour cannot start with a cubic control point! */ - if ( tag == FT_Curve_Tag_Cubic ) - goto Invalid_Outline; - - /* check first point to determine origin */ - if ( tag == FT_Curve_Tag_Conic ) - { - /* first point is conic control. Yes, this happens. */ - if ( FT_CURVE_TAG( outline->tags[last] ) == FT_Curve_Tag_On ) - { - /* start at last point if it is on the curve */ - v_start = v_last; - limit--; - } - else - { - /* if both first and last points are conic, */ - /* start at their middle and record its position */ - /* for closure */ - v_start.x = ( v_start.x + v_last.x ) / 2; - v_start.y = ( v_start.y + v_last.y ) / 2; - - v_last = v_start; - } - point--; - tags--; - } - - error = interface->move_to( &v_start, user ); - if ( error ) - goto Exit; - - while ( point < limit ) - { - point++; - tags++; - - tag = FT_CURVE_TAG( tags[0] ); - switch ( tag ) - { - case FT_Curve_Tag_On: /* emit a single line_to */ - { - FT_Vector vec; - - - vec.x = SCALED( point->x ); - vec.y = SCALED( point->y ); - - error = interface->line_to( &vec, user ); - if ( error ) - goto Exit; - continue; - } - - case FT_Curve_Tag_Conic: /* consume conic arcs */ - { - v_control.x = SCALED( point->x ); - v_control.y = SCALED( point->y ); - - Do_Conic: - if ( point < limit ) - { - FT_Vector vec; - FT_Vector v_middle; - - - point++; - tags++; - tag = FT_CURVE_TAG( tags[0] ); - - vec.x = SCALED( point->x ); - vec.y = SCALED( point->y ); - - if ( tag == FT_Curve_Tag_On ) - { - error = interface->conic_to( &v_control, &vec, user ); - if ( error ) - goto Exit; - continue; - } - - if ( tag != FT_Curve_Tag_Conic ) - goto Invalid_Outline; - - v_middle.x = ( v_control.x + vec.x ) / 2; - v_middle.y = ( v_control.y + vec.y ) / 2; - - error = interface->conic_to( &v_control, &v_middle, user ); - if ( error ) - goto Exit; - - v_control = vec; - goto Do_Conic; - } - - error = interface->conic_to( &v_control, &v_start, user ); - goto Close; - } - - default: /* FT_Curve_Tag_Cubic */ - { - FT_Vector vec1, vec2; - - - if ( point + 1 > limit || - FT_CURVE_TAG( tags[1] ) != FT_Curve_Tag_Cubic ) - goto Invalid_Outline; - - point += 2; - tags += 2; - - vec1.x = SCALED( point[-2].x ); vec1.y = SCALED( point[-2].y ); - vec2.x = SCALED( point[-1].x ); vec2.y = SCALED( point[-1].y ); - - if ( point <= limit ) - { - FT_Vector vec; - - - vec.x = SCALED( point->x ); - vec.y = SCALED( point->y ); - - error = interface->cubic_to( &vec1, &vec2, &vec, user ); - if ( error ) - goto Exit; - continue; - } - - error = interface->cubic_to( &vec1, &vec2, &v_start, user ); - goto Close; - } - } - } - - /* close the contour with a line segment */ - error = interface->line_to( &v_start, user ); - - Close: - if ( error ) - goto Exit; - - first = last + 1; - } - - return 0; - - Exit: - return error; - - Invalid_Outline: - return ErrRaster_Invalid_Outline; - } - -#endif /* _STANDALONE_ */ - - - typedef struct TBand_ - { - FT_Pos min, max; - - } TBand; - - - static - int grays_convert_glyph( RAS_ARG_ FT_Outline* outline ) - { - static - FT_Outline_Funcs interface = - { - (FT_Outline_MoveTo_Func) Move_To, - (FT_Outline_LineTo_Func) Line_To, - (FT_Outline_ConicTo_Func)Conic_To, - (FT_Outline_CubicTo_Func)Cubic_To, - 0, - 0 - }; - - TBand bands[40], *band; - int n, num_bands; - TPos min, max, max_y; - - - /* Set up state in the raster object */ - compute_cbox( RAS_VAR_ outline ); - - /* clip to target bitmap, exit if nothing to do */ - if ( ras.max_ex <= 0 || ras.min_ex >= ras.target.width || - ras.max_ey <= 0 || ras.min_ey >= ras.target.rows ) - return 0; - - if ( ras.min_ex < 0 ) ras.min_ex = 0; - if ( ras.min_ey < 0 ) ras.min_ey = 0; - - if ( ras.max_ex > ras.target.width ) ras.max_ex = ras.target.width; - if ( ras.max_ey > ras.target.rows ) ras.max_ey = ras.target.rows; - - /* simple heuristic used to speed-up the bezier decomposition -- see */ - /* the code in render_conic() and render_cubic() for more details */ - ras.conic_level = 32; - ras.cubic_level = 16; - - { - int level = 0; - - - if ( ras.max_ex > 24 || ras.max_ey > 24 ) - level++; - if ( ras.max_ex > 120 || ras.max_ey > 120 ) - level += 2; - - ras.conic_level <<= level; - ras.cubic_level <<= level; - } - - /* setup vertical bands */ - num_bands = ( ras.max_ey - ras.min_ey ) / ras.band_size; - if ( num_bands == 0 ) num_bands = 1; - if ( num_bands >= 39 ) num_bands = 39; - - ras.band_shoot = 0; - - min = ras.min_ey; - max_y = ras.max_ey; - - for ( n = 0; n < num_bands; n++, min = max ) - { - max = min + ras.band_size; - if ( n == num_bands - 1 || max > max_y ) - max = max_y; - - bands[0].min = min; - bands[0].max = max; - band = bands; - - while ( band >= bands ) - { - FT_Pos bottom, top, middle; - int error; - - - ras.num_cells = 0; - ras.invalid = 1; - ras.min_ey = band->min; - ras.max_ey = band->max; - - error = FT_Outline_Decompose( outline, &interface, &ras ) || - record_cell( RAS_VAR ); - - if ( !error ) - { -#ifdef SHELL_SORT - shell_sort( ras.cells, ras.num_cells ); -#else - quick_sort( ras.cells, ras.num_cells ); -#endif - -#ifdef DEBUG_GRAYS - check_sort( ras.cells, ras.num_cells ); - dump_cells( RAS_VAR ); -#endif - - grays_sweep( RAS_VAR_ &ras.target ); - band--; - continue; - } - - /* render pool overflow, we will reduce the render band by half */ - bottom = band->min; - top = band->max; - middle = bottom + ( ( top - bottom ) >> 1 ); - - /* waoow! This is too complex for a single scanline, something */ - /* must be really rotten here! */ - if ( middle == bottom ) - { -#ifdef DEBUG_GRAYS - fprintf( stderr, "Rotten glyph!\n" ); -#endif - return 1; - } - - if ( bottom-top >= ras.band_size ) - ras.band_shoot++; - - band[1].min = bottom; - band[1].max = middle; - band[0].min = middle; - band[0].max = top; - band++; - } - } - - if ( ras.band_shoot > 8 && ras.band_size > 16 ) - ras.band_size = ras.band_size / 2; - - return 0; - } - - - extern - int grays_raster_render( PRaster raster, - FT_Raster_Params* params ) - { - FT_Outline* outline = (FT_Outline*)params->source; - FT_Bitmap* target_map = params->target; - - - if ( !raster || !raster->cells || !raster->max_cells ) - return -1; - - /* return immediately if the outline is empty */ - if ( outline->n_points == 0 || outline->n_contours <= 0 ) - return 0; - - if ( !outline || !outline->contours || !outline->points ) - return ErrRaster_Invalid_Outline; - - if ( outline->n_points != - outline->contours[outline->n_contours - 1] + 1 ) - return ErrRaster_Invalid_Outline; - - if ( !target_map || !target_map->buffer ) - return -1; - - /* XXX: this version does not support monochrome rendering yet! */ - if ( !(params->flags & ft_raster_flag_aa) ) - return ErrRaster_Invalid_Mode; - - ras.outline = *outline; - ras.target = *target_map; - ras.num_cells = 0; - ras.invalid = 1; - - ras.render_span = (FT_Raster_Span_Func)grays_render_span; - ras.render_span_data = &ras; - - if ( params->flags & ft_raster_flag_direct ) - { - ras.render_span = (FT_Raster_Span_Func)params->gray_spans; - ras.render_span_data = params->user; - } - - return grays_convert_glyph( (PRaster)raster, outline ); - } - - - /**** RASTER OBJECT CREATION: In standalone mode, we simply use *****/ - /**** a static object. *****/ - -#ifdef _STANDALONE_ - - static - int grays_raster_new( void* memory, - FT_Raster* araster ) - { - static TRaster the_raster; - - FT_UNUSED( memory ); - - - *araster = (FT_Raster)&the_raster; - memset( &the_raster, 0, sizeof ( the_raster ) ); - - return 0; - } - - - static - void grays_raster_done( FT_Raster raster ) - { - /* nothing */ - FT_UNUSED( raster ); - } - -#else /* _STANDALONE_ */ - - static - int grays_raster_new( FT_Memory memory, - FT_Raster* araster ) - { - FT_Error error; - PRaster raster; - - - *araster = 0; - if ( !ALLOC( raster, sizeof ( TRaster ) ) ) - { - raster->memory = memory; - *araster = (FT_Raster)raster; - } - - return error; - } - - - static - void grays_raster_done( FT_Raster raster ) - { - FT_Memory memory = (FT_Memory)((PRaster)raster)->memory; - - - FREE( raster ); - } - -#endif /* _STANDALONE_ */ - - - static - void grays_raster_reset( FT_Raster raster, - const char* pool_base, - long pool_size ) - { - PRaster rast = (PRaster)raster; - - - if ( raster && pool_base && pool_size >= 4096 ) - init_cells( rast, (char*)pool_base, pool_size ); - - rast->band_size = ( pool_size / sizeof ( TCell ) ) / 8; - } - - - FT_Raster_Funcs ft_grays_raster = - { - ft_glyph_format_outline, - - (FT_Raster_New_Func) grays_raster_new, - (FT_Raster_Reset_Func) grays_raster_reset, - (FT_Raster_Set_Mode_Func)0, - (FT_Raster_Render_Func) grays_raster_render, - (FT_Raster_Done_Func) grays_raster_done - }; - - -/* END */ diff --git a/src/freetype/smooth/ftgrays.h b/src/freetype/smooth/ftgrays.h deleted file mode 100644 index 2423a0e45e..0000000000 --- a/src/freetype/smooth/ftgrays.h +++ /dev/null @@ -1,52 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftgrays.h */ -/* */ -/* FreeType smooth renderer declaration */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - -#ifndef FTGRAYS_H -#define FTGRAYS_H - -#ifdef __cplusplus - extern "C" { -#endif - -#ifdef _STANDALONE_ -#include "ftimage.h" -#else -#include -#endif - - /*************************************************************************/ - /* */ - /* To make ftgrays.h independent from configuration files we check */ - /* whether FT_EXPORT_DEF has been defined already. */ - /* */ - /* On some systems and compilers (Win32 mostly), an extra keyword is */ - /* necessary to compile the library as a DLL. */ - /* */ -#ifndef FT_EXPORT_VAR -#define FT_EXPORT_VAR( x ) extern x -#endif - - FT_EXPORT_VAR( FT_Raster_Funcs ) ft_grays_raster; - -#ifdef __cplusplus - } -#endif - -#endif /* FTGRAYS_H */ - - -/* END */ diff --git a/src/freetype/smooth/ftsmooth.c b/src/freetype/smooth/ftsmooth.c deleted file mode 100644 index 6f399acf59..0000000000 --- a/src/freetype/smooth/ftsmooth.c +++ /dev/null @@ -1,220 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftsmooth.c */ -/* */ -/* Anti-aliasing renderer interface (body). */ -/* */ -/* Copyright 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 -#include - - -#ifdef FT_FLAT_COMPILE - -#include "ftsmooth.h" -#include "ftgrays.h" - -#else - -#include -#include - -#endif - - - /* initialize renderer -- init its raster */ - static - FT_Error ft_smooth_init( FT_Renderer render ) - { - FT_Library library = FT_MODULE_LIBRARY( render ); - - - render->clazz->raster_class->raster_reset( render->raster, - library->raster_pool, - library->raster_pool_size ); - - return 0; - } - - - /* sets render-specific mode */ - static - FT_Error ft_smooth_set_mode( FT_Renderer render, - FT_ULong mode_tag, - FT_Pointer data ) - { - /* we simply pass it to the raster */ - return render->clazz->raster_class->raster_set_mode( render->raster, - mode_tag, - data ); - } - - /* transform a given glyph image */ - static - FT_Error ft_smooth_transform( FT_Renderer render, - FT_GlyphSlot slot, - FT_Matrix* matrix, - FT_Vector* delta ) - { - FT_Error error = FT_Err_Ok; - - - if ( slot->format != render->glyph_format ) - { - error = FT_Err_Invalid_Argument; - goto Exit; - } - - if ( matrix ) - FT_Outline_Transform( &slot->outline, matrix ); - - if ( delta ) - FT_Outline_Translate( &slot->outline, delta->x, delta->y ); - - Exit: - return error; - } - - - /* return the glyph's control box */ - static - void ft_smooth_get_cbox( FT_Renderer render, - FT_GlyphSlot slot, - FT_BBox* cbox ) - { - MEM_Set( cbox, 0, sizeof ( *cbox ) ); - - if ( slot->format == render->glyph_format ) - FT_Outline_Get_CBox( &slot->outline, cbox ); - } - - - /* convert a slot's glyph image into a bitmap */ - static - FT_Error ft_smooth_render( FT_Renderer render, - FT_GlyphSlot slot, - FT_UInt mode, - FT_Vector* origin ) - { - FT_Error error; - FT_Outline* outline; - FT_BBox cbox; - FT_UInt width, height, pitch; - FT_Bitmap* bitmap; - FT_Memory memory; - - FT_Raster_Params params; - - - /* check glyph image format */ - if ( slot->format != render->glyph_format ) - { - error = FT_Err_Invalid_Argument; - goto Exit; - } - - /* check mode */ - if ( mode != ft_render_mode_normal ) - return FT_Err_Cannot_Render_Glyph; - - outline = &slot->outline; - - /* translate the outline to the new origin if needed */ - if ( origin ) - FT_Outline_Translate( outline, origin->x, origin->y ); - - /* compute the control box, and grid fit it */ - FT_Outline_Get_CBox( outline, &cbox ); - - cbox.xMin &= -64; - cbox.yMin &= -64; - cbox.xMax = ( cbox.xMax + 63 ) & -64; - cbox.yMax = ( cbox.yMax + 63 ) & -64; - - width = ( cbox.xMax - cbox.xMin ) >> 6; - height = ( cbox.yMax - cbox.yMin ) >> 6; - bitmap = &slot->bitmap; - memory = render->root.memory; - - /* release old bitmap buffer */ - if ( slot->flags & ft_glyph_own_bitmap ) - { - FREE( bitmap->buffer ); - slot->flags &= ~ft_glyph_own_bitmap; - } - - /* allocate new one, depends on pixel format */ - pitch = width; - bitmap->pixel_mode = ft_pixel_mode_grays; - bitmap->num_grays = 256; - bitmap->width = width; - bitmap->rows = height; - bitmap->pitch = pitch; - - if ( ALLOC( bitmap->buffer, (FT_ULong)pitch * height ) ) - goto Exit; - - slot->flags |= ft_glyph_own_bitmap; - - /* translate outline to render it into the bitmap */ - FT_Outline_Translate( outline, -cbox.xMin, -cbox.yMin ); - - /* set up parameters */ - params.target = bitmap; - params.source = outline; - params.flags = ft_raster_flag_aa; - - /* render outline into the bitmap */ - error = render->raster_render( render->raster, ¶ms ); - if ( error ) - goto Exit; - - slot->format = ft_glyph_format_bitmap; - slot->bitmap_left = cbox.xMin >> 6; - slot->bitmap_top = cbox.yMax >> 6; - - Exit: - return error; - } - - - const FT_Renderer_Class ft_smooth_renderer_class = - { - { - ft_module_renderer, - sizeof( FT_RendererRec ), - - "smooth", - 0x10000L, - 0x20000L, - - 0, /* module specific interface */ - - (FT_Module_Constructor)ft_smooth_init, - (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 - }, - - ft_glyph_format_outline, - - (FTRenderer_render) ft_smooth_render, - (FTRenderer_transform)ft_smooth_transform, - (FTRenderer_getCBox) ft_smooth_get_cbox, - (FTRenderer_setMode) ft_smooth_set_mode, - - (FT_Raster_Funcs*) &ft_grays_raster - }; - - -/* END */ diff --git a/src/freetype/smooth/ftsmooth.h b/src/freetype/smooth/ftsmooth.h deleted file mode 100644 index 4b8a533437..0000000000 --- a/src/freetype/smooth/ftsmooth.h +++ /dev/null @@ -1,35 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftsmooth.h */ -/* */ -/* Anti-aliasing renderer interface (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifndef FTSMOOTH_H -#define FTSMOOTH_H - -#include - -#ifndef FT_CONFIG_OPTION_NO_STD_RASTER - FT_EXPORT_VAR( const FT_Renderer_Class ) ft_std_renderer_class; -#endif - -#ifndef FT_CONFIG_OPTION_NO_SMOOTH_RASTER - FT_EXPORT_VAR( const FT_Renderer_Class ) ft_smooth_renderer_class; -#endif - -#endif /* FTSMOOTH_H */ - - -/* END */ diff --git a/src/freetype/smooth/module.mk b/src/freetype/smooth/module.mk deleted file mode 100644 index b93bc4d3dd..0000000000 --- a/src/freetype/smooth/module.mk +++ /dev/null @@ -1,7 +0,0 @@ -make_module_list: add_smooth_renderer - -add_smooth_renderer: - $(OPEN_DRIVER)ft_smooth_renderer_class$(CLOSE_DRIVER) - $(ECHO_DRIVER)smooth $(ECHO_DRIVER_DESC)anti-aliased bitmap renderer$(ECHO_DRIVER_DONE) - -# EOF diff --git a/src/freetype/smooth/rules.mk b/src/freetype/smooth/rules.mk deleted file mode 100644 index a81d60ae86..0000000000 --- a/src/freetype/smooth/rules.mk +++ /dev/null @@ -1,69 +0,0 @@ -# -# FreeType 2 renderer module build rules -# - - -# 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. - - -# smooth driver directory -# -SMOOTH_DIR := $(SRC_)smooth -SMOOTH_DIR_ := $(SMOOTH_DIR)$(SEP) - -# compilation flags for the driver -# -SMOOTH_COMPILE := $(FT_COMPILE) - - -# smooth driver sources (i.e., C files) -# -SMOOTH_DRV_SRC := $(SMOOTH_DIR_)ftgrays.c \ - $(SMOOTH_DIR_)ftsmooth.c - - -# smooth driver headers -# -SMOOTH_DRV_H := $(SMOOTH_DRV_SRC:%c=%h) - - -# smooth driver object(s) -# -# SMOOTH_DRV_OBJ_M is used during `multi' builds. -# SMOOTH_DRV_OBJ_S is used during `single' builds. -# -SMOOTH_DRV_OBJ_M := $(SMOOTH_DRV_SRC:$(SMOOTH_DIR_)%.c=$(OBJ_)%.$O) -SMOOTH_DRV_OBJ_S := $(OBJ_)smooth.$O - -# smooth driver source file for single build -# -SMOOTH_DRV_SRC_S := $(SMOOTH_DIR_)smooth.c - - -# smooth driver - single object -# -$(SMOOTH_DRV_OBJ_S): $(SMOOTH_DRV_SRC_S) $(SMOOTH_DRV_SRC) \ - $(FREETYPE_H) $(SMOOTH_DRV_H) - $(SMOOTH_COMPILE) $T$@ $(SMOOTH_DRV_SRC_S) - - -# smooth driver - multiple objects -# -$(OBJ_)%.$O: $(SMOOTH_DIR_)%.c $(FREETYPE_H) $(SMOOTH_DRV_H) - $(SMOOTH_COMPILE) $T$@ $< - - -# update main driver object lists -# -DRV_OBJS_S += $(SMOOTH_DRV_OBJ_S) -DRV_OBJS_M += $(SMOOTH_DRV_OBJ_M) - - -# EOF diff --git a/src/freetype/smooth/smooth.c b/src/freetype/smooth/smooth.c deleted file mode 100644 index 41cc4aea52..0000000000 --- a/src/freetype/smooth/smooth.c +++ /dev/null @@ -1,35 +0,0 @@ -/***************************************************************************/ -/* */ -/* smooth.c */ -/* */ -/* FreeType anti-aliasing rasterer module component (body only). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#define FT_MAKE_OPTION_SINGLE_OBJECT - - -#ifdef FT_FLAT_COMPILE - -#include "ftgrays.c" -#include "ftsmooth.c" - -#else - -#include -#include - -#endif - - -/* END */ diff --git a/src/freetype/truetype/module.mk b/src/freetype/truetype/module.mk deleted file mode 100644 index 79072bb54b..0000000000 --- a/src/freetype/truetype/module.mk +++ /dev/null @@ -1,7 +0,0 @@ -make_module_list: add_truetype_driver - -add_truetype_driver: - $(OPEN_DRIVER)tt_driver_class$(CLOSE_DRIVER) - $(ECHO_DRIVER)truetype $(ECHO_DRIVER_DESC)Windows/Mac font files with extension *.ttf or *.ttc$(ECHO_DRIVER_DONE) - -# EOF diff --git a/src/freetype/truetype/rules.mk b/src/freetype/truetype/rules.mk deleted file mode 100644 index 9289378cb5..0000000000 --- a/src/freetype/truetype/rules.mk +++ /dev/null @@ -1,70 +0,0 @@ -# -# FreeType 2 TrueType driver configuration rules -# - - -# 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. - - -# TrueType driver directory -# -TT_DIR := $(SRC_)truetype -TT_DIR_ := $(TT_DIR)$(SEP) - - -# compilation flags for the driver -# -TT_COMPILE := $(FT_COMPILE) - - -# TrueType driver sources (i.e., C files) -# -TT_DRV_SRC := $(TT_DIR_)ttobjs.c \ - $(TT_DIR_)ttpload.c \ - $(TT_DIR_)ttgload.c \ - $(TT_DIR_)ttinterp.c \ - $(TT_DIR_)ttdriver.c - -# TrueType driver headers -# -TT_DRV_H := $(TT_DRV_SRC:%.c=%.h) - - -# TrueType driver object(s) -# -# TT_DRV_OBJ_M is used during `multi' builds -# TT_DRV_OBJ_S is used during `single' builds -# -TT_DRV_OBJ_M := $(TT_DRV_SRC:$(TT_DIR_)%.c=$(OBJ_)%.$O) -TT_DRV_OBJ_S := $(OBJ_)truetype.$O - -# TrueType driver source file for single build -# -TT_DRV_SRC_S := $(TT_DIR_)truetype.c - - -# TrueType driver - single object -# -$(TT_DRV_OBJ_S): $(TT_DRV_SRC_S) $(TT_DRV_SRC) $(FREETYPE_H) $(TT_DRV_H) - $(TT_COMPILE) $T$@ $(TT_DRV_SRC_S) - - -# driver - multiple objects -# -$(OBJ_)%.$O: $(TT_DIR_)%.c $(FREETYPE_H) $(TT_DRV_H) - $(TT_COMPILE) $T$@ $< - - -# update main driver object lists -# -DRV_OBJS_S += $(TT_DRV_OBJ_S) -DRV_OBJS_M += $(TT_DRV_OBJ_M) - -# EOF diff --git a/src/freetype/truetype/truetype.c b/src/freetype/truetype/truetype.c deleted file mode 100644 index 55ba0c9d41..0000000000 --- a/src/freetype/truetype/truetype.c +++ /dev/null @@ -1,47 +0,0 @@ -/***************************************************************************/ -/* */ -/* truetype.c */ -/* */ -/* FreeType TrueType driver component (body only). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#define FT_MAKE_OPTION_SINGLE_OBJECT - - -#ifdef FT_FLAT_COMPILE - -#include "ttdriver.c" /* driver interface */ -#include "ttpload.c" /* tables loader */ -#include "ttgload.c" /* glyph loader */ -#include "ttobjs.c" /* object manager */ - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER -#include "ttinterp.c" /* bytecode interpreter */ -#endif - -#else /* FT_FLAT_COMPILE */ - -#include /* driver interface */ -#include /* tables loader */ -#include /* glyph loader */ -#include /* object manager */ - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER -#include /* bytecode interpreter */ -#endif - -#endif /* FT_FLAT_COMPILE */ - - -/* END */ diff --git a/src/freetype/truetype/ttdriver.c b/src/freetype/truetype/ttdriver.c deleted file mode 100644 index 0b3cb480c5..0000000000 --- a/src/freetype/truetype/ttdriver.c +++ /dev/null @@ -1,511 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttdriver.c */ -/* */ -/* TrueType font driver implementation (body). */ -/* */ -/* 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 -#include -#include -#include - - -#ifdef FT_FLAT_COMPILE - -#include "ttdriver.h" -#include "ttgload.h" - -#else - -#include -#include - -#endif - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_ttdriver - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** F A C E S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - -#undef PAIR_TAG -#define PAIR_TAG( left, right ) ( ( (FT_ULong)left << 16 ) | \ - (FT_ULong)right ) - - - /*************************************************************************/ - /* */ - /* */ - /* Get_Kerning */ - /* */ - /* */ - /* A driver method used to return the kerning vector between two */ - /* glyphs of the same face. */ - /* */ - /* */ - /* face :: A handle to the source face object. */ - /* */ - /* left_glyph :: The index of the left glyph in the kern pair. */ - /* */ - /* right_glyph :: The index of the right glyph in the kern pair. */ - /* */ - /* */ - /* kerning :: The kerning vector. This is in font units for */ - /* scalable formats, and in pixels for fixed-sizes */ - /* formats. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Only horizontal layouts (left-to-right & right-to-left) are */ - /* supported by this function. Other layouts, or more sophisticated */ - /* kernings, are out of scope of this method (the basic driver */ - /* interface is meant to be simple). */ - /* */ - /* They can be implemented by format-specific interfaces. */ - /* */ - static - FT_Error Get_Kerning( TT_Face face, - FT_UInt left_glyph, - FT_UInt right_glyph, - FT_Vector* kerning ) - { - TT_Kern_0_Pair* pair; - - - if ( !face ) - return TT_Err_Invalid_Face_Handle; - - kerning->x = 0; - kerning->y = 0; - - if ( face->kern_pairs ) - { - /* there are some kerning pairs in this font file! */ - FT_ULong search_tag = PAIR_TAG( left_glyph, right_glyph ); - FT_Long left, right; - - - left = 0; - right = face->num_kern_pairs - 1; - - while ( left <= right ) - { - FT_Int middle = left + ( ( right - left ) >> 1 ); - FT_ULong cur_pair; - - - pair = face->kern_pairs + middle; - cur_pair = PAIR_TAG( pair->left, pair->right ); - - if ( cur_pair == search_tag ) - goto Found; - - if ( cur_pair < search_tag ) - left = middle + 1; - else - right = middle - 1; - } - } - - Exit: - return TT_Err_Ok; - - Found: - kerning->x = pair->value; - goto Exit; - } - - -#undef PAIR_TAG - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** S I Z E S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* Set_Char_Sizes */ - /* */ - /* */ - /* A driver method used to reset a size's character sizes (horizontal */ - /* and vertical) expressed in fractional points. */ - /* */ - /* */ - /* char_width :: The character width expressed in 26.6 */ - /* fractional points. */ - /* */ - /* char_height :: The character height expressed in 26.6 */ - /* fractional points. */ - /* */ - /* horz_resolution :: The horizontal resolution of the output device. */ - /* */ - /* vert_resolution :: The vertical resolution of the output device. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error Set_Char_Sizes( TT_Size size, - FT_F26Dot6 char_width, - FT_F26Dot6 char_height, - FT_UInt horz_resolution, - FT_UInt vert_resolution ) - { - FT_Size_Metrics* metrics = &size->root.metrics; - TT_Face face = (TT_Face)size->root.face; - FT_Long dim_x, dim_y; - - - /* This bit flag, when set, indicates that the pixel size must be */ - /* truncated to an integer. Nearly all TrueType fonts have this */ - /* bit set, as hinting won't work really well otherwise. */ - /* */ - /* However, for those rare fonts who do not set it, we override */ - /* the default computations performed by the base layer. I */ - /* really don't know whether this is useful, but hey, that's the */ - /* spec :-) */ - /* */ - if ( ( face->header.Flags & 8 ) == 0 ) - { - /* Compute pixel sizes in 26.6 units */ - dim_x = ( char_width * horz_resolution ) / 72; - dim_y = ( char_height * vert_resolution ) / 72; - - metrics->x_scale = FT_DivFix( dim_x, face->root.units_per_EM ); - metrics->y_scale = FT_DivFix( dim_y, face->root.units_per_EM ); - - metrics->x_ppem = (FT_UShort)( dim_x >> 6 ); - metrics->y_ppem = (FT_UShort)( dim_y >> 6 ); - } - - size->ttmetrics.valid = FALSE; - - return TT_Reset_Size( size ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* Set_Pixel_Sizes */ - /* */ - /* */ - /* A driver method used to reset a size's character sizes (horizontal */ - /* and vertical) expressed in integer pixels. */ - /* */ - /* */ - /* pixel_width :: The character width expressed in integer pixels. */ - /* */ - /* pixel_height :: The character height expressed in integer pixels. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error Set_Pixel_Sizes( TT_Size size, - FT_UInt pixel_width, - FT_UInt pixel_height ) - { - FT_UNUSED( pixel_width ); - FT_UNUSED( pixel_height ); - - /* many things have been pre-computed by the base layer */ - - size->ttmetrics.valid = FALSE; - - return TT_Reset_Size( size ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* Load_Glyph */ - /* */ - /* */ - /* A driver method used to load a glyph within a given glyph slot. */ - /* */ - /* */ - /* slot :: A handle to the target slot object where the glyph */ - /* will be loaded. */ - /* */ - /* size :: A handle to the source face size at which the glyph */ - /* must be scaled, loaded, etc. */ - /* */ - /* glyph_index :: The index of the glyph in the font file. */ - /* */ - /* load_flags :: A flag indicating what to load for this glyph. The */ - /* FTLOAD_??? constants can be used to control the */ - /* glyph loading process (e.g., whether the outline */ - /* should be scaled, whether to load bitmaps or not, */ - /* whether to hint the outline, etc). */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error Load_Glyph( TT_GlyphSlot slot, - TT_Size size, - FT_UShort glyph_index, - FT_UInt load_flags ) - { - FT_Error error; - - - if ( !slot ) - return TT_Err_Invalid_Glyph_Handle; - - /* check whether we want a scaled outline or bitmap */ - if ( !size ) - load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; - - if ( load_flags & FT_LOAD_NO_SCALE ) - size = NULL; - - /* reset the size object if necessary */ - if ( size ) - { - /* these two object must have the same parent */ - if ( size->root.face != slot->face ) - return TT_Err_Invalid_Face_Handle; - - if ( !size->ttmetrics.valid ) - { - if ( FT_SET_ERROR( TT_Reset_Size( size ) ) ) - return error; - } - } - - /* now load the glyph outline if necessary */ - error = TT_Load_Glyph( size, slot, glyph_index, load_flags ); - - /* force drop-out mode to 2 - irrelevant now */ - /* slot->outline.dropout_mode = 2; */ - - return error; - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** C H A R A C T E R M A P P I N G S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* */ - /* Get_Char_Index */ - /* */ - /* */ - /* Uses a charmap to return a given character code's glyph index. */ - /* */ - /* */ - /* charmap :: A handle to the source charmap object. */ - /* charcode :: The character code. */ - /* */ - /* */ - /* Glyph index. 0 means `undefined character code'. */ - /* */ - static - FT_UInt Get_Char_Index( TT_CharMap charmap, - FT_Long charcode ) - { - FT_Error error; - TT_Face face; - TT_CMapTable* cmap; - - - cmap = &charmap->cmap; - face = (TT_Face)charmap->root.face; - - /* Load table if needed */ - if ( !cmap->loaded ) - { - SFNT_Interface* sfnt = (SFNT_Interface*)face->sfnt; - - - error = sfnt->load_charmap( face, cmap, face->root.stream ); - if ( error ) - return 0; - - cmap->loaded = TRUE; - } - - if ( cmap->get_index ) - return cmap->get_index( cmap, charcode ); - else - return 0; - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** D R I V E R I N T E R F A C E ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - static - FT_Module_Interface tt_get_interface( TT_Driver driver, - const char* interface ) - { - FT_Module sfntd = FT_Get_Module( driver->root.root.library, - "sfnt" ); - SFNT_Interface* sfnt; - - - /* only return the default interface from the SFNT module */ - if ( sfntd ) - { - sfnt = (SFNT_Interface*)( sfntd->clazz->module_interface ); - if ( sfnt ) - return sfnt->get_interface( FT_MODULE( driver ), interface ); - } - - return 0; - } - - - /* The FT_DriverInterface structure is defined in ftdriver.h. */ - - const FT_Driver_Class tt_driver_class = - { - { - ft_module_font_driver | - ft_module_driver_scalable | -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - ft_module_driver_has_hinter, -#else - 0, -#endif - - sizeof ( TT_DriverRec ), - - "truetype", /* driver name */ - 0x10000L, /* driver version == 1.0 */ - 0x20000L, /* driver requires FreeType 2.0 or above */ - - (void*)0, /* driver specific interface */ - - (FT_Module_Constructor)TT_Init_Driver, - (FT_Module_Destructor) TT_Done_Driver, - (FT_Module_Requester) tt_get_interface, - }, - - sizeof ( TT_FaceRec ), - sizeof ( TT_SizeRec ), - sizeof ( FT_GlyphSlotRec ), - - - (FTDriver_initFace) TT_Init_Face, - (FTDriver_doneFace) TT_Done_Face, - (FTDriver_initSize) TT_Init_Size, - (FTDriver_doneSize) TT_Done_Size, - (FTDriver_initGlyphSlot)0, - (FTDriver_doneGlyphSlot)0, - - (FTDriver_setCharSizes) Set_Char_Sizes, - (FTDriver_setPixelSizes)Set_Pixel_Sizes, - (FTDriver_loadGlyph) Load_Glyph, - (FTDriver_getCharIndex) Get_Char_Index, - - (FTDriver_getKerning) Get_Kerning, - (FTDriver_attachFile) 0, - (FTDriver_getAdvances) 0 - }; - - -#ifdef FT_CONFIG_OPTION_DYNAMIC_DRIVERS - - - /*************************************************************************/ - /* */ - /* */ - /* getDriverInterface */ - /* */ - /* */ - /* This function is used when compiling the TrueType driver as a */ - /* shared library (`.DLL' or `.so'). It will be used by the */ - /* high-level library of FreeType to retrieve the address of the */ - /* driver's generic interface. */ - /* */ - /* It shouldn't be implemented in a static build, as each driver must */ - /* have the same function as an exported entry point. */ - /* */ - /* */ - /* The address of the TrueType's driver generic interface. The */ - /* format-specific interface can then be retrieved through the method */ - /* interface->get_format_interface. */ - /* */ - EXPORT_FUNC( const FT_Driver_Class* ) getDriverClass( void ) - { - return &tt_driver_class; - } - - -#endif /* CONFIG_OPTION_DYNAMIC_DRIVERS */ - - -/* END */ diff --git a/src/freetype/truetype/ttdriver.h b/src/freetype/truetype/ttdriver.h deleted file mode 100644 index 9867fbc309..0000000000 --- a/src/freetype/truetype/ttdriver.h +++ /dev/null @@ -1,31 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttdriver.h */ -/* */ -/* High-level TrueType driver interface (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifndef TTDRIVER_H -#define TTDRIVER_H - -#include - - - FT_EXPORT_VAR( const FT_Driver_Class ) tt_driver_class; - - -#endif /* TTDRIVER_H */ - - -/* END */ diff --git a/src/freetype/truetype/ttgload.c b/src/freetype/truetype/ttgload.c deleted file mode 100644 index e9b87fa67e..0000000000 --- a/src/freetype/truetype/ttgload.c +++ /dev/null @@ -1,1477 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttgload.c */ -/* */ -/* TrueType Glyph Loader (body). */ -/* */ -/* 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 -#include -#include -#include -#include -#include - - -#ifdef FT_FLAT_COMPILE - -#include "ttgload.h" - -#else - -#include - -#endif - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_ttgload - - - /*************************************************************************/ - /* */ - /* Composite font flags. */ - /* */ -#define ARGS_ARE_WORDS 0x001 -#define ARGS_ARE_XY_VALUES 0x002 -#define ROUND_XY_TO_GRID 0x004 -#define WE_HAVE_A_SCALE 0x008 -/* reserved 0x010 */ -#define MORE_COMPONENTS 0x020 -#define WE_HAVE_AN_XY_SCALE 0x040 -#define WE_HAVE_A_2X2 0x080 -#define WE_HAVE_INSTR 0x100 -#define USE_MY_METRICS 0x200 - - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Get_Metrics */ - /* */ - /* */ - /* Returns the horizontal or vertical metrics in font units for a */ - /* given glyph. The metrics are the left side bearing (resp. top */ - /* side bearing) and advance width (resp. advance height). */ - /* */ - /* */ - /* header :: A pointer to either the horizontal or vertical metrics */ - /* structure. */ - /* */ - /* index :: The glyph index. */ - /* */ - /* */ - /* bearing :: The bearing, either left side or top side. */ - /* */ - /* advance :: The advance width resp. advance height. */ - /* */ - /* */ - /* This function will much probably move to another component in the */ - /* near future, but I haven't decided which yet. */ - /* */ - LOCAL_FUNC - void TT_Get_Metrics( TT_HoriHeader* header, - FT_UInt index, - FT_Short* bearing, - FT_UShort* advance ) - { - TT_LongMetrics* longs_m; - FT_UShort k = header->number_Of_HMetrics; - - - if ( index < k ) - { - longs_m = (TT_LongMetrics*)header->long_metrics + index; - *bearing = longs_m->bearing; - *advance = longs_m->advance; - } - else - { - *bearing = ((TT_ShortMetrics*)header->short_metrics)[index - k]; - *advance = ((TT_LongMetrics*)header->long_metrics)[k - 1].advance; - } - } - - - /*************************************************************************/ - /* */ - /* Returns the horizontal metrics in font units for a given glyph. If */ - /* `check' is true, take care of monospaced fonts by returning the */ - /* advance width maximum. */ - /* */ - static - void Get_HMetrics( TT_Face face, - FT_UInt index, - FT_Bool check, - FT_Short* lsb, - FT_UShort* aw ) - { - TT_Get_Metrics( &face->horizontal, index, lsb, aw ); - - if ( check && face->postscript.isFixedPitch ) - *aw = face->horizontal.advance_Width_Max; - } - - - /*************************************************************************/ - /* */ - /* Returns the advance width table for a given pixel size if it is */ - /* found in the font's `hdmx' table (if any). */ - /* */ - static - FT_Byte* Get_Advance_Widths( TT_Face face, - FT_UShort ppem ) - { - FT_UShort n; - - for ( n = 0; n < face->hdmx.num_records; n++ ) - if ( face->hdmx.records[n].ppem == ppem ) - return face->hdmx.records[n].widths; - - return NULL; - } - - -#define cur_to_org( n, zone ) \ - MEM_Copy( (zone)->org, (zone)->cur, n * sizeof ( FT_Vector ) ) - -#define org_to_cur( n, zone ) \ - MEM_Copy( (zone)->cur, (zone)->org, n * sizeof ( FT_Vector ) ) - - - /*************************************************************************/ - /* */ - /* Translates an array of coordinates. */ - /* */ - static - void translate_array( FT_UInt n, - FT_Vector* coords, - FT_Pos delta_x, - FT_Pos delta_y ) - { - FT_UInt k; - - - if ( delta_x ) - for ( k = 0; k < n; k++ ) - coords[k].x += delta_x; - - if ( delta_y ) - for ( k = 0; k < n; k++ ) - coords[k].y += delta_y; - } - - - static - void tt_prepare_zone( TT_GlyphZone* zone, - FT_GlyphLoad* load, - FT_UInt start_point, - FT_UInt start_contour ) - { - zone->n_points = load->outline.n_points - start_point; - zone->n_contours = load->outline.n_contours - start_contour; - zone->org = load->extra_points + start_point; - zone->cur = load->outline.points + start_point; - zone->tags = (FT_Byte*)load->outline.tags + start_point; - zone->contours = (FT_UShort*)load->outline.contours + start_contour; - } - - -#undef IS_HINTED -#define IS_HINTED( flags ) ( ( flags & FT_LOAD_NO_HINTING ) == 0 ) - - - /*************************************************************************/ - /* */ - /* The following functions are used by default with TrueType fonts. */ - /* However, they can be replaced by alternatives if we need to support */ - /* TrueType-compressed formats (like MicroType) in the future. */ - /* */ - /*************************************************************************/ - - static - FT_Error TT_Access_Glyph_Frame( TT_Loader* loader, - FT_UInt glyph_index, - FT_ULong offset, - FT_UInt byte_count ) - { - FT_Error error; - FT_Stream stream = loader->stream; - - - /* the following line sets the `error' variable through macros! */ - (void)( FILE_Seek( offset ) || ACCESS_Frame( byte_count ) ); - - FT_TRACE5(( "Glyph %ld\n", glyph_index )); - return error; - } - - - static - void TT_Forget_Glyph_Frame( TT_Loader* loader ) - { - FT_Stream stream = loader->stream; - - - FORGET_Frame(); - } - - - static - FT_Error TT_Load_Glyph_Header( TT_Loader* loader ) - { - FT_Stream stream = loader->stream; - - - loader->n_contours = GET_Short(); - - loader->bbox.xMin = GET_Short(); - loader->bbox.yMin = GET_Short(); - loader->bbox.xMax = GET_Short(); - loader->bbox.yMax = GET_Short(); - - FT_TRACE5(( " # of contours: %d\n", loader->n_contours )); - FT_TRACE5(( " xMin: %4d xMax: %4d\n", loader->bbox.xMin, - loader->bbox.xMax )); - FT_TRACE5(( " yMin: %4d yMax: %4d\n", loader->bbox.yMin, - loader->bbox.yMax )); - - return FT_Err_Ok; - } - - - static - FT_Error TT_Load_Simple_Glyph( TT_Loader* load ) - { - FT_Error error; - FT_Stream stream = load->stream; - FT_GlyphLoader* gloader = load->gloader; - FT_Int n_contours = load->n_contours; - FT_Outline* outline; - TT_Face face = (TT_Face)load->face; - TT_GlyphSlot slot = (TT_GlyphSlot)load->glyph; - FT_UShort n_ins; - FT_Int n, n_points; - - - /* reading the contours endpoints & number of points */ - { - short* cur = gloader->current.outline.contours; - short* limit = cur + n_contours; - - - for ( ; cur < limit; cur++ ) - cur[0] = GET_UShort(); - - n_points = 0; - if ( n_contours > 0 ) - n_points = cur[-1] + 1; - - error = FT_GlyphLoader_Check_Points( gloader, n_points + 2, 0 ); - if ( error ) - goto Fail; - - outline = &gloader->current.outline; - } - - /* reading the bytecode instructions */ - slot->control_len = 0; - slot->control_data = 0; - - n_ins = GET_UShort(); - - FT_TRACE5(( " Instructions size: %d\n", n_ins )); - - if ( n_ins > face->max_profile.maxSizeOfInstructions ) - { - FT_TRACE0(( "ERROR: Too many instructions!\n" )); - error = TT_Err_Too_Many_Ins; - goto Fail; - } - - if ( stream->cursor + n_ins > stream->limit ) - { - FT_TRACE0(( "ERROR: Instruction count mismatch!\n" )); - error = TT_Err_Too_Many_Ins; - goto Fail; - } - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - if ( ( load->load_flags & - ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING ) ) == 0 && - load->instructions ) - { - slot->control_len = n_ins; - slot->control_data = load->instructions; - - MEM_Copy( load->instructions, stream->cursor, n_ins ); - } - -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ - - stream->cursor += n_ins; - - /* reading the point tags */ - - { - FT_Byte* flag = (FT_Byte*)outline->tags; - FT_Byte* limit = flag + n_points; - FT_Byte c, count; - - - for ( ; flag < limit; flag++ ) - { - *flag = c = GET_Byte(); - if ( c & 8 ) - { - for ( count = GET_Byte(); count > 0; count-- ) - *++flag = c; - } - } - } - - /* reading the X coordinates */ - - { - FT_Vector* vec = outline->points; - FT_Vector* limit = vec + n_points; - FT_Byte* flag = (FT_Byte*)outline->tags; - FT_Pos x = 0; - - - for ( ; vec < limit; vec++, flag++ ) - { - FT_Pos y = 0; - - - if ( *flag & 2 ) - { - y = GET_Byte(); - if ( ( *flag & 16 ) == 0 ) - y = -y; - } - else if ( ( *flag & 16 ) == 0 ) - y = GET_Short(); - - x += y; - vec->x = x; - } - } - - /* reading the Y coordinates */ - - { - FT_Vector* vec = gloader->current.outline.points; - FT_Vector* limit = vec + n_points; - FT_Byte* flag = (FT_Byte*)outline->tags; - FT_Pos x = 0; - - - for ( ; vec < limit; vec++, flag++ ) - { - FT_Pos y = 0; - - - if ( *flag & 4 ) - { - y = GET_Byte(); - if ( ( *flag & 32 ) == 0 ) - y = -y; - } - else if ( ( *flag & 32 ) == 0 ) - y = GET_Short(); - - x += y; - vec->y = x; - } - } - - /* clear the touch tags */ - for ( n = 0; n < n_points; n++ ) - outline->tags[n] &= FT_Curve_Tag_On; - - outline->n_points = n_points; - outline->n_contours = n_contours; - - Fail: - return error; - } - - - static - FT_Error TT_Load_Composite_Glyph( TT_Loader* loader ) - { - FT_Error error; - FT_Stream stream = loader->stream; - FT_GlyphLoader* gloader = loader->gloader; - FT_SubGlyph* subglyph; - FT_UInt num_subglyphs; - - - num_subglyphs = 0; - - do - { - FT_Fixed xx, xy, yy, yx; - - - /* check that we can load a new subglyph */ - error = FT_GlyphLoader_Check_Subglyphs( gloader, num_subglyphs + 1 ); - if ( error ) - goto Fail; - - subglyph = gloader->current.subglyphs + num_subglyphs; - - subglyph->arg1 = subglyph->arg2 = 0; - - subglyph->flags = GET_UShort(); - subglyph->index = GET_UShort(); - - /* read arguments */ - if ( subglyph->flags & ARGS_ARE_WORDS ) - { - subglyph->arg1 = GET_Short(); - subglyph->arg2 = GET_Short(); - } - else - { - subglyph->arg1 = GET_Char(); - subglyph->arg2 = GET_Char(); - } - - /* read transform */ - xx = yy = 0x10000L; - xy = yx = 0; - - if ( subglyph->flags & WE_HAVE_A_SCALE ) - { - xx = (FT_Fixed)GET_Short() << 2; - yy = xx; - } - else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE ) - { - xx = (FT_Fixed)GET_Short() << 2; - yy = (FT_Fixed)GET_Short() << 2; - } - else if ( subglyph->flags & WE_HAVE_A_2X2 ) - { - xx = (FT_Fixed)GET_Short() << 2; - xy = (FT_Fixed)GET_Short() << 2; - yx = (FT_Fixed)GET_Short() << 2; - yy = (FT_Fixed)GET_Short() << 2; - } - - subglyph->transform.xx = xx; - subglyph->transform.xy = xy; - subglyph->transform.yx = yx; - subglyph->transform.yy = yy; - - num_subglyphs++; - - } while ( subglyph->flags & MORE_COMPONENTS ); - - gloader->current.num_subglyphs = num_subglyphs; - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - { - /* we must undo the ACCESS_Frame in order to point to the */ - /* composite instructions, if we find some. */ - /* we will process them later... */ - /* */ - loader->ins_pos = FILE_Pos() + stream->cursor - stream->limit; - } -#endif - - Fail: - return error; - } - - - LOCAL_FUNC - void TT_Init_Glyph_Loading( TT_Face face ) - { - face->access_glyph_frame = TT_Access_Glyph_Frame; - face->read_glyph_header = TT_Load_Glyph_Header; - face->read_simple_glyph = TT_Load_Simple_Glyph; - face->read_composite_glyph = TT_Load_Composite_Glyph; - face->forget_glyph_frame = TT_Forget_Glyph_Frame; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Process_Simple_Glyph */ - /* */ - /* */ - /* Once a simple glyph has been loaded, it needs to be processed. */ - /* Usually, this means scaling and hinting through bytecode */ - /* interpretation. */ - /* */ - static - FT_Error TT_Process_Simple_Glyph( TT_Loader* load, - FT_Bool debug ) - { - FT_GlyphLoader* gloader = load->gloader; - FT_Outline* outline = &gloader->current.outline; - FT_UInt n_points = outline->n_points; - FT_UInt n_ins; - TT_GlyphZone* zone = &load->zone; - FT_Error error = FT_Err_Ok; - - - n_ins = load->glyph->control_len; - - /* add shadow points */ - - /* Now add the two shadow points at n and n + 1. */ - /* We need the left side bearing and advance width. */ - - { - FT_Vector* pp1; - FT_Vector* pp2; - - - /* pp1 = xMin - lsb */ - pp1 = outline->points + n_points; - pp1->x = load->bbox.xMin - load->left_bearing; - pp1->y = 0; - - /* pp2 = pp1 + aw */ - pp2 = pp1 + 1; - pp2->x = pp1->x + load->advance; - pp2->y = 0; - - outline->tags[n_points ] = 0; - outline->tags[n_points + 1] = 0; - } - - /* Note that we return two more points that are not */ - /* part of the glyph outline. */ - - n_points += 2; - - /* set up zone for hinting */ - tt_prepare_zone( zone, &gloader->current, 0, 0 ); - - /* eventually scale the glyph */ - if ( !( load->load_flags & FT_LOAD_NO_SCALE ) ) - { - FT_Vector* vec = zone->cur; - FT_Vector* limit = vec + n_points; - FT_Fixed x_scale = load->size->metrics.x_scale; - FT_Fixed y_scale = load->size->metrics.y_scale; - - - /* first scale the glyph points */ - for ( ; vec < limit; vec++ ) - { - vec->x = FT_MulFix( vec->x, x_scale ); - vec->y = FT_MulFix( vec->y, y_scale ); - } - } - - cur_to_org( n_points, zone ); - - /* eventually hint the glyph */ - if ( IS_HINTED( load->load_flags ) ) - { - FT_Pos x = zone->org[n_points-2].x; - - - x = ( ( x + 32 ) & -64 ) - x; - translate_array( n_points, zone->org, x, 0 ); - - org_to_cur( n_points, zone ); - - zone->cur[n_points - 1].x = ( zone->cur[n_points - 1].x + 32 ) & -64; - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - /* now consider hinting */ - if ( n_ins > 0 ) - { - error = TT_Set_CodeRange( load->exec, tt_coderange_glyph, - load->exec->glyphIns, n_ins ); - if ( error ) - goto Exit; - - load->exec->is_composite = FALSE; - load->exec->pedantic_hinting = (FT_Bool)( load->load_flags & - FT_LOAD_PEDANTIC ); - load->exec->pts = *zone; - load->exec->pts.n_points += 2; - - error = TT_Run_Context( load->exec, debug ); - if ( error && load->exec->pedantic_hinting ) - goto Exit; - - error = FT_Err_Ok; /* ignore bytecode errors in non-pedantic mode */ - } - -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ - - } - - /* save glyph phantom points */ - if ( !load->preserve_pps ) - { - load->pp1 = zone->cur[n_points - 2]; - load->pp2 = zone->cur[n_points - 1]; - } - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - Exit: -#endif - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* load_truetype_glyph */ - /* */ - /* */ - /* Loads a given truetype glyph. Handles composites and uses a */ - /* TT_Loader object. */ - /* */ - static - FT_Error load_truetype_glyph( TT_Loader* loader, - FT_UInt glyph_index ) - { - FT_Stream stream = loader->stream; - FT_Error error; - TT_Face face = (TT_Face)loader->face; - FT_ULong offset; - FT_Int contours_count; - FT_UInt index, num_points, num_contours, count; - FT_Fixed x_scale, y_scale; - FT_ULong ins_offset; - FT_GlyphLoader* gloader = loader->gloader; - FT_Bool opened_frame = 0; - - - /* check glyph index */ - index = glyph_index; - if ( index >= (FT_UInt)face->root.num_glyphs ) - { - error = TT_Err_Invalid_Glyph_Index; - goto Exit; - } - - loader->glyph_index = glyph_index; - num_contours = 0; - num_points = 0; - ins_offset = 0; - - x_scale = 0x10000L; - y_scale = 0x10000L; - if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) - { - x_scale = loader->size->metrics.x_scale; - y_scale = loader->size->metrics.y_scale; - } - - /* get horizontal metrics */ - { - FT_Short left_bearing; - FT_UShort advance_width; - - - Get_HMetrics( face, index, - (FT_Bool)!(loader->load_flags & - FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH), - &left_bearing, - &advance_width ); - - loader->left_bearing = left_bearing; - loader->advance = advance_width; - } - - offset = face->glyph_locations[index]; - count = 0; - - if ( index < (FT_UInt)face->num_locations - 1 ) - count = face->glyph_locations[index + 1] - offset; - - if ( count == 0 ) - { - /* as described by Frederic Loyer, these are spaces, and */ - /* not the unknown glyph. */ - loader->bbox.xMin = 0; - loader->bbox.xMax = 0; - loader->bbox.yMin = 0; - loader->bbox.yMax = 0; - - loader->pp1.x = 0; - loader->pp2.x = loader->advance; - - if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) - loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale ); - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - if ( loader->exec ) - loader->exec->glyphSize = 0; - -#endif - - error = FT_Err_Ok; - goto Exit; - } - - offset = loader->glyf_offset + offset; - - /* access glyph frame */ - error = face->access_glyph_frame( loader, glyph_index, offset, count ); - if ( error ) - goto Exit; - - opened_frame = 1; - - /* read first glyph header */ - error = face->read_glyph_header( loader ); - if ( error ) - goto Fail; - - contours_count = loader->n_contours; - - count -= 10; - - loader->pp1.x = loader->bbox.xMin - loader->left_bearing; - loader->pp1.y = 0; - loader->pp2.x = loader->pp1.x + loader->advance; - loader->pp2.y = 0; - - if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) - { - loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale ); - loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale ); - } - - /***********************************************************************/ - /***********************************************************************/ - /***********************************************************************/ - - /* if it is a simple glyph, load it */ - - if ( contours_count >= 0 ) - { - /* check that we can add the contours to the glyph */ - error = FT_GlyphLoader_Check_Points( gloader, 0, contours_count ); - if ( error ) - goto Fail; - - error = face->read_simple_glyph( loader ); - if ( error ) - goto Fail; - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - { - TT_Size size = (TT_Size)loader->size; - - - error = TT_Process_Simple_Glyph( loader, - (FT_Bool)( size && size->debug ) ); - } - -#else - - error = TT_Process_Simple_Glyph( loader, 0 ); - -#endif - - if ( error ) - goto Fail; - - FT_GlyphLoader_Add( gloader ); - - /* Note: We could have put the simple loader source there */ - /* but the code is fat enough already :-) */ - } - - /***********************************************************************/ - /***********************************************************************/ - /***********************************************************************/ - - /* otherwise, load a composite! */ - else - { - TT_GlyphSlot glyph = (TT_GlyphSlot)loader->glyph; - FT_UInt start_point, start_contour; - FT_ULong ins_pos; /* position of composite instructions, if any */ - - - /* for each subglyph, read composite header */ - start_point = gloader->base.outline.n_points; - start_contour = gloader->base.outline.n_contours; - - error = face->read_composite_glyph( loader ); - if ( error ) - goto Fail; - - ins_pos = loader->ins_pos; - face->forget_glyph_frame( loader ); - opened_frame = 0; - - /* if the flag FT_LOAD_NO_RECURSE is set, we return the subglyph */ - /* `as is' in the glyph slot (the client application will be */ - /* responsible for interpreting this data)... */ - /* */ - if ( loader->load_flags & FT_LOAD_NO_RECURSE ) - { - /* set up remaining glyph fields */ - FT_GlyphLoader_Add( gloader ); - - glyph->num_subglyphs = gloader->base.num_subglyphs; - glyph->format = ft_glyph_format_composite; - glyph->subglyphs = gloader->base.subglyphs; - - goto Exit; - } - - /*********************************************************************/ - /*********************************************************************/ - /*********************************************************************/ - - /* Now, read each subglyph independently. */ - { - FT_Int n, num_base_points, num_new_points; - FT_SubGlyph* subglyph = 0; - - FT_UInt num_subglyphs = gloader->current.num_subglyphs; - FT_UInt num_base_subgs = gloader->base.num_subglyphs; - - - FT_GlyphLoader_Add( gloader ); - - for ( n = 0; n < (FT_Int)num_subglyphs; n++ ) - { - FT_Vector pp1, pp2; - FT_Pos x, y; - - - /* Each time we call load_truetype_glyph in this loop, the */ - /* value of `gloader.base.subglyphs' can change due to table */ - /* reallocations. We thus need to recompute the subglyph */ - /* pointer on each iteration. */ - subglyph = gloader->base.subglyphs + num_base_subgs + n; - - pp1 = loader->pp1; - pp2 = loader->pp2; - - num_base_points = gloader->base.outline.n_points; - - error = load_truetype_glyph( loader, subglyph->index ); - if ( error ) - goto Fail; - - subglyph = gloader->base.subglyphs + num_base_subgs + n; - - if ( subglyph->flags & USE_MY_METRICS ) - { - pp1 = loader->pp1; - pp2 = loader->pp2; - } - else - { - loader->pp1 = pp1; - loader->pp2 = pp2; - } - - num_points = gloader->base.outline.n_points; - - num_new_points = num_points - num_base_points; - - /* now perform the transform required for this subglyph */ - - if ( subglyph->flags & ( WE_HAVE_A_SCALE | - WE_HAVE_AN_XY_SCALE | - WE_HAVE_A_2X2 ) ) - { - FT_Vector* cur = gloader->base.outline.points + - num_base_points; - FT_Vector* org = gloader->base.extra_points + - num_base_points; - FT_Vector* limit = cur + num_new_points; - - - for ( ; cur < limit; cur++, org++ ) - { - FT_Vector_Transform( cur, &subglyph->transform ); - FT_Vector_Transform( org, &subglyph->transform ); - } - } - - /* apply offset */ - - if ( !( subglyph->flags & ARGS_ARE_XY_VALUES ) ) - { - FT_UInt k = subglyph->arg1; - FT_UInt l = subglyph->arg2; - FT_Vector* p1; - FT_Vector* p2; - - - if ( start_point + k >= (FT_UInt)num_base_points || - l >= (FT_UInt)num_new_points ) - { - error = TT_Err_Invalid_Composite; - goto Fail; - } - - l += num_base_points; - - p1 = gloader->base.outline.points + start_point + k; - p2 = gloader->base.outline.points + start_point + l; - - x = p1->x - p2->x; - y = p1->y - p2->y; - } - else - { - x = subglyph->arg1; - y = subglyph->arg2; - - if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) ) - { - x = FT_MulFix( x, x_scale ); - y = FT_MulFix( y, y_scale ); - - if ( subglyph->flags & ROUND_XY_TO_GRID ) - { - x = ( x + 32 ) & -64; - y = ( y + 32 ) & -64; - } - } - } - - translate_array( num_new_points, loader->zone.cur, x, y ); - cur_to_org( num_new_points, &loader->zone ); - } - - /*******************************************************************/ - /*******************************************************************/ - /*******************************************************************/ - - /* we have finished loading all sub-glyphs; now, look for */ - /* instructions for this composite! */ - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - if ( num_subglyphs > 0 && - loader->exec && - ins_pos > 0 && - subglyph->flags & WE_HAVE_INSTR ) - { - FT_UShort n_ins; - TT_ExecContext exec = loader->exec; - TT_GlyphZone* pts; - FT_Vector* pp1; - - - /* read size of instructions */ - if ( FILE_Seek( ins_pos ) || - READ_UShort( n_ins ) ) - goto Fail; - FT_TRACE5(( " Instructions size = %d\n", n_ins )); - - /* in some fonts? */ - if ( n_ins == 0xFFFF ) - n_ins = 0; - - /* check it */ - if ( n_ins > face->max_profile.maxSizeOfInstructions ) - { - FT_TRACE0(( "Too many instructions (%d) in composite glyph %ld\n", - n_ins, subglyph->index )); - return TT_Err_Too_Many_Ins; - } - - /* read the instructions */ - if ( FILE_Read( exec->glyphIns, n_ins ) ) - goto Fail; - - glyph->control_data = exec->glyphIns; - glyph->control_len = n_ins; - - error = TT_Set_CodeRange( exec, - tt_coderange_glyph, - exec->glyphIns, - n_ins ); - if ( error ) - goto Fail; - - /* prepare the execution context */ - tt_prepare_zone( &exec->pts, &gloader->base, - start_point, start_contour ); - pts = &exec->pts; - - pts->n_points = num_points + 2; - pts->n_contours = gloader->base.outline.n_contours; - - /* add phantom points */ - pp1 = pts->cur + num_points; - pp1[0] = loader->pp1; - pp1[1] = loader->pp2; - - pts->tags[num_points ] = 0; - pts->tags[num_points + 1] = 0; - - /* if hinting, round the phantom points */ - if ( IS_HINTED( loader->load_flags ) ) - { - pp1[0].x = ( ( loader->pp1.x + 32 ) & -64 ); - pp1[1].x = ( ( loader->pp2.x + 32 ) & -64 ); - } - - { - FT_UInt k; - - - for ( k = 0; k < num_points; k++ ) - pts->tags[k] &= FT_Curve_Tag_On; - } - - cur_to_org( num_points + 2, pts ); - - /* now consider hinting */ - if ( IS_HINTED( loader->load_flags ) && n_ins > 0 ) - { - exec->is_composite = TRUE; - exec->pedantic_hinting = - (FT_Bool)( loader->load_flags & FT_LOAD_PEDANTIC ); - - error = TT_Run_Context( exec, ((TT_Size)loader->size)->debug ); - if ( error && exec->pedantic_hinting ) - goto Fail; - } - - /* save glyph origin and advance points */ - loader->pp1 = pp1[0]; - loader->pp2 = pp1[1]; - } - -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ - - } - /* end of composite loading */ - } - - /***********************************************************************/ - /***********************************************************************/ - /***********************************************************************/ - - Fail: - if ( opened_frame ) - face->forget_glyph_frame( loader ); - - Exit: - return error; - } - - - static - void compute_glyph_metrics( TT_Loader* loader, - FT_UInt glyph_index ) - { - FT_BBox bbox; - TT_Face face = (TT_Face)loader->face; - FT_Fixed x_scale, y_scale; - TT_GlyphSlot glyph = loader->glyph; - TT_Size size = (TT_Size)loader->size; - - - x_scale = 0x10000L; - y_scale = 0x10000L; - if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) - { - x_scale = size->root.metrics.x_scale; - y_scale = size->root.metrics.y_scale; - } - - if ( glyph->format != ft_glyph_format_composite ) - { - glyph->outline.flags &= ~ft_outline_single_pass; - - /* copy outline to our glyph slot */ - FT_GlyphLoader_Copy_Points( glyph->loader, loader->gloader ); - glyph->outline = glyph->loader->base.outline; - - /* translate array so that (0,0) is the glyph's origin */ - FT_Outline_Translate( &glyph->outline, -loader->pp1.x, 0 ); - - FT_Outline_Get_CBox( &glyph->outline, &bbox ); - - if ( IS_HINTED( loader->load_flags ) ) - { - /* grid-fit the bounding box */ - bbox.xMin &= -64; - bbox.yMin &= -64; - bbox.xMax = ( bbox.xMax + 63 ) & -64; - bbox.yMax = ( bbox.yMax + 63 ) & -64; - } - } - else - bbox = loader->bbox; - - /* get the device-independent horizontal advance. It is scaled later */ - /* by the base layer. */ - { - FT_Pos advance = loader->advance; - - - /* the flag FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH was introduced to */ - /* correctly support DynaLab fonts, which have an incorrect */ - /* `advance_Width_Max' field! It is used, to my knowledge, */ - /* exclusively in the X-TrueType font server. */ - /* */ - if ( face->postscript.isFixedPitch && - ( loader->load_flags & FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ) == 0 ) - advance = face->horizontal.advance_Width_Max; - - /* we need to return the advance in font units in linearHoriAdvance, */ - /* it will be scaled later by the base layer. */ - glyph->linearHoriAdvance = advance; - } - - glyph->metrics.horiBearingX = bbox.xMin; - glyph->metrics.horiBearingY = bbox.yMax; - glyph->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; - - /* Now take care of vertical metrics. In the case where there is */ - /* no vertical information within the font (relatively common), make */ - /* up some metrics by `hand'... */ - - { - FT_Short top_bearing; /* vertical top side bearing (EM units) */ - FT_UShort advance_height; /* vertical advance height (EM units) */ - - FT_Pos left; /* scaled vertical left side bearing */ - FT_Pos Top; /* scaled original vertical top side bearing */ - FT_Pos top; /* scaled vertical top side bearing */ - FT_Pos advance; /* scaled vertical advance height */ - - - /* Get the unscaled `tsb' and `ah' */ - if ( face->vertical_info && - face->vertical.number_Of_VMetrics > 0 ) - { - /* Don't assume that both the vertical header and vertical */ - /* metrics are present in the same font :-) */ - - TT_Get_Metrics( (TT_HoriHeader*)&face->vertical, - glyph_index, - &top_bearing, - &advance_height ); - } - else - { - /* Make up the distances from the horizontal header. */ - - /* NOTE: The OS/2 values are the only `portable' ones, */ - /* which is why we use them, if there is an OS/2 */ - /* table in the font. Otherwise, we use the */ - /* values defined in the horizontal header. */ - /* */ - /* NOTE2: The sTypoDescender is negative, which is why */ - /* we compute the baseline-to-baseline distance */ - /* here with: */ - /* ascender - descender + linegap */ - /* */ - if ( face->os2.version != 0xFFFF ) - { - top_bearing = face->os2.sTypoLineGap / 2; - advance_height = (FT_UShort)( face->os2.sTypoAscender - - face->os2.sTypoDescender + - face->os2.sTypoLineGap ); - } - else - { - top_bearing = face->horizontal.Line_Gap / 2; - advance_height = (FT_UShort)( face->horizontal.Ascender + - face->horizontal.Descender + - face->horizontal.Line_Gap ); - } - } - - /* We must adjust the top_bearing value from the bounding box given */ - /* in the glyph header to te bounding box calculated with */ - /* FT_Get_Outline_CBox(). */ - - /* scale the metrics */ - if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) ) - { - Top = FT_MulFix( top_bearing, y_scale ); - top = FT_MulFix( top_bearing + loader->bbox.yMax, y_scale ) - - bbox.yMax; - advance = FT_MulFix( advance_height, y_scale ); - } - else - { - Top = top_bearing; - top = top_bearing + loader->bbox.yMax - bbox.yMax; - advance = advance_height; - } - - /* set the advance height in design units. It is scaled later by */ - /* the base layer. */ - glyph->linearVertAdvance = advance_height; - - /* XXX: for now, we have no better algorithm for the lsb, but it */ - /* should work fine. */ - /* */ - left = ( bbox.xMin - bbox.xMax ) / 2; - - /* grid-fit them if necessary */ - if ( IS_HINTED( loader->load_flags ) ) - { - left &= -64; - top = ( top + 63 ) & -64; - advance = ( advance + 32 ) & -64; - } - - glyph->metrics.vertBearingX = left; - glyph->metrics.vertBearingY = top; - glyph->metrics.vertAdvance = advance; - } - - /* adjust advance width to the value contained in the hdmx table */ - if ( !face->postscript.isFixedPitch && size && - IS_HINTED( loader->load_flags ) ) - { - FT_Byte* widths = Get_Advance_Widths( face, - size->root.metrics.x_ppem ); - - - if ( widths ) - glyph->metrics.horiAdvance = widths[glyph_index] << 6; - } - - /* set glyph dimensions */ - glyph->metrics.width = bbox.xMax - bbox.xMin; - glyph->metrics.height = bbox.yMax - bbox.yMin; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Glyph */ - /* */ - /* */ - /* A function used to load a single glyph within a given glyph slot, */ - /* for a given size. */ - /* */ - /* */ - /* glyph :: A handle to a target slot object where the glyph */ - /* will be loaded. */ - /* */ - /* size :: A handle to the source face size at which the glyph */ - /* must be scaled/loaded. */ - /* */ - /* glyph_index :: The index of the glyph in the font file. */ - /* */ - /* load_flags :: A flag indicating what to load for this glyph. The */ - /* FT_LOAD_XXX constants can be used to control the */ - /* glyph loading process (e.g., whether the outline */ - /* should be scaled, whether to load bitmaps or not, */ - /* whether to hint the outline, etc). */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_Glyph( TT_Size size, - TT_GlyphSlot glyph, - FT_UShort glyph_index, - FT_UInt load_flags ) - { - SFNT_Interface* sfnt; - TT_Face face; - FT_Stream stream; - FT_Memory memory; - FT_Error error; - TT_Loader loader; - - - face = (TT_Face)glyph->face; - sfnt = (SFNT_Interface*)face->sfnt; - stream = face->root.stream; - memory = face->root.memory; - error = 0; - - if ( !size || ( load_flags & FT_LOAD_NO_SCALE ) || - ( load_flags & FT_LOAD_NO_RECURSE ) ) - { - size = NULL; - load_flags |= FT_LOAD_NO_SCALE | - FT_LOAD_NO_HINTING | - FT_LOAD_NO_BITMAP; - } - - glyph->num_subglyphs = 0; - -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - - /* try to load embedded bitmap if any */ - if ( size && - ( load_flags & FT_LOAD_NO_BITMAP ) == 0 && - sfnt->load_sbits ) - { - TT_SBit_Metrics metrics; - - - error = sfnt->load_sbit_image( face, - size->root.metrics.x_ppem, - size->root.metrics.y_ppem, - glyph_index, - load_flags, - stream, - &glyph->bitmap, - &metrics ); - if ( !error ) - { - glyph->outline.n_points = 0; - glyph->outline.n_contours = 0; - - glyph->metrics.width = (FT_Pos)metrics.width << 6; - glyph->metrics.height = (FT_Pos)metrics.height << 6; - - glyph->metrics.horiBearingX = (FT_Pos)metrics.horiBearingX << 6; - glyph->metrics.horiBearingY = (FT_Pos)metrics.horiBearingY << 6; - glyph->metrics.horiAdvance = (FT_Pos)metrics.horiAdvance << 6; - - glyph->metrics.vertBearingX = (FT_Pos)metrics.vertBearingX << 6; - glyph->metrics.vertBearingY = (FT_Pos)metrics.vertBearingY << 6; - glyph->metrics.vertAdvance = (FT_Pos)metrics.vertAdvance << 6; - - glyph->format = ft_glyph_format_bitmap; - if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) - { - glyph->bitmap_left = metrics.vertBearingX; - glyph->bitmap_top = metrics.vertBearingY; - } - else - { - glyph->bitmap_left = metrics.horiBearingX; - glyph->bitmap_top = metrics.horiBearingY; - } - return error; - } - } - -#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ - - /* seek to the beginning of the glyph table. For Type 42 fonts */ - /* the table might be accessed from a Postscript stream or something */ - /* else... */ - - error = face->goto_table( face, TTAG_glyf, stream, 0 ); - if ( error ) - { - FT_ERROR(( "TT_Load_Glyph: could not access glyph table\n" )); - goto Exit; - } - - MEM_Set( &loader, 0, sizeof ( loader ) ); - - /* update the glyph zone bounds */ - { - FT_GlyphLoader* gloader = FT_FACE_DRIVER(face)->glyph_loader; - - - loader.gloader = gloader; - - FT_GlyphLoader_Rewind( gloader ); - - tt_prepare_zone( &loader.zone, &gloader->base, 0, 0 ); - tt_prepare_zone( &loader.base, &gloader->base, 0, 0 ); - } - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - if ( size ) - { - /* query new execution context */ - loader.exec = size->debug ? size->context : TT_New_Context( face ); - if ( !loader.exec ) - return TT_Err_Could_Not_Find_Context; - - TT_Load_Context( loader.exec, face, size ); - loader.instructions = loader.exec->glyphIns; - - /* load default graphics state - if needed */ - if ( size->GS.instruct_control & 2 ) - loader.exec->GS = tt_default_graphics_state; - } - -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ - - /* clear all outline flags, except the `owner' one */ - glyph->outline.flags = 0; - - if ( size && size->root.metrics.y_ppem < 24 ) - glyph->outline.flags |= ft_outline_high_precision; - - /* let's initialize the rest of our loader now */ - - loader.load_flags = load_flags; - - loader.face = (FT_Face)face; - loader.size = (FT_Size)size; - loader.glyph = (FT_GlyphSlot)glyph; - loader.stream = stream; - - loader.glyf_offset = FILE_Pos(); - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - /* if the cvt program has disabled hinting, the argument */ - /* is ignored. */ - if ( size && ( size->GS.instruct_control & 1 ) ) - loader.load_flags |= FT_LOAD_NO_HINTING; - -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ - - /* Main loading loop */ - glyph->format = ft_glyph_format_outline; - glyph->num_subglyphs = 0; - error = load_truetype_glyph( &loader, glyph_index ); - if ( !error ) - compute_glyph_metrics( &loader, glyph_index ); - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - if ( !size || !size->debug ) - TT_Done_Context( loader.exec ); - -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ - - Exit: - return error; - } - - -/* END */ diff --git a/src/freetype/truetype/ttgload.h b/src/freetype/truetype/ttgload.h deleted file mode 100644 index 2f3e96b7b0..0000000000 --- a/src/freetype/truetype/ttgload.h +++ /dev/null @@ -1,69 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttgload.h */ -/* */ -/* TrueType Glyph Loader (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifndef TTGLOAD_H -#define TTGLOAD_H - - -#ifdef FT_FLAT_COMPILE - -#include "ttobjs.h" - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER -#include "ttinterp.h" -#endif - -#else /* FT_FLAT_COMPILE */ - -#include - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER -#include -#endif - -#endif /* FT_FLAT_COMPILE */ - - -#ifdef __cplusplus - extern "C" { -#endif - - - LOCAL_DEF - void TT_Get_Metrics( TT_HoriHeader* header, - FT_UInt index, - FT_Short* bearing, - FT_UShort* advance ); - - LOCAL_DEF - void TT_Init_Glyph_Loading( TT_Face face ); - - LOCAL_DEF - FT_Error TT_Load_Glyph( TT_Size size, - TT_GlyphSlot glyph, - FT_UShort glyph_index, - FT_UInt load_flags ); - -#ifdef __cplusplus - } -#endif - -#endif /* TTGLOAD_H */ - - -/* END */ diff --git a/src/freetype/truetype/ttinterp.c b/src/freetype/truetype/ttinterp.c deleted file mode 100644 index 9dc0c190a7..0000000000 --- a/src/freetype/truetype/ttinterp.c +++ /dev/null @@ -1,7544 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttinterp.c */ -/* */ -/* TrueType bytecode interpreter (body). */ -/* */ -/* 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 -#include -#include - - -#ifdef FT_FLAT_COMPILE - -#include "ttinterp.h" - -#else - -#include - -#endif - - -#include - - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - -#define TT_MULFIX FT_MulFix -#define TT_MULDIV FT_MulDiv - -#define TT_INT64 FT_Int64 - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_ttinterp - -#undef NO_APPLE_PATENT -#define APPLE_THRESHOLD 0x4000000L - - /*************************************************************************/ - /* */ - /* In order to detect infinite loops in the code, we set up a counter */ - /* within the run loop. A single stroke of interpretation is now */ - /* limitet to a maximal number of opcodes defined below. */ - /* */ -#define MAX_RUNNABLE_OPCODES 1000000L - - - /*************************************************************************/ - /* */ - /* There are two kinds of implementations: */ - /* */ - /* a. static implementation */ - /* */ - /* The current execution context is a static variable, which fields */ - /* are accessed directly by the interpreter during execution. The */ - /* context is named `cur'. */ - /* */ - /* This version is non-reentrant, of course. */ - /* */ - /* b. indirect implementation */ - /* */ - /* The current execution context is passed to _each_ function as its */ - /* first argument, and each field is thus accessed indirectly. */ - /* */ - /* This version is fully re-entrant. */ - /* */ - /* The idea is that an indirect implementation may be slower to execute */ - /* on low-end processors that are used in some systems (like 386s or */ - /* even 486s). */ - /* */ - /* As a consequence, the indirect implementation is now the default, as */ - /* its performance costs can be considered negligible in our context. */ - /* Note, however, that we kept the same source with macros because: */ - /* */ - /* - The code is kept very close in design to the Pascal code used for */ - /* development. */ - /* */ - /* - It's much more readable that way! */ - /* */ - /* - It's still open to experimentation and tuning. */ - /* */ - /*************************************************************************/ - - -#ifndef TT_CONFIG_OPTION_STATIC_INTERPRETER /* indirect implementation */ - -#define CUR (*exc) /* see ttobjs.h */ - -#else /* static implementation */ - -#define CUR cur - - static - TT_ExecContextRec cur; /* static exec. context variable */ - - /* apparently, we have a _lot_ of direct indexing when accessing */ - /* the static `cur', which makes the code bigger (due to all the */ - /* four bytes addresses). */ - -#endif /* TT_CONFIG_OPTION_STATIC_INTERPRETER */ - - - /*************************************************************************/ - /* */ - /* The instruction argument stack. */ - /* */ -#define INS_ARG EXEC_OP_ FT_Long* args /* see ttobjs.h for EXEC_OP_ */ - - - /*************************************************************************/ - /* */ - /* This macro is used whenever `exec' is unused in a function, to avoid */ - /* stupid warnings from pedantic compilers. */ - /* */ -#define FT_UNUSED_EXEC FT_UNUSED( CUR ) - - - /*************************************************************************/ - /* */ - /* This macro is used whenever `args' is unused in a function, to avoid */ - /* stupid warnings from pedantic compilers. */ - /* */ -#define FT_UNUSED_ARG FT_UNUSED_EXEC; FT_UNUSED( args ) - - - /*************************************************************************/ - /* */ - /* The following macros hide the use of EXEC_ARG and EXEC_ARG_ to */ - /* increase readabilty of the code. */ - /* */ - /*************************************************************************/ - - -#define SKIP_Code() \ - SkipCode( EXEC_ARG ) - -#define GET_ShortIns() \ - GetShortIns( EXEC_ARG ) - -#define NORMalize( x, y, v ) \ - Normalize( EXEC_ARG_ x, y, v ) - -#define SET_SuperRound( scale, flags ) \ - SetSuperRound( EXEC_ARG_ scale, flags ) - -#define ROUND_None( d, c ) \ - Round_None( EXEC_ARG_ d, c ) - -#define INS_Goto_CodeRange( range, ip ) \ - Ins_Goto_CodeRange( EXEC_ARG_ range, ip ) - -#define CUR_Func_project( x, y ) \ - CUR.func_project( EXEC_ARG_ x, y ) - -#define CUR_Func_move( z, p, d ) \ - CUR.func_move( EXEC_ARG_ z, p, d ) - -#define CUR_Func_dualproj( x, y ) \ - CUR.func_dualproj( EXEC_ARG_ x, y ) - -#define CUR_Func_freeProj( x, y ) \ - CUR.func_freeProj( EXEC_ARG_ x, y ) - -#define CUR_Func_round( d, c ) \ - CUR.func_round( EXEC_ARG_ d, c ) - -#define CUR_Func_read_cvt( index ) \ - CUR.func_read_cvt( EXEC_ARG_ index ) - -#define CUR_Func_write_cvt( index, val ) \ - CUR.func_write_cvt( EXEC_ARG_ index, val ) - -#define CUR_Func_move_cvt( index, val ) \ - CUR.func_move_cvt( EXEC_ARG_ index, val ) - -#define CURRENT_Ratio() \ - Current_Ratio( EXEC_ARG ) - -#define CURRENT_Ppem() \ - Current_Ppem( EXEC_ARG ) - -#define CUR_Ppem() \ - Cur_PPEM( EXEC_ARG ) - -#define CALC_Length() \ - Calc_Length( EXEC_ARG ) - -#define INS_SxVTL( a, b, c, d ) \ - Ins_SxVTL( EXEC_ARG_ a, b, c, d ) - -#define COMPUTE_Funcs() \ - Compute_Funcs( EXEC_ARG ) - -#define COMPUTE_Round( a ) \ - Compute_Round( EXEC_ARG_ a ) - -#define COMPUTE_Point_Displacement( a, b, c, d ) \ - Compute_Point_Displacement( EXEC_ARG_ a, b, c, d ) - -#define MOVE_Zp2_Point( a, b, c, t ) \ - Move_Zp2_Point( EXEC_ARG_ a, b, c, t ) - - - /*************************************************************************/ - /* */ - /* Instruction dispatch function, as used by the interpreter. */ - /* */ - typedef void (*TInstruction_Function)( INS_ARG ); - - - /*************************************************************************/ - /* */ - /* A simple bounds-checking macro. */ - /* */ -#define BOUNDS( x, n ) ( (FT_UInt)(x) >= (FT_UInt)(n) ) - - -#undef SUCCESS -#define SUCCESS 0 - -#undef FAILURE -#define FAILURE 1 - - - /*************************************************************************/ - /* */ - /* CODERANGE FUNCTIONS */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Goto_CodeRange */ - /* */ - /* */ - /* Switches to a new code range (updates the code related elements in */ - /* `exec', and `IP'). */ - /* */ - /* */ - /* range :: The new execution code range. */ - /* */ - /* IP :: The new IP in the new code range. */ - /* */ - /* */ - /* exec :: The target execution context. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Goto_CodeRange( TT_ExecContext exec, - FT_Int range, - FT_Long IP ) - { - TT_CodeRange* coderange; - - - FT_Assert( range >= 1 && range <= 3 ); - - coderange = &exec->codeRangeTable[range - 1]; - - FT_Assert( coderange->base != NULL ); - - /* NOTE: Because the last instruction of a program may be a CALL */ - /* which will return to the first byte *after* the code */ - /* range, we test for IP <= Size instead of IP < Size. */ - /* */ - FT_Assert( (FT_ULong)IP <= coderange->size ); - - exec->code = coderange->base; - exec->codeSize = coderange->size; - exec->IP = IP; - exec->curRange = range; - - return TT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Set_CodeRange */ - /* */ - /* */ - /* Sets a code range. */ - /* */ - /* */ - /* range :: The code range index. */ - /* */ - /* base :: The new code base. */ - /* */ - /* length :: The range size in bytes. */ - /* */ - /* */ - /* exec :: The target execution context. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Set_CodeRange( TT_ExecContext exec, - FT_Int range, - void* base, - FT_Long length ) - { - FT_Assert( range >= 1 && range <= 3 ); - - exec->codeRangeTable[range - 1].base = (FT_Byte*)base; - exec->codeRangeTable[range - 1].size = length; - - return TT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Clear_CodeRange */ - /* */ - /* */ - /* Clears a code range. */ - /* */ - /* */ - /* range :: The code range index. */ - /* */ - /* */ - /* exec :: The target execution context. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Does not set the Error variable. */ - /* */ - LOCAL_FUNC - FT_Error TT_Clear_CodeRange( TT_ExecContext exec, - FT_Int range ) - { - FT_Assert( range >= 1 && range <= 3 ); - - exec->codeRangeTable[range - 1].base = NULL; - exec->codeRangeTable[range - 1].size = 0; - - return TT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* EXECUTION CONTEXT ROUTINES */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Destroy_Context */ - /* */ - /* */ - /* Destroys a given context. */ - /* */ - /* */ - /* exec :: A handle to the target execution context. */ - /* */ - /* memory :: A handle to the parent memory object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Only the glyph loader and debugger should call this function. */ - /* */ - LOCAL_FUNC - FT_Error TT_Destroy_Context( TT_ExecContext exec, - FT_Memory memory ) - { - /* free composite load stack */ - FREE( exec->loadStack ); - exec->loadSize = 0; - - /* points zone */ - exec->maxPoints = 0; - exec->maxContours = 0; - - /* free stack */ - FREE( exec->stack ); - exec->stackSize = 0; - - /* free call stack */ - FREE( exec->callStack ); - exec->callSize = 0; - exec->callTop = 0; - - /* free glyph code range */ - FREE( exec->glyphIns ); - exec->glyphSize = 0; - - exec->size = NULL; - exec->face = NULL; - - FREE( exec ); - return TT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Init_Context */ - /* */ - /* */ - /* Initializes a context object. */ - /* */ - /* */ - /* memory :: A handle to the parent memory object. */ - /* */ - /* face :: A handle to the source TrueType face object. */ - /* */ - /* */ - /* exec :: A handle to the target execution context. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error Init_Context( TT_ExecContext exec, - TT_Face face, - FT_Memory memory ) - { - FT_Error error; - - - FT_TRACE1(( "Init_Context: new object at 0x%08p, parent = 0x%08p\n", - exec, face )); - - exec->memory = memory; - exec->callSize = 32; - - if ( ALLOC_ARRAY( exec->callStack, exec->callSize, TT_CallRec ) ) - goto Fail_Memory; - - /* all values in the context are set to 0 already, but this is */ - /* here as a remainder */ - exec->maxPoints = 0; - exec->maxContours = 0; - - exec->stackSize = 0; - exec->loadSize = 0; - exec->glyphSize = 0; - - exec->stack = NULL; - exec->loadStack = NULL; - exec->glyphIns = NULL; - - exec->face = face; - exec->size = NULL; - - return TT_Err_Ok; - - Fail_Memory: - FT_ERROR(( "Init_Context: not enough memory for 0x%08lx\n", - (FT_Long)exec )); - TT_Destroy_Context( exec, memory ); - - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Update_Max */ - /* */ - /* */ - /* Checks the size of a buffer and reallocates it if necessary. */ - /* */ - /* */ - /* memory :: A handle to the parent memory object. */ - /* */ - /* multiplier :: The size in bytes of each element in the buffer. */ - /* */ - /* new_max :: The new capacity (size) of the buffer. */ - /* */ - /* */ - /* size :: The address of the buffer's current size expressed */ - /* in elements. */ - /* */ - /* buff :: The address of the buffer base pointer. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error Update_Max( FT_Memory memory, - FT_ULong* size, - FT_Long multiplier, - void** buff, - FT_ULong new_max ) - { - FT_Error error; - - - if ( *size < new_max ) - { - FREE( *buff ); - if ( ALLOC( *buff, new_max * multiplier ) ) - return error; - *size = new_max; - } - - return TT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Context */ - /* */ - /* */ - /* Prepare an execution context for glyph hinting. */ - /* */ - /* */ - /* face :: A handle to the source face object. */ - /* */ - /* size :: A handle to the source size object. */ - /* */ - /* */ - /* exec :: A handle to the target execution context. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Only the glyph loader and debugger should call this function. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_Context( TT_ExecContext exec, - TT_Face face, - TT_Size size ) - { - FT_Int i; - FT_ULong tmp; - TT_MaxProfile* maxp; - FT_Error error; - - - exec->face = face; - maxp = &face->max_profile; - exec->size = size; - - if ( size ) - { - exec->numFDefs = size->num_function_defs; - exec->maxFDefs = size->max_function_defs; - exec->numIDefs = size->num_instruction_defs; - exec->maxIDefs = size->max_instruction_defs; - exec->FDefs = size->function_defs; - exec->IDefs = size->instruction_defs; - exec->tt_metrics = size->ttmetrics; - exec->metrics = size->root.metrics; - - exec->maxFunc = size->max_func; - exec->maxIns = size->max_ins; - - for ( i = 0; i < TT_MAX_CODE_RANGES; i++ ) - exec->codeRangeTable[i] = size->codeRangeTable[i]; - - /* set graphics state */ - exec->GS = size->GS; - - exec->cvtSize = size->cvt_size; - exec->cvt = size->cvt; - - exec->storeSize = size->storage_size; - exec->storage = size->storage; - - exec->twilight = size->twilight; - } - - error = Update_Max( exec->memory, - &exec->loadSize, - sizeof ( TT_SubGlyphRec ), - (void**)&exec->loadStack, - exec->face->max_components + 1 ); - if ( error ) - return error; - - /* XXX: We reserve a little more elements on the stack to deal safely */ - /* with broken fonts like arialbs, courbs, timesbs, etc. */ - tmp = exec->stackSize; - error = Update_Max( exec->memory, - &tmp, - sizeof ( FT_F26Dot6 ), - (void**)&exec->stack, - maxp->maxStackElements + 32 ); - exec->stackSize = (FT_UInt)tmp; - if ( error ) - return error; - - tmp = exec->glyphSize; - error = Update_Max( exec->memory, - &tmp, - sizeof ( FT_Byte ), - (void**)&exec->glyphIns, - maxp->maxSizeOfInstructions ); - exec->glyphSize = (FT_UShort)tmp; - if ( error ) - return error; - - exec->pts.n_points = 0; - exec->pts.n_contours = 0; - - exec->instruction_trap = FALSE; - - return TT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Save_Context */ - /* */ - /* */ - /* Saves the code ranges in a `size' object. */ - /* */ - /* */ - /* exec :: A handle to the source execution context. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Only the glyph loader and debugger should call this function. */ - /* */ - LOCAL_FUNC - FT_Error TT_Save_Context( TT_ExecContext exec, - TT_Size size ) - { - FT_Int i; - - - /* XXXX: Will probably disappear soon with all the code range */ - /* management, which is now rather obsolete. */ - /* */ - size->num_function_defs = exec->numFDefs; - size->num_instruction_defs = exec->numIDefs; - - size->max_func = exec->maxFunc; - size->max_ins = exec->maxIns; - - for ( i = 0; i < TT_MAX_CODE_RANGES; i++ ) - size->codeRangeTable[i] = exec->codeRangeTable[i]; - - return TT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Run_Context */ - /* */ - /* */ - /* Executes one or more instructions in the execution context. */ - /* */ - /* */ - /* debug :: A Boolean flag. If set, the function sets some internal */ - /* variables and returns immediately, otherwise TT_RunIns() */ - /* is called. */ - /* */ - /* This is commented out currently. */ - /* */ - /* */ - /* exec :: A handle to the target execution context. */ - /* */ - /* */ - /* TrueTyoe error code. 0 means success. */ - /* */ - /* */ - /* Only the glyph loader and debugger should call this function. */ - /* */ - LOCAL_FUNC - FT_Error TT_Run_Context( TT_ExecContext exec, - FT_Bool debug ) - { - FT_Error error; - - - if ( ( error = TT_Goto_CodeRange( exec, tt_coderange_glyph, 0 ) ) - != TT_Err_Ok ) - return error; - - exec->zp0 = exec->pts; - exec->zp1 = exec->pts; - exec->zp2 = exec->pts; - - exec->GS.gep0 = 1; - exec->GS.gep1 = 1; - exec->GS.gep2 = 1; - - exec->GS.projVector.x = 0x4000; - exec->GS.projVector.y = 0x0000; - - exec->GS.freeVector = exec->GS.projVector; - exec->GS.dualVector = exec->GS.projVector; - - exec->GS.round_state = 1; - exec->GS.loop = 1; - - /* some glyphs leave something on the stack. so we clean it */ - /* before a new execution. */ - exec->top = 0; - exec->callTop = 0; - -#if 1 - FT_UNUSED( debug ); - - return exec->face->interpreter( exec ); -#else - if ( !debug ) - return TT_RunIns( exec ); - else - return TT_Err_Ok; -#endif - } - - - const TT_GraphicsState tt_default_graphics_state = - { - 0, 0, 0, - { 0x4000, 0 }, - { 0x4000, 0 }, - { 0x4000, 0 }, - 1, 64, 1, - TRUE, 68, 0, 0, 9, 3, - 0, FALSE, 2, 1, 1, 1 - }; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_New_Context */ - /* */ - /* */ - /* Queries the face context for a given font. Note that there is */ - /* now a _single_ execution context in the TrueType driver which is */ - /* shared among faces. */ - /* */ - /* */ - /* face :: A handle to the source face object. */ - /* */ - /* */ - /* A handle to the execution context. Initialized for `face'. */ - /* */ - /* */ - /* Only the glyph loader and debugger should call this function. */ - /* */ - FT_EXPORT_FUNC( TT_ExecContext ) TT_New_Context( TT_Face face ) - { - TT_Driver driver; - TT_ExecContext exec; - FT_Memory memory; - - - if ( !face ) - return 0; - - driver = (TT_Driver)face->root.driver; - - memory = driver->root.root.memory; - exec = driver->context; - - if ( !driver->context ) - { - FT_Error error; - - - /* allocate object */ - if ( ALLOC( exec, sizeof ( *exec ) ) ) - goto Exit; - - /* initialize it */ - error = Init_Context( exec, face, memory ); - if ( error ) - goto Fail; - - /* store it into the driver */ - driver->context = exec; - } - - Exit: - return driver->context; - - Fail: - FREE( exec ); - - return 0; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Done_Context */ - /* */ - /* */ - /* Discards an execution context. */ - /* */ - /* */ - /* exec :: A handle to the target execution context. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Only the glyph loader and debugger should call this function. */ - /* */ - LOCAL_FUNC - FT_Error TT_Done_Context( TT_ExecContext exec ) - { - /* Nothing at all for now */ - FT_UNUSED( exec ); - - return TT_Err_Ok; - } - - -#ifdef FT_CONFIG_OPTION_OLD_CALCS - - static FT_F26Dot6 Norm( FT_F26Dot6 X, - FT_F26Dot6 Y ) - { - TT_INT64 T1, T2; - - - MUL_64( X, X, T1 ); - MUL_64( Y, Y, T2 ); - - ADD_64( T1, T2, T1 ); - - return (FT_F26Dot6)SQRT_64( T1 ); - } - -#endif /* FT_CONFIG_OPTION_OLD_CALCS */ - - - /*************************************************************************/ - /* */ - /* Before an opcode is executed, the interpreter verifies that there are */ - /* enough arguments on the stack, with the help of the Pop_Push_Count */ - /* table. */ - /* */ - /* For each opcode, the first column gives the number of arguments that */ - /* are popped from the stack; the second one gives the number of those */ - /* that are pushed in result. */ - /* */ - /* Note that for opcodes with a varying number of parameters, either 0 */ - /* or 1 arg is verified before execution, depending on the nature of the */ - /* instruction: */ - /* */ - /* - if the number of arguments is given by the bytecode stream or the */ - /* loop variable, 0 is chosen. */ - /* */ - /* - if the first argument is a count n that is followed by arguments */ - /* a1 .. an, then 1 is chosen. */ - /* */ - /*************************************************************************/ - - -#undef PACK -#define PACK( x, y ) ( ( x << 4 ) | y ) - - - static - const FT_Byte Pop_Push_Count[256] = - { - /* opcodes are gathered in groups of 16 */ - /* please keep the spaces as they are */ - - /* SVTCA y */ PACK( 0, 0 ), - /* SVTCA x */ PACK( 0, 0 ), - /* SPvTCA y */ PACK( 0, 0 ), - /* SPvTCA x */ PACK( 0, 0 ), - /* SFvTCA y */ PACK( 0, 0 ), - /* SFvTCA x */ PACK( 0, 0 ), - /* SPvTL // */ PACK( 2, 0 ), - /* SPvTL + */ PACK( 2, 0 ), - /* SFvTL // */ PACK( 2, 0 ), - /* SFvTL + */ PACK( 2, 0 ), - /* SPvFS */ PACK( 2, 0 ), - /* SFvFS */ PACK( 2, 0 ), - /* GPV */ PACK( 0, 2 ), - /* GFV */ PACK( 0, 2 ), - /* SFvTPv */ PACK( 0, 0 ), - /* ISECT */ PACK( 5, 0 ), - - /* SRP0 */ PACK( 1, 0 ), - /* SRP1 */ PACK( 1, 0 ), - /* SRP2 */ PACK( 1, 0 ), - /* SZP0 */ PACK( 1, 0 ), - /* SZP1 */ PACK( 1, 0 ), - /* SZP2 */ PACK( 1, 0 ), - /* SZPS */ PACK( 1, 0 ), - /* SLOOP */ PACK( 1, 0 ), - /* RTG */ PACK( 0, 0 ), - /* RTHG */ PACK( 0, 0 ), - /* SMD */ PACK( 1, 0 ), - /* ELSE */ PACK( 0, 0 ), - /* JMPR */ PACK( 1, 0 ), - /* SCvTCi */ PACK( 1, 0 ), - /* SSwCi */ PACK( 1, 0 ), - /* SSW */ PACK( 1, 0 ), - - /* DUP */ PACK( 1, 2 ), - /* POP */ PACK( 1, 0 ), - /* CLEAR */ PACK( 0, 0 ), - /* SWAP */ PACK( 2, 2 ), - /* DEPTH */ PACK( 0, 1 ), - /* CINDEX */ PACK( 1, 1 ), - /* MINDEX */ PACK( 1, 0 ), - /* AlignPTS */ PACK( 2, 0 ), - /* INS_$28 */ PACK( 0, 0 ), - /* UTP */ PACK( 1, 0 ), - /* LOOPCALL */ PACK( 2, 0 ), - /* CALL */ PACK( 1, 0 ), - /* FDEF */ PACK( 1, 0 ), - /* ENDF */ PACK( 0, 0 ), - /* MDAP[0] */ PACK( 1, 0 ), - /* MDAP[1] */ PACK( 1, 0 ), - - /* IUP[0] */ PACK( 0, 0 ), - /* IUP[1] */ PACK( 0, 0 ), - /* SHP[0] */ PACK( 0, 0 ), - /* SHP[1] */ PACK( 0, 0 ), - /* SHC[0] */ PACK( 1, 0 ), - /* SHC[1] */ PACK( 1, 0 ), - /* SHZ[0] */ PACK( 1, 0 ), - /* SHZ[1] */ PACK( 1, 0 ), - /* SHPIX */ PACK( 1, 0 ), - /* IP */ PACK( 0, 0 ), - /* MSIRP[0] */ PACK( 2, 0 ), - /* MSIRP[1] */ PACK( 2, 0 ), - /* AlignRP */ PACK( 0, 0 ), - /* RTDG */ PACK( 0, 0 ), - /* MIAP[0] */ PACK( 2, 0 ), - /* MIAP[1] */ PACK( 2, 0 ), - - /* NPushB */ PACK( 0, 0 ), - /* NPushW */ PACK( 0, 0 ), - /* WS */ PACK( 2, 0 ), - /* RS */ PACK( 1, 1 ), - /* WCvtP */ PACK( 2, 0 ), - /* RCvt */ PACK( 1, 1 ), - /* GC[0] */ PACK( 1, 1 ), - /* GC[1] */ PACK( 1, 1 ), - /* SCFS */ PACK( 2, 0 ), - /* MD[0] */ PACK( 2, 1 ), - /* MD[1] */ PACK( 2, 1 ), - /* MPPEM */ PACK( 0, 1 ), - /* MPS */ PACK( 0, 1 ), - /* FlipON */ PACK( 0, 0 ), - /* FlipOFF */ PACK( 0, 0 ), - /* DEBUG */ PACK( 1, 0 ), - - /* LT */ PACK( 2, 1 ), - /* LTEQ */ PACK( 2, 1 ), - /* GT */ PACK( 2, 1 ), - /* GTEQ */ PACK( 2, 1 ), - /* EQ */ PACK( 2, 1 ), - /* NEQ */ PACK( 2, 1 ), - /* ODD */ PACK( 1, 1 ), - /* EVEN */ PACK( 1, 1 ), - /* IF */ PACK( 1, 0 ), - /* EIF */ PACK( 0, 0 ), - /* AND */ PACK( 2, 1 ), - /* OR */ PACK( 2, 1 ), - /* NOT */ PACK( 1, 1 ), - /* DeltaP1 */ PACK( 1, 0 ), - /* SDB */ PACK( 1, 0 ), - /* SDS */ PACK( 1, 0 ), - - /* ADD */ PACK( 2, 1 ), - /* SUB */ PACK( 2, 1 ), - /* DIV */ PACK( 2, 1 ), - /* MUL */ PACK( 2, 1 ), - /* ABS */ PACK( 1, 1 ), - /* NEG */ PACK( 1, 1 ), - /* FLOOR */ PACK( 1, 1 ), - /* CEILING */ PACK( 1, 1 ), - /* ROUND[0] */ PACK( 1, 1 ), - /* ROUND[1] */ PACK( 1, 1 ), - /* ROUND[2] */ PACK( 1, 1 ), - /* ROUND[3] */ PACK( 1, 1 ), - /* NROUND[0] */ PACK( 1, 1 ), - /* NROUND[1] */ PACK( 1, 1 ), - /* NROUND[2] */ PACK( 1, 1 ), - /* NROUND[3] */ PACK( 1, 1 ), - - /* WCvtF */ PACK( 2, 0 ), - /* DeltaP2 */ PACK( 1, 0 ), - /* DeltaP3 */ PACK( 1, 0 ), - /* DeltaCn[0] */ PACK( 1, 0 ), - /* DeltaCn[1] */ PACK( 1, 0 ), - /* DeltaCn[2] */ PACK( 1, 0 ), - /* SROUND */ PACK( 1, 0 ), - /* S45Round */ PACK( 1, 0 ), - /* JROT */ PACK( 2, 0 ), - /* JROF */ PACK( 2, 0 ), - /* ROFF */ PACK( 0, 0 ), - /* INS_$7B */ PACK( 0, 0 ), - /* RUTG */ PACK( 0, 0 ), - /* RDTG */ PACK( 0, 0 ), - /* SANGW */ PACK( 1, 0 ), - /* AA */ PACK( 1, 0 ), - - /* FlipPT */ PACK( 0, 0 ), - /* FlipRgON */ PACK( 2, 0 ), - /* FlipRgOFF */ PACK( 2, 0 ), - /* INS_$83 */ PACK( 0, 0 ), - /* INS_$84 */ PACK( 0, 0 ), - /* ScanCTRL */ PACK( 1, 0 ), - /* SDVPTL[0] */ PACK( 2, 0 ), - /* SDVPTL[1] */ PACK( 2, 0 ), - /* GetINFO */ PACK( 1, 1 ), - /* IDEF */ PACK( 1, 0 ), - /* ROLL */ PACK( 3, 3 ), - /* MAX */ PACK( 2, 1 ), - /* MIN */ PACK( 2, 1 ), - /* ScanTYPE */ PACK( 1, 0 ), - /* InstCTRL */ PACK( 2, 0 ), - /* INS_$8F */ PACK( 0, 0 ), - - /* INS_$90 */ PACK( 0, 0 ), - /* INS_$91 */ PACK( 0, 0 ), - /* INS_$92 */ PACK( 0, 0 ), - /* INS_$93 */ PACK( 0, 0 ), - /* INS_$94 */ PACK( 0, 0 ), - /* INS_$95 */ PACK( 0, 0 ), - /* INS_$96 */ PACK( 0, 0 ), - /* INS_$97 */ PACK( 0, 0 ), - /* INS_$98 */ PACK( 0, 0 ), - /* INS_$99 */ PACK( 0, 0 ), - /* INS_$9A */ PACK( 0, 0 ), - /* INS_$9B */ PACK( 0, 0 ), - /* INS_$9C */ PACK( 0, 0 ), - /* INS_$9D */ PACK( 0, 0 ), - /* INS_$9E */ PACK( 0, 0 ), - /* INS_$9F */ PACK( 0, 0 ), - - /* INS_$A0 */ PACK( 0, 0 ), - /* INS_$A1 */ PACK( 0, 0 ), - /* INS_$A2 */ PACK( 0, 0 ), - /* INS_$A3 */ PACK( 0, 0 ), - /* INS_$A4 */ PACK( 0, 0 ), - /* INS_$A5 */ PACK( 0, 0 ), - /* INS_$A6 */ PACK( 0, 0 ), - /* INS_$A7 */ PACK( 0, 0 ), - /* INS_$A8 */ PACK( 0, 0 ), - /* INS_$A9 */ PACK( 0, 0 ), - /* INS_$AA */ PACK( 0, 0 ), - /* INS_$AB */ PACK( 0, 0 ), - /* INS_$AC */ PACK( 0, 0 ), - /* INS_$AD */ PACK( 0, 0 ), - /* INS_$AE */ PACK( 0, 0 ), - /* INS_$AF */ PACK( 0, 0 ), - - /* PushB[0] */ PACK( 0, 1 ), - /* PushB[1] */ PACK( 0, 2 ), - /* PushB[2] */ PACK( 0, 3 ), - /* PushB[3] */ PACK( 0, 4 ), - /* PushB[4] */ PACK( 0, 5 ), - /* PushB[5] */ PACK( 0, 6 ), - /* PushB[6] */ PACK( 0, 7 ), - /* PushB[7] */ PACK( 0, 8 ), - /* PushW[0] */ PACK( 0, 1 ), - /* PushW[1] */ PACK( 0, 2 ), - /* PushW[2] */ PACK( 0, 3 ), - /* PushW[3] */ PACK( 0, 4 ), - /* PushW[4] */ PACK( 0, 5 ), - /* PushW[5] */ PACK( 0, 6 ), - /* PushW[6] */ PACK( 0, 7 ), - /* PushW[7] */ PACK( 0, 8 ), - - /* MDRP[00] */ PACK( 1, 0 ), - /* MDRP[01] */ PACK( 1, 0 ), - /* MDRP[02] */ PACK( 1, 0 ), - /* MDRP[03] */ PACK( 1, 0 ), - /* MDRP[04] */ PACK( 1, 0 ), - /* MDRP[05] */ PACK( 1, 0 ), - /* MDRP[06] */ PACK( 1, 0 ), - /* MDRP[07] */ PACK( 1, 0 ), - /* MDRP[08] */ PACK( 1, 0 ), - /* MDRP[09] */ PACK( 1, 0 ), - /* MDRP[10] */ PACK( 1, 0 ), - /* MDRP[11] */ PACK( 1, 0 ), - /* MDRP[12] */ PACK( 1, 0 ), - /* MDRP[13] */ PACK( 1, 0 ), - /* MDRP[14] */ PACK( 1, 0 ), - /* MDRP[15] */ PACK( 1, 0 ), - - /* MDRP[16] */ PACK( 1, 0 ), - /* MDRP[17] */ PACK( 1, 0 ), - /* MDRP[18] */ PACK( 1, 0 ), - /* MDRP[19] */ PACK( 1, 0 ), - /* MDRP[20] */ PACK( 1, 0 ), - /* MDRP[21] */ PACK( 1, 0 ), - /* MDRP[22] */ PACK( 1, 0 ), - /* MDRP[23] */ PACK( 1, 0 ), - /* MDRP[24] */ PACK( 1, 0 ), - /* MDRP[25] */ PACK( 1, 0 ), - /* MDRP[26] */ PACK( 1, 0 ), - /* MDRP[27] */ PACK( 1, 0 ), - /* MDRP[28] */ PACK( 1, 0 ), - /* MDRP[29] */ PACK( 1, 0 ), - /* MDRP[30] */ PACK( 1, 0 ), - /* MDRP[31] */ PACK( 1, 0 ), - - /* MIRP[00] */ PACK( 2, 0 ), - /* MIRP[01] */ PACK( 2, 0 ), - /* MIRP[02] */ PACK( 2, 0 ), - /* MIRP[03] */ PACK( 2, 0 ), - /* MIRP[04] */ PACK( 2, 0 ), - /* MIRP[05] */ PACK( 2, 0 ), - /* MIRP[06] */ PACK( 2, 0 ), - /* MIRP[07] */ PACK( 2, 0 ), - /* MIRP[08] */ PACK( 2, 0 ), - /* MIRP[09] */ PACK( 2, 0 ), - /* MIRP[10] */ PACK( 2, 0 ), - /* MIRP[11] */ PACK( 2, 0 ), - /* MIRP[12] */ PACK( 2, 0 ), - /* MIRP[13] */ PACK( 2, 0 ), - /* MIRP[14] */ PACK( 2, 0 ), - /* MIRP[15] */ PACK( 2, 0 ), - - /* MIRP[16] */ PACK( 2, 0 ), - /* MIRP[17] */ PACK( 2, 0 ), - /* MIRP[18] */ PACK( 2, 0 ), - /* MIRP[19] */ PACK( 2, 0 ), - /* MIRP[20] */ PACK( 2, 0 ), - /* MIRP[21] */ PACK( 2, 0 ), - /* MIRP[22] */ PACK( 2, 0 ), - /* MIRP[23] */ PACK( 2, 0 ), - /* MIRP[24] */ PACK( 2, 0 ), - /* MIRP[25] */ PACK( 2, 0 ), - /* MIRP[26] */ PACK( 2, 0 ), - /* MIRP[27] */ PACK( 2, 0 ), - /* MIRP[28] */ PACK( 2, 0 ), - /* MIRP[29] */ PACK( 2, 0 ), - /* MIRP[30] */ PACK( 2, 0 ), - /* MIRP[31] */ PACK( 2, 0 ) - }; - - - static - const FT_Char opcode_length[256] = - { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - -1,-1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 3, 4, 5, 6, 7, 8, 9, 3, 5, 7, 9, 11,13,15,17, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 - }; - - static - const FT_Vector Null_Vector = {0,0}; - - -#undef PACK - - -#undef NULL_Vector -#define NULL_Vector (FT_Vector*)&Null_Vector - - - /*************************************************************************/ - /* */ - /* */ - /* Current_Ratio */ - /* */ - /* */ - /* Returns the current aspect ratio scaling factor depending on the */ - /* projection vector's state and device resolutions. */ - /* */ - /* */ - /* The aspect ratio in 16.16 format, always <= 1.0 . */ - /* */ - static - FT_Long Current_Ratio( EXEC_OP ) - { - if ( CUR.tt_metrics.ratio ) - return CUR.tt_metrics.ratio; - - if ( CUR.GS.projVector.y == 0 ) - CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio; - - else if ( CUR.GS.projVector.x == 0 ) - CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio; - - else - { - FT_Long x, y; - - -#ifdef FT_CONFIG_OPTION_OLD_CALCS - - x = TT_MULDIV( CUR.GS.projVector.x, CUR.tt_metrics.x_ratio, 0x4000 ); - y = TT_MULDIV( CUR.GS.projVector.y, CUR.tt_metrics.y_ratio, 0x4000 ); - CUR.tt_metrics.ratio = Norm( x, y ); - -#else - - x = TT_MULDIV( CUR.GS.projVector.x, CUR.tt_metrics.x_ratio, 0x8000 ); - y = TT_MULDIV( CUR.GS.projVector.y, CUR.tt_metrics.y_ratio, 0x8000 ); - CUR.tt_metrics.ratio = FT_Sqrt32( x * x + y * y ) << 1; - -#endif /* FT_CONFIG_OPTION_OLD_CALCS */ - - } - - return CUR.tt_metrics.ratio; - } - - - static - FT_Long Current_Ppem( EXEC_OP ) - { - return TT_MULFIX( CUR.tt_metrics.ppem, CURRENT_Ratio() ); - } - - - /*************************************************************************/ - /* */ - /* Functions related to the control value table (CVT). */ - /* */ - /*************************************************************************/ - - - static - FT_F26Dot6 Read_CVT( EXEC_OP_ FT_ULong index ) - { - return CUR.cvt[index]; - } - - - static - FT_F26Dot6 Read_CVT_Stretched( EXEC_OP_ FT_ULong index ) - { - return TT_MULFIX( CUR.cvt[index], CURRENT_Ratio() ); - } - - - static - void Write_CVT( EXEC_OP_ FT_ULong index, - FT_F26Dot6 value ) - { - CUR.cvt[index] = value; - } - - - static - void Write_CVT_Stretched( EXEC_OP_ FT_ULong index, - FT_F26Dot6 value ) - { - CUR.cvt[index] = FT_DivFix( value, CURRENT_Ratio() ); - } - - - static - void Move_CVT( EXEC_OP_ FT_ULong index, - FT_F26Dot6 value ) - { - CUR.cvt[index] += value; - } - - - static - void Move_CVT_Stretched( EXEC_OP_ FT_ULong index, - FT_F26Dot6 value ) - { - CUR.cvt[index] += FT_DivFix( value, CURRENT_Ratio() ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* GetShortIns */ - /* */ - /* */ - /* Returns a short integer taken from the instruction stream at */ - /* address IP. */ - /* */ - /* */ - /* Short read at code[IP]. */ - /* */ - /* */ - /* This one could become a macro. */ - /* */ - static FT_Short GetShortIns( EXEC_OP ) - { - /* Reading a byte stream so there is no endianess (DaveP) */ - CUR.IP += 2; - return (FT_Short)( ( CUR.code[CUR.IP - 2] << 8 ) + - CUR.code[CUR.IP - 1] ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* Ins_Goto_CodeRange */ - /* */ - /* */ - /* Goes to a certain code range in the instruction stream. */ - /* */ - /* */ - /* aRange :: The index of the code range. */ - /* */ - /* aIP :: The new IP address in the code range. */ - /* */ - /* */ - /* SUCCESS or FAILURE. */ - /* */ - static - FT_Bool Ins_Goto_CodeRange( EXEC_OP_ FT_Int aRange, - FT_ULong aIP ) - { - TT_CodeRange* range; - - - if ( aRange < 1 || aRange > 3 ) - { - CUR.error = TT_Err_Bad_Argument; - return FAILURE; - } - - range = &CUR.codeRangeTable[aRange - 1]; - - if ( range->base == NULL ) /* invalid coderange */ - { - CUR.error = TT_Err_Invalid_CodeRange; - return FAILURE; - } - - /* NOTE: Because the last instruction of a program may be a CALL */ - /* which will return to the first byte *after* the code */ - /* range, we test for AIP <= Size, instead of AIP < Size. */ - - if ( aIP > range->size ) - { - CUR.error = TT_Err_Code_Overflow; - return FAILURE; - } - - CUR.code = range->base; - CUR.codeSize = range->size; - CUR.IP = aIP; - CUR.curRange = aRange; - - return SUCCESS; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Direct_Move */ - /* */ - /* */ - /* Moves a point by a given distance along the freedom vector. The */ - /* point will be `touched'. */ - /* */ - /* */ - /* point :: The index of the point to move. */ - /* */ - /* distance :: The distance to apply. */ - /* */ - /* */ - /* zone :: The affected glyph zone. */ - /* */ - static - void Direct_Move( EXEC_OP_ TT_GlyphZone* zone, - FT_UShort point, - FT_F26Dot6 distance ) - { - FT_F26Dot6 v; - - - v = CUR.GS.freeVector.x; - - if ( v != 0 ) - { - -#ifdef NO_APPLE_PATENT - - if ( ABS( CUR.F_dot_P ) > APPLE_THRESHOLD ) - zone->cur[point].x += distance; - -#else - - zone->cur[point].x += TT_MULDIV( distance, - v * 0x10000L, - CUR.F_dot_P ); - -#endif - - zone->tags[point] |= FT_Curve_Tag_Touch_X; - } - - v = CUR.GS.freeVector.y; - - if ( v != 0 ) - { - -#ifdef NO_APPLE_PATENT - - if ( ABS( CUR.F_dot_P ) > APPLE_THRESHOLD ) - zone->cur[point].y += distance; - -#else - - zone->cur[point].y += TT_MULDIV( distance, - v * 0x10000L, - CUR.F_dot_P ); - -#endif - - zone->tags[point] |= FT_Curve_Tag_Touch_Y; - } - } - - - /*************************************************************************/ - /* */ - /* Special versions of Direct_Move() */ - /* */ - /* The following versions are used whenever both vectors are both */ - /* along one of the coordinate unit vectors, i.e. in 90% of the cases. */ - /* */ - /*************************************************************************/ - - - static - void Direct_Move_X( EXEC_OP_ TT_GlyphZone* zone, - FT_UShort point, - FT_F26Dot6 distance ) - { - FT_UNUSED_EXEC; - - zone->cur[point].x += distance; - zone->tags[point] |= FT_Curve_Tag_Touch_X; - } - - - static - void Direct_Move_Y( EXEC_OP_ TT_GlyphZone* zone, - FT_UShort point, - FT_F26Dot6 distance ) - { - FT_UNUSED_EXEC; - - zone->cur[point].y += distance; - zone->tags[point] |= FT_Curve_Tag_Touch_Y; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Round_None */ - /* */ - /* */ - /* Does not round, but adds engine compensation. */ - /* */ - /* */ - /* distance :: The distance (not) to round. */ - /* */ - /* compensation :: The engine compensation. */ - /* */ - /* */ - /* The compensated distance. */ - /* */ - /* */ - /* The TrueType specification says very few about the relationship */ - /* between rounding and engine compensation. However, it seems from */ - /* the description of super round that we should add the compensation */ - /* before rounding. */ - /* */ - static - FT_F26Dot6 Round_None( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) - { - FT_F26Dot6 val; - - FT_UNUSED_EXEC; - - - if ( distance >= 0 ) - { - val = distance + compensation; - if ( val < 0 ) - val = 0; - } - else { - val = distance - compensation; - if ( val > 0 ) - val = 0; - } - return val; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Round_To_Grid */ - /* */ - /* */ - /* Rounds value to grid after adding engine compensation. */ - /* */ - /* */ - /* distance :: The distance to round. */ - /* */ - /* compensation :: The engine compensation. */ - /* */ - /* */ - /* Rounded distance. */ - /* */ - static - FT_F26Dot6 Round_To_Grid( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) - { - FT_F26Dot6 val; - - FT_UNUSED_EXEC; - - - if ( distance >= 0 ) - { - val = distance + compensation + 32; - if ( val > 0 ) - val &= ~63; - else - val = 0; - } - else - { - val = -( ( compensation - distance + 32 ) & -64 ); - if ( val > 0 ) - val = 0; - } - - return val; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Round_To_Half_Grid */ - /* */ - /* */ - /* Rounds value to half grid after adding engine compensation. */ - /* */ - /* */ - /* distance :: The distance to round. */ - /* */ - /* compensation :: The engine compensation. */ - /* */ - /* */ - /* Rounded distance. */ - /* */ - static - FT_F26Dot6 Round_To_Half_Grid( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) - { - FT_F26Dot6 val; - - FT_UNUSED_EXEC; - - - if ( distance >= 0 ) - { - val = ( ( distance + compensation ) & -64 ) + 32; - if ( val < 0 ) - val = 0; - } - else - { - val = -( ( (compensation - distance) & -64 ) + 32 ); - if ( val > 0 ) - val = 0; - } - - return val; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Round_Down_To_Grid */ - /* */ - /* */ - /* Rounds value down to grid after adding engine compensation. */ - /* */ - /* */ - /* distance :: The distance to round. */ - /* */ - /* compensation :: The engine compensation. */ - /* */ - /* */ - /* Rounded distance. */ - /* */ - static - FT_F26Dot6 Round_Down_To_Grid( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) - { - FT_F26Dot6 val; - - FT_UNUSED_EXEC; - - - if ( distance >= 0 ) - { - val = distance + compensation; - if ( val > 0 ) - val &= ~63; - else - val = 0; - } - else - { - val = -( ( compensation - distance ) & -64 ); - if ( val > 0 ) - val = 0; - } - - return val; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Round_Up_To_Grid */ - /* */ - /* */ - /* Rounds value up to grid after adding engine compensation. */ - /* */ - /* */ - /* distance :: The distance to round. */ - /* */ - /* compensation :: The engine compensation. */ - /* */ - /* */ - /* Rounded distance. */ - /* */ - static - FT_F26Dot6 Round_Up_To_Grid( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) - { - FT_F26Dot6 val; - - - FT_UNUSED_EXEC; - - if ( distance >= 0 ) - { - val = distance + compensation + 63; - if ( val > 0 ) - val &= ~63; - else - val = 0; - } - else - { - val = -( ( compensation - distance + 63 ) & -64 ); - if ( val > 0 ) - val = 0; - } - - return val; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Round_To_Double_Grid */ - /* */ - /* */ - /* Rounds value to double grid after adding engine compensation. */ - /* */ - /* */ - /* distance :: The distance to round. */ - /* */ - /* compensation :: The engine compensation. */ - /* */ - /* */ - /* Rounded distance. */ - /* */ - static - FT_F26Dot6 Round_To_Double_Grid( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) - { - FT_F26Dot6 val; - - FT_UNUSED_EXEC; - - - if ( distance >= 0 ) - { - val = distance + compensation + 16; - if ( val > 0 ) - val &= ~31; - else - val = 0; - } - else - { - val = -( ( compensation - distance + 16 ) & -32 ); - if ( val > 0 ) - val = 0; - } - - return val; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Round_Super */ - /* */ - /* */ - /* Super-rounds value to grid after adding engine compensation. */ - /* */ - /* */ - /* distance :: The distance to round. */ - /* */ - /* compensation :: The engine compensation. */ - /* */ - /* */ - /* Rounded distance. */ - /* */ - /* */ - /* The TrueType specification says very few about the relationship */ - /* between rounding and engine compensation. However, it seems from */ - /* the description of super round that we should add the compensation */ - /* before rounding. */ - /* */ - static - FT_F26Dot6 Round_Super( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) - { - FT_F26Dot6 val; - - - if ( distance >= 0 ) - { - val = ( distance - CUR.phase + CUR.threshold + compensation ) & - -CUR.period; - if ( val < 0 ) - val = 0; - val += CUR.phase; - } - else - { - val = -( ( CUR.threshold - CUR.phase - distance + compensation ) & - -CUR.period ); - if ( val > 0 ) - val = 0; - val -= CUR.phase; - } - - return val; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Round_Super_45 */ - /* */ - /* */ - /* Super-rounds value to grid after adding engine compensation. */ - /* */ - /* */ - /* distance :: The distance to round. */ - /* */ - /* compensation :: The engine compensation. */ - /* */ - /* */ - /* Rounded distance. */ - /* */ - /* */ - /* There is a separate function for Round_Super_45() as we may need */ - /* greater precision. */ - /* */ - static - FT_F26Dot6 Round_Super_45( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) - { - FT_F26Dot6 val; - - - if ( distance >= 0 ) - { - val = ( ( distance - CUR.phase + CUR.threshold + compensation ) / - CUR.period ) * CUR.period; - if ( val < 0 ) - val = 0; - val += CUR.phase; - } - else - { - val = -( ( ( CUR.threshold - CUR.phase - distance + compensation ) / - CUR.period ) * CUR.period ); - if ( val > 0 ) - val = 0; - val -= CUR.phase; - } - - return val; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Compute_Round */ - /* */ - /* */ - /* Sets the rounding mode. */ - /* */ - /* */ - /* round_mode :: The rounding mode to be used. */ - /* */ - static - void Compute_Round( EXEC_OP_ FT_Byte round_mode ) - { - switch ( round_mode ) - { - case TT_Round_Off: - CUR.func_round = (TT_Round_Func)Round_None; - break; - - case TT_Round_To_Grid: - CUR.func_round = (TT_Round_Func)Round_To_Grid; - break; - - case TT_Round_Up_To_Grid: - CUR.func_round = (TT_Round_Func)Round_Up_To_Grid; - break; - - case TT_Round_Down_To_Grid: - CUR.func_round = (TT_Round_Func)Round_Down_To_Grid; - break; - - case TT_Round_To_Half_Grid: - CUR.func_round = (TT_Round_Func)Round_To_Half_Grid; - break; - - case TT_Round_To_Double_Grid: - CUR.func_round = (TT_Round_Func)Round_To_Double_Grid; - break; - - case TT_Round_Super: - CUR.func_round = (TT_Round_Func)Round_Super; - break; - - case TT_Round_Super_45: - CUR.func_round = (TT_Round_Func)Round_Super_45; - break; - } - } - - - /*************************************************************************/ - /* */ - /* */ - /* SetSuperRound */ - /* */ - /* */ - /* Sets Super Round parameters. */ - /* */ - /* */ - /* GridPeriod :: Grid period */ - /* selector :: SROUND opcode */ - /* */ - static - void SetSuperRound( EXEC_OP_ FT_F26Dot6 GridPeriod, - FT_Long selector ) - { - switch ( (FT_Int)( selector & 0xC0 ) ) - { - case 0: - CUR.period = GridPeriod / 2; - break; - - case 0x40: - CUR.period = GridPeriod; - break; - - case 0x80: - CUR.period = GridPeriod * 2; - break; - - /* This opcode is reserved, but... */ - - case 0xC0: - CUR.period = GridPeriod; - break; - } - - switch ( (FT_Int)( selector & 0x30 ) ) - { - case 0: - CUR.phase = 0; - break; - - case 0x10: - CUR.phase = CUR.period / 4; - break; - - case 0x20: - CUR.phase = CUR.period / 2; - break; - - case 0x30: - CUR.phase = GridPeriod * 3 / 4; - break; - } - - if ( (selector & 0x0F) == 0 ) - CUR.threshold = CUR.period - 1; - else - CUR.threshold = ( (FT_Int)( selector & 0x0F ) - 4 ) * CUR.period / 8; - - CUR.period /= 256; - CUR.phase /= 256; - CUR.threshold /= 256; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Project */ - /* */ - /* */ - /* Computes the projection of vector given by (v2-v1) along the */ - /* current projection vector. */ - /* */ - /* */ - /* v1 :: First input vector. */ - /* v2 :: Second input vector. */ - /* */ - /* */ - /* The distance in F26dot6 format. */ - /* */ - static - FT_F26Dot6 Project( EXEC_OP_ FT_Vector* v1, - FT_Vector* v2 ) - { - return TT_MULDIV( v1->x - v2->x, CUR.GS.projVector.x, 0x4000 ) + - TT_MULDIV( v1->y - v2->y, CUR.GS.projVector.y, 0x4000 ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* Dual_Project */ - /* */ - /* */ - /* Computes the projection of the vector given by (v2-v1) along the */ - /* current dual vector. */ - /* */ - /* */ - /* v1 :: First input vector. */ - /* v2 :: Second input vector. */ - /* */ - /* */ - /* The distance in F26dot6 format. */ - /* */ - static - FT_F26Dot6 Dual_Project( EXEC_OP_ FT_Vector* v1, - FT_Vector* v2 ) - { - return TT_MULDIV( v1->x - v2->x, CUR.GS.dualVector.x, 0x4000 ) + - TT_MULDIV( v1->y - v2->y, CUR.GS.dualVector.y, 0x4000 ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* Free_Project */ - /* */ - /* */ - /* Computes the projection of the vector given by (v2-v1) along the */ - /* current freedom vector. */ - /* */ - /* */ - /* v1 :: First input vector. */ - /* v2 :: Second input vector. */ - /* */ - /* */ - /* The distance in F26dot6 format. */ - /* */ - static - FT_F26Dot6 Free_Project( EXEC_OP_ FT_Vector* v1, - FT_Vector* v2 ) - { - return TT_MULDIV( v1->x - v2->x, CUR.GS.freeVector.x, 0x4000 ) + - TT_MULDIV( v1->y - v2->y, CUR.GS.freeVector.y, 0x4000 ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* Project_x */ - /* */ - /* */ - /* Computes the projection of the vector given by (v2-v1) along the */ - /* horizontal axis. */ - /* */ - /* */ - /* v1 :: First input vector. */ - /* v2 :: Second input vector. */ - /* */ - /* */ - /* The distance in F26dot6 format. */ - /* */ - static - FT_F26Dot6 Project_x( EXEC_OP_ FT_Vector* v1, - FT_Vector* v2 ) - { - FT_UNUSED_EXEC; - - return ( v1->x - v2->x ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* Project_y */ - /* */ - /* */ - /* Computes the projection of the vector given by (v2-v1) along the */ - /* vertical axis. */ - /* */ - /* */ - /* v1 :: First input vector. */ - /* v2 :: Second input vector. */ - /* */ - /* */ - /* The distance in F26dot6 format. */ - /* */ - static - FT_F26Dot6 Project_y( EXEC_OP_ FT_Vector* v1, - FT_Vector* v2 ) - { - FT_UNUSED_EXEC; - - return ( v1->y - v2->y ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* Compute_Funcs */ - /* */ - /* */ - /* Computes the projection and movement function pointers according */ - /* to the current graphics state. */ - /* */ - static - void Compute_Funcs( EXEC_OP ) - { - if ( CUR.GS.freeVector.x == 0x4000 ) - { - CUR.func_freeProj = (TT_Project_Func)Project_x; - CUR.F_dot_P = CUR.GS.projVector.x * 0x10000L; - } - else - { - if ( CUR.GS.freeVector.y == 0x4000 ) - { - CUR.func_freeProj = (TT_Project_Func)Project_y; - CUR.F_dot_P = CUR.GS.projVector.y * 0x10000L; - } - else - { - CUR.func_freeProj = (TT_Project_Func)Free_Project; - CUR.F_dot_P = (FT_Long)CUR.GS.projVector.x * CUR.GS.freeVector.x * 4 + - (FT_Long)CUR.GS.projVector.y * CUR.GS.freeVector.y * 4; - } - } - - if ( CUR.GS.projVector.x == 0x4000 ) - CUR.func_project = (TT_Project_Func)Project_x; - else - { - if ( CUR.GS.projVector.y == 0x4000 ) - CUR.func_project = (TT_Project_Func)Project_y; - else - CUR.func_project = (TT_Project_Func)Project; - } - - if ( CUR.GS.dualVector.x == 0x4000 ) - CUR.func_dualproj = (TT_Project_Func)Project_x; - else - { - if ( CUR.GS.dualVector.y == 0x4000 ) - CUR.func_dualproj = (TT_Project_Func)Project_y; - else - CUR.func_dualproj = (TT_Project_Func)Dual_Project; - } - - CUR.func_move = (TT_Move_Func)Direct_Move; - - if ( CUR.F_dot_P == 0x40000000L ) - { - if ( CUR.GS.freeVector.x == 0x4000 ) - CUR.func_move = (TT_Move_Func)Direct_Move_X; - else - { - if ( CUR.GS.freeVector.y == 0x4000 ) - CUR.func_move = (TT_Move_Func)Direct_Move_Y; - } - } - - /* at small sizes, F_dot_P can become too small, resulting */ - /* in overflows and `spikes' in a number of glyphs like `w'. */ - - if ( ABS( CUR.F_dot_P ) < 0x4000000L ) - CUR.F_dot_P = 0x40000000L; - - /* Disable cached aspect ratio */ - CUR.tt_metrics.ratio = 0; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Normalize */ - /* */ - /* */ - /* Norms a vector. */ - /* */ - /* */ - /* Vx :: The horizontal input vector coordinate. */ - /* Vy :: The vertical input vector coordinate. */ - /* */ - /* */ - /* R :: The normed unit vector. */ - /* */ - /* */ - /* Returns FAILURE if a vector parameter is zero. */ - /* */ - /* */ - /* In case Vx and Vy are both zero, Normalize() returns SUCCESS, and */ - /* R is undefined. */ - /* */ - -#ifdef FT_CONFIG_OPTION_OLD_CALCS - - static - FT_Bool Normalize( EXEC_OP_ FT_F26Dot6 Vx, - FT_F26Dot6 Vy, - FT_UnitVector* R ) - { - FT_F26Dot6 W; - FT_Bool S1, S2; - - FT_UNUSED_EXEC; - - - if ( ABS( Vx ) < 0x10000L && ABS( Vy ) < 0x10000L ) - { - Vx *= 0x100; - Vy *= 0x100; - - W = Norm( Vx, Vy ); - - if ( W == 0 ) - { - /* XXX: UNDOCUMENTED! It seems that it is possible to try */ - /* to normalize the vector (0,0). Return immediately. */ - return SUCCESS; - } - - R->x = (FT_F2Dot14)FT_MulDiv( Vx, 0x4000L, W ); - R->y = (FT_F2Dot14)FT_MulDiv( Vy, 0x4000L, W ); - - return SUCCESS; - } - - W = Norm( Vx, Vy ); - - Vx = FT_MulDiv( Vx, 0x4000L, W ); - Vy = FT_MulDiv( Vy, 0x4000L, W ); - - W = Vx * Vx + Vy * Vy; - - /* Now, we want that Sqrt( W ) = 0x4000 */ - /* Or 0x1000000 <= W < 0x1004000 */ - - if ( Vx < 0 ) - { - Vx = -Vx; - S1 = TRUE; - } - else - S1 = FALSE; - - if ( Vy < 0 ) - { - Vy = -Vy; - S2 = TRUE; - } - else - S2 = FALSE; - - while ( W < 0x1000000L ) - { - /* We need to increase W by a minimal amount */ - if ( Vx < Vy ) - Vx++; - else - Vy++; - - W = Vx * Vx + Vy * Vy; - } - - while ( W >= 0x1004000L ) - { - /* We need to decrease W by a minimal amount */ - if ( Vx < Vy ) - Vx--; - else - Vy--; - - W = Vx * Vx + Vy * Vy; - } - - /* Note that in various cases, we can only */ - /* compute a Sqrt(W) of 0x3FFF, eg. Vx = Vy */ - - if ( S1 ) - Vx = -Vx; - - if ( S2 ) - Vy = -Vy; - - R->x = (FT_F2Dot14)Vx; /* Type conversion */ - R->y = (FT_F2Dot14)Vy; /* Type conversion */ - - return SUCCESS; - } - -#else - - static - FT_Bool Normalize( EXEC_OP_ FT_F26Dot6 Vx, - FT_F26Dot6 Vy, - FT_UnitVector* R ) - { - FT_F26Dot6 u, v, d; - FT_Int shift; - FT_ULong H, L, L2, hi, lo, med; - - - u = ABS( Vx ); - v = ABS( Vy ); - - if ( u < v ) - { - d = u; - u = v; - v = d; - } - - R->x = 0; - R->y = 0; - - /* check that we are not trying to normalise zero! */ - if ( u == 0 ) - return SUCCESS; - - /* compute (u*u + v*v) on 64 bits with two 32-bit registers [H:L] */ - hi = (FT_ULong)u >> 16; - lo = (FT_ULong)u & 0xFFFF; - med = hi * lo; - - H = hi * hi + ( med >> 15 ); - med <<= 17; - L = lo * lo + med; - if ( L < med ) - H++; - - hi = (FT_ULong)v >> 16; - lo = (FT_ULong)v & 0xFFFF; - med = hi * lo; - - H += hi * hi + ( med >> 15 ); - med <<= 17; - L2 = lo * lo + med; - if ( L2 < med ) - H++; - - L += L2; - if ( L < L2 ) - H++; - - /* if the value is smaller than 32-bits */ - if ( H == 0 ) - { - shift = 0; - while ( ( L & 0xC0000000L ) == 0 ) - { - L <<= 2; - shift++; - } - - d = FT_Sqrt32( L ); - R->x = (FT_F2Dot14)TT_MULDIV( Vx << shift, 0x4000, d ); - R->y = (FT_F2Dot14)TT_MULDIV( Vy << shift, 0x4000, d ); - } - /* if the value is greater than 64-bits */ - else - { - shift = 0; - while ( H ) - { - L = ( L >> 2 ) | ( H << 30 ); - H >>= 2; - shift++; - } - - d = FT_Sqrt32( L ); - R->x = (FT_F2Dot14)TT_MULDIV( Vx >> shift, 0x4000, d ); - R->y = (FT_F2Dot14)TT_MULDIV( Vy >> shift, 0x4000, d ); - } - - { - FT_ULong x, y, w; - FT_Int sx, sy; - - - sx = R->x >= 0 ? 1 : -1; - sy = R->y >= 0 ? 1 : -1; - x = (FT_ULong)sx * R->x; - y = (FT_ULong)sy * R->y; - - w = x * x + y * y; - - /* we now want to adjust (x,y) in order to have sqrt(w) == 0x4000 */ - /* which means 0x1000000 <= w < 0x1004000 */ - while ( w <= 0x10000000L ) - { - /* increment the smallest coordinate */ - if ( x < y ) - x++; - else - y++; - - w = x * x + y * y; - } - - while ( w >= 0x10040000L ) - { - /* decrement the smallest coordinate */ - if ( x < y ) - x--; - else - y--; - - w = x * x + y * y; - } - - R->x = sx * x; - R->y = sy * y; - } - - return SUCCESS; - } - -#endif /* FT_CONFIG_OPTION_OLD_CALCS */ - - - /*************************************************************************/ - /* */ - /* Here we start with the implementation of the various opcodes. */ - /* */ - /*************************************************************************/ - - - static - FT_Bool Ins_SxVTL( EXEC_OP_ FT_UShort aIdx1, - FT_UShort aIdx2, - FT_Int aOpc, - FT_UnitVector* Vec ) - { - FT_Long A, B, C; - FT_Vector* p1; - FT_Vector* p2; - - - if ( BOUNDS( aIdx1, CUR.zp2.n_points ) || - BOUNDS( aIdx2, CUR.zp1.n_points ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = TT_Err_Invalid_Reference; - return FAILURE; - } - - p1 = CUR.zp1.cur + aIdx2; - p2 = CUR.zp2.cur + aIdx1; - - A = p1->x - p2->x; - B = p1->y - p2->y; - - if ( ( aOpc & 1 ) != 0 ) - { - C = B; /* counter clockwise rotation */ - B = A; - A = -C; - } - - NORMalize( A, B, Vec ); - - return SUCCESS; - } - - - /* When not using the big switch statements, the interpreter uses a */ - /* call table defined later below in this source. Each opcode must */ - /* thus have a corresponding function, even trivial ones. */ - /* */ - /* They are all defined there. */ - -#define DO_SVTCA \ - { \ - FT_Short A, B; \ - \ - \ - A = (FT_Short)( CUR.opcode & 1 ) << 14; \ - B = A ^ (FT_Short)0x4000; \ - \ - CUR.GS.freeVector.x = A; \ - CUR.GS.projVector.x = A; \ - CUR.GS.dualVector.x = A; \ - \ - CUR.GS.freeVector.y = B; \ - CUR.GS.projVector.y = B; \ - CUR.GS.dualVector.y = B; \ - \ - COMPUTE_Funcs(); \ - } - - -#define DO_SPVTCA \ - { \ - FT_Short A, B; \ - \ - \ - A = (FT_Short)( CUR.opcode & 1 ) << 14; \ - B = A ^ (FT_Short)0x4000; \ - \ - CUR.GS.projVector.x = A; \ - CUR.GS.dualVector.x = A; \ - \ - CUR.GS.projVector.y = B; \ - CUR.GS.dualVector.y = B; \ - \ - COMPUTE_Funcs(); \ - } - - -#define DO_SFVTCA \ - { \ - FT_Short A, B; \ - \ - \ - A = (FT_Short)( CUR.opcode & 1 ) << 14; \ - B = A ^ (FT_Short)0x4000; \ - \ - CUR.GS.freeVector.x = A; \ - CUR.GS.freeVector.y = B; \ - \ - COMPUTE_Funcs(); \ - } - - -#define DO_SPVTL \ - if ( INS_SxVTL( (FT_UShort)args[1], \ - (FT_UShort)args[0], \ - CUR.opcode, \ - &CUR.GS.projVector ) == SUCCESS ) \ - { \ - CUR.GS.dualVector = CUR.GS.projVector; \ - COMPUTE_Funcs(); \ - } - - -#define DO_SFVTL \ - if ( INS_SxVTL( (FT_UShort)args[1], \ - (FT_UShort)args[0], \ - CUR.opcode, \ - &CUR.GS.freeVector ) == SUCCESS ) \ - COMPUTE_Funcs(); - - -#define DO_SFVTPV \ - CUR.GS.freeVector = CUR.GS.projVector; \ - COMPUTE_Funcs(); - - -#define DO_SPVFS \ - { \ - FT_Short S; \ - FT_Long X, Y; \ - \ - \ - /* Only use low 16bits, then sign extend */ \ - S = (FT_Short)args[1]; \ - Y = (FT_Long)S; \ - S = (FT_Short)args[0]; \ - X = (FT_Long)S; \ - \ - NORMalize( X, Y, &CUR.GS.projVector ); \ - \ - CUR.GS.dualVector = CUR.GS.projVector; \ - COMPUTE_Funcs(); \ - } - - -#define DO_SFVFS \ - { \ - FT_Short S; \ - FT_Long X, Y; \ - \ - \ - /* Only use low 16bits, then sign extend */ \ - S = (FT_Short)args[1]; \ - Y = (FT_Long)S; \ - S = (FT_Short)args[0]; \ - X = S; \ - \ - NORMalize( X, Y, &CUR.GS.freeVector ); \ - COMPUTE_Funcs(); \ - } - - -#define DO_GPV \ - args[0] = CUR.GS.projVector.x; \ - args[1] = CUR.GS.projVector.y; - - -#define DO_GFV \ - args[0] = CUR.GS.freeVector.x; \ - args[1] = CUR.GS.freeVector.y; - - -#define DO_SRP0 \ - CUR.GS.rp0 = (FT_UShort)args[0]; - - -#define DO_SRP1 \ - CUR.GS.rp1 = (FT_UShort)args[0]; - - -#define DO_SRP2 \ - CUR.GS.rp2 = (FT_UShort)args[0]; - - -#define DO_RTHG \ - CUR.GS.round_state = TT_Round_To_Half_Grid; \ - CUR.func_round = (TT_Round_Func)Round_To_Half_Grid; - - -#define DO_RTG \ - CUR.GS.round_state = TT_Round_To_Grid; \ - CUR.func_round = (TT_Round_Func)Round_To_Grid; - - -#define DO_RTDG \ - CUR.GS.round_state = TT_Round_To_Double_Grid; \ - CUR.func_round = (TT_Round_Func)Round_To_Double_Grid; - - -#define DO_RUTG \ - CUR.GS.round_state = TT_Round_Up_To_Grid; \ - CUR.func_round = (TT_Round_Func)Round_Up_To_Grid; - - -#define DO_RDTG \ - CUR.GS.round_state = TT_Round_Down_To_Grid; \ - CUR.func_round = (TT_Round_Func)Round_Down_To_Grid; - - -#define DO_ROFF \ - CUR.GS.round_state = TT_Round_Off; \ - CUR.func_round = (TT_Round_Func)Round_None; - - -#define DO_SROUND \ - SET_SuperRound( 0x4000, args[0] ); \ - CUR.GS.round_state = TT_Round_Super; \ - CUR.func_round = (TT_Round_Func)Round_Super; - - -#define DO_S45ROUND \ - SET_SuperRound( 0x2D41, args[0] ); \ - CUR.GS.round_state = TT_Round_Super_45; \ - CUR.func_round = (TT_Round_Func)Round_Super_45; - - -#define DO_SLOOP \ - if ( args[0] < 0 ) \ - CUR.error = TT_Err_Bad_Argument; \ - else \ - CUR.GS.loop = args[0]; - - -#define DO_SMD \ - CUR.GS.minimum_distance = args[0]; - - -#define DO_SCVTCI \ - CUR.GS.control_value_cutin = (FT_F26Dot6)args[0]; - - -#define DO_SSWCI \ - CUR.GS.single_width_cutin = (FT_F26Dot6)args[0]; - - - /* XXX: UNDOCUMENTED! or bug in the Windows engine? */ - /* */ - /* It seems that the value that is read here is */ - /* expressed in 16.16 format rather than in font */ - /* units. */ - /* */ -#define DO_SSW \ - CUR.GS.single_width_value = (FT_F26Dot6)( args[0] >> 10 ); - - -#define DO_FLIPON \ - CUR.GS.auto_flip = TRUE; - - -#define DO_FLIPOFF \ - CUR.GS.auto_flip = FALSE; - - -#define DO_SDB \ - CUR.GS.delta_base = (FT_Short)args[0]; - - -#define DO_SDS \ - CUR.GS.delta_shift = (FT_Short)args[0]; - - -#define DO_MD /* nothing */ - - -#define DO_MPPEM \ - args[0] = CURRENT_Ppem(); - - - /* Note: The pointSize should be irrelevant in a given font program; */ - /* we thus decide to return only the ppem. */ -#if 0 - -#define DO_MPS \ - args[0] = CUR.metrics.pointSize; - -#else - -#define DO_MPS \ - args[0] = CURRENT_Ppem(); - -#endif /* 0 */ - - -#define DO_DUP \ - args[1] = args[0]; - - -#define DO_CLEAR \ - CUR.new_top = 0; - - -#define DO_SWAP \ - { \ - FT_Long L; \ - \ - \ - L = args[0]; \ - args[0] = args[1]; \ - args[1] = L; \ - } - - -#define DO_DEPTH \ - args[0] = CUR.top; - - -#define DO_CINDEX \ - { \ - FT_Long L; \ - \ - \ - L = args[0]; \ - \ - if ( L <= 0 || L > CUR.args ) \ - CUR.error = TT_Err_Invalid_Reference; \ - else \ - args[0] = CUR.stack[CUR.args - L]; \ - } - - -#define DO_JROT \ - if ( args[1] != 0 ) \ - { \ - CUR.IP += args[0]; \ - CUR.step_ins = FALSE; \ - } - - -#define DO_JMPR \ - CUR.IP += args[0]; \ - CUR.step_ins = FALSE; - - -#define DO_JROF \ - if ( args[1] == 0 ) \ - { \ - CUR.IP += args[0]; \ - CUR.step_ins = FALSE; \ - } - - -#define DO_LT \ - args[0] = ( args[0] < args[1] ); - - -#define DO_LTEQ \ - args[0] = ( args[0] <= args[1] ); - - -#define DO_GT \ - args[0] = ( args[0] > args[1] ); - - -#define DO_GTEQ \ - args[0] = ( args[0] >= args[1] ); - - -#define DO_EQ \ - args[0] = ( args[0] == args[1] ); - - -#define DO_NEQ \ - args[0] = ( args[0] != args[1] ); - - -#define DO_ODD \ - args[0] = ( ( CUR_Func_round( args[0], 0 ) & 127 ) == 64 ); - - -#define DO_EVEN \ - args[0] = ( ( CUR_Func_round( args[0], 0 ) & 127 ) == 0 ); - - -#define DO_AND \ - args[0] = ( args[0] && args[1] ); - - -#define DO_OR \ - args[0] = ( args[0] || args[1] ); - - -#define DO_NOT \ - args[0] = !args[0]; - - -#define DO_ADD \ - args[0] += args[1]; - - -#define DO_SUB \ - args[0] -= args[1]; - - -#define DO_DIV \ - if ( args[1] == 0 ) \ - CUR.error = TT_Err_Divide_By_Zero; \ - else \ - args[0] = TT_MULDIV( args[0], 64L, args[1] ); - - -#define DO_MUL \ - args[0] = TT_MULDIV( args[0], args[1], 64L ); - - -#define DO_ABS \ - args[0] = ABS( args[0] ); - - -#define DO_NEG \ - args[0] = -args[0]; - - -#define DO_FLOOR \ - args[0] &= -64; - - -#define DO_CEILING \ - args[0] = ( args[0] + 63 ) & -64; - - -#define DO_RS \ - { \ - FT_ULong I = (FT_ULong)args[0]; \ - \ - \ - if ( BOUNDS( I, CUR.storeSize ) ) \ - { \ - if ( CUR.pedantic_hinting ) \ - { \ - ARRAY_BOUND_ERROR; \ - } \ - else \ - args[0] = 0; \ - } \ - else \ - args[0] = CUR.storage[I]; \ - } - - -#define DO_WS \ - { \ - FT_ULong I = (FT_ULong)args[0]; \ - \ - \ - if ( BOUNDS( I, CUR.storeSize ) ) \ - { \ - if ( CUR.pedantic_hinting ) \ - { \ - ARRAY_BOUND_ERROR; \ - } \ - } \ - else \ - CUR.storage[I] = args[1]; \ - } - - -#define DO_RCVT \ - { \ - FT_ULong I = (FT_ULong)args[0]; \ - \ - \ - if ( BOUNDS( I, CUR.cvtSize ) ) \ - { \ - if ( CUR.pedantic_hinting ) \ - { \ - ARRAY_BOUND_ERROR; \ - } \ - else \ - args[0] = 0; \ - } \ - else \ - args[0] = CUR_Func_read_cvt( I ); \ - } - - -#define DO_WCVTP \ - { \ - FT_ULong I = (FT_ULong)args[0]; \ - \ - \ - if ( BOUNDS( I, CUR.cvtSize ) ) \ - { \ - if ( CUR.pedantic_hinting ) \ - { \ - ARRAY_BOUND_ERROR; \ - } \ - } \ - else \ - CUR_Func_write_cvt( I, args[1] ); \ - } - - -#define DO_WCVTF \ - { \ - FT_ULong I = (FT_ULong)args[0]; \ - \ - \ - if ( BOUNDS( I, CUR.cvtSize ) ) \ - { \ - if ( CUR.pedantic_hinting ) \ - { \ - ARRAY_BOUND_ERROR; \ - } \ - } \ - else \ - CUR.cvt[I] = TT_MULFIX( args[1], CUR.tt_metrics.scale ); \ - } - - -#define DO_DEBUG \ - CUR.error = TT_Err_Debug_OpCode; - - -#define DO_ROUND \ - args[0] = CUR_Func_round( \ - args[0], \ - CUR.tt_metrics.compensations[CUR.opcode - 0x68] ); - - -#define DO_NROUND \ - args[0] = ROUND_None( args[0], \ - CUR.tt_metrics.compensations[CUR.opcode - 0x6C] ); - - -#define DO_MAX \ - if ( args[1] > args[0] ) \ - args[0] = args[1]; - - -#define DO_MIN \ - if ( args[1] < args[0] ) \ - args[0] = args[1]; - - -#ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH - - -#undef ARRAY_BOUND_ERROR -#define ARRAY_BOUND_ERROR \ - { \ - CUR.error = TT_Err_Invalid_Reference; \ - return; \ - } - - - /*************************************************************************/ - /* */ - /* SVTCA[a]: Set (F and P) Vectors to Coordinate Axis */ - /* Opcode range: 0x00-0x01 */ - /* Stack: --> */ - /* */ - static - void Ins_SVTCA( INS_ARG ) - { - DO_SVTCA - } - - - /*************************************************************************/ - /* */ - /* SPVTCA[a]: Set PVector to Coordinate Axis */ - /* Opcode range: 0x02-0x03 */ - /* Stack: --> */ - /* */ - static - void Ins_SPVTCA( INS_ARG ) - { - DO_SPVTCA - } - - - /*************************************************************************/ - /* */ - /* SFVTCA[a]: Set FVector to Coordinate Axis */ - /* Opcode range: 0x04-0x05 */ - /* Stack: --> */ - /* */ - static - void Ins_SFVTCA( INS_ARG ) - { - DO_SFVTCA - } - - - /*************************************************************************/ - /* */ - /* SPVTL[a]: Set PVector To Line */ - /* Opcode range: 0x06-0x07 */ - /* Stack: uint32 uint32 --> */ - /* */ - static - void Ins_SPVTL( INS_ARG ) - { - DO_SPVTL - } - - - /*************************************************************************/ - /* */ - /* SFVTL[a]: Set FVector To Line */ - /* Opcode range: 0x08-0x09 */ - /* Stack: uint32 uint32 --> */ - /* */ - static - void Ins_SFVTL( INS_ARG ) - { - DO_SFVTL - } - - - /*************************************************************************/ - /* */ - /* SFVTPV[]: Set FVector To PVector */ - /* Opcode range: 0x0E */ - /* Stack: --> */ - /* */ - static - void Ins_SFVTPV( INS_ARG ) - { - DO_SFVTPV - } - - - /*************************************************************************/ - /* */ - /* SPVFS[]: Set PVector From Stack */ - /* Opcode range: 0x0A */ - /* Stack: f2.14 f2.14 --> */ - /* */ - static - void Ins_SPVFS( INS_ARG ) - { - DO_SPVFS - } - - - /*************************************************************************/ - /* */ - /* SFVFS[]: Set FVector From Stack */ - /* Opcode range: 0x0B */ - /* Stack: f2.14 f2.14 --> */ - /* */ - static - void Ins_SFVFS( INS_ARG ) - { - DO_SFVFS - } - - - /*************************************************************************/ - /* */ - /* GPV[]: Get Projection Vector */ - /* Opcode range: 0x0C */ - /* Stack: ef2.14 --> ef2.14 */ - /* */ - static - void Ins_GPV( INS_ARG ) - { - DO_GPV - } - - - /*************************************************************************/ - /* GFV[]: Get Freedom Vector */ - /* Opcode range: 0x0D */ - /* Stack: ef2.14 --> ef2.14 */ - /* */ - static - void Ins_GFV( INS_ARG ) - { - DO_GFV - } - - - /*************************************************************************/ - /* */ - /* SRP0[]: Set Reference Point 0 */ - /* Opcode range: 0x10 */ - /* Stack: uint32 --> */ - /* */ - static - void Ins_SRP0( INS_ARG ) - { - DO_SRP0 - } - - - /*************************************************************************/ - /* */ - /* SRP1[]: Set Reference Point 1 */ - /* Opcode range: 0x11 */ - /* Stack: uint32 --> */ - /* */ - static - void Ins_SRP1( INS_ARG ) - { - DO_SRP1 - } - - - /*************************************************************************/ - /* */ - /* SRP2[]: Set Reference Point 2 */ - /* Opcode range: 0x12 */ - /* Stack: uint32 --> */ - /* */ - static - void Ins_SRP2( INS_ARG ) - { - DO_SRP2 - } - - - /*************************************************************************/ - /* */ - /* RTHG[]: Round To Half Grid */ - /* Opcode range: 0x19 */ - /* Stack: --> */ - /* */ - static - void Ins_RTHG( INS_ARG ) - { - DO_RTHG - } - - - /*************************************************************************/ - /* */ - /* RTG[]: Round To Grid */ - /* Opcode range: 0x18 */ - /* Stack: --> */ - /* */ - static - void Ins_RTG( INS_ARG ) - { - DO_RTG - } - - - /*************************************************************************/ - /* RTDG[]: Round To Double Grid */ - /* Opcode range: 0x3D */ - /* Stack: --> */ - /* */ - static - void Ins_RTDG( INS_ARG ) - { - DO_RTDG - } - - - /*************************************************************************/ - /* RUTG[]: Round Up To Grid */ - /* Opcode range: 0x7C */ - /* Stack: --> */ - /* */ - static - void Ins_RUTG( INS_ARG ) - { - DO_RUTG - } - - - /*************************************************************************/ - /* */ - /* RDTG[]: Round Down To Grid */ - /* Opcode range: 0x7D */ - /* Stack: --> */ - /* */ - static - void Ins_RDTG( INS_ARG ) - { - DO_RDTG - } - - - /*************************************************************************/ - /* */ - /* ROFF[]: Round OFF */ - /* Opcode range: 0x7A */ - /* Stack: --> */ - /* */ - static - void Ins_ROFF( INS_ARG ) - { - DO_ROFF - } - - - /*************************************************************************/ - /* */ - /* SROUND[]: Super ROUND */ - /* Opcode range: 0x76 */ - /* Stack: Eint8 --> */ - /* */ - static - void Ins_SROUND( INS_ARG ) - { - DO_SROUND - } - - - /*************************************************************************/ - /* */ - /* S45ROUND[]: Super ROUND 45 degrees */ - /* Opcode range: 0x77 */ - /* Stack: uint32 --> */ - /* */ - static - void Ins_S45ROUND( INS_ARG ) - { - DO_S45ROUND - } - - - /*************************************************************************/ - /* */ - /* SLOOP[]: Set LOOP variable */ - /* Opcode range: 0x17 */ - /* Stack: int32? --> */ - /* */ - static - void Ins_SLOOP( INS_ARG ) - { - DO_SLOOP - } - - - /*************************************************************************/ - /* */ - /* SMD[]: Set Minimum Distance */ - /* Opcode range: 0x1A */ - /* Stack: f26.6 --> */ - /* */ - static - void Ins_SMD( INS_ARG ) - { - DO_SMD - } - - - /*************************************************************************/ - /* */ - /* SCVTCI[]: Set Control Value Table Cut In */ - /* Opcode range: 0x1D */ - /* Stack: f26.6 --> */ - /* */ - static - void Ins_SCVTCI( INS_ARG ) - { - DO_SCVTCI - } - - - /*************************************************************************/ - /* */ - /* SSWCI[]: Set Single Width Cut In */ - /* Opcode range: 0x1E */ - /* Stack: f26.6 --> */ - /* */ - static - void Ins_SSWCI( INS_ARG ) - { - DO_SSWCI - } - - - /*************************************************************************/ - /* */ - /* SSW[]: Set Single Width */ - /* Opcode range: 0x1F */ - /* Stack: int32? --> */ - /* */ - static - void Ins_SSW( INS_ARG ) - { - DO_SSW - } - - - /*************************************************************************/ - /* */ - /* FLIPON[]: Set auto-FLIP to ON */ - /* Opcode range: 0x4D */ - /* Stack: --> */ - /* */ - static - void Ins_FLIPON( INS_ARG ) - { - DO_FLIPON - } - - - /*************************************************************************/ - /* */ - /* FLIPOFF[]: Set auto-FLIP to OFF */ - /* Opcode range: 0x4E */ - /* Stack: --> */ - /* */ - static - void Ins_FLIPOFF( INS_ARG ) - { - DO_FLIPOFF - } - - - /*************************************************************************/ - /* */ - /* SANGW[]: Set ANGle Weight */ - /* Opcode range: 0x7E */ - /* Stack: uint32 --> */ - /* */ - static - void Ins_SANGW( INS_ARG ) - { - /* instruction not supported anymore */ - } - - - /*************************************************************************/ - /* */ - /* SDB[]: Set Delta Base */ - /* Opcode range: 0x5E */ - /* Stack: uint32 --> */ - /* */ - static - void Ins_SDB( INS_ARG ) - { - DO_SDB - } - - - /*************************************************************************/ - /* */ - /* SDS[]: Set Delta Shift */ - /* Opcode range: 0x5F */ - /* Stack: uint32 --> */ - /* */ - static - void Ins_SDS( INS_ARG ) - { - DO_SDS - } - - - /*************************************************************************/ - /* */ - /* MPPEM[]: Measure Pixel Per EM */ - /* Opcode range: 0x4B */ - /* Stack: --> Euint16 */ - /* */ - static - void Ins_MPPEM( INS_ARG ) - { - DO_MPPEM - } - - - /*************************************************************************/ - /* */ - /* MPS[]: Measure Point Size */ - /* Opcode range: 0x4C */ - /* Stack: --> Euint16 */ - /* */ - static - void Ins_MPS( INS_ARG ) - { - DO_MPS - } - - - /*************************************************************************/ - /* */ - /* DUP[]: DUPlicate the top stack's element */ - /* Opcode range: 0x20 */ - /* Stack: StkElt --> StkElt StkElt */ - /* */ - static - void Ins_DUP( INS_ARG ) - { - DO_DUP - } - - - /*************************************************************************/ - /* */ - /* POP[]: POP the stack's top element */ - /* Opcode range: 0x21 */ - /* Stack: StkElt --> */ - /* */ - static - void Ins_POP( INS_ARG ) - { - /* nothing to do */ - } - - - /*************************************************************************/ - /* */ - /* CLEAR[]: CLEAR the entire stack */ - /* Opcode range: 0x22 */ - /* Stack: StkElt... --> */ - /* */ - static - void Ins_CLEAR( INS_ARG ) - { - DO_CLEAR - } - - - /*************************************************************************/ - /* */ - /* SWAP[]: SWAP the stack's top two elements */ - /* Opcode range: 0x23 */ - /* Stack: 2 * StkElt --> 2 * StkElt */ - /* */ - static - void Ins_SWAP( INS_ARG ) - { - DO_SWAP - } - - - /*************************************************************************/ - /* */ - /* DEPTH[]: return the stack DEPTH */ - /* Opcode range: 0x24 */ - /* Stack: --> uint32 */ - /* */ - static - void Ins_DEPTH( INS_ARG ) - { - DO_DEPTH - } - - - /*************************************************************************/ - /* */ - /* CINDEX[]: Copy INDEXed element */ - /* Opcode range: 0x25 */ - /* Stack: int32 --> StkElt */ - /* */ - static - void Ins_CINDEX( INS_ARG ) - { - DO_CINDEX - } - - - /*************************************************************************/ - /* */ - /* EIF[]: End IF */ - /* Opcode range: 0x59 */ - /* Stack: --> */ - /* */ - static - void Ins_EIF( INS_ARG ) - { - /* nothing to do */ - } - - - /*************************************************************************/ - /* */ - /* JROT[]: Jump Relative On True */ - /* Opcode range: 0x78 */ - /* Stack: StkElt int32 --> */ - /* */ - static - void Ins_JROT( INS_ARG ) - { - DO_JROT - } - - - /*************************************************************************/ - /* */ - /* JMPR[]: JuMP Relative */ - /* Opcode range: 0x1C */ - /* Stack: int32 --> */ - /* */ - static - void Ins_JMPR( INS_ARG ) - { - DO_JMPR - } - - - /*************************************************************************/ - /* */ - /* JROF[]: Jump Relative On False */ - /* Opcode range: 0x79 */ - /* Stack: StkElt int32 --> */ - /* */ - static - void Ins_JROF( INS_ARG ) - { - DO_JROF - } - - - /*************************************************************************/ - /* */ - /* LT[]: Less Than */ - /* Opcode range: 0x50 */ - /* Stack: int32? int32? --> bool */ - /* */ - static - void Ins_LT( INS_ARG ) - { - DO_LT - } - - - /*************************************************************************/ - /* */ - /* LTEQ[]: Less Than or EQual */ - /* Opcode range: 0x51 */ - /* Stack: int32? int32? --> bool */ - /* */ - static - void Ins_LTEQ( INS_ARG ) - { - DO_LTEQ - } - - - /*************************************************************************/ - /* */ - /* GT[]: Greater Than */ - /* Opcode range: 0x52 */ - /* Stack: int32? int32? --> bool */ - /* */ - static - void Ins_GT( INS_ARG ) - { - DO_GT - } - - - /*************************************************************************/ - /* */ - /* GTEQ[]: Greater Than or EQual */ - /* Opcode range: 0x53 */ - /* Stack: int32? int32? --> bool */ - /* */ - static - void Ins_GTEQ( INS_ARG ) - { - DO_GTEQ - } - - - /*************************************************************************/ - /* */ - /* EQ[]: EQual */ - /* Opcode range: 0x54 */ - /* Stack: StkElt StkElt --> bool */ - /* */ - static - void Ins_EQ( INS_ARG ) - { - DO_EQ - } - - - /*************************************************************************/ - /* */ - /* NEQ[]: Not EQual */ - /* Opcode range: 0x55 */ - /* Stack: StkElt StkElt --> bool */ - /* */ - static - void Ins_NEQ( INS_ARG ) - { - DO_NEQ - } - - - /*************************************************************************/ - /* */ - /* ODD[]: Is ODD */ - /* Opcode range: 0x56 */ - /* Stack: f26.6 --> bool */ - /* */ - static - void Ins_ODD( INS_ARG ) - { - DO_ODD - } - - - /*************************************************************************/ - /* */ - /* EVEN[]: Is EVEN */ - /* Opcode range: 0x57 */ - /* Stack: f26.6 --> bool */ - /* */ - static - void Ins_EVEN( INS_ARG ) - { - DO_EVEN - } - - - /*************************************************************************/ - /* */ - /* AND[]: logical AND */ - /* Opcode range: 0x5A */ - /* Stack: uint32 uint32 --> uint32 */ - /* */ - static - void Ins_AND( INS_ARG ) - { - DO_AND - } - - - /*************************************************************************/ - /* */ - /* OR[]: logical OR */ - /* Opcode range: 0x5B */ - /* Stack: uint32 uint32 --> uint32 */ - /* */ - static - void Ins_OR( INS_ARG ) - { - DO_OR - } - - - /*************************************************************************/ - /* */ - /* NOT[]: logical NOT */ - /* Opcode range: 0x5C */ - /* Stack: StkElt --> uint32 */ - /* */ - static - void Ins_NOT( INS_ARG ) - { - DO_NOT - } - - - /*************************************************************************/ - /* */ - /* ADD[]: ADD */ - /* Opcode range: 0x60 */ - /* Stack: f26.6 f26.6 --> f26.6 */ - /* */ - static - void Ins_ADD( INS_ARG ) - { - DO_ADD - } - - - /*************************************************************************/ - /* */ - /* SUB[]: SUBtract */ - /* Opcode range: 0x61 */ - /* Stack: f26.6 f26.6 --> f26.6 */ - /* */ - static - void Ins_SUB( INS_ARG ) - { - DO_SUB - } - - - /*************************************************************************/ - /* */ - /* DIV[]: DIVide */ - /* Opcode range: 0x62 */ - /* Stack: f26.6 f26.6 --> f26.6 */ - /* */ - static - void Ins_DIV( INS_ARG ) - { - DO_DIV - } - - - /*************************************************************************/ - /* */ - /* MUL[]: MULtiply */ - /* Opcode range: 0x63 */ - /* Stack: f26.6 f26.6 --> f26.6 */ - /* */ - static - void Ins_MUL( INS_ARG ) - { - DO_MUL - } - - - /*************************************************************************/ - /* */ - /* ABS[]: ABSolute value */ - /* Opcode range: 0x64 */ - /* Stack: f26.6 --> f26.6 */ - /* */ - static - void Ins_ABS( INS_ARG ) - { - DO_ABS - } - - - /*************************************************************************/ - /* */ - /* NEG[]: NEGate */ - /* Opcode range: 0x65 */ - /* Stack: f26.6 --> f26.6 */ - /* */ - static - void Ins_NEG( INS_ARG ) - { - DO_NEG - } - - - /*************************************************************************/ - /* */ - /* FLOOR[]: FLOOR */ - /* Opcode range: 0x66 */ - /* Stack: f26.6 --> f26.6 */ - /* */ - static - void Ins_FLOOR( INS_ARG ) - { - DO_FLOOR - } - - - /*************************************************************************/ - /* */ - /* CEILING[]: CEILING */ - /* Opcode range: 0x67 */ - /* Stack: f26.6 --> f26.6 */ - /* */ - static - void Ins_CEILING( INS_ARG ) - { - DO_CEILING - } - - - /*************************************************************************/ - /* */ - /* RS[]: Read Store */ - /* Opcode range: 0x43 */ - /* Stack: uint32 --> uint32 */ - /* */ - static - void Ins_RS( INS_ARG ) - { - DO_RS - } - - - /*************************************************************************/ - /* */ - /* WS[]: Write Store */ - /* Opcode range: 0x42 */ - /* Stack: uint32 uint32 --> */ - /* */ - static - void Ins_WS( INS_ARG ) - { - DO_WS - } - - - /*************************************************************************/ - /* */ - /* WCVTP[]: Write CVT in Pixel units */ - /* Opcode range: 0x44 */ - /* Stack: f26.6 uint32 --> */ - /* */ - static - void Ins_WCVTP( INS_ARG ) - { - DO_WCVTP - } - - - /*************************************************************************/ - /* */ - /* WCVTF[]: Write CVT in Funits */ - /* Opcode range: 0x70 */ - /* Stack: uint32 uint32 --> */ - /* */ - static - void Ins_WCVTF( INS_ARG ) - { - DO_WCVTF - } - - - /*************************************************************************/ - /* */ - /* RCVT[]: Read CVT */ - /* Opcode range: 0x45 */ - /* Stack: uint32 --> f26.6 */ - /* */ - static - void Ins_RCVT( INS_ARG ) - { - DO_RCVT - } - - - /*************************************************************************/ - /* */ - /* AA[]: Adjust Angle */ - /* Opcode range: 0x7F */ - /* Stack: uint32 --> */ - /* */ - static - void Ins_AA( INS_ARG ) - { - /* intentionally no longer supported */ - } - - - /*************************************************************************/ - /* */ - /* DEBUG[]: DEBUG. Unsupported. */ - /* Opcode range: 0x4F */ - /* Stack: uint32 --> */ - /* */ - /* Note: The original instruction pops a value from the stack. */ - /* */ - static - void Ins_DEBUG( INS_ARG ) - { - DO_DEBUG - } - - - /*************************************************************************/ - /* */ - /* ROUND[ab]: ROUND value */ - /* Opcode range: 0x68-0x6B */ - /* Stack: f26.6 --> f26.6 */ - /* */ - static - void Ins_ROUND( INS_ARG ) - { - DO_ROUND - } - - - /*************************************************************************/ - /* */ - /* NROUND[ab]: No ROUNDing of value */ - /* Opcode range: 0x6C-0x6F */ - /* Stack: f26.6 --> f26.6 */ - /* */ - static - void Ins_NROUND( INS_ARG ) - { - DO_NROUND - } - - - /*************************************************************************/ - /* */ - /* MAX[]: MAXimum */ - /* Opcode range: 0x68 */ - /* Stack: int32? int32? --> int32 */ - /* */ - static - void Ins_MAX( INS_ARG ) - { - DO_MAX - } - - - /*************************************************************************/ - /* */ - /* MIN[]: MINimum */ - /* Opcode range: 0x69 */ - /* Stack: int32? int32? --> int32 */ - /* */ - static - void Ins_MIN( INS_ARG ) - { - DO_MIN - } - - -#endif /* !TT_CONFIG_OPTION_INTERPRETER_SWITCH */ - - - /*************************************************************************/ - /* */ - /* The following functions are called as is within the switch statement. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* MINDEX[]: Move INDEXed element */ - /* Opcode range: 0x26 */ - /* Stack: int32? --> StkElt */ - /* */ - static - void Ins_MINDEX( INS_ARG ) - { - FT_Long L, K; - - - L = args[0]; - - if ( L <= 0 || L > CUR.args ) - { - CUR.error = TT_Err_Invalid_Reference; - return; - } - - K = CUR.stack[CUR.args - L]; - - MEM_Move( &CUR.stack[CUR.args - L ], - &CUR.stack[CUR.args - L + 1], - ( L - 1 ) * sizeof ( FT_Long ) ); - - CUR.stack[CUR.args - 1] = K; - } - - - /*************************************************************************/ - /* */ - /* ROLL[]: ROLL top three elements */ - /* Opcode range: 0x8A */ - /* Stack: 3 * StkElt --> 3 * StkElt */ - /* */ - static - void Ins_ROLL( INS_ARG ) - { - FT_Long A, B, C; - - FT_UNUSED_EXEC; - - - A = args[2]; - B = args[1]; - C = args[0]; - - args[2] = C; - args[1] = A; - args[0] = B; - } - - - /*************************************************************************/ - /* */ - /* MANAGING THE FLOW OF CONTROL */ - /* */ - /* Instructions appear in the specification's order. */ - /* */ - /*************************************************************************/ - - - static - FT_Bool SkipCode( EXEC_OP ) - { - CUR.IP += CUR.length; - - if ( CUR.IP < CUR.codeSize ) - { - CUR.opcode = CUR.code[CUR.IP]; - - CUR.length = opcode_length[CUR.opcode]; - if ( CUR.length < 0 ) - { - if ( CUR.IP + 1 > CUR.codeSize ) - goto Fail_Overflow; - CUR.length = CUR.code[CUR.IP + 1] + 2; - } - - if ( CUR.IP + CUR.length <= CUR.codeSize ) - return SUCCESS; - } - - Fail_Overflow: - CUR.error = TT_Err_Code_Overflow; - return FAILURE; - } - - - /*************************************************************************/ - /* */ - /* IF[]: IF test */ - /* Opcode range: 0x58 */ - /* Stack: StkElt --> */ - /* */ - static - void Ins_IF( INS_ARG ) - { - FT_Int nIfs; - FT_Bool Out; - - - if ( args[0] != 0 ) - return; - - nIfs = 1; - Out = 0; - - do - { - if ( SKIP_Code() == FAILURE ) - return; - - switch ( CUR.opcode ) - { - case 0x58: /* IF */ - nIfs++; - break; - - case 0x1B: /* ELSE */ - Out = ( nIfs == 1 ); - break; - - case 0x59: /* EIF */ - nIfs--; - Out = ( nIfs == 0 ); - break; - } - } while ( Out == 0 ); - } - - - /*************************************************************************/ - /* */ - /* ELSE[]: ELSE */ - /* Opcode range: 0x1B */ - /* Stack: --> */ - /* */ - static - void Ins_ELSE( INS_ARG ) - { - FT_Int nIfs; - - FT_UNUSED_ARG; - - - nIfs = 1; - - do - { - if ( SKIP_Code() == FAILURE ) - return; - - switch ( CUR.opcode ) - { - case 0x58: /* IF */ - nIfs++; - break; - - case 0x59: /* EIF */ - nIfs--; - break; - } - } while ( nIfs != 0 ); - } - - - /*************************************************************************/ - /* */ - /* DEFINING AND USING FUNCTIONS AND INSTRUCTIONS */ - /* */ - /* Instructions appear in the specification's order. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* FDEF[]: Function DEFinition */ - /* Opcode range: 0x2C */ - /* Stack: uint32 --> */ - /* */ - static - void Ins_FDEF( INS_ARG ) - { - FT_ULong n; - TT_DefRecord* rec; - TT_DefRecord* limit; - - - /* some font programs are broken enough to redefine functions! */ - /* We will then parse the current table. */ - - rec = CUR.FDefs; - limit = rec + CUR.numFDefs; - n = args[0]; - - for ( ; rec < limit; rec++ ) - { - if ( rec->opc == n ) - break; - } - - if ( rec == limit ) - { - /* check that there is enough room for new functions */ - if ( CUR.numFDefs >= CUR.maxFDefs ) - { - CUR.error = TT_Err_Too_Many_Function_Defs; - return; - } - CUR.numFDefs++; - } - - rec->range = CUR.curRange; - rec->opc = n; - rec->start = CUR.IP + 1; - rec->active = TRUE; - - if ( n > CUR.maxFunc ) - CUR.maxFunc = n; - - /* Now skip the whole function definition. */ - /* We don't allow nested IDEFS & FDEFs. */ - - while ( SKIP_Code() == SUCCESS ) - { - switch ( CUR.opcode ) - { - case 0x89: /* IDEF */ - case 0x2C: /* FDEF */ - CUR.error = TT_Err_Nested_DEFS; - return; - - case 0x2D: /* ENDF */ - return; - } - } - } - - - /*************************************************************************/ - /* */ - /* ENDF[]: END Function definition */ - /* Opcode range: 0x2D */ - /* Stack: --> */ - /* */ - static - void Ins_ENDF( INS_ARG ) - { - TT_CallRec* pRec; - - FT_UNUSED_ARG; - - - if ( CUR.callTop <= 0 ) /* We encountered an ENDF without a call */ - { - CUR.error = TT_Err_ENDF_In_Exec_Stream; - return; - } - - CUR.callTop--; - - pRec = &CUR.callStack[CUR.callTop]; - - pRec->Cur_Count--; - - CUR.step_ins = FALSE; - - if ( pRec->Cur_Count > 0 ) - { - CUR.callTop++; - CUR.IP = pRec->Cur_Restart; - } - else - /* Loop through the current function */ - INS_Goto_CodeRange( pRec->Caller_Range, - pRec->Caller_IP ); - - /* Exit the current call frame. */ - - /* NOTE: If the last intruction of a program is a */ - /* CALL or LOOPCALL, the return address is */ - /* always out of the code range. This is a */ - /* valid address, and it is why we do not test */ - /* the result of Ins_Goto_CodeRange() here! */ - } - - - /*************************************************************************/ - /* */ - /* CALL[]: CALL function */ - /* Opcode range: 0x2B */ - /* Stack: uint32? --> */ - /* */ - static - void Ins_CALL( INS_ARG ) - { - FT_ULong F; - TT_CallRec* pCrec; - TT_DefRecord* def; - - - /* first of all, check the index */ - - F = args[0]; - if ( BOUNDS( F, CUR.maxFunc + 1 ) ) - goto Fail; - - /* Except for some old Apple fonts, all functions in a TrueType */ - /* font are defined in increasing order, starting from 0. This */ - /* means that we normally have */ - /* */ - /* CUR.maxFunc+1 == CUR.numFDefs */ - /* CUR.FDefs[n].opc == n for n in 0..CUR.maxFunc */ - /* */ - /* If this isn't true, we need to look up the function table. */ - - def = CUR.FDefs + F; - if ( CUR.maxFunc + 1 != CUR.numFDefs || def->opc != F ) - { - /* look up the FDefs table */ - TT_DefRecord* limit; - - - def = CUR.FDefs; - limit = def + CUR.numFDefs; - - while ( def < limit && def->opc != F ) - def++; - - if ( def == limit ) - goto Fail; - } - - /* check that the function is active */ - if ( !def->active ) - goto Fail; - - /* check the call stack */ - if ( CUR.callTop >= CUR.callSize ) - { - CUR.error = TT_Err_Stack_Overflow; - return; - } - - pCrec = CUR.callStack + CUR.callTop; - - pCrec->Caller_Range = CUR.curRange; - pCrec->Caller_IP = CUR.IP + 1; - pCrec->Cur_Count = 1; - pCrec->Cur_Restart = def->start; - - CUR.callTop++; - - INS_Goto_CodeRange( def->range, - def->start ); - - CUR.step_ins = FALSE; - return; - - Fail: - CUR.error = TT_Err_Invalid_Reference; - } - - - /*************************************************************************/ - /* */ - /* LOOPCALL[]: LOOP and CALL function */ - /* Opcode range: 0x2A */ - /* Stack: uint32? Eint16? --> */ - /* */ - static - void Ins_LOOPCALL( INS_ARG ) - { - FT_ULong F; - TT_CallRec* pCrec; - TT_DefRecord* def; - - - /* first of all, check the index */ - F = args[1]; - if ( BOUNDS( F, CUR.maxFunc + 1 ) ) - goto Fail; - - /* Except for some old Apple fonts, all functions in a TrueType */ - /* font are defined in increasing order, starting from 0. This */ - /* means that we normally have */ - /* */ - /* CUR.maxFunc+1 == CUR.numFDefs */ - /* CUR.FDefs[n].opc == n for n in 0..CUR.maxFunc */ - /* */ - /* If this isn't true, we need to look up the function table. */ - - def = CUR.FDefs + F; - if ( CUR.maxFunc + 1 != CUR.numFDefs || def->opc != F ) - { - /* look up the FDefs table */ - TT_DefRecord* limit; - - - def = CUR.FDefs; - limit = def + CUR.numFDefs; - - while ( def < limit && def->opc != F ) - def++; - - if ( def == limit ) - goto Fail; - } - - /* check that the function is active */ - if ( !def->active ) - goto Fail; - - /* check stack */ - if ( CUR.callTop >= CUR.callSize ) - { - CUR.error = TT_Err_Stack_Overflow; - return; - } - - if ( args[0] > 0 ) - { - pCrec = CUR.callStack + CUR.callTop; - - pCrec->Caller_Range = CUR.curRange; - pCrec->Caller_IP = CUR.IP + 1; - pCrec->Cur_Count = (FT_Int)args[0]; - pCrec->Cur_Restart = def->start; - - CUR.callTop++; - - INS_Goto_CodeRange( def->range, def->start ); - - CUR.step_ins = FALSE; - } - return; - - Fail: - CUR.error = TT_Err_Invalid_Reference; - } - - - /*************************************************************************/ - /* */ - /* IDEF[]: Instruction DEFinition */ - /* Opcode range: 0x89 */ - /* Stack: Eint8 --> */ - /* */ - static - void Ins_IDEF( INS_ARG ) - { - TT_DefRecord* def; - TT_DefRecord* limit; - - - /* First of all, look for the same function in our table */ - - def = CUR.IDefs; - limit = def + CUR.numIDefs; - - for ( ; def < limit; def++ ) - if ( def->opc == (FT_ULong)args[0] ) - break; - - if ( def == limit ) - { - /* check that there is enough room for a new instruction */ - if ( CUR.numIDefs >= CUR.maxIDefs ) - { - CUR.error = TT_Err_Too_Many_Instruction_Defs; - return; - } - CUR.numIDefs++; - } - - def->opc = args[0]; - def->start = CUR.IP+1; - def->range = CUR.curRange; - def->active = TRUE; - - if ( (FT_ULong)args[0] > CUR.maxIns ) - CUR.maxIns = args[0]; - - /* Now skip the whole function definition. */ - /* We don't allow nested IDEFs & FDEFs. */ - - while ( SKIP_Code() == SUCCESS ) - { - switch ( CUR.opcode ) - { - case 0x89: /* IDEF */ - case 0x2C: /* FDEF */ - CUR.error = TT_Err_Nested_DEFS; - return; - case 0x2D: /* ENDF */ - return; - } - } - } - - - /*************************************************************************/ - /* */ - /* PUSHING DATA ONTO THE INTERPRETER STACK */ - /* */ - /* Instructions appear in the specification's order. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* NPUSHB[]: PUSH N Bytes */ - /* Opcode range: 0x40 */ - /* Stack: --> uint32... */ - /* */ - static - void Ins_NPUSHB( INS_ARG ) - { - FT_UShort L, K; - - - L = (FT_UShort)CUR.code[CUR.IP + 1]; - - if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) - { - CUR.error = TT_Err_Stack_Overflow; - return; - } - - for ( K = 1; K <= L; K++ ) - args[K - 1] = CUR.code[CUR.IP + K + 1]; - - CUR.new_top += L; - } - - - /*************************************************************************/ - /* */ - /* NPUSHW[]: PUSH N Words */ - /* Opcode range: 0x41 */ - /* Stack: --> int32... */ - /* */ - static - void Ins_NPUSHW( INS_ARG ) - { - FT_UShort L, K; - - - L = (FT_UShort)CUR.code[CUR.IP + 1]; - - if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) - { - CUR.error = TT_Err_Stack_Overflow; - return; - } - - CUR.IP += 2; - - for ( K = 0; K < L; K++ ) - args[K] = GET_ShortIns(); - - CUR.step_ins = FALSE; - CUR.new_top += L; - } - - - /*************************************************************************/ - /* */ - /* PUSHB[abc]: PUSH Bytes */ - /* Opcode range: 0xB0-0xB7 */ - /* Stack: --> uint32... */ - /* */ - static - void Ins_PUSHB( INS_ARG ) - { - FT_UShort L, K; - - - L = (FT_UShort)CUR.opcode - 0xB0 + 1; - - if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) - { - CUR.error = TT_Err_Stack_Overflow; - return; - } - - for ( K = 1; K <= L; K++ ) - args[K - 1] = CUR.code[CUR.IP + K]; - } - - - /*************************************************************************/ - /* */ - /* PUSHW[abc]: PUSH Words */ - /* Opcode range: 0xB8-0xBF */ - /* Stack: --> int32... */ - /* */ - static - void Ins_PUSHW( INS_ARG ) - { - FT_UShort L, K; - - - L = (FT_UShort)CUR.opcode - 0xB8 + 1; - - if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) ) - { - CUR.error = TT_Err_Stack_Overflow; - return; - } - - CUR.IP++; - - for ( K = 0; K < L; K++ ) - args[K] = GET_ShortIns(); - - CUR.step_ins = FALSE; - } - - - /*************************************************************************/ - /* */ - /* MANAGING THE GRAPHICS STATE */ - /* */ - /* Instructions appear in the specs' order. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* GC[a]: Get Coordinate projected onto */ - /* Opcode range: 0x46-0x47 */ - /* Stack: uint32 --> f26.6 */ - /* */ - /* BULLSHIT: Measures from the original glyph must be taken along the */ - /* dual projection vector! */ - /* */ - static void Ins_GC( INS_ARG ) - { - FT_ULong L; - FT_F26Dot6 R; - - - L = (FT_ULong)args[0]; - - if ( BOUNDS( L, CUR.zp2.n_points ) ) - { - if ( CUR.pedantic_hinting ) - { - CUR.error = TT_Err_Invalid_Reference; - return; - } - else - R = 0; - } - else - { - if ( CUR.opcode & 1 ) - R = CUR_Func_dualproj( CUR.zp2.org + L, NULL_Vector ); - else - R = CUR_Func_project( CUR.zp2.cur + L, NULL_Vector ); - } - - args[0] = R; - } - - - /*************************************************************************/ - /* */ - /* SCFS[]: Set Coordinate From Stack */ - /* Opcode range: 0x48 */ - /* Stack: f26.6 uint32 --> */ - /* */ - /* Formula: */ - /* */ - /* OA := OA + ( value - OA.p )/( f.p ) * f */ - /* */ - static - void Ins_SCFS( INS_ARG ) - { - FT_Long K; - FT_UShort L; - - - L = (FT_UShort)args[0]; - - if ( BOUNDS( L, CUR.zp2.n_points ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = TT_Err_Invalid_Reference; - return; - } - - K = CUR_Func_project( CUR.zp2.cur + L, NULL_Vector ); - - CUR_Func_move( &CUR.zp2, L, args[1] - K ); - - /* not part of the specs, but here for safety */ - - if ( CUR.GS.gep2 == 0 ) - CUR.zp2.org[L] = CUR.zp2.cur[L]; - } - - - /*************************************************************************/ - /* */ - /* MD[a]: Measure Distance */ - /* Opcode range: 0x49-0x4A */ - /* Stack: uint32 uint32 --> f26.6 */ - /* */ - /* BULLSHIT: Measure taken in the original glyph must be along the dual */ - /* projection vector. */ - /* */ - /* Second BULLSHIT: Flag attributes are inverted! */ - /* 0 => measure distance in original outline */ - /* 1 => measure distance in grid-fitted outline */ - /* */ - /* Third one: `zp0 - zp1', and not `zp2 - zp1! */ - /* */ - static - void Ins_MD( INS_ARG ) - { - FT_UShort K, L; - FT_F26Dot6 D; - - - K = (FT_UShort)args[1]; - L = (FT_UShort)args[0]; - - if( BOUNDS( L, CUR.zp0.n_points ) || - BOUNDS( K, CUR.zp1.n_points ) ) - { - if ( CUR.pedantic_hinting ) - { - CUR.error = TT_Err_Invalid_Reference; - return; - } - D = 0; - } - else - { - if ( CUR.opcode & 1 ) - D = CUR_Func_project( CUR.zp0.cur + L, CUR.zp1.cur + K ); - else - D = CUR_Func_dualproj( CUR.zp0.org + L, CUR.zp1.org + K ); - } - - args[0] = D; - } - - - /*************************************************************************/ - /* */ - /* SDPVTL[a]: Set Dual PVector to Line */ - /* Opcode range: 0x86-0x87 */ - /* Stack: uint32 uint32 --> */ - /* */ - static - void Ins_SDPVTL( INS_ARG ) - { - FT_Long A, B, C; - FT_UShort p1, p2; /* was FT_Int in pas type ERROR */ - - - p1 = (FT_UShort)args[1]; - p2 = (FT_UShort)args[0]; - - if ( BOUNDS( p2, CUR.zp1.n_points ) || - BOUNDS( p1, CUR.zp2.n_points ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = TT_Err_Invalid_Reference; - return; - } - - { - FT_Vector* v1 = CUR.zp1.org + p2; - FT_Vector* v2 = CUR.zp2.org + p1; - - - A = v1->x - v2->x; - B = v1->y - v2->y; - } - - if ( ( CUR.opcode & 1 ) != 0 ) - { - C = B; /* counter clockwise rotation */ - B = A; - A = -C; - } - - NORMalize( A, B, &CUR.GS.dualVector ); - - { - FT_Vector* v1 = CUR.zp1.cur + p2; - FT_Vector* v2 = CUR.zp2.cur + p1; - - - A = v1->x - v2->x; - B = v1->y - v2->y; - } - - if ( ( CUR.opcode & 1 ) != 0 ) - { - C = B; /* counter clockwise rotation */ - B = A; - A = -C; - } - - NORMalize( A, B, &CUR.GS.projVector ); - - COMPUTE_Funcs(); - } - - - /*************************************************************************/ - /* */ - /* SZP0[]: Set Zone Pointer 0 */ - /* Opcode range: 0x13 */ - /* Stack: uint32 --> */ - /* */ - static - void Ins_SZP0( INS_ARG ) - { - switch ( (FT_Int)args[0] ) - { - case 0: - CUR.zp0 = CUR.twilight; - break; - - case 1: - CUR.zp0 = CUR.pts; - break; - - default: - if ( CUR.pedantic_hinting ) - CUR.error = TT_Err_Invalid_Reference; - return; - } - - CUR.GS.gep0 = (FT_UShort)args[0]; - } - - - /*************************************************************************/ - /* */ - /* SZP1[]: Set Zone Pointer 1 */ - /* Opcode range: 0x14 */ - /* Stack: uint32 --> */ - /* */ - static - void Ins_SZP1( INS_ARG ) - { - switch ( (FT_Int)args[0] ) - { - case 0: - CUR.zp1 = CUR.twilight; - break; - - case 1: - CUR.zp1 = CUR.pts; - break; - - default: - if ( CUR.pedantic_hinting ) - CUR.error = TT_Err_Invalid_Reference; - return; - } - - CUR.GS.gep1 = (FT_UShort)args[0]; - } - - - /*************************************************************************/ - /* */ - /* SZP2[]: Set Zone Pointer 2 */ - /* Opcode range: 0x15 */ - /* Stack: uint32 --> */ - /* */ - static - void Ins_SZP2( INS_ARG ) - { - switch ( (FT_Int)args[0] ) - { - case 0: - CUR.zp2 = CUR.twilight; - break; - - case 1: - CUR.zp2 = CUR.pts; - break; - - default: - if ( CUR.pedantic_hinting ) - CUR.error = TT_Err_Invalid_Reference; - return; - } - - CUR.GS.gep2 = (FT_UShort)args[0]; - } - - - /*************************************************************************/ - /* */ - /* SZPS[]: Set Zone PointerS */ - /* Opcode range: 0x16 */ - /* Stack: uint32 --> */ - /* */ - static - void Ins_SZPS( INS_ARG ) - { - switch ( (FT_Int)args[0] ) - { - case 0: - CUR.zp0 = CUR.twilight; - break; - - case 1: - CUR.zp0 = CUR.pts; - break; - - default: - if ( CUR.pedantic_hinting ) - CUR.error = TT_Err_Invalid_Reference; - return; - } - - CUR.zp1 = CUR.zp0; - CUR.zp2 = CUR.zp0; - - CUR.GS.gep0 = (FT_UShort)args[0]; - CUR.GS.gep1 = (FT_UShort)args[0]; - CUR.GS.gep2 = (FT_UShort)args[0]; - } - - - /*************************************************************************/ - /* */ - /* INSTCTRL[]: INSTruction ConTRoL */ - /* Opcode range: 0x8e */ - /* Stack: int32 int32 --> */ - /* */ - static - void Ins_INSTCTRL( INS_ARG ) - { - FT_Long K, L; - - - K = args[1]; - L = args[0]; - - if ( K < 1 || K > 2 ) - { - if ( CUR.pedantic_hinting ) - CUR.error = TT_Err_Invalid_Reference; - return; - } - - if ( L != 0 ) - L = K; - - CUR.GS.instruct_control = - (FT_Byte)( CUR.GS.instruct_control & ~(FT_Byte)K ) | (FT_Byte)L; - } - - - /*************************************************************************/ - /* */ - /* SCANCTRL[]: SCAN ConTRoL */ - /* Opcode range: 0x85 */ - /* Stack: uint32? --> */ - /* */ - static - void Ins_SCANCTRL( INS_ARG ) - { - FT_Int A; - - - /* Get Threshold */ - A = (FT_Int)( args[0] & 0xFF ); - - if ( A == 0xFF ) - { - CUR.GS.scan_control = TRUE; - return; - } - else if ( A == 0 ) - { - CUR.GS.scan_control = FALSE; - return; - } - - A *= 64; - -#if 0 - if ( (args[0] & 0x100) != 0 && CUR.metrics.pointSize <= A ) - CUR.GS.scan_control = TRUE; -#endif - - if ( (args[0] & 0x200) != 0 && CUR.tt_metrics.rotated ) - CUR.GS.scan_control = TRUE; - - if ( (args[0] & 0x400) != 0 && CUR.tt_metrics.stretched ) - CUR.GS.scan_control = TRUE; - -#if 0 - if ( (args[0] & 0x800) != 0 && CUR.metrics.pointSize > A ) - CUR.GS.scan_control = FALSE; -#endif - - if ( (args[0] & 0x1000) != 0 && CUR.tt_metrics.rotated ) - CUR.GS.scan_control = FALSE; - - if ( (args[0] & 0x2000) != 0 && CUR.tt_metrics.stretched ) - CUR.GS.scan_control = FALSE; -} - - - /*************************************************************************/ - /* */ - /* SCANTYPE[]: SCAN TYPE */ - /* Opcode range: 0x8D */ - /* Stack: uint32? --> */ - /* */ - static - void Ins_SCANTYPE( INS_ARG ) - { - /* for compatibility with future enhancements, */ - /* we must ignore new modes */ - - if ( args[0] >= 0 && args[0] <= 5 ) - { - if ( args[0] == 3 ) - args[0] = 2; - - CUR.GS.scan_type = (FT_Int)args[0]; - } - } - - - /*************************************************************************/ - /* */ - /* MANAGING OUTLINES */ - /* */ - /* Instructions appear in the specification's order. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* FLIPPT[]: FLIP PoinT */ - /* Opcode range: 0x80 */ - /* Stack: uint32... --> */ - /* */ - static - void Ins_FLIPPT( INS_ARG ) - { - FT_UShort point; - - FT_UNUSED_ARG; - - - if ( CUR.top < CUR.GS.loop ) - { - CUR.error = TT_Err_Too_Few_Arguments; - return; - } - - while ( CUR.GS.loop > 0 ) - { - CUR.args--; - - point = (FT_UShort)CUR.stack[CUR.args]; - - if ( BOUNDS( point, CUR.pts.n_points ) ) - { - if ( CUR.pedantic_hinting ) - { - CUR.error = TT_Err_Invalid_Reference; - return; - } - } - else - CUR.pts.tags[point] ^= FT_Curve_Tag_On; - - CUR.GS.loop--; - } - - CUR.GS.loop = 1; - CUR.new_top = CUR.args; - } - - - /*************************************************************************/ - /* */ - /* FLIPRGON[]: FLIP RanGe ON */ - /* Opcode range: 0x81 */ - /* Stack: uint32 uint32 --> */ - /* */ - static - void Ins_FLIPRGON( INS_ARG ) - { - FT_UShort I, K, L; - - - K = (FT_UShort)args[1]; - L = (FT_UShort)args[0]; - - if ( BOUNDS( K, CUR.pts.n_points ) || - BOUNDS( L, CUR.pts.n_points ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = TT_Err_Invalid_Reference; - return; - } - - for ( I = L; I <= K; I++ ) - CUR.pts.tags[I] |= FT_Curve_Tag_On; - } - - - /*************************************************************************/ - /* */ - /* FLIPRGOFF: FLIP RanGe OFF */ - /* Opcode range: 0x82 */ - /* Stack: uint32 uint32 --> */ - /* */ - static - void Ins_FLIPRGOFF( INS_ARG ) - { - FT_UShort I, K, L; - - - K = (FT_UShort)args[1]; - L = (FT_UShort)args[0]; - - if ( BOUNDS( K, CUR.pts.n_points ) || - BOUNDS( L, CUR.pts.n_points ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = TT_Err_Invalid_Reference; - return; - } - - for ( I = L; I <= K; I++ ) - CUR.pts.tags[I] &= ~FT_Curve_Tag_On; - } - - - static - FT_Bool Compute_Point_Displacement( EXEC_OP_ FT_F26Dot6* x, - FT_F26Dot6* y, - TT_GlyphZone* zone, - FT_UShort* refp ) - { - TT_GlyphZone zp; - FT_UShort p; - FT_F26Dot6 d; - - - if ( CUR.opcode & 1 ) - { - zp = CUR.zp0; - p = CUR.GS.rp1; - } - else - { - zp = CUR.zp1; - p = CUR.GS.rp2; - } - - if ( BOUNDS( p, zp.n_points ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = TT_Err_Invalid_Reference; - return FAILURE; - } - - *zone = zp; - *refp = p; - - d = CUR_Func_project( zp.cur + p, zp.org + p ); - -#ifdef NO_APPLE_PATENT - - *x = TT_MULDIV( d, CUR.GS.freeVector.x, 0x4000 ); - *y = TT_MULDIV( d, CUR.GS.freeVector.y, 0x4000 ); - -#else - - *x = TT_MULDIV( d, - (FT_Long)CUR.GS.freeVector.x * 0x10000L, - CUR.F_dot_P ); - *y = TT_MULDIV( d, - (FT_Long)CUR.GS.freeVector.y * 0x10000L, - CUR.F_dot_P ); - -#endif /* NO_APPLE_PATENT */ - - return SUCCESS; - } - - - static - void Move_Zp2_Point( EXEC_OP_ FT_UShort point, - FT_F26Dot6 dx, - FT_F26Dot6 dy, - FT_Bool touch ) - { - if ( CUR.GS.freeVector.x != 0 ) - { - CUR.zp2.cur[point].x += dx; - if ( touch ) - CUR.zp2.tags[point] |= FT_Curve_Tag_Touch_X; - } - - if ( CUR.GS.freeVector.y != 0 ) - { - CUR.zp2.cur[point].y += dy; - if ( touch ) - CUR.zp2.tags[point] |= FT_Curve_Tag_Touch_Y; - } - } - - - /*************************************************************************/ - /* */ - /* SHP[a]: SHift Point by the last point */ - /* Opcode range: 0x32-0x33 */ - /* Stack: uint32... --> */ - /* */ - static - void Ins_SHP( INS_ARG ) - { - TT_GlyphZone zp; - FT_UShort refp; - - FT_F26Dot6 dx, - dy; - FT_UShort point; - - FT_UNUSED_ARG; - - - if ( CUR.top < CUR.GS.loop ) - { - CUR.error = TT_Err_Invalid_Reference; - return; - } - - if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) - return; - - while ( CUR.GS.loop > 0 ) - { - CUR.args--; - point = (FT_UShort)CUR.stack[CUR.args]; - - if ( BOUNDS( point, CUR.zp2.n_points ) ) - { - if ( CUR.pedantic_hinting ) - { - CUR.error = TT_Err_Invalid_Reference; - return; - } - } - else - /* XXX: UNDOCUMENTED! SHP touches the points */ - MOVE_Zp2_Point( point, dx, dy, TRUE ); - - CUR.GS.loop--; - } - - CUR.GS.loop = 1; - CUR.new_top = CUR.args; - } - - - /*************************************************************************/ - /* */ - /* SHC[a]: SHift Contour */ - /* Opcode range: 0x34-35 */ - /* Stack: uint32 --> */ - /* */ - static - void Ins_SHC( INS_ARG ) - { - TT_GlyphZone zp; - FT_UShort refp; - FT_F26Dot6 dx, - dy; - - FT_Short contour; - FT_UShort first_point, last_point, i; - - - contour = (FT_UShort)args[0]; - - if ( BOUNDS( contour, CUR.pts.n_contours ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = TT_Err_Invalid_Reference; - return; - } - - if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) - return; - - if ( contour == 0 ) - first_point = 0; - else - first_point = CUR.pts.contours[contour - 1] + 1; - - last_point = CUR.pts.contours[contour]; - - /* XXX: this is probably wrong... at least it prevents memory */ - /* corruption when zp2 is the twilight zone */ - if ( last_point > CUR.zp2.n_points ) - { - if ( CUR.zp2.n_points > 0 ) - last_point = CUR.zp2.n_points - 1; - else - last_point = 0; - } - - /* XXX: UNDOCUMENTED! SHC doesn't touch the points */ - for ( i = first_point; i <= last_point; i++ ) - { - if ( zp.cur != CUR.zp2.cur || refp != i ) - MOVE_Zp2_Point( i, dx, dy, FALSE ); - } - } - - - /*************************************************************************/ - /* */ - /* SHZ[a]: SHift Zone */ - /* Opcode range: 0x36-37 */ - /* Stack: uint32 --> */ - /* */ - static - void Ins_SHZ( INS_ARG ) - { - TT_GlyphZone zp; - FT_UShort refp; - FT_F26Dot6 dx, - dy; - - FT_UShort last_point, i; - - - if ( BOUNDS( args[0], 2 ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = TT_Err_Invalid_Reference; - return; - } - - if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) ) - return; - - if ( CUR.zp2.n_points > 0 ) - last_point = CUR.zp2.n_points - 1; - else - last_point = 0; - - /* XXX: UNDOCUMENTED! SHZ doesn't touch the points */ - for ( i = 0; i <= last_point; i++ ) - { - if ( zp.cur != CUR.zp2.cur || refp != i ) - MOVE_Zp2_Point( i, dx, dy, FALSE ); - } - } - - - /*************************************************************************/ - /* */ - /* SHPIX[]: SHift points by a PIXel amount */ - /* Opcode range: 0x38 */ - /* Stack: f26.6 uint32... --> */ - /* */ - static - void Ins_SHPIX( INS_ARG ) - { - FT_F26Dot6 dx, dy; - FT_UShort point; - - - if ( CUR.top < CUR.GS.loop + 1 ) - { - CUR.error = TT_Err_Invalid_Reference; - return; - } - - dx = TT_MULDIV( args[0], - (FT_Long)CUR.GS.freeVector.x, - 0x4000 ); - dy = TT_MULDIV( args[0], - (FT_Long)CUR.GS.freeVector.y, - 0x4000 ); - - while ( CUR.GS.loop > 0 ) - { - CUR.args--; - - point = (FT_UShort)CUR.stack[CUR.args]; - - if ( BOUNDS( point, CUR.zp2.n_points ) ) - { - if ( CUR.pedantic_hinting ) - { - CUR.error = TT_Err_Invalid_Reference; - return; - } - } - else - MOVE_Zp2_Point( point, dx, dy, TRUE ); - - CUR.GS.loop--; - } - - CUR.GS.loop = 1; - CUR.new_top = CUR.args; - } - - - /*************************************************************************/ - /* */ - /* MSIRP[a]: Move Stack Indirect Relative Position */ - /* Opcode range: 0x3A-0x3B */ - /* Stack: f26.6 uint32 --> */ - /* */ - static - void Ins_MSIRP( INS_ARG ) - { - FT_UShort point; - FT_F26Dot6 distance; - - - point = (FT_UShort)args[0]; - - if ( BOUNDS( point, CUR.zp1.n_points ) || - BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = TT_Err_Invalid_Reference; - return; - } - - /* XXX: UNDOCUMENTED! behaviour */ - if ( CUR.GS.gep0 == 0 ) /* if in twilight zone */ - { - CUR.zp1.org[point] = CUR.zp0.org[CUR.GS.rp0]; - CUR.zp1.cur[point] = CUR.zp1.org[point]; - } - - distance = CUR_Func_project( CUR.zp1.cur + point, - CUR.zp0.cur + CUR.GS.rp0 ); - - CUR_Func_move( &CUR.zp1, point, args[1] - distance ); - - CUR.GS.rp1 = CUR.GS.rp0; - CUR.GS.rp2 = point; - - if ( (CUR.opcode & 1) != 0 ) - CUR.GS.rp0 = point; - } - - - /*************************************************************************/ - /* */ - /* MDAP[a]: Move Direct Absolute Point */ - /* Opcode range: 0x2E-0x2F */ - /* Stack: uint32 --> */ - /* */ - static - void Ins_MDAP( INS_ARG ) - { - FT_UShort point; - FT_F26Dot6 cur_dist, - distance; - - - point = (FT_UShort)args[0]; - - if ( BOUNDS( point, CUR.zp0.n_points ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = TT_Err_Invalid_Reference; - return; - } - - /* XXX: Is there some undocumented feature while in the */ - /* twilight zone? ? */ - if ( ( CUR.opcode & 1 ) != 0 ) - { - cur_dist = CUR_Func_project( CUR.zp0.cur + point, NULL_Vector ); - distance = CUR_Func_round( cur_dist, - CUR.tt_metrics.compensations[0] ) - cur_dist; - } - else - distance = 0; - - CUR_Func_move( &CUR.zp0, point, distance ); - - CUR.GS.rp0 = point; - CUR.GS.rp1 = point; - } - - - /*************************************************************************/ - /* */ - /* MIAP[a]: Move Indirect Absolute Point */ - /* Opcode range: 0x3E-0x3F */ - /* Stack: uint32 uint32 --> */ - /* */ - static - void Ins_MIAP( INS_ARG ) - { - FT_ULong cvtEntry; - FT_UShort point; - FT_F26Dot6 distance, - org_dist; - - - cvtEntry = (FT_ULong)args[1]; - point = (FT_UShort)args[0]; - - if ( BOUNDS( point, CUR.zp0.n_points ) || - BOUNDS( cvtEntry, CUR.cvtSize ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = TT_Err_Invalid_Reference; - return; - } - - /* UNDOCUMENTED! */ - /* */ - /* The behaviour of an MIAP instruction is quite */ - /* different when used in the twilight zone. */ - /* */ - /* First, no control value cutin test is performed */ - /* as it would fail anyway. Second, the original */ - /* point, i.e. (org_x,org_y) of zp0.point, is set */ - /* to the absolute, unrounded distance found in */ - /* the CVT. */ - /* */ - /* This is used in the CVT programs of the Microsoft */ - /* fonts Arial, Times, etc., in order to re-adjust */ - /* some key font heights. It allows the use of the */ - /* IP instruction in the twilight zone, which */ - /* otherwise would be `illegal' according to the */ - /* specification. */ - /* */ - /* We implement it with a special sequence for the */ - /* twilight zone. This is a bad hack, but it seems */ - /* to work. */ - - distance = CUR_Func_read_cvt( cvtEntry ); - - if ( CUR.GS.gep0 == 0 ) /* If in twilight zone */ - { - CUR.zp0.org[point].x = TT_MULDIV( CUR.GS.freeVector.x, - distance, 0x4000 ); - CUR.zp0.org[point].y = TT_MULDIV( CUR.GS.freeVector.y, - distance, 0x4000 ); - CUR.zp0.cur[point] = CUR.zp0.org[point]; - } - - org_dist = CUR_Func_project( CUR.zp0.cur + point, NULL_Vector ); - - if ( ( CUR.opcode & 1 ) != 0 ) /* rounding and control cutin flag */ - { - if ( ABS( distance - org_dist ) > CUR.GS.control_value_cutin ) - distance = org_dist; - - distance = CUR_Func_round( distance, CUR.tt_metrics.compensations[0] ); - } - - CUR_Func_move( &CUR.zp0, point, distance - org_dist ); - - CUR.GS.rp0 = point; - CUR.GS.rp1 = point; - } - - - /*************************************************************************/ - /* */ - /* MDRP[abcde]: Move Direct Relative Point */ - /* Opcode range: 0xC0-0xDF */ - /* Stack: uint32 --> */ - /* */ - static - void Ins_MDRP( INS_ARG ) - { - FT_UShort point; - FT_F26Dot6 org_dist, distance; - - - point = (FT_UShort)args[0]; - - if ( BOUNDS( point, CUR.zp1.n_points ) || - BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = TT_Err_Invalid_Reference; - return; - } - - /* XXX: Is there some undocumented feature while in the */ - /* twilight zone? */ - - org_dist = CUR_Func_dualproj( CUR.zp1.org + point, - CUR.zp0.org + CUR.GS.rp0 ); - - /* single width cutin test */ - - if ( ABS( org_dist ) < CUR.GS.single_width_cutin ) - { - if ( org_dist >= 0 ) - org_dist = CUR.GS.single_width_value; - else - org_dist = -CUR.GS.single_width_value; - } - - /* round flag */ - - if ( ( CUR.opcode & 4 ) != 0 ) - distance = CUR_Func_round( - org_dist, - CUR.tt_metrics.compensations[CUR.opcode & 3] ); - else - distance = ROUND_None( - org_dist, - CUR.tt_metrics.compensations[CUR.opcode & 3] ); - - /* minimum distance flag */ - - if ( ( CUR.opcode & 8 ) != 0 ) - { - if ( org_dist >= 0 ) - { - if ( distance < CUR.GS.minimum_distance ) - distance = CUR.GS.minimum_distance; - } - else - { - if ( distance > -CUR.GS.minimum_distance ) - distance = -CUR.GS.minimum_distance; - } - } - - /* now move the point */ - - org_dist = CUR_Func_project( CUR.zp1.cur + point, - CUR.zp0.cur + CUR.GS.rp0 ); - - CUR_Func_move( &CUR.zp1, point, distance - org_dist ); - - CUR.GS.rp1 = CUR.GS.rp0; - CUR.GS.rp2 = point; - - if ( ( CUR.opcode & 16 ) != 0 ) - CUR.GS.rp0 = point; - } - - - /*************************************************************************/ - /* */ - /* MIRP[abcde]: Move Indirect Relative Point */ - /* Opcode range: 0xE0-0xFF */ - /* Stack: int32? uint32 --> */ - /* */ - static - void Ins_MIRP( INS_ARG ) - { - FT_UShort point; - FT_ULong cvtEntry; - - FT_F26Dot6 cvt_dist, - distance, - cur_dist, - org_dist; - - - point = (FT_UShort)args[0]; - cvtEntry = (FT_ULong)( args[1] + 1 ); - - /* XXX: UNDOCUMENTED! cvt[-1] = 0 always */ - - if ( BOUNDS( point, CUR.zp1.n_points ) || - BOUNDS( cvtEntry, CUR.cvtSize + 1 ) || - BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = TT_Err_Invalid_Reference; - return; - } - - if ( !cvtEntry ) - cvt_dist = 0; - else - cvt_dist = CUR_Func_read_cvt( cvtEntry - 1 ); - - /* single width test */ - - if ( ABS( cvt_dist ) < CUR.GS.single_width_cutin ) - { - if ( cvt_dist >= 0 ) - cvt_dist = CUR.GS.single_width_value; - else - cvt_dist = -CUR.GS.single_width_value; - } - - /* XXX: UNDOCUMENTED! -- twilight zone */ - - if ( CUR.GS.gep1 == 0 ) - { - CUR.zp1.org[point].x = CUR.zp0.org[CUR.GS.rp0].x + - TT_MULDIV( cvt_dist, - CUR.GS.freeVector.x, - 0x4000 ); - - CUR.zp1.org[point].y = CUR.zp0.org[CUR.GS.rp0].y + - TT_MULDIV( cvt_dist, - CUR.GS.freeVector.y, - 0x4000 ); - - CUR.zp1.cur[point] = CUR.zp1.org[point]; - } - - org_dist = CUR_Func_dualproj( CUR.zp1.org + point, - CUR.zp0.org + CUR.GS.rp0 ); - - cur_dist = CUR_Func_project( CUR.zp1.cur + point, - CUR.zp0.cur + CUR.GS.rp0 ); - - /* auto-flip test */ - - if ( CUR.GS.auto_flip ) - { - if ( ( org_dist ^ cvt_dist ) < 0 ) - cvt_dist = -cvt_dist; - } - - /* control value cutin and round */ - - if ( ( CUR.opcode & 4 ) != 0 ) - { - /* XXX: UNDOCUMENTED! Only perform cut-in test when both points */ - /* refer to the same zone. */ - - if ( CUR.GS.gep0 == CUR.GS.gep1 ) - if ( ABS( cvt_dist - org_dist ) >= CUR.GS.control_value_cutin ) - cvt_dist = org_dist; - - distance = CUR_Func_round( - cvt_dist, - CUR.tt_metrics.compensations[CUR.opcode & 3] ); - } - else - distance = ROUND_None( - cvt_dist, - CUR.tt_metrics.compensations[CUR.opcode & 3] ); - - /* minimum distance test */ - - if ( ( CUR.opcode & 8 ) != 0 ) - { - if ( org_dist >= 0 ) - { - if ( distance < CUR.GS.minimum_distance ) - distance = CUR.GS.minimum_distance; - } - else - { - if ( distance > -CUR.GS.minimum_distance ) - distance = -CUR.GS.minimum_distance; - } - } - - CUR_Func_move( &CUR.zp1, point, distance - cur_dist ); - - CUR.GS.rp1 = CUR.GS.rp0; - - if ( ( CUR.opcode & 16 ) != 0 ) - CUR.GS.rp0 = point; - - /* XXX: UNDOCUMENTED! */ - - CUR.GS.rp2 = point; - } - - - /*************************************************************************/ - /* */ - /* ALIGNRP[]: ALIGN Relative Point */ - /* Opcode range: 0x3C */ - /* Stack: uint32 uint32... --> */ - /* */ - static - void Ins_ALIGNRP( INS_ARG ) - { - FT_UShort point; - FT_F26Dot6 distance; - - FT_UNUSED_ARG; - - - if ( CUR.top < CUR.GS.loop || - BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = TT_Err_Invalid_Reference; - return; - } - - while ( CUR.GS.loop > 0 ) - { - CUR.args--; - - point = (FT_UShort)CUR.stack[CUR.args]; - - if ( BOUNDS( point, CUR.zp1.n_points ) ) - { - if ( CUR.pedantic_hinting ) - { - CUR.error = TT_Err_Invalid_Reference; - return; - } - } - else - { - distance = CUR_Func_project( CUR.zp1.cur + point, - CUR.zp0.cur + CUR.GS.rp0 ); - - CUR_Func_move( &CUR.zp1, point, -distance ); - } - - CUR.GS.loop--; - } - - CUR.GS.loop = 1; - CUR.new_top = CUR.args; - } - - - /*************************************************************************/ - /* */ - /* ISECT[]: moves point to InterSECTion */ - /* Opcode range: 0x0F */ - /* Stack: 5 * uint32 --> */ - /* */ - static - void Ins_ISECT( INS_ARG ) - { - FT_UShort point, - a0, a1, - b0, b1; - - FT_F26Dot6 discriminant; - - FT_F26Dot6 dx, dy, - dax, day, - dbx, dby; - - FT_F26Dot6 val; - - FT_Vector R; - - - point = (FT_UShort)args[0]; - - a0 = (FT_UShort)args[1]; - a1 = (FT_UShort)args[2]; - b0 = (FT_UShort)args[3]; - b1 = (FT_UShort)args[4]; - - if ( BOUNDS( b0, CUR.zp0.n_points ) || - BOUNDS( b1, CUR.zp0.n_points ) || - BOUNDS( a0, CUR.zp1.n_points ) || - BOUNDS( a1, CUR.zp1.n_points ) || - BOUNDS( point, CUR.zp2.n_points ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = TT_Err_Invalid_Reference; - return; - } - - dbx = CUR.zp0.cur[b1].x - CUR.zp0.cur[b0].x; - dby = CUR.zp0.cur[b1].y - CUR.zp0.cur[b0].y; - - dax = CUR.zp1.cur[a1].x - CUR.zp1.cur[a0].x; - day = CUR.zp1.cur[a1].y - CUR.zp1.cur[a0].y; - - dx = CUR.zp0.cur[b0].x - CUR.zp1.cur[a0].x; - dy = CUR.zp0.cur[b0].y - CUR.zp1.cur[a0].y; - - CUR.zp2.tags[point] |= FT_Curve_Tag_Touch_Both; - - discriminant = TT_MULDIV( dax, -dby, 0x40 ) + - TT_MULDIV( day, dbx, 0x40 ); - - if ( ABS( discriminant ) >= 0x40 ) - { - val = TT_MULDIV( dx, -dby, 0x40 ) + TT_MULDIV( dy, dbx, 0x40 ); - - R.x = TT_MULDIV( val, dax, discriminant ); - R.y = TT_MULDIV( val, day, discriminant ); - - CUR.zp2.cur[point].x = CUR.zp1.cur[a0].x + R.x; - CUR.zp2.cur[point].y = CUR.zp1.cur[a0].y + R.y; - } - else - { - /* else, take the middle of the middles of A and B */ - - CUR.zp2.cur[point].x = ( CUR.zp1.cur[a0].x + - CUR.zp1.cur[a1].x + - CUR.zp0.cur[b0].x + - CUR.zp0.cur[b1].x ) / 4; - CUR.zp2.cur[point].y = ( CUR.zp1.cur[a0].y + - CUR.zp1.cur[a1].y + - CUR.zp0.cur[b0].y + - CUR.zp0.cur[b1].y ) / 4; - } - } - - - /*************************************************************************/ - /* */ - /* ALIGNPTS[]: ALIGN PoinTS */ - /* Opcode range: 0x27 */ - /* Stack: uint32 uint32 --> */ - /* */ - static - void Ins_ALIGNPTS( INS_ARG ) - { - FT_UShort p1, p2; - FT_F26Dot6 distance; - - - p1 = (FT_UShort)args[0]; - p2 = (FT_UShort)args[1]; - - if ( BOUNDS( args[0], CUR.zp1.n_points ) || - BOUNDS( args[1], CUR.zp0.n_points ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = TT_Err_Invalid_Reference; - return; - } - - distance = CUR_Func_project( CUR.zp0.cur + p2, - CUR.zp1.cur + p1 ) / 2; - - CUR_Func_move( &CUR.zp1, p1, distance ); - CUR_Func_move( &CUR.zp0, p2, -distance ); - } - - - /*************************************************************************/ - /* */ - /* IP[]: Interpolate Point */ - /* Opcode range: 0x39 */ - /* Stack: uint32... --> */ - /* */ - static - void Ins_IP( INS_ARG ) - { - FT_F26Dot6 org_a, org_b, org_x, - cur_a, cur_b, cur_x, - distance; - FT_UShort point; - - FT_UNUSED_ARG; - - - if ( CUR.top < CUR.GS.loop ) - { - CUR.error = TT_Err_Invalid_Reference; - return; - } - - /* XXX: There are some glyphs in some braindead but popular */ - /* fonts out there (e.g. [aeu]grave in monotype.ttf) */ - /* calling IP[] with bad values of rp[12]. */ - /* Do something sane when this odd thing happens. */ - - if ( BOUNDS( CUR.GS.rp1, CUR.zp0.n_points ) || - BOUNDS( CUR.GS.rp2, CUR.zp1.n_points ) ) - { - org_a = cur_a = 0; - org_b = cur_b = 0; - } - else - { - org_a = CUR_Func_dualproj( CUR.zp0.org + CUR.GS.rp1, NULL_Vector ); - org_b = CUR_Func_dualproj( CUR.zp1.org + CUR.GS.rp2, NULL_Vector ); - - cur_a = CUR_Func_project( CUR.zp0.cur + CUR.GS.rp1, NULL_Vector ); - cur_b = CUR_Func_project( CUR.zp1.cur + CUR.GS.rp2, NULL_Vector ); - } - - while ( CUR.GS.loop > 0 ) - { - CUR.args--; - - point = (FT_UShort)CUR.stack[CUR.args]; - if ( BOUNDS( point, CUR.zp2.n_points ) ) - { - if ( CUR.pedantic_hinting ) - { - CUR.error = TT_Err_Invalid_Reference; - return; - } - } - else - { - org_x = CUR_Func_dualproj( CUR.zp2.org + point, NULL_Vector ); - cur_x = CUR_Func_project ( CUR.zp2.cur + point, NULL_Vector ); - - if ( ( org_a <= org_b && org_x <= org_a ) || - ( org_a > org_b && org_x >= org_a ) ) - - distance = ( cur_a - org_a ) + ( org_x - cur_x ); - - else if ( ( org_a <= org_b && org_x >= org_b ) || - ( org_a > org_b && org_x < org_b ) ) - - distance = ( cur_b - org_b ) + ( org_x - cur_x ); - - else - /* note: it seems that rounding this value isn't a good */ - /* idea (cf. width of capital `S' in Times) */ - - distance = TT_MULDIV( cur_b - cur_a, - org_x - org_a, - org_b - org_a ) + ( cur_a - cur_x ); - - CUR_Func_move( &CUR.zp2, point, distance ); - } - - CUR.GS.loop--; - } - - CUR.GS.loop = 1; - CUR.new_top = CUR.args; - } - - - /*************************************************************************/ - /* */ - /* UTP[a]: UnTouch Point */ - /* Opcode range: 0x29 */ - /* Stack: uint32 --> */ - /* */ - static - void Ins_UTP( INS_ARG ) - { - FT_UShort point; - FT_Byte mask; - - - point = (FT_UShort)args[0]; - - if ( BOUNDS( point, CUR.zp0.n_points ) ) - { - if ( CUR.pedantic_hinting ) - CUR.error = TT_Err_Invalid_Reference; - return; - } - - mask = 0xFF; - - if ( CUR.GS.freeVector.x != 0 ) - mask &= ~FT_Curve_Tag_Touch_X; - - if ( CUR.GS.freeVector.y != 0 ) - mask &= ~FT_Curve_Tag_Touch_Y; - - CUR.zp0.tags[point] &= mask; - } - - - /* Local variables for Ins_IUP: */ - struct LOC_Ins_IUP - { - FT_Vector* orgs; /* original and current coordinate */ - FT_Vector* curs; /* arrays */ - }; - - - static - void Shift( FT_UInt p1, - FT_UInt p2, - FT_UInt p, - struct LOC_Ins_IUP* LINK ) - { - FT_UInt i; - FT_F26Dot6 x; - - - x = LINK->curs[p].x - LINK->orgs[p].x; - - for ( i = p1; i < p; i++ ) - LINK->curs[i].x += x; - - for ( i = p + 1; i <= p2; i++ ) - LINK->curs[i].x += x; - } - - - static - void Interp( FT_UInt p1, - FT_UInt p2, - FT_UInt ref1, - FT_UInt ref2, - struct LOC_Ins_IUP* LINK ) - { - FT_UInt i; - FT_F26Dot6 x, x1, x2, d1, d2; - - - if ( p1 > p2 ) - return; - - x1 = LINK->orgs[ref1].x; - d1 = LINK->curs[ref1].x - LINK->orgs[ref1].x; - x2 = LINK->orgs[ref2].x; - d2 = LINK->curs[ref2].x - LINK->orgs[ref2].x; - - if ( x1 == x2 ) - { - for ( i = p1; i <= p2; i++ ) - { - x = LINK->orgs[i].x; - - if ( x <= x1 ) - x += d1; - else - x += d2; - - LINK->curs[i].x = x; - } - return; - } - - if ( x1 < x2 ) - { - for ( i = p1; i <= p2; i++ ) - { - x = LINK->orgs[i].x; - - if ( x <= x1 ) - x += d1; - else - { - if ( x >= x2 ) - x += d2; - else - x = LINK->curs[ref1].x + - TT_MULDIV( x - x1, - LINK->curs[ref2].x - LINK->curs[ref1].x, - x2 - x1 ); - } - LINK->curs[i].x = x; - } - return; - } - - /* x2 < x1 */ - - for ( i = p1; i <= p2; i++ ) - { - x = LINK->orgs[i].x; - if ( x <= x2 ) - x += d2; - else - { - if ( x >= x1 ) - x += d1; - else - x = LINK->curs[ref1].x + - TT_MULDIV( x - x1, - LINK->curs[ref2].x - LINK->curs[ref1].x, - x2 - x1 ); - } - LINK->curs[i].x = x; - } - } - - - /*************************************************************************/ - /* */ - /* IUP[a]: Interpolate Untouched Points */ - /* Opcode range: 0x30-0x31 */ - /* Stack: --> */ - /* */ - static - void Ins_IUP( INS_ARG ) - { - struct LOC_Ins_IUP V; - FT_Byte mask; - - FT_UInt first_point; /* first point of contour */ - FT_UInt end_point; /* end point (last+1) of contour */ - - FT_UInt first_touched; /* first touched point in contour */ - FT_UInt cur_touched; /* current touched point in contour */ - - FT_UInt point; /* current point */ - FT_Short contour; /* current contour */ - - FT_UNUSED_ARG; - - - if ( CUR.opcode & 1 ) - { - mask = FT_Curve_Tag_Touch_X; - V.orgs = CUR.pts.org; - V.curs = CUR.pts.cur; - } - else - { - mask = FT_Curve_Tag_Touch_Y; - V.orgs = (FT_Vector*)( (FT_Pos*)CUR.pts.org + 1 ); - V.curs = (FT_Vector*)( (FT_Pos*)CUR.pts.cur + 1 ); - } - - contour = 0; - point = 0; - - do - { - end_point = CUR.pts.contours[contour]; - first_point = point; - - while ( point <= end_point && (CUR.pts.tags[point] & mask) == 0 ) - point++; - - if ( point <= end_point ) - { - first_touched = point; - cur_touched = point; - - point++; - - while ( point <= end_point ) - { - if ( ( CUR.pts.tags[point] & mask ) != 0 ) - { - if ( point > 0 ) - Interp( cur_touched + 1, - point - 1, - cur_touched, - point, - &V ); - cur_touched = point; - } - - point++; - } - - if ( cur_touched == first_touched ) - Shift( first_point, end_point, cur_touched, &V ); - else - { - Interp( (FT_UShort)( cur_touched + 1 ), - end_point, - cur_touched, - first_touched, - &V ); - - if ( first_touched > 0 ) - Interp( first_point, - first_touched - 1, - cur_touched, - first_touched, - &V ); - } - } - contour++; - } while ( contour < CUR.pts.n_contours ); - } - - - /*************************************************************************/ - /* */ - /* DELTAPn[]: DELTA exceptions P1, P2, P3 */ - /* Opcode range: 0x5D,0x71,0x72 */ - /* Stack: uint32 (2 * uint32)... --> */ - /* */ - static - void Ins_DELTAP( INS_ARG ) - { - FT_ULong k, nump; - FT_UShort A; - FT_ULong C; - FT_Long B; - - - nump = (FT_ULong)args[0]; /* some points theoretically may occur more - than once, thus UShort isn't enough */ - - for ( k = 1; k <= nump; k++ ) - { - if ( CUR.args < 2 ) - { - CUR.error = TT_Err_Too_Few_Arguments; - return; - } - - CUR.args -= 2; - - A = (FT_UShort)CUR.stack[CUR.args + 1]; - B = CUR.stack[CUR.args]; - - /* XXX: Because some popular fonts contain some invalid DeltaP */ - /* instructions, we simply ignore them when the stacked */ - /* point reference is off limit, rather than returning an */ - /* error. As a delta instruction doesn't change a glyph */ - /* in great ways, this shouldn't be a problem. */ - - if ( !BOUNDS( A, CUR.zp0.n_points ) ) - { - C = ( (FT_ULong)B & 0xF0 ) >> 4; - - switch ( CUR.opcode ) - { - case 0x5D: - break; - - case 0x71: - C += 16; - break; - - case 0x72: - C += 32; - break; - } - - C += CUR.GS.delta_base; - - if ( CURRENT_Ppem() == (FT_Long)C ) - { - B = ( (FT_ULong)B & 0xF ) - 8; - if ( B >= 0 ) - B++; - B = B * 64 / ( 1L << CUR.GS.delta_shift ); - - CUR_Func_move( &CUR.zp0, A, B ); - } - } - else - if ( CUR.pedantic_hinting ) - CUR.error = TT_Err_Invalid_Reference; - } - - CUR.new_top = CUR.args; - } - - - /*************************************************************************/ - /* */ - /* DELTACn[]: DELTA exceptions C1, C2, C3 */ - /* Opcode range: 0x73,0x74,0x75 */ - /* Stack: uint32 (2 * uint32)... --> */ - /* */ - static - void Ins_DELTAC( INS_ARG ) - { - FT_ULong nump, k; - FT_ULong A, C; - FT_Long B; - - - nump = (FT_ULong)args[0]; - - for ( k = 1; k <= nump; k++ ) - { - if ( CUR.args < 2 ) - { - CUR.error = TT_Err_Too_Few_Arguments; - return; - } - - CUR.args -= 2; - - A = (FT_ULong)CUR.stack[CUR.args + 1]; - B = CUR.stack[CUR.args]; - - if ( BOUNDS( A, CUR.cvtSize ) ) - { - if ( CUR.pedantic_hinting ) - { - CUR.error = TT_Err_Invalid_Reference; - return; - } - } - else - { - C = ( (FT_ULong)B & 0xF0 ) >> 4; - - switch ( CUR.opcode ) - { - case 0x73: - break; - - case 0x74: - C += 16; - break; - - case 0x75: - C += 32; - break; - } - - C += CUR.GS.delta_base; - - if ( CURRENT_Ppem() == (FT_Long)C ) - { - B = ( (FT_ULong)B & 0xF ) - 8; - if ( B >= 0 ) - B++; - B = B * 64 / ( 1L << CUR.GS.delta_shift ); - - CUR_Func_move_cvt( A, B ); - } - } - } - - CUR.new_top = CUR.args; - } - - - /*************************************************************************/ - /* */ - /* MISC. INSTRUCTIONS */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* GETINFO[]: GET INFOrmation */ - /* Opcode range: 0x88 */ - /* Stack: uint32 --> uint32 */ - /* */ - /* XXX: According to Apple specs, bits 1 & 2 of the argument ought to be */ - /* consulted before rotated/stretched info is returned. */ - static - void Ins_GETINFO( INS_ARG ) - { - FT_Long K; - - - K = 0; - - /* We return then Windows 3.1 version number */ - /* for the font scaler */ - if ( ( args[0] & 1 ) != 0 ) - K = 3; - - /* Has the glyph been rotated ? */ - if ( CUR.tt_metrics.rotated ) - K |= 0x80; - - /* Has the glyph been stretched ? */ - if ( CUR.tt_metrics.stretched ) - K |= 0x100; - - args[0] = K; - } - - - static - void Ins_UNKNOWN( INS_ARG ) - { - TT_DefRecord* def = CUR.IDefs; - TT_DefRecord* limit = def + CUR.numIDefs; - - FT_UNUSED_ARG; - - - for ( ; def < limit; def++ ) - { - if ( def->opc == CUR.opcode && def->active ) - { - TT_CallRec* call; - - - if ( CUR.callTop >= CUR.callSize ) - { - CUR.error = TT_Err_Stack_Overflow; - return; - } - - call = CUR.callStack + CUR.callTop++; - - call->Caller_Range = CUR.curRange; - call->Caller_IP = CUR.IP+1; - call->Cur_Count = 1; - call->Cur_Restart = def->start; - - INS_Goto_CodeRange( def->range, def->start ); - - CUR.step_ins = FALSE; - return; - } - } - - CUR.error = TT_Err_Invalid_Opcode; - } - - -#ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH - - - static - TInstruction_Function Instruct_Dispatch[256] = - { - /* Opcodes are gathered in groups of 16. */ - /* Please keep the spaces as they are. */ - - /* SVTCA y */ Ins_SVTCA, - /* SVTCA x */ Ins_SVTCA, - /* SPvTCA y */ Ins_SPVTCA, - /* SPvTCA x */ Ins_SPVTCA, - /* SFvTCA y */ Ins_SFVTCA, - /* SFvTCA x */ Ins_SFVTCA, - /* SPvTL // */ Ins_SPVTL, - /* SPvTL + */ Ins_SPVTL, - /* SFvTL // */ Ins_SFVTL, - /* SFvTL + */ Ins_SFVTL, - /* SPvFS */ Ins_SPVFS, - /* SFvFS */ Ins_SFVFS, - /* GPV */ Ins_GPV, - /* GFV */ Ins_GFV, - /* SFvTPv */ Ins_SFVTPV, - /* ISECT */ Ins_ISECT, - - /* SRP0 */ Ins_SRP0, - /* SRP1 */ Ins_SRP1, - /* SRP2 */ Ins_SRP2, - /* SZP0 */ Ins_SZP0, - /* SZP1 */ Ins_SZP1, - /* SZP2 */ Ins_SZP2, - /* SZPS */ Ins_SZPS, - /* SLOOP */ Ins_SLOOP, - /* RTG */ Ins_RTG, - /* RTHG */ Ins_RTHG, - /* SMD */ Ins_SMD, - /* ELSE */ Ins_ELSE, - /* JMPR */ Ins_JMPR, - /* SCvTCi */ Ins_SCVTCI, - /* SSwCi */ Ins_SSWCI, - /* SSW */ Ins_SSW, - - /* DUP */ Ins_DUP, - /* POP */ Ins_POP, - /* CLEAR */ Ins_CLEAR, - /* SWAP */ Ins_SWAP, - /* DEPTH */ Ins_DEPTH, - /* CINDEX */ Ins_CINDEX, - /* MINDEX */ Ins_MINDEX, - /* AlignPTS */ Ins_ALIGNPTS, - /* INS_0x28 */ Ins_UNKNOWN, - /* UTP */ Ins_UTP, - /* LOOPCALL */ Ins_LOOPCALL, - /* CALL */ Ins_CALL, - /* FDEF */ Ins_FDEF, - /* ENDF */ Ins_ENDF, - /* MDAP[0] */ Ins_MDAP, - /* MDAP[1] */ Ins_MDAP, - - /* IUP[0] */ Ins_IUP, - /* IUP[1] */ Ins_IUP, - /* SHP[0] */ Ins_SHP, - /* SHP[1] */ Ins_SHP, - /* SHC[0] */ Ins_SHC, - /* SHC[1] */ Ins_SHC, - /* SHZ[0] */ Ins_SHZ, - /* SHZ[1] */ Ins_SHZ, - /* SHPIX */ Ins_SHPIX, - /* IP */ Ins_IP, - /* MSIRP[0] */ Ins_MSIRP, - /* MSIRP[1] */ Ins_MSIRP, - /* AlignRP */ Ins_ALIGNRP, - /* RTDG */ Ins_RTDG, - /* MIAP[0] */ Ins_MIAP, - /* MIAP[1] */ Ins_MIAP, - - /* NPushB */ Ins_NPUSHB, - /* NPushW */ Ins_NPUSHW, - /* WS */ Ins_WS, - /* RS */ Ins_RS, - /* WCvtP */ Ins_WCVTP, - /* RCvt */ Ins_RCVT, - /* GC[0] */ Ins_GC, - /* GC[1] */ Ins_GC, - /* SCFS */ Ins_SCFS, - /* MD[0] */ Ins_MD, - /* MD[1] */ Ins_MD, - /* MPPEM */ Ins_MPPEM, - /* MPS */ Ins_MPS, - /* FlipON */ Ins_FLIPON, - /* FlipOFF */ Ins_FLIPOFF, - /* DEBUG */ Ins_DEBUG, - - /* LT */ Ins_LT, - /* LTEQ */ Ins_LTEQ, - /* GT */ Ins_GT, - /* GTEQ */ Ins_GTEQ, - /* EQ */ Ins_EQ, - /* NEQ */ Ins_NEQ, - /* ODD */ Ins_ODD, - /* EVEN */ Ins_EVEN, - /* IF */ Ins_IF, - /* EIF */ Ins_EIF, - /* AND */ Ins_AND, - /* OR */ Ins_OR, - /* NOT */ Ins_NOT, - /* DeltaP1 */ Ins_DELTAP, - /* SDB */ Ins_SDB, - /* SDS */ Ins_SDS, - - /* ADD */ Ins_ADD, - /* SUB */ Ins_SUB, - /* DIV */ Ins_DIV, - /* MUL */ Ins_MUL, - /* ABS */ Ins_ABS, - /* NEG */ Ins_NEG, - /* FLOOR */ Ins_FLOOR, - /* CEILING */ Ins_CEILING, - /* ROUND[0] */ Ins_ROUND, - /* ROUND[1] */ Ins_ROUND, - /* ROUND[2] */ Ins_ROUND, - /* ROUND[3] */ Ins_ROUND, - /* NROUND[0] */ Ins_NROUND, - /* NROUND[1] */ Ins_NROUND, - /* NROUND[2] */ Ins_NROUND, - /* NROUND[3] */ Ins_NROUND, - - /* WCvtF */ Ins_WCVTF, - /* DeltaP2 */ Ins_DELTAP, - /* DeltaP3 */ Ins_DELTAP, - /* DeltaCn[0] */ Ins_DELTAC, - /* DeltaCn[1] */ Ins_DELTAC, - /* DeltaCn[2] */ Ins_DELTAC, - /* SROUND */ Ins_SROUND, - /* S45Round */ Ins_S45ROUND, - /* JROT */ Ins_JROT, - /* JROF */ Ins_JROF, - /* ROFF */ Ins_ROFF, - /* INS_0x7B */ Ins_UNKNOWN, - /* RUTG */ Ins_RUTG, - /* RDTG */ Ins_RDTG, - /* SANGW */ Ins_SANGW, - /* AA */ Ins_AA, - - /* FlipPT */ Ins_FLIPPT, - /* FlipRgON */ Ins_FLIPRGON, - /* FlipRgOFF */ Ins_FLIPRGOFF, - /* INS_0x83 */ Ins_UNKNOWN, - /* INS_0x84 */ Ins_UNKNOWN, - /* ScanCTRL */ Ins_SCANCTRL, - /* SDPVTL[0] */ Ins_SDPVTL, - /* SDPVTL[1] */ Ins_SDPVTL, - /* GetINFO */ Ins_GETINFO, - /* IDEF */ Ins_IDEF, - /* ROLL */ Ins_ROLL, - /* MAX */ Ins_MAX, - /* MIN */ Ins_MIN, - /* ScanTYPE */ Ins_SCANTYPE, - /* InstCTRL */ Ins_INSTCTRL, - /* INS_0x8F */ Ins_UNKNOWN, - - /* INS_0x90 */ Ins_UNKNOWN, - /* INS_0x91 */ Ins_UNKNOWN, - /* INS_0x92 */ Ins_UNKNOWN, - /* INS_0x93 */ Ins_UNKNOWN, - /* INS_0x94 */ Ins_UNKNOWN, - /* INS_0x95 */ Ins_UNKNOWN, - /* INS_0x96 */ Ins_UNKNOWN, - /* INS_0x97 */ Ins_UNKNOWN, - /* INS_0x98 */ Ins_UNKNOWN, - /* INS_0x99 */ Ins_UNKNOWN, - /* INS_0x9A */ Ins_UNKNOWN, - /* INS_0x9B */ Ins_UNKNOWN, - /* INS_0x9C */ Ins_UNKNOWN, - /* INS_0x9D */ Ins_UNKNOWN, - /* INS_0x9E */ Ins_UNKNOWN, - /* INS_0x9F */ Ins_UNKNOWN, - - /* INS_0xA0 */ Ins_UNKNOWN, - /* INS_0xA1 */ Ins_UNKNOWN, - /* INS_0xA2 */ Ins_UNKNOWN, - /* INS_0xA3 */ Ins_UNKNOWN, - /* INS_0xA4 */ Ins_UNKNOWN, - /* INS_0xA5 */ Ins_UNKNOWN, - /* INS_0xA6 */ Ins_UNKNOWN, - /* INS_0xA7 */ Ins_UNKNOWN, - /* INS_0xA8 */ Ins_UNKNOWN, - /* INS_0xA9 */ Ins_UNKNOWN, - /* INS_0xAA */ Ins_UNKNOWN, - /* INS_0xAB */ Ins_UNKNOWN, - /* INS_0xAC */ Ins_UNKNOWN, - /* INS_0xAD */ Ins_UNKNOWN, - /* INS_0xAE */ Ins_UNKNOWN, - /* INS_0xAF */ Ins_UNKNOWN, - - /* PushB[0] */ Ins_PUSHB, - /* PushB[1] */ Ins_PUSHB, - /* PushB[2] */ Ins_PUSHB, - /* PushB[3] */ Ins_PUSHB, - /* PushB[4] */ Ins_PUSHB, - /* PushB[5] */ Ins_PUSHB, - /* PushB[6] */ Ins_PUSHB, - /* PushB[7] */ Ins_PUSHB, - /* PushW[0] */ Ins_PUSHW, - /* PushW[1] */ Ins_PUSHW, - /* PushW[2] */ Ins_PUSHW, - /* PushW[3] */ Ins_PUSHW, - /* PushW[4] */ Ins_PUSHW, - /* PushW[5] */ Ins_PUSHW, - /* PushW[6] */ Ins_PUSHW, - /* PushW[7] */ Ins_PUSHW, - - /* MDRP[00] */ Ins_MDRP, - /* MDRP[01] */ Ins_MDRP, - /* MDRP[02] */ Ins_MDRP, - /* MDRP[03] */ Ins_MDRP, - /* MDRP[04] */ Ins_MDRP, - /* MDRP[05] */ Ins_MDRP, - /* MDRP[06] */ Ins_MDRP, - /* MDRP[07] */ Ins_MDRP, - /* MDRP[08] */ Ins_MDRP, - /* MDRP[09] */ Ins_MDRP, - /* MDRP[10] */ Ins_MDRP, - /* MDRP[11] */ Ins_MDRP, - /* MDRP[12] */ Ins_MDRP, - /* MDRP[13] */ Ins_MDRP, - /* MDRP[14] */ Ins_MDRP, - /* MDRP[15] */ Ins_MDRP, - - /* MDRP[16] */ Ins_MDRP, - /* MDRP[17] */ Ins_MDRP, - /* MDRP[18] */ Ins_MDRP, - /* MDRP[19] */ Ins_MDRP, - /* MDRP[20] */ Ins_MDRP, - /* MDRP[21] */ Ins_MDRP, - /* MDRP[22] */ Ins_MDRP, - /* MDRP[23] */ Ins_MDRP, - /* MDRP[24] */ Ins_MDRP, - /* MDRP[25] */ Ins_MDRP, - /* MDRP[26] */ Ins_MDRP, - /* MDRP[27] */ Ins_MDRP, - /* MDRP[28] */ Ins_MDRP, - /* MDRP[29] */ Ins_MDRP, - /* MDRP[30] */ Ins_MDRP, - /* MDRP[31] */ Ins_MDRP, - - /* MIRP[00] */ Ins_MIRP, - /* MIRP[01] */ Ins_MIRP, - /* MIRP[02] */ Ins_MIRP, - /* MIRP[03] */ Ins_MIRP, - /* MIRP[04] */ Ins_MIRP, - /* MIRP[05] */ Ins_MIRP, - /* MIRP[06] */ Ins_MIRP, - /* MIRP[07] */ Ins_MIRP, - /* MIRP[08] */ Ins_MIRP, - /* MIRP[09] */ Ins_MIRP, - /* MIRP[10] */ Ins_MIRP, - /* MIRP[11] */ Ins_MIRP, - /* MIRP[12] */ Ins_MIRP, - /* MIRP[13] */ Ins_MIRP, - /* MIRP[14] */ Ins_MIRP, - /* MIRP[15] */ Ins_MIRP, - - /* MIRP[16] */ Ins_MIRP, - /* MIRP[17] */ Ins_MIRP, - /* MIRP[18] */ Ins_MIRP, - /* MIRP[19] */ Ins_MIRP, - /* MIRP[20] */ Ins_MIRP, - /* MIRP[21] */ Ins_MIRP, - /* MIRP[22] */ Ins_MIRP, - /* MIRP[23] */ Ins_MIRP, - /* MIRP[24] */ Ins_MIRP, - /* MIRP[25] */ Ins_MIRP, - /* MIRP[26] */ Ins_MIRP, - /* MIRP[27] */ Ins_MIRP, - /* MIRP[28] */ Ins_MIRP, - /* MIRP[29] */ Ins_MIRP, - /* MIRP[30] */ Ins_MIRP, - /* MIRP[31] */ Ins_MIRP - }; - - -#endif /* !TT_CONFIG_OPTION_INTERPRETER_SWITCH */ - - - /*************************************************************************/ - /* */ - /* RUN */ - /* */ - /* This function executes a run of opcodes. It will exit in the */ - /* following cases: */ - /* */ - /* - Errors (in which case it returns FALSE). */ - /* */ - /* - Reaching the end of the main code range (returns TRUE). */ - /* Reaching the end of a code range within a function call is an */ - /* error. */ - /* */ - /* - After executing one single opcode, if the flag `Instruction_Trap' */ - /* is set to TRUE (returns TRUE). */ - /* */ - /* On exit whith TRUE, test IP < CodeSize to know wether it comes from */ - /* an instruction trap or a normal termination. */ - /* */ - /* */ - /* Note: The documented DEBUG opcode pops a value from the stack. This */ - /* behaviour is unsupported; here a DEBUG opcode is always an */ - /* error. */ - /* */ - /* */ - /* THIS IS THE INTERPRETER'S MAIN LOOP. */ - /* */ - /* Instructions appear in the specification's order. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* TT_RunIns */ - /* */ - /* */ - /* Executes one or more instruction in the execution context. This */ - /* is the main function of the TrueType opcode interpreter. */ - /* */ - /* */ - /* exec :: A handle to the target execution context. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Only the object manager and debugger should call this function. */ - /* */ - /* This function is publicly exported because it is directly */ - /* invoked by the TrueType debugger. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) TT_RunIns( TT_ExecContext exc ) - { - FT_Long ins_counter = 0; /* executed instructions counter */ - - -#ifdef TT_CONFIG_OPTION_STATIC_RASTER - cur = *exc; -#endif - - /* set CVT functions */ - CUR.tt_metrics.ratio = 0; - if ( CUR.metrics.x_ppem != CUR.metrics.y_ppem ) - { - /* non-square pixels, use the stretched routines */ - CUR.func_read_cvt = Read_CVT_Stretched; - CUR.func_write_cvt = Write_CVT_Stretched; - CUR.func_move_cvt = Move_CVT_Stretched; - } - else - { - /* square pixels, use normal routines */ - CUR.func_read_cvt = Read_CVT; - CUR.func_write_cvt = Write_CVT; - CUR.func_move_cvt = Move_CVT; - } - - COMPUTE_Funcs(); - COMPUTE_Round( (FT_Byte)exc->GS.round_state ); - - do - { - CUR.opcode = CUR.code[CUR.IP]; - - if ( ( CUR.length = opcode_length[CUR.opcode] ) < 0 ) - { - if ( CUR.IP + 1 > CUR.codeSize ) - goto LErrorCodeOverflow_; - - CUR.length = CUR.code[CUR.IP + 1] + 2; - } - - if ( CUR.IP + CUR.length > CUR.codeSize ) - goto LErrorCodeOverflow_; - - /* First, let's check for empty stack and overflow */ - CUR.args = CUR.top - ( Pop_Push_Count[CUR.opcode] >> 4 ); - - /* `args' is the top of the stack once arguments have been popped. */ - /* One can also interpret it as the index of the last argument. */ - if ( CUR.args < 0 ) - { - CUR.error = TT_Err_Too_Few_Arguments; - goto LErrorLabel_; - } - - CUR.new_top = CUR.args + ( Pop_Push_Count[CUR.opcode] & 15 ); - - /* `new_top' is the new top of the stack, after the instruction's */ - /* execution. `top' will be set to `new_top' after the `switch' */ - /* statement. */ - if ( CUR.new_top > CUR.stackSize ) - { - CUR.error = TT_Err_Stack_Overflow; - goto LErrorLabel_; - } - - CUR.step_ins = TRUE; - CUR.error = TT_Err_Ok; - -#ifdef TT_CONFIG_OPTION_INTERPRETER_SWITCH - - { - FT_Long* args = CUR.stack + CUR.args; - FT_Byte opcode = CUR.opcode; - - -#undef ARRAY_BOUND_ERROR -#define ARRAY_BOUND_ERROR goto Set_Invalid_Ref - - - switch ( opcode ) - { - case 0x00: /* SVTCA y */ - case 0x01: /* SVTCA x */ - case 0x02: /* SPvTCA y */ - case 0x03: /* SPvTCA x */ - case 0x04: /* SFvTCA y */ - case 0x05: /* SFvTCA x */ - { - FT_Short AA, BB; - - - AA = (FT_Short)( opcode & 1 ) << 14; - BB = AA ^ (FT_Short)0x4000; - - if ( opcode < 4 ) - { - CUR.GS.projVector.x = AA; - CUR.GS.projVector.y = BB; - - CUR.GS.dualVector.x = AA; - CUR.GS.dualVector.y = BB; - } - - if ( ( opcode & 2 ) == 0 ) - { - CUR.GS.freeVector.x = AA; - CUR.GS.freeVector.y = BB; - } - - COMPUTE_Funcs(); - } - break; - - case 0x06: /* SPvTL // */ - case 0x07: /* SPvTL + */ - DO_SPVTL - break; - - case 0x08: /* SFvTL // */ - case 0x09: /* SFvTL + */ - DO_SFVTL - break; - - case 0x0A: /* SPvFS */ - DO_SPVFS - break; - - case 0x0B: /* SFvFS */ - DO_SFVFS - break; - - case 0x0C: /* GPV */ - DO_GPV - break; - - case 0x0D: /* GFV */ - DO_GFV - break; - - case 0x0E: /* SFvTPv */ - DO_SFVTPV - break; - - case 0x0F: /* ISECT */ - Ins_ISECT( EXEC_ARG_ args ); - break; - - case 0x10: /* SRP0 */ - DO_SRP0 - break; - - case 0x11: /* SRP1 */ - DO_SRP1 - break; - - case 0x12: /* SRP2 */ - DO_SRP2 - break; - - case 0x13: /* SZP0 */ - Ins_SZP0( EXEC_ARG_ args ); - break; - - case 0x14: /* SZP1 */ - Ins_SZP1( EXEC_ARG_ args ); - break; - - case 0x15: /* SZP2 */ - Ins_SZP2( EXEC_ARG_ args ); - break; - - case 0x16: /* SZPS */ - Ins_SZPS( EXEC_ARG_ args ); - break; - - case 0x17: /* SLOOP */ - DO_SLOOP - break; - - case 0x18: /* RTG */ - DO_RTG - break; - - case 0x19: /* RTHG */ - DO_RTHG - break; - - case 0x1A: /* SMD */ - DO_SMD - break; - - case 0x1B: /* ELSE */ - Ins_ELSE( EXEC_ARG_ args ); - break; - - case 0x1C: /* JMPR */ - DO_JMPR - break; - - case 0x1D: /* SCVTCI */ - DO_SCVTCI - break; - - case 0x1E: /* SSWCI */ - DO_SSWCI - break; - - case 0x1F: /* SSW */ - DO_SSW - break; - - case 0x20: /* DUP */ - DO_DUP - break; - - case 0x21: /* POP */ - /* nothing :-) */ - break; - - case 0x22: /* CLEAR */ - DO_CLEAR - break; - - case 0x23: /* SWAP */ - DO_SWAP - break; - - case 0x24: /* DEPTH */ - DO_DEPTH - break; - - case 0x25: /* CINDEX */ - DO_CINDEX - break; - - case 0x26: /* MINDEX */ - Ins_MINDEX( EXEC_ARG_ args ); - break; - - case 0x27: /* ALIGNPTS */ - Ins_ALIGNPTS( EXEC_ARG_ args ); - break; - - case 0x28: /* ???? */ - Ins_UNKNOWN( EXEC_ARG_ args ); - break; - - case 0x29: /* UTP */ - Ins_UTP( EXEC_ARG_ args ); - break; - - case 0x2A: /* LOOPCALL */ - Ins_LOOPCALL( EXEC_ARG_ args ); - break; - - case 0x2B: /* CALL */ - Ins_CALL( EXEC_ARG_ args ); - break; - - case 0x2C: /* FDEF */ - Ins_FDEF( EXEC_ARG_ args ); - break; - - case 0x2D: /* ENDF */ - Ins_ENDF( EXEC_ARG_ args ); - break; - - case 0x2E: /* MDAP */ - case 0x2F: /* MDAP */ - Ins_MDAP( EXEC_ARG_ args ); - break; - - - case 0x30: /* IUP */ - case 0x31: /* IUP */ - Ins_IUP( EXEC_ARG_ args ); - break; - - case 0x32: /* SHP */ - case 0x33: /* SHP */ - Ins_SHP( EXEC_ARG_ args ); - break; - - case 0x34: /* SHC */ - case 0x35: /* SHC */ - Ins_SHC( EXEC_ARG_ args ); - break; - - case 0x36: /* SHZ */ - case 0x37: /* SHZ */ - Ins_SHZ( EXEC_ARG_ args ); - break; - - case 0x38: /* SHPIX */ - Ins_SHPIX( EXEC_ARG_ args ); - break; - - case 0x39: /* IP */ - Ins_IP( EXEC_ARG_ args ); - break; - - case 0x3A: /* MSIRP */ - case 0x3B: /* MSIRP */ - Ins_MSIRP( EXEC_ARG_ args ); - break; - - case 0x3C: /* AlignRP */ - Ins_ALIGNRP( EXEC_ARG_ args ); - break; - - case 0x3D: /* RTDG */ - DO_RTDG - break; - - case 0x3E: /* MIAP */ - case 0x3F: /* MIAP */ - Ins_MIAP( EXEC_ARG_ args ); - break; - - case 0x40: /* NPUSHB */ - Ins_NPUSHB( EXEC_ARG_ args ); - break; - - case 0x41: /* NPUSHW */ - Ins_NPUSHW( EXEC_ARG_ args ); - break; - - case 0x42: /* WS */ - DO_WS - break; - - Set_Invalid_Ref: - CUR.error = TT_Err_Invalid_Reference; - break; - - case 0x43: /* RS */ - DO_RS - break; - - case 0x44: /* WCVTP */ - DO_WCVTP - break; - - case 0x45: /* RCVT */ - DO_RCVT - break; - - case 0x46: /* GC */ - case 0x47: /* GC */ - Ins_GC( EXEC_ARG_ args ); - break; - - case 0x48: /* SCFS */ - Ins_SCFS( EXEC_ARG_ args ); - break; - - case 0x49: /* MD */ - case 0x4A: /* MD */ - Ins_MD( EXEC_ARG_ args ); - break; - - case 0x4B: /* MPPEM */ - DO_MPPEM - break; - - case 0x4C: /* MPS */ - DO_MPS - break; - - case 0x4D: /* FLIPON */ - DO_FLIPON - break; - - case 0x4E: /* FLIPOFF */ - DO_FLIPOFF - break; - - case 0x4F: /* DEBUG */ - DO_DEBUG - break; - - case 0x50: /* LT */ - DO_LT - break; - - case 0x51: /* LTEQ */ - DO_LTEQ - break; - - case 0x52: /* GT */ - DO_GT - break; - - case 0x53: /* GTEQ */ - DO_GTEQ - break; - - case 0x54: /* EQ */ - DO_EQ - break; - - case 0x55: /* NEQ */ - DO_NEQ - break; - - case 0x56: /* ODD */ - DO_ODD - break; - - case 0x57: /* EVEN */ - DO_EVEN - break; - - case 0x58: /* IF */ - Ins_IF( EXEC_ARG_ args ); - break; - - case 0x59: /* EIF */ - /* do nothing */ - break; - - case 0x5A: /* AND */ - DO_AND - break; - - case 0x5B: /* OR */ - DO_OR - break; - - case 0x5C: /* NOT */ - DO_NOT - break; - - case 0x5D: /* DELTAP1 */ - Ins_DELTAP( EXEC_ARG_ args ); - break; - - case 0x5E: /* SDB */ - DO_SDB - break; - - case 0x5F: /* SDS */ - DO_SDS - break; - - case 0x60: /* ADD */ - DO_ADD - break; - - case 0x61: /* SUB */ - DO_SUB - break; - - case 0x62: /* DIV */ - DO_DIV - break; - - case 0x63: /* MUL */ - DO_MUL - break; - - case 0x64: /* ABS */ - DO_ABS - break; - - case 0x65: /* NEG */ - DO_NEG - break; - - case 0x66: /* FLOOR */ - DO_FLOOR - break; - - case 0x67: /* CEILING */ - DO_CEILING - break; - - case 0x68: /* ROUND */ - case 0x69: /* ROUND */ - case 0x6A: /* ROUND */ - case 0x6B: /* ROUND */ - DO_ROUND - break; - - case 0x6C: /* NROUND */ - case 0x6D: /* NROUND */ - case 0x6E: /* NRRUND */ - case 0x6F: /* NROUND */ - DO_NROUND - break; - - case 0x70: /* WCVTF */ - DO_WCVTF - break; - - case 0x71: /* DELTAP2 */ - case 0x72: /* DELTAP3 */ - Ins_DELTAP( EXEC_ARG_ args ); - break; - - case 0x73: /* DELTAC0 */ - case 0x74: /* DELTAC1 */ - case 0x75: /* DELTAC2 */ - Ins_DELTAC( EXEC_ARG_ args ); - break; - - case 0x76: /* SROUND */ - DO_SROUND - break; - - case 0x77: /* S45Round */ - DO_S45ROUND - break; - - case 0x78: /* JROT */ - DO_JROT - break; - - case 0x79: /* JROF */ - DO_JROF - break; - - case 0x7A: /* ROFF */ - DO_ROFF - break; - - case 0x7B: /* ???? */ - Ins_UNKNOWN( EXEC_ARG_ args ); - break; - - case 0x7C: /* RUTG */ - DO_RUTG - break; - - case 0x7D: /* RDTG */ - DO_RDTG - break; - - case 0x7E: /* SANGW */ - case 0x7F: /* AA */ - /* nothing - obsolete */ - break; - - case 0x80: /* FLIPPT */ - Ins_FLIPPT( EXEC_ARG_ args ); - break; - - case 0x81: /* FLIPRGON */ - Ins_FLIPRGON( EXEC_ARG_ args ); - break; - - case 0x82: /* FLIPRGOFF */ - Ins_FLIPRGOFF( EXEC_ARG_ args ); - break; - - case 0x83: /* UNKNOWN */ - case 0x84: /* UNKNOWN */ - Ins_UNKNOWN( EXEC_ARG_ args ); - break; - - case 0x85: /* SCANCTRL */ - Ins_SCANCTRL( EXEC_ARG_ args ); - break; - - case 0x86: /* SDPVTL */ - case 0x87: /* SDPVTL */ - Ins_SDPVTL( EXEC_ARG_ args ); - break; - - case 0x88: /* GETINFO */ - Ins_GETINFO( EXEC_ARG_ args ); - break; - - case 0x89: /* IDEF */ - Ins_IDEF( EXEC_ARG_ args ); - break; - - case 0x8A: /* ROLL */ - Ins_ROLL( EXEC_ARG_ args ); - break; - - case 0x8B: /* MAX */ - DO_MAX - break; - - case 0x8C: /* MIN */ - DO_MIN - break; - - case 0x8D: /* SCANTYPE */ - Ins_SCANTYPE( EXEC_ARG_ args ); - break; - - case 0x8E: /* INSTCTRL */ - Ins_INSTCTRL( EXEC_ARG_ args ); - break; - - case 0x8F: - Ins_UNKNOWN( EXEC_ARG_ args ); - break; - - default: - if ( opcode >= 0xE0 ) - Ins_MIRP( EXEC_ARG_ args ); - else if ( opcode >= 0xC0 ) - Ins_MDRP( EXEC_ARG_ args ); - else if ( opcode >= 0xB8 ) - Ins_PUSHW( EXEC_ARG_ args ); - else if ( opcode >= 0xB0 ) - Ins_PUSHB( EXEC_ARG_ args ); - else - Ins_UNKNOWN( EXEC_ARG_ args ); - } - - } - -#else - - Instruct_Dispatch[CUR.opcode]( EXEC_ARG_ &CUR.stack[CUR.args] ); - -#endif /* TT_CONFIG_OPTION_INTERPRETER_SWITCH */ - - if ( CUR.error != TT_Err_Ok ) - { - switch ( CUR.error ) - { - case TT_Err_Invalid_Opcode: /* looking for redefined instructions */ - { - TT_DefRecord* def = CUR.IDefs; - TT_DefRecord* limit = def + CUR.numIDefs; - - - for ( ; def < limit; def++ ) - { - if ( def->active && CUR.opcode == def->opc ) - { - TT_CallRec* callrec; - - - if ( CUR.callTop >= CUR.callSize ) - { - CUR.error = TT_Err_Invalid_Reference; - goto LErrorLabel_; - } - - callrec = &CUR.callStack[CUR.callTop]; - - callrec->Caller_Range = CUR.curRange; - callrec->Caller_IP = CUR.IP + 1; - callrec->Cur_Count = 1; - callrec->Cur_Restart = def->start; - - if ( INS_Goto_CodeRange( def->range, def->start ) == FAILURE ) - goto LErrorLabel_; - - goto LSuiteLabel_; - } - } - } - - CUR.error = TT_Err_Invalid_Opcode; - goto LErrorLabel_; - -#if 0 - break; /* Unreachable code warning suppression. */ - /* Leave to remind in case a later change the editor */ - /* to consider break; */ -#endif - - default: - goto LErrorLabel_; - -#if 0 - break; -#endif - } - } - - CUR.top = CUR.new_top; - - if ( CUR.step_ins ) - CUR.IP += CUR.length; - - /* increment instruction counter and check if we didn't */ - /* run this program for too long (e.g. infinite loops). */ - if ( ++ins_counter > MAX_RUNNABLE_OPCODES ) - return TT_Err_Execution_Too_Long; - - LSuiteLabel_: - if ( CUR.IP >= CUR.codeSize ) - { - if ( CUR.callTop > 0 ) - { - CUR.error = TT_Err_Code_Overflow; - goto LErrorLabel_; - } - else - goto LNo_Error_; - } - } while ( !CUR.instruction_trap ); - - LNo_Error_: - -#ifdef TT_CONFIG_OPTION_STATIC_RASTER - *exc = cur; -#endif - - return TT_Err_Ok; - - LErrorCodeOverflow_: - CUR.error = TT_Err_Code_Overflow; - - LErrorLabel_: - -#ifdef TT_CONFIG_OPTION_STATIC_RASTER - *exc = cur; -#endif - - return CUR.error; - } - - -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ - - -/* END */ diff --git a/src/freetype/truetype/ttinterp.h b/src/freetype/truetype/ttinterp.h deleted file mode 100644 index 6e92699cdc..0000000000 --- a/src/freetype/truetype/ttinterp.h +++ /dev/null @@ -1,278 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttinterp.h */ -/* */ -/* TrueType bytecode interpreter (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifndef TTINTERP_H -#define TTINTERP_H - - -#ifdef FT_FLAT_COMPILE - -#include "ttobjs.h" - -#else - -#include - -#endif - - -#ifdef __cplusplus - extern "C" { -#endif - - -#ifndef TT_CONFIG_OPTION_STATIC_INTEPRETER /* indirect implementation */ - -#define EXEC_OP_ TT_ExecContext exc, -#define EXEC_OP TT_ExecContext exc -#define EXEC_ARG_ exc, -#define EXEC_ARG exc - -#else /* static implementation */ - -#define EXEC_OP_ /* void */ -#define EXEC_OP /* void */ -#define EXEC_ARG_ /* void */ -#define EXEC_ARG /* void */ - -#endif /* TT_CONFIG_OPTION_STATIC_INTERPRETER */ - - - /*************************************************************************/ - /* */ - /* Rounding mode constants. */ - /* */ -#define TT_Round_Off 5 -#define TT_Round_To_Half_Grid 0 -#define TT_Round_To_Grid 1 -#define TT_Round_To_Double_Grid 2 -#define TT_Round_Up_To_Grid 4 -#define TT_Round_Down_To_Grid 3 -#define TT_Round_Super 6 -#define TT_Round_Super_45 7 - - - /*************************************************************************/ - /* */ - /* Function types used by the interpreter, depending on various modes */ - /* (e.g. the rounding mode, whether to render a vertical or horizontal */ - /* line etc). */ - /* */ - /*************************************************************************/ - - /* Rounding function */ - typedef FT_F26Dot6 (*TT_Round_Func)( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ); - - /* Point displacement along the freedom vector routine */ - typedef void (*TT_Move_Func)( EXEC_OP_ TT_GlyphZone* zone, - FT_UInt point, - FT_F26Dot6 distance ); - - /* Distance projection along one of the projection vectors */ - typedef FT_F26Dot6 (*TT_Project_Func)( EXEC_OP_ FT_Vector* v1, - FT_Vector* v2 ); - - /* reading a cvt value. Take care of non-square pixels if necessary */ - typedef FT_F26Dot6 (*TT_Get_CVT_Func)( EXEC_OP_ FT_ULong index ); - - /* setting or moving a cvt value. Take care of non-square pixels */ - /* if necessary */ - typedef void (*TT_Set_CVT_Func)( EXEC_OP_ FT_ULong index, - FT_F26Dot6 value ); - - - /*************************************************************************/ - /* */ - /* This structure defines a call record, used to manage function calls. */ - /* */ - typedef struct TT_CallRec_ - { - FT_Int Caller_Range; - FT_Long Caller_IP; - FT_Long Cur_Count; - FT_Long Cur_Restart; - - } TT_CallRec, *TT_CallStack; - - - /*************************************************************************/ - /* */ - /* The main structure for the interpreter which collects all necessary */ - /* variables and states. */ - /* */ - typedef struct TT_ExecContextRec_ - { - TT_Face face; - TT_Size size; - FT_Memory memory; - - /* instructions state */ - - FT_Error error; /* last execution error */ - - FT_Long top; /* top of exec. stack */ - - FT_UInt stackSize; /* size of exec. stack */ - FT_Long* stack; /* current exec. stack */ - - FT_Long args; - FT_UInt new_top; /* new top after exec. */ - - TT_GlyphZone zp0, /* zone records */ - zp1, - zp2, - pts, - twilight; - - FT_Size_Metrics metrics; - TT_Size_Metrics tt_metrics; /* size metrics */ - - TT_GraphicsState GS; /* current graphics state */ - - FT_Int curRange; /* current code range number */ - FT_Byte* code; /* current code range */ - FT_Long IP; /* current instruction pointer */ - FT_Long codeSize; /* size of current range */ - - FT_Byte opcode; /* current opcode */ - FT_Int length; /* length of current opcode */ - - FT_Bool step_ins; /* true if the interpreter must */ - /* increment IP after ins. exec */ - FT_Long cvtSize; - FT_Long* cvt; - - FT_UInt glyphSize; /* glyph instructions buffer size */ - FT_Byte* glyphIns; /* glyph instructions buffer */ - - FT_UInt numFDefs; /* number of function defs */ - FT_UInt maxFDefs; /* maximum number of function defs */ - TT_DefArray FDefs; /* table of FDefs entries */ - - FT_UInt numIDefs; /* number of instruction defs */ - FT_UInt maxIDefs; /* maximum number of ins defs */ - TT_DefArray IDefs; /* table of IDefs entries */ - - FT_UInt maxFunc; /* maximum function index */ - FT_UInt maxIns; /* maximum instruction index */ - - FT_Int callTop, /* top of call stack during execution */ - callSize; /* size of call stack */ - TT_CallStack callStack; /* call stack */ - - FT_UShort maxPoints; /* capacity of this context's `pts' */ - FT_Short maxContours; /* record, expressed in points and */ - /* contours. */ - - TT_CodeRangeTable codeRangeTable; /* table of valid code ranges */ - /* useful for the debugger */ - - FT_UShort storeSize; /* size of current storage */ - FT_Long* storage; /* storage area */ - - FT_F26Dot6 period; /* values used for the */ - FT_F26Dot6 phase; /* `SuperRounding' */ - FT_F26Dot6 threshold; - -#if 0 - /* this seems to be unused */ - FT_Int cur_ppem; /* ppem along the current proj vector */ -#endif - - FT_Bool instruction_trap; /* If `True', the interpreter will */ - /* exit after each instruction */ - - TT_GraphicsState default_GS; /* graphics state resulting from */ - /* the prep program */ - FT_Bool is_composite; /* true if the glyph is composite */ - FT_Bool pedantic_hinting; /* true for pedantic interpretation */ - - /* latest interpreter additions */ - - FT_Long F_dot_P; /* dot product of freedom and projection */ - /* vectors */ - TT_Round_Func func_round; /* current rounding function */ - - TT_Project_Func func_project, /* current projection function */ - func_dualproj, /* current dual proj. function */ - func_freeProj; /* current freedom proj. func */ - - TT_Move_Func func_move; /* current point move function */ - - TT_Get_CVT_Func func_read_cvt; /* read a cvt entry */ - TT_Set_CVT_Func func_write_cvt; /* write a cvt entry (in pixels) */ - TT_Set_CVT_Func func_move_cvt; /* incr a cvt entry (in pixels) */ - - FT_ULong loadSize; - TT_SubGlyph_Stack loadStack; /* loading subglyph stack */ - - } TT_ExecContextRec; - - - extern const TT_GraphicsState tt_default_graphics_state; - - - LOCAL_DEF - FT_Error TT_Goto_CodeRange( TT_ExecContext exec, - FT_Int range, - FT_Long IP ); - - LOCAL_DEF - FT_Error TT_Set_CodeRange( TT_ExecContext exec, - FT_Int range, - void* base, - FT_Long length ); - - LOCAL_DEF - FT_Error TT_Clear_CodeRange( TT_ExecContext exec, - FT_Int range ); - - FT_EXPORT_DEF( TT_ExecContext ) TT_New_Context( TT_Face face ); - - LOCAL_DEF - FT_Error TT_Done_Context( TT_ExecContext exec ); - - LOCAL_DEF - FT_Error TT_Destroy_Context( TT_ExecContext exec, - FT_Memory memory ); - - LOCAL_DEF - FT_Error TT_Load_Context( TT_ExecContext exec, - TT_Face face, - TT_Size size ); - - LOCAL_DEF - FT_Error TT_Save_Context( TT_ExecContext exec, - TT_Size ins ); - - LOCAL_DEF - FT_Error TT_Run_Context( TT_ExecContext exec, - FT_Bool debug ); - - FT_EXPORT_DEF( FT_Error ) TT_RunIns( TT_ExecContext exec ); - - -#ifdef __cplusplus - } -#endif - -#endif /* TTINTERP_H */ - - -/* END */ diff --git a/src/freetype/truetype/ttobjs.c b/src/freetype/truetype/ttobjs.c deleted file mode 100644 index 2ba715dc11..0000000000 --- a/src/freetype/truetype/ttobjs.c +++ /dev/null @@ -1,734 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttobjs.c */ -/* */ -/* Objects manager (body). */ -/* */ -/* 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 -#include -#include -#include -#include - -#include -#include - - -#ifdef FT_FLAT_COMPILE - -#include "ttgload.h" -#include "ttpload.h" - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER -#include "ttinterp.h" -#endif - -#else /* FT_FLAT_COMPILE */ - -#include -#include - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER -#include -#endif - -#endif /* FT_FLAT_COMPILE */ - - -#include - - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_ttobjs - - - /*************************************************************************/ - /* */ - /* GLYPH ZONE FUNCTIONS */ - /* */ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* */ - /* TT_Done_GlyphZone */ - /* */ - /* */ - /* Deallocates a glyph zone. */ - /* */ - /* */ - /* zone :: A pointer to the target glyph zone. */ - /* */ - LOCAL_FUNC - void TT_Done_GlyphZone( TT_GlyphZone* zone ) - { - FT_Memory memory = zone->memory; - - - FREE( zone->contours ); - FREE( zone->tags ); - FREE( zone->cur ); - FREE( zone->org ); - - zone->max_points = zone->n_points = 0; - zone->max_contours = zone->n_contours = 0; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_New_GlyphZone */ - /* */ - /* */ - /* Allocates a new glyph zone. */ - /* */ - /* */ - /* memory :: A handle to the current memory object. */ - /* */ - /* maxPoints :: The capacity of glyph zone in points. */ - /* */ - /* maxContours :: The capacity of glyph zone in contours. */ - /* */ - /* */ - /* zone :: A pointer to the target glyph zone record. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_New_GlyphZone( FT_Memory memory, - FT_UShort maxPoints, - FT_Short maxContours, - TT_GlyphZone* zone ) - { - FT_Error error; - - - if ( maxPoints > 0 ) - maxPoints += 2; - - MEM_Set( zone, 0, sizeof ( *zone ) ); - zone->memory = memory; - - if ( ALLOC_ARRAY( zone->org, maxPoints * 2, FT_F26Dot6 ) || - ALLOC_ARRAY( zone->cur, maxPoints * 2, FT_F26Dot6 ) || - ALLOC_ARRAY( zone->tags, maxPoints, FT_Byte ) || - ALLOC_ARRAY( zone->contours, maxContours, FT_UShort ) ) - { - TT_Done_GlyphZone( zone ); - } - - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Init_Face */ - /* */ - /* */ - /* Initializes a given TrueType face object. */ - /* */ - /* */ - /* stream :: The source font stream. */ - /* */ - /* face_index :: The index of the font face in the resource. */ - /* */ - /* num_params :: Number of additional generic parameters. Ignored. */ - /* */ - /* params :: Additional generic parameters. Ignored. */ - /* */ - /* */ - /* face :: The newly built face object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_DEF - FT_Error TT_Init_Face( FT_Stream stream, - TT_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ) - { - FT_Error error; - FT_Library library; - SFNT_Interface* sfnt; - - - library = face->root.driver->root.library; - sfnt = (SFNT_Interface*)FT_Get_Module_Interface( library, "sfnt" ); - if ( !sfnt ) - goto Bad_Format; - - /* create input stream from resource */ - if ( FILE_Seek( 0 ) ) - goto Exit; - - /* check that we have a valid TrueType file */ - error = sfnt->init_face( stream, face, face_index, num_params, params ); - if ( error ) - goto Exit; - - /* We must also be able to accept Mac/GX fonts, as well as OT ones */ - if ( face->format_tag != 0x00010000L && /* MS fonts */ - face->format_tag != TTAG_true ) /* Mac fonts */ - { - FT_TRACE2(( "[not a valid TTF font]\n" )); - goto Bad_Format; - } - - /* If we are performing a simple font format check, exit immediately */ - if ( face_index < 0 ) - return TT_Err_Ok; - - /* Load font directory */ - error = sfnt->load_face( stream, face, face_index, num_params, params ); - if ( error ) - goto Exit; - - error = TT_Load_Locations( face, stream ) || - TT_Load_CVT ( face, stream ) || - TT_Load_Programs ( face, stream ); - - /* initialize standard glyph loading routines */ - TT_Init_Glyph_Loading( face ); - - Exit: - return error; - - Bad_Format: - error = FT_Err_Unknown_File_Format; - goto Exit; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Done_Face */ - /* */ - /* */ - /* Finalizes a given face object. */ - /* */ - /* */ - /* face :: A pointer to the face object to destroy. */ - /* */ - LOCAL_DEF - void TT_Done_Face( TT_Face face ) - { - FT_Memory memory = face->root.memory; - FT_Stream stream = face->root.stream; - - SFNT_Interface* sfnt = (SFNT_Interface*)face->sfnt; - - - /* for `extended TrueType formats' (i.e. compressed versions) */ - if ( face->extra.finalizer ) - face->extra.finalizer( face->extra.data ); - - if ( sfnt ) - sfnt->done_face( face ); - - /* freeing the locations table */ - FREE( face->glyph_locations ); - face->num_locations = 0; - - /* freeing the CVT */ - FREE( face->cvt ); - face->cvt_size = 0; - - /* freeing the programs */ - RELEASE_Frame( face->font_program ); - RELEASE_Frame( face->cvt_program ); - face->font_program_size = 0; - face->cvt_program_size = 0; - } - - - /*************************************************************************/ - /* */ - /* SIZE FUNCTIONS */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Init_Size */ - /* */ - /* */ - /* Initializes a new TrueType size object. */ - /* */ - /* */ - /* size :: A handle to the size object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_DEF - FT_Error TT_Init_Size( TT_Size size ) - { - FT_Error error = TT_Err_Ok; - - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - TT_Face face = (TT_Face)size->root.face; - FT_Memory memory = face->root.memory; - FT_Int i; - - TT_ExecContext exec; - FT_UShort n_twilight; - TT_MaxProfile* maxp = &face->max_profile; - - - size->ttmetrics.valid = FALSE; - - size->max_function_defs = maxp->maxFunctionDefs; - size->max_instruction_defs = maxp->maxInstructionDefs; - - size->num_function_defs = 0; - size->num_instruction_defs = 0; - - size->max_func = 0; - size->max_ins = 0; - - size->cvt_size = face->cvt_size; - size->storage_size = maxp->maxStorage; - - /* Set default metrics */ - { - FT_Size_Metrics* metrics = &size->root.metrics; - TT_Size_Metrics* metrics2 = &size->ttmetrics; - - - metrics->x_ppem = 0; - metrics->y_ppem = 0; - - metrics2->rotated = FALSE; - metrics2->stretched = FALSE; - - /* set default compensation (all 0) */ - for ( i = 0; i < 4; i++ ) - metrics2->compensations[i] = 0; - } - - /* allocate function defs, instruction defs, cvt, and storage area */ - if ( ALLOC_ARRAY( size->function_defs, - size->max_function_defs, - TT_DefRecord ) || - - ALLOC_ARRAY( size->instruction_defs, - size->max_instruction_defs, - TT_DefRecord ) || - - ALLOC_ARRAY( size->cvt, - size->cvt_size, FT_Long ) || - - ALLOC_ARRAY( size->storage, - size->storage_size, FT_Long ) ) - - goto Fail_Memory; - - /* reserve twilight zone */ - n_twilight = maxp->maxTwilightPoints; - error = TT_New_GlyphZone( memory, n_twilight, 0, &size->twilight ); - if ( error ) - goto Fail_Memory; - - size->twilight.n_points = n_twilight; - - /* set `face->interpreter' according to the debug hook present */ - { - FT_Library library = face->root.driver->root.library; - - - face->interpreter = (TT_Interpreter) - library->debug_hooks[FT_DEBUG_HOOK_TRUETYPE]; - if ( !face->interpreter ) - face->interpreter = (TT_Interpreter)TT_RunIns; - } - - /* Fine, now execute the font program! */ - exec = size->context; - /* size objects used during debugging have their own context */ - if ( !size->debug ) - exec = TT_New_Context( face ); - - if ( !exec ) - { - error = TT_Err_Could_Not_Find_Context; - goto Fail_Memory; - } - - size->GS = tt_default_graphics_state; - TT_Load_Context( exec, face, size ); - - exec->callTop = 0; - exec->top = 0; - - exec->period = 64; - exec->phase = 0; - exec->threshold = 0; - - { - FT_Size_Metrics* metrics = &exec->metrics; - TT_Size_Metrics* tt_metrics = &exec->tt_metrics; - - - metrics->x_ppem = 0; - metrics->y_ppem = 0; - metrics->x_scale = 0; - metrics->y_scale = 0; - - tt_metrics->ppem = 0; - tt_metrics->scale = 0; - tt_metrics->ratio = 0x10000L; - } - - exec->instruction_trap = FALSE; - - exec->cvtSize = size->cvt_size; - exec->cvt = size->cvt; - - exec->F_dot_P = 0x10000L; - - /* allow font program execution */ - TT_Set_CodeRange( exec, - tt_coderange_font, - face->font_program, - face->font_program_size ); - - /* disable CVT and glyph programs coderange */ - TT_Clear_CodeRange( exec, tt_coderange_cvt ); - TT_Clear_CodeRange( exec, tt_coderange_glyph ); - - if ( face->font_program_size > 0 ) - { - error = TT_Goto_CodeRange( exec, tt_coderange_font, 0 ); - if ( !error ) - error = face->interpreter( exec ); - - if ( error ) - goto Fail_Exec; - } - else - error = TT_Err_Ok; - - TT_Save_Context( exec, size ); - - if ( !size->debug ) - TT_Done_Context( exec ); - -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ - - size->ttmetrics.valid = FALSE; - return error; - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - Fail_Exec: - if ( !size->debug ) - TT_Done_Context( exec ); - - Fail_Memory: - -#endif - - TT_Done_Size( size ); - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Done_Size */ - /* */ - /* */ - /* The TrueType size object finalizer. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - LOCAL_FUNC - void TT_Done_Size( TT_Size size ) - { - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - FT_Memory memory = size->root.face->memory; - - - if ( size->debug ) - { - /* the debug context must be deleted by the debugger itself */ - size->context = NULL; - size->debug = FALSE; - } - - FREE( size->cvt ); - size->cvt_size = 0; - - /* free storage area */ - FREE( size->storage ); - size->storage_size = 0; - - /* twilight zone */ - TT_Done_GlyphZone( &size->twilight ); - - FREE( size->function_defs ); - FREE( size->instruction_defs ); - - size->num_function_defs = 0; - size->max_function_defs = 0; - size->num_instruction_defs = 0; - size->max_instruction_defs = 0; - - size->max_func = 0; - size->max_ins = 0; - -#endif - - size->ttmetrics.valid = FALSE; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Reset_Size */ - /* */ - /* */ - /* Resets a TrueType size when resolutions and character dimensions */ - /* have been changed. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - LOCAL_DEF - FT_Error TT_Reset_Size( TT_Size size ) - { - TT_Face face; - FT_Error error = TT_Err_Ok; - - FT_Size_Metrics* metrics; - - - if ( size->ttmetrics.valid ) - return TT_Err_Ok; - - face = (TT_Face)size->root.face; - - metrics = &size->root.metrics; - - if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 ) - return TT_Err_Invalid_PPem; - - /* compute new transformation */ - if ( metrics->x_ppem >= metrics->y_ppem ) - { - size->ttmetrics.scale = metrics->x_scale; - size->ttmetrics.ppem = metrics->x_ppem; - size->ttmetrics.x_ratio = 0x10000L; - size->ttmetrics.y_ratio = FT_MulDiv( metrics->y_ppem, - 0x10000L, - metrics->x_ppem ); - } - else - { - size->ttmetrics.scale = metrics->y_scale; - size->ttmetrics.ppem = metrics->y_ppem; - size->ttmetrics.x_ratio = FT_MulDiv( metrics->x_ppem, - 0x10000L, - metrics->y_ppem ); - size->ttmetrics.y_ratio = 0x10000L; - } - - /* Compute root ascender, descender, test height, and max_advance */ - metrics->ascender = ( FT_MulFix( face->root.ascender, - metrics->y_scale ) + 32 ) & -64; - metrics->descender = ( FT_MulFix( face->root.descender, - metrics->y_scale ) + 32 ) & -64; - metrics->height = ( FT_MulFix( face->root.height, - metrics->y_scale ) + 32 ) & -64; - metrics->max_advance = ( FT_MulFix( face->root.max_advance_width, - metrics->x_scale ) + 32 ) & -64; - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - { - TT_ExecContext exec; - FT_UInt i, j; - - - /* Scale the cvt values to the new ppem. */ - /* We use by default the y ppem to scale the CVT. */ - for ( i = 0; i < size->cvt_size; i++ ) - size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale ); - - /* All twilight points are originally zero */ - for ( j = 0; j < size->twilight.n_points; j++ ) - { - size->twilight.org[j].x = 0; - size->twilight.org[j].y = 0; - size->twilight.cur[j].x = 0; - size->twilight.cur[j].y = 0; - } - - /* clear storage area */ - for ( i = 0; i < size->storage_size; i++ ) - size->storage[i] = 0; - - size->GS = tt_default_graphics_state; - - /* get execution context and run prep program */ - if ( size->debug ) - exec = size->context; - else - exec = TT_New_Context( face ); - /* debugging instances have their own context */ - - if ( !exec ) - return TT_Err_Could_Not_Find_Context; - - TT_Load_Context( exec, face, size ); - - TT_Set_CodeRange( exec, - tt_coderange_cvt, - face->cvt_program, - face->cvt_program_size ); - - TT_Clear_CodeRange( exec, tt_coderange_glyph ); - - exec->instruction_trap = FALSE; - - exec->top = 0; - exec->callTop = 0; - - if ( face->cvt_program_size > 0 ) - { - error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 ); - if ( error ) - goto End; - - if ( !size->debug ) - error = face->interpreter( exec ); - } - else - error = TT_Err_Ok; - - size->GS = exec->GS; - /* save default graphics state */ - - End: - TT_Save_Context( exec, size ); - - if ( !size->debug ) - TT_Done_Context( exec ); - /* debugging instances keep their context */ - } - -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ - - if ( !error ) - size->ttmetrics.valid = TRUE; - - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Init_Driver */ - /* */ - /* */ - /* Initializes a given TrueType driver object. */ - /* */ - /* */ - /* driver :: A handle to the target driver object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Init_Driver( TT_Driver driver ) - { - FT_Error error; - - - /* set `extra' in glyph loader */ - error = FT_GlyphLoader_Create_Extra( FT_DRIVER( driver )->glyph_loader ); - - /* init extension registry if needed */ - -#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE - if ( !error ) - return TT_Init_Extensions( driver ); -#endif - - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Done_Driver */ - /* */ - /* */ - /* Finalizes a given TrueType driver. */ - /* */ - /* */ - /* driver :: A handle to the target TrueType driver. */ - /* */ - LOCAL_FUNC - void TT_Done_Driver( TT_Driver driver ) - { - /* destroy extensions registry if needed */ - -#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE - - TT_Done_Extensions( driver ); - -#endif - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - /* destroy the execution context */ - if ( driver->context ) - { - TT_Destroy_Context( driver->context, driver->root.root.memory ); - driver->context = NULL; - } - -#endif - - } - - -/* END */ diff --git a/src/freetype/truetype/ttobjs.h b/src/freetype/truetype/ttobjs.h deleted file mode 100644 index 3e55de3cb1..0000000000 --- a/src/freetype/truetype/ttobjs.h +++ /dev/null @@ -1,412 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttobjs.h */ -/* */ -/* Objects manager (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifndef TTOBJS_H -#define TTOBJS_H - - -#include -#include -#include - - -#ifdef __cplusplus - extern "C" { -#endif - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Driver */ - /* */ - /* */ - /* A handle to a TrueType driver object. */ - /* */ - typedef struct TT_DriverRec_* TT_Driver; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Instance */ - /* */ - /* */ - /* A handle to a TrueType size object. */ - /* */ - typedef struct TT_SizeRec_* TT_Size; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_GlyphSlot */ - /* */ - /* */ - /* A handle to a TrueType glyph slot object. */ - /* */ - /* */ - /* This is a direct typedef of FT_GlyphSlot, as there is nothing */ - /* specific about the TrueType glyph slot. */ - /* */ - typedef FT_GlyphSlot TT_GlyphSlot; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_GraphicsState */ - /* */ - /* */ - /* The TrueType graphics state used during bytecode interpretation. */ - /* */ - typedef struct TT_GraphicsState_ - { - FT_UShort rp0; - FT_UShort rp1; - FT_UShort rp2; - - FT_UnitVector dualVector; - FT_UnitVector projVector; - FT_UnitVector freeVector; - - FT_Long loop; - FT_F26Dot6 minimum_distance; - FT_Int round_state; - - FT_Bool auto_flip; - FT_F26Dot6 control_value_cutin; - FT_F26Dot6 single_width_cutin; - FT_F26Dot6 single_width_value; - FT_Short delta_base; - FT_Short delta_shift; - - FT_Byte instruct_control; - FT_Bool scan_control; - FT_Int scan_type; - - FT_UShort gep0; - FT_UShort gep1; - FT_UShort gep2; - - } TT_GraphicsState; - - - LOCAL_DEF void TT_Done_GlyphZone( TT_GlyphZone* zone ); - - LOCAL_DEF FT_Error TT_New_GlyphZone( FT_Memory memory, - FT_UShort maxPoints, - FT_Short maxContours, - TT_GlyphZone* zone ); - - - /*************************************************************************/ - /* */ - /* EXECUTION SUBTABLES */ - /* */ - /* These sub-tables relate to instruction execution. */ - /* */ - /*************************************************************************/ - - -#define TT_MAX_CODE_RANGES 3 - - - /*************************************************************************/ - /* */ - /* There can only be 3 active code ranges at once: */ - /* - the Font Program */ - /* - the CVT Program */ - /* - a glyph's instructions set */ - /* */ - typedef enum TT_CodeRange_Tag_ - { - tt_coderange_none = 0, - tt_coderange_font, - tt_coderange_cvt, - tt_coderange_glyph - - } TT_CodeRange_Tag; - - - typedef struct TT_CodeRange_ - { - FT_Byte* base; - FT_ULong size; - - } TT_CodeRange; - - typedef TT_CodeRange TT_CodeRangeTable[TT_MAX_CODE_RANGES]; - - - /*************************************************************************/ - /* */ - /* Defines a function/instruction definition record. */ - /* */ - typedef struct TT_DefRecord_ - { - FT_Int range; /* in which code range is it located? */ - FT_Long start; /* where does it start? */ - FT_UInt opc; /* function #, or instruction code */ - FT_Bool active; /* is it active? */ - - } TT_DefRecord, *TT_DefArray; - - - /*************************************************************************/ - /* */ - /* Subglyph transformation record. */ - /* */ - typedef struct TT_Transform_ - { - FT_Fixed xx, xy; /* transformation matrix coefficients */ - FT_Fixed yx, yy; - FT_F26Dot6 ox, oy; /* offsets */ - - } TT_Transform; - - - /*************************************************************************/ - /* */ - /* Subglyph loading record. Used to load composite components. */ - /* */ - typedef struct TT_SubglyphRec_ - { - FT_Long index; /* subglyph index; initialized with -1 */ - FT_Bool is_scaled; /* is the subglyph scaled? */ - FT_Bool is_hinted; /* should it be hinted? */ - FT_Bool preserve_pps; /* preserve phantom points? */ - - FT_Long file_offset; - - FT_BBox bbox; - FT_Pos left_bearing; - FT_Pos advance; - - TT_GlyphZone zone; - - FT_Long arg1; /* first argument */ - FT_Long arg2; /* second argument */ - - FT_UShort element_flag; /* current load element flag */ - - TT_Transform transform; /* transformation matrix */ - - FT_Vector pp1, pp2; /* phantom points */ - - } TT_SubGlyphRec, *TT_SubGlyph_Stack; - - - /*************************************************************************/ - /* */ - /* A note regarding non-squared pixels: */ - /* */ - /* (This text will probably go into some docs at some time; for now, it */ - /* is kept here to explain some definitions in the TIns_Metrics */ - /* record). */ - /* */ - /* The CVT is a one-dimensional array containing values that control */ - /* certain important characteristics in a font, like the height of all */ - /* capitals, all lowercase letter, default spacing or stem width/height. */ - /* */ - /* These values are found in FUnits in the font file, and must be scaled */ - /* to pixel coordinates before being used by the CVT and glyph programs. */ - /* Unfortunately, when using distinct x and y resolutions (or distinct x */ - /* and y pointsizes), there are two possible scalings. */ - /* */ - /* A first try was to implement a `lazy' scheme where all values were */ - /* scaled when first used. However, while some values are always used */ - /* in the same direction, some others are used under many different */ - /* circumstances and orientations. */ - /* */ - /* I have found a simpler way to do the same, and it even seems to work */ - /* in most of the cases: */ - /* */ - /* - All CVT values are scaled to the maximum ppem size. */ - /* */ - /* - When performing a read or write in the CVT, a ratio factor is used */ - /* to perform adequate scaling. Example: */ - /* */ - /* x_ppem = 14 */ - /* y_ppem = 10 */ - /* */ - /* We choose ppem = x_ppem = 14 as the CVT scaling size. All cvt */ - /* entries are scaled to it. */ - /* */ - /* x_ratio = 1.0 */ - /* y_ratio = y_ppem/ppem (< 1.0) */ - /* */ - /* We compute the current ratio like: */ - /* */ - /* - If projVector is horizontal, */ - /* ratio = x_ratio = 1.0 */ - /* */ - /* - if projVector is vertical, */ - /* ratio = y_ratio */ - /* */ - /* - else, */ - /* ratio = sqrt( (proj.x * x_ratio) ^ 2 + (proj.y * y_ratio) ^ 2 ) */ - /* */ - /* Reading a cvt value returns */ - /* ratio * cvt[index] */ - /* */ - /* Writing a cvt value in pixels: */ - /* cvt[index] / ratio */ - /* */ - /* The current ppem is simply */ - /* ratio * ppem */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* Metrics used by the TrueType size and context objects. */ - /* */ - typedef struct TT_Size_Metrics_ - { - /* for non-square pixels */ - FT_Long x_ratio; - FT_Long y_ratio; - - FT_UShort ppem; /* maximum ppem size */ - FT_Long ratio; /* current ratio */ - FT_Fixed scale; - - FT_F26Dot6 compensations[4]; /* device-specific compensations */ - - FT_Bool valid; - - FT_Bool rotated; /* `is the glyph rotated?'-flag */ - FT_Bool stretched; /* `is the glyph stretched?'-flag */ - - } TT_Size_Metrics; - - - /*************************************************************************/ - /* */ - /* TrueType size class. */ - /* */ - typedef struct TT_SizeRec_ - { - FT_SizeRec root; - - TT_Size_Metrics ttmetrics; - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - FT_UInt num_function_defs; /* number of function definitions */ - FT_UInt max_function_defs; - TT_DefArray function_defs; /* table of function definitions */ - - FT_UInt num_instruction_defs; /* number of ins. definitions */ - FT_UInt max_instruction_defs; - TT_DefArray instruction_defs; /* table of ins. definitions */ - - FT_UInt max_func; - FT_UInt max_ins; - - TT_CodeRangeTable codeRangeTable; - - TT_GraphicsState GS; - - FT_ULong cvt_size; /* the scaled control value table */ - FT_Long* cvt; - - FT_UShort storage_size; /* The storage area is now part of */ - FT_Long* storage; /* the instance */ - - TT_GlyphZone twilight; /* The instance's twilight zone */ - - /* debugging variables */ - - /* When using the debugger, we must keep the */ - /* execution context tied to the instance */ - /* object rather than asking it on demand. */ - - FT_Bool debug; - TT_ExecContext context; - -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ - - } TT_SizeRec; - - - /*************************************************************************/ - /* */ - /* TrueType driver class. */ - /* */ - typedef struct TT_DriverRec_ - { - FT_DriverRec root; - TT_ExecContext context; /* execution context */ - TT_GlyphZone zone; /* glyph loader points zone */ - - void* extension_component; - - } TT_DriverRec; - - - /*************************************************************************/ - /* */ - /* Face functions */ - /* */ - LOCAL_DEF - FT_Error TT_Init_Face( FT_Stream stream, - TT_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ); - - LOCAL_DEF - void TT_Done_Face( TT_Face face ); - - - /*************************************************************************/ - /* */ - /* Size functions */ - /* */ - LOCAL_DEF - FT_Error TT_Init_Size( TT_Size size ); - - LOCAL_DEF - void TT_Done_Size( TT_Size size ); - - LOCAL_DEF - FT_Error TT_Reset_Size( TT_Size size ); - - - /*************************************************************************/ - /* */ - /* Driver functions */ - /* */ - LOCAL_DEF - FT_Error TT_Init_Driver( TT_Driver driver ); - - LOCAL_DEF - void TT_Done_Driver( TT_Driver driver ); - - -#ifdef __cplusplus - } -#endif - -#endif /* TTOBJS_H */ - - -/* END */ diff --git a/src/freetype/truetype/ttpload.c b/src/freetype/truetype/ttpload.c deleted file mode 100644 index d82dd45bea..0000000000 --- a/src/freetype/truetype/ttpload.c +++ /dev/null @@ -1,273 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttpload.h */ -/* */ -/* TrueType glyph data/program tables loader (body). */ -/* */ -/* 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 -#include -#include -#include - -#ifdef FT_FLAT_COMPILE -#include "ttpload.h" -#else -#include -#endif - -#include - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_ttpload - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Locations */ - /* */ - /* */ - /* Loads the locations table. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* */ - /* stream :: The input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_Locations( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - FT_Memory memory = stream->memory; - FT_Short LongOffsets; - FT_ULong table_len; - - - FT_TRACE2(( "Locations " )); - LongOffsets = face->header.Index_To_Loc_Format; - - error = face->goto_table( face, TTAG_loca, stream, &table_len ); - if ( error ) - { - error = TT_Err_Locations_Missing; - goto Exit; - } - - if ( LongOffsets != 0 ) - { - face->num_locations = (FT_UShort)( table_len >> 2 ); - - FT_TRACE2(( "(32bit offsets): %12d ", face->num_locations )); - - if ( ALLOC_ARRAY( face->glyph_locations, - face->num_locations, - FT_Long ) ) - goto Exit; - - if ( ACCESS_Frame( face->num_locations * 4L ) ) - goto Exit; - - { - FT_Long* loc = face->glyph_locations; - FT_Long* limit = loc + face->num_locations; - - - for ( ; loc < limit; loc++ ) - *loc = GET_Long(); - } - - FORGET_Frame(); - } - else - { - face->num_locations = (FT_UShort)( table_len >> 1 ); - - FT_TRACE2(( "(16bit offsets): %12d ", face->num_locations )); - - if ( ALLOC_ARRAY( face->glyph_locations, - face->num_locations, - FT_Long ) ) - goto Exit; - - if ( ACCESS_Frame( face->num_locations * 2L ) ) - goto Exit; - { - FT_Long* loc = face->glyph_locations; - FT_Long* limit = loc + face->num_locations; - - - for ( ; loc < limit; loc++ ) - *loc = (FT_Long)( (FT_ULong)GET_UShort() * 2 ); - } - FORGET_Frame(); - } - - FT_TRACE2(( "loaded\n" )); - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_CVT */ - /* */ - /* */ - /* Loads the control value table into a face object. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* */ - /* stream :: A handle to the input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_CVT( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - FT_Memory memory = stream->memory; - FT_ULong table_len; - - - FT_TRACE2(( "CVT " )); - - error = face->goto_table( face, TTAG_cvt, stream, &table_len ); - if ( error ) - { - FT_TRACE2(( "is missing!\n" )); - - face->cvt_size = 0; - face->cvt = NULL; - error = TT_Err_Ok; - - goto Exit; - } - - face->cvt_size = table_len / 2; - - if ( ALLOC_ARRAY( face->cvt, - face->cvt_size, - FT_Short ) ) - goto Exit; - - if ( ACCESS_Frame( face->cvt_size * 2L ) ) - goto Exit; - - { - FT_Short* cur = face->cvt; - FT_Short* limit = cur + face->cvt_size; - - - for ( ; cur < limit; cur++ ) - *cur = GET_Short(); - } - - FORGET_Frame(); - FT_TRACE2(( "loaded\n" )); - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Progams */ - /* */ - /* */ - /* Loads the font program and the cvt program. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* */ - /* stream :: A handle to the input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_Programs( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - FT_ULong table_len; - - - FT_TRACE2(( "Font program " )); - - /* The font program is optional */ - error = face->goto_table( face, TTAG_fpgm, stream, &table_len ); - if ( error ) - { - face->font_program = NULL; - face->font_program_size = 0; - - FT_TRACE2(( "is missing!\n" )); - } - else - { - face->font_program_size = table_len; - if ( EXTRACT_Frame( table_len, face->font_program ) ) - goto Exit; - - FT_TRACE2(( "loaded, %12d bytes\n", face->font_program_size )); - } - - FT_TRACE2(( "Prep program " )); - - error = face->goto_table( face, TTAG_prep, stream, &table_len ); - if ( error ) - { - face->cvt_program = NULL; - face->cvt_program_size = 0; - error = TT_Err_Ok; - - FT_TRACE2(( "is missing!\n" )); - } - else - { - face->cvt_program_size = table_len; - if ( EXTRACT_Frame( table_len, face->cvt_program ) ) - goto Exit; - - FT_TRACE2(( "loaded, %12d bytes\n", face->cvt_program_size )); - } - - Exit: - return error; - } - - -/* END */ diff --git a/src/freetype/truetype/ttpload.h b/src/freetype/truetype/ttpload.h deleted file mode 100644 index 77802a6424..0000000000 --- a/src/freetype/truetype/ttpload.h +++ /dev/null @@ -1,51 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttpload.h */ -/* */ -/* TrueType glyph data/program tables loader (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifndef TTPLOAD_H -#define TTPLOAD_H - -#include - - -#ifdef __cplusplus - extern "C" { -#endif - - - LOCAL_DEF - FT_Error TT_Load_Locations( TT_Face face, - FT_Stream stream ); - - LOCAL_DEF - FT_Error TT_Load_CVT( TT_Face face, - FT_Stream stream ); - - LOCAL_DEF - FT_Error TT_Load_Programs( TT_Face face, - FT_Stream stream ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* TTPLOAD_H */ - - -/* END */ diff --git a/src/freetype/type1/module.mk0 b/src/freetype/type1/module.mk0 deleted file mode 100644 index af99eae25f..0000000000 --- a/src/freetype/type1/module.mk0 +++ /dev/null @@ -1,6 +0,0 @@ -make_module_list: add_type1_driver - -add_type1_driver: - $(OPEN_DRIVER)t1_driver_class$(CLOSE_DRIVER) - $(ECHO_DRIVER)type1 $(ECHO_DRIVER_DESC)Postscript font files with extension *.pfa or *.pfb$(ECHO_DRIVER_DONE) - diff --git a/src/freetype/type1/rules.mk0 b/src/freetype/type1/rules.mk0 deleted file mode 100644 index b544446ae6..0000000000 --- a/src/freetype/type1/rules.mk0 +++ /dev/null @@ -1,74 +0,0 @@ -# -# FreeType 2 Type 1 driver configuration rules -# - - -# 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. - - -# Type1 driver directory -# -T1_DIR := $(SRC_)type1 -T1_DIR_ := $(T1_DIR)$(SEP) - - -# compilation flags for the driver -# -T1_COMPILE := $(FT_COMPILE) - - -# Type1 driver sources (i.e., C files) -# -T1_DRV_SRC := $(T1_DIR_)t1objs.c \ - $(T1_DIR_)t1load.c \ - $(T1_DIR_)t1parse.c \ - $(T1_DIR_)t1tokens.c \ - $(T1_DIR_)t1driver.c \ - $(T1_DIR_)t1hinter.c \ - $(T1_DIR_)t1afm.c \ - $(T1_DIR_)t1gload.c - -# Type1 driver headers -# -T1_DRV_H := $(T1_DRV_SRC:%.c=%.h) - - -# Type1 driver object(s) -# -# T1_DRV_OBJ_M is used during `multi' builds -# T1_DRV_OBJ_S is used during `single' builds -# -T1_DRV_OBJ_M := $(T1_DRV_SRC:$(T1_DIR_)%.c=$(OBJ_)%.$O) -T1_DRV_OBJ_S := $(OBJ_)type1.$O - -# Type1 driver source file for single build -# -T1_DRV_SRC_S := $(T1_DIR_)type1.c - - -# Type1 driver - single object -# -$(T1_DRV_OBJ_S): $(T1_DRV_SRC_S) $(T1_DRV_SRC) $(FREETYPE_H) $(T1_DRV_H) - $(T1_COMPILE) $T$@ $(T1_DRV_SRC_S) - - -# Type1 driver - multiple objects -# -$(OBJ_)%.$O: $(T1_DIR_)%.c $(FREETYPE_H) $(T1_DRV_H) - $(T1_COMPILE) $T$@ $< - - -# update main driver object lists -# -DRV_OBJS_S += $(T1_DRV_OBJ_S) -DRV_OBJS_M += $(T1_DRV_OBJ_M) - - -# EOF diff --git a/src/freetype/type1/t1afm.c b/src/freetype/type1/t1afm.c deleted file mode 100644 index a6ac1b98a6..0000000000 --- a/src/freetype/type1/t1afm.c +++ /dev/null @@ -1,293 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1afm.c */ -/* */ -/* AFM support for Type 1 fonts (body). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifdef FT_FLAT_COMPILE - -#include "t1afm.h" - -#else - -#include - -#endif - - -#include -#include - -#include /* for qsort() */ -#include /* for strcmp() */ -#include /* for isalnum() */ - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_t1afm - - - LOCAL_FUNC - void T1_Done_AFM( FT_Memory memory, - T1_AFM* afm ) - { - FREE( afm->kern_pairs ); - afm->num_pairs = 0; - } - - -#undef IS_KERN_PAIR -#define IS_KERN_PAIR( p ) ( p[0] == 'K' && p[1] == 'P' ) - -#define IS_ALPHANUM( c ) ( isalnum( c ) || \ - c == '_' || \ - c == '.' ) - - - /* read a glyph name and return the equivalent glyph index */ - static - FT_UInt afm_atoindex( FT_Byte** start, - FT_Byte* limit, - T1_Font* type1 ) - { - FT_Byte* p = *start; - FT_Int len; - FT_UInt result = 0; - char temp[64]; - - - /* skip whitespace */ - while ( ( *p == ' ' || *p == '\t' || *p == ':' || *p == ';' ) && - p < limit ) - p++; - *start = p; - - /* now, read glyph name */ - while ( IS_ALPHANUM( *p ) && p < limit ) - p++; - - len = p - *start; - - if ( len > 0 && len < 64 ) - { - FT_Int n; - - - /* copy glyph name to intermediate array */ - MEM_Copy( temp, *start, len ); - temp[len] = 0; - - /* lookup glyph name in face array */ - for ( n = 0; n < type1->num_glyphs; n++ ) - { - char* gname = (char*)type1->glyph_names[n]; - - - if ( gname && gname[0] == temp[0] && strcmp( gname, temp ) == 0 ) - { - result = n; - break; - } - } - } - *start = p; - return result; - } - - - /* read an integer */ - static - int afm_atoi( FT_Byte** start, - FT_Byte* limit ) - { - FT_Byte* p = *start; - int sum = 0; - int sign = 1; - - - /* skip everything that is not a number */ - while ( p < limit && !isdigit( *p ) ) - { - sign = 1; - if ( *p == '-' ) - sign = -1; - - p++; - } - - while ( p < limit && isdigit( *p ) ) - { - sum = sum * 10 + ( *p - '0' ); - p++; - } - *start = p; - - return sum * sign; - } - - -#undef KERN_INDEX -#define KERN_INDEX( g1, g2 ) ( ( (FT_ULong)g1 << 16 ) | g2 ) - - - /* compare two kerning pairs */ - static - int compare_kern_pairs( const void* a, - const void* b ) - { - T1_Kern_Pair* pair1 = (T1_Kern_Pair*)a; - T1_Kern_Pair* pair2 = (T1_Kern_Pair*)b; - - FT_ULong index1 = KERN_INDEX( pair1->glyph1, pair1->glyph2 ); - FT_ULong index2 = KERN_INDEX( pair2->glyph1, pair2->glyph2 ); - - - return ( index1 - index2 ); - } - - - /* parse an AFM file -- for now, only read the kerning pairs */ - LOCAL_FUNC - FT_Error T1_Read_AFM( FT_Face t1_face, - FT_Stream stream ) - { - FT_Error error; - FT_Memory memory = stream->memory; - FT_Byte* start; - FT_Byte* limit; - FT_Byte* p; - FT_Int count = 0; - T1_Kern_Pair* pair; - T1_Font* type1 = &((T1_Face)t1_face)->type1; - T1_AFM* afm = 0; - - - if ( ACCESS_Frame( stream->size ) ) - return error; - - start = (FT_Byte*)stream->cursor; - limit = (FT_Byte*)stream->limit; - p = start; - - /* we are now going to count the occurences of `KP' or `KPX' in */ - /* the AFM file */ - count = 0; - for ( p = start; p < limit - 3; p++ ) - { - if ( IS_KERN_PAIR( p ) ) - count++; - } - - /* Actually, kerning pairs are simply optional! */ - if ( count == 0 ) - goto Exit; - - /* allocate the pairs */ - if ( ALLOC( afm, sizeof ( *afm ) ) || - ALLOC_ARRAY( afm->kern_pairs, count, T1_Kern_Pair ) ) - goto Exit; - - /* now, read each kern pair */ - pair = afm->kern_pairs; - afm->num_pairs = count; - - /* save in face object */ - ((T1_Face)t1_face)->afm_data = afm; - - for ( p = start; p < limit - 3; p++ ) - { - if ( IS_KERN_PAIR( p ) ) - { - FT_Byte* q; - - - /* skip keyword (KP or KPX) */ - q = p + 2; - if ( *q == 'X' ) - q++; - - pair->glyph1 = afm_atoindex( &q, limit, type1 ); - pair->glyph2 = afm_atoindex( &q, limit, type1 ); - pair->kerning.x = afm_atoi( &q, limit ); - - pair->kerning.y = 0; - if ( p[2] != 'X' ) - pair->kerning.y = afm_atoi( &q, limit ); - - pair++; - } - } - - /* now, sort the kern pairs according to their glyph indices */ - qsort( afm->kern_pairs, count, sizeof ( T1_Kern_Pair ), - compare_kern_pairs ); - - Exit: - if ( error ) - FREE( afm ); - - FORGET_Frame(); - - return error; - } - - - /* find the kerning for a given glyph pair */ - LOCAL_FUNC - void T1_Get_Kerning( T1_AFM* afm, - FT_UInt glyph1, - FT_UInt glyph2, - FT_Vector* kerning ) - { - T1_Kern_Pair *min, *mid, *max; - FT_ULong index = KERN_INDEX( glyph1, glyph2 ); - - - /* simple binary search */ - min = afm->kern_pairs; - max = min + afm->num_pairs - 1; - - while ( min <= max ) - { - FT_ULong midi; - - - mid = min + ( max - min ) / 2; - midi = KERN_INDEX( mid->glyph1, mid->glyph2 ); - - if ( midi == index ) - { - *kerning = mid->kerning; - return; - } - - if ( midi < index ) - min = mid + 1; - else - max = mid - 1; - } - - kerning->x = 0; - kerning->y = 0; - } - - -/* END */ diff --git a/src/freetype/type1/t1afm.h b/src/freetype/type1/t1afm.h deleted file mode 100644 index 709154ec7b..0000000000 --- a/src/freetype/type1/t1afm.h +++ /dev/null @@ -1,70 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1afm.h */ -/* */ -/* AFM support for Type 1 fonts (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifndef T1AFM_H -#define T1AFM_H - -#include - - -#ifdef __cplusplus - extern "C" { -#endif - - - typedef struct T1_Kern_Pair_ - { - FT_UInt glyph1; - FT_UInt glyph2; - FT_Vector kerning; - - } T1_Kern_Pair; - - - typedef struct T1_AFM_ - { - FT_Int num_pairs; - T1_Kern_Pair* kern_pairs; - - } T1_AFM; - - - LOCAL_DEF - FT_Error T1_Read_AFM( FT_Face face, - FT_Stream stream ); - - LOCAL_DEF - void T1_Done_AFM( FT_Memory memory, - T1_AFM* afm ); - - LOCAL_DEF - void T1_Get_Kerning( T1_AFM* afm, - FT_UInt glyph1, - FT_UInt glyph2, - FT_Vector* kerning ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* T1AFM_H */ - - -/* END */ diff --git a/src/freetype/type1/t1driver.c b/src/freetype/type1/t1driver.c deleted file mode 100644 index 49b5a56374..0000000000 --- a/src/freetype/type1/t1driver.c +++ /dev/null @@ -1,381 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1driver.c */ -/* */ -/* Type 1 driver interface (body). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifdef FT_FLAT_COMPILE - -#include "t1driver.h" -#include "t1gload.h" -#include "t1afm.h" - -#else - -#include -#include -#include - -#endif - - -#include -#include -#include - -#include /* for strcmp() */ - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_t1driver - - -#ifndef T1_CONFIG_OPTION_NO_AFM - - - /*************************************************************************/ - /* */ - /* */ - /* Get_Kerning */ - /* */ - /* */ - /* A driver method used to return the kerning vector between two */ - /* glyphs of the same face. */ - /* */ - /* */ - /* face :: A handle to the source face object. */ - /* */ - /* left_glyph :: The index of the left glyph in the kern pair. */ - /* */ - /* right_glyph :: The index of the right glyph in the kern pair. */ - /* */ - /* */ - /* kerning :: The kerning vector. This is in font units for */ - /* scalable formats, and in pixels for fixed-sizes */ - /* formats. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Only horizontal layouts (left-to-right & right-to-left) are */ - /* supported by this function. Other layouts, or more sophisticated */ - /* kernings are out of scope of this method (the basic driver */ - /* interface is meant to be simple). */ - /* */ - /* They can be implemented by format-specific interfaces. */ - /* */ - static - FT_Error Get_Kerning( T1_Face face, - FT_UInt left_glyph, - FT_UInt right_glyph, - FT_Vector* kerning ) - { - T1_AFM* afm; - - - kerning->x = 0; - kerning->y = 0; - - afm = (T1_AFM*)face->afm_data; - if ( afm ) - T1_Get_Kerning( afm, left_glyph, right_glyph, kerning ); - - return T1_Err_Ok; - } - - -#endif /* T1_CONFIG_OPTION_NO_AFM */ - - - static - FT_Error get_t1_glyph_name( T1_Face face, - FT_UInt glyph_index, - FT_Pointer buffer, - FT_UInt buffer_max ) - { - FT_String* gname; - - - gname = face->type1.glyph_names[glyph_index]; - - if ( buffer_max > 0 ) - { - FT_UInt len = strlen( gname ); - - - if ( len >= buffer_max ) - len = buffer_max - 1; - - MEM_Copy( buffer, gname, len ); - ((FT_Byte*)buffer)[len] = 0; - } - - return T1_Err_Ok; - } - - - static - FT_Module_Interface T1_Get_Interface( FT_Module module, - const char* interface ) - { - FT_UNUSED( module ); - - if ( strcmp( interface, "glyph_name" ) == 0 ) - return (FT_Module_Interface)get_t1_glyph_name; - - return 0; - } - - - - /*************************************************************************/ - /* */ - /* */ - /* Set_Char_Sizes */ - /* */ - /* */ - /* A driver method used to reset a size's character sizes (horizontal */ - /* and vertical) expressed in fractional points. */ - /* */ - /* */ - /* char_width :: The character width expressed in 26.6 */ - /* fractional points. */ - /* */ - /* char_height :: The character height expressed in 26.6 */ - /* fractional points. */ - /* */ - /* horz_resolution :: The horizontal resolution of the output device. */ - /* */ - /* vert_resolution :: The vertical resolution of the output device. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error Set_Char_Sizes( T1_Size size, - FT_F26Dot6 char_width, - FT_F26Dot6 char_height, - FT_UInt horz_resolution, - FT_UInt vert_resolution ) - { - FT_UNUSED( char_width ); - FT_UNUSED( char_height ); - FT_UNUSED( horz_resolution ); - FT_UNUSED( vert_resolution ); - - size->valid = FALSE; - - return T1_Reset_Size( size ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* Set_Pixel_Sizes */ - /* */ - /* */ - /* A driver method used to reset a size's character sizes (horizontal */ - /* and vertical) expressed in integer pixels. */ - /* */ - /* */ - /* pixel_width :: The character width expressed in integer pixels. */ - /* */ - /* pixel_height :: The character height expressed in integer pixels. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error Set_Pixel_Sizes( T1_Size size, - FT_Int pixel_width, - FT_Int pixel_height ) - { - FT_UNUSED( pixel_width ); - FT_UNUSED( pixel_height ); - - size->valid = FALSE; - - return T1_Reset_Size( size ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* Get_Char_Index */ - /* */ - /* */ - /* Uses a charmap to return a given character code's glyph index. */ - /* */ - /* */ - /* charmap :: A handle to the source charmap object. */ - /* charcode :: The character code. */ - /* */ - /* */ - /* Glyph index. 0 means `undefined character code'. */ - /* */ - static - FT_UInt Get_Char_Index( FT_CharMap charmap, - FT_Long charcode ) - { - T1_Face face; - FT_UInt result = 0; - PSNames_Interface* psnames; - - - face = (T1_Face)charmap->face; - psnames = (PSNames_Interface*)face->psnames; - if ( psnames ) - switch ( charmap->encoding ) - { - /*******************************************************************/ - /* */ - /* Unicode encoding support */ - /* */ - case ft_encoding_unicode: - /* use the `PSNames' module to synthetize the Unicode charmap */ - result = psnames->lookup_unicode( &face->unicode_map, - (FT_ULong)charcode ); - - /* the function returns 0xFFFF if the Unicode charcode has */ - /* no corresponding glyph */ - if ( result == 0xFFFF ) - result = 0; - goto Exit; - - /*******************************************************************/ - /* */ - /* Custom Type 1 encoding */ - /* */ - case ft_encoding_adobe_custom: - { - T1_Encoding* encoding = &face->type1.encoding; - - - if ( charcode >= encoding->code_first && - charcode <= encoding->code_last ) - result = encoding->char_index[charcode]; - goto Exit; - } - - /*******************************************************************/ - /* */ - /* Adobe Standard & Expert encoding support */ - /* */ - default: - if ( charcode < 256 ) - { - FT_UInt code; - FT_Int n; - const char* glyph_name; - - - code = psnames->adobe_std_encoding[charcode]; - if ( charmap->encoding == ft_encoding_adobe_expert ) - code = psnames->adobe_expert_encoding[charcode]; - - glyph_name = psnames->adobe_std_strings( code ); - if ( !glyph_name ) - break; - - for ( n = 0; n < face->type1.num_glyphs; n++ ) - { - const char* gname = face->type1.glyph_names[n]; - - - if ( gname && gname[0] == glyph_name[0] && - strcmp( gname, glyph_name ) == 0 ) - { - result = n; - break; - } - } - } - } - Exit: - return result; - } - - - - const FT_Driver_Class t1_driver_class = - { - { - ft_module_font_driver | ft_module_driver_scalable, - sizeof( FT_DriverRec ), - - "type1", /* driver name */ - 0x10000L, /* driver version 1.0 */ - 0x20000L, /* driver requires FreeType 2.0 or above */ - - 0, /* module specific interface */ - - (FT_Module_Constructor)0, - (FT_Module_Destructor) 0, - (FT_Module_Requester) T1_Get_Interface - }, - - sizeof( T1_FaceRec ), - sizeof( T1_SizeRec ), - sizeof( T1_GlyphSlotRec ), - - (FTDriver_initFace) T1_Init_Face, - (FTDriver_doneFace) T1_Done_Face, - (FTDriver_initSize) T1_Init_Size, - (FTDriver_doneSize) T1_Done_Size, - (FTDriver_initGlyphSlot)T1_Init_GlyphSlot, - (FTDriver_doneGlyphSlot)T1_Done_GlyphSlot, - - (FTDriver_setCharSizes) Set_Char_Sizes, - (FTDriver_setPixelSizes)Set_Pixel_Sizes, - (FTDriver_loadGlyph) T1_Load_Glyph, - (FTDriver_getCharIndex) Get_Char_Index, - -#ifdef T1_CONFIG_OPTION_NO_AFM - (FTDriver_getKerning) 0, - (FTDriver_attachFile) 0, -#else - (FTDriver_getKerning) Get_Kerning, - (FTDriver_attachFile) T1_Read_AFM, -#endif - (FTDriver_getAdvances) 0 - }; - - -#ifdef FT_CONFIG_OPTION_DYNAMIC_DRIVERS - - EXPORT_FUNC( const FT_Driver_Class* ) getDriverClass( void ) - { - return &t1_driver_class; - } - -#endif /* FT_CONFIG_OPTION_DYNAMIC_DRIVERS */ - - -/* END */ diff --git a/src/freetype/type1/t1driver.h b/src/freetype/type1/t1driver.h deleted file mode 100644 index 5d615b5baf..0000000000 --- a/src/freetype/type1/t1driver.h +++ /dev/null @@ -1,30 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1driver.h */ -/* */ -/* High-level Type 1 driver interface (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifndef T1DRIVER_H -#define T1DRIVER_H - -#include - - FT_EXPORT_VAR( const FT_Driver_Class ) t1_driver_class; - - -#endif /* T1DRIVER_H */ - - -/* END */ diff --git a/src/freetype/type1/t1gload.c b/src/freetype/type1/t1gload.c deleted file mode 100644 index 37cfc8c5d7..0000000000 --- a/src/freetype/type1/t1gload.c +++ /dev/null @@ -1,1823 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1gload.c */ -/* */ -/* Type 1 Glyph Loader (body). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifdef FT_FLAT_COMPILE - -#include "t1gload.h" - -#ifndef T1_CONFIG_OPTION_DISABLE_HINTER -#include "t1hinter.h" -#endif - -#else /* FT_FLAT_COMPILE */ - -#include - -#ifndef T1_CONFIG_OPTION_DISABLE_HINTER -#include -#endif - -#endif /* FT_FLAT_COMPILE */ - - -#include -#include -#include - -#include /* for strcmp() */ - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_t1gload - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********** *********/ - /********** *********/ - /********** GENERIC CHARSTRING PARSING *********/ - /********** *********/ - /********** *********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - static - void T1_Reset_Builder( T1_Builder* builder, - FT_Bool reset_base ) - { - builder->pos_x = 0; - builder->pos_y = 0; - - builder->left_bearing.x = 0; - builder->left_bearing.y = 0; - builder->advance.x = 0; - builder->advance.y = 0; - - builder->pass = 0; - builder->hint_point = 0; - - if ( builder->loader ) - { - if ( reset_base ) - FT_GlyphLoader_Rewind( builder->loader ); - - FT_GlyphLoader_Prepare( builder->loader ); - } - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Init_Builder */ - /* */ - /* */ - /* Initializes a given glyph builder. */ - /* */ - /* */ - /* builder :: A pointer to the glyph builder to initialize. */ - /* */ - /* */ - /* face :: The current face object. */ - /* */ - /* size :: The current size object. */ - /* */ - /* glyph :: The current glyph object. */ - /* */ - /* funcs :: Glyph builder functions (or `methods'). */ - /* */ - LOCAL_FUNC - void T1_Init_Builder( T1_Builder* builder, - T1_Face face, - T1_Size size, - T1_GlyphSlot glyph, - const T1_Builder_Funcs* funcs ) - { - builder->funcs = *funcs; - builder->path_begun = 0; - builder->load_points = 1; - - builder->face = face; - builder->size = size; - builder->glyph = glyph; - builder->memory = face->root.memory; - - if ( glyph ) - { - FT_GlyphLoader* loader = FT_SLOT( glyph )->loader; - - - builder->loader = loader; - builder->base = &loader->base.outline; - builder->current = &loader->current.outline; - } - - if ( size ) - { - builder->scale_x = size->root.metrics.x_scale; - builder->scale_y = size->root.metrics.y_scale; - } - - T1_Reset_Builder( builder, 1 ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Done_Builder */ - /* */ - /* */ - /* Finalizes a given glyph builder. Its contents can still be used */ - /* after the call, but the function saves important information */ - /* within the corresponding glyph slot. */ - /* */ - /* */ - /* builder :: A pointer to the glyph builder to finalize. */ - /* */ - LOCAL_FUNC - void T1_Done_Builder( T1_Builder* builder ) - { - T1_GlyphSlot glyph = builder->glyph; - - - if ( glyph ) - glyph->root.outline = *builder->base; - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Init_Decoder */ - /* */ - /* */ - /* Initializes a given glyph decoder. */ - /* */ - /* */ - /* decoder :: A pointer to the glyph builder to initialize. */ - /* */ - /* */ - /* funcs :: The hinting functions interface. */ - /* */ - LOCAL_FUNC - void T1_Init_Decoder( T1_Decoder* decoder, - const T1_Hinter_Funcs* funcs ) - { - decoder->hinter = *funcs; /* copy hinter interface */ - decoder->top = 0; - decoder->zone = 0; - - decoder->flex_state = 0; - decoder->num_flex_vectors = 0; - - /* Clear loader */ - MEM_Set( &decoder->builder, 0, sizeof ( decoder->builder ) ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* lookup_glyph_by_stdcharcode */ - /* */ - /* */ - /* Looks up a given glyph by its StandardEncoding charcode. Used */ - /* to implement the SEAC Type 1 operator. */ - /* */ - /* */ - /* face :: The current face object. */ - /* */ - /* charcode :: The character code to look for. */ - /* */ - /* */ - /* A glyph index in the font face. Returns -1 if the corresponding */ - /* glyph wasn't found. */ - /* */ - static - FT_Int lookup_glyph_by_stdcharcode( T1_Face face, - FT_Int charcode ) - { - FT_Int n; - const FT_String* glyph_name; - PSNames_Interface* psnames = (PSNames_Interface*)face->psnames; - - - /* check range of standard char code */ - if ( charcode < 0 || charcode > 255 ) - return -1; - - glyph_name = psnames->adobe_std_strings( - psnames->adobe_std_encoding[charcode] ); - - for ( n = 0; n < face->type1.num_glyphs; n++ ) - { - FT_String* name = (FT_String*)face->type1.glyph_names[n]; - - - if ( name && strcmp( name, glyph_name ) == 0 ) - return n; - } - - return -1; - } - - - /*************************************************************************/ - /* */ - /* */ - /* t1operator_seac */ - /* */ - /* */ - /* Implements the `seac' Type 1 operator for a Type 1 decoder. */ - /* */ - /* */ - /* decoder :: The current CID decoder. */ - /* */ - /* asb :: The accent's side bearing. */ - /* */ - /* adx :: The horizontal offset of the accent. */ - /* */ - /* ady :: The vertical offset of the accent. */ - /* */ - /* bchar :: The base character's StandardEncoding charcode. */ - /* */ - /* achar :: The accent character's StandardEncoding charcode. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error t1operator_seac( T1_Decoder* decoder, - FT_Pos asb, - FT_Pos adx, - FT_Pos ady, - FT_Int bchar, - FT_Int achar ) - { - FT_Error error; - FT_Int bchar_index, achar_index, n_base_points; - FT_Outline* base = decoder->builder.base; - FT_Vector left_bearing, advance; - T1_Face face = decoder->builder.face; - T1_Font* type1 = &face->type1; - - - bchar_index = lookup_glyph_by_stdcharcode( face, bchar ); - achar_index = lookup_glyph_by_stdcharcode( face, achar ); - - if ( bchar_index < 0 || achar_index < 0 ) - { - FT_ERROR(( "t1operator_seac:" )); - FT_ERROR(( " invalid seac character code arguments\n" )); - return T1_Err_Syntax_Error; - } - - /* if we are trying to load a composite glyph, do not load the */ - /* accent character and return the array of subglyphs. */ - if ( decoder->builder.no_recurse ) - { - FT_GlyphSlot glyph = (FT_GlyphSlot)decoder->builder.glyph; - FT_GlyphLoader* loader = glyph->loader; - FT_SubGlyph* subg; - - - /* reallocate subglyph array if necessary */ - error = FT_GlyphLoader_Check_Subglyphs( loader, 2 ); - if ( error ) - goto Exit; - - subg = loader->current.subglyphs; - - /* subglyph 0 = base character */ - subg->index = bchar_index; - subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES | - FT_SUBGLYPH_FLAG_USE_MY_METRICS; - subg->arg1 = 0; - subg->arg2 = 0; - subg++; - - /* subglyph 1 = accent character */ - subg->index = achar_index; - subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES; - subg->arg1 = adx - asb; - subg->arg2 = ady; - - /* set up remaining glyph fields */ - glyph->num_subglyphs = 2; - glyph->subglyphs = loader->current.subglyphs; - glyph->format = ft_glyph_format_composite; - - loader->current.num_subglyphs = 2; - goto Exit; - } - - /* First load `bchar' in builder */ - /* now load the unscaled outline */ - - if ( decoder->builder.loader ) - FT_GlyphLoader_Prepare( decoder->builder.loader ); /* prepare loader */ - - error = T1_Parse_CharStrings( decoder, - type1->charstrings [bchar_index], - type1->charstrings_len[bchar_index], - type1->num_subrs, - type1->subrs, - type1->subrs_len ); - if ( error ) - goto Exit; - - n_base_points = base->n_points; - - /* save the left bearing and width of the base character */ - /* as they will be erased by the next load. */ - - left_bearing = decoder->builder.left_bearing; - advance = decoder->builder.advance; - - decoder->builder.left_bearing.x = 0; - decoder->builder.left_bearing.y = 0; - - /* Now load `achar' on top of the base outline */ - error = T1_Parse_CharStrings( decoder, - type1->charstrings [achar_index], - type1->charstrings_len[achar_index], - type1->num_subrs, - type1->subrs, - type1->subrs_len ); - if ( error ) - return error; - - /* restore the left side bearing and */ - /* advance width of the base character */ - - decoder->builder.left_bearing = left_bearing; - decoder->builder.advance = advance; - - /* Finally, move the accent */ - if ( decoder->builder.load_points ) - { - FT_Outline dummy; - - - dummy.n_points = base->n_points - n_base_points; - dummy.points = base->points + n_base_points; - - FT_Outline_Translate( &dummy, adx - asb, ady ); - } - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* t1operator_flex */ - /* */ - /* */ - /* Implements the `flex' Type 1 operator for a Type 1 decoder. */ - /* */ - /* */ - /* decoder :: The current Type 1 decoder. */ - /* threshold :: The threshold. */ - /* end_x :: The horizontal position of the final flex point. */ - /* end_y :: The vertical position of the final flex point. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error t1operator_flex( T1_Decoder* decoder, - FT_Pos threshold, - FT_Pos end_x, - FT_Pos end_y ) - { - FT_Vector vec; - FT_Vector* flex = decoder->flex_vectors; - FT_Int n; - - FT_UNUSED( threshold ); - FT_UNUSED( end_x ); - FT_UNUSED( end_y ); - - - /* we don't even try to test the threshold in the non-hinting */ - /* builder, even if the flex operator is said to be a path */ - /* construction statement in the specification. This is better */ - /* left to the hinter. */ - - flex = decoder->flex_vectors; - vec = *flex++; - - for ( n = 0; n < 6; n++ ) - { - flex->x += vec.x; - flex->y += vec.y; - - vec = *flex++; - } - - flex = decoder->flex_vectors; - - return decoder->builder.funcs.rcurve_to( &decoder->builder, - flex[0].x, flex[0].y, - flex[1].x, flex[1].y, - flex[2].x, flex[2].y ) || - - decoder->builder.funcs.rcurve_to( &decoder->builder, - flex[3].x, flex[3].y, - flex[4].x, flex[4].y, - flex[5].x, flex[5].y ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Parse_CharStrings */ - /* */ - /* */ - /* Parses a given Type 1 charstrings program. */ - /* */ - /* */ - /* decoder :: The current Type 1 decoder. */ - /* */ - /* charstring_base :: The base address of the charstring stream. */ - /* */ - /* charstring_len :: The length in bytes of the charstring stream. */ - /* */ - /* num_subrs :: The number of sub-routines. */ - /* */ - /* subrs_base :: An array of sub-routines addresses. */ - /* */ - /* subrs_len :: An array of sub-routines lengths. */ - /* */ - /* */ - /* Free error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error T1_Parse_CharStrings( T1_Decoder* decoder, - FT_Byte* charstring_base, - FT_Int charstring_len, - FT_Int num_subrs, - FT_Byte** subrs_base, - FT_Int* subrs_len ) - { - FT_Error error; - T1_Decoder_Zone* zone; - FT_Byte* ip; - FT_Byte* limit; - T1_Builder* builder = &decoder->builder; - T1_Builder_Funcs* builds = &builder->funcs; - T1_Hinter_Funcs* hints = &decoder->hinter; - - static - const FT_Int args_count[op_max] = - { - 0, /* none */ - 0, /* endchar */ - 2, /* hsbw */ - 5, /* seac */ - 4, /* sbw */ - 0, /* closepath */ - 1, /* hlineto */ - 1, /* hmoveto */ - 4, /* hvcurveto */ - 2, /* rlineto */ - 2, /* rmoveto */ - 6, /* rrcurveto */ - 4, /* vhcurveto */ - 1, /* vlineto */ - 1, /* vmoveto */ - 0, /* dotsection */ - 2, /* hstem */ - 6, /* hstem3 */ - 2, /* vstem */ - 6, /* vstem3 */ - 2, /* div */ - -1, /* callothersubr */ - 1, /* callsubr */ - 0, /* pop */ - 0, /* return */ - 2 /* setcurrentpoint */ - }; - - - /* First of all, initialize the decoder */ - decoder->top = decoder->stack; - decoder->zone = decoder->zones; - zone = decoder->zones; - - builder->path_begun = 0; - - zone->base = charstring_base; - limit = zone->limit = charstring_base + charstring_len; - ip = zone->cursor = zone->base; - - error = T1_Err_Ok; - - /* now, execute loop */ - while ( ip < limit ) - { - FT_Int* top = decoder->top; - T1_Operator op = op_none; - FT_Long value = 0; - - - /* Start with the decompression of operator or value */ - switch ( *ip++ ) - { - case 1: - op = op_hstem; - break; - - case 3: - op = op_vstem; - break; - case 4: - op = op_vmoveto; - break; - case 5: - op = op_rlineto; - break; - case 6: - op = op_hlineto; - break; - case 7: - op = op_vlineto; - break; - case 8: - op = op_rrcurveto; - break; - case 9: - op = op_closepath; - break; - case 10: - op = op_callsubr; - break; - case 11: - op = op_return; - break; - - case 13: - op = op_hsbw; - break; - case 14: - op = op_endchar; - break; - - case 21: - op = op_rmoveto; - break; - case 22: - op = op_hmoveto; - break; - - case 30: - op = op_vhcurveto; - break; - case 31: - op = op_hvcurveto; - break; - - case 12: - if ( ip > limit ) - { - FT_ERROR(( "T1_Parse_CharStrings: invalid escape (12+EOF)\n" )); - goto Syntax_Error; - } - - switch ( *ip++ ) - { - case 0: - op = op_dotsection; - break; - case 1: - op = op_vstem3; - break; - case 2: - op = op_hstem3; - break; - case 6: - op = op_seac; - break; - case 7: - op = op_sbw; - break; - case 12: - op = op_div; - break; - case 16: - op = op_callothersubr; - break; - case 17: - op = op_pop; - break; - case 33: - op = op_setcurrentpoint; - break; - - default: - FT_ERROR(( "T1_Parse_CharStrings: invalid escape (12+%d)\n", - ip[-1] )); - goto Syntax_Error; - } - break; - - case 255: /* four bytes integer */ - if ( ip + 4 > limit ) - { - FT_ERROR(( "T1_Parse_CharStrings: unexpected EOF in integer\n" )); - goto Syntax_Error; - } - - value = ( (FT_Long)ip[0] << 24 ) | - ( (FT_Long)ip[1] << 16 ) | - ( (FT_Long)ip[2] << 8 ) | - ip[3]; - ip += 4; - break; - - default: - if ( ip[-1] >= 32 ) - { - if ( ip[-1] < 247 ) - value = (FT_Long)ip[-1] - 139; - else - { - if ( ++ip > limit ) - { - FT_ERROR(( "T1_Parse_CharStrings:" )); - FT_ERROR(( " unexpected EOF in integer\n" )); - goto Syntax_Error; - } - - if ( ip[-2] < 251 ) - value = ((FT_Long)( ip[-2] - 247 ) << 8 ) + ip[-1] + 108; - else - value = -( ( ( (FT_Long)ip[-2] - 251 ) << 8 ) + ip[-1] + 108 ); - } - } - else - { - FT_ERROR(( "T1_Parse_CharStrings: invalid byte (%d)\n", - ip[-1] )); - goto Syntax_Error; - } - } - - /* push value if necessary */ - if ( op == op_none ) - { - if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS ) - { - FT_ERROR(( "T1_Parse_CharStrings: stack overflow!\n" )); - goto Syntax_Error; - } - - *top++ = value; - decoder->top = top; - } - - else if ( op == op_callothersubr ) /* check arguments differently */ - { - if ( top - decoder->stack < 2 ) - goto Stack_Underflow; - - top -= 2; - - switch ( top[1] ) - { - case 1: /* start flex feature */ - if ( top[0] != 0 ) - goto Unexpected_OtherSubr; - - decoder->flex_state = 1; - decoder->num_flex_vectors = 0; - decoder->flex_vectors[0].x = 0; - decoder->flex_vectors[0].y = 0; - break; - - case 2: /* add flex vector */ - { - FT_Int index; - FT_Vector* flex; - - - if ( top[0] != 0 ) - goto Unexpected_OtherSubr; - - top -= 2; - if ( top < decoder->stack ) - goto Stack_Underflow; - - index = decoder->num_flex_vectors++; - if ( index >= 7 ) - { - FT_ERROR(( "T1_Parse_CharStrings: too many flex vectors!\n" )); - goto Syntax_Error; - } - - flex = decoder->flex_vectors + index; - flex->x += top[0]; - flex->y += top[1]; - } - break; - - case 0: /* end flex feature */ - if ( decoder->flex_state == 0 || - decoder->num_flex_vectors != 7 ) - { - FT_ERROR(( "T1_Parse_CharStrings: unexpected flex end\n" )); - goto Syntax_Error; - } - - if ( top[0] != 3 ) - goto Unexpected_OtherSubr; - - top -= 3; - if ( top < decoder->stack ) - goto Stack_Underflow; - - /* now consume the remaining `pop pop setcurrentpoint' */ - if ( ip + 6 > limit || - ip[0] != 12 || ip[1] != 17 || /* pop */ - ip[2] != 12 || ip[3] != 17 || /* pop */ - ip[4] != 12 || ip[5] != 33 ) /* setcurrentpoint */ - { - FT_ERROR(( "T1_Parse_CharStrings: invalid flex charstring\n" )); - goto Syntax_Error; - } - - decoder->flex_state = 0; - decoder->top = top; - - error = t1operator_flex( decoder, top[0], top[1], top[2] ); - break; - - case 3: /* change hints */ - if ( top[0] != 1 ) - goto Unexpected_OtherSubr; - - /* eat the following `pop' */ - if ( ip + 2 > limit ) - { - FT_ERROR(( "T1_Parse_CharStrings: invalid escape (12+%d)\n", - ip[-1] )); - goto Syntax_Error; - } - - if ( ip[0] != 12 || ip[1] != 17 ) - { - FT_ERROR(( "T1_Parse_CharStrings:" )); - FT_ERROR(( " `pop' expected, found (%d %d)\n", ip[0], ip[1] )); - goto Syntax_Error; - } - - ip += 2; - - error = hints->change_hints( builder ); - break; - - default: - /* invalid OtherSubrs call */ - Unexpected_OtherSubr: - FT_ERROR(( "T1_Parse_CharStrings: unexpected OtherSubrs [%d %d]\n", - top[0], top[1] )); - goto Syntax_Error; - } - decoder->top = top; - } - else - { - FT_Int num_args = args_count[op]; - - - if ( top - decoder->stack < num_args ) - goto Stack_Underflow; - - top -= num_args; - - switch ( op ) - { - case op_endchar: - error = builds->end_char( builder ); - break; - - case op_hsbw: - error = builds->set_bearing_point( builder, top[0], 0, - top[1], 0 ); - break; - - case op_seac: - /* return immediately after the processing */ - return t1operator_seac( decoder, top[0], top[1], - top[2], top[3], top[4] ); - - case op_sbw: - error = builds->set_bearing_point( builder, top[0], top[1], - top[2], top[3] ); - break; - - case op_closepath: - error = builds->close_path( builder ); - break; - - case op_hlineto: - error = builds->rline_to( builder, top[0], 0 ); - break; - - case op_hmoveto: - error = builds->rmove_to( builder, top[0], 0 ); - break; - - case op_hvcurveto: - error = builds->rcurve_to( builder, top[0], 0, - top[1], top[2], - 0, top[3] ); - break; - - case op_rlineto: - error = builds->rline_to( builder, top[0], top[1] ); - break; - - case op_rmoveto: - /* ignore operator when in flex mode */ - if ( decoder->flex_state == 0 ) - error = builds->rmove_to( builder, top[0], top[1] ); - else - top += 2; - break; - - case op_rrcurveto: - error = builds->rcurve_to( builder, top[0], top[1], - top[2], top[3], - top[4], top[5] ); - break; - - case op_vhcurveto: - error = builds->rcurve_to( builder, 0, top[0], - top[1], top[2], - top[3], 0 ); - break; - - case op_vlineto: - error = builds->rline_to( builder, 0, top[0] ); - break; - - case op_vmoveto: - error = builds->rmove_to( builder, 0, top[0] ); - break; - - case op_dotsection: - error = hints->dot_section( builder ); - break; - - case op_hstem: - error = hints->stem( builder, top[0], top[1], 0 ); - break; - - case op_hstem3: - error = hints->stem3( builder, top[0], top[1], top[2], - top[3], top[4], top[5], 0 ); - break; - - case op_vstem: - error = hints->stem( builder, top[0], top[1], 1 ); - break; - - case op_vstem3: - error = hints->stem3( builder, top[0], top[1], top[2], - top[3], top[4], top[5], 1 ); - break; - - case op_div: - if ( top[1] ) - { - *top = top[0] / top[1]; - ++top; - } - else - { - FT_ERROR(( "T1_Parse_CHarStrings: division by 0\n" )); - goto Syntax_Error; - } - break; - - case op_callsubr: - { - FT_Int index = top[0]; - - - if ( index < 0 || index >= num_subrs ) - { - FT_ERROR(( "T1_Parse_CharStrings: invalid subrs index\n" )); - goto Syntax_Error; - } - - if ( zone - decoder->zones >= T1_MAX_SUBRS_CALLS ) - { - FT_ERROR(( "T1_Parse_CharStrings: too many nested subrs\n" )); - goto Syntax_Error; - } - - zone->cursor = ip; /* save current instruction pointer */ - - zone++; - zone->base = subrs_base[index]; - zone->limit = zone->base + subrs_len[index]; - zone->cursor = zone->base; - - if ( !zone->base ) - { - FT_ERROR(( "T1_Parse_CharStrings: invoking empty subrs!\n" )); - goto Syntax_Error; - } - - decoder->zone = zone; - ip = zone->base; - limit = zone->limit; - } - break; - - case op_pop: - FT_ERROR(( "T1_Parse_CharStrings: unexpected POP\n" )); - goto Syntax_Error; - - case op_return: - if ( zone <= decoder->zones ) - { - FT_ERROR(( "T1_Parse_CharStrings: unexpected return\n" )); - goto Syntax_Error; - } - - zone--; - ip = zone->cursor; - limit = zone->limit; - decoder->zone = zone; - break; - - case op_setcurrentpoint: - FT_ERROR(( "T1_Parse_CharStrings:" )); - FT_ERROR(( " unexpected `setcurrentpoint'\n" )); - goto Syntax_Error; - break; - - default: - FT_ERROR(( "T1_Parse_CharStrings: unhandled opcode %d\n", op )); - goto Syntax_Error; - } - - decoder->top = top; - } - } - - return error; - - Syntax_Error: - return T1_Err_Syntax_Error; - - Stack_Underflow: - return T1_Err_Stack_Underflow; - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Add_Points */ - /* */ - /* */ - /* Checks that there is enough room in the current load glyph outline */ - /* to accept `num_points' additional outline points. If not, this */ - /* function grows the load outline's arrays accordingly. */ - /* */ - /* */ - /* builder :: A pointer to the glyph builder object. */ - /* */ - /* num_points :: The number of points that will be added later. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* This function does NOT update the points count in the glyph */ - /* builder. This must be done by the caller itself, after this */ - /* function has been invoked. */ - /* */ - LOCAL_FUNC - FT_Error T1_Add_Points( T1_Builder* builder, - FT_Int num_points ) - { - return FT_GlyphLoader_Check_Points( builder->loader, num_points, 0 ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Add_Contours */ - /* */ - /* */ - /* Checks that there is enough room in the current load glyph outline */ - /* to accept `num_contours' additional contours. If not, this */ - /* function grows the load outline's arrays accordingly. */ - /* */ - /* */ - /* builder :: A pointer to the glyph builder object. */ - /* */ - /* num_contours :: The number of contours that will be added later. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* This function does NOT update the contours count in the load glyph */ - /* This must be done by the caller itself, after this function is */ - /* invoked. */ - /* */ - LOCAL_FUNC - FT_Error T1_Add_Contours( T1_Builder* builder, - FT_Int num_contours ) - { - return FT_GlyphLoader_Check_Points( builder->loader, 0, num_contours ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********** *********/ - /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/ - /********** *********/ - /********** The following code is in charge of computing *********/ - /********** the maximum advance width of the font. It *********/ - /********** quickly processes each glyph charstring to *********/ - /********** extract the value from either a `sbw' or `seac' *********/ - /********** operator. *********/ - /********** *********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - static - FT_Error maxadv_sbw( T1_Decoder* decoder, - FT_Pos sbx, - FT_Pos sby, - FT_Pos wx, - FT_Pos wy ) - { - FT_UNUSED( sbx ); - FT_UNUSED( sby ); - FT_UNUSED( wy ); - - if ( wx > decoder->builder.advance.x ) - decoder->builder.advance.x = wx; - - return -1; /* return an error code to exit the Type 1 parser */ - /* immediately. */ - } - - - static - FT_Int maxadv_error( void ) - { - /* we should never reach this code, unless with a buggy font */ - return -2; - } - - - /* the maxadv_gbuilder_interface is used when computing the maximum */ - /* advance width of all glyphs in a given font. We only process the */ - /* `sbw' operator here, and return an error for all others. */ - - /* Note that `seac' is processed by the T1_Decoder. */ - static - const T1_Builder_Funcs maxadv_builder_interface = - { - (T1_Builder_EndChar) maxadv_error, - (T1_Builder_Sbw) maxadv_sbw, - (T1_Builder_ClosePath)maxadv_error, - (T1_Builder_RLineTo) maxadv_error, - (T1_Builder_RMoveTo) maxadv_error, - (T1_Builder_RCurveTo) maxadv_error - }; - - - /* the maxadv_hinter_interface always return an error. */ - static - const T1_Hinter_Funcs maxadv_hinter_interface = - { - (T1_Hinter_DotSection) maxadv_error, - (T1_Hinter_ChangeHints)maxadv_error, - (T1_Hinter_Stem) maxadv_error, - (T1_Hinter_Stem3) maxadv_error, - }; - - - LOCAL_FUNC - FT_Error T1_Compute_Max_Advance( T1_Face face, - FT_Int* max_advance ) - { - FT_Error error; - T1_Decoder decoder; - FT_Int glyph_index; - T1_Font* type1 = &face->type1; - - - *max_advance = 0; - - /* Initialize load decoder */ - T1_Init_Decoder( &decoder, &maxadv_hinter_interface ); - - T1_Init_Builder( &decoder.builder, face, 0, 0, - &maxadv_builder_interface ); - - /* For each glyph, parse the glyph charstring and extract */ - /* the advance width. */ - for ( glyph_index = 0; glyph_index < type1->num_glyphs; glyph_index++ ) - { - /* now get load the unscaled outline */ - error = T1_Parse_CharStrings( &decoder, - type1->charstrings [glyph_index], - type1->charstrings_len[glyph_index], - type1->num_subrs, - type1->subrs, - type1->subrs_len ); - /* ignore the error if one occured - skip to next glyph */ - } - - *max_advance = decoder.builder.advance.x; - return T1_Err_Ok; - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********** *********/ - /********** UNHINTED GLYPH LOADER *********/ - /********** *********/ - /********** The following code is in charge of loading a *********/ - /********** single outline. It completely ignores hinting *********/ - /********** and is used when FT_LOAD_NO_HINTING is set. *********/ - /********** *********/ - /********** The Type 1 hinter is located in `t1hint.c' *********/ - /********** *********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - static - FT_Error close_open_path( T1_Builder* builder ) - { - FT_Error error; - FT_Outline* cur = builder->current; - FT_Int num_points; - FT_Int first_point; - - - /* Some fonts, like Hershey, are made of `open paths' which are */ - /* now managed directly by FreeType. In this case, it is necessary */ - /* to close the path by duplicating its points in reverse order, */ - /* which is precisely the purpose of this function. */ - - /* first compute the number of points to duplicate */ - if ( cur->n_contours > 1 ) - first_point = cur->contours[cur->n_contours - 2] + 1; - else - first_point = 0; - - num_points = cur->n_points - first_point - 2; - if ( num_points > 0 ) - { - FT_Vector* source_point; - char* source_tags; - FT_Vector* point; - char* tags; - - - error = T1_Add_Points( builder, num_points ); - if ( error ) - return error; - - point = cur->points + cur->n_points; - tags = cur->tags + cur->n_points; - - source_point = point - 2; - source_tags = tags - 2; - - cur->n_points += num_points; - - if ( builder->load_points ) - do - { - *point++ = *source_point--; - *tags++ = *source_tags--; - num_points--; - - } while ( num_points > 0 ); - } - - builder->path_begun = 0; - return T1_Err_Ok; - } - - - static - FT_Error gload_closepath( T1_Builder* builder ) - { - FT_Outline* cur = builder->current; - - - /* XXXX: We must not include the last point in the path if it */ - /* is located on the first point. */ - if ( cur->n_points > 1 ) - { - FT_Int first = 0; - FT_Vector* p1 = cur->points + first; - FT_Vector* p2 = cur->points + cur->n_points - 1; - - - if ( cur->n_contours > 1 ) - { - first = cur->contours[cur->n_contours - 2] + 1; - p1 = cur->points + first; - } - - if ( p1->x == p2->x && p1->y == p2->y ) - cur->n_points--; - } - - /* save current contour, if any */ - if ( cur->n_contours > 0 ) - cur->contours[cur->n_contours - 1] = cur->n_points - 1; - -#ifndef T1_CONFIG_OPTION_DISABLE_HINTER - /* hint last points if necessary -- this is not strictly required */ - /* there, but it helps for debugging, and doesn't affect performance */ - if ( builder->pass == 1 ) - T1_Hint_Points( builder ); -#endif - - builder->path_begun = 0; - return T1_Err_Ok; - } - - - static - FT_Error gload_endchar( T1_Builder* builder ) - { - FT_Error error; - - - /* close path if needed */ - if ( builder->path_begun ) - { - error = close_open_path( builder ); - if ( error ) - return error; - } - - error = gload_closepath( builder ); - - FT_GlyphLoader_Add( builder->loader ); - - return error; - } - - - static - FT_Error gload_sbw( T1_Builder* builder, - FT_Pos sbx, - FT_Pos sby, - FT_Pos wx, - FT_Pos wy ) - { - builder->left_bearing.x += sbx; - builder->left_bearing.y += sby; - builder->advance.x = wx; - builder->advance.y = wy; - - builder->last.x = sbx; - builder->last.y = sby; - - return 0; - } - - - static - FT_Error gload_rlineto( T1_Builder* builder, - FT_Pos dx, - FT_Pos dy ) - { - FT_Error error; - FT_Outline* cur = builder->current; - FT_Vector vec; - - - /* grow buffer if necessary */ - error = T1_Add_Points( builder, 1 ); - if ( error ) - return error; - - if ( builder->load_points ) - { - /* save point */ - vec.x = builder->last.x + dx; - vec.y = builder->last.y + dy; - - cur->points[cur->n_points] = vec; - cur->tags [cur->n_points] = FT_Curve_Tag_On; - - builder->last = vec; - } - cur->n_points++; - - builder->path_begun = 1; - - return T1_Err_Ok; - } - - - static - FT_Error gload_rmoveto( T1_Builder* builder, - FT_Pos dx, - FT_Pos dy ) - { - FT_Error error; - FT_Outline* cur = builder->current; - FT_Vector vec; - - - /* in the case where `path_begun' is set, we have an `rmoveto' */ - /* after some normal path definition. If the face's paint type */ - /* is set to 1, this means that we have an `open path', also */ - /* called a `stroke'. The FreeType raster doesn't support */ - /* opened paths, so we'll close it explicitely there. */ - - if ( builder->path_begun && builder->face->type1.paint_type == 1 ) - { - if ( builder->face->type1.paint_type == 1 ) - { - error = close_open_path( builder ); - if ( error ) - return error; - } - } - - /* grow buffer if necessary */ - error = T1_Add_Contours( builder, 1 ) || - T1_Add_Points ( builder, 1 ); - if ( error ) - return error; - - /* save current contour, if any */ - if ( cur->n_contours > 0 ) - cur->contours[cur->n_contours - 1] = cur->n_points - 1; - - if ( builder->load_points ) - { - /* save point */ - vec.x = builder->last.x + dx; - vec.y = builder->last.y + dy; - cur->points[cur->n_points] = vec; - cur->tags [cur->n_points] = FT_Curve_Tag_On; - - builder->last = vec; - } - - cur->n_contours++; - cur->n_points++; - - return T1_Err_Ok; - } - - - static - FT_Error gload_rrcurveto( T1_Builder* builder, - FT_Pos dx1, - FT_Pos dy1, - FT_Pos dx2, - FT_Pos dy2, - FT_Pos dx3, - FT_Pos dy3 ) - { - FT_Error error; - FT_Outline* cur = builder->current; - FT_Vector vec; - FT_Vector* points; - char* tags; - - - /* grow buffer if necessary */ - error = T1_Add_Points( builder, 3 ); - if ( error ) - return error; - - if ( builder->load_points ) - { - /* save point */ - points = cur->points + cur->n_points; - tags = cur->tags + cur->n_points; - - vec.x = builder->last.x + dx1; - vec.y = builder->last.y + dy1; - points[0] = vec; - tags[0] = FT_Curve_Tag_Cubic; - - vec.x += dx2; - vec.y += dy2; - points[1] = vec; - tags[1] = FT_Curve_Tag_Cubic; - - vec.x += dx3; - vec.y += dy3; - points[2] = vec; - tags[2] = FT_Curve_Tag_On; - - builder->last = vec; - } - - cur->n_points += 3; - builder->path_begun = 1; - - return T1_Err_Ok; - } - - - static - FT_Error gload_ignore( void ) - { - return 0; - } - - - static - const T1_Builder_Funcs gload_builder_interface = - { - gload_endchar, - gload_sbw, - gload_closepath, - gload_rlineto, - gload_rmoveto, - gload_rrcurveto - }; - - - static - const T1_Builder_Funcs gload_builder_interface_null = - { - (T1_Builder_EndChar) gload_ignore, - (T1_Builder_Sbw) gload_sbw, /* record left bearing */ - (T1_Builder_ClosePath)gload_ignore, - (T1_Builder_RLineTo) gload_ignore, - (T1_Builder_RMoveTo) gload_ignore, - (T1_Builder_RCurveTo) gload_ignore - }; - - - static - const T1_Hinter_Funcs gload_hinter_interface = - { - (T1_Hinter_DotSection) gload_ignore, /* dotsection */ - (T1_Hinter_ChangeHints)gload_ignore, /* changehints */ - (T1_Hinter_Stem) gload_ignore, /* hstem & vstem */ - (T1_Hinter_Stem3) gload_ignore, /* hstem3 & vestem3 */ - }; - - -#ifndef T1_CONFIG_OPTION_DISABLE_HINTER - - - /*************************************************************************/ - /* */ - /* Hinter overview: */ - /* */ - /* This is a two-pass hinter. On the first pass, the hints are all */ - /* recorded by the hinter, and no point is loaded in the outline. */ - /* */ - /* When the first pass is finished, all stems hints are grid-fitted */ - /* at once. */ - /* */ - /* Then, a second pass is performed to load the outline points as */ - /* well as hint/scale them correctly. */ - /* */ - /*************************************************************************/ - - - static - FT_Error t1_load_hinted_glyph( T1_Decoder* decoder, - FT_UInt glyph_index, - FT_Bool recurse ) - { - T1_Builder* builder = &decoder->builder; - T1_GlyphSlot glyph = builder->glyph; - T1_Font* type1 = &builder->face->type1; - FT_UInt old_points, old_contours; - FT_GlyphLoader* loader = decoder->builder.loader; - FT_Error error; - - - /* Pass 1 -- try to load first glyph, simply recording points */ - old_points = loader->base.outline.n_points; - old_contours = loader->base.outline.n_contours; - - FT_GlyphLoader_Prepare( decoder->builder.loader ); - - T1_Reset_Builder( builder, 0 ); - - builder->no_recurse = recurse; - builder->pass = 0; - glyph->hints->hori_stems.num_stems = 0; - glyph->hints->vert_stems.num_stems = 0; - - error = T1_Parse_CharStrings( decoder, - type1->charstrings [glyph_index], - type1->charstrings_len[glyph_index], - type1->num_subrs, - type1->subrs, - type1->subrs_len ); - if ( error ) - goto Exit; - - /* check for composite (i.e. `seac' operator) */ - if ( glyph->root.format == ft_glyph_format_composite ) - { - /* this is a composite glyph, we must then load the first one, */ - /* then load the second one on top of it and translate it by a */ - /* fixed amount. */ - FT_UInt n_base_points; - FT_SubGlyph* subglyph = loader->base.subglyphs; - T1_Size size = builder->size; - FT_Pos dx, dy; - FT_Vector left_bearing, advance; - - - /* clean glyph format */ - glyph->root.format = ft_glyph_format_none; - - /* First load `bchar' in builder */ - builder->no_recurse = 0; - error = t1_load_hinted_glyph( decoder, subglyph->index, 0 ); - if ( error ) - goto Exit; - - /* save the left bearing and width of the base character */ - /* as they will be erased by the next load */ - left_bearing = builder->left_bearing; - advance = builder->advance; - - /* Then load `achar' in builder */ - n_base_points = builder->base->n_points; - subglyph++; - error = t1_load_hinted_glyph( decoder, subglyph->index, 0 ); - if ( error ) - goto Exit; - - /* Finally, move the accent */ - dx = FT_MulFix( subglyph->arg1, size->root.metrics.x_scale ); - dy = FT_MulFix( subglyph->arg2, size->root.metrics.y_scale ); - dx = ( dx + 32 ) & -64; - dy = ( dy + 32 ) & -64; - { - FT_Outline dummy; - - - dummy.n_points = loader->base.outline.n_points - n_base_points; - dummy.points = loader->base.outline.points + n_base_points; - - FT_Outline_Translate( &dummy, dx, dy ); - } - - /* restore the left side bearing and */ - /* advance width of the base character */ - builder->left_bearing = left_bearing; - builder->advance = advance; - } - else - { - /* All right, pass 1 is finished, now grid-fit all stem hints */ - T1_Hint_Stems( &decoder->builder ); - - /* undo the end-char */ - builder->base->n_points = old_points; - builder->base->n_contours = old_contours; - - /* Pass 2 -- record and scale/hint the points */ - T1_Reset_Builder( builder, 0 ); - - builder->pass = 1; - builder->no_recurse = 0; - - error = T1_Parse_CharStrings( decoder, - type1->charstrings [glyph_index], - type1->charstrings_len[glyph_index], - type1->num_subrs, - type1->subrs, - type1->subrs_len ); - } - - /* save new glyph tables */ - if ( recurse ) - T1_Done_Builder( builder ); - - Exit: - return error; - } - - -#endif /* !T1_CONFIG_OPTION_DISABLE_HINTER */ - - - LOCAL_FUNC - FT_Error T1_Load_Glyph( T1_GlyphSlot glyph, - T1_Size size, - FT_Int glyph_index, - FT_Int load_flags ) - { - FT_Error error; - T1_Decoder decoder; - T1_Face face = (T1_Face)glyph->root.face; - FT_Bool hinting; - T1_Font* type1 = &face->type1; - - - if ( load_flags & FT_LOAD_NO_RECURSE ) - load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; - - glyph->x_scale = size->root.metrics.x_scale; - glyph->y_scale = size->root.metrics.y_scale; - - glyph->root.outline.n_points = 0; - glyph->root.outline.n_contours = 0; - - glyph->root.format = ft_glyph_format_outline; /* by default */ - - hinting = 0; - -#ifndef T1_CONFIG_OPTION_DISABLE_HINTER - - hinting = ( load_flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING ) ) == 0; - - if ( hinting ) - { - T1_Init_Decoder( &decoder, &t1_hinter_funcs ); - T1_Init_Builder( &decoder.builder, face, size, glyph, - &gload_builder_interface ); - - error = t1_load_hinted_glyph( &decoder, glyph_index, 1 ); - } - else - -#endif /* !T1_CONFIG_OPTION_DISABLE_HINTER */ - - { - T1_Init_Decoder( &decoder, &gload_hinter_interface ); - - T1_Init_Builder( &decoder.builder, face, size, glyph, - &gload_builder_interface ); - - decoder.builder.no_recurse = ( load_flags & FT_LOAD_NO_RECURSE ) != 0; - - /* now load the unscaled outline */ - error = T1_Parse_CharStrings( &decoder, - type1->charstrings [glyph_index], - type1->charstrings_len[glyph_index], - type1->num_subrs, - type1->subrs, - type1->subrs_len ); - - /* save new glyph tables */ - T1_Done_Builder( &decoder.builder ); - } - - /* Now, set the metrics -- this is rather simple, as */ - /* the left side bearing is the xMin, and the top side */ - /* bearing the yMax */ - if ( !error ) - { - /* for composite glyphs, return only the left side bearing and the */ - /* advance width */ - if ( glyph->root.format == ft_glyph_format_composite ) - { - glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x; - glyph->root.metrics.horiAdvance = decoder.builder.advance.x; - } - else - { - FT_BBox cbox; - FT_Glyph_Metrics* metrics = &glyph->root.metrics; - - - /* apply the font matrix */ - FT_Outline_Transform( &glyph->root.outline, - &face->type1.font_matrix ); - - FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); - - /* grid fit the bounding box if necessary */ - if ( hinting ) - { - cbox.xMin &= -64; - cbox.yMin &= -64; - cbox.xMax = ( cbox.xMax + 63 ) & -64; - cbox.yMax = ( cbox.yMax + 63 ) & -64; - } - - metrics->width = cbox.xMax - cbox.xMin; - metrics->height = cbox.yMax - cbox.yMin; - - metrics->horiBearingX = cbox.xMin; - metrics->horiBearingY = cbox.yMax; - - /* copy the _unscaled_ advance width */ - metrics->horiAdvance = decoder.builder.advance.x; - - /* make up vertical metrics */ - metrics->vertBearingX = 0; - metrics->vertBearingY = 0; - metrics->vertAdvance = 0; - - glyph->root.format = ft_glyph_format_outline; - - glyph->root.outline.flags = 0; - - if ( size->root.metrics.y_ppem < 24 ) - glyph->root.outline.flags |= ft_outline_high_precision; - - glyph->root.outline.flags |= ft_outline_reverse_fill; - - if ( hinting ) - { - /* adjust the advance width */ - /* XXX TODO: consider stem hints grid-fit */ - metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, - glyph->x_scale ); - } - else if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ) - { - /* scale the outline and the metrics */ - FT_Int n; - FT_Outline* cur = decoder.builder.base; - FT_Vector* vec = cur->points; - FT_Fixed x_scale = glyph->x_scale; - FT_Fixed y_scale = glyph->y_scale; - - - /* First of all, scale the points */ - for ( n = cur->n_points; n > 0; n--, vec++ ) - { - vec->x = FT_MulFix( vec->x, x_scale ); - vec->y = FT_MulFix( vec->y, y_scale ); - } - - /* Then scale the metrics */ - metrics->width = FT_MulFix( metrics->width, x_scale ); - metrics->height = FT_MulFix( metrics->height, y_scale ); - - metrics->horiBearingX = FT_MulFix( metrics->horiBearingX, x_scale ); - metrics->horiBearingY = FT_MulFix( metrics->horiBearingY, y_scale ); - - metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale ); - metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale ); - - metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); - metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); - } - } - } - - return error; - } - - -/* END */ diff --git a/src/freetype/type1/t1gload.h b/src/freetype/type1/t1gload.h deleted file mode 100644 index 658a929d06..0000000000 --- a/src/freetype/type1/t1gload.h +++ /dev/null @@ -1,326 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1gload.h */ -/* */ -/* Type 1 Glyph Loader (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifndef T1GLOAD_H -#define T1GLOAD_H - - -#ifdef FT_FLAT_COMPILE - -#include "t1objs.h" - -#else - -#include - -#endif - - -#ifdef __cplusplus - extern "C" { -#endif - - - typedef struct T1_Builder_ T1_Builder; - - typedef FT_Error (*T1_Builder_EndChar)( T1_Builder* loader ); - - typedef FT_Error (*T1_Builder_Sbw)( T1_Builder* loader, - FT_Pos sbx, - FT_Pos sby, - FT_Pos wx, - FT_Pos wy ); - - typedef FT_Error (*T1_Builder_ClosePath)( T1_Builder* loader ); - - typedef FT_Error (*T1_Builder_RLineTo)( T1_Builder* loader, - FT_Pos dx, - FT_Pos dy ); - - typedef FT_Error (*T1_Builder_RMoveTo)( T1_Builder* loader, - FT_Pos dx, - FT_Pos dy ); - - typedef FT_Error (*T1_Builder_RCurveTo)( T1_Builder* loader, - FT_Pos dx1, - FT_Pos dy1, - FT_Pos dx2, - FT_Pos dy2, - FT_Pos dx3, - FT_Pos dy3 ); - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Builder_Funcs */ - /* */ - /* */ - /* A structure to store the address of various functions used by a */ - /* glyph builder to implement the outline's `path construction'. */ - /* */ - typedef struct T1_Builder_Funcs_ - { - T1_Builder_EndChar end_char; - T1_Builder_Sbw set_bearing_point; - T1_Builder_ClosePath close_path; - T1_Builder_RLineTo rline_to; - T1_Builder_RMoveTo rmove_to; - T1_Builder_RCurveTo rcurve_to; - - } T1_Builder_Funcs; - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Builder */ - /* */ - /* */ - /* A structure used during glyph loading to store its outline. */ - /* */ - /* */ - /* memory :: The current memory object. */ - /* */ - /* face :: The current face object. */ - /* */ - /* size :: The current size object. */ - /* */ - /* glyph :: The current glyph slot. */ - /* */ - /* loader :: The current glyph loader. */ - /* */ - /* current :: The current glyph outline. */ - /* */ - /* base :: The base glyph outline. */ - /* */ - /* last :: The last point position. */ - /* */ - /* scale_x :: The horizontal scale (FUnits to sub-pixels). */ - /* */ - /* scale_y :: The vertical scale (FUnits to sub-pixels). */ - /* */ - /* pos_x :: The horizontal translation (for composite glyphs). */ - /* */ - /* pos_y :: The vertical translation (for composite glyphs). */ - /* */ - /* left_bearing :: The left side bearing point. */ - /* */ - /* advance :: The horizontal advance vector. */ - /* */ - /* no_recurse :: */ - /* */ - /* bbox :: The glyph's bounding box. */ - /* */ - /* path_begun :: A flag which indicates that a new path has begun. */ - /* */ - /* load_points :: A flag which indicates, if not set, that no points */ - /* are loaded. */ - /* */ - /* pass :: The pass number for multi-pass hinters. */ - /* */ - /* hint_point :: The index of the next point to hint. */ - /* */ - /* funcs :: A table of builder functions used to perform the */ - /* outline's path construction. */ - /* */ - struct T1_Builder_ - { - FT_Memory memory; - T1_Face face; - T1_Size size; - T1_GlyphSlot glyph; - FT_GlyphLoader* loader; - - FT_Outline* current; /* the current glyph outline */ - FT_Outline* base; /* the composite glyph outline */ - - FT_Vector last; - - FT_Fixed scale_x; - FT_Fixed scale_y; - - FT_Pos pos_x; - FT_Pos pos_y; - - FT_Vector left_bearing; - FT_Vector advance; - FT_Bool no_recurse; - - FT_BBox bbox; /* bounding box */ - FT_Bool path_begun; - FT_Bool load_points; - - FT_Int pass; - FT_Int hint_point; - - /* path construction function interface */ - T1_Builder_Funcs funcs; - }; - - - typedef FT_Error (*T1_Hinter_ChangeHints)( T1_Builder* builder ); - - typedef FT_Error (*T1_Hinter_DotSection)( T1_Builder* builder ); - - typedef FT_Error (*T1_Hinter_Stem)( T1_Builder* builder, - FT_Pos pos, - FT_Pos width, - FT_Bool vertical ); - - typedef FT_Error (*T1_Hinter_Stem3)( T1_Builder* builder, - FT_Pos pos0, - FT_Pos width0, - FT_Pos pos1, - FT_Pos width1, - FT_Pos pos2, - FT_Pos width2, - FT_Bool vertical ); - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Hinter_Funcs */ - /* */ - /* */ - /* A structure to store the address of various functions used by a */ - /* Type 1 hinter to perform outline hinting. */ - /* */ - typedef struct T1_Hinter_Func_ - { - T1_Hinter_ChangeHints change_hints; - T1_Hinter_DotSection dot_section; - T1_Hinter_Stem stem; - T1_Hinter_Stem3 stem3; - - } T1_Hinter_Funcs; - - - typedef enum T1_Operator_ - { - op_none = 0, - op_endchar, - op_hsbw, - op_seac, - op_sbw, - op_closepath, - op_hlineto, - op_hmoveto, - op_hvcurveto, - op_rlineto, - op_rmoveto, - op_rrcurveto, - op_vhcurveto, - op_vlineto, - op_vmoveto, - op_dotsection, - op_hstem, - op_hstem3, - op_vstem, - op_vstem3, - op_div, - op_callothersubr, - op_callsubr, - op_pop, - op_return, - op_setcurrentpoint, - - op_max /* never remove this one */ - - } T1_Operator; - - - /* execution context charstring zone */ - typedef struct T1_Decoder_Zone_ - { - FT_Byte* base; - FT_Byte* limit; - FT_Byte* cursor; - - } T1_Decoder_Zone; - - - typedef struct T1_Decoder_ - { - T1_Builder builder; - T1_Hinter_Funcs hinter; - - FT_Int stack[T1_MAX_CHARSTRINGS_OPERANDS]; - FT_Int* top; - - T1_Decoder_Zone zones[T1_MAX_SUBRS_CALLS + 1]; - T1_Decoder_Zone* zone; - - FT_Int flex_state; - FT_Int num_flex_vectors; - FT_Vector flex_vectors[7]; - - } T1_Decoder; - - - LOCAL_DEF - void T1_Init_Builder( T1_Builder* builder, - T1_Face face, - T1_Size size, - T1_GlyphSlot glyph, - const T1_Builder_Funcs* funcs ); - - LOCAL_DEF - void T1_Done_Builder( T1_Builder* builder ); - - LOCAL_DEF - void T1_Init_Decoder( T1_Decoder* decoder, - const T1_Hinter_Funcs* funcs ); - - LOCAL_DEF - FT_Error T1_Compute_Max_Advance( T1_Face face, - FT_Int* max_advance ); - - LOCAL_DEF - FT_Error T1_Parse_CharStrings( T1_Decoder* decoder, - FT_Byte* charstring_base, - FT_Int charstring_len, - FT_Int num_subrs, - FT_Byte** subrs_base, - FT_Int* subrs_len ); - - LOCAL_DEF - FT_Error T1_Add_Points( T1_Builder* builder, - FT_Int num_points ); - - LOCAL_DEF - FT_Error T1_Add_Contours( T1_Builder* builder, - FT_Int num_contours ); - - LOCAL_DEF - FT_Error T1_Load_Glyph( T1_GlyphSlot glyph, - T1_Size size, - FT_Int glyph_index, - FT_Int load_flags ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* T1GLOAD_H */ - - -/* END */ diff --git a/src/freetype/type1/t1hinter.c b/src/freetype/type1/t1hinter.c deleted file mode 100644 index 7ce746228a..0000000000 --- a/src/freetype/type1/t1hinter.c +++ /dev/null @@ -1,1347 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1hinter.c */ -/* */ -/* Type 1 hinter (body). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* The Hinter is in charge of fitting th scaled outline to the pixel */ - /* grid in order to considerably improve the quality of the Type 1 font */ - /* driver's output. */ - /* */ - /*************************************************************************/ - - -#include - - -#ifdef FT_FLAT_COMPILE - -#include "t1objs.h" -#include "t1hinter.h" - -#else - -#include -#include - -#endif - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_t1hint - - -#undef ONE_PIXEL -#define ONE_PIXEL 64 - -#undef ROUND -#define ROUND( x ) ( ( x + ONE_PIXEL / 2 ) & -ONE_PIXEL ) - -#undef SCALE -#define SCALE( val ) FT_MulFix( val, scale ) - -/* various constants used to describe the alignment of a horizontal */ -/* stem with regards to the blue zones */ - -#define T1_ALIGN_NONE 0 -#define T1_ALIGN_BOTTOM 1 -#define T1_ALIGN_TOP 2 -#define T1_ALIGN_BOTH 3 - - - /* very simple bubble sort (not a lot of elements, mostly */ - /* pre-sorted, no need for quicksort) */ - - static - void t1_sort_blues( FT_Int* blues, - FT_Int count ) - { - FT_Int i, swap; - FT_Int* cur; - - - for ( i = 2; i < count; i += 2 ) - { - cur = blues + i; - do - { - if ( cur[-1] < cur[0] ) - break; - - swap = cur[-2]; cur[-2] = cur[0]; cur[0] = swap; - swap = cur[-1]; cur[-1] = cur[1]; cur[1] = swap; - cur -= 2; - - } while ( cur > blues ); - } - } - - - /*************************************************************************/ - /* */ - /* */ - /* t1_set_blue_zones */ - /* */ - /* */ - /* Sets a size object's blue zones during reset. This will compute */ - /* the `snap' zone corresponding to each blue zone. */ - /* */ - /* */ - /* size :: A handle to target size object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* This functions does the following: */ - /* */ - /* 1. It extracts the bottom and top blue zones from the face object. */ - /* */ - /* 2. Each zone is then grown by `BlueFuzz', overlapping is */ - /* eliminated by adjusting the zone edges appropriately. */ - /* */ - /* 3. For each zone, we keep its original font units position, its */ - /* original scaled position, as well as its grown/adjusted edges. */ - /* */ - static - FT_Error t1_set_blue_zones( T1_Size size ) - { - T1_Face face = (T1_Face)size->root.face; - T1_Private* priv = &face->type1.private_dict; - FT_Int n; - FT_Int blues[24]; - FT_Int num_bottom; - FT_Int num_top; - FT_Int num_blues; - T1_Size_Hints* hints = size->hints; - T1_Snap_Zone* zone; - FT_Pos pix, orus; - FT_Pos min, max, threshold; - FT_Fixed scale; - FT_Bool is_bottom; - - - /***********************************************************************/ - /* */ - /* copy bottom and top blue zones in local arrays */ - /* */ - - /* First of all, check the sizes of the /BlueValues and /OtherBlues */ - /* tables. They all must contain an even number of arguments. */ - if ( priv->num_other_blues & 1 || - priv->num_blue_values & 1 ) - { - FT_ERROR(( "t1_set_blue_zones: odd number of blue values\n" )); - return T1_Err_Syntax_Error; - } - - /* copy the bottom blue zones from /OtherBlues */ - num_top = 0; - num_bottom = priv->num_other_blues; - - for ( n = 0; n < num_bottom; n++ ) - blues[n] = priv->other_blues[n]; - - /* add the first blue zone in /BlueValues to the table */ - num_top = priv->num_blue_values - 2; - if ( num_top >= 0 ) - { - blues[num_bottom ] = priv->blue_values[0]; - blues[num_bottom + 1] = priv->blue_values[1]; - - num_bottom += 2; - } - - /* sort the bottom blue zones */ - t1_sort_blues( blues, num_bottom ); - - hints->num_bottom_zones = num_bottom >> 1; - - /* now copy the /BlueValues to the top of the blues array */ - if ( num_top > 0 ) - { - for ( n = 0; n < num_top; n++ ) - blues[num_bottom + n] = priv->blue_values[n + 2]; - - /* sort the top blue zones */ - t1_sort_blues( blues + num_bottom, num_top ); - } - else - num_top = 0; - - num_blues = num_top + num_bottom; - hints->num_blue_zones = ( num_blues ) >> 1; - - /***********************************************************************/ - /* */ - /* build blue snap zones from the local blues arrays */ - /* */ - - scale = size->root.metrics.y_scale; - zone = hints->blue_zones; - threshold = ONE_PIXEL / 4; /* 0.25 pixels */ - - for ( n = 0; n < num_blues; n += 2, zone++ ) - { - is_bottom = n < num_bottom ? 1 : 0; - - orus = blues[n + is_bottom]; /* get alignement coordinate */ - pix = SCALE( orus ); /* scale it */ - - min = SCALE( blues[n ] - priv->blue_fuzz ); - max = SCALE( blues[n + 1] + priv->blue_fuzz ); - - if ( min > pix - threshold ) - min = pix - threshold; - if ( max < pix + threshold ) - max = pix + threshold; - - zone->orus = orus; - zone->pix = pix; - zone->min = min; - zone->max = max; - } - - /* adjust edges in case of overlap */ - zone = hints->blue_zones; - for ( n = 0; n < num_blues - 2; n += 2, zone++ ) - { - if ( n != num_bottom - 2 && - zone[0].max > zone[1].min ) - zone[0].max = zone[1].min = ( zone[0].pix + zone[1].pix ) / 2; - } - - /* compare the current pixel size with the BlueScale value */ - /* to know whether to supress overshoots */ - - hints->supress_overshoots = - size->root.metrics.y_ppem < FT_MulFix( 1000, priv->blue_scale ); - -#ifdef FT_DEBUG_LEVEL_TRACE - - /* now print the new blue values in tracing mode */ - - FT_TRACE2(( "Blue Zones for size object at $%08lx:\n", (long)size )); - FT_TRACE2(( " orus pix min max\n" )); - FT_TRACE2(( "-------------------------------\n" )); - - zone = hints->blue_zones; - for ( n = 0; n < hints->num_blue_zones; n++ ) - { - FT_TRACE2(( " %3d %.2f %.2f %.2f\n", - zone->orus, - zone->pix / 64.0, - zone->min / 64.0, - zone->max / 64.0 )); - zone++; - } - FT_TRACE2(( "\nOvershoots are %s\n\n", - hints->supress_overshoots ? "supressed" : "active" )); - -#endif /* DEBUG_LEVEL_TRACE */ - - return T1_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* t1_set_snap_zones */ - /* */ - /* */ - /* This function set a size object's stem snap zones. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* This function performs the following: */ - /* */ - /* 1. It reads and scales the stem snap widths from the parent face. */ - /* */ - /* 2. A `snap zone' is computed for each snap width, by `growing' it */ - /* with a threshold of 1/2 pixel. Overlapping is avoided through */ - /* proper edge adjustment. */ - /* */ - /* 3. Each width whose zone contain the scaled standard set width is */ - /* removed from the table. */ - /* */ - /* 4. Finally, the standard set width is scaled, and its correponding */ - /* `snap zone' is inserted into the sorted snap zones table. */ - /* */ - static - FT_Error t1_set_snap_zones( T1_Size size ) - { - FT_Int n, direction, n_zones, num_zones; - T1_Snap_Zone* zone; - T1_Snap_Zone* base_zone; - FT_Short* orgs; - FT_Pos standard_width; - FT_Fixed scale; - - T1_Face face = (T1_Face)size->root.face; - T1_Private* priv = &face->type1.private_dict; - T1_Size_Hints* hints = size->hints; - - - /* start with horizontal snap zones */ - direction = 0; - standard_width = priv->standard_width[0]; - n_zones = priv->num_snap_widths; - base_zone = hints->snap_widths; - orgs = priv->snap_widths; - scale = size->root.metrics.x_scale; - - while ( direction < 2 ) - { - /*********************************************************************/ - /* */ - /* Read and scale stem snap widths table from the physical font */ - /* record. */ - /* */ - - FT_Pos prev, orus, pix, min, max, threshold; - - - threshold = ONE_PIXEL / 4; - zone = base_zone; - - if ( n_zones > 0 ) - { - orus = *orgs++; - pix = SCALE( orus ); - min = pix - threshold; - max = pix + threshold; - - zone->orus = orus; - zone->pix = pix; - zone->min = min; - prev = pix; - - for ( n = 1; n < n_zones; n++ ) - { - orus = *orgs++; - pix = SCALE( orus ); - - if ( pix - prev < 2 * threshold ) - { - min = max = ( pix + prev ) / 2; - } - else - min = pix - threshold; - - zone->max = max; - zone++; - zone->orus = orus; - zone->pix = pix; - zone->min = min; - - max = pix + threshold; - prev = pix; - } - zone->max = max; - } - -#ifdef FT_DEBUG_LEVEL_TRACE - - /* print the scaled stem snap values in tracing mode */ - - FT_TRACE2(( "Set_Snap_Zones: first %s pass\n", - direction ? "vertical" : "horizontal" )); - - FT_TRACE2(( "Scaled original stem snap zones:\n" )); - FT_TRACE2(( " orus pix min max\n" )); - FT_TRACE2(( "-----------------------------\n" )); - - zone = base_zone; - for ( n = 0; n < n_zones; n++, zone++ ) - FT_TRACE2(( " %3d %.2f %.2f %.2f\n", - zone->orus, - zone->pix / 64.0, - zone->min / 64.0, - zone->max / 64.0 )); - FT_TRACE2(( "\n" )); - - FT_TRACE2(( "Standard width = %d\n", standard_width )); - -#endif /* FT_DEBUG_LEVEL_TRACE */ - - /*********************************************************************/ - /* */ - /* Now, each snap width which is in the range of the standard set */ - /* width will be removed from the list. */ - /* */ - - if ( standard_width > 0 ) - { - T1_Snap_Zone* parent; - FT_Pos std_pix, std_min, std_max; - - - std_pix = SCALE( standard_width ); - - std_min = std_pix - threshold; - std_max = std_pix + threshold; - - num_zones = 0; - zone = base_zone; - parent = base_zone; - - for ( n = 0; n < n_zones; n++ ) - { - if ( zone->pix >= std_min && zone->pix <= std_max ) - { - /* this zone must be removed from the list */ - if ( std_min > zone->min ) - std_min = zone->min; - if ( std_max < zone->max ) - std_max = zone->max; - } - else - { - *parent++ = *zone; - num_zones++; - } - zone++; - } - - /*******************************************************************/ - /* */ - /* Now, insert the standard width zone */ - /* */ - - zone = base_zone + num_zones; - while ( zone > base_zone && zone[-1].pix > std_max ) - { - zone[0] = zone[-1]; - zone--; - } - - /* check border zones */ - if ( zone > base_zone && zone[-1].max > std_min ) - zone[-1].max = std_min; - - if ( zone < base_zone + num_zones && zone[1].min < std_max ) - zone[1].min = std_max; - - zone->orus = standard_width; - zone->pix = std_pix; - zone->min = std_min; - zone->max = std_max; - - num_zones++; - } - else - num_zones = n_zones; - - /* save total number of stem snaps now */ - if ( direction ) - hints->num_snap_heights = num_zones; - else - hints->num_snap_widths = num_zones; - -#ifdef FT_DEBUG_LEVEL_TRACE - - /* print the scaled stem snap values in tracing mode */ - - FT_TRACE2(( "Set_Snap_Zones: second %s pass\n", - direction ? "vertical" : "horizontal" )); - - FT_TRACE2(( "Scaled clipped stem snap zones:\n" )); - FT_TRACE2(( " orus pix min max\n" )); - FT_TRACE2(( "-----------------------------\n" )); - - zone = base_zone; - for ( n = 0; n < num_zones; n++, zone++ ) - FT_TRACE2(( " %3d %.2f %.2f %.2f\n", - zone->orus, - zone->pix / 64.0, - zone->min / 64.0, - zone->max / 64.0 )); - FT_TRACE2(( "\n" )); - - FT_TRACE2(( "Standard width = %d\n", standard_width )); - -#endif /* FT_DEBUG_LEVEL_TRACE */ - - /* continue with vertical snap zone */ - direction++; - standard_width = priv->standard_height[0]; - n_zones = priv->num_snap_heights; - base_zone = hints->snap_heights; - orgs = priv->snap_heights; - scale = size->root.metrics.y_scale; - } - - return T1_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_New_Size_Hinter */ - /* */ - /* */ - /* Allocates a new hinter structure for a given size object. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - /* */ - /* FreeType Error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error T1_New_Size_Hinter( T1_Size size ) - { - FT_Memory memory = size->root.face->memory; - - - return MEM_Alloc( size->hints, sizeof ( *size->hints ) ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Done_Size_Hinter */ - /* */ - /* */ - /* Releases a given size object's hinter structure. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - LOCAL_FUNC - void T1_Done_Size_Hinter( T1_Size size ) - { - FT_Memory memory = size->root.face->memory; - - - FREE( size->hints ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Reset_Size_Hinter */ - /* */ - /* */ - /* Recomputes hinting information when a given size object has */ - /* changed its resolutions/char sizes/pixel sizes. */ - /* */ - /* */ - /* size :: A handle to the size object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error T1_Reset_Size_Hinter( T1_Size size ) - { - return t1_set_blue_zones( size ) || t1_set_snap_zones( size ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_New_Glyph_Hinter */ - /* */ - /* */ - /* Allocates a new hinter structure for a given glyph slot. */ - /* */ - /* */ - /* glyph :: A handle to the target glyph slot. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error T1_New_Glyph_Hinter( T1_GlyphSlot glyph ) - { - FT_Memory memory = glyph->root.face->memory; - - - return MEM_Alloc( glyph->hints, sizeof ( *glyph->hints ) ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Done_Glyph_Hinter */ - /* */ - /* */ - /* Releases a given glyph slot's hinter structure. */ - /* */ - /* */ - /* glyph :: A handle to the glyph slot. */ - /* */ - LOCAL_FUNC - void T1_Done_Glyph_Hinter( T1_GlyphSlot glyph ) - { - FT_Memory memory = glyph->root.face->memory; - - - FREE( glyph->hints ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********** **********/ - /********** HINTED GLYPH LOADER **********/ - /********** **********/ - /********** The following code is in charge of the first **********/ - /********** and second pass when loading a single outline **********/ - /********** **********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - static - FT_Error t1_hinter_ignore( void ) - { - /* do nothing, used for `dotsection' which is unsupported for now */ - return 0; - } - - - static - FT_Error t1_hinter_stem( T1_Builder* builder, - FT_Pos pos, - FT_Int width, - FT_Bool vertical ) - { - T1_Stem_Table* stem_table; - T1_Stem_Hint* stems; - T1_Stem_Hint* cur_stem; - FT_Int min, max, n, num_stems; - FT_Bool new_stem; - T1_Glyph_Hints* hinter = builder->glyph->hints; - - - /* select the appropriate stem array */ - stem_table = vertical ? &hinter->vert_stems : &hinter->hori_stems; - stems = stem_table->stems; - num_stems = stem_table->num_stems; - - /* Compute minimum and maximum coord for the stem */ - min = pos + ( vertical - ? builder->left_bearing.x - : builder->left_bearing.y ); - - if ( width >= 0 ) - max = min + width; - else - { - /* a negative width indicates a `ghost' stem */ - if ( width == -21 ) - min += width; - - max = min; - } - - /* Now scan the array. If we find a stem with the same borders */ - /* simply activate it. */ - cur_stem = stems; - new_stem = 1; - - for ( n = 0; n < num_stems; n++, cur_stem++ ) - { - if ( cur_stem->min_edge.orus == min && - cur_stem->max_edge.orus == max ) - { - /* This stem is already in the table, simply activate it */ - if ( ( cur_stem->hint_flags & T1_HINT_FLAG_ACTIVE ) == 0 ) - { - cur_stem->hint_flags |= T1_HINT_FLAG_ACTIVE; - stem_table->num_active++; - } - new_stem = 0; - break; - } - } - - /* add a new stem to the array if necessary */ - if ( new_stem ) - { - if ( cur_stem >= stems + T1_HINTER_MAX_EDGES ) - { - FT_ERROR(( "t1_hinter_stem: too many stems in glyph charstring\n" )); - return T1_Err_Syntax_Error; - } - - /* on the first pass, we record the stem, otherwise, this is */ - /* a bug in the glyph loader! */ - if ( builder->pass == 0 ) - { - cur_stem->min_edge.orus = min; - cur_stem->max_edge.orus = max; - cur_stem->hint_flags = T1_HINT_FLAG_ACTIVE; - - stem_table->num_stems++; - stem_table->num_active++; - } - else - { - FT_ERROR(( "t1_hinter_stem:" )); - FT_ERROR(( " fatal glyph loader bug -- pass2-stem\n" )); - return T1_Err_Syntax_Error; - } - } - - return T1_Err_Ok; - } - - - static - FT_Error t1_hinter_stem3( T1_Builder* builder, - FT_Pos pos0, - FT_Int width0, - FT_Pos pos1, - FT_Int width1, - FT_Pos pos2, - FT_Int width2, - FT_Bool vertical ) - { - /* For now, simply call `stem' 3 times */ - return t1_hinter_stem( builder, pos0, width0, vertical ) || - t1_hinter_stem( builder, pos1, width1, vertical ) || - t1_hinter_stem( builder, pos2, width2, vertical ); - } - - - static - FT_Error t1_hinter_changehints( T1_Builder* builder ) - { - FT_Int dimension; - T1_Stem_Table* stem_table; - T1_Glyph_Hints* hinter = builder->glyph->hints; - - - /* If we are in the second pass of glyph hinting, we must */ - /* call the function T1_Hint_Points() on the builder in order */ - /* to force the fit the latest points to the pixel grid. */ - if ( builder->pass == 1 ) - T1_Hint_Points( builder ); - - /* Simply de-activate all hints in all arrays */ - stem_table = &hinter->hori_stems; - - for ( dimension = 2; dimension > 0; dimension-- ) - { - T1_Stem_Hint* cur = stem_table->stems; - T1_Stem_Hint* limit = cur + stem_table->num_stems; - - - for ( ; cur < limit; cur++ ) - cur->hint_flags &= ~T1_HINT_FLAG_ACTIVE; - - stem_table->num_active = 0; - stem_table = &hinter->vert_stems; - } - - return T1_Err_Ok; - } - - - const T1_Hinter_Funcs t1_hinter_funcs = - { - (T1_Hinter_ChangeHints)t1_hinter_changehints, - (T1_Hinter_DotSection) t1_hinter_ignore, - (T1_Hinter_Stem) t1_hinter_stem, - (T1_Hinter_Stem3) t1_hinter_stem3 - }; - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********** *********/ - /********** *********/ - /********** STEM HINTS MANAGEMENT *********/ - /********** *********/ - /********** The following code is in charge of computing *********/ - /********** the placement of each scaled stem hint. *********/ - /********** *********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* t1_sort_hints */ - /* */ - /* */ - /* Sorta the list of active stems in increasing order, through the */ - /* `sort' indexing table. */ - /* */ - /* */ - /* table :: A stem hints table. */ - /* */ - static - void t1_sort_hints( T1_Stem_Table* table ) - { - FT_Int num_stems = table->num_stems; - FT_Int num_active = 0; - FT_Int* sort = table->sort; - T1_Stem_Hint* stems = table->stems; - FT_Int n; - - - /* record active stems in sort table */ - for ( n = 0; n < num_stems; n++ ) - { - if ( stems[n].hint_flags & T1_HINT_FLAG_ACTIVE ) - sort[num_active++] = n; - } - - /* Now sort the indices. There are usually very few stems, */ - /* and they are pre-sorted in 90% cases, so we choose a */ - /* simple bubble sort (quicksort would be slower). */ - for ( n = 1; n < num_active; n++ ) - { - FT_Int p = n - 1; - T1_Stem_Hint* cur = stems + sort[n]; - - - do - { - FT_Int swap; - T1_Stem_Hint* prev = stems + sort[p]; - - - /* note that by definition, the active stems cannot overlap */ - /* so we simply compare their `min' to sort them (we could compare */ - /* their max values also; this wouldn't change anything). */ - if ( prev->min_edge.orus <= cur->min_edge.orus ) - break; - - /* swap elements */ - swap = sort[p ]; - sort[p ] = sort[p + 1]; - sort[p + 1] = swap; - p--; - - } while ( p >= 0 ); - } - - table->num_active = num_active; - } - - - /*************************************************************************/ - /* */ - /* */ - /* t1_hint_horizontal_stems */ - /* */ - /* */ - /* Computes the location of each scaled horizontal stem hint. This */ - /* takes care of the blue zones and the horizontal stem snap table. */ - /* */ - /* */ - /* table :: The horizontal stem hints table. */ - /* */ - /* hints :: The current size's hint structure. */ - /* */ - /* blueShift :: The value of the /BlueShift as taken from the face */ - /* object. */ - /* */ - /* scale :: The 16.16 scale used to convert outline units to */ - /* 26.6 pixels. */ - /* */ - /* */ - /* For now, all stems are hinted independently from each other. It */ - /* might be necessary, for better performance, to introduce the */ - /* notion of `controlled' hints describing things like counter-stems, */ - /* stem3, as well as overlapping stems control. */ - /* */ - static - void t1_hint_horizontal_stems( T1_Stem_Table* table, - T1_Size_Hints* hints, - FT_Pos blueShift, - FT_Fixed scale ) - { - T1_Stem_Hint* stem = table->stems; - T1_Stem_Hint* limit = stem + table->num_stems; - - - /* first of all, scale the blueShift */ - blueShift = SCALE( blueShift ); - - /* then scan the horizontal stem table */ - for ( ; stem < limit; stem++ ) - { - FT_Pos bottom_orus = stem->min_edge.orus; - FT_Pos top_orus = stem->max_edge.orus; - - FT_Pos top_pix = SCALE( top_orus ); - FT_Pos bottom_pix = SCALE( bottom_orus ); - FT_Pos width_pix = top_pix - bottom_pix; - - FT_Pos bottom = bottom_pix; - FT_Pos top = top_pix; - FT_Int align = T1_ALIGN_NONE; - - - /*********************************************************************/ - /* */ - /* Snap pixel width if in stem snap range */ - /* */ - - { - T1_Snap_Zone* zone = hints->snap_heights; - T1_Snap_Zone* zone_limit = zone + hints->num_snap_heights; - FT_Pos best_dist = 32000; - T1_Snap_Zone* best_zone = 0; - - - for ( ; zone < zone_limit; zone++ ) - { - FT_Pos dist; - - - dist = width_pix - zone->min; - if ( dist < 0 ) - dist = -dist; - if ( dist < best_dist ) - { - best_zone = zone; - best_dist = dist; - } - } - - if ( best_zone ) - { - if ( width_pix > best_zone->pix ) - { - width_pix -= 0x20; - if ( width_pix < best_zone->pix ) - width_pix = best_zone->pix; - } - else - { - width_pix += 0x20; - if ( width_pix > best_zone->pix ) - width_pix = best_zone->pix; - } - } - } - - /*********************************************************************/ - /* */ - /* round width - minimum 1 pixel if this isn't a ghost stem */ - /* */ - - if ( width_pix > 0 ) - width_pix = width_pix < ONE_PIXEL ? ONE_PIXEL : ROUND( width_pix ); - - - /*********************************************************************/ - /* */ - /* Now check for bottom blue zones alignement */ - /* */ - - { - FT_Int num_blues = hints->num_bottom_zones; - T1_Snap_Zone* blue = hints->blue_zones; - T1_Snap_Zone* blue_limit = blue + num_blues; - - - for ( ; blue < blue_limit; blue++ ) - { - if ( bottom_pix < blue->min ) - break; - - if ( bottom_pix <= blue->max ) - { - align = T1_ALIGN_BOTTOM; - bottom = ROUND( blue->pix ); - - /* implement blue shift */ - if ( !hints->supress_overshoots ) - { - FT_Pos delta = blue->pix - bottom_pix; - - - delta = delta < blueShift ? 0 : ROUND( delta ); - bottom -= delta; - } - } - } - } - - /*********************************************************************/ - /* */ - /* check for top blue zones alignement */ - /* */ - - { - FT_Int num_blues = hints->num_blue_zones - - hints->num_bottom_zones; - - T1_Snap_Zone* blue = hints->blue_zones + - hints->num_bottom_zones; - - T1_Snap_Zone* blue_limit = blue + num_blues; - - - for ( ; blue < blue_limit; blue++ ) - { - if ( top_pix < blue->min ) - break; - - if ( top_pix <= blue->max ) - { - align |= T1_ALIGN_TOP; - top = ROUND( blue->pix ); - - /* implement blue shift */ - if ( !hints->supress_overshoots ) - { - FT_Pos delta = top - blue->pix; - - - delta = delta < blueShift ? 0 : ROUND( delta ); - top += delta; - } - } - } - } - - /*********************************************************************/ - /* */ - /* compute the hinted stem position, according to its alignment */ - /* */ - - switch ( align ) - { - case T1_ALIGN_BOTTOM: /* bottom zone alignment */ - bottom_pix = bottom; - top_pix = bottom + width_pix; - break; - - case T1_ALIGN_TOP: /* top zone alignment */ - top_pix = top; - bottom_pix = top - width_pix; - break; - - case T1_ALIGN_BOTH: /* bottom+top zone alignment */ - bottom_pix = bottom; - top_pix = top; - break; - - default: /* no alignment */ - /* XXX TODO: Add management of controlled stems */ - bottom = ( SCALE( bottom_orus + top_orus ) - width_pix ) / 2; - - bottom_pix = ROUND( bottom ); - top_pix = bottom_pix + width_pix; - } - - stem->min_edge.pix = bottom_pix; - stem->max_edge.pix = top_pix; - } - } - - - /*************************************************************************/ - /* */ - /* */ - /* t1_hint_vertical_stems */ - /* */ - /* */ - /* Computes the location of each scaled vertical stem hint. This */ - /* takes care of the vertical stem snap table. */ - /* */ - /* */ - /* table :: The vertical stem hints table. */ - /* hints :: The current size's hint structure. */ - /* scale :: The 16.16 scale used to convert outline units to */ - /* 26.6 pixels. */ - /* */ - /* */ - /* For now, all stems are hinted independently from each other. It */ - /* might be necessary, for better performance, to introduce the */ - /* notion of `controlled' hints describing things like counter-stems, */ - /* stem3 as well as overlapping stems control. */ - /* */ - static - void t1_hint_vertical_stems( T1_Stem_Table* table, - T1_Size_Hints* hints, - FT_Fixed scale ) - { - T1_Stem_Hint* stem = table->stems; - T1_Stem_Hint* limit = stem + table->num_stems; - - - for ( ; stem < limit; stem++ ) - { - FT_Pos stem_left = stem->min_edge.orus; - FT_Pos stem_right = stem->max_edge.orus; - FT_Pos width_pix, left; - - - width_pix = SCALE( stem_right - stem_left ); - - /* Snap pixel width if in stem snap range */ - { - T1_Snap_Zone* zone = hints->snap_heights; - T1_Snap_Zone* zone_limit = zone + hints->num_snap_heights; - FT_Pos best_dist = 32000; - T1_Snap_Zone* best_zone = 0; - - - for ( ; zone < zone_limit; zone++ ) - { - FT_Pos dist; - - - dist = width_pix - zone->min; - if ( dist < 0 ) - dist = -dist; - if ( dist < best_dist ) - { - best_zone = zone; - best_dist = dist; - } - } - - if ( best_zone ) - { - if ( width_pix > best_zone->pix ) - { - width_pix -= 0x20; - if ( width_pix < best_zone->pix ) - width_pix = best_zone->pix; - } - else - { - width_pix += 0x20; - if ( width_pix > best_zone->pix ) - width_pix = best_zone->pix; - } - } - } - - /* round width - minimum 1 pixel if this isn't a ghost stem */ - if ( width_pix > 0 ) - width_pix = width_pix < ONE_PIXEL ? ONE_PIXEL - : ROUND( width_pix ); - - /* now place the snapped and rounded stem */ - - /* XXX TODO: implement controlled stems for the overlapping */ - /* cases */ - - left = ( SCALE( stem_left + stem_right ) - width_pix ) / 2; - - stem->min_edge.pix = ROUND( left ); - stem->max_edge.pix = stem->min_edge.pix + width_pix; - } - } - - - /*************************************************************************/ - /* */ - /* */ - /* t1_hint_point */ - /* */ - /* */ - /* Grid-fit a coordinate with regards to a given stem hints table. */ - /* */ - /* */ - /* table :: The source stem hints table. */ - /* coord :: The original coordinate, expressed in font units. */ - /* scale :: The 16.16 scale used to convert font units into */ - /* 26.6 pixels. */ - /* */ - /* */ - /* The hinted/scaled value in 26.6 pixels. */ - /* */ - /* */ - /* For now, all stems are hinted independently from each other. It */ - /* might be necessary, for better performance, to introduce the */ - /* notion of `controlled' hints describing things like counter-stems, */ - /* stem3 as well as overlapping stems control. */ - /* */ - static - FT_Pos t1_hint_point( T1_Stem_Table* table, - FT_Pos coord, - FT_Fixed scale ) - { - FT_Int num_active = table->num_active; - FT_Int n; - T1_Stem_Hint* prev = 0; - T1_Stem_Hint* cur = 0; - T1_Edge* min; - T1_Edge* max; - FT_Pos delta; - - - /* only hint when there is at least one stem defined */ - if ( num_active <= 0 ) - return SCALE( coord ); - - /* scan the stem table to determine placement of coordinate */ - /* relative to the list of sorted and stems */ - for ( n = 0; n < num_active; n++, prev = cur ) - { - cur = table->stems + table->sort[n]; - - /* is it on the left of the current edge? */ - delta = cur->min_edge.orus - coord; - if ( delta == 0 ) - return cur->min_edge.pix; - - if ( delta > 0 ) - { - /* if this is the left of the first edge, simply shift */ - if ( !prev ) - return cur->min_edge.pix - SCALE( delta ); - - /* otherwise, interpolate between the maximum of the */ - /* previous stem, and the minimum of the current one */ - min = &prev->max_edge; - max = &cur->min_edge; - - goto Interpolate; - } - - /* is it within the current edge? */ - delta = cur->max_edge.orus - coord; - if ( delta == 0 ) - return cur->max_edge.pix; - - if ( delta > 0 ) - { - /* interpolate within the stem */ - min = &cur->min_edge; - max = &cur->max_edge; - - goto Interpolate; - } - } - - /* apparently, this coordinate is on the right of the last stem */ - delta = coord - cur->max_edge.orus; - return cur->max_edge.pix + SCALE( delta ); - - Interpolate: - return min->pix + FT_MulDiv( coord - min->orus, - max->pix - min->pix, - max->orus - min->orus ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Hint_Points */ - /* */ - /* */ - /* This function grid-fits several points in a given Type 1 builder */ - /* at once. */ - /* */ - /* */ - /* builder :: A handle to target Type 1 builder. */ - /* */ - LOCAL_FUNC - void T1_Hint_Points( T1_Builder* builder ) - { - FT_Int first = builder->hint_point; - FT_Int last = builder->current->n_points - 1; - - T1_Size size = builder->size; - FT_Fixed scale_x = size->root.metrics.x_scale; - FT_Fixed scale_y = size->root.metrics.y_scale; - - T1_Glyph_Hints* hints = builder->glyph->hints; - T1_Stem_Table* hori_stems = &hints->hori_stems; - T1_Stem_Table* vert_stems = &hints->vert_stems; - - FT_Vector* cur = builder->current->points + first; - FT_Vector* limit = cur + last - first + 1; - - - /* first of all, sort the active stem hints */ - t1_sort_hints( hori_stems ); - t1_sort_hints( vert_stems ); - - for ( ; cur < limit; cur++ ) - { - cur->x = t1_hint_point( vert_stems, cur->x, scale_x ); - cur->y = t1_hint_point( hori_stems, cur->y, scale_y ); - } - - builder->hint_point = builder->current->n_points; - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Hint_Stems */ - /* */ - /* */ - /* This function is used to compute the location of each stem hint */ - /* between the first and second passes of the glyph loader on the */ - /* charstring. */ - /* */ - /* */ - /* builder :: A handle to the target builder. */ - /* */ - LOCAL_FUNC - void T1_Hint_Stems( T1_Builder* builder ) - { - T1_Glyph_Hints* hints = builder->glyph->hints; - T1_Private* priv = &builder->face->type1.private_dict; - - T1_Size size = builder->size; - FT_Fixed scale_x = size->root.metrics.x_scale; - FT_Fixed scale_y = size->root.metrics.y_scale; - - - t1_hint_horizontal_stems( &hints->hori_stems, - builder->size->hints, - priv->blue_shift, - scale_y ); - - t1_hint_vertical_stems( &hints->vert_stems, - builder->size->hints, - scale_x ); - } - - -/* END */ diff --git a/src/freetype/type1/t1hinter.h b/src/freetype/type1/t1hinter.h deleted file mode 100644 index a82882e097..0000000000 --- a/src/freetype/type1/t1hinter.h +++ /dev/null @@ -1,273 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1hinter.h */ -/* */ -/* Type 1 hinter (body). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifndef T1HINTER_H -#define T1HINTER_H - - -#ifdef FT_FLAT_COMPILE - -#include "t1objs.h" -#include "t1gload.h" - -#else - -#include -#include - -#endif - - -#ifdef __cplusplus - extern "C" { -#endif - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Snap_Zone */ - /* */ - /* */ - /* A `snap zone' is used to model either a blue zone or a stem width */ - /* at a given character size. It is made of a minimum and maximum */ - /* edge, defined in 26.6 pixels, as well as an `original' and */ - /* `scaled' position. */ - /* */ - /* The position corresponds to the stem width (for stem snap zones) */ - /* or to the blue position (for blue zones). */ - /* */ - /* */ - /* orus :: The original position in font units. */ - /* */ - /* pix :: The current position in sub-pixel units. */ - /* */ - /* min :: The minimum boundary in sub-pixel units. */ - /* */ - /* max :: The maximum boundary in sub-pixel units. */ - /* */ - typedef struct T1_Snap_Zone_ - { - FT_Pos orus; - FT_Pos pix; - FT_Pos min; - FT_Pos max; - - } T1_Snap_Zone; - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Edge */ - /* */ - /* */ - /* A very simple structure used to model a stem edge. */ - /* */ - /* */ - /* orus :: The original edge position in font units. */ - /* */ - /* pix :: The scaled edge position in sub-pixel units. */ - /* */ - typedef struct T1_Edge_ - { - FT_Pos orus; - FT_Pos pix; - - } T1_Edge; - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Stem_Hint */ - /* */ - /* */ - /* A simple structure used to model a stem hint. */ - /* */ - /* */ - /* min_edge :: The hint's minimum edge. */ - /* */ - /* max_edge :: The hint's maximum edge. */ - /* */ - /* hint_flags :: Some flags describing the stem properties. */ - /* */ - /* */ - /* The min and max edges of a ghost stem have the same position, even */ - /* if they are coded in a weird way in the charstrings. */ - /* */ - typedef struct T1_Stem_Hint_ - { - T1_Edge min_edge; - T1_Edge max_edge; - FT_Int hint_flags; - - } T1_Stem_Hint; - - -#define T1_HINT_FLAG_ACTIVE 1 /* indicates an active stem */ -#define T1_HINT_FLAG_MIN_BORDER 2 /* unused for now */ -#define T1_HINT_FLAG_MAX_BORDER 4 /* unused for now */ - - /* hinter's configuration constants */ -#define T1_HINTER_MAX_BLUES 24 /* maximum number of blue zones */ -#define T1_HINTER_MAX_SNAPS 16 /* maximum number of stem snap zones */ -#define T1_HINTER_MAX_EDGES 64 /* maximum number of stem hints */ - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Size_Hints */ - /* */ - /* */ - /* A structure used to model the hinting information related to a size */ - /* object. */ - /* */ - /* */ - /* supress_overshoots :: A boolean flag to tell whether overshoot */ - /* supression should occur. */ - /* */ - /* num_blue_zones :: The total number of blue zones (top+bottom). */ - /* */ - /* num_bottom_zones :: The number of bottom zones. */ - /* */ - /* blue_zones :: The blue zones table. Bottom zones are */ - /* stored first in the table, followed by all */ - /* top zones. */ - /* */ - /* num_snap_widths :: The number of horizontal stem snap zones. */ - /* */ - /* snap_widths :: An array of horizontal stem snap zones. */ - /* */ - /* num_snap_heights :: The number of vertical stem snap zones. */ - /* */ - /* snap_heights :: An array of vertical stem snap zones. */ - /* */ - struct T1_Size_Hints_ - { - FT_Bool supress_overshoots; - - FT_Int num_blue_zones; - FT_Int num_bottom_zones; - T1_Snap_Zone blue_zones[T1_HINTER_MAX_BLUES]; - - FT_Int num_snap_widths; - T1_Snap_Zone snap_widths[T1_HINTER_MAX_SNAPS]; - - FT_Int num_snap_heights; - T1_Snap_Zone snap_heights[T1_HINTER_MAX_SNAPS]; - }; - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Stem_Table */ - /* */ - /* */ - /* A simple structure used to model a set of stem hints in a single */ - /* direction during the loading of a given glyph outline. Not all */ - /* stem hints are active at a time. Moreover, stems must be sorted */ - /* regularly. */ - /* */ - /* */ - /* num_stems :: The total number of stems in the table. */ - /* */ - /* num_active :: The number of active stems in the table. */ - /* */ - /* stems :: A table of all stems. */ - /* */ - /* sort :: A table of indices into the stems table, used to */ - /* keep a sorted list of the active stems. */ - /* */ - typedef struct T1_Stem_Table_ - { - FT_Int num_stems; - FT_Int num_active; - - T1_Stem_Hint stems[T1_HINTER_MAX_EDGES]; - FT_Int sort [T1_HINTER_MAX_EDGES]; - - } T1_Stem_Table; - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Glyph_Hints */ - /* */ - /* */ - /* A structure used to model the stem hints of a given glyph outline */ - /* during glyph loading. */ - /* */ - /* */ - /* hori_stems :: The horizontal stem hints table. */ - /* vert_stems :: The vertical stem hints table. */ - /* */ - struct T1_Glyph_Hints_ - { - T1_Stem_Table hori_stems; - T1_Stem_Table vert_stems; - }; - - - /*************************************************************************/ - /* */ - /* */ - /* t1_hinter_funcs */ - /* */ - /* */ - /* A table containing the address of various functions used during */ - /* the loading of an hinted scaled outline. */ - /* */ - extern const T1_Hinter_Funcs t1_hinter_funcs; - - - LOCAL_DEF - FT_Error T1_New_Size_Hinter( T1_Size size ); - - LOCAL_DEF - void T1_Done_Size_Hinter( T1_Size size ); - - LOCAL_DEF - FT_Error T1_Reset_Size_Hinter( T1_Size size ); - - LOCAL_DEF - FT_Error T1_New_Glyph_Hinter( T1_GlyphSlot glyph ); - - LOCAL_DEF - void T1_Done_Glyph_Hinter( T1_GlyphSlot glyph ); - - - LOCAL_DEF - void T1_Hint_Points( T1_Builder* builder ); - - LOCAL_DEF - void T1_Hint_Stems( T1_Builder* builder ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* T1HINTER_H */ - - -/* END */ diff --git a/src/freetype/type1/t1load.c b/src/freetype/type1/t1load.c deleted file mode 100644 index 00a56a2463..0000000000 --- a/src/freetype/type1/t1load.c +++ /dev/null @@ -1,1594 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1load.c */ -/* */ -/* Type 1 font loader (body). */ -/* */ -/* 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 -#include -#include - - -#ifdef FT_FLAT_COMPILE - -#include "t1tokens.h" -#include "t1parse.h" - -#else - -#include -#include - -#endif - - -#include - -#include /* for strncpy(), strncmp(), strlen() */ - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_t1load - - - typedef FT_Error (*T1_Parse_Func)( T1_Parser* parser ); - - - /*************************************************************************/ - /* */ - /* */ - /* Init_T1_Parser */ - /* */ - /* */ - /* Initializes a given parser object to build a given T1_Face. */ - /* */ - /* */ - /* parser :: A handle to the newly built parser object. */ - /* */ - /* */ - /* face :: A handle to the target Type 1 face object. */ - /* */ - /* tokenizer :: A handle to the target Type 1 token manager. */ - /* */ - LOCAL_FUNC - void Init_T1_Parser( T1_Parser* parser, - T1_Face face, - T1_Tokenizer tokenizer ) - { - parser->error = 0; - parser->face = face; - parser->tokenizer = tokenizer; - parser->top = parser->stack; - parser->limit = parser->stack + T1_MAX_STACK_DEPTH; - - parser->state_index = 0; - parser->state_stack[0] = dict_none; - - parser->encoding_type = t1_encoding_none; - parser->encoding_names = 0; - parser->encoding_offsets = 0; - parser->encoding_lengths = 0; - - parser->dump_tokens = 0; - face->type1.private_dict.lenIV = 4; /* XXX : is it sure? */ - } - - - /*************************************************************************/ - /* */ - /* */ - /* Next_T1_Token */ - /* */ - /* */ - /* Grabs the next significant token from a parser's input stream. */ - /* This function ignores a number of tokens, and translates */ - /* alternate forms into their common ones. */ - /* */ - /* */ - /* parser :: A handle to the source parser. */ - /* */ - /* */ - /* token :: The extracted token descriptor. */ - /* */ - /* */ - /* FreeTyoe error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error Next_T1_Token( T1_Parser* parser, - T1_Token* token ) - { - FT_Error error; - T1_Tokenizer tokzer = parser->tokenizer; - - - L1: - error = Read_Token( tokzer ); - if ( error ) - return error; - - /* we now must ignore a number of tokens like `dup', `executeonly', */ - /* `readonly', etc. */ - *token = tokzer->token; - if ( token->kind == tok_keyword ) - switch( token->kind2 ) - { - case key_dup: - case key_execonly: - case key_readonly: - case key_noaccess: - case key_userdict: - /* do nothing - loop */ - goto L1; - - /* we also translate some other keywords from their alternative */ - /* to their `normal' form */ - - case key_NP_alternate: - token->kind2 = key_NP; - break; - - case key_RD_alternate: - token->kind2 = key_RD; - break; - - case key_ND_alternate: - token->kind2 = key_ND; - break; - - default: - ; - } - -#if defined( FT_DEBUG_LEVEL_ERROR ) || defined( FT_DEBUG_LEVEL_TRACE ) - - /* Dump the token when requested. This feature is only available */ - /* in the `error' and `trace' debug levels. */ - if ( parser->dump_tokens ) - { - FT_String temp_string[128]; - FT_Int len; - - - len = token->len; - if ( len > 127 ) - len = 127; - strncpy( temp_string, - (FT_String*)tokzer->base + token->start, - len ); - temp_string[len] = '\0'; - FT_ERROR(( "%s\n", temp_string )); - } - -#endif /* FT_DEBUG_LEVEL_ERROR or FT_DEBUG_LEVEL_TRACE */ - - return T1_Err_Ok; - } - - - static - FT_Error Expect_Keyword( T1_Parser* parser, - T1_TokenType keyword ) - { - T1_Token token; - FT_Error error; - - - error = Next_T1_Token( parser, &token ); - if ( error ) - goto Exit; - - if ( token.kind != tok_keyword || - token.kind2 != keyword ) - { - error = T1_Err_Syntax_Error; - FT_ERROR(( "Expect_Keyword: keyword `%s' expected.\n", - t1_keywords[keyword - key_first_] )); - } - - Exit: - return error; - } - - - static - FT_Error Expect_Keyword2( T1_Parser* parser, - T1_TokenType keyword1, - T1_TokenType keyword2 ) - { - T1_Token token; - FT_Error error; - - - error = Next_T1_Token( parser, &token ); - if ( error ) - goto Exit; - - if ( token.kind != tok_keyword || - ( token.kind2 != keyword1 && - token.kind2 != keyword2 ) ) - { - error = T1_Err_Syntax_Error; - FT_ERROR(( "Expect_Keyword2: keyword `%s' or `%s' expected.\n", - t1_keywords[keyword1 - key_first_], - t1_keywords[keyword2 - key_first_] )); - } - - Exit: - return error; - } - - - static - void Parse_Encoding( T1_Parser* parser ) - { - T1_Token* token = parser->top+1; - FT_Memory memory = parser->face->root.memory; - T1_Encoding* encode = &parser->face->type1.encoding; - FT_Error error = 0; - - - if ( token->kind == tok_keyword && - ( token->kind2 == key_StandardEncoding || - token->kind2 == key_ExpertEncoding ) ) - { - encode->num_chars = 256; - encode->code_first = 32; - encode->code_last = 255; - - if ( ALLOC_ARRAY( encode->char_index, 256, FT_Short ) ) - goto Exit; - - encode->char_name = 0; /* no need to store glyph names */ - - /* Now copy the encoding */ - switch ( token->kind2 ) - { - case key_ExpertEncoding: - parser->encoding_type = t1_encoding_expert; - break; - - default: - parser->encoding_type = t1_encoding_standard; - break; - } - } - else - { - FT_ERROR(( "Parse_Encoding: invalid encoding type\n" )); - error = T1_Err_Syntax_Error; - } - - Exit: - parser->error = error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* IMPLEMENTATION OF THE `DEF' KEYWORD DEPENDING ON */ - /* CURRENT DICTIONARY STATE */ - /* */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* Do_Def_Font */ - /* */ - /* */ - /* This function performs a `def' if in the Font dictionary. Its */ - /* purpose is to build the T1_Face attributes directly from the */ - /* stream. */ - /* */ - /* */ - /* parser :: A handle to the current parser. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error Do_Def_Font( T1_Parser* parser ) - { - T1_Token* top = parser->top; - T1_Face face = parser->face; - T1_Font* type1 = &face->type1; - - - switch ( top[0].kind2 ) - { - case imm_FontName: - /* in some cases, the /FontName is an immediate like */ - /* /TimesNewRoman. In this case, we simply copy the */ - /* token string (without the /). */ - if ( top[1].kind == tok_immediate ) - { - FT_Memory memory = parser->tokenizer->memory; - FT_Error error; - FT_Int len = top[1].len; - - - if ( ALLOC( type1->font_name, len + 1 ) ) - { - parser->error = error; - return error; - } - - MEM_Copy( type1->font_name, - parser->tokenizer->base + top[1].start, - len ); - type1->font_name[len] = '\0'; - } - else - type1->font_name = CopyString( parser ); - break; - - case imm_Encoding: - Parse_Encoding( parser ); - break; - - case imm_PaintType: - type1->paint_type = (FT_Byte)CopyInteger( parser ); - break; - - case imm_FontType: - type1->font_type = (FT_Byte)CopyInteger( parser ); - break; - - case imm_FontMatrix: - CopyMatrix( parser, &type1->font_matrix ); - break; - - case imm_FontBBox: - CopyBBox( parser, &type1->font_bbox ); - break; - - case imm_UniqueID: - type1->private_dict.unique_id = CopyInteger( parser ); - break; - - case imm_StrokeWidth: - type1->stroke_width = CopyInteger( parser ); - break; - - case imm_FontID: - type1->font_id = CopyInteger( parser ); - break; - - default: - /* ignore all other things */ - parser->error = T1_Err_Ok; - } - - return parser->error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Do_Def_FontInfo */ - /* */ - /* */ - /* This function performs a `def' if in the FontInfo dictionary. Its */ - /* purpose is to build the T1_FontInfo structure directly from the */ - /* stream. */ - /* */ - /* */ - /* parser :: A handle to the current parser. */ - /* */ - /* */ - /* FreeTyoe error code. 0 means success. */ - /* */ - static - FT_Error Do_Def_FontInfo( T1_Parser* parser ) - { - T1_Token* top = parser->top; - T1_FontInfo* info = &parser->face->type1.font_info; - - - switch ( top[0].kind2 ) - { - case imm_version: - info->version = CopyString( parser ); - break; - - case imm_Notice: - info->notice = CopyString( parser ); - break; - - case imm_FullName: - info->full_name = CopyString( parser ); - break; - - case imm_FamilyName: - info->family_name = CopyString( parser ); - break; - - case imm_Weight: - info->weight = CopyString( parser ); - break; - - case imm_ItalicAngle: - info->italic_angle = CopyInteger( parser ); - break; - - case imm_isFixedPitch: - info->is_fixed_pitch = CopyBoolean( parser ); - break; - - case imm_UnderlinePosition: - info->underline_position = (FT_Short)CopyInteger( parser ); - break; - - case imm_UnderlineThickness: - info->underline_thickness = (FT_Short)CopyInteger( parser ); - break; - - default: - /* ignore all other things */ - parser->error = T1_Err_Ok; - } - - return parser->error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Do_Def_Private */ - /* */ - /* */ - /* This function performs a `def' if in the Private dictionary. Its */ - /* purpose is to build the T1_Private structure directly from the */ - /* stream. */ - /* */ - /* */ - /* parser :: A handle to the current parser. */ - /* */ - /* */ - /* FreeTyoe error code. 0 means success. */ - /* */ - static - FT_Error Do_Def_Private( T1_Parser* parser ) - { - T1_Token* top = parser->top; - T1_Private* priv = &parser->face->type1.private_dict; - - - switch ( top[0].kind2 ) - { - /* Ignore the definitions of RD, NP, ND, and their alternate forms */ - case imm_RD: - case imm_RD_alternate: - case imm_ND: - case imm_ND_alternate: - case imm_NP: - case imm_NP_alternate: - parser->error = T1_Err_Ok; - break; - - case imm_BlueValues: - CopyArray( parser, &priv->num_blue_values, - priv->blue_values, 14 ); - break; - - case imm_OtherBlues: - CopyArray( parser, &priv->num_other_blues, - priv->other_blues, 10 ); - break; - - case imm_FamilyBlues: - CopyArray( parser, &priv->num_family_blues, - priv->family_blues, 14 ); - break; - - case imm_FamilyOtherBlues: - CopyArray( parser, &priv->num_family_other_blues, - priv->family_other_blues, 10 ); - break; - - case imm_BlueScale: - priv->blue_scale = CopyFloat( parser, 0x10000L ); - break; - - case imm_BlueShift: - priv->blue_shift = CopyInteger( parser ); - break; - - case imm_BlueFuzz: - priv->blue_fuzz = CopyInteger( parser ); - break; - - case imm_StdHW: - CopyArray( parser, 0, (FT_Short*)&priv->standard_width, 1 ); - break; - - case imm_StdVW: - CopyArray( parser, 0, (FT_Short*)&priv->standard_height, 1 ); - break; - - case imm_StemSnapH: - CopyArray( parser, &priv->num_snap_widths, - priv->snap_widths, 12 ); - break; - - case imm_StemSnapV: - CopyArray( parser, &priv->num_snap_heights, - priv->snap_heights, 12 ); - break; - - case imm_ForceBold: - priv->force_bold = CopyBoolean( parser ); - break; - - case imm_LanguageGroup: - priv->language_group = CopyInteger( parser ); - break; - - case imm_password: - priv->password = CopyInteger( parser ); - break; - - case imm_UniqueID: - priv->unique_id = CopyInteger( parser ); - break; - - case imm_lenIV: - priv->lenIV = CopyInteger( parser ); - break; - - case imm_MinFeature: - CopyArray( parser, 0, priv->min_feature, 2 ); - break; - - default: - /* ignore all other things */ - parser->error = T1_Err_Ok; - } - - return parser->error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Do_Def_Error */ - /* */ - /* */ - /* This function returns a simple syntax error when invoked. It is */ - /* used for the `def' keyword if in the `encoding', `subrs', */ - /* `othersubrs', and `charstrings' dictionary states. */ - /* */ - /* */ - /* parser :: A handle to the current parser. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error Do_Def_Error( T1_Parser* parser ) - { - FT_ERROR(( "Do_Def_Error:" )); - FT_ERROR(( " `def' keyword encountered in bad dictionary/array\n" )); - - parser->error = T1_Err_Syntax_Error; - - return parser->error; - } - - - static - FT_Error Do_Def_Ignore( T1_Parser* parser ) - { - FT_UNUSED( parser ); - return T1_Err_Ok; - } - - - static - T1_Parse_Func def_funcs[dict_max] = - { - Do_Def_Error, - Do_Def_Font, - Do_Def_FontInfo, - Do_Def_Ignore, - Do_Def_Private, - Do_Def_Ignore, - Do_Def_Ignore, - Do_Def_Ignore, - Do_Def_Ignore, - Do_Def_Ignore, - Do_Def_Ignore, - }; - - - /*************************************************************************/ - /* */ - /* */ - /* IMPLEMENTATION OF THE `PUT' KEYWORD DEPENDING ON */ - /* CURRENT DICTIONARY STATE */ - /* */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* Do_Put_Encoding */ - /* */ - /* */ - /* This function performs a `put' if in the Encoding array. The */ - /* glyph name is copied into the T1 recorder, and the charcode and */ - /* glyph name pointer are written into the face object encoding. */ - /* */ - /* */ - /* parser :: A handle to the current parser. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error Do_Put_Encoding( T1_Parser* parser ) - { - FT_Error error = T1_Err_Ok; - T1_Face face = parser->face; - T1_Token* top = parser->top; - T1_Encoding* encode = &face->type1.encoding; - FT_Int index; - - - /* record and check the character code */ - if ( top[0].kind != tok_number ) - { - FT_TRACE4(( "Do_Put_Encoding: number expected\n" )); - goto Syntax_Error; - } - index = (FT_Int)CopyInteger( parser ); - if ( parser->error ) - return parser->error; - - if ( index < 0 || index >= encode->num_chars ) - { - FT_TRACE4(( "Do_Put_Encoding: invalid character code\n" )); - goto Syntax_Error; - } - - /* record the immediate name */ - if ( top[1].kind != tok_immediate ) - { - FT_TRACE4(( "Do_Put_Encoding: immediate name expected\n" )); - goto Syntax_Error; - } - - /* if the glyph name is `.notdef', store a NULL char name; */ - /* otherwise, record the glyph name */ - if ( top[1].kind == imm_notdef ) - { - parser->table.elements[index] = 0; - parser->table.lengths [index] = 0; - } - else - { - FT_String temp_name[128]; - T1_Token* token = top + 1; - FT_Int len = token->len - 1; - - - /* copy immediate name */ - if ( len > 127 ) - len = 127; - MEM_Copy( temp_name, parser->tokenizer->base + token->start + 1, len ); - temp_name[len] = '\0'; - - error = T1_Add_Table( &parser->table, index, - (FT_Byte*)temp_name, len + 1 ); - - /* adjust code_first and code_last */ - if ( index < encode->code_first ) encode->code_first = index; - if ( index > encode->code_last ) encode->code_last = index; - } - return error; - - Syntax_Error: - /* ignore the error, and simply clear the stack */ - FT_TRACE4(( "Do_Put_Encoding: invalid syntax encountered\n" )); - parser->top = parser->stack; - - return T1_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* IMPLEMENTATION OF THE "RD" KEYWORD DEPENDING ON */ - /* CURRENT DICTIONARY STATE */ - /* */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* Do_RD_Subrs */ - /* */ - /* */ - /* This function performs an `RD' if in the Subrs dictionary. It */ - /* simply records the array of bytecodes/charstrings corresponding to */ - /* the sub-routine. */ - /* */ - /* */ - /* parser :: A handle to the current parser. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error Do_RD_Subrs( T1_Parser* parser ) - { - FT_Error error = T1_Err_Ok; - T1_Face face = parser->face; - T1_Token* top = parser->top; - T1_Tokenizer tokzer = parser->tokenizer; - FT_Int index, count; - - - /* record and check the character code */ - if ( top[0].kind != tok_number || - top[1].kind != tok_number ) - { - FT_ERROR(( "Do_RD_Subrs: number expected\n" )); - goto Syntax_Error; - } - index = (FT_Int)CopyInteger( parser ); - error = parser->error; - if ( error ) - goto Exit; - - count = (FT_Int)CopyInteger( parser ); - error = parser->error; - if ( error ) - goto Exit; - - if ( index < 0 || index >= face->type1.num_subrs ) - { - FT_ERROR(( "Do_RD_Subrs: invalid character code\n" )); - goto Syntax_Error; - } - - /* decrypt charstring and skip it */ - { - FT_Byte* base = tokzer->base + tokzer->cursor; - - - tokzer->cursor += count; - - /* some fonts use a value of -1 for lenIV to indicate that */ - /* the charstrings are unencoded. */ - /* */ - /* Thanks to Tom Kacvinsky for pointing this out. */ - /* */ - if ( face->type1.private_dict.lenIV >= 0 ) - { - t1_decrypt( base, count, 4330 ); - - base += face->type1.private_dict.lenIV; - count -= face->type1.private_dict.lenIV; - } - - error = T1_Add_Table( &parser->table, index, base, count ); - } - - /* consume the closing NP or `put' */ - error = Expect_Keyword2( parser, key_NP, key_put ); - - Exit: - return error; - - Syntax_Error: - return T1_Err_Syntax_Error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Do_RD_CharStrings */ - /* */ - /* */ - /* This function performs an `RD' if in the CharStrings dictionary. */ - /* It simply records the array of bytecodes/charstrings corresponding */ - /* to the glyph program string. */ - /* */ - /* */ - /* parser :: A handle to the current parser. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error Do_RD_Charstrings( T1_Parser* parser ) - { - FT_Error error = T1_Err_Ok; - T1_Face face = parser->face; - T1_Token* top = parser->top; - T1_Tokenizer tokzer = parser->tokenizer; - FT_Int index, count; - - - /* check the character name argument */ - if ( top[0].kind != tok_immediate ) - { - FT_ERROR(( "Do_RD_Charstrings: immediate character name expected\n" )); - goto Syntax_Error; - } - - /* check the count argument */ - if ( top[1].kind != tok_number ) - { - FT_ERROR(( "Do_RD_Charstrings: number expected\n" )); - goto Syntax_Error; - } - - parser->args++; - count = (FT_Int)CopyInteger( parser ); - error = parser->error; - if ( error ) - goto Exit; - - /* record the glyph name and get the corresponding glyph index */ - if ( top[0].kind2 == imm_notdef ) - index = 0; - else - { - FT_String temp_name[128]; - T1_Token* token = top; - FT_Int len = token->len - 1; - - - /* copy immediate name */ - if ( len > 127 ) - len = 127; - MEM_Copy( temp_name, parser->tokenizer->base + token->start + 1, len ); - temp_name[len] = '\0'; - - index = parser->cur_name++; - error = T1_Add_Table( &parser->table, index * 2, - (FT_Byte*)temp_name, len + 1 ); - if ( error ) - goto Exit; - } - - /* decrypt and record charstring, then skip them */ - { - FT_Byte* base = tokzer->base + tokzer->cursor; - - - tokzer->cursor += count; /* skip */ - - if ( face->type1.private_dict.lenIV >= 0 ) - { - t1_decrypt( base, count, 4330 ); - - base += face->type1.private_dict.lenIV; - count -= face->type1.private_dict.lenIV; - } - - error = T1_Add_Table( &parser->table, index * 2 + 1, base, count ); - } - - /* consume the closing `ND' */ - if ( !error ) - error = Expect_Keyword( parser, key_ND ); - - Exit: - return error; - - Syntax_Error: - return T1_Err_Syntax_Error; - } - - - static - FT_Error Expect_Dict_Arguments( T1_Parser* parser, - FT_Int num_args, - T1_TokenType immediate, - T1_DictState new_state, - FT_Int* count ) - { - /* check that we have enough arguments in the stack, including */ - /* the `dict' keyword */ - if ( parser->top - parser->stack < num_args ) - { - FT_ERROR(( "Expect_Dict_Arguments: expecting at least %d arguments", - num_args )); - goto Syntax_Error; - } - - /* check that we have the correct immediate, if needed */ - if ( num_args == 2 ) - { - if ( parser->top[-2].kind != tok_immediate || - parser->top[-2].kind2 != immediate ) - { - FT_ERROR(( "Expect_Dict_Arguments: expecting `/%s' dictionary\n", - t1_immediates[immediate - imm_first_] )); - goto Syntax_Error; - } - } - - parser->args = parser->top-1; - - /* check that the count argument is a number */ - if ( parser->args->kind != tok_number ) - { - FT_ERROR(( "Expect_Dict_Arguments:" )); - FT_ERROR(( " expecting numerical count argument for `dict'\n" )); - goto Syntax_Error; - } - - if ( count ) - { - *count = CopyInteger( parser ); - if ( parser->error ) - return parser->error; - } - - /* save the dictionary state */ - parser->state_stack[++parser->state_index] = new_state; - - /* consume the `begin' keyword and clear the stack */ - parser->top -= num_args; - return Expect_Keyword( parser, key_begin ); - - Syntax_Error: - return T1_Err_Syntax_Error; - } - - - static - FT_Error Expect_Array_Arguments( T1_Parser* parser ) - { - T1_Token* top = parser->top; - FT_Error error = T1_Err_Ok; - T1_DictState new_state; - FT_Int count; - T1_Face face = parser->face; - FT_Memory memory = face->root.memory; - - - /* Check arguments format */ - if ( top - parser->stack < 2 ) - { - FT_ERROR(( "Expect_Array_Arguments: two arguments expected\n" )); - error = T1_Err_Stack_Underflow; - goto Exit; - } - - parser->top -= 2; - top -= 2; - parser->args = top + 1; - - if ( top[0].kind != tok_immediate ) - { - FT_ERROR(( "Expect_Array_Arguments:" )); - FT_ERROR(( " first argument must be an immediate name\n" )); - goto Syntax_Error; - } - - if ( top[1].kind != tok_number ) - { - FT_ERROR(( "Expect_Array_Arguments:" )); - FT_ERROR(( " second argument must be a number\n" )); - goto Syntax_Error; - } - - count = (FT_Int)CopyInteger( parser ); - - /* Is this an array we know about? */ - switch ( top[0].kind2 ) - { - case imm_Encoding: - { - T1_Encoding* encode = &face->type1.encoding; - - - new_state = dict_encoding; - - encode->code_first = count; - encode->code_last = 0; - encode->num_chars = count; - - /* Allocate the table of character indices. The table of */ - /* character names is allocated through init_t1_recorder(). */ - if ( ALLOC_ARRAY( encode->char_index, count, FT_Short ) ) - return error; - - error = T1_New_Table( &parser->table, count, memory ); - if ( error ) - goto Exit; - - parser->encoding_type = t1_encoding_array; - } - break; - - case imm_Subrs: - new_state = dict_subrs; - face->type1.num_subrs = count; - - error = T1_New_Table( &parser->table, count, memory ); - if ( error ) - goto Exit; - break; - - case imm_CharStrings: - new_state = dict_charstrings; - break; - - default: - new_state = dict_unknown_array; - } - - parser->state_stack[++parser->state_index] = new_state; - - Exit: - return error; - - Syntax_Error: - return T1_Err_Syntax_Error; - } - - - static - FT_Error Finalize_Parsing( T1_Parser* parser ) - { - T1_Face face = parser->face; - T1_Font* type1 = &face->type1; - FT_Memory memory = face->root.memory; - T1_Table* strings = &parser->table; - PSNames_Interface* psnames = (PSNames_Interface*)face->psnames; - - FT_Int num_glyphs; - FT_Int n; - FT_Error error; - - - num_glyphs = type1->num_glyphs = parser->cur_name; - - /* allocate glyph names and charstrings arrays */ - if ( ALLOC_ARRAY( type1->glyph_names, num_glyphs, FT_String* ) || - ALLOC_ARRAY( type1->charstrings, num_glyphs, FT_Byte* ) || - ALLOC_ARRAY( type1->charstrings_len, num_glyphs, FT_Int* ) ) - return error; - - /* copy glyph names and charstrings offsets and lengths */ - type1->charstrings_block = strings->block; - for ( n = 0; n < num_glyphs; n++ ) - { - type1->glyph_names[n] = (FT_String*)strings->elements[2 * n]; - type1->charstrings[n] = strings->elements[2 * n + 1]; - type1->charstrings_len[n] = strings->lengths [2 * n + 1]; - } - - /* now free the old tables */ - FREE( strings->elements ); - FREE( strings->lengths ); - - if ( !psnames ) - { - FT_ERROR(( "Finalize_Parsing: `PSNames' module missing!\n" )); - return T1_Err_Unimplemented_Feature; - } - - /* compute encoding if required */ - if ( parser->encoding_type == t1_encoding_none ) - { - FT_ERROR(( "Finalize_Parsing: no encoding specified in font file\n" )); - return T1_Err_Syntax_Error; - } - - { - FT_Int n; - T1_Encoding* encode = &type1->encoding; - - - encode->code_first = encode->num_chars - 1; - encode->code_last = 0; - - for ( n = 0; n < encode->num_chars; n++ ) - { - FT_String** names; - FT_Int index; - FT_Int m; - - - switch ( parser->encoding_type ) - { - case t1_encoding_standard: - index = psnames->adobe_std_encoding[n]; - names = 0; - break; - - case t1_encoding_expert: - index = psnames->adobe_expert_encoding[n]; - names = 0; - break; - - default: - index = n; - names = (FT_String**)parser->encoding_offsets; - } - - encode->char_index[n] = 0; - - if ( index ) - { - FT_String* name; - - - if ( names ) - name = names[index]; - else - name = (FT_String*)psnames->adobe_std_strings(index); - - if ( name ) - { - FT_Int len = strlen( name ); - - - /* lookup glyph index from name */ - for ( m = 0; m < num_glyphs; m++ ) - { - if ( strncmp( type1->glyph_names[m], name, len ) == 0 ) - { - encode->char_index[n] = m; - break; - } - } - - if ( n < encode->code_first ) encode->code_first = n; - if ( n > encode->code_last ) encode->code_last = n; - } - } - } - - parser->encoding_type = t1_encoding_none; - - FREE( parser->encoding_names ); - FREE( parser->encoding_lengths ); - FREE( parser->encoding_offsets ); - } - - return T1_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Parse_T1_FontProgram */ - /* */ - /* */ - /* Parses a given Type 1 font file and builds its face object. */ - /* */ - /* */ - /* parser :: A handle to the target parser object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The parser contains a handle to the target face object. */ - /* */ - LOCAL_FUNC - FT_Error Parse_T1_FontProgram( T1_Parser* parser ) - { - FT_Error error; - T1_Font* type1 = &parser->face->type1; - - - for (;;) - { - T1_Token token; - T1_Token* top; - T1_DictState dict_state; - FT_Int dict_index; - - - error = Next_T1_Token( parser, &token ); - top = parser->top; - dict_index = parser->state_index; - dict_state = parser->state_stack[dict_index]; - - switch ( token.kind ) - { - /* a keyword has been detected */ - case tok_keyword: - switch ( token.kind2 ) - { - case key_dict: - switch ( dict_state ) - { - case dict_none: - /* All right, we are beginning the font dictionary. */ - /* Check that we only have one number argument, then */ - /* consume the `begin' and change to `dict_font' */ - /* state. */ - error = Expect_Dict_Arguments( parser, 1, tok_error, - dict_font, 0 ); - if ( error ) - goto Exit; - - /* clear stack from all the previous content. This */ - /* could be some stupid Postscript code. */ - parser->top = parser->stack; - break; - - case dict_font: - /* This must be the /FontInfo dictionary, so check */ - /* that we have at least two arguments, that they */ - /* are `/FontInfo' and a number, then change the */ - /* dictionary state. */ - error = Expect_Dict_Arguments( parser, 2, imm_FontInfo, - dict_fontinfo, 0 ); - if ( error ) - goto Exit; - break; - - case dict_none2: - error = Expect_Dict_Arguments( parser, 2, imm_Private, - dict_private, 0 ); - if ( error ) - goto Exit; - break; - - case dict_private: - { - T1_Face face = parser->face; - FT_Int count; - - - error = Expect_Dict_Arguments( parser, 2, imm_CharStrings, - dict_charstrings, &count ); - if ( error ) - goto Exit; - - type1->num_glyphs = count; - error = T1_New_Table( &parser->table, count * 2, - face->root.memory ); - if ( error ) - goto Exit; - - /* record `.notdef' as the first glyph in the font */ - error = T1_Add_Table( &parser->table, 0, - (FT_Byte*)".notdef", 8 ); - parser->cur_name = 1; - /* XXX: DO SOMETHING HERE */ - } - break; - - default: - /* All other uses are invalid */ - FT_ERROR(( "Parse_T1_FontProgram:" )); - FT_ERROR(( " invalid use of `dict' keyword\n" )); - goto Syntax_Error; - } - break; - - case key_array: - /* Are we in an array yet? If so, raise an error */ - switch ( dict_state ) - { - case dict_encoding: - case dict_subrs: - case dict_othersubrs: - case dict_charstrings: - case dict_unknown_array: - FT_ERROR(( "Parse_T1_FontProgram: nested array definitions\n" )); - goto Syntax_Error; - - default: - ; - } - error = Expect_Array_Arguments( parser ); - if ( error ) - goto Exit; - break; - - case key_ND: - case key_NP: - case key_def: - /* Are we in an array? If so, finalize it. */ - switch ( dict_state ) - { - case dict_encoding: /* finish encoding array */ - /* copy table names to the face object */ - T1_Done_Table( &parser->table ); - - parser->encoding_names = parser->table.block; - parser->encoding_lengths = parser->table.lengths; - parser->encoding_offsets = parser->table.elements; - - parser->state_index--; - break; - - case dict_subrs: - /* copy recorder sub-routines */ - T1_Done_Table( &parser->table ); - - parser->subrs = parser->table.block; - type1->subrs = parser->table.elements; - type1->subrs_len = parser->table.lengths; - type1->subrs_block = parser->table.block; - - parser->state_index--; - break; - - case dict_charstrings: - case dict_othersubrs: - case dict_unknown_array: - FT_ERROR(( "Parse_T1_FontProgram: unsupported array\n" )); - goto Syntax_Error; - break; - - default: /* normal `def' processing */ - /* Check that we have sufficient operands in the stack */ - if ( top >= parser->stack + 2 ) - { - /* Now check that the first operand is an immediate. */ - /* If so, call the appropriate `def' routine based */ - /* on the current parser state. */ - if ( top[-2].kind == tok_immediate ) - { - parser->top -= 2; - parser->args = parser->top + 1; - error = def_funcs[dict_state](parser); - } - else - { - /* This is an error, but some fonts contain */ - /* stupid Postscript code. We simply ignore */ - /* an invalid `def' by clearing the stack. */ -#if 0 - FT_ERROR(( "Parse_T1_FontProgram: immediate expected\n" )); - goto Syntax_Error; -#else - parser->top = parser->stack; -#endif - } - } - else - { - FT_ERROR(( "Parse_T1_FontProgram: not enough arguments\n" )); - goto Stack_Underflow; - } - } - break; - - case key_index: - if ( top <= parser->stack ) - { - FT_ERROR(( "Parse_T1_FontProgram: not enough arguments\n" )); - goto Stack_Underflow; - } - - /* simply ignore? */ - parser->top --; - break; - - case key_put: - /* Check that we have sufficient operands in stack */ - if ( top < parser->stack + 2 ) - { - FT_ERROR(( "Parse_T1_FontProgram: not enough arguments\n" )); - goto Stack_Underflow; - } - - parser->top -= 2; - parser->args = parser->top; - - switch ( dict_state ) - { - case dict_encoding: - error = Do_Put_Encoding( parser ); - if ( error ) - goto Exit; - break; - - case dict_unknown_array: /* ignore the `put' */ - break; - - default: -#if 0 - FT_ERROR(( "Parse_T1_FontProgram: invalid context\n" )); - goto Syntax_Error; -#else - /* invalid context; simply ignore the `put' and */ - /* clear the stack (stupid Postscript code) */ - FT_TRACE4(( "Parse_T1_FontProgram: invalid context ignored.\n" )); - parser->top = parser->stack; -#endif - } - break; - - case key_RD: - /* Check that we have sufficient operands in stack */ - if ( top < parser->stack + 2 ) - { - FT_ERROR(( "Parse_T1_FontProgram: not enough arguments\n" )); - goto Stack_Underflow; - } - - parser->top -= 2; - parser->args = parser->top; - switch ( dict_state ) - { - case dict_subrs: - error = Do_RD_Subrs( parser ); - if ( error ) - goto Exit; - break; - - case dict_charstrings: - error = Do_RD_Charstrings( parser ); - if ( error ) - goto Exit; - break; - - default: - FT_ERROR(( "Parse_T1_FontProgram: invalid context\n" )); - goto Syntax_Error; - } - break; - - case key_end: - /* Were we in a dictionary or in an array? */ - if ( dict_index <= 0 ) - { - FT_ERROR(( "Parse_T1_FontProgram: no dictionary defined\n" )); - goto Syntax_Error; - } - - switch ( dict_state ) - { - /* jump to the private dictionary if we are closing the */ - /* `/Font' dictionary */ - case dict_font: - goto Open_Private; - - /* exit the parser when closing the CharStrings dictionary */ - case dict_charstrings: - return Finalize_Parsing( parser ); - - default: - /* Pop the current dictionary state and return to previous */ - /* one. Consume the `def'. */ - - /* Because some buggy fonts (BitStream) have incorrect */ - /* syntax, we never escape from the private dictionary */ - if ( dict_state != dict_private ) - parser->state_index--; - - /* many fonts use `NP' instead of `def' or `put', so */ - /* we simply ignore the next token */ -#if 0 - error = Expect_Keyword2( parser, key_def, key_put ); - if ( error ) - goto Exit; -#else - (void)Expect_Keyword2( parser, key_def, key_put ); -#endif - } - break; - - case key_for: - /* check that we have four arguments and simply */ - /* ignore them */ - if ( top - parser->stack < 4 ) - { - FT_ERROR(( "Parse_T1_FontProgram: not enough arguments\n" )); - goto Stack_Underflow; - } - - parser->top -= 4; - break; - - case key_currentdict: - Open_Private: - parser->state_index = 0; - parser->state_stack[0] = dict_none2; - error = Open_PrivateDict( parser->tokenizer ); - if ( error ) - goto Exit; - break; - - case key_true: - case key_false: - case key_StandardEncoding: - case key_ExpertEncoding: - goto Push_Element; - - default: - FT_ERROR(( "Parse_T1_FontProgram:" )); - FT_ERROR(( " invalid keyword in context\n" )); - error = T1_Err_Syntax_Error; - } - break; - - /* check for the presence of `/BlendAxisTypes' -- we cannot deal */ - /* with multiple master fonts, so we must return a correct error */ - /* code to allow another driver to load them */ - case tok_immediate: - if ( token.kind2 == imm_BlendAxisTypes ) - { - error = FT_Err_Unknown_File_Format; - goto Exit; - } - /* fallthrough */ - - /* A number was detected */ - case tok_string: - case tok_program: - case tok_array: - case tok_hexarray: - case tok_any: - case tok_number: /* push number on stack */ - - Push_Element: - if ( top >= parser->limit ) - { - error = T1_Err_Stack_Overflow; - goto Exit; - } - else - *parser->top++ = token; - break; - - /* anything else is an error per se the spec, but we */ - /* frequently encounter stupid postscript code in fonts, */ - /* so just ignore them */ - default: - error = T1_Err_Ok; /* ignore token */ - } - - if ( error ) - return error; - } - - Exit: - return error; - - Syntax_Error: - return T1_Err_Syntax_Error; - - Stack_Underflow: - return T1_Err_Stack_Underflow; - } - - -/* END */ diff --git a/src/freetype/type1/t1load.h b/src/freetype/type1/t1load.h deleted file mode 100644 index d278374f0f..0000000000 --- a/src/freetype/type1/t1load.h +++ /dev/null @@ -1,57 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1load.h */ -/* */ -/* Type 1 font loader (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifndef T1LOAD_H -#define T1LOAD_H - -#include - - -#ifdef FT_FLAT_COMPILE - -#include "t1parse.h" - -#else - -#include - -#endif - - -#ifdef __cplusplus - extern "C" { -#endif - - LOCAL_DEF - void Init_T1_Parser( T1_Parser* parser, - T1_Face face, - T1_Tokenizer tokenizer ); - - - LOCAL_DEF - FT_Error Parse_T1_FontProgram( T1_Parser* parser ); - - -#ifdef __cplusplus - } -#endif - -#endif /* T1LOAD_H */ - - -/* END */ diff --git a/src/freetype/type1/t1objs.c b/src/freetype/type1/t1objs.c deleted file mode 100644 index 1e6f9ca2a3..0000000000 --- a/src/freetype/type1/t1objs.c +++ /dev/null @@ -1,544 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1objs.c */ -/* */ -/* Type 1 objects manager (body). */ -/* */ -/* 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 -#include - - -#ifdef FT_FLAT_COMPILE - -#include "t1gload.h" -#include "t1load.h" -#include "t1afm.h" - -#ifndef T1_CONFIG_OPTION_DISABLE_HINTER -#include "t1hinter.h" -#endif - -#else /* FT_FLAT_COMPILE */ - -#include -#include -#include - -#ifndef T1_CONFIG_OPTION_DISABLE_HINTER -#include -#endif - -#endif /* FT_FLAT_COMPILE */ - - -#include - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_t1objs - - - /*************************************************************************/ - /* */ - /* SIZE FUNCTIONS */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Done_Size */ - /* */ - /* */ - /* The Type 1 size object destructor. Used to discard a given size */ - /* object. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - LOCAL_FUNC - void T1_Done_Size( T1_Size size ) - { - if ( size ) - { - -#ifndef T1_CONFIG_OPTION_DISABLE_HINTER - T1_Done_Size_Hinter( size ); -#endif - - size->valid = 0; - } - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Init_Size */ - /* */ - /* */ - /* The size object initializer. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - /* */ - /* FreeTrue error code. 0 means success. */ - /* */ - LOCAL_DEF - FT_Error T1_Init_Size( T1_Size size ) - { - FT_Error error; - - - size->valid = 0; - -#ifndef T1_CONFIG_OPTION_DISABLE_HINTER - error = T1_New_Size_Hinter( size ); - - return error; -#else - - FT_UNUSED( error ); - - return T1_Err_Ok; - -#endif - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Reset_Size */ - /* */ - /* */ - /* Resets an instance to a new pointsize/transform. This function is */ - /* in charge of resetting the blue zones,a s well as the stem snap */ - /* tables for a given size. */ - /* */ - /* */ - /* size :: The target size object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error T1_Reset_Size( T1_Size size ) - { - /* recompute ascender, descender, etc. */ - T1_Face face = (T1_Face)size->root.face; - FT_Size_Metrics* metrics = &size->root.metrics; - - - if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 ) - return FT_Err_Invalid_Argument; - - /* Compute root ascender, descender, test height, and max_advance */ - metrics->ascender = ( FT_MulFix( face->root.ascender, - metrics->y_scale ) + 32 ) & -64; - metrics->descender = ( FT_MulFix( face->root.descender, - metrics->y_scale ) + 32 ) & -64; - metrics->height = ( FT_MulFix( face->root.height, - metrics->y_scale ) + 32 ) & -64; - metrics->max_advance = ( FT_MulFix( face->root.max_advance_width, - metrics->x_scale ) + 32 ) & -64; - -#ifndef T1_CONFIG_OPTION_DISABLE_HINTER - return T1_Reset_Size_Hinter( size ); -#else - return 0; -#endif - } - - - /*************************************************************************/ - /* */ - /* FACE FUNCTIONS */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Done_Face */ - /* */ - /* */ - /* The face object destructor. */ - /* */ - /* */ - /* face :: A typeless pointer to the face object to destroy. */ - /* */ - LOCAL_FUNC - void T1_Done_Face( T1_Face face ) - { - FT_Memory memory; - T1_Font* type1 = &face->type1; - - - if ( face ) - { - memory = face->root.memory; - - /* release font info strings */ - { - T1_FontInfo* info = &type1->font_info; - - - FREE( info->version ); - FREE( info->notice ); - FREE( info->full_name ); - FREE( info->family_name ); - FREE( info->weight ); - } - - /* release top dictionary */ - FREE( type1->charstrings_len ); - FREE( type1->charstrings ); - FREE( type1->glyph_names ); - - FREE( type1->subrs ); - FREE( type1->subrs_len ); - - FREE( type1->subrs_block ); - FREE( type1->charstrings_block ); - FREE( type1->glyph_names_block ); - - FREE( type1->encoding.char_index ); - FREE( type1->font_name ); - -#ifndef T1_CONFIG_OPTION_NO_AFM - /* release afm data if present */ - if ( face->afm_data ) - T1_Done_AFM( memory, (T1_AFM*)face->afm_data ); -#endif - - /* release unicode map, if any */ - FREE( face->unicode_map.maps ); - face->unicode_map.num_maps = 0; - - face->root.family_name = 0; - face->root.style_name = 0; - } - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Init_Face */ - /* */ - /* */ - /* The face object constructor. */ - /* */ - /* */ - /* stream :: input stream where to load font data. */ - /* */ - /* face_index :: The index of the font face in the resource. */ - /* */ - /* num_params :: Number of additional generic parameters. Ignored. */ - /* */ - /* params :: Additional generic parameters. Ignored. */ - /* */ - /* */ - /* face :: The face record to build. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error T1_Init_Face( FT_Stream stream, - T1_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ) - { - T1_Tokenizer tokenizer; - FT_Error error; - PSNames_Interface* psnames; - - FT_UNUSED( num_params ); - FT_UNUSED( params ); - FT_UNUSED( face_index ); - FT_UNUSED( face ); - - - face->root.num_faces = 1; - - psnames = (PSNames_Interface*)face->psnames; - if ( !psnames ) - { - psnames = (PSNames_Interface*) - FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), - "psnames" ); - - face->psnames = psnames; - } - - /* open the tokenizer, this will also check the font format */ - error = New_Tokenizer( stream, &tokenizer ); - if ( error ) - goto Fail; - - /* if we just wanted to check the format, leave successfully now */ - if ( face_index < 0 ) - goto Leave; - - /* check the face index */ - if ( face_index != 0 ) - { - FT_ERROR(( "T1_Init_Face: invalid face index\n" )); - error = T1_Err_Invalid_Argument; - goto Leave; - } - - /* Now, load the font program into the face object */ - { - T1_Parser parser; - - - Init_T1_Parser( &parser, face, tokenizer ); - error = Parse_T1_FontProgram( &parser ); - if ( error ) - goto Leave; - - /* Init the face object fields */ - /* Now set up root face fields */ - { - FT_Face root = (FT_Face)&face->root; - T1_Font* type1 = &face->type1; - - - root->num_glyphs = type1->num_glyphs; - root->num_charmaps = 1; - - root->face_index = face_index; - root->face_flags = FT_FACE_FLAG_SCALABLE; - - root->face_flags |= FT_FACE_FLAG_HORIZONTAL; - - root->face_flags |= FT_FACE_FLAG_GLYPH_NAMES; - - if ( type1->font_info.is_fixed_pitch ) - root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; - - /* XXX: TODO -- add kerning with .afm support */ - - /* get style name - be careful, some broken fonts only */ - /* have a `/FontName' dictionary entry! */ - root->family_name = type1->font_info.family_name; - if ( root->family_name ) - { - char* full = type1->font_info.full_name; - char* family = root->family_name; - - - while ( *family && *full == *family ) - { - family++; - full++; - } - - root->style_name = ( *full == ' ' ? full + 1 - : (char *)"Regular" ); - } - else - { - /* do we have a `/FontName'? */ - if (type1->font_name) - { - root->family_name = type1->font_name; - root->style_name = "Regular"; - } - } - - /* no embedded bitmap support */ - root->num_fixed_sizes = 0; - root->available_sizes = 0; - - root->bbox = type1->font_bbox; - root->units_per_EM = 1000; - root->ascender = (FT_Short)type1->font_bbox.yMax; - root->descender = -(FT_Short)type1->font_bbox.yMin; - root->height = ( ( root->ascender + root->descender) * 12 ) - / 10; - - /* now compute the maximum advance width */ - - root->max_advance_width = type1->private_dict.standard_width[0]; - - /* compute max advance width for proportional fonts */ - if ( !type1->font_info.is_fixed_pitch ) - { - FT_Int max_advance; - - - error = T1_Compute_Max_Advance( face, &max_advance ); - - /* in case of error, keep the standard width */ - if ( !error ) - root->max_advance_width = max_advance; - else - error = 0; /* clear error */ - } - - root->max_advance_height = root->height; - - root->underline_position = type1->font_info.underline_position; - root->underline_thickness = type1->font_info.underline_thickness; - - root->max_points = 0; - root->max_contours = 0; - } - } - - /* charmap support - synthetize unicode charmap when possible */ - { - FT_Face root = &face->root; - FT_CharMap charmap = face->charmaprecs; - - - /* synthesize a Unicode charmap if there is support in the `PSNames' */ - /* module.. */ - if ( face->psnames ) - { - PSNames_Interface* psnames = (PSNames_Interface*)face->psnames; - - - if ( psnames->unicode_value ) - { - error = psnames->build_unicodes( - root->memory, - face->type1.num_glyphs, - (const char**)face->type1.glyph_names, - &face->unicode_map ); - if ( !error ) - { - root->charmap = charmap; - charmap->face = (FT_Face)face; - charmap->encoding = ft_encoding_unicode; - charmap->platform_id = 3; - charmap->encoding_id = 1; - charmap++; - } - - /* simply clear the error in case of failure (which really) */ - /* means that out of memory or no unicode glyph names */ - error = 0; - } - } - - /* now, support either the standard, expert, or custom encodings */ - charmap->face = (FT_Face)face; - charmap->platform_id = 7; /* a new platform id for Adobe fonts ?? */ - - switch ( face->type1.encoding_type ) - { - case t1_encoding_standard: - charmap->encoding = ft_encoding_adobe_standard; - charmap->encoding_id = 0; - break; - - case t1_encoding_expert: - charmap->encoding = ft_encoding_adobe_expert; - charmap->encoding_id = 1; - break; - - default: - charmap->encoding = ft_encoding_adobe_custom; - charmap->encoding_id = 2; - break; - } - - root->charmaps = face->charmaps; - root->num_charmaps = charmap - face->charmaprecs + 1; - face->charmaps[0] = &face->charmaprecs[0]; - face->charmaps[1] = &face->charmaprecs[1]; - } - - Leave: - Done_Tokenizer( tokenizer ); - - Fail: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Done_GlyphSlot */ - /* */ - /* */ - /* The glyph slot object destructor. */ - /* */ - /* */ - /* glyph :: The glyph slot handle to destroy. */ - /* */ - LOCAL_FUNC - void T1_Done_GlyphSlot( T1_GlyphSlot glyph ) - { -#ifndef T1_CONFIG_OPTION_DISABLE_HINTER - - T1_Done_Glyph_Hinter( glyph ); - -#else - - FT_UNUSED( glyph ); - -#endif - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Init_GlyphSlot */ - /* */ - /* */ - /* The glyph slot object constructor. */ - /* */ - /* */ - /* glyph :: The glyph slot handle to initialize. */ - /* */ - LOCAL_FUNC - FT_Error T1_Init_GlyphSlot( T1_GlyphSlot glyph ) - { - FT_Error error = FT_Err_Ok; - - -#ifndef T1_CONFIG_OPTION_DISABLE_HINTER - - error = T1_New_Glyph_Hinter( glyph ); - -#else - - FT_UNUSED( glyph ); - -#endif - - return error; - } - - -/* END */ diff --git a/src/freetype/type1/t1objs.h b/src/freetype/type1/t1objs.h deleted file mode 100644 index 47b0a37be1..0000000000 --- a/src/freetype/type1/t1objs.h +++ /dev/null @@ -1,172 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1objs.h */ -/* */ -/* Type 1 objects manager (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifndef T1OBJS_H -#define T1OBJS_H - -#include -#include -#include - -#include - -#ifdef __cplusplus - extern "C" { -#endif - - - /* The following structures must be defined by the hinter */ - typedef struct T1_Size_Hints_ T1_Size_Hints; - typedef struct T1_Glyph_Hints_ T1_Glyph_Hints; - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Driver */ - /* */ - /* */ - /* A handle to a Type 1 driver object. */ - /* */ - typedef struct T1_DriverRec_* T1_Driver; - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Size */ - /* */ - /* */ - /* A handle to a Type 1 size object. */ - /* */ - typedef struct T1_SizeRec_* T1_Size; - - - /*************************************************************************/ - /* */ - /* */ - /* T1_GlyphSlot */ - /* */ - /* */ - /* A handle to a Type 1 glyph slot object. */ - /* */ - typedef struct T1_GlyphSlotRec_* T1_GlyphSlot; - - - /*************************************************************************/ - /* */ - /* */ - /* T1_CharMap */ - /* */ - /* */ - /* A handle to a Type 1 character mapping object. */ - /* */ - /* */ - /* The Type 1 format doesn't use a charmap but an encoding table. */ - /* The driver is responsible for making up charmap objects */ - /* corresponding to these tables. */ - /* */ - typedef struct T1_CharMapRec_* T1_CharMap; - - - /*************************************************************************/ - /* */ - /* HERE BEGINS THE TYPE1 SPECIFIC STUFF */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* T1_SizeRec */ - /* */ - /* */ - /* Type 1 size record. */ - /* */ - typedef struct T1_SizeRec_ - { - FT_SizeRec root; - FT_Bool valid; - T1_Size_Hints* hints; /* defined in the hinter. This allows */ - /* us to experiment with different */ - /* hinting schemes without having to */ - /* change `t1objs' each time. */ - } T1_SizeRec; - - - /*************************************************************************/ - /* */ - /* */ - /* T1_GlyphSlotRec */ - /* */ - /* */ - /* Type 1 glyph slot record. */ - /* */ - typedef struct T1_GlyphSlotRec_ - { - FT_GlyphSlotRec root; - - FT_Bool hint; - FT_Bool scaled; - - FT_Int max_points; - FT_Int max_contours; - - FT_Fixed x_scale; - FT_Fixed y_scale; - - T1_Glyph_Hints* hints; /* defined in the hinter */ - - } T1_GlyphSlotRec; - - - LOCAL_DEF - FT_Error T1_Init_Face( FT_Stream stream, - T1_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ); - - LOCAL_DEF - void T1_Done_Face( T1_Face face ); - - LOCAL_DEF - FT_Error T1_Init_Size( T1_Size size ); - - LOCAL_DEF - void T1_Done_Size( T1_Size size ); - - LOCAL_DEF - FT_Error T1_Reset_Size( T1_Size size ); - - LOCAL_DEF - FT_Error T1_Init_GlyphSlot( T1_GlyphSlot slot ); - - LOCAL_DEF - void T1_Done_GlyphSlot( T1_GlyphSlot slot ); - - -#ifdef __cplusplus - } -#endif - -#endif /* T1OBJS_H */ - - -/* END */ diff --git a/src/freetype/type1/t1parse.c b/src/freetype/type1/t1parse.c deleted file mode 100644 index 8b7ca25245..0000000000 --- a/src/freetype/type1/t1parse.c +++ /dev/null @@ -1,761 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1parse.c */ -/* */ -/* Type 1 parser (body). */ -/* */ -/* 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 -#include - - -#ifdef FT_FLAT_COMPILE - -#include "t1parse.h" - -#else - -#include - -#endif - - -#include /* for sscanf() */ -#include /* for strncpy() */ - - - /*************************************************************************/ - /* */ - /* */ - /* T1_New_Table */ - /* */ - /* */ - /* Initializes a T1_Table structure. */ - /* */ - /* */ - /* table :: The address of the target table. */ - /* */ - /* */ - /* count :: The table size (i.e. maximum number of elements). */ - /* memory :: The memory object to use for all subsequent */ - /* reallocations. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error T1_New_Table( T1_Table* table, - FT_Int count, - FT_Memory memory ) - { - FT_Error error; - - - table->memory = memory; - - if ( ALLOC_ARRAY( table->elements, count, FT_Byte* ) ) - return error; - - if ( ALLOC_ARRAY( table->lengths, count, FT_Byte* ) ) - { - FREE( table->elements ); - return error; - } - - table->max_elems = count; - table->num_elems = 0; - - table->block = 0; - table->capacity = 0; - table->cursor = 0; - - return error; - } - - - static - FT_Error reallocate_t1_table( T1_Table* table, - FT_Int new_size ) - { - FT_Memory memory = table->memory; - FT_Byte* old_base = table->block; - FT_Error error; - - - /* reallocate the base block */ - if ( REALLOC( table->block, table->capacity, new_size ) ) - return error; - table->capacity = new_size; - - /* shift all offsets if necessary */ - if ( old_base ) - { - FT_Long delta = table->block - old_base; - FT_Byte** offset = table->elements; - FT_Byte** limit = offset + table->max_elems; - - - if ( delta ) - for ( ; offset < limit; offset ++ ) - if (offset[0]) - offset[0] += delta; - } - - return T1_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Add_Table */ - /* */ - /* */ - /* Adds an object to a T1_Table, possibly growing its memory block. */ - /* */ - /* */ - /* table :: The target table. */ - /* */ - /* */ - /* index :: The index of the object in the table. */ - /* */ - /* object :: The address of the object to copy in memory. */ - /* */ - /* length :: The length in bytes of the source object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. An error is returned if a */ - /* reallocation failed. */ - /* */ - LOCAL_FUNC - FT_Error T1_Add_Table( T1_Table* table, - FT_Int index, - void* object, - FT_Int length ) - { - if ( index < 0 || index > table->max_elems ) - { - FT_ERROR(( "T1_Add_Table: invalid index\n" )); - return T1_Err_Syntax_Error; - } - - /* grow the base block if needed */ - if ( table->cursor + length > table->capacity ) - { - FT_Error error; - FT_Int new_size = table->capacity; - - - while ( new_size < table->cursor + length ) - new_size += 1024; - - error = reallocate_t1_table( table, new_size ); - if ( error ) - return error; - } - - /* add the object to the base block and adjust offset */ - table->elements[index] = table->block + table->cursor; - table->lengths [index] = length; - MEM_Copy( table->block + table->cursor, object, length ); - - table->cursor += length; - - return T1_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Done_Table */ - /* */ - /* */ - /* Finalize a T1_Table (reallocate it to its current cursor). */ - /* */ - /* */ - /* table :: The target table. */ - /* */ - /* */ - /* This function does NOT release the heap's memory block. It is up */ - /* to the caller to clean it, or reference it in its own structures. */ - /* */ - LOCAL_FUNC - void T1_Done_Table( T1_Table* table ) - { - FT_Memory memory = table->memory; - FT_Error error; - FT_Byte* old_base; - - - /* should never fail, as rec.cursor <= rec.size */ - old_base = table->block; - if ( !old_base ) - return; - - (void)REALLOC( table->block, table->capacity, table->cursor ); - table->capacity = table->cursor; - - if ( old_base != table->block ) - { - FT_Long delta = table->block - old_base; - FT_Byte** element = table->elements; - FT_Byte** limit = element + table->max_elems; - - - for ( ; element < limit; element++ ) - if ( element[0] ) - element[0] += delta; - } - } - - - LOCAL_FUNC - FT_String* CopyString( T1_Parser* parser ) - { - FT_String* string = NULL; - T1_Token* token = parser->args++; - FT_Memory memory = parser->tokenizer->memory; - FT_Error error; - - - if ( token->kind == tok_string ) - { - FT_Int len = token->len - 2; - - - if ( ALLOC( string, len + 1 ) ) - { - parser->error = error; - return 0; - } - - MEM_Copy( string, parser->tokenizer->base + token->start + 1, len ); - string[len] = '\0'; - - parser->error = T1_Err_Ok; - } - else - { - FT_ERROR(( "T1_CopyString: syntax error, string token expected!\n" )); - parser->error = T1_Err_Syntax_Error; - } - - return string; - } - - - static - FT_Error parse_int( FT_Byte* base, - FT_Byte* limit, - FT_Long* result ) - { - FT_Bool sign = 0; - FT_Long sum = 0; - - - if ( base >= limit ) - goto Fail; - - /* check sign */ - if ( *base == '+' ) - base++; - - else if ( *base == '-' ) - { - sign++; - base++; - } - - /* parse digits */ - if ( base >= limit ) - goto Fail; - - do - { - sum = ( 10 * sum + ( *base++ - '0' ) ); - - } while ( base < limit ); - - if ( sign ) - sum = -sum; - - *result = sum; - return T1_Err_Ok; - - Fail: - FT_ERROR(( "parse_int: integer expected\n" )); - *result = 0; - return T1_Err_Syntax_Error; - } - - - static - FT_Error parse_float( FT_Byte* base, - FT_Byte* limit, - FT_Long scale, - FT_Long* result ) - { -#if 1 - - /* XXX: We are simply much too lazy to code this function */ - /* properly for now. We will do that when the rest of */ - /* the driver works properly. */ - char temp[32]; - int len = limit - base; - double value; - - - if ( len > 31 ) - goto Fail; - - strncpy( temp, (char*)base, len ); - temp[len] = '\0'; - if ( sscanf( temp, "%lf", &value ) != 1 ) - goto Fail; - - *result = (FT_Long)( scale * value ); - return 0; - -#else - - FT_Byte* cur; - FT_Bool sign = 0; /* sign */ - FT_Long number_int = 0; /* integer part */ - FT_Long number_frac = 0; /* fractional part */ - FT_Long exponent = 0; /* exponent value */ - FT_Int num_frac = 0; /* number of fractional digits */ - - - /* check sign */ - if ( *base == '+' ) - base++; - - else if ( *base == '-' ) - { - sign++; - base++; - } - - /* find integer part */ - cur = base; - while ( cur < limit ) - { - FT_Byte c = *cur; - - - if ( c == '.' || c == 'e' || c == 'E' ) - break; - - cur++; - } - - if ( cur > base ) - { - error = parse_integer( base, cur, &number_int ); - if ( error ) - goto Fail; - } - - /* read fractional part, if any */ - if ( *cur == '.' ) - { - cur++; - base = cur; - while ( cur < limit ) - { - FT_Byte c = *cur; - - - if ( c == 'e' || c == 'E' ) - break; - cur++; - } - - num_frac = cur - base; - - if ( cur > base ) - { - error = parse_integer( base, cur, &number_frac ); - if ( error ) - goto Fail; - base = cur; - } - } - - /* read exponent, if any */ - if ( *cur == 'e' || *cur == 'E' ) - { - cur++; - base = cur; - error = parse_integer( base, limit, &exponent ); - if ( error ) - goto Fail; - - /* now check that exponent is within `correct bounds' */ - /* i.e. between -6 and 6 */ - if ( exponent < -6 || exponent > 6 ) - goto Fail; - } - - /* now adjust integer value and exponent for fractional part */ - while ( num_frac > 0 ) - { - number_int *= 10; - exponent--; - num_frac--; - } - - number_int += num_frac; - - /* skip point if any, read fractional part */ - if ( cur + 1 < limit ) - { - if (*cur.. - } - - /* now compute scaled float value */ - /* XXX: incomplete! */ - -#endif /* 1 */ - - Fail: - FT_ERROR(( "parse_float: syntax error!\n" )); - return T1_Err_Syntax_Error; - } - - - static - FT_Error parse_integer( FT_Byte* base, - FT_Byte* limit, - FT_Long* result ) - { - FT_Byte* cur; - - - /* the lexical analyser accepts floats as well as integers */ - /* now; check that we really have an int in this token */ - cur = base; - while ( cur < limit ) - { - FT_Byte c = *cur++; - - - if ( c == '.' || c == 'e' || c == 'E' ) - goto Float_Number; - } - - /* now read the number's value */ - return parse_int( base, limit, result ); - - Float_Number: - /* we really have a float there; simply call parse_float in this */ - /* case with a scale of `10' to perform round */ - { - FT_Error error; - - - error = parse_float( base, limit, 10, result ); - if ( !error ) - { - if ( *result >= 0 ) - *result = ( *result + 5 ) / 10; /* round value */ - else - *result = -( ( 5 - *result ) / 10 ); - } - return error; - } - } - - - LOCAL_FUNC - FT_Long CopyInteger( T1_Parser* parser ) - { - FT_Long sum = 0; - T1_Token* token = parser->args++; - - - if ( token->kind == tok_number ) - { - FT_Byte* base = parser->tokenizer->base + token->start; - FT_Byte* limit = base + token->len; - - - /* now read the number's value */ - parser->error = parse_integer( base, limit, &sum ); - return sum; - } - - FT_ERROR(( "CopyInteger: number expected\n" )); - parser->args--; - parser->error = T1_Err_Syntax_Error; - return 0; - } - - - LOCAL_FUNC - FT_Bool CopyBoolean( T1_Parser* parser ) - { - FT_Error error = T1_Err_Ok; - FT_Bool result = 0; - T1_Token* token = parser->args++; - - - if ( token->kind == tok_keyword ) - { - if ( token->kind2 == key_false ) - result = 0; - - else if ( token->kind2 == key_true ) - result = !0; - - else - goto Fail; - } - else - { - Fail: - FT_ERROR(( "CopyBoolean:" )); - FT_ERROR(( " syntax error; `false' or `true' expected\n" )); - error = T1_Err_Syntax_Error; - } - parser->error = error; - return result; - } - - - LOCAL_FUNC - FT_Long CopyFloat( T1_Parser* parser, - FT_Int scale ) - { - FT_Error error; - FT_Long sum = 0; - T1_Token* token = parser->args++; - - - if ( token->kind == tok_number ) - { - FT_Byte* base = parser->tokenizer->base + token->start; - FT_Byte* limit = base + token->len; - - - error = parser->error = parse_float( base, limit, scale, &sum ); - if ( error ) - goto Fail; - - return sum; - } - - Fail: - FT_ERROR(( "CopyFloat: syntax error!\n" )); - parser->error = T1_Err_Syntax_Error; - return 0; - } - - - LOCAL_FUNC - void CopyBBox( T1_Parser* parser, - FT_BBox* bbox ) - { - T1_Token* token = parser->args++; - FT_Int n; - FT_Error error; - - - if ( token->kind == tok_program || - token->kind == tok_array ) - { - /* get rid of `['/`]', or `{'/`}' */ - FT_Byte* base = parser->tokenizer->base + token->start + 1; - FT_Byte* limit = base + token->len - 2; - FT_Byte* cur; - FT_Byte* start; - - - /* read each parameter independently */ - cur = base; - for ( n = 0; n < 4; n++ ) - { - FT_Long* result; - - - /* skip whitespace */ - while ( cur < limit && *cur == ' ' ) - cur++; - - /* skip numbers */ - start = cur; - while ( cur < limit && *cur != ' ' ) - cur++; - - /* compute result address */ - switch ( n ) - { - case 0: - result = &bbox->xMin; - break; - case 1: - result = &bbox->yMin; - break; - case 2: - result = &bbox->xMax; - break; - default: - result = &bbox->yMax; - } - - error = parse_integer( start, cur, result ); - if ( error ) - goto Fail; - } - parser->error = 0; - return; - } - - Fail: - FT_ERROR(( "CopyBBox: syntax error!\n" )); - parser->error = T1_Err_Syntax_Error; - } - - - LOCAL_FUNC - void CopyMatrix( T1_Parser* parser, - FT_Matrix* matrix ) - { - T1_Token* token = parser->args++; - FT_Error error; - - - if ( token->kind == tok_array ) - { - /* get rid of `[' and `]' */ - FT_Byte* base = parser->tokenizer->base + token->start + 1; - FT_Byte* limit = base + token->len - 2; - FT_Byte* cur; - FT_Byte* start; - FT_Int n; - - - /* read each parameter independently */ - cur = base; - for ( n = 0; n < 4; n++ ) - { - FT_Long* result; - - - /* skip whitespace */ - while ( cur < limit && *cur == ' ' ) - cur++; - - /* skip numbers */ - start = cur; - while ( cur < limit && *cur != ' ') - cur++; - - /* compute result address */ - switch ( n ) - { - case 0: - result = &matrix->xx; - break; - case 1: - result = &matrix->yx; - break; - case 2: - result = &matrix->xy; - break; - default: - result = &matrix->yy; - } - - error = parse_float( start, cur, 65536000L, result ); - if ( error ) - goto Fail; - } - parser->error = 0; - return; - } - - Fail: - FT_ERROR(( "CopyMatrix: syntax error!\n" )); - parser->error = T1_Err_Syntax_Error; - } - - - LOCAL_FUNC - void CopyArray( T1_Parser* parser, - FT_Byte* num_elements, - FT_Short* elements, - FT_Int max_elements ) - { - T1_Token* token = parser->args++; - FT_Error error; - - - if ( token->kind == tok_array || - token->kind == tok_program ) /* in the case of MinFeature */ - { - /* get rid of `['/`]', or `{'/`}' */ - FT_Byte* base = parser->tokenizer->base + token->start + 1; - FT_Byte* limit = base + token->len - 2; - FT_Byte* cur; - FT_Byte* start; - FT_Int n; - - - /* read each parameter independently */ - cur = base; - for ( n = 0; n < max_elements; n++ ) - { - FT_Long result; - - - /* test end of string */ - if ( cur >= limit ) - break; - - /* skip whitespace */ - while ( cur < limit && *cur == ' ' ) - cur++; - - /* end of list? */ - if ( cur >= limit ) - break; - - /* skip numbers */ - start = cur; - while ( cur < limit && *cur != ' ' ) - cur++; - - error = parse_integer( start, cur, &result ); - if ( error ) - goto Fail; - - *elements++ = (FT_Short)result; - } - - if ( num_elements ) - *num_elements = (FT_Byte)n; - - parser->error = 0; - return; - } - - Fail: - FT_ERROR(( "CopyArray: syntax error!\n" )); - parser->error = T1_Err_Syntax_Error; - } - - -/* END */ diff --git a/src/freetype/type1/t1parse.h b/src/freetype/type1/t1parse.h deleted file mode 100644 index 2c42b8cec4..0000000000 --- a/src/freetype/type1/t1parse.h +++ /dev/null @@ -1,261 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1parse.h */ -/* */ -/* Type 1 parser (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* The Type1 parser component is in charge of simply parsing the font */ - /* input stream and convert simple tokens and elements into integers, */ - /* floats, matrices, strings, etc. */ - /* */ - /* It is used by the Type1 loader. */ - /* */ - /*************************************************************************/ - - -#ifndef T1PARSE_H -#define T1PARSE_H - -#include - - -#ifdef FT_FLAT_COMPILE - -#include "t1tokens.h" - -#else - -#include - -#endif - - -#ifdef __cplusplus - extern "C" { -#endif - - - /*************************************************************************/ - /* */ - /* */ - /* T1_DictState */ - /* */ - /* */ - /* An enumeration used to describe the Type 1 parser's state, i.e. */ - /* which dictionary (or array) it is scanning and processing at the */ - /* current moment. */ - /* */ - typedef enum T1_DictState_ - { - dict_none = 0, - dict_font, /* parsing the font dictionary */ - dict_fontinfo, /* parsing the font info dictionary */ - dict_none2, /* beginning to parse the encrypted section */ - dict_private, /* parsing the private dictionary */ - dict_encoding, /* parsing the encoding array */ - dict_subrs, /* parsing the subrs array */ - dict_othersubrs, /* parsing the othersubrs array (?) */ - dict_charstrings, /* parsing the charstrings dictionary */ - dict_unknown_array, /* parsing/ignoring an unknown array */ - dict_unknown_dict, /* parsing/ignoring an unknown dictionary */ - - dict_max /* do not remove from list */ - - } T1_DictState; - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Table */ - /* */ - /* */ - /* A T1_Table is a simple object used to store an array of objects in */ - /* a single memory block. */ - /* */ - /* */ - /* block :: The address in memory of the growheap's block. This */ - /* can change between two object adds, due to */ - /* reallocation. */ - /* */ - /* cursor :: The current top of the grow heap within its block. */ - /* */ - /* capacity :: The current size of the heap block. Increments by */ - /* 1kByte chunks. */ - /* */ - /* max_elems :: The maximum number of elements in table. */ - /* */ - /* num_elems :: The current number of elements in table. */ - /* */ - /* elements :: A table of element addresses within the block. */ - /* */ - /* lengths :: A table of element sizes within the block. */ - /* */ - /* memory :: The object used for memory operations */ - /* (alloc/realloc). */ - /* */ - typedef struct T1_Table_ - { - FT_Byte* block; /* current memory block */ - FT_Int cursor; /* current cursor in memory block */ - FT_Int capacity; /* current size of memory block */ - - FT_Int max_elems; - FT_Int num_elems; - FT_Byte** elements; /* addresses of table elements */ - FT_Int* lengths; /* lengths of table elements */ - - FT_Memory memory; - - } T1_Table; - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Parser */ - /* */ - /* */ - /* A Type 1 parser. This object is in charge of parsing Type 1 ASCII */ - /* streams and builds dictionaries for a T1_Face object. */ - /* */ - /* */ - /* error :: The current error code. 0 means success. */ - /* */ - /* face :: The target T1_Face object being built. */ - /* */ - /* tokenizer :: The tokenizer (lexical analyser) used for */ - /* processing the input stream. */ - /* */ - /* dump_tokens :: XXX */ - /* */ - /* stack :: The current token stack. Note that we don't */ - /* use intermediate Postscript objects here! */ - /* */ - /* top :: The current top of token stack. */ - /* */ - /* limit :: The current upper bound of the token stack. */ - /* Used for overflow checks. */ - /* */ - /* args :: The arguments of a given operator. Used and */ - /* increased by the various CopyXXX() functions. */ - /* */ - /* state_index :: The index of the top of the dictionary state */ - /* stack. */ - /* */ - /* state_stack :: The dictionary states stack. */ - /* */ - /* table :: A T1_Table object used to record various kinds */ - /* of dictionaries or arrays (like `/Encoding', */ - /* `/Subrs', `/CharStrings'). */ - /* */ - /* cur_name :: XXX */ - /* */ - /* encoding_type :: XXX */ - /* */ - /* encoding_names :: XXX */ - /* */ - /* encoding_lengths :: XXX */ - /* */ - /* encoding_offsets :: XXX */ - /* */ - /* subrs :: XXX */ - /* */ - /* charstrings :: XXX */ - /* */ - typedef struct T1_Parser_ - { - FT_Error error; - T1_Face face; - - T1_Tokenizer tokenizer; - FT_Bool dump_tokens; - - T1_Token stack[T1_MAX_STACK_DEPTH]; - T1_Token* top; - T1_Token* limit; - T1_Token* args; - - FT_Int state_index; - T1_DictState state_stack[T1_MAX_DICT_DEPTH]; - - T1_Table table; - - FT_Int cur_name; - - T1_EncodingType encoding_type; - FT_Byte* encoding_names; - FT_Int* encoding_lengths; - FT_Byte** encoding_offsets; - - FT_Byte* subrs; - FT_Byte* charstrings; - - } T1_Parser; - - - LOCAL_DEF - FT_Error T1_New_Table( T1_Table* table, - FT_Int count, - FT_Memory memory ); - - LOCAL_DEF - FT_Error T1_Add_Table( T1_Table* table, - FT_Int index, - void* object, - FT_Int length ); - - LOCAL_DEF - void T1_Done_Table( T1_Table* table ); - - - LOCAL_DEF - FT_String* CopyString( T1_Parser* parser ); - - LOCAL_DEF - FT_Long CopyInteger( T1_Parser* parser ); - - LOCAL_DEF - FT_Bool CopyBoolean( T1_Parser* parser ); - - LOCAL_DEF - FT_Long CopyFloat( T1_Parser* parser, - FT_Int scale ); - - LOCAL_DEF - void CopyBBox( T1_Parser* parser, - FT_BBox* bbox ); - - LOCAL_DEF - void CopyMatrix( T1_Parser* parser, - FT_Matrix* matrix ); - - LOCAL_DEF - void CopyArray( T1_Parser* parser, - FT_Byte* num_elements, - FT_Short* elements, - FT_Int max_elements ); - - -#ifdef __cplusplus - } -#endif - -#endif /* T1PARSE_H */ - - -/* END */ diff --git a/src/freetype/type1/t1tokens.c b/src/freetype/type1/t1tokens.c deleted file mode 100644 index 2953322c99..0000000000 --- a/src/freetype/type1/t1tokens.c +++ /dev/null @@ -1,1101 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1parse.c */ -/* */ -/* Type 1 parser (body). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* The tokenizer is in charge of loading and reading a Type1 font file */ - /* (either in PFB or PFA format), and extracting successive tokens and */ - /* keywords from its two streams (i.e. the font program, and the private */ - /* dictionary). */ - /* */ - /* Eexec decryption is performed automatically when entering the private */ - /* dictionary, or when retrieving char strings. */ - /* */ - /*************************************************************************/ - - -#include -#include - - -#ifdef FT_FLAT_COMPILE - -#include "t1tokens.h" -#include "t1load.h" - -#else - -#include -#include - -#endif - - -#include /* for strncmp() */ - - -#undef READ_BUFFER_INCREMENT -#define READ_BUFFER_INCREMENT 0x400 - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_t1load - - - /* An array of Type1 keywords supported by this engine. This table */ - /* places the keyword in lexicographical order. It should always */ - /* correspond to the enums `key_xxx'! */ - /* */ - const char* t1_keywords[key_max - key_first_] = - { - "-|", "ExpertEncoding", "ND", "NP", "RD", "StandardEncoding", "array", - "begin", "closefile", "currentdict", "currentfile", "def", "dict", "dup", - "eexec", "end", "executeonly", "false", "for", "index", "noaccess", - "put", "readonly", "true", "userdict", "|", "|-" - }; - - - const char* t1_immediates[imm_max - imm_first_] = - { - "-|", ".notdef", "BlendAxisTypes", "BlueFuzz", "BlueScale", "BlueShift", - "BlueValues", "CharStrings", "Encoding", "FamilyBlues", "FamilyName", - "FamilyOtherBlues", "FID", "FontBBox", "FontID", "FontInfo", "FontMatrix", - "FontName", "FontType", "ForceBold", "FullName", "ItalicAngle", - "LanguageGroup", "Metrics", "MinFeature", "ND", "NP", "Notice", - "OtherBlues", "OtherSubrs", "PaintType", "Private", "RD", "RndStemUp", - "StdHW", "StdVW", "StemSnapH", "StemSnapV", "StrokeWidth", "Subrs", - "UnderlinePosition", "UnderlineThickness", "UniqueID", "Weight", - "isFixedPitch", "lenIV", "password", "version", "|", "|-" - }; - - - /* lexicographic comparison of two strings */ - static - int lexico_strcmp( const char* str1, - int str1_len, - const char* str2 ) - { - int c2 = 0; - - - for ( ; str1_len > 0; str1_len-- ) - { - int c1, diff; - - - c1 = *str1++; - c2 = *str2++; - - diff = c1 - c2; - if ( diff ) - return diff; - }; - - return -*str2; - } - - - /* find a given token/name, performing binary search */ - static - int Find_Name( char* base, - int length, - const char** table, - int table_len ) - { - int left, right; - - - left = 0; - right = table_len - 1; - - while ( right - left > 1 ) - { - int middle = left + ( ( right - left ) >> 1 ); - int cmp; - - - cmp = lexico_strcmp( base, length, table[middle] ); - if ( !cmp ) - return middle; - - if ( cmp < 0 ) - right = middle; - else - left = middle; - } - - if ( !lexico_strcmp( base, length, table[left ] ) ) - return left; - if ( !lexico_strcmp( base, length, table[right] ) ) - return right; - - return -1; - } - - - /* read the small PFB section header */ - static - FT_Error Read_PFB_Tag( FT_Stream stream, - FT_UShort* atag, - FT_ULong* asize ) - { - FT_UShort tag; - FT_ULong size; - FT_Error error; - - - FT_TRACE2(( "Read_PFB_Tag: reading\n" )); - - if ( ACCESS_Frame( 6L ) ) - return error; - - tag = GET_UShort(); - size = GET_ULong(); - - FORGET_Frame(); - - *atag = tag; - *asize = ( ( size & 0xFF ) << 24 ) | - ( ( ( size >> 8 ) & 0xFF ) << 16 ) | - ( ( ( size >> 16 ) & 0xFF ) << 8 ) | - ( ( ( size >> 24 ) & 0xFF ) ); - - FT_TRACE2(( " tag = %04x\n", tag )); - FT_TRACE4(( " asze = %08x\n", size )); - FT_TRACE2(( " size = %08x\n", *asize )); - - return T1_Err_Ok; - } - - - static - FT_Error grow( T1_Tokenizer tokzer ) - { - FT_Error error; - FT_Long left_bytes; - FT_Memory memory = tokzer->memory; - - - left_bytes = tokzer->max - tokzer->limit; - - if ( left_bytes > 0 ) - { - FT_Stream stream = tokzer->stream; - - - if ( left_bytes > READ_BUFFER_INCREMENT ) - left_bytes = READ_BUFFER_INCREMENT; - - FT_TRACE2(( "Growing tokenizer buffer by %d bytes\n", left_bytes )); - - if ( !REALLOC( tokzer->base, tokzer->limit, - tokzer->limit + left_bytes ) && - !FILE_Read( tokzer->base + tokzer->limit, left_bytes ) ) - tokzer->limit += left_bytes; - } - else - { - FT_ERROR(( "Unexpected end of Type1 fragment!\n" )); - error = T1_Err_Invalid_File_Format; - } - - tokzer->error = error; - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* t1_decrypt */ - /* */ - /* */ - /* Performs the Type 1 charstring decryption process. */ - /* */ - /* */ - /* buffer :: The base address of the data to decrypt. */ - /* length :: The number of bytes to decrypt (beginning from the base */ - /* address. */ - /* seed :: The encryption seed (4330 for charstrings). */ - /* */ - LOCAL_FUNC - void t1_decrypt( FT_Byte* buffer, - FT_Int length, - FT_UShort seed ) - { - while ( length > 0 ) - { - FT_Byte plain; - - - plain = ( *buffer ^ ( seed >> 8 ) ); - seed = ( *buffer + seed ) * 52845 + 22719; - *buffer++ = plain; - length--; - } - } - - - /*************************************************************************/ - /* */ - /* */ - /* New_Tokenizer */ - /* */ - /* */ - /* Creates a new tokenizer from a given input stream. This function */ - /* automatically recognizes `pfa' or `pfb' files. The function */ - /* Read_Token() can then be used to extract successive tokens from */ - /* the stream. */ - /* */ - /* */ - /* stream :: The input stream. */ - /* */ - /* */ - /* tokenizer :: A handle to a new tokenizer object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* This function copies the stream handle within the object. Callers */ - /* should not discard `stream'. This is done by the Done_Tokenizer() */ - /* function. */ - /* */ - LOCAL_FUNC - FT_Error New_Tokenizer( FT_Stream stream, - T1_Tokenizer* tokenizer ) - { - FT_Memory memory = stream->memory; - T1_Tokenizer tokzer; - FT_Error error; - FT_UShort tag; - FT_ULong size; - - FT_Byte* tok_base; - FT_ULong tok_limit; - FT_ULong tok_max; - - - *tokenizer = 0; - - /* allocate object */ - if ( FILE_Seek( 0L ) || - ALLOC( tokzer, sizeof ( *tokzer ) ) ) - return error; - - tokzer->stream = stream; - tokzer->memory = stream->memory; - - tokzer->in_pfb = 0; - tokzer->in_private = 0; - - tok_base = 0; - tok_limit = 0; - tok_max = stream->size; - - error = Read_PFB_Tag( stream, &tag, &size ); - if ( error ) - goto Fail; - - if ( tag != 0x8001 ) - { - /* assume that it is a PFA file -- an error will be produced later */ - /* if a character with value > 127 is encountered */ - - /* rewind to start of file */ - if ( FILE_Seek( 0L ) ) - goto Fail; - - size = stream->size; - } - else - tokzer->in_pfb = 1; - - /* if it is a memory-based resource, set up pointer */ - if ( !stream->read ) - { - tok_base = (FT_Byte*)stream->base + stream->pos; - tok_limit = size; - tok_max = size; - - /* check that the `size' field is valid */ - if ( FILE_Skip( size ) ) - goto Fail; - } - else if ( tag == 0x8001 ) - { - /* read segment in memory */ - if ( ALLOC( tok_base, size ) ) - goto Fail; - - if ( FILE_Read( tok_base, size ) ) - { - FREE( tok_base ); - goto Fail; - } - - tok_limit = size; - tok_max = size; - } - - tokzer->base = tok_base; - tokzer->limit = tok_limit; - tokzer->max = tok_max; - tokzer->cursor = 0; - - *tokenizer = tokzer; - - /* now check font format; we must see `%!PS-AdobeFont-1' */ - /* or `%!FontType' */ - { - if ( 16 > tokzer->limit ) - grow( tokzer ); - - if ( tokzer->limit <= 16 || - ( strncmp( (const char*)tokzer->base, "%!PS-AdobeFont-1", 16 ) && - strncmp( (const char*)tokzer->base, "%!FontType", 10 ) ) ) - { - FT_TRACE2(( "[not a Type1 font]\n" )); - error = FT_Err_Unknown_File_Format; - goto Fail; - } - } - return T1_Err_Ok; - - Fail: - FREE( tokzer->base ); - FREE( tokzer ); - return error; - } - - - /* return the value of an hexadecimal digit */ - static - int hexa_value( char c ) - { - unsigned int d; - - - d = (unsigned int)( c - '0' ); - if ( d <= 9 ) - return (int)d; - - d = (unsigned int)( c - 'a' ); - if ( d <= 5 ) - return (int)( d + 10 ); - - d = (unsigned int)( c - 'A' ); - if ( d <= 5 ) - return (int)( d + 10 ); - - return -1; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Done_Tokenizer */ - /* */ - /* */ - /* Closes a given tokenizer. This function will also close the */ - /* stream embedded in the object. */ - /* */ - /* */ - /* tokenizer :: The target tokenizer object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error Done_Tokenizer( T1_Tokenizer tokenizer ) - { - FT_Memory memory = tokenizer->memory; - - - /* clear read buffer if needed (disk-based resources) */ - if ( tokenizer->in_private || !tokenizer->stream->base ) - FREE( tokenizer->base ); - - FREE( tokenizer ); - return T1_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Open_PrivateDict */ - /* */ - /* */ - /* This function must be called to set the tokenizer to the private */ - /* section of the Type1 file. It recognizes automatically the */ - /* the kind of eexec encryption used (ascii or binary). */ - /* */ - /* */ - /* tokenizer :: The target tokenizer object. */ - /* lenIV :: The value of the `lenIV' variable. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error Open_PrivateDict( T1_Tokenizer tokenizer ) - { - T1_Tokenizer tokzer = tokenizer; - FT_Stream stream = tokzer->stream; - FT_Memory memory = tokzer->memory; - FT_Error error = 0; - - FT_UShort tag; - FT_ULong size; - - FT_Byte* private_dict; - - /* are we already in the private dictionary ? */ - if ( tokzer->in_private ) - return 0; - - if ( tokzer->in_pfb ) - { - /* in the case of the PFB format, the private dictionary can be */ - /* made of several segments. We thus first read the number of */ - /* segments to compute the total size of the private dictionary */ - /* then re-read them into memory. */ - FT_Long start_pos = FILE_Pos(); - FT_ULong private_dict_size = 0; - - - for (;;) - { - error = Read_PFB_Tag( stream, &tag, &size ); - if ( error || tag != 0x8002 ) - break; - - private_dict_size += size; - - if ( FILE_Skip( size ) ) - goto Fail; - } - - /* check that we have a private dictionary there */ - /* and allocate private dictionary buffer */ - if ( private_dict_size == 0 ) - { - FT_ERROR(( "Open_PrivateDict:" )); - FT_ERROR(( " invalid private dictionary section\n" )); - error = T1_Err_Invalid_File_Format; - goto Fail; - } - - if ( ALLOC( private_dict, private_dict_size ) ) - goto Fail; - - /* read all sections into buffer */ - if ( FILE_Seek( start_pos ) ) - goto Fail_Private; - - private_dict_size = 0; - for (;;) - { - error = Read_PFB_Tag( stream, &tag, &size ); - if ( error || tag != 0x8002 ) - { - error = 0; - break; - } - - if ( FILE_Read( private_dict + private_dict_size, size ) ) - goto Fail_Private; - - private_dict_size += size; - } - - /* we must free the field `tokzer.base' if we are in a disk-based */ - /* PFB file. */ - if ( stream->read ) - FREE( tokzer->base ); - - tokzer->base = private_dict; - tokzer->cursor = 0; - tokzer->limit = private_dict_size; - tokzer->max = private_dict_size; - } - else - { - char* base; - - - /* we are in a PFA file; read each token until we find `eexec' */ - while ( tokzer->token.kind2 != key_eexec ) - { - error = Read_Token( tokzer ); - if ( error ) - goto Fail; - } - - /* now determine whether the private dictionary is encoded in binary */ - /* or hexadecimal ASCII format. */ - - /* we need to access the next 4 bytes (after the final \r following */ - /* the `eexec' keyword); if they all are hexadecimal digits, then */ - /* we have a case of ASCII storage. */ - while ( tokzer->cursor + 5 > tokzer->limit ) - { - error = grow( tokzer ); - if ( error ) - goto Fail; - } - - /* skip whitespace/line feed after `eexec' */ - base = (char*)tokzer->base + tokzer->cursor + 1; - if ( ( hexa_value( base[0] ) | hexa_value( base[1] ) | - hexa_value( base[2] ) | hexa_value( base[3] ) ) < 0 ) - { - /* binary encoding -- `simply' read the stream */ - - /* if it is a memory-based resource, we need to allocate a new */ - /* storage buffer for the private dictionary, as it must be */ - /* decrypted later */ - if ( stream->base ) - { - size = stream->size - tokzer->cursor - 1; /* remaining bytes */ - - if ( ALLOC( private_dict, size ) ) /* alloc private dict buffer */ - goto Fail; - - /* copy eexec-encrypted bytes */ - MEM_Copy( private_dict, tokzer->base + tokzer->cursor + 1, size ); - - /* reset pointers - forget about file mapping */ - tokzer->base = private_dict; - tokzer->limit = size; - tokzer->max = size; - tokzer->cursor = 0; - } - /* On the opposite, for disk based resources, we simply grow */ - /* the current buffer until its completion, and decrypt the */ - /* bytes within it. In all cases, the `base' buffer will be */ - /* discarded on DoneTokenizer if we are in the private dict. */ - else - { - /* grow the read buffer to the full file */ - while ( tokzer->limit < tokzer->max ) - { - error = grow( tokenizer ); - if ( error ) - goto Fail; - } - - /* set up cursor to first encrypted byte */ - tokzer->cursor++; - } - } - else - { - /* ASCII hexadecimal encoding. This sucks... */ - FT_Byte* write; - FT_Byte* cur; - FT_Byte* limit; - FT_Int count; - - - /* allocate a buffer, read each one byte at a time */ - count = stream->size - tokzer->cursor; - size = count / 2; - - if ( ALLOC( private_dict, size ) ) /* alloc private dict buffer */ - goto Fail; - - write = private_dict; - cur = tokzer->base + tokzer->cursor; - limit = tokzer->base + tokzer->limit; - - /* read each bytes */ - while ( count > 0 ) - { - /* ensure that we can read the next 2 bytes! */ - while ( cur + 2 > limit ) - { - int cursor = cur - tokzer->base; - - - error = grow( tokzer ); - if ( error ) - goto Fail_Private; - cur = tokzer->base + cursor; - limit = tokzer->base + tokzer->limit; - } - - /* check for new line */ - if ( cur[0] == '\r' || cur[0] == '\n' ) - { - cur++; - count--; - } - else - { - int hex1 = hexa_value(cur[0]); - - - /* exit if we have a non-hexadecimal digit which isn't */ - /* a new-line character */ - if ( hex1 < 0 ) - break; - - /* otherwise, store byte */ - *write++ = ( hex1 << 4 ) | hexa_value( cur[1] ); - cur += 2; - count -= 2; - } - } - - /* get rid of old buffer in the case of disk-based resources */ - if ( !stream->base ) - FREE( tokzer->base ); - - /* set up pointers */ - tokzer->base = private_dict; - tokzer->limit = size; - tokzer->max = size; - tokzer->cursor = 0; - } - } - - /* finally, decrypt the private dictionary - and skip the lenIV bytes */ - t1_decrypt( tokzer->base, tokzer->limit, 55665 ); - tokzer->cursor += 4; - - Fail: - return error; - - Fail_Private: - FREE( private_dict ); - goto Fail; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Read_Token */ - /* */ - /* */ - /* Reads a new token from the current input stream. This function */ - /* extracts a token from the font program until Open_PrivateDict() */ - /* has been called. After this, it returns tokens from the */ - /* (eexec-encrypted) private dictionary. */ - /* */ - /* */ - /* tokenizer :: The target tokenizer object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Use the function Read_CharStrings() to read the binary charstrings */ - /* from the private dict. */ - /* */ - LOCAL_FUNC - FT_Error Read_Token( T1_Tokenizer tokenizer ) - { - T1_Tokenizer tok = tokenizer; - FT_Long cur, limit; - FT_Byte* base; - char c, starter, ender; - FT_Bool token_started; - - T1_TokenType kind; - - - tok->error = T1_Err_Ok; - tok->token.kind = tok_any; - - base = tok->base; - limit = tok->limit; - cur = tok->cursor; - - token_started = 0; - - for (;;) - { - if ( cur >= limit ) - { - if ( grow( tok ) ) - goto Exit; - base = tok->base; - limit = tok->limit; - } - - c = (char)base[cur++]; - - /* check that we have an ASCII character */ - if ( (FT_Byte)c > 127 ) - { - FT_ERROR(( "Read_Token:" )); - FT_ERROR(( " unexpected binary data in Type1 fragment!\n" )); - tok->error = T1_Err_Invalid_File_Format; - goto Exit; - } - - switch ( c ) - { - case '\r': - case '\n': - case ' ' : - case '\t': /* skip initial whitespace => skip to next */ - if ( token_started ) - { - /* possibly a name, keyword, wathever */ - tok->token.kind = tok_any; - tok->token.len = cur-tok->token.start - 1; - goto Exit; - } - /* otherwise, skip everything */ - break; - - case '%': /* this is a comment -- skip everything */ - for (;;) - { - FT_Int left = limit - cur; - - - while ( left > 0 ) - { - c = (char)base[cur++]; - if ( c == '\r' || c == '\n' ) - goto Next; - left--; - } - - if ( grow( tokenizer ) ) - goto Exit; - base = tok->base; - limit = tok->limit; - } - - case '(': /* a Postscript string */ - kind = tok_string; - ender = ')'; - - L1: - if ( !token_started ) - { - token_started = 1; - tok->token.start = cur - 1; - } - - { - FT_Int nest_level = 1; - - - starter = c; - for (;;) - { - FT_Int left = limit - cur; - - - while ( left > 0 ) - { - c = (char)base[cur++]; - - if ( c == starter ) - nest_level++; - - else if ( c == ender ) - { - nest_level--; - if ( nest_level <= 0 ) - { - tok->token.kind = kind; - tok->token.len = cur - tok->token.start; - goto Exit; - } - } - left--; - } - - if ( grow( tok ) ) - goto Exit; - base = tok->base; - limit = tok->limit; - } - } - - case '[': /* a Postscript array */ - if ( token_started ) - goto Any_Token; - - kind = tok_array; - ender = ']'; - goto L1; - break; - - case '{': /* a Postscript program */ - if ( token_started ) - goto Any_Token; - - kind = tok_program; - ender = '}'; - goto L1; - break; - - case '<': /* a Postscript hex byte array? */ - if ( token_started ) - goto Any_Token; - - kind = tok_hexarray; - ender = '>'; - goto L1; - break; - - case '0': /* any number */ - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if ( token_started ) - goto Next; - - tok->token.kind = tok_number; - token_started = 1; - tok->token.start = cur - 1; - - L2: - for (;;) - { - FT_Int left = limit-cur; - - - while ( left > 0 ) - { - c = (char)base[cur++]; - - switch ( c ) - { - case '[': /* ] */ - case '{': /* } */ - case '(': /* ) */ - case '<': - case '/': - goto Any_Token; - - case ' ': - case '\r': - case '\t': - case '\n': - tok->token.len = cur - tok->token.start - 1; - goto Exit; - - default: - ; - } - left--; - } - - if ( grow( tok ) ) - goto Exit; - base = tok->base; - limit = tok->limit; - } - - case '.': /* maybe a number */ - case '-': - case '+': - if ( token_started ) - goto Next; - - token_started = 1; - tok->token.start = cur - 1; - - for (;;) - { - FT_Int left = limit - cur; - - - if ( left > 0 ) - { - /* test for any following digit, interpreted as number */ - c = (char)base[cur]; - tok->token.kind = ( c >= '0' && c <= '9' ? tok_number : tok_any ); - goto L2; - } - - if ( grow( tok ) ) - goto Exit; - base = tok->base; - limit = tok->limit; - } - - case '/': /* maybe an immediate name */ - if ( !token_started ) - { - token_started = 1; - tok->token.start = cur - 1; - - for (;;) - { - FT_Int left = limit - cur; - - - if ( left > 0 ) - { - /* test for single '/', interpreted as garbage */ - c = (char)base[cur]; - tok->token.kind = ( c == ' ' || c == '\t' || - c == '\r' || c == '\n' ) ? tok_any - : tok_immediate; - goto L2; - } - - if ( grow( tok ) ) - goto Exit; - base = tok->base; - limit = tok->limit; - } - } - else - { - Any_Token: /* possibly a name or wathever */ - cur--; - tok->token.len = cur - tok->token.start; - goto Exit; - } - - default: - if ( !token_started ) - { - token_started = 1; - tok->token.start = cur - 1; - } - } - - Next: - ; - } - - Exit: - tok->cursor = cur; - - if ( !tok->error ) - { - /* now, tries to match keywords and immediate names */ - FT_Int index; - - - switch ( tok->token.kind ) - { - case tok_immediate: /* immediate name */ - index = Find_Name( (char*)( tok->base + tok->token.start + 1 ), - tok->token.len - 1, - t1_immediates, - imm_max - imm_first_ ); - tok->token.kind2 = ( index >= 0 ) - ? (T1_TokenType)( imm_first_ + index ) - : tok_error; - break; - - case tok_any: /* test for keyword */ - index = Find_Name( (char*)( tok->base + tok->token.start ), - tok->token.len, - t1_keywords, - key_max - key_first_ ); - if ( index >= 0 ) - { - tok->token.kind = tok_keyword; - tok->token.kind2 = (T1_TokenType)( key_first_ + index ); - } - else - tok->token.kind2 = tok_error; - break; - - default: - tok->token.kind2 = tok_error; - } - } - return tokenizer->error; - } - - -#if 0 - - /*************************************************************************/ - /* */ - /* */ - /* Read_CharStrings */ - /* */ - /* */ - /* Reads a charstrings element from the current input stream. These */ - /* are binary bytes that encode each individual glyph outline. */ - /* */ - /* The caller is responsible for skipping the `lenIV' bytes at the */ - /* start of the record. */ - /* */ - /* */ - /* tokenizer :: The target tokenizer object. */ - /* num_chars :: The number of binary bytes to read. */ - /* */ - /* */ - /* buffer :: The target array of bytes. These are */ - /* eexec-decrypted. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Use the function Read_CharStrings() to read binary charstrings */ - /* from the private dict. */ - /* */ - LOCAL_FUNC - FT_Error Read_CharStrings( T1_Tokenizer tokenizer, - FT_Int num_chars, - FT_Byte* buffer ) - { - for (;;) - { - FT_Int left = tokenizer->limit - tokenizer->cursor; - - - if ( left >= num_chars ) - { - MEM_Copy( buffer, tokenizer->base + tokenizer->cursor, num_chars ); - t1_decrypt( buffer, num_chars, 4330 ); - tokenizer->cursor += num_chars; - return T1_Err_Ok; - } - - if ( grow( tokenizer ) ) - return tokenizer->error; - } - } - -#endif /* 0 */ - - -/* END */ diff --git a/src/freetype/type1/t1tokens.h b/src/freetype/type1/t1tokens.h deleted file mode 100644 index 119c54ba19..0000000000 --- a/src/freetype/type1/t1tokens.h +++ /dev/null @@ -1,258 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1tokens.h */ -/* */ -/* Type 1 tokenizer (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifndef T1TOKENS_H -#define T1TOKENS_H - - -#ifdef FT_FLAT_COMPILE - -#include "t1objs.h" - -#else - -#include - -#endif - - -#ifdef __cplusplus - extern "C" { -#endif - - - /* enum value of first keyword */ -#define key_first_ 100 - - /* enum value of first immediate name */ -#define imm_first_ 200 - - - typedef enum T1_TokenType_ - { - tok_error = 0, - - tok_eof, /* end of file */ - - /* simple token types */ - - tok_keyword, /* keyword */ - tok_number, /* number (integer or real) */ - tok_string, /* postscript string */ - tok_program, /* postscript program */ - tok_immediate, /* any immediate name */ - tok_array, /* matrix, array, etc.. */ - tok_hexarray, /* array of hexadecimal nibbles */ - tok_any, /* anything else */ - - /* Postscript keywords -- placed in lexicographical order */ - - key_RD_alternate = key_first_, /* `-|' = alternate form of RD */ - key_ExpertEncoding, - key_ND, - key_NP, - key_RD, - key_StandardEncoding, - key_array, - key_begin, - key_closefile, - key_currentdict, - key_currentfile, - key_def, - key_dict, - key_dup, - key_eexec, - key_end, - key_execonly, - key_false, - key_for, - key_index, - key_noaccess, - key_put, - key_readonly, - key_true, - key_userdict, - key_NP_alternate, /* `|' = alternate form of NP */ - key_ND_alternate, /* `|-' = alternate form of ND */ - - key_max, /* always keep this value there */ - - /* Postscript immediate names -- other names will be ignored, except */ - /* in charstrings */ - - imm_RD_alternate = imm_first_, /* `-|' = alternate form of RD */ - imm_notdef, /* `/.notdef' immediate */ - imm_BlendAxisTypes, - imm_BlueFuzz, - imm_BlueScale, - imm_BlueShift, - imm_BlueValues, - imm_CharStrings, - imm_Encoding, - imm_FamilyBlues, - imm_FamilyName, - imm_FamilyOtherBlues, - imm_FID, - imm_FontBBox, - imm_FontID, - imm_FontInfo, - imm_FontMatrix, - imm_FontName, - imm_FontType, - imm_ForceBold, - imm_FullName, - imm_ItalicAngle, - imm_LanguageGroup, - imm_Metrics, - imm_MinFeature, - imm_ND, - imm_NP, - imm_Notice, - imm_OtherBlues, - imm_OtherSubrs, - imm_PaintType, - imm_Private, - imm_RD, - imm_RndStemUp, - imm_StdHW, - imm_StdVW, - imm_StemSnapH, - imm_StemSnapV, - imm_StrokeWidth, - imm_Subrs, - imm_UnderlinePosition, - imm_UnderlineThickness, - imm_UniqueID, - imm_Weight, - - imm_isFixedPitch, - imm_lenIV, - imm_password, - imm_version, - - imm_NP_alternate, /* `|' = alternate form of NP */ - imm_ND_alternate, /* `|-' = alternate form of ND */ - - imm_max /* always keep this value here */ - - } T1_TokenType; - - - /* these arrays are visible for debugging purposes */ - extern const char* t1_keywords[]; - extern const char* t1_immediates[]; - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Token */ - /* */ - /* */ - /* A structure used to describe a token in the current input stream. */ - /* Note that the Type1 driver doesn't try to interpret tokens until */ - /* it really needs to. */ - /* */ - /* */ - /* kind :: The token type. Describes the token to the loader. */ - /* */ - /* kind2 :: Detailed token type. */ - /* */ - /* start :: The index of the first character of token in the input */ - /* stream. */ - /* */ - /* len :: The length of the token in characters. */ - /* */ - typedef struct T1_Token_ - { - T1_TokenType kind; /* simple type */ - T1_TokenType kind2; /* detailed type */ - FT_Int start; /* index of first token character */ - FT_Int len; /* length of token in chars */ - - } T1_Token; - - - typedef struct T1_TokenParser_ - { - FT_Memory memory; - FT_Stream stream; - - FT_Bool in_pfb; /* true if PFB file, PFA otherwise */ - FT_Bool in_private; /* true if in private dictionary */ - - FT_Byte* base; /* base address of current read buffer */ - FT_Long cursor; /* current position in read buffer */ - FT_Long limit; /* limit of current read buffer */ - FT_Long max; /* maximum size of read buffer */ - - FT_Error error; /* last error */ - T1_Token token; /* last token read */ - - } T1_TokenParser; - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Tokenizer */ - /* */ - /* */ - /* A handle to an object used to extract tokens from the input. The */ - /* object is able to perform PFA/PFB recognition, eexec decryption of */ - /* the private dictionary, as well as eexec decryption of the */ - /* charstrings. */ - /* */ - typedef T1_TokenParser* T1_Tokenizer; - - - LOCAL_DEF - FT_Error New_Tokenizer( FT_Stream stream, - T1_Tokenizer* tokenizer ); - - LOCAL_DEF - FT_Error Done_Tokenizer( T1_Tokenizer tokenizer ); - - LOCAL_DEF - FT_Error Open_PrivateDict( T1_Tokenizer tokenizer ); - - LOCAL_DEF - FT_Error Read_Token( T1_Tokenizer tokenizer ); - - -#if 0 - LOCAL_DEF - FT_Error Read_CharStrings( T1_Tokenizer tokenizer, - FT_Int num_chars, - FT_Byte* buffer ); -#endif /* 0 */ - - LOCAL_DEF - void t1_decrypt( FT_Byte* buffer, - FT_Int length, - FT_UShort seed ); - - -#ifdef __cplusplus - } -#endif - -#endif /* T1TOKENS_H */ - - -/* END */ diff --git a/src/freetype/type1/type1.c b/src/freetype/type1/type1.c deleted file mode 100644 index d2058d620f..0000000000 --- a/src/freetype/type1/type1.c +++ /dev/null @@ -1,59 +0,0 @@ -/***************************************************************************/ -/* */ -/* type1.c */ -/* */ -/* FreeType Type 1 driver component (body only). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#define FT_MAKE_OPTION_SINGLE_OBJECT - - -#ifdef FT_FLAT_COMPILE - -#include "t1driver.c" -#include "t1objs.c" -#include "t1load.c" -#include "t1gload.c" -#include "t1tokens.c" -#include "t1parse.c" - -#ifndef T1_CONFIG_OPTION_DISABLE_HINTER -#include "t1hinter.c" -#endif - -#ifndef T1_CONFIG_OPTION_NO_AFM -#include "t1afm.c" -#endif - -#else /* FT_FLAT_COMPILE */ - -#include -#include -#include -#include -#include -#include - -#ifndef T1_CONFIG_OPTION_DISABLE_HINTER -#include -#endif - -#ifndef T1_CONFIG_OPTION_NO_AFM -#include -#endif - -#endif /* FT_FLAT_COMPILE */ - - -/* END */ diff --git a/src/freetype/type1z/Readme.txt b/src/freetype/type1z/Readme.txt deleted file mode 100644 index 6502fb9d9f..0000000000 --- a/src/freetype/type1z/Readme.txt +++ /dev/null @@ -1,10 +0,0 @@ -This directory contains an experimental Type 1 driver that will ultimately -replace the "official" one in "src/type1". - -This driver doesn't provide a mini Postscript interpreter, but uses -pattern matching in order to load data from fonts. It works better and -faster than the official driver, but will replace it only when we finish -the auto-hinting module.. - -You don't need to compile it to support Type 1 fonts, the driver should -co-exist peacefully with the rest of the engine however.. diff --git a/src/freetype/type1z/module.mk b/src/freetype/type1z/module.mk deleted file mode 100644 index 545887d824..0000000000 --- a/src/freetype/type1z/module.mk +++ /dev/null @@ -1,7 +0,0 @@ -make_module_list: add_type1_driver - -add_type1_driver: - $(OPEN_DRIVER)t1_driver_class$(CLOSE_DRIVER) - $(ECHO_DRIVER)type1 $(ECHO_DRIVER_DESC)Postscript font files with extension *.pfa or *.pfb$(ECHO_DRIVER_DONE) - -# EOF diff --git a/src/freetype/type1z/rules.mk b/src/freetype/type1z/rules.mk deleted file mode 100644 index 3411fd171c..0000000000 --- a/src/freetype/type1z/rules.mk +++ /dev/null @@ -1,72 +0,0 @@ -# -# FreeType 2 Type1z driver configuration rules -# - - -# 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. - - -# Type1z driver directory -# -T1Z_DIR := $(SRC_)type1z -T1Z_DIR_ := $(T1Z_DIR)$(SEP) - - -# compilation flags for the driver -# -T1Z_COMPILE := $(FT_COMPILE) - - -# Type1 driver sources (i.e., C files) -# -T1Z_DRV_SRC := $(T1Z_DIR_)z1parse.c \ - $(T1Z_DIR_)z1load.c \ - $(T1Z_DIR_)z1driver.c \ - $(T1Z_DIR_)z1afm.c \ - $(T1Z_DIR_)z1gload.c \ - $(T1Z_DIR_)z1objs.c - -# Type1 driver headers -# -T1Z_DRV_H := $(T1Z_DRV_SRC:%.c=%.h) \ - $(T1Z_DIR_)z1tokens.h - - -# Type1z driver object(s) -# -# T1Z_DRV_OBJ_M is used during `multi' builds -# T1Z_DRV_OBJ_S is used during `single' builds -# -T1Z_DRV_OBJ_M := $(T1Z_DRV_SRC:$(T1Z_DIR_)%.c=$(OBJ_)%.$O) -T1Z_DRV_OBJ_S := $(OBJ_)type1z.$O - -# Type1z driver source file for single build -# -T1Z_DRV_SRC_S := $(T1Z_DIR_)type1z.c - - -# Type1z driver - single object -# -$(T1Z_DRV_OBJ_S): $(T1Z_DRV_SRC_S) $(T1Z_DRV_SRC) $(FREETYPE_H) $(T1Z_DRV_H) - $(T1Z_COMPILE) $T$@ $(T1Z_DRV_SRC_S) - - -# Type1z driver - multiple objects -# -$(OBJ_)%.$O: $(T1Z_DIR_)%.c $(FREETYPE_H) $(T1Z_DRV_H) - $(T1Z_COMPILE) $T$@ $< - - -# update main driver object lists -# -DRV_OBJS_S += $(T1Z_DRV_OBJ_S) -DRV_OBJS_M += $(T1Z_DRV_OBJ_M) - -# EOF diff --git a/src/freetype/type1z/type1z.c b/src/freetype/type1z/type1z.c deleted file mode 100644 index 17e89ac157..0000000000 --- a/src/freetype/type1z/type1z.c +++ /dev/null @@ -1,49 +0,0 @@ -/***************************************************************************/ -/* */ -/* type1z.c */ -/* */ -/* FreeType experimental Type 1 driver component (body only). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#define FT_MAKE_OPTION_SINGLE_OBJECT - - -#ifdef FT_FLAT_COMPILE - -#include "z1parse.c" -#include "z1load.c" -#include "z1objs.c" -#include "z1driver.c" -#include "z1gload.c" - -#ifndef Z1_CONFIG_OPTION_NO_AFM -#include "z1afm.c" -#endif - -#else /* FT_FLAT_COMPILE */ - -#include -#include -#include -#include -#include - -#ifndef Z1_CONFIG_OPTION_NO_AFM -#include -#endif - -#endif /* FT_FLAT_COMPILE */ - - -/* END */ diff --git a/src/freetype/type1z/z1afm.c b/src/freetype/type1z/z1afm.c deleted file mode 100644 index b329cd347f..0000000000 --- a/src/freetype/type1z/z1afm.c +++ /dev/null @@ -1,293 +0,0 @@ -/***************************************************************************/ -/* */ -/* z1afm.c */ -/* */ -/* AFM support for Type 1 fonts (body). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifdef FT_FLAT_COMPILE - -#include "z1afm.h" - -#else - -#include - -#endif - - -#include -#include - -#include /* for qsort() */ -#include /* for strcmp() */ -#include /* for isalnum() */ - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_z1afm - - - LOCAL_FUNC - void Z1_Done_AFM( FT_Memory memory, - Z1_AFM* afm ) - { - FREE( afm->kern_pairs ); - afm->num_pairs = 0; - } - - -#undef IS_KERN_PAIR -#define IS_KERN_PAIR( p ) ( p[0] == 'K' && p[1] == 'P' ) - -#define IS_ALPHANUM( c ) ( isalnum( c ) || \ - c == '_' || \ - c == '.' ) - - - /* read a glyph name and return the equivalent glyph index */ - static - FT_UInt afm_atoindex( FT_Byte** start, - FT_Byte* limit, - T1_Font* type1 ) - { - FT_Byte* p = *start; - FT_Int len; - FT_UInt result = 0; - char temp[64]; - - - /* skip whitespace */ - while ( ( *p == ' ' || *p == '\t' || *p == ':' || *p == ';' ) && - p < limit ) - p++; - *start = p; - - /* now, read glyph name */ - while ( IS_ALPHANUM( *p ) && p < limit ) - p++; - - len = p - *start; - - if ( len > 0 && len < 64 ) - { - FT_Int n; - - - /* copy glyph name to intermediate array */ - MEM_Copy( temp, *start, len ); - temp[len] = 0; - - /* lookup glyph name in face array */ - for ( n = 0; n < type1->num_glyphs; n++ ) - { - char* gname = (char*)type1->glyph_names[n]; - - - if ( gname && gname[0] == temp[0] && strcmp( gname, temp ) == 0 ) - { - result = n; - break; - } - } - } - *start = p; - return result; - } - - - /* read an integer */ - static - int afm_atoi( FT_Byte** start, - FT_Byte* limit ) - { - FT_Byte* p = *start; - int sum = 0; - int sign = 1; - - - /* skip everything that is not a number */ - while ( p < limit && !isdigit( *p ) ) - { - sign = 1; - if ( *p == '-' ) - sign = -1; - - p++; - } - - while ( p < limit && isdigit( *p ) ) - { - sum = sum * 10 + ( *p - '0' ); - p++; - } - *start = p; - - return sum * sign; - } - - -#undef KERN_INDEX -#define KERN_INDEX( g1, g2 ) ( ( (FT_ULong)g1 << 16 ) | g2 ) - - - /* compare two kerning pairs */ - static - int compare_kern_pairs( const void* a, - const void* b ) - { - Z1_Kern_Pair* pair1 = (Z1_Kern_Pair*)a; - Z1_Kern_Pair* pair2 = (Z1_Kern_Pair*)b; - - FT_ULong index1 = KERN_INDEX( pair1->glyph1, pair1->glyph2 ); - FT_ULong index2 = KERN_INDEX( pair2->glyph1, pair2->glyph2 ); - - - return ( index1 - index2 ); - } - - - /* parse an AFM file -- for now, only read the kerning pairs */ - LOCAL_FUNC - FT_Error Z1_Read_AFM( FT_Face t1_face, - FT_Stream stream ) - { - FT_Error error; - FT_Memory memory = stream->memory; - FT_Byte* start; - FT_Byte* limit; - FT_Byte* p; - FT_Int count = 0; - Z1_Kern_Pair* pair; - T1_Font* type1 = &((T1_Face)t1_face)->type1; - Z1_AFM* afm = 0; - - - if ( ACCESS_Frame( stream->size ) ) - return error; - - start = (FT_Byte*)stream->cursor; - limit = (FT_Byte*)stream->limit; - p = start; - - /* we are now going to count the occurences of `KP' or `KPX' in */ - /* the AFM file */ - count = 0; - for ( p = start; p < limit - 3; p++ ) - { - if ( IS_KERN_PAIR( p ) ) - count++; - } - - /* Actually, kerning pairs are simply optional! */ - if ( count == 0 ) - goto Exit; - - /* allocate the pairs */ - if ( ALLOC( afm, sizeof ( *afm ) ) || - ALLOC_ARRAY( afm->kern_pairs, count, Z1_Kern_Pair ) ) - goto Exit; - - /* now, read each kern pair */ - pair = afm->kern_pairs; - afm->num_pairs = count; - - /* save in face object */ - ((T1_Face)t1_face)->afm_data = afm; - - for ( p = start; p < limit - 3; p++ ) - { - if ( IS_KERN_PAIR( p ) ) - { - FT_Byte* q; - - - /* skip keyword (KP or KPX) */ - q = p + 2; - if ( *q == 'X' ) - q++; - - pair->glyph1 = afm_atoindex( &q, limit, type1 ); - pair->glyph2 = afm_atoindex( &q, limit, type1 ); - pair->kerning.x = afm_atoi( &q, limit ); - - pair->kerning.y = 0; - if ( p[2] != 'X' ) - pair->kerning.y = afm_atoi( &q, limit ); - - pair++; - } - } - - /* now, sort the kern pairs according to their glyph indices */ - qsort( afm->kern_pairs, count, sizeof ( Z1_Kern_Pair ), - compare_kern_pairs ); - - Exit: - if ( error ) - FREE( afm ); - - FORGET_Frame(); - - return error; - } - - - /* find the kerning for a given glyph pair */ - LOCAL_FUNC - void Z1_Get_Kerning( Z1_AFM* afm, - FT_UInt glyph1, - FT_UInt glyph2, - FT_Vector* kerning ) - { - Z1_Kern_Pair *min, *mid, *max; - FT_ULong index = KERN_INDEX( glyph1, glyph2 ); - - - /* simple binary search */ - min = afm->kern_pairs; - max = min + afm->num_pairs - 1; - - while ( min <= max ) - { - FT_ULong midi; - - - mid = min + ( max - min ) / 2; - midi = KERN_INDEX( mid->glyph1, mid->glyph2 ); - - if ( midi == index ) - { - *kerning = mid->kerning; - return; - } - - if ( midi < index ) - min = mid + 1; - else - max = mid - 1; - } - - kerning->x = 0; - kerning->y = 0; - } - - -/* END */ diff --git a/src/freetype/type1z/z1afm.h b/src/freetype/type1z/z1afm.h deleted file mode 100644 index bfacce7135..0000000000 --- a/src/freetype/type1z/z1afm.h +++ /dev/null @@ -1,79 +0,0 @@ -/***************************************************************************/ -/* */ -/* z1afm.h */ -/* */ -/* AFM support for Type 1 fonts (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifndef Z1AFM_H -#define Z1AFM_H - - -#ifdef FT_FLAT_COMPILE - -#include "z1objs.h" - -#else - -#include - -#endif - - -#ifdef __cplusplus - extern "C" { -#endif - - - typedef struct Z1_Kern_Pair_ - { - FT_UInt glyph1; - FT_UInt glyph2; - FT_Vector kerning; - - } Z1_Kern_Pair; - - - typedef struct Z1_AFM_ - { - FT_Int num_pairs; - Z1_Kern_Pair* kern_pairs; - - } Z1_AFM; - - - LOCAL_DEF - FT_Error Z1_Read_AFM( FT_Face face, - FT_Stream stream ); - - LOCAL_DEF - void Z1_Done_AFM( FT_Memory memory, - Z1_AFM* afm ); - - LOCAL_DEF - void Z1_Get_Kerning( Z1_AFM* afm, - FT_UInt glyph1, - FT_UInt glyph2, - FT_Vector* kerning ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* Z1AFM_H */ - - -/* END */ diff --git a/src/freetype/type1z/z1driver.c b/src/freetype/type1z/z1driver.c deleted file mode 100644 index aea2c10f1f..0000000000 --- a/src/freetype/type1z/z1driver.c +++ /dev/null @@ -1,340 +0,0 @@ -/***************************************************************************/ -/* */ -/* z1driver.c */ -/* */ -/* Experimental Type 1 driver interface (body). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifdef FT_FLAT_COMPILE - -#include "z1driver.h" -#include "z1gload.h" -#include "z1load.h" -#include "z1afm.h" - -#else - -#include -#include -#include -#include - -#endif - - -#include -#include -#include - -#include /* for strcmp() */ - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_z1driver - - - static - FT_Error get_z1_glyph_name( T1_Face face, - FT_UInt glyph_index, - FT_Pointer buffer, - FT_UInt buffer_max ) - { - FT_String* gname; - - - gname = face->type1.glyph_names[glyph_index]; - - if ( buffer_max > 0 ) - { - FT_UInt len = strlen( gname ); - - - if (len >= buffer_max) - len = buffer_max - 1; - - MEM_Copy( buffer, gname, len ); - ((FT_Byte*)buffer)[len] = 0; - } - - return T1_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Get_Interface */ - /* */ - /* */ - /* Each driver can provide one or more extensions to the base */ - /* FreeType API. These can be used to access format specific */ - /* features (e.g., all TrueType/OpenType resources share a common */ - /* file structure and common tables which can be accessed through the */ - /* `sfnt' interface), or more simply generic ones (e.g., the */ - /* `postscript names' interface which can be used to retrieve the */ - /* PostScript name of a given glyph index). */ - /* */ - /* */ - /* driver :: A handle to a driver object. */ - /* */ - /* */ - /* interface :: A string designing the interface. Examples are */ - /* `sfnt', `post_names', `charmaps', etc. */ - /* */ - /* */ - /* A typeless pointer to the extension's interface (normally a table */ - /* of function pointers). Returns NULL if the requested extension */ - /* isn't available (i.e., wasn't compiled in the driver at build */ - /* time). */ - /* */ - static - FT_Module_Interface Get_Interface( FT_Driver driver, - const FT_String* interface ) - { - FT_UNUSED( driver ); - FT_UNUSED( interface ); - - if ( strcmp( (const char*)interface, "glyph_name" ) == 0 ) - return (FT_Module_Interface)get_z1_glyph_name; - -#ifndef Z1_CONFIG_OPTION_NO_MM_SUPPORT - if ( strcmp( (const char*)interface, "get_mm" ) == 0 ) - return (FT_Module_Interface)Z1_Get_Multi_Master; - - if ( strcmp( (const char*)interface, "set_mm_design") == 0 ) - return (FT_Module_Interface)Z1_Set_MM_Design; - - if ( strcmp( (const char*)interface, "set_mm_blend") == 0 ) - return (FT_Module_Interface)Z1_Set_MM_Blend; -#endif - return 0; - } - - -#ifndef Z1_CONFIG_OPTION_NO_AFM - - /*************************************************************************/ - /* */ - /* */ - /* Get_Kerning */ - /* */ - /* */ - /* A driver method used to return the kerning vector between two */ - /* glyphs of the same face. */ - /* */ - /* */ - /* face :: A handle to the source face object. */ - /* */ - /* left_glyph :: The index of the left glyph in the kern pair. */ - /* */ - /* right_glyph :: The index of the right glyph in the kern pair. */ - /* */ - /* */ - /* kerning :: The kerning vector. This is in font units for */ - /* scalable formats, and in pixels for fixed-sizes */ - /* formats. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Only horizontal layouts (left-to-right & right-to-left) are */ - /* supported by this function. Other layouts, or more sophisticated */ - /* kernings are out of scope of this method (the basic driver */ - /* interface is meant to be simple). */ - /* */ - /* They can be implemented by format-specific interfaces. */ - /* */ - static - FT_Error Get_Kerning( T1_Face face, - FT_UInt left_glyph, - FT_UInt right_glyph, - FT_Vector* kerning ) - { - Z1_AFM* afm; - - - kerning->x = 0; - kerning->y = 0; - - afm = (Z1_AFM*)face->afm_data; - if ( afm ) - Z1_Get_Kerning( afm, left_glyph, right_glyph, kerning ); - - return T1_Err_Ok; - } - - -#endif /* T1_CONFIG_OPTION_NO_AFM */ - - - /*************************************************************************/ - /* */ - /* */ - /* Get_Char_Index */ - /* */ - /* */ - /* Uses a charmap to return a given character code's glyph index. */ - /* */ - /* */ - /* charmap :: A handle to the source charmap object. */ - /* charcode :: The character code. */ - /* */ - /* */ - /* Glyph index. 0 means `undefined character code'. */ - /* */ - static - FT_UInt Get_Char_Index( FT_CharMap charmap, - FT_Long charcode ) - { - T1_Face face; - FT_UInt result = 0; - PSNames_Interface* psnames; - - - face = (T1_Face)charmap->face; - psnames = (PSNames_Interface*)face->psnames; - if ( psnames ) - switch ( charmap->encoding ) - { - /*******************************************************************/ - /* */ - /* Unicode encoding support */ - /* */ - case ft_encoding_unicode: - /* use the `PSNames' module to synthetize the Unicode charmap */ - result = psnames->lookup_unicode( &face->unicode_map, - (FT_ULong)charcode ); - - /* the function returns 0xFFFF if the Unicode charcode has */ - /* no corresponding glyph */ - if ( result == 0xFFFF ) - result = 0; - goto Exit; - - /*******************************************************************/ - /* */ - /* Custom Type 1 encoding */ - /* */ - case ft_encoding_adobe_custom: - { - T1_Encoding* encoding = &face->type1.encoding; - - - if ( charcode >= encoding->code_first && - charcode <= encoding->code_last ) - result = encoding->char_index[charcode]; - goto Exit; - } - - /*******************************************************************/ - /* */ - /* Adobe Standard & Expert encoding support */ - /* */ - default: - if ( charcode < 256 ) - { - FT_UInt code; - FT_Int n; - const char* glyph_name; - - - code = psnames->adobe_std_encoding[charcode]; - if ( charmap->encoding == ft_encoding_adobe_expert ) - code = psnames->adobe_expert_encoding[charcode]; - - glyph_name = psnames->adobe_std_strings( code ); - if ( !glyph_name ) - break; - - for ( n = 0; n < face->type1.num_glyphs; n++ ) - { - const char* gname = face->type1.glyph_names[n]; - - - if ( gname && gname[0] == glyph_name[0] && - strcmp( gname, glyph_name ) == 0 ) - { - result = n; - break; - } - } - } - } - Exit: - return result; - } - - - const FT_Driver_Class t1_driver_class = - { - { - ft_module_font_driver | ft_module_driver_scalable, - sizeof( FT_DriverRec ), - - "type1", - 0x10000L, - 0x20000L, - - 0, /* format interface */ - - (FT_Module_Constructor)Z1_Init_Driver, - (FT_Module_Destructor) Z1_Done_Driver, - (FT_Module_Requester) Get_Interface, - }, - - sizeof( T1_FaceRec ), - sizeof( Z1_SizeRec ), - sizeof( Z1_GlyphSlotRec ), - - (FTDriver_initFace) Z1_Init_Face, - (FTDriver_doneFace) Z1_Done_Face, - (FTDriver_initSize) 0, - (FTDriver_doneSize) 0, - (FTDriver_initGlyphSlot)0, - (FTDriver_doneGlyphSlot)0, - - (FTDriver_setCharSizes) 0, - (FTDriver_setPixelSizes)0, - (FTDriver_loadGlyph) Z1_Load_Glyph, - (FTDriver_getCharIndex) Get_Char_Index, - -#ifdef Z1_CONFIG_OPTION_NO_AFM - (FTDriver_getKerning) 0, - (FTDriver_attachFile) 0, -#else - (FTDriver_getKerning) Get_Kerning, - (FTDriver_attachFile) Z1_Read_AFM, -#endif - (FTDriver_getAdvances) 0 - }; - - -#ifdef FT_CONFIG_OPTION_DYNAMIC_DRIVERS - - EXPORT_FUNC( const FT_Driver_Class* ) getDriverClass( void ) - { - return &t1z_driver_class; - } - -#endif /* FT_CONFIG_OPTION_DYNAMIC_DRIVERS */ - - -/* END */ diff --git a/src/freetype/type1z/z1driver.h b/src/freetype/type1z/z1driver.h deleted file mode 100644 index 08bd544d56..0000000000 --- a/src/freetype/type1z/z1driver.h +++ /dev/null @@ -1,29 +0,0 @@ -/***************************************************************************/ -/* */ -/* z1driver.h */ -/* */ -/* High-level experimental Type 1 driver interface (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifndef Z1DRIVER_H -#define Z1DRIVER_H - -#include - - FT_EXPORT_VAR( const FT_Driver_Class ) t1_driver_class; - -#endif /* Z1DRIVER_H */ - - -/* END */ diff --git a/src/freetype/type1z/z1gload.c b/src/freetype/type1z/z1gload.c deleted file mode 100644 index 0b25d2ecc7..0000000000 --- a/src/freetype/type1z/z1gload.c +++ /dev/null @@ -1,1482 +0,0 @@ -/***************************************************************************/ -/* */ -/* z1gload.c */ -/* */ -/* Experimental Type 1 Glyph Loader (body). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifdef FT_FLAT_COMPILE - -#include "z1gload.h" - -#else - -#include - -#endif - - -#include -#include -#include - -#include /* for strcmp() */ - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_z1gload - - - typedef enum Z1_Operator_ - { - op_none = 0, - op_endchar, - op_hsbw, - op_seac, - op_sbw, - op_closepath, - op_hlineto, - op_hmoveto, - op_hvcurveto, - op_rlineto, - op_rmoveto, - op_rrcurveto, - op_vhcurveto, - op_vlineto, - op_vmoveto, - op_dotsection, - op_hstem, - op_hstem3, - op_vstem, - op_vstem3, - op_div, - op_callothersubr, - op_callsubr, - op_pop, - op_return, - op_setcurrentpoint, - - op_max /* never remove this one */ - - } Z1_Operator; - - static - const FT_Int t1_args_count[op_max] = - { - 0, /* none */ - 0, /* endchar */ - 2, /* hsbw */ - 5, /* seac */ - 4, /* sbw */ - 0, /* closepath */ - 1, /* hlineto */ - 1, /* hmoveto */ - 4, /* hvcurveto */ - 2, /* rlineto */ - 2, /* rmoveto */ - 6, /* rrcurveto */ - 4, /* vhcurveto */ - 1, /* vlineto */ - 1, /* vmoveto */ - 0, /* dotsection */ - 2, /* hstem */ - 6, /* hstem3 */ - 2, /* vstem */ - 6, /* vstem3 */ - 2, /* div */ - -1, /* callothersubr */ - 1, /* callsubr */ - 0, /* pop */ - 0, /* return */ - 2 /* setcurrentpoint */ - }; - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********** *********/ - /********** *********/ - /********** GENERIC CHARSTRING PARSING *********/ - /********** *********/ - /********** *********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_Init_Builder */ - /* */ - /* */ - /* Initializes a given glyph builder. */ - /* */ - /* */ - /* builder :: A pointer to the glyph builder to initialize. */ - /* */ - /* */ - /* face :: The current face object. */ - /* */ - /* size :: The current size object. */ - /* */ - /* glyph :: The current glyph object. */ - /* */ - LOCAL_FUNC - void Z1_Init_Builder( Z1_Builder* builder, - T1_Face face, - Z1_Size size, - Z1_GlyphSlot glyph ) - { - builder->path_begun = 0; - builder->load_points = 1; - - builder->face = face; - builder->glyph = glyph; - builder->memory = face->root.memory; - - if ( glyph ) - { - FT_GlyphLoader* loader = glyph->root.loader; - - - builder->loader = loader; - builder->current = &loader->current.outline; - builder->base = &loader->base.outline; - - FT_GlyphLoader_Rewind( loader ); - } - - if ( size ) - { - builder->scale_x = size->root.metrics.x_scale; - builder->scale_y = size->root.metrics.y_scale; - } - - builder->pos_x = 0; - builder->pos_y = 0; - - builder->left_bearing.x = 0; - builder->left_bearing.y = 0; - builder->advance.x = 0; - builder->advance.y = 0; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_Done_Builder */ - /* */ - /* */ - /* Finalizes a given glyph builder. Its contents can still be used */ - /* after the call, but the function saves important information */ - /* within the corresponding glyph slot. */ - /* */ - /* */ - /* builder :: A pointer to the glyph builder to finalize. */ - /* */ - LOCAL_FUNC - void Z1_Done_Builder( Z1_Builder* builder ) - { - Z1_GlyphSlot glyph = builder->glyph; - - - if ( glyph ) - glyph->root.outline = *builder->base; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_Init_Decoder */ - /* */ - /* */ - /* Initializes a given glyph decoder. */ - /* */ - /* */ - /* decoder :: A pointer to the glyph builder to initialize. */ - /* */ - LOCAL_FUNC - void Z1_Init_Decoder( Z1_Decoder* decoder ) - { - decoder->top = 0; - decoder->zone = 0; - decoder->flex_state = 0; - decoder->num_flex_vectors = 0; - decoder->blend = 0; - - /* Clear loader */ - MEM_Set( &decoder->builder, 0, sizeof ( decoder->builder ) ); - } - - - /* check that there is enough space for `count' more points */ - static - FT_Error check_points( Z1_Builder* builder, - FT_Int count ) - { - return FT_GlyphLoader_Check_Points( builder->loader, count, 0 ); - } - - - /* add a new point; do not check space */ - static - void add_point( Z1_Builder* builder, - FT_Pos x, - FT_Pos y, - FT_Byte flag ) - { - FT_Outline* outline = builder->current; - - - if ( builder->load_points ) - { - FT_Vector* point = outline->points + outline->n_points; - FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points; - - - point->x = x; - point->y = y; - *control = flag ? FT_Curve_Tag_On : FT_Curve_Tag_Cubic; - - builder->last = *point; - } - - outline->n_points++; - } - - - /* check space for a new on-curve point, then add it */ - static - FT_Error add_point1( Z1_Builder* builder, - FT_Pos x, - FT_Pos y ) - { - FT_Error error; - - - error = check_points( builder, 1 ); - if ( !error ) - add_point( builder, x, y, 1 ); - - return error; - } - - - /* check space for a new contour, then add it */ - static - FT_Error add_contour( Z1_Builder* builder ) - { - FT_Outline* outline = builder->current; - FT_Error error; - - - if ( !builder->load_points ) - { - outline->n_contours++; - return FT_Err_Ok; - } - - /* reallocate contours array if necessary */ - error = FT_GlyphLoader_Check_Points( builder->loader, 0, 1 ); - if ( !error ) - { - if ( outline->n_contours > 0 ) - outline->contours[outline->n_contours - 1] = outline->n_points - 1; - - outline->n_contours++; - } - - return error; - } - - - /* if a path was begun, add its first on-curve point */ - static - FT_Error start_point( Z1_Builder* builder, - FT_Pos x, - FT_Pos y ) - { - /* test whether we are building a new contour */ - if ( !builder->path_begun ) - { - FT_Error error; - - - builder->path_begun = 1; - error = add_contour( builder ); - if ( error ) - return error; - } - return add_point1( builder, x, y ); - } - - - /* close the current contour */ - static - void close_contour( Z1_Builder* builder ) - { - FT_Outline* outline = builder->current; - - - /* XXX: we must not include the last point in the path if it */ - /* is located on the first point */ - if ( outline->n_points > 1 ) - { - FT_Int first = 0; - FT_Vector* p1 = outline->points + first; - FT_Vector* p2 = outline->points + outline->n_points-1; - - - if ( outline->n_contours > 1 ) - { - first = outline->contours[outline->n_contours - 2] + 1; - p1 = outline->points + first; - } - - if ( p1->x == p2->x && p1->y == p2->y ) - outline->n_points--; - } - - if ( outline->n_contours > 0 ) - outline->contours[outline->n_contours - 1] = outline->n_points - 1; - } - - - /*************************************************************************/ - /* */ - /* */ - /* lookup_glyph_by_stdcharcode */ - /* */ - /* */ - /* Looks up a given glyph by its StandardEncoding charcode. Used */ - /* to implement the SEAC Type 1 operator. */ - /* */ - /* */ - /* face :: The current face object. */ - /* */ - /* charcode :: The character code to look for. */ - /* */ - /* */ - /* A glyph index in the font face. Returns -1 if the corresponding */ - /* glyph wasn't found. */ - /* */ - static - FT_Int lookup_glyph_by_stdcharcode( T1_Face face, - FT_Int charcode ) - { - FT_Int n; - const FT_String* glyph_name; - PSNames_Interface* psnames = (PSNames_Interface*)face->psnames; - - - /* check range of standard char code */ - if ( charcode < 0 || charcode > 255 ) - return -1; - - glyph_name = psnames->adobe_std_strings( - psnames->adobe_std_encoding[charcode]); - - for ( n = 0; n < face->type1.num_glyphs; n++ ) - { - FT_String* name = (FT_String*)face->type1.glyph_names[n]; - - - if ( name && strcmp( name,glyph_name ) == 0 ) - return n; - } - - return -1; - } - - - /*************************************************************************/ - /* */ - /* */ - /* t1operator_seac */ - /* */ - /* */ - /* Implements the `seac' Type 1 operator for a Type 1 decoder. */ - /* */ - /* */ - /* decoder :: The current CID decoder. */ - /* */ - /* asb :: The accent's side bearing. */ - /* */ - /* adx :: The horizontal offset of the accent. */ - /* */ - /* ady :: The vertical offset of the accent. */ - /* */ - /* bchar :: The base character's StandardEncoding charcode. */ - /* */ - /* achar :: The accent character's StandardEncoding charcode. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error t1operator_seac( Z1_Decoder* decoder, - FT_Pos asb, - FT_Pos adx, - FT_Pos ady, - FT_Int bchar, - FT_Int achar ) - { - FT_Error error; - FT_Int bchar_index, achar_index, n_base_points; - FT_Outline* base = decoder->builder.base; - FT_Vector left_bearing, advance; - T1_Face face = decoder->builder.face; - T1_Font* type1 = &face->type1; - - - bchar_index = lookup_glyph_by_stdcharcode( face, bchar ); - achar_index = lookup_glyph_by_stdcharcode( face, achar ); - - if ( bchar_index < 0 || achar_index < 0 ) - { - FT_ERROR(( "t1operator_seac:" )); - FT_ERROR(( " invalid seac character code arguments\n" )); - return T1_Err_Syntax_Error; - } - - /* if we are trying to load a composite glyph, do not load the */ - /* accent character and return the array of subglyphs. */ - if ( decoder->builder.no_recurse ) - { - FT_GlyphSlot glyph = (FT_GlyphSlot)decoder->builder.glyph; - FT_GlyphLoader* loader = glyph->loader; - FT_SubGlyph* subg; - - - /* reallocate subglyph array if necessary */ - error = FT_GlyphLoader_Check_Subglyphs( loader, 2 ); - if ( error ) - goto Exit; - - subg = loader->current.subglyphs; - - /* subglyph 0 = base character */ - subg->index = bchar_index; - subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES | - FT_SUBGLYPH_FLAG_USE_MY_METRICS; - subg->arg1 = 0; - subg->arg2 = 0; - subg++; - - /* subglyph 1 = accent character */ - subg->index = achar_index; - subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES; - subg->arg1 = adx - asb; - subg->arg2 = ady; - - /* set up remaining glyph fields */ - glyph->num_subglyphs = 2; - glyph->subglyphs = loader->base.subglyphs; - glyph->format = ft_glyph_format_composite; - - loader->current.num_subglyphs = 2; - } - - /* First load `bchar' in builder */ - /* now load the unscaled outline */ - - FT_GlyphLoader_Prepare( decoder->builder.loader ); /* prepare loader */ - - error = Z1_Parse_CharStrings( decoder, - type1->charstrings [bchar_index], - type1->charstrings_len[bchar_index], - type1->num_subrs, - type1->subrs, - type1->subrs_len ); - if ( error ) - goto Exit; - - n_base_points = base->n_points; - - /* save the left bearing and width of the base character */ - /* as they will be erased by the next load. */ - - left_bearing = decoder->builder.left_bearing; - advance = decoder->builder.advance; - - decoder->builder.left_bearing.x = 0; - decoder->builder.left_bearing.y = 0; - - /* Now load `achar' on top of */ - /* the base outline */ - error = Z1_Parse_CharStrings( decoder, - type1->charstrings [achar_index], - type1->charstrings_len[achar_index], - type1->num_subrs, - type1->subrs, - type1->subrs_len ); - if ( error ) - return error; - - /* restore the left side bearing and */ - /* advance width of the base character */ - - decoder->builder.left_bearing = left_bearing; - decoder->builder.advance = advance; - - /* Finally, move the accent */ - if ( decoder->builder.load_points ) - { - FT_Outline dummy; - - - dummy.n_points = base->n_points - n_base_points; - dummy.points = base->points + n_base_points; - FT_Outline_Translate( &dummy, adx - asb, ady ); - } - - Exit: - return error; - } - - -#define USE_ARGS( n ) do \ - { \ - top -= n; \ - if ( top < decoder->stack ) \ - goto Stack_Underflow; \ - } while ( 0 ) - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_Parse_CharStrings */ - /* */ - /* */ - /* Parses a given Type 1 charstrings program. */ - /* */ - /* */ - /* decoder :: The current Type 1 decoder. */ - /* */ - /* charstring_base :: The base address of the charstring stream. */ - /* */ - /* charstring_len :: The length in bytes of the charstring stream. */ - /* */ - /* num_subrs :: The number of sub-routines. */ - /* */ - /* subrs_base :: An array of sub-routines addresses. */ - /* */ - /* subrs_len :: An array of sub-routines lengths. */ - /* */ - /* */ - /* Free error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error Z1_Parse_CharStrings( Z1_Decoder* decoder, - FT_Byte* charstring_base, - FT_Int charstring_len, - FT_Int num_subrs, - FT_Byte** subrs_base, - FT_Int* subrs_len ) - { - FT_Error error; - Z1_Decoder_Zone* zone; - FT_Byte* ip; - FT_Byte* limit; - Z1_Builder* builder = &decoder->builder; - FT_Outline* outline; - FT_Pos x, y; - - - /* First of all, initialize the decoder */ - decoder->top = decoder->stack; - decoder->zone = decoder->zones; - zone = decoder->zones; - - builder->path_begun = 0; - - zone->base = charstring_base; - limit = zone->limit = charstring_base + charstring_len; - ip = zone->cursor = zone->base; - - error = T1_Err_Ok; - outline = builder->current; - - x = builder->pos_x; - y = builder->pos_y; - - /* now, execute loop */ - while ( ip < limit ) - { - FT_Int* top = decoder->top; - Z1_Operator op = op_none; - FT_Long value = 0; - - - /*********************************************************************/ - /* */ - /* Decode operator or operand */ - /* */ - /* */ - - /* first of all, decompress operator or value */ - switch ( *ip++ ) - { - case 1: - op = op_hstem; - break; - - case 3: - op = op_vstem; - break; - case 4: - op = op_vmoveto; - break; - case 5: - op = op_rlineto; - break; - case 6: - op = op_hlineto; - break; - case 7: - op = op_vlineto; - break; - case 8: - op = op_rrcurveto; - break; - case 9: - op = op_closepath; - break; - case 10: - op = op_callsubr; - break; - case 11: - op = op_return; - break; - - case 13: - op = op_hsbw; - break; - case 14: - op = op_endchar; - break; - - case 21: - op = op_rmoveto; - break; - case 22: - op = op_hmoveto; - break; - - case 30: - op = op_vhcurveto; - break; - case 31: - op = op_hvcurveto; - break; - - case 12: - if ( ip > limit ) - { - FT_ERROR(( "Z1_Parse_CharStrings: invalid escape (12+EOF)\n" )); - goto Syntax_Error; - } - - switch ( *ip++ ) - { - case 0: - op = op_dotsection; - break; - case 1: - op = op_vstem3; - break; - case 2: - op = op_hstem3; - break; - case 6: - op = op_seac; - break; - case 7: - op = op_sbw; - break; - case 12: - op = op_div; - break; - case 16: - op = op_callothersubr; - break; - case 17: - op = op_pop; - break; - case 33: - op = op_setcurrentpoint; - break; - - default: - FT_ERROR(( "Z1_Parse_CharStrings: invalid escape (12+%d)\n", - ip[-1] )); - goto Syntax_Error; - } - break; - - case 255: /* four bytes integer */ - if ( ip + 4 > limit ) - { - FT_ERROR(( "Z1_Parse_CharStrings: unexpected EOF in integer\n" )); - goto Syntax_Error; - } - - value = ( (FT_Long)ip[0] << 24 ) | - ( (FT_Long)ip[1] << 16 ) | - ( (FT_Long)ip[2] << 8 ) | - ip[3]; - ip += 4; - break; - - default: - if ( ip[-1] >= 32 ) - { - if ( ip[-1] < 247 ) - value = (FT_Long)ip[-1] - 139; - else - { - if ( ++ip > limit ) - { - FT_ERROR(( "Z1_Parse_CharStrings:" )); - FT_ERROR(( " unexpected EOF in integer\n" )); - goto Syntax_Error; - } - - if ( ip[-2] < 251 ) - value = ( (FT_Long)( ip[-2] - 247 ) << 8 ) + ip[-1] + 108; - else - value = -( ( ( (FT_Long)ip[-2] - 251 ) << 8 ) + ip[-1] + 108 ); - } - } - else - { - FT_ERROR(( "Z1_Parse_CharStrings: invalid byte (%d)\n", - ip[-1] )); - goto Syntax_Error; - } - } - - /*********************************************************************/ - /* */ - /* Push value on stack, or process operator */ - /* */ - /* */ - if ( op == op_none ) - { - if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS ) - { - FT_ERROR(( "Z1_Parse_CharStrings: stack overflow!\n" )); - goto Syntax_Error; - } - - FT_TRACE4(( " %ld", value )); - - *top++ = value; - decoder->top = top; - } - else if ( op == op_callothersubr ) /* callothersubr */ - { - FT_TRACE4(( " callothersubr" )); - - if ( top - decoder->stack < 2 ) - goto Stack_Underflow; - - top -= 2; - switch ( top[1] ) - { - case 1: /* start flex feature */ - if ( top[0] != 0 ) - goto Unexpected_OtherSubr; - - decoder->flex_state = 1; - decoder->num_flex_vectors = 0; - if ( start_point( builder, x, y ) || - check_points( builder, 6 ) ) - goto Memory_Error; - break; - - case 2: /* add flex vectors */ - { - FT_Int index; - - if ( top[0] != 0 ) - goto Unexpected_OtherSubr; - - /* note that we should not add a point for index 0; */ - /* this will move our current position to the flex */ - /* point without adding any point to the outline */ - index = decoder->num_flex_vectors++; - if ( index > 0 && index < 7 ) - add_point( builder, - x, - y, - (FT_Byte)( index == 3 || index == 6 ) ); - } - break; - - case 0: /* end flex feature */ - if ( top[0] != 3 ) - goto Unexpected_OtherSubr; - - if ( decoder->flex_state == 0 || - decoder->num_flex_vectors != 7 ) - { - FT_ERROR(( "Z1_Parse_CharStrings: unexpected flex end\n" )); - goto Syntax_Error; - } - - /* now consume the remaining `pop pop setcurpoint' */ - if ( ip + 6 > limit || - ip[0] != 12 || ip[1] != 17 || /* pop */ - ip[2] != 12 || ip[3] != 17 || /* pop */ - ip[4] != 12 || ip[5] != 33 ) /* setcurpoint */ - { - FT_ERROR(( "Z1_Parse_CharStrings: invalid flex charstring\n" )); - goto Syntax_Error; - } - - ip += 6; - decoder->flex_state = 0; - break; - - case 3: /* change hints */ - if ( top[0] != 1 ) - goto Unexpected_OtherSubr; - - /* eat the following `pop' */ - if ( ip + 2 > limit ) - { - FT_ERROR(( "Z1_Parse_CharStrings: invalid escape (12+%d)\n", - ip[-1] )); - goto Syntax_Error; - } - - if ( ip[0] != 12 || ip[1] != 17 ) - { - FT_ERROR(( "Z1_Parse_CharStrings:" )); - FT_ERROR(( " `pop' expected, found (%d %d)\n", - ip[0], ip[1] )); - goto Syntax_Error; - } - ip += 2; - break; - - case 12: - case 13: - /* counter control hints, clear stack */ - top = decoder->stack; - break; - - case 14: - case 15: - case 16: - case 17: - case 18: /* multiple masters */ - { - T1_Blend* blend = decoder->blend; - FT_UInt num_points, nn, mm; - FT_Int* delta; - FT_Int* values; - - - if ( !blend ) - { - FT_ERROR(( "Z1_Parse_CharStrings:" )); - FT_ERROR(( " unexpected multiple masters operator!\n" )); - goto Syntax_Error; - } - - num_points = top[1] - 13 + ( top[1] == 18 ); - if ( top[0] != (FT_Int)( num_points * blend->num_designs ) ) - { - FT_ERROR(( "Z1_Parse_CharStrings:" )); - FT_ERROR(( " incorrect number of mm arguments\n" )); - goto Syntax_Error; - } - - top -= blend->num_designs*num_points; - if ( top < decoder->stack ) - goto Stack_Underflow; - - /* we want to compute: */ - /* */ - /* a0*w0 + a1*w1 + ... + ak*wk */ - /* */ - /* but we only have the a0, a1-a0, a2-a0, .. ak-a0 */ - /* however, given that w0 + w1 + ... + wk == 1, we can */ - /* rewrite it easily as: */ - /* */ - /* a0 + (a1-a0)*w1 + (a2-a0)*w2 + .. + (ak-a0)*wk */ - /* */ - /* where k == num_designs-1 */ - /* */ - /* I guess that's why it's written in this `compact' */ - /* form. */ - /* */ - delta = top + num_points; - values = top; - for ( nn = 0; nn < num_points; nn++ ) - { - FT_Int x = values[0]; - - - for ( mm = 1; mm < blend->num_designs; mm++ ) - x += FT_MulFix( *delta++, blend->weight_vector[mm] ); - - *values++ = x; - } - /* note that `top' will be incremented later by calls to `pop' */ - break; - } - - default: - Unexpected_OtherSubr: - FT_ERROR(( "Z1_Parse_CharStrings: invalid othersubr [%d %d]!\n", - top[0], top[1] )); - goto Syntax_Error; - } - decoder->top = top; - } - else /* general operator */ - { - FT_Int num_args = t1_args_count[op]; - - - if ( top - decoder->stack < num_args ) - goto Stack_Underflow; - - top -= num_args; - - switch ( op ) - { - case op_endchar: - FT_TRACE4(( " endchar" )); - - close_contour( builder ); - - /* add current outline to the glyph slot */ - FT_GlyphLoader_Add( builder->loader ); - - /* return now! */ - FT_TRACE4(( "\n\n" )); - return T1_Err_Ok; - - case op_hsbw: - FT_TRACE4(( " hsbw" )); - - builder->left_bearing.x += top[0]; - builder->advance.x = top[1]; - builder->advance.y = 0; - - builder->last.x = x = top[0]; - builder->last.y = y = 0; - - /* the `metrics_only' indicates that we only want to compute */ - /* the glyph's metrics (lsb + advance width), not load the */ - /* rest of it; so exit immediately */ - if ( builder->metrics_only ) - return T1_Err_Ok; - - break; - - case op_seac: - /* return immediately after the processing */ - return t1operator_seac( decoder, top[0], top[1], - top[2], top[3], top[4] ); - - case op_sbw: - FT_TRACE4(( " sbw" )); - - builder->left_bearing.x += top[0]; - builder->left_bearing.y += top[1]; - builder->advance.x = top[2]; - builder->advance.y = top[3]; - - builder->last.x = x = top[0]; - builder->last.y = y = top[1]; - - /* the `metrics_only' indicates that we only want to compute */ - /* the glyph's metrics (lsb + advance width), not load the */ - /* rest of it; so exit immediately */ - if ( builder->metrics_only ) - return T1_Err_Ok; - - break; - - case op_closepath: - FT_TRACE4(( " closepath" )); - - close_contour( builder ); - builder->path_begun = 0; - break; - - case op_hlineto: - FT_TRACE4(( " hlineto" )); - - if ( start_point( builder, x, y ) ) - goto Memory_Error; - - x += top[0]; - goto Add_Line; - - case op_hmoveto: - FT_TRACE4(( " hmoveto" )); - - x += top[0]; - break; - - case op_hvcurveto: - FT_TRACE4(( " hvcurveto" )); - - if ( start_point( builder, x, y ) || - check_points( builder, 3 ) ) - goto Memory_Error; - - x += top[0]; - add_point( builder, x, y, 0 ); - x += top[1]; - y += top[2]; - add_point( builder, x, y, 0 ); - y += top[3]; - add_point( builder, x, y, 1 ); - break; - - case op_rlineto: - FT_TRACE4(( " rlineto" )); - - if ( start_point( builder, x, y ) ) - goto Memory_Error; - - x += top[0]; - y += top[1]; - - Add_Line: - if ( add_point1( builder, x, y ) ) - goto Memory_Error; - break; - - case op_rmoveto: - FT_TRACE4(( " rmoveto" )); - - x += top[0]; - y += top[1]; - break; - - case op_rrcurveto: - FT_TRACE4(( " rcurveto" )); - - if ( start_point( builder, x, y ) || - check_points( builder, 3 ) ) - goto Memory_Error; - - x += top[0]; - y += top[1]; - add_point( builder, x, y, 0 ); - - x += top[2]; - y += top[3]; - add_point( builder, x, y, 0 ); - - x += top[4]; - y += top[5]; - add_point( builder, x, y, 1 ); - break; - - case op_vhcurveto: - FT_TRACE4(( " vhcurveto" )); - - if ( start_point( builder, x, y ) || - check_points( builder, 3 ) ) - goto Memory_Error; - - y += top[0]; - add_point( builder, x, y, 0 ); - x += top[1]; - y += top[2]; - add_point( builder, x, y, 0 ); - x += top[3]; - add_point( builder, x, y, 1 ); - break; - - case op_vlineto: - FT_TRACE4(( " vlineto" )); - - if ( start_point( builder, x, y ) ) - goto Memory_Error; - - y += top[0]; - goto Add_Line; - - case op_vmoveto: - FT_TRACE4(( " vmoveto" )); - - y += top[0]; - break; - - case op_div: - FT_TRACE4(( " div" )); - - if ( top[1] ) - { - *top = top[0] / top[1]; - ++top; - } - else - { - FT_ERROR(( "Z1_Parse_CharStrings: division by 0\n" )); - goto Syntax_Error; - } - break; - - case op_callsubr: - { - FT_Int index; - - - FT_TRACE4(( " callsubr" )); - - index = top[0]; - if ( index < 0 || index >= num_subrs ) - { - FT_ERROR(( "Z1_Parse_CharStrings: invalid subrs index\n" )); - goto Syntax_Error; - } - - if ( zone - decoder->zones >= T1_MAX_SUBRS_CALLS ) - { - FT_ERROR(( "Z1_Parse_CharStrings: too many nested subrs\n" )); - goto Syntax_Error; - } - - zone->cursor = ip; /* save current instruction pointer */ - - zone++; - zone->base = subrs_base[index]; - zone->limit = zone->base + subrs_len[index]; - zone->cursor = zone->base; - - if ( !zone->base ) - { - FT_ERROR(( "Z1_Parse_CharStrings: invoking empty subrs!\n" )); - goto Syntax_Error; - } - - decoder->zone = zone; - ip = zone->base; - limit = zone->limit; - break; - } - - case op_pop: - FT_TRACE4(( " pop" )); - - /* theorically, the arguments are already on the stack */ - top++; - break; - - case op_return: - FT_TRACE4(( " return" )); - - if ( zone <= decoder->zones ) - { - FT_ERROR(( "Z1_Parse_CharStrings: unexpected return\n" )); - goto Syntax_Error; - } - - zone--; - ip = zone->cursor; - limit = zone->limit; - decoder->zone = zone; - break; - - case op_dotsection: - FT_TRACE4(( " dotsection" )); - - break; - - case op_hstem: - FT_TRACE4(( " hstem" )); - - break; - - case op_hstem3: - FT_TRACE4(( " hstem3" )); - - break; - - case op_vstem: - FT_TRACE4(( " vstem" )); - - break; - - case op_vstem3: - FT_TRACE4(( " vstem3" )); - - break; - - case op_setcurrentpoint: - FT_TRACE4(( " setcurrentpoint" )); - - FT_ERROR(( "Z1_Parse_CharStrings:" )); - FT_ERROR(( " unexpected `setcurrentpoint'\n" )); - goto Syntax_Error; - - default: - FT_ERROR(( "Z1_Parse_CharStrings: unhandled opcode %d\n", op )); - goto Syntax_Error; - } - - decoder->top = top; - - } /* general operator processing */ - - } /* while ip < limit */ - - FT_TRACE4(( "..end..\n\n" )); - return error; - - Syntax_Error: - return T1_Err_Syntax_Error; - - Stack_Underflow: - return T1_Err_Stack_Underflow; - - Memory_Error: - return builder->error; - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********** *********/ - /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/ - /********** *********/ - /********** The following code is in charge of computing *********/ - /********** the maximum advance width of the font. It *********/ - /********** quickly processes each glyph charstring to *********/ - /********** extract the value from either a `sbw' or `seac' *********/ - /********** operator. *********/ - /********** *********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - LOCAL_FUNC - FT_Error Z1_Compute_Max_Advance( T1_Face face, - FT_Int* max_advance ) - { - FT_Error error; - Z1_Decoder decoder; - FT_Int glyph_index; - T1_Font* type1 = &face->type1; - - - *max_advance = 0; - - /* Initialize load decoder */ - Z1_Init_Decoder( &decoder ); - Z1_Init_Builder( &decoder.builder, face, 0, 0 ); - - decoder.blend = face->blend; - decoder.builder.metrics_only = 1; - decoder.builder.load_points = 0; - - /* for each glyph, parse the glyph charstring and extract */ - /* the advance width */ - for ( glyph_index = 0; glyph_index < type1->num_glyphs; glyph_index++ ) - { - /* now get load the unscaled outline */ - error = Z1_Parse_CharStrings( &decoder, - type1->charstrings [glyph_index], - type1->charstrings_len[glyph_index], - type1->num_subrs, - type1->subrs, - type1->subrs_len ); - /* ignore the error if one occured - skip to next glyph */ - } - - *max_advance = decoder.builder.advance.x; - return T1_Err_Ok; - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********** *********/ - /********** UNHINTED GLYPH LOADER *********/ - /********** *********/ - /********** The following code is in charge of loading a *********/ - /********** single outline. It completely ignores hinting *********/ - /********** and is used when FT_LOAD_NO_HINTING is set. *********/ - /********** *********/ - /********** The Type 1 hinter is located in `t1hint.c' *********/ - /********** *********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - LOCAL_FUNC - FT_Error Z1_Load_Glyph( Z1_GlyphSlot glyph, - Z1_Size size, - FT_Int glyph_index, - FT_Int load_flags ) - { - FT_Error error; - Z1_Decoder decoder; - T1_Face face = (T1_Face)glyph->root.face; - FT_Bool hinting; - T1_Font* type1 = &face->type1; - - - if ( load_flags & FT_LOAD_NO_RECURSE ) - load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; - - glyph->x_scale = size->root.metrics.x_scale; - glyph->y_scale = size->root.metrics.y_scale; - - glyph->root.outline.n_points = 0; - glyph->root.outline.n_contours = 0; - - hinting = ( load_flags & FT_LOAD_NO_SCALE ) == 0 && - ( load_flags & FT_LOAD_NO_HINTING ) == 0; - - glyph->root.format = ft_glyph_format_outline; - - Z1_Init_Decoder( &decoder ); - Z1_Init_Builder( &decoder.builder, face, size, glyph ); - - decoder.blend = ((T1_Face)glyph->root.face)->blend; - decoder.builder.no_recurse = ( load_flags & FT_LOAD_NO_RECURSE ) != 0; - - /* now load the unscaled outline */ - error = Z1_Parse_CharStrings( &decoder, - type1->charstrings [glyph_index], - type1->charstrings_len[glyph_index], - type1->num_subrs, - type1->subrs, - type1->subrs_len ); - - /* save new glyph tables */ - Z1_Done_Builder( &decoder.builder ); - - /* now, set the metrics -- this is rather simple, as */ - /* the left side bearing is the xMin, and the top side */ - /* bearing the yMax */ - if ( !error ) - { - glyph->root.outline.flags &= ft_outline_owner; - glyph->root.outline.flags |= ft_outline_reverse_fill; - - /* for composite glyphs, return only left side bearing and */ - /* advance width */ - if ( load_flags & FT_LOAD_NO_RECURSE ) - { - glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x; - glyph->root.metrics.horiAdvance = decoder.builder.advance.x; - } - else - { - FT_BBox cbox; - FT_Glyph_Metrics* metrics = &glyph->root.metrics; - - - /* copy the _unscaled_ advance width */ - metrics->horiAdvance = decoder.builder.advance.x; - - /* make up vertical metrics */ - metrics->vertBearingX = 0; - metrics->vertBearingY = 0; - metrics->vertAdvance = 0; - - glyph->root.format = ft_glyph_format_outline; - - if ( size && size->root.metrics.y_ppem < 24 ) - glyph->root.outline.flags |= ft_outline_high_precision; - -#if 0 - glyph->root.outline.second_pass = TRUE; - glyph->root.outline.high_precision = size->root.metrics.y_ppem < 24; - glyph->root.outline.dropout_mode = 2; -#endif /* 0 */ - - if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ) - { - /* scale the outline and the metrics */ - FT_Int n; - FT_Outline* cur = decoder.builder.base; - FT_Vector* vec = cur->points; - FT_Fixed x_scale = glyph->x_scale; - FT_Fixed y_scale = glyph->y_scale; - - - /* First of all, scale the points */ - for ( n = cur->n_points; n > 0; n--, vec++ ) - { - vec->x = FT_MulFix( vec->x, x_scale ); - vec->y = FT_MulFix( vec->y, y_scale ); - } - - FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); - - /* Then scale the metrics */ - metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); - metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); - - metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale ); - metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale ); - } - - /* apply the font matrix */ - FT_Outline_Transform( &glyph->root.outline, - &face->type1.font_matrix ); - - /* compute the other metrics */ - FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); - - /* grid fit the bounding box if necessary */ - if ( hinting ) - { - cbox.xMin &= -64; - cbox.yMin &= -64; - cbox.xMax = ( cbox.xMax+63 ) & -64; - cbox.yMax = ( cbox.yMax+63 ) & -64; - } - - metrics->width = cbox.xMax - cbox.xMin; - metrics->height = cbox.yMax - cbox.yMin; - - metrics->horiBearingX = cbox.xMin; - metrics->horiBearingY = cbox.yMax; - } - } - return error; - } - - -/* END */ diff --git a/src/freetype/type1z/z1gload.h b/src/freetype/type1z/z1gload.h deleted file mode 100644 index 5bb6dc0a25..0000000000 --- a/src/freetype/type1z/z1gload.h +++ /dev/null @@ -1,187 +0,0 @@ -/***************************************************************************/ -/* */ -/* z1gload.h */ -/* */ -/* Experimental Type 1 Glyph Loader (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifndef Z1GLOAD_H -#define Z1GLOAD_H - - -#ifdef FT_FLAT_COMPILE - -#include "z1objs.h" - -#else - -#include - -#endif - - -#ifdef __cplusplus - extern "C" { -#endif - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_Builder */ - /* */ - /* */ - /* A structure used during glyph loading to store its outline. */ - /* */ - /* */ - /* memory :: The current memory object. */ - /* */ - /* face :: The current face object. */ - /* */ - /* glyph :: The current glyph slot. */ - /* */ - /* loader :: The current glyph loader. */ - /* */ - /* current :: The current glyph outline. */ - /* */ - /* base :: The base glyph outline. */ - /* */ - /* last :: The last point position. */ - /* */ - /* scale_x :: The horizontal scale (FUnits to sub-pixels). */ - /* */ - /* scale_y :: The vertical scale (FUnits to sub-pixels). */ - /* */ - /* pos_x :: The horizontal translation (for composite glyphs). */ - /* */ - /* pos_y :: The vertical translation (for composite glyphs). */ - /* */ - /* left_bearing :: The left side bearing point. */ - /* */ - /* advance :: The horizontal advance vector. */ - /* */ - /* no_recurse :: */ - /* */ - /* bbox :: The glyph's bounding box. */ - /* */ - /* path_begun :: A flag which indicates that a new path has begun. */ - /* */ - /* load_points :: A flag which indicates, if not set, that no points */ - /* are loaded. */ - /* */ - /* error :: The current error code. */ - /* */ - /* metrics_only :: A flag whether to compute metrics only. */ - /* */ - typedef struct Z1_Builder_ - { - FT_Memory memory; - T1_Face face; - Z1_GlyphSlot glyph; - FT_GlyphLoader* loader; - - FT_Outline* current; /* the current glyph outline */ - FT_Outline* base; /* the composite glyph outline */ - - FT_Vector last; - - FT_Fixed scale_x; - FT_Fixed scale_y; - - FT_Pos pos_x; - FT_Pos pos_y; - - FT_Vector left_bearing; - FT_Vector advance; - - FT_BBox bbox; /* bounding box */ - FT_Bool path_begun; - FT_Bool load_points; - FT_Bool no_recurse; - - FT_Error error; /* only used for memory errors */ - FT_Bool metrics_only; - - } Z1_Builder; - - - /* execution context charstring zone */ - typedef struct Z1_Decoder_Zone_ - { - FT_Byte* base; - FT_Byte* limit; - FT_Byte* cursor; - - } Z1_Decoder_Zone; - - - typedef struct Z1_Decoder_ - { - Z1_Builder builder; - - FT_Int stack[T1_MAX_CHARSTRINGS_OPERANDS]; - FT_Int* top; - - Z1_Decoder_Zone zones[T1_MAX_SUBRS_CALLS + 1]; - Z1_Decoder_Zone* zone; - - FT_Int flex_state; - FT_Int num_flex_vectors; - FT_Vector flex_vectors[7]; - - T1_Blend* blend; /* for multiple masters */ - - } Z1_Decoder; - - - LOCAL_DEF - void Z1_Init_Builder( Z1_Builder* builder, - T1_Face face, - Z1_Size size, - Z1_GlyphSlot glyph ); - - LOCAL_DEF - void Z1_Done_Builder( Z1_Builder* builder ); - - LOCAL_DEF - void Z1_Init_Decoder( Z1_Decoder* decoder ); - - LOCAL_DEF - FT_Error Z1_Compute_Max_Advance( T1_Face face, - FT_Int* max_advance ); - - LOCAL_DEF - FT_Error Z1_Parse_CharStrings( Z1_Decoder* decoder, - FT_Byte* charstring_base, - FT_Int charstring_len, - FT_Int num_subrs, - FT_Byte** subrs_base, - FT_Int* subrs_len ); - - LOCAL_DEF - FT_Error Z1_Load_Glyph( Z1_GlyphSlot glyph, - Z1_Size size, - FT_Int glyph_index, - FT_Int load_flags ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* Z1GLOAD_H */ - - -/* END */ diff --git a/src/freetype/type1z/z1load.c b/src/freetype/type1z/z1load.c deleted file mode 100644 index 46478d1a85..0000000000 --- a/src/freetype/type1z/z1load.c +++ /dev/null @@ -1,1725 +0,0 @@ -/***************************************************************************/ -/* */ -/* z1load.c */ -/* */ -/* Experimental Type 1 font loader (body). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This is the new and improved Type 1 data loader for FreeType 2. The */ - /* old loader has several problems: it is slow, complex, difficult to */ - /* maintain, and contains incredible hacks to make it accept some */ - /* ill-formed Type 1 fonts without hiccup-ing. Moreover, about 5% of */ - /* the Type 1 fonts on my machine still aren't loaded correctly by it. */ - /* */ - /* This version is much simpler, much faster and also easier to read and */ - /* maintain by a great order of magnitude. The idea behind it is to */ - /* _not_ try to read the Type 1 token stream with a state machine (i.e. */ - /* a Postscript-like interpreter) but rather to perform simple pattern */ - /* matching. */ - /* */ - /* Indeed, nearly all data definitions follow a simple pattern like */ - /* */ - /* ... /Field ... */ - /* */ - /* where can be a number, a boolean, a string, or an array of */ - /* numbers. There are a few exceptions, namely the encoding, font name, */ - /* charstrings, and subrs; they are handled with a special pattern */ - /* matching routine. */ - /* */ - /* All other common cases are handled very simply. The matching rules */ - /* are defined in the file `t1tokens.h' through the use of several */ - /* macros calls PARSE_XXX. */ - /* */ - /* This file is included twice here; the first time to generate parsing */ - /* callback functions, the second to generate a table of keywords (with */ - /* pointers to the associated callback). */ - /* */ - /* The function `parse_dict' simply scans *linearly* a given dictionary */ - /* (either the top-level or private one) and calls the appropriate */ - /* callback when it encounters an immediate keyword. */ - /* */ - /* This is by far the fastest way one can find to parse and read all */ - /* data. */ - /* */ - /* This led to tremendous code size reduction. Note that later, the */ - /* glyph loader will also be _greatly_ simplified, and the automatic */ - /* hinter will replace the clumsy `t1hinter'. */ - /* */ - /*************************************************************************/ - - -#include -#include -#include - -#include -#include - - -#ifdef FT_FLAT_COMPILE - -#include "z1load.h" - -#else - -#include - -#endif - - -#include /* for strncmp(), strcmp() */ -#include /* for isalnum() */ - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_z1load - - -#ifndef Z1_CONFIG_OPTION_NO_MM_SUPPORT - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** MULTIPLE MASTERS SUPPORT *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - static - FT_Error t1_allocate_blend( T1_Face face, - FT_UInt num_designs, - FT_UInt num_axis ) - { - T1_Blend* blend; - FT_Memory memory = face->root.memory; - FT_Error error = 0; - - - blend = face->blend; - if ( !blend ) - { - if ( ALLOC( blend, sizeof ( *blend ) ) ) - goto Exit; - - face->blend = blend; - } - - /* allocate design data if needed */ - if ( num_designs > 0 ) - { - if ( blend->num_designs == 0 ) - { - FT_UInt nn; - - - /* allocate the blend `private' and `font_info' dictionaries */ - if ( ALLOC_ARRAY( blend->font_infos[1], num_designs, T1_FontInfo ) || - ALLOC_ARRAY( blend->privates[1], num_designs, T1_Private ) || - ALLOC_ARRAY( blend->weight_vector, num_designs * 2, FT_Fixed ) ) - goto Exit; - - blend->default_weight_vector = blend->weight_vector + num_designs; - - blend->font_infos[0] = &face->type1.font_info; - blend->privates [0] = &face->type1.private_dict; - - for ( nn = 2; nn <= num_designs; nn++ ) - { - blend->privates[nn] = blend->privates [nn - 1] + 1; - blend->font_infos[nn] = blend->font_infos[nn - 1] + 1; - } - - blend->num_designs = num_designs; - } - else if ( blend->num_designs != num_designs ) - goto Fail; - } - - /* allocate axis data if needed */ - if ( num_axis > 0 ) - { - if ( blend->num_axis != 0 && blend->num_axis != num_axis ) - goto Fail; - - blend->num_axis = num_axis; - } - - /* allocate the blend design pos table if needed */ - num_designs = blend->num_designs; - num_axis = blend->num_axis; - if ( num_designs && num_axis && blend->design_pos[0] == 0 ) - { - FT_UInt n; - - - if ( ALLOC_ARRAY( blend->design_pos[0], - num_designs * num_axis, FT_Fixed ) ) - goto Exit; - - for ( n = 1; n < num_designs; n++ ) - blend->design_pos[n] = blend->design_pos[0] + num_axis * n; - } - - Exit: - return error; - - Fail: - error = -1; - goto Exit; - } - - - LOCAL_FUNC - FT_Error Z1_Get_Multi_Master( T1_Face face, - FT_Multi_Master* master ) - { - T1_Blend* blend = face->blend; - FT_UInt n; - FT_Error error; - - - error = T1_Err_Invalid_Argument; - - if ( blend ) - { - master->num_axis = blend->num_axis; - master->num_designs = blend->num_designs; - - for ( n = 0; n < blend->num_axis; n++ ) - { - FT_MM_Axis* axis = master->axis + n; - T1_DesignMap* map = blend->design_map + n; - - - axis->name = blend->axis_names[n]; - axis->minimum = map->design_points[0]; - axis->maximum = map->design_points[map->num_points - 1]; - } - error = 0; - } - return error; - } - - - LOCAL_FUNC - FT_Error Z1_Set_MM_Blend( T1_Face face, - FT_UInt num_coords, - FT_Fixed* coords ) - { - T1_Blend* blend = face->blend; - FT_Error error; - FT_UInt n, m; - - - error = T1_Err_Invalid_Argument; - - if ( blend && blend->num_axis == num_coords ) - { - /* recompute the weight vector from the blend coordinates */ - error = FT_Err_Ok; - - for ( n = 0; n < blend->num_designs; n++ ) - { - FT_Fixed result = 0x10000L; /* 1.0 fixed */ - - - for ( m = 0; m < blend->num_axis; m++ ) - { - FT_Fixed factor; - - - /* get current blend axis position */ - factor = coords[m]; - if ( factor < 0 ) factor = 0; - if ( factor > 0x10000L ) factor = 0x10000L; - - if ( ( n & ( 1 << m ) ) == 0 ) - factor = 0x10000L - factor; - - result = FT_MulFix( result, factor ); - } - blend->weight_vector[n] = result; - } - - error = FT_Err_Ok; - } - return error; - } - - - LOCAL_FUNC - FT_Error Z1_Set_MM_Design( T1_Face face, - FT_UInt num_coords, - FT_Long* coords ) - { - T1_Blend* blend = face->blend; - FT_Error error; - FT_UInt n, p; - - - error = T1_Err_Invalid_Argument; - if ( blend && blend->num_axis == num_coords ) - { - /* compute the blend coordinates through the blend design map */ - FT_Fixed final_blends[T1_MAX_MM_DESIGNS]; - - - for ( n = 0; n < blend->num_axis; n++ ) - { - FT_Long design = coords[n]; - FT_Fixed the_blend; - T1_DesignMap* map = blend->design_map + n; - FT_Fixed* designs = map->design_points; - FT_Fixed* blends = map->blend_points; - FT_Int before = -1, after = -1; - - for ( p = 0; p < map->num_points; p++ ) - { - FT_Fixed p_design = designs[p]; - - - /* exact match ? */ - if ( design == p_design ) - { - the_blend = blends[p]; - goto Found; - } - - if ( design < p_design ) - { - after = p; - break; - } - - before = p; - } - - /* now, interpolate if needed */ - if ( before < 0 ) - the_blend = blends[0]; - - else if ( after < 0 ) - the_blend = blends[map->num_points - 1]; - - else - the_blend = FT_MulDiv( design - designs[before], - blends [after] - blends [before], - designs[after] - designs[before] ); - - Found: - final_blends[n] = the_blend; - } - - error = Z1_Set_MM_Blend( face, num_coords, final_blends ); - } - - return error; - } - - - LOCAL_FUNC - void Z1_Done_Blend( T1_Face face ) - { - FT_Memory memory = face->root.memory; - T1_Blend* blend = face->blend; - - - if ( blend ) - { - FT_UInt num_designs = blend->num_designs; - FT_UInt num_axis = blend->num_axis; - FT_UInt n; - - - /* release design pos table */ - FREE( blend->design_pos[0] ); - for ( n = 1; n < num_designs; n++ ) - blend->design_pos[n] = 0; - - /* release blend `private' and `font info' dictionaries */ - FREE( blend->privates[1] ); - FREE( blend->font_infos[1] ); - - for ( n = 0; n < num_designs; n++ ) - { - blend->privates [n] = 0; - blend->font_infos[n] = 0; - } - - /* release weight vectors */ - FREE( blend->weight_vector ); - blend->default_weight_vector = 0; - - /* release axis names */ - for ( n = 0; n < num_axis; n++ ) - FREE( blend->axis_names[n] ); - - /* release design map */ - for ( n = 0; n < num_axis; n++ ) - { - T1_DesignMap* dmap = blend->design_map + n; - - - FREE( dmap->design_points ); - dmap->num_points = 0; - } - - FREE( face->blend ); - } - } - - - static - void parse_blend_axis_types( T1_Face face, - Z1_Loader* loader ) - { - Z1_Token_Rec axis_tokens[ T1_MAX_MM_AXIS ]; - FT_Int n, num_axis; - FT_Error error = 0; - T1_Blend* blend; - FT_Memory memory; - - - /* take an array of objects */ - Z1_ToTokenArray( &loader->parser, axis_tokens, - T1_MAX_MM_AXIS, &num_axis ); - if ( num_axis <= 0 || num_axis > T1_MAX_MM_AXIS ) - { - FT_ERROR(( "parse_blend_axis_types: incorrect number of axes: %d\n", - num_axis )); - error = T1_Err_Invalid_File_Format; - goto Exit; - } - - /* allocate blend if necessary */ - error = t1_allocate_blend( face, 0, (FT_UInt)num_axis ); - if ( error ) - goto Exit; - - blend = face->blend; - memory = face->root.memory; - - /* each token is an immediate containing the name of the axis */ - for ( n = 0; n < num_axis; n++ ) - { - Z1_Token_Rec* token = axis_tokens + n; - FT_Byte* name; - FT_Int len; - - /* skip first slash, if any */ - if (token->start[0] == '/') - token->start++; - - len = token->limit - token->start; - if ( len <= 0 ) - { - error = T1_Err_Invalid_File_Format; - goto Exit; - } - - if ( ALLOC( blend->axis_names[n], len + 1 ) ) - goto Exit; - - name = (FT_Byte*)blend->axis_names[n]; - MEM_Copy( name, token->start, len ); - name[len] = 0; - } - - Exit: - loader->parser.error = error; - } - - - static - void parse_blend_design_positions( T1_Face face, - Z1_Loader* loader ) - { - Z1_Token_Rec design_tokens[ T1_MAX_MM_DESIGNS ]; - FT_Int num_designs; - FT_Int num_axis; - Z1_Parser* parser = &loader->parser; - - FT_Error error = 0; - T1_Blend* blend; - - - /* get the array of design tokens - compute number of designs */ - Z1_ToTokenArray( parser, design_tokens, T1_MAX_MM_DESIGNS, &num_designs ); - if ( num_designs <= 0 || num_designs > T1_MAX_MM_DESIGNS ) - { - FT_ERROR(( "parse_blend_design_positions:" )); - FT_ERROR(( " incorrect number of designs: %d\n", - num_designs )); - error = T1_Err_Invalid_File_Format; - goto Exit; - } - - { - FT_Byte* old_cursor = parser->cursor; - FT_Byte* old_limit = parser->limit; - FT_UInt n; - - - blend = face->blend; - num_axis = 0; /* make compiler happy */ - - for ( n = 0; n < (FT_UInt)num_designs; n++ ) - { - Z1_Token_Rec axis_tokens[ T1_MAX_MM_DESIGNS ]; - Z1_Token_Rec* token; - FT_Int axis, n_axis; - - - /* read axis/coordinates tokens */ - token = design_tokens + n; - parser->cursor = token->start - 1; - parser->limit = token->limit + 1; - Z1_ToTokenArray( parser, axis_tokens, T1_MAX_MM_AXIS, &n_axis ); - - if ( n == 0 ) - { - num_axis = n_axis; - error = t1_allocate_blend( face, num_designs, num_axis ); - if ( error ) - goto Exit; - blend = face->blend; - } - else if ( n_axis != num_axis ) - { - FT_ERROR(( "parse_blend_design_positions: incorrect table\n" )); - error = T1_Err_Invalid_File_Format; - goto Exit; - } - - /* now, read each axis token into the design position */ - for ( axis = 0; axis < n_axis; axis++ ) - { - Z1_Token_Rec* token2 = axis_tokens + axis; - - - parser->cursor = token2->start; - parser->limit = token2->limit; - blend->design_pos[n][axis] = Z1_ToFixed( parser, 0 ); - } - } - - loader->parser.cursor = old_cursor; - loader->parser.limit = old_limit; - } - - Exit: - loader->parser.error = error; - } - - - static - void parse_blend_design_map( T1_Face face, - Z1_Loader* loader ) - { - FT_Error error = 0; - Z1_Parser* parser = &loader->parser; - T1_Blend* blend; - Z1_Token_Rec axis_tokens[ T1_MAX_MM_AXIS ]; - FT_Int n, num_axis; - FT_Byte* old_cursor; - FT_Byte* old_limit; - FT_Memory memory = face->root.memory; - - - Z1_ToTokenArray( parser, axis_tokens, T1_MAX_MM_AXIS, &num_axis ); - if ( num_axis <= 0 || num_axis > T1_MAX_MM_AXIS ) - { - FT_ERROR(( "parse_blend_design_map: incorrect number of axes: %d\n", - num_axis )); - error = T1_Err_Invalid_File_Format; - goto Exit; - } - old_cursor = parser->cursor; - old_limit = parser->limit; - - error = t1_allocate_blend( face, 0, num_axis ); - if ( error ) - goto Exit; - blend = face->blend; - - /* now, read each axis design map */ - for ( n = 0; n < num_axis; n++ ) - { - T1_DesignMap* map = blend->design_map + n; - Z1_Token_Rec* token; - FT_Int p, num_points; - - - token = axis_tokens + n; - parser->cursor = token->start; - parser->limit = token->limit; - - /* count the number of map points */ - { - FT_Byte* p = token->start; - FT_Byte* limit = token->limit; - - - num_points = 0; - for ( ; p < limit; p++ ) - if ( p[0] == '[' ) - num_points++; - } - if ( num_points <= 0 || num_points > T1_MAX_MM_MAP_POINTS ) - { - FT_ERROR(( "parse_blend_design_map: incorrect table\n" )); - error = T1_Err_Invalid_File_Format; - goto Exit; - } - - /* allocate design map data */ - if ( ALLOC_ARRAY( map->design_points, num_points * 2, FT_Fixed ) ) - goto Exit; - map->blend_points = map->design_points + num_points; - map->num_points = (FT_Byte)num_points; - - for ( p = 0; p < num_points; p++ ) - { - map->design_points[p] = Z1_ToInt( parser ); - map->blend_points [p] = Z1_ToFixed( parser, 0 ); - } - } - - parser->cursor = old_cursor; - parser->limit = old_limit; - - Exit: - parser->error = error; - } - - - static - void parse_weight_vector( T1_Face face, - Z1_Loader* loader ) - { - FT_Error error = 0; - Z1_Parser* parser = &loader->parser; - T1_Blend* blend = face->blend; - Z1_Token_Rec master; - FT_UInt n; - FT_Byte* old_cursor; - FT_Byte* old_limit; - - - if ( !blend || blend->num_designs == 0 ) - { - FT_ERROR(( "parse_weight_vector: too early!\n" )); - error = T1_Err_Invalid_File_Format; - goto Exit; - } - - Z1_ToToken( parser, &master ); - if ( master.type != t1_token_array ) - { - FT_ERROR(( "parse_weight_vector: incorrect format!\n" )); - error = T1_Err_Invalid_File_Format; - goto Exit; - } - - old_cursor = parser->cursor; - old_limit = parser->limit; - - parser->cursor = master.start; - parser->limit = master.limit; - - for ( n = 0; n < blend->num_designs; n++ ) - { - blend->default_weight_vector[n] = - blend->weight_vector[n] = Z1_ToFixed( parser, 0 ); - } - - parser->cursor = old_cursor; - parser->limit = old_limit; - - Exit: - parser->error = error; - } - - - /* the keyword `/shareddict' appears in some multiple master fonts */ - /* with a lot of Postscript garbage behind it (that's completely out */ - /* of spec!); we detect it and terminate the parsing */ - /* */ - static - void parse_shared_dict( T1_Face face, - Z1_Loader* loader ) - { - Z1_Parser* parser = &loader->parser; - - FT_UNUSED( face ); - - - parser->cursor = parser->limit; - parser->error = 0; - } - -#endif /* Z1_CONFIG_OPTION_NO_MM_SUPPORT */ - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** TYPE 1 SYMBOL PARSING *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* First of all, define the token field static variables. This is a set */ - /* of Z1_Field_Rec variables used later. */ - /* */ - /*************************************************************************/ - -#define Z1_NEW_STRING( _name, _field ) \ - static \ - const Z1_Field_Rec t1_field_ ## _field = \ - Z1_FIELD_STRING( T1TYPE, _field ); - -#define Z1_NEW_BOOL( _name, _field ) \ - static \ - const Z1_Field_Rec t1_field_ ## _field = \ - Z1_FIELD_BOOL( T1TYPE, _field ); - -#define Z1_NEW_NUM( _name, _field ) \ - static \ - const Z1_Field_Rec t1_field_ ## _field = \ - Z1_FIELD_NUM( T1TYPE, _field ); - -#define Z1_NEW_FIXED( _name, _field ) \ - static \ - const Z1_Field_Rec t1_field_ ## _field = \ - Z1_FIELD_FIXED( T1TYPE, _field, _power ); - -#define Z1_NEW_NUM_TABLE( _name, _field, _max, _count ) \ - static \ - const Z1_Field_Rec t1_field_ ## _field = \ - Z1_FIELD_NUM_ARRAY( T1TYPE, _field, _count, _max ); - -#define Z1_NEW_FIXED_TABLE( _name, _field, _max, _count ) \ - static \ - const Z1_Field_Rec t1_field_ ## _field = \ - Z1_FIELD_FIXED_ARRAY( T1TYPE, _field, _count, _max ); - -#define Z1_NEW_NUM_TABLE2( _name, _field, _max ) \ - static \ - const Z1_Field_Rec t1_field_ ## _field = \ - Z1_FIELD_NUM_ARRAY2( T1TYPE, _field, _max ); - -#define Z1_NEW_FIXED_TABLE2( _name, _field, _max ) \ - static \ - const Z1_Field_Rec t1_field_ ## _field = \ - Z1_FIELD_FIXED_ARRAY2( T1TYPE, _field, _max ); - - -#define Z1_FONTINFO_STRING( n, f ) Z1_NEW_STRING( n, f ) -#define Z1_FONTINFO_NUM( n, f ) Z1_NEW_NUM( n, f ) -#define Z1_FONTINFO_BOOL( n, f ) Z1_NEW_BOOL( n, f ) -#define Z1_PRIVATE_NUM( n, f ) Z1_NEW_NUM( n, f ) -#define Z1_PRIVATE_FIXED( n, f ) Z1_NEW_FIXED( n, f ) -#define Z1_PRIVATE_NUM_TABLE( n, f, m, c ) Z1_NEW_NUM_TABLE( n, f, m, c ) -#define Z1_PRIVATE_NUM_TABLE2( n, f, m ) Z1_NEW_NUM_TABLE2( n, f, m ) -#define Z1_TOPDICT_NUM( n, f ) Z1_NEW_NUM( n, f ) -#define Z1_TOPDICT_NUM_FIXED2( n, f, m ) Z1_NEW_FIXED_TABLE2( n, f, m ) - - - /* including this file defines all field variables */ -#ifdef FT_FLAT_COMPILE - -#include "z1tokens.h" - -#else - -#include - -#endif - - - /*************************************************************************/ - /* */ - /* Second, define the keyword variables. This is a set of Z1_KeyWord */ - /* structures used to model the way each keyword is `loaded'. */ - /* */ - /*************************************************************************/ - - typedef void (*Z1_Parse_Func)( T1_Face face, - Z1_Loader* loader ); - - - typedef enum Z1_KeyWord_Type_ - { - t1_keyword_callback = 0, - t1_keyword_field, - t1_keyword_field_table - - } Z1_KeyWord_Type; - - - typedef enum Z1_KeyWord_Location_ - { - t1_keyword_type1 = 0, - t1_keyword_font_info, - t1_keyword_private - - } Z1_KeyWord_Location; - - - typedef struct Z1_KeyWord_ - { - const char* name; - Z1_KeyWord_Type type; - Z1_KeyWord_Location location; - Z1_Parse_Func parsing; - const Z1_Field_Rec* field; - - } Z1_KeyWord; - - -#define Z1_KEYWORD_CALLBACK( name, callback ) \ - { \ - name, t1_keyword_callback, t1_keyword_type1, callback, 0 \ - } - -#define Z1_KEYWORD_TYPE1( name, f ) \ - { \ - name, t1_keyword_field, t1_keyword_type1, 0, &t1_field_ ## f \ - } - -#define Z1_KEYWORD_FONTINFO( name, f ) \ - { \ - name, t1_keyword_field, t1_keyword_font_info, 0, &t1_field_ ## f \ - } - -#define Z1_KEYWORD_PRIVATE( name, f ) \ - { \ - name, t1_keyword_field, t1_keyword_private, 0, &t1_field_ ## f \ - } - -#define Z1_KEYWORD_FONTINFO_TABLE( name, f ) \ - { \ - name, t1_keyword_field_table, t1_keyword_font_info, 0, \ - &t1_field_ ## f \ - } - -#define Z1_KEYWORD_PRIVATE_TABLE( name, f ) \ - { \ - name, t1_keyword_field_table, t1_keyword_private, 0, \ - &t1_field_ ## f \ - } - - -#undef Z1_FONTINFO_STRING -#undef Z1_FONTINFO_NUM -#undef Z1_FONTINFO_BOOL -#undef Z1_PRIVATE_NUM -#undef Z1_PRIVATE_FIXED -#undef Z1_PRIVATE_NUM_TABLE -#undef Z1_PRIVATE_NUM_TABLE2 -#undef Z1_TOPDICT_NUM -#undef Z1_TOPDICT_NUM_FIXED2 - -#define Z1_FONTINFO_STRING( n, f ) Z1_KEYWORD_FONTINFO( n, f ), -#define Z1_FONTINFO_NUM( n, f ) Z1_KEYWORD_FONTINFO( n, f ), -#define Z1_FONTINFO_BOOL( n, f ) Z1_KEYWORD_FONTINFO( n, f ), -#define Z1_PRIVATE_NUM( n, f ) Z1_KEYWORD_PRIVATE( n, f ), -#define Z1_PRIVATE_FIXED( n, f ) Z1_KEYWORD_PRIVATE( n, f ), -#define Z1_PRIVATE_NUM_TABLE( n, f, m, c ) Z1_KEYWORD_PRIVATE_TABLE( n, f ), -#define Z1_PRIVATE_NUM_TABLE2( n, f, m ) Z1_KEYWORD_PRIVATE_TABLE( n, f ), -#define Z1_TOPDICT_NUM( n, f ) Z1_KEYWORD_TYPE1( n, f ), -#define Z1_TOPDICT_NUM_FIXED2( n, f, m ) Z1_KEYWORD_TYPE1( n, f ), - - - static - FT_Error t1_load_keyword( T1_Face face, - Z1_Loader* loader, - Z1_KeyWord* keyword ) - { - FT_Error error; - void* dummy_object; - void** objects; - FT_UInt max_objects; - T1_Blend* blend = face->blend; - - - /* if the keyword has a dedicated callback, call it */ - if ( keyword->type == t1_keyword_callback ) - { - keyword->parsing( face, loader ); - error = loader->parser.error; - goto Exit; - } - - /* now, the keyword is either a simple field, or a table of fields; */ - /* we are now going to take care of it */ - switch ( keyword->location ) - { - case t1_keyword_font_info: - dummy_object = &face->type1.font_info; - objects = &dummy_object; - max_objects = 0; - - if ( blend ) - { - objects = (void**)blend->font_infos; - max_objects = blend->num_designs; - } - break; - - case t1_keyword_private: - dummy_object = &face->type1.private_dict; - objects = &dummy_object; - max_objects = 0; - - if ( blend ) - { - objects = (void**)blend->privates; - max_objects = blend->num_designs; - } - break; - - default: - dummy_object = &face->type1; - objects = &dummy_object; - max_objects = 0; - } - - if ( keyword->type == t1_keyword_field_table ) - error = Z1_Load_Field_Table( &loader->parser, keyword->field, - objects, max_objects, 0 ); - else - error = Z1_Load_Field( &loader->parser, keyword->field, - objects, max_objects, 0 ); - - Exit: - return error; - } - - - static - int is_space( char c ) - { - return ( c == ' ' || c == '\t' || c == '\r' || c == '\n' ); - } - - - static - int is_alpha( char c ) - { - return ( isalnum( c ) || - ( c == '.' ) || - ( c == '_' ) ); - } - - - static - void skip_whitespace( Z1_Parser* parser ) - { - FT_Byte* cur = parser->cursor; - - - while ( cur < parser->limit && is_space( *cur ) ) - cur++; - - parser->cursor = cur; - } - - - static - void skip_blackspace( Z1_Parser* parser ) - { - FT_Byte* cur = parser->cursor; - - while ( cur < parser->limit && !is_space( *cur ) ) - cur++; - - parser->cursor = cur; - } - - - static - int read_binary_data( Z1_Parser* parser, - FT_Int* size, - FT_Byte** base ) - { - FT_Byte* cur; - FT_Byte* limit = parser->limit; - - - /* the binary data has the following format */ - /* */ - /* `size' [white*] RD white ....... ND */ - /* */ - - skip_whitespace( parser ); - cur = parser->cursor; - - if ( cur < limit && (FT_Byte)( *cur - '0' ) < 10 ) - { - *size = Z1_ToInt( parser ); - - skip_whitespace( parser ); - skip_blackspace( parser ); /* `RD' or `-|' or something else */ - - /* there is only one whitespace char after the */ - /* `RD' or `-|' token */ - *base = parser->cursor + 1; - - parser->cursor += *size+1; - return 1; - } - - FT_ERROR(( "read_binary_data: invalid size field\n" )); - parser->error = T1_Err_Invalid_File_Format; - return 0; - } - - - /* we will now define the routines used to handle */ - /* the `/Encoding', `/Subrs', and `/CharStrings' */ - /* dictionaries */ - - static - void parse_font_name( T1_Face face, - Z1_Loader* loader ) - { - Z1_Parser* parser = &loader->parser; - FT_Error error; - FT_Memory memory = parser->memory; - FT_Int len; - FT_Byte* cur; - FT_Byte* cur2; - FT_Byte* limit; - - - skip_whitespace( parser ); - - cur = parser->cursor; - limit = parser->limit; - - if ( cur >= limit - 1 || *cur != '/' ) - return; - - cur++; - cur2 = cur; - while ( cur2 < limit && is_alpha( *cur2 ) ) - cur2++; - - len = cur2 - cur; - if ( len > 0 ) - { - if ( ALLOC( face->type1.font_name, len + 1 ) ) - { - parser->error = error; - return; - } - - MEM_Copy( face->type1.font_name, cur, len ); - face->type1.font_name[len] = '\0'; - } - parser->cursor = cur2; - } - - - static - void parse_font_bbox( T1_Face face, - Z1_Loader* loader ) - { - Z1_Parser* parser = &loader->parser; - FT_Short temp[4]; - FT_BBox* bbox = &face->type1.font_bbox; - - - (void)Z1_ToCoordArray( parser, 4, temp ); - bbox->xMin = temp[0]; - bbox->yMin = temp[1]; - bbox->xMax = temp[2]; - bbox->yMax = temp[3]; - } - - - static - void parse_font_matrix( T1_Face face, - Z1_Loader* loader ) - { - Z1_Parser* parser = &loader->parser; - FT_Matrix* matrix = &face->type1.font_matrix; - FT_Fixed temp[4]; - - - (void)Z1_ToFixedArray( parser, 4, temp, 3 ); - matrix->xx = temp[0]; - matrix->yx = temp[1]; - matrix->xy = temp[2]; - matrix->yy = temp[3]; - } - - - static - void parse_encoding( T1_Face face, - Z1_Loader* loader ) - { - Z1_Parser* parser = &loader->parser; - FT_Byte* cur = parser->cursor; - FT_Byte* limit = parser->limit; - - - /* skip whitespace */ - while ( is_space( *cur ) ) - { - cur++; - if ( cur >= limit ) - { - FT_ERROR(( "parse_encoding: out of bounds!\n" )); - parser->error = T1_Err_Invalid_File_Format; - return; - } - } - - /* if we have a number, then the encoding is an array, */ - /* and we must load it now */ - if ( (FT_Byte)( *cur - '0' ) < 10 ) - { - T1_Encoding* encode = &face->type1.encoding; - FT_Int count, n; - Z1_Table* char_table = &loader->encoding_table; - FT_Memory memory = parser->memory; - FT_Error error; - - - /* read the number of entries in the encoding, should be 256 */ - count = Z1_ToInt( parser ); - if ( parser->error ) - return; - - /* we use a Z1_Table to store our charnames */ - encode->num_chars = count; - if ( ALLOC_ARRAY( encode->char_index, count, FT_Short ) || - ALLOC_ARRAY( encode->char_name, count, FT_String* ) || - ( error = Z1_New_Table( char_table, count, memory ) ) != 0 ) - { - parser->error = error; - return; - } - - /* Now, we will need to read a record of the form */ - /* ... charcode /charname ... for each entry in our table */ - /* */ - /* We simply look for a number followed by an immediate */ - /* name. Note that this ignores correctly the sequence */ - /* that is often seen in type1 fonts: */ - /* */ - /* 0 1 255 { 1 index exch /.notdef put } for dup */ - /* */ - /* used to clean the encoding array before anything else. */ - /* */ - /* We stop when we encounter a `def'. */ - - cur = parser->cursor; - limit = parser->limit; - n = 0; - - for ( ; cur < limit; ) - { - FT_Byte c; - - - c = *cur; - - /* we stop when we encounter a `def' */ - if ( c == 'd' && cur + 3 < limit ) - { - if ( cur[1] == 'e' && - cur[2] == 'f' && - is_space(cur[-1]) && - is_space(cur[3]) ) - { - FT_TRACE6(( "encoding end\n" )); - break; - } - } - - /* otherwise, we must find a number before anything else */ - if ( (FT_Byte)( c - '0' ) < 10 ) - { - FT_Int charcode; - - - parser->cursor = cur; - charcode = Z1_ToInt( parser ); - cur = parser->cursor; - - /* skip whitespace */ - while ( cur < limit && is_space( *cur ) ) - cur++; - - if ( cur < limit && *cur == '/' ) - { - /* bingo, we have an immediate name -- it must be a */ - /* character name */ - FT_Byte* cur2 = cur + 1; - FT_Int len; - - - while ( cur2 < limit && is_alpha( *cur2 ) ) - cur2++; - - len = cur2 - cur - 1; - - parser->error = Z1_Add_Table( char_table, charcode, - cur + 1, len + 1 ); - char_table->elements[charcode][len] = '\0'; - if ( parser->error ) - return; - - cur = cur2; - } - } - else - cur++; - } - - face->type1.encoding_type = t1_encoding_array; - parser->cursor = cur; - } - /* Otherwise, we should have either `StandardEncoding' or */ - /* `ExpertEncoding' */ - else - { - if ( cur + 17 < limit && - strncmp( (const char*)cur, "StandardEncoding", 16 ) == 0 ) - face->type1.encoding_type = t1_encoding_standard; - - else if ( cur + 15 < limit && - strncmp( (const char*)cur, "ExpertEncoding", 14 ) == 0 ) - face->type1.encoding_type = t1_encoding_expert; - - else - { - FT_ERROR(( "parse_encoding: invalid token!\n" )); - parser->error = T1_Err_Invalid_File_Format; - } - } - } - - - static - void parse_subrs( T1_Face face, - Z1_Loader* loader ) - { - Z1_Parser* parser = &loader->parser; - Z1_Table* table = &loader->subrs; - FT_Memory memory = parser->memory; - FT_Error error; - FT_Int n; - - - loader->num_subrs = Z1_ToInt( parser ); - if ( parser->error ) - return; - - /* position the parser right before the `dup' of the first subr */ - skip_whitespace( parser ); - skip_blackspace( parser ); /* `array' */ - skip_whitespace( parser ); - - /* initialize subrs array */ - error = Z1_New_Table( table, loader->num_subrs, memory ); - if ( error ) - goto Fail; - - /* the format is simple: */ - /* */ - /* `index' + binary data */ - /* */ - - for ( n = 0; n < loader->num_subrs; n++ ) - { - FT_Int index, size; - FT_Byte* base; - - - /* If the next token isn't `dup', we are also done. This */ - /* happens when there are `holes' in the Subrs array. */ - if ( strncmp( (char*)parser->cursor, "dup", 3 ) != 0 ) - break; - - index = Z1_ToInt( parser ); - - if ( !read_binary_data( parser, &size, &base ) ) - return; - - /* The binary string is followed by one token, e.g. `NP' */ - /* (bound to `noaccess put') or by two separate tokens: */ - /* `noaccess' & `put'. We position the parser right */ - /* before the next `dup', if any. */ - skip_whitespace( parser ); - skip_blackspace( parser ); /* `NP' or `I' or `noaccess' */ - skip_whitespace( parser ); - - if ( strncmp( (char*)parser->cursor, "put", 3 ) == 0 ) - { - skip_blackspace( parser ); /* skip `put' */ - skip_whitespace( parser ); - } - - /* some fonts use a value of -1 for lenIV to indicate that */ - /* the charstrings are unencoded */ - /* */ - /* thanks to Tom Kacvinsky for pointing this out */ - /* */ - if ( face->type1.private_dict.lenIV >= 0 ) - { - Z1_Decrypt( base, size, 4330 ); - size -= face->type1.private_dict.lenIV; - base += face->type1.private_dict.lenIV; - } - - error = Z1_Add_Table( table, index, base, size ); - if ( error ) - goto Fail; - } - return; - - Fail: - parser->error = error; - } - - - static - void parse_charstrings( T1_Face face, - Z1_Loader* loader ) - { - Z1_Parser* parser = &loader->parser; - Z1_Table* code_table = &loader->charstrings; - Z1_Table* name_table = &loader->glyph_names; - FT_Memory memory = parser->memory; - FT_Error error; - - FT_Byte* cur; - FT_Byte* limit = parser->limit; - FT_Int n; - - - loader->num_glyphs = Z1_ToInt( parser ); - if ( parser->error ) - return; - - /* initialize tables */ - error = Z1_New_Table( code_table, loader->num_glyphs, memory ) || - Z1_New_Table( name_table, loader->num_glyphs, memory ); - if ( error ) - goto Fail; - - n = 0; - for (;;) - { - FT_Int size; - FT_Byte* base; - - - /* the format is simple: */ - /* `/glyphname' + binary data */ - /* */ - /* note that we stop when we find a `def' */ - /* */ - skip_whitespace( parser ); - - cur = parser->cursor; - if ( cur >= limit ) - break; - - /* we stop when we find a `def' or `end' keyword */ - if ( *cur == 'd' && - cur + 3 < limit && - cur[1] == 'e' && - cur[2] == 'f' ) - break; - - if ( *cur == 'e' && - cur + 3 < limit && - cur[1] == 'n' && - cur[2] == 'd' ) - break; - - if ( *cur != '/' ) - skip_blackspace( parser ); - else - { - FT_Byte* cur2 = cur + 1; - FT_Int len; - - - while ( cur2 < limit && is_alpha( *cur2 ) ) - cur2++; - len = cur2 - cur - 1; - - error = Z1_Add_Table( name_table, n, cur + 1, len + 1 ); - if ( error ) - goto Fail; - - /* add a trailing zero to the name table */ - name_table->elements[n][len] = '\0'; - - parser->cursor = cur2; - if ( !read_binary_data( parser, &size, &base ) ) - return; - - if ( face->type1.private_dict.lenIV >= 0 ) - { - Z1_Decrypt( base, size, 4330 ); - size -= face->type1.private_dict.lenIV; - base += face->type1.private_dict.lenIV; - } - - error = Z1_Add_Table( code_table, n, base, size ); - if ( error ) - goto Fail; - - n++; - if ( n >= loader->num_glyphs ) - break; - } - } - loader->num_glyphs = n; - return; - - Fail: - parser->error = error; - } - - - static - const Z1_KeyWord t1_keywords[] = - { - -#ifdef FT_FLAT_COMPILE - -#include "z1tokens.h" - -#else - -#include - -#endif - - /* now add the special functions... */ - Z1_KEYWORD_CALLBACK( "FontName", parse_font_name ), - Z1_KEYWORD_CALLBACK( "FontBBox", parse_font_bbox ), - Z1_KEYWORD_CALLBACK( "FontMatrix", parse_font_matrix ), - Z1_KEYWORD_CALLBACK( "Encoding", parse_encoding ), - Z1_KEYWORD_CALLBACK( "Subrs", parse_subrs ), - Z1_KEYWORD_CALLBACK( "CharStrings", parse_charstrings ), - -#ifndef Z1_CONFIG_OPTION_NO_MM_SUPPORT - Z1_KEYWORD_CALLBACK( "BlendDesignPositions", parse_blend_design_positions ), - Z1_KEYWORD_CALLBACK( "BlendDesignMap", parse_blend_design_map ), - Z1_KEYWORD_CALLBACK( "BlendAxisTypes", parse_blend_axis_types ), - Z1_KEYWORD_CALLBACK( "WeightVector", parse_weight_vector ), - Z1_KEYWORD_CALLBACK( "shareddict", parse_shared_dict ), -#endif - - Z1_KEYWORD_CALLBACK( 0, 0 ) - }; - - - static - FT_Error parse_dict( T1_Face face, - Z1_Loader* loader, - FT_Byte* base, - FT_Long size ) - { - Z1_Parser* parser = &loader->parser; - - - parser->cursor = base; - parser->limit = base + size; - parser->error = 0; - - { - FT_Byte* cur = base; - FT_Byte* limit = cur + size; - - - for ( ; cur < limit; cur++ ) - { - /* look for `FontDirectory', which causes problems on some fonts */ - if ( *cur == 'F' && cur + 25 < limit && - strncmp( (char*)cur, "FontDirectory", 13 ) == 0 ) - { - FT_Byte* cur2; - - - /* skip the `FontDirectory' keyword */ - cur += 13; - cur2 = cur; - - /* lookup the `known' keyword */ - while ( cur < limit && *cur != 'k' && - strncmp( (char*)cur, "known", 5 ) ) - cur++; - - if ( cur < limit ) - { - Z1_Token_Rec token; - - - /* skip the `known' keyword and the token following it */ - cur += 5; - loader->parser.cursor = cur; - Z1_ToToken( &loader->parser, &token ); - - /* if the last token was an array, skip it! */ - if ( token.type == t1_token_array ) - cur2 = parser->cursor; - } - cur = cur2; - } - /* look for immediates */ - else if ( *cur == '/' && cur + 2 < limit ) - { - FT_Byte* cur2; - FT_Int len; - - - cur++; - cur2 = cur; - while ( cur2 < limit && is_alpha( *cur2 ) ) - cur2++; - - len = cur2 - cur; - if ( len > 0 && len < 22 ) - { - if ( !loader->fontdata ) - { - if ( strncmp( (char*)cur, "FontInfo", 8 ) == 0 ) - loader->fontdata = 1; - } - else - { - /* now, compare the immediate name to the keyword table */ - Z1_KeyWord* keyword = (Z1_KeyWord*)t1_keywords; - - - for (;;) - { - FT_Byte* name; - - - name = (FT_Byte*)keyword->name; - if ( !name ) - break; - - if ( cur[0] == name[0] && - len == (FT_Int)strlen( (const char*)name ) ) - { - FT_Int n; - - - for ( n = 1; n < len; n++ ) - if ( cur[n] != name[n] ) - break; - - if ( n >= len ) - { - /* we found it -- run the parsing callback! */ - parser->cursor = cur2; - skip_whitespace( parser ); - parser->error = t1_load_keyword( face, loader, keyword ); - if ( parser->error ) - return parser->error; - - cur = parser->cursor; - break; - } - } - keyword++; - } - } - } - } - } - } - return parser->error; - } - - - static - void t1_init_loader( Z1_Loader* loader, - T1_Face face ) - { - FT_UNUSED( face ); - - MEM_Set( loader, 0, sizeof ( *loader ) ); - loader->num_glyphs = 0; - loader->num_chars = 0; - - /* initialize the tables -- simply set their `init' field to 0 */ - loader->encoding_table.init = 0; - loader->charstrings.init = 0; - loader->glyph_names.init = 0; - loader->subrs.init = 0; - loader->fontdata = 0; - } - - - static - void t1_done_loader( Z1_Loader* loader ) - { - Z1_Parser* parser = &loader->parser; - - - /* finalize tables */ - Z1_Release_Table( &loader->encoding_table ); - Z1_Release_Table( &loader->charstrings ); - Z1_Release_Table( &loader->glyph_names ); - Z1_Release_Table( &loader->subrs ); - - /* finalize parser */ - Z1_Done_Parser( parser ); - } - - - LOCAL_FUNC - FT_Error Z1_Open_Face( T1_Face face ) - { - Z1_Loader loader; - Z1_Parser* parser; - T1_Font* type1 = &face->type1; - FT_Error error; - - - t1_init_loader( &loader, face ); - - /* default lenIV */ - type1->private_dict.lenIV = 4; - - parser = &loader.parser; - error = Z1_New_Parser( parser, face->root.stream, face->root.memory ); - if ( error ) - goto Exit; - - error = parse_dict( face, &loader, parser->base_dict, parser->base_len ); - if ( error ) - goto Exit; - - error = Z1_Get_Private_Dict( parser ); - if ( error ) - goto Exit; - - error = parse_dict( face, &loader, parser->private_dict, - parser->private_len ); - if ( error ) - goto Exit; - - /* now, propagate the subrs, charstrings, and glyphnames tables */ - /* to the Type1 data */ - type1->num_glyphs = loader.num_glyphs; - - if ( !loader.subrs.init ) - { - FT_ERROR(( "Z1_Open_Face: no subrs array in face!\n" )); - error = T1_Err_Invalid_File_Format; - } - - if ( !loader.charstrings.init ) - { - FT_ERROR(( "Z1_Open_Face: no charstrings array in face!\n" )); - error = T1_Err_Invalid_File_Format; - } - - loader.subrs.init = 0; - type1->num_subrs = loader.num_subrs; - type1->subrs_block = loader.subrs.block; - type1->subrs = loader.subrs.elements; - type1->subrs_len = loader.subrs.lengths; - - loader.charstrings.init = 0; - type1->charstrings_block = loader.charstrings.block; - type1->charstrings = loader.charstrings.elements; - type1->charstrings_len = loader.charstrings.lengths; - - /* we copy the glyph names `block' and `elements' fields; */ - /* the `lengths' field must be released later */ - type1->glyph_names_block = loader.glyph_names.block; - type1->glyph_names = (FT_String**)loader.glyph_names.elements; - loader.glyph_names.block = 0; - loader.glyph_names.elements = 0; - - /* we must now build type1.encoding when we have a custom */ - /* array.. */ - if ( type1->encoding_type == t1_encoding_array ) - { - FT_Int charcode, index, min_char, max_char; - FT_Byte* char_name; - FT_Byte* glyph_name; - - - /* OK, we do the following: for each element in the encoding */ - /* table, look up the index of the glyph having the same name */ - /* the index is then stored in type1.encoding.char_index, and */ - /* a the name to type1.encoding.char_name */ - - min_char = +32000; - max_char = -32000; - - charcode = 0; - for ( ; charcode < loader.encoding_table.num_elems; charcode++ ) - { - type1->encoding.char_index[charcode] = 0; - type1->encoding.char_name [charcode] = ".notdef"; - - char_name = loader.encoding_table.elements[charcode]; - if ( char_name ) - for ( index = 0; index < type1->num_glyphs; index++ ) - { - glyph_name = (FT_Byte*)type1->glyph_names[index]; - if ( strcmp( (const char*)char_name, - (const char*)glyph_name ) == 0 ) - { - type1->encoding.char_index[charcode] = index; - type1->encoding.char_name [charcode] = (char*)glyph_name; - - if (charcode < min_char) min_char = charcode; - if (charcode > max_char) max_char = charcode; - break; - } - } - } - type1->encoding.code_first = min_char; - type1->encoding.code_last = max_char; - type1->encoding.num_chars = loader.num_chars; - } - - Exit: - t1_done_loader( &loader ); - return error; - } - - -/* END */ diff --git a/src/freetype/type1z/z1load.h b/src/freetype/type1z/z1load.h deleted file mode 100644 index 672b5531b6..0000000000 --- a/src/freetype/type1z/z1load.h +++ /dev/null @@ -1,93 +0,0 @@ -/***************************************************************************/ -/* */ -/* z1load.h */ -/* */ -/* Experimental Type 1 font loader (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifndef Z1LOAD_H -#define Z1LOAD_H - -#include -#include -#include - - -#ifdef FT_FLAT_COMPILE - -#include "z1parse.h" - -#else - -#include - -#endif - - -#ifdef __cplusplus - extern "C" { -#endif - - typedef struct Z1_Loader_ - { - Z1_Parser parser; /* parser used to read the stream */ - - FT_Int num_chars; /* number of characters in encoding */ - Z1_Table encoding_table; /* Z1_Table used to store the */ - /* encoding character names */ - - FT_Int num_glyphs; - Z1_Table glyph_names; - Z1_Table charstrings; - - FT_Int num_subrs; - Z1_Table subrs; - FT_Bool fontdata; - - } Z1_Loader; - - - LOCAL_DEF - FT_Error Z1_Open_Face( T1_Face face ); - -#ifndef Z1_CONFIG_OPTION_NO_MM_SUPPORT - - LOCAL_DEF - FT_Error Z1_Get_Multi_Master( T1_Face face, - FT_Multi_Master* master ); - - LOCAL_DEF - FT_Error Z1_Set_MM_Blend( T1_Face face, - FT_UInt num_coords, - FT_Fixed* coords ); - - LOCAL_DEF - FT_Error Z1_Set_MM_Design( T1_Face face, - FT_UInt num_coords, - FT_Long* coords ); - - LOCAL_DEF - void Z1_Done_Blend( T1_Face face ); - -#endif /* !Z1_CONFIG_OPTION_NO_MM_SUPPORT */ - - -#ifdef __cplusplus - } -#endif - -#endif /* Z1LOAD_H */ - - -/* END */ diff --git a/src/freetype/type1z/z1objs.c b/src/freetype/type1z/z1objs.c deleted file mode 100644 index e452bb5edd..0000000000 --- a/src/freetype/type1z/z1objs.c +++ /dev/null @@ -1,398 +0,0 @@ -/***************************************************************************/ -/* */ -/* z1objs.c */ -/* */ -/* Experimental Type 1 objects manager (body). */ -/* */ -/* 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 -#include - - -#ifdef FT_FLAT_COMPILE - -#include "z1gload.h" -#include "z1load.h" -#include "z1afm.h" - -#else - -#include -#include -#include - -#endif - - -#include - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_z1objs - - - /*************************************************************************/ - /* */ - /* FACE FUNCTIONS */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_Done_Face */ - /* */ - /* */ - /* The face object destructor. */ - /* */ - /* */ - /* face :: A typeless pointer to the face object to destroy. */ - /* */ - LOCAL_FUNC - void Z1_Done_Face( T1_Face face ) - { - FT_Memory memory; - T1_Font* type1 = &face->type1; - - - if ( face ) - { - memory = face->root.memory; - -#ifndef Z1_CONFIG_OPTION_NO_MM_SUPPORT - /* release multiple masters information */ - Z1_Done_Blend( face ); - face->blend = 0; -#endif - - /* release font info strings */ - { - T1_FontInfo* info = &type1->font_info; - - - FREE( info->version ); - FREE( info->notice ); - FREE( info->full_name ); - FREE( info->family_name ); - FREE( info->weight ); - } - - /* release top dictionary */ - FREE( type1->charstrings_len ); - FREE( type1->charstrings ); - FREE( type1->glyph_names ); - - FREE( type1->subrs ); - FREE( type1->subrs_len ); - - FREE( type1->subrs_block ); - FREE( type1->charstrings_block ); - FREE( type1->glyph_names_block ); - - FREE( type1->encoding.char_index ); - FREE( type1->font_name ); - -#ifndef Z1_CONFIG_OPTION_NO_AFM - /* release afm data if present */ - if ( face->afm_data ) - Z1_Done_AFM( memory, (Z1_AFM*)face->afm_data ); -#endif - - /* release unicode map, if any */ - FREE( face->unicode_map.maps ); - face->unicode_map.num_maps = 0; - - face->root.family_name = 0; - face->root.style_name = 0; - } - } - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_Init_Face */ - /* */ - /* */ - /* The face object constructor. */ - /* */ - /* */ - /* stream :: input stream where to load font data. */ - /* */ - /* face_index :: The index of the font face in the resource. */ - /* */ - /* num_params :: Number of additional generic parameters. Ignored. */ - /* */ - /* params :: Additional generic parameters. Ignored. */ - /* */ - /* */ - /* face :: The face record to build. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error Z1_Init_Face( FT_Stream stream, - T1_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ) - { - FT_Error error; - PSNames_Interface* psnames; - - FT_UNUSED( num_params ); - FT_UNUSED( params ); - FT_UNUSED( face_index ); - FT_UNUSED( stream ); - - - face->root.num_faces = 1; - - psnames = (PSNames_Interface*)face->psnames; - if ( !psnames ) - { - psnames = (PSNames_Interface*) - FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), "psnames" ); - - face->psnames = psnames; - } - - /* open the tokenizer, this will also check the font format */ - error = Z1_Open_Face( face ); - if ( error ) - goto Exit; - - /* if we just wanted to check the format, leave successfully now */ - if ( face_index < 0 ) - goto Exit; - - /* check the face index */ - if ( face_index != 0 ) - { - FT_ERROR(( "Z1_Init_Face: invalid face index\n" )); - error = T1_Err_Invalid_Argument; - goto Exit; - } - - /* Now, load the font program into the face object */ - - /* Init the face object fields */ - /* Now set up root face fields */ - { - FT_Face root = (FT_Face)&face->root; - - - root->num_glyphs = face->type1.num_glyphs; - root->num_charmaps = 1; - - root->face_index = face_index; - root->face_flags = FT_FACE_FLAG_SCALABLE; - - root->face_flags |= FT_FACE_FLAG_HORIZONTAL; - - root->face_flags |= FT_FACE_FLAG_GLYPH_NAMES; - - if ( face->type1.font_info.is_fixed_pitch ) - root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; - - if ( face->blend ) - root->face_flags |= FT_FACE_FLAG_MULTIPLE_MASTERS; - - /* XXX: TODO -- add kerning with .afm support */ - - /* get style name -- be careful, some broken fonts only */ - /* have a `/FontName' dictionary entry! */ - root->family_name = face->type1.font_info.family_name; - if ( root->family_name ) - { - char* full = face->type1.font_info.full_name; - char* family = root->family_name; - - - while ( *family && *full == *family ) - { - family++; - full++; - } - - root->style_name = ( *full == ' ' ? full + 1 - : (char *)"Regular" ); - } - else - { - /* do we have a `/FontName'? */ - if ( face->type1.font_name ) - { - root->family_name = face->type1.font_name; - root->style_name = "Regular"; - } - } - - /* no embedded bitmap support */ - root->num_fixed_sizes = 0; - root->available_sizes = 0; - - root->bbox = face->type1.font_bbox; - root->units_per_EM = 1000; - root->ascender = (FT_Short)face->type1.font_bbox.yMax; - root->descender = -(FT_Short)face->type1.font_bbox.yMin; - root->height = ( ( root->ascender + root->descender ) * 12 ) / 10; - - /* now compute the maximum advance width */ - - root->max_advance_width = face->type1.private_dict.standard_width[0]; - - /* compute max advance width for proportional fonts */ - if ( !face->type1.font_info.is_fixed_pitch ) - { - FT_Int max_advance; - - - error = Z1_Compute_Max_Advance( face, &max_advance ); - - /* in case of error, keep the standard width */ - if ( !error ) - root->max_advance_width = max_advance; - else - error = 0; /* clear error */ - } - - root->max_advance_height = root->height; - - root->underline_position = face->type1.font_info.underline_position; - root->underline_thickness = face->type1.font_info.underline_thickness; - - root->max_points = 0; - root->max_contours = 0; - } - - /* charmap support -- synthetize unicode charmap if possible */ - { - FT_Face root = &face->root; - FT_CharMap charmap = face->charmaprecs; - - - /* synthesize a Unicode charmap if there is support in the `PSNames' */ - /* module */ - if ( face->psnames ) - { - PSNames_Interface* psnames = (PSNames_Interface*)face->psnames; - - - if ( psnames->unicode_value ) - { - error = psnames->build_unicodes( - root->memory, - face->type1.num_glyphs, - (const char**)face->type1.glyph_names, - &face->unicode_map ); - if ( !error ) - { - root->charmap = charmap; - charmap->face = (FT_Face)face; - charmap->encoding = ft_encoding_unicode; - charmap->platform_id = 3; - charmap->encoding_id = 1; - charmap++; - } - - /* simply clear the error in case of failure (which really) */ - /* means that out of memory or no unicode glyph names */ - error = FT_Err_Ok; - } - } - - /* now, support either the standard, expert, or custom encoding */ - charmap->face = (FT_Face)face; - charmap->platform_id = 7; /* a new platform id for Adobe fonts? */ - - switch ( face->type1.encoding_type ) - { - case t1_encoding_standard: - charmap->encoding = ft_encoding_adobe_standard; - charmap->encoding_id = 0; - break; - - case t1_encoding_expert: - charmap->encoding = ft_encoding_adobe_expert; - charmap->encoding_id = 1; - break; - - default: - charmap->encoding = ft_encoding_adobe_custom; - charmap->encoding_id = 2; - break; - } - - root->charmaps = face->charmaps; - root->num_charmaps = charmap - face->charmaprecs + 1; - face->charmaps[0] = &face->charmaprecs[0]; - face->charmaps[1] = &face->charmaprecs[1]; - } - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_Init_Driver */ - /* */ - /* */ - /* Initializes a given Type 1 driver object. */ - /* */ - /* */ - /* driver :: A handle to the target driver object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error Z1_Init_Driver( Z1_Driver driver ) - { - FT_UNUSED( driver ); - - return T1_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_Done_Driver */ - /* */ - /* */ - /* Finalizes a given Type 1 driver. */ - /* */ - /* */ - /* driver :: A handle to the target Type 1 driver. */ - /* */ - LOCAL_DEF - void Z1_Done_Driver( Z1_Driver driver ) - { - FT_UNUSED( driver ); - } - - -/* END */ diff --git a/src/freetype/type1z/z1objs.h b/src/freetype/type1z/z1objs.h deleted file mode 100644 index c655a67318..0000000000 --- a/src/freetype/type1z/z1objs.h +++ /dev/null @@ -1,161 +0,0 @@ -/***************************************************************************/ -/* */ -/* z1objs.h */ -/* */ -/* Experimental Type 1 objects manager (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifndef Z1OBJS_H -#define Z1OBJS_H - -#include -#include -#include -#include - -#ifdef __cplusplus - extern "C" { -#endif - - /* The following structures must be defined by the hinter */ - typedef struct Z1_Size_Hints_ Z1_Size_Hints; - typedef struct Z1_Glyph_Hints_ Z1_Glyph_Hints; - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_Driver */ - /* */ - /* */ - /* A handle to a Type 1 driver object. */ - /* */ - typedef struct Z1_DriverRec_ *Z1_Driver; - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_Size */ - /* */ - /* */ - /* A handle to a Type 1 size object. */ - /* */ - typedef struct Z1_SizeRec_* Z1_Size; - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_GlyphSlot */ - /* */ - /* */ - /* A handle to a Type 1 glyph slot object. */ - /* */ - typedef struct Z1_GlyphSlotRec_* Z1_GlyphSlot; - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_CharMap */ - /* */ - /* */ - /* A handle to a Type 1 character mapping object. */ - /* */ - /* */ - /* The Type 1 format doesn't use a charmap but an encoding table. */ - /* The driver is responsible for making up charmap objects */ - /* corresponding to these tables. */ - /* */ - typedef struct Z1_CharMapRec_* Z1_CharMap; - - - /*************************************************************************/ - /* */ - /* HERE BEGINS THE TYPE1 SPECIFIC STUFF */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_SizeRec */ - /* */ - /* */ - /* Type 1 size record. */ - /* */ - typedef struct Z1_SizeRec_ - { - FT_SizeRec root; - FT_Bool valid; - Z1_Size_Hints* hints; /* defined in the hinter. This allows */ - /* us to experiment with different */ - /* hinting schemes without having to */ - /* change `z1objs' each time. */ - } Z1_SizeRec; - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_GlyphSlotRec */ - /* */ - /* */ - /* Type 1 glyph slot record. */ - /* */ - typedef struct Z1_GlyphSlotRec_ - { - FT_GlyphSlotRec root; - - FT_Bool hint; - FT_Bool scaled; - - FT_Int max_points; - FT_Int max_contours; - - FT_Fixed x_scale; - FT_Fixed y_scale; - - Z1_Glyph_Hints* hints; /* defined in the hinter */ - - } Z1_GlyphSlotRec; - - - LOCAL_DEF - FT_Error Z1_Init_Face( FT_Stream stream, - T1_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ); - - LOCAL_DEF - void Z1_Done_Face( T1_Face face ); - - LOCAL_DEF - FT_Error Z1_Init_Driver( Z1_Driver driver ); - - LOCAL_DEF - void Z1_Done_Driver( Z1_Driver driver ); - - -#ifdef __cplusplus - } -#endif - -#endif /* Z1OBJS_H */ - - -/* END */ diff --git a/src/freetype/type1z/z1parse.c b/src/freetype/type1z/z1parse.c deleted file mode 100644 index 9bc2913874..0000000000 --- a/src/freetype/type1z/z1parse.c +++ /dev/null @@ -1,1398 +0,0 @@ -/***************************************************************************/ -/* */ -/* z1parse.c */ -/* */ -/* Experimental Type 1 parser (body). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* The Type 1 parser is in charge of the following: */ - /* */ - /* - provide an implementation of a growing sequence of objects called */ - /* a `Z1_Table' (used to build various tables needed by the loader). */ - /* */ - /* - opening .pfb and .pfa files to extract their top-level and private */ - /* dictionaries. */ - /* */ - /* - read numbers, arrays & strings from any dictionary. */ - /* */ - /* See `z1load.c' to see how data is loaded from the font file. */ - /* */ - /*************************************************************************/ - - -#include -#include -#include -#include -#include - - -#ifdef FT_FLAT_COMPILE - -#include "z1parse.h" - -#else - -#include - -#endif - - -#include /* for strncmp() */ - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_z1parse - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** IMPLEMENTATION OF Z1_TABLE OBJECT *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_New_Table */ - /* */ - /* */ - /* Initialises a Z1_Table. */ - /* */ - /* */ - /* table :: The address of the target table. */ - /* */ - /* */ - /* count :: The table size = the maximum number of elements. */ - /* */ - /* memory :: The memory object to use for all subsequent */ - /* reallocations. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error Z1_New_Table( Z1_Table* table, - FT_Int count, - FT_Memory memory ) - { - FT_Error error; - - - table->memory = memory; - if ( ALLOC_ARRAY( table->elements, count, FT_Byte* ) || - ALLOC_ARRAY( table->lengths, count, FT_Byte* ) ) - goto Exit; - - table->max_elems = count; - table->init = 0xdeadbeef; - table->num_elems = 0; - table->block = 0; - table->capacity = 0; - table->cursor = 0; - - Exit: - if ( error ) - FREE( table->elements ); - - return error; - } - - - static - void shift_elements( Z1_Table* table, - FT_Byte* old_base ) - { - FT_Long delta = table->block - old_base; - FT_Byte** offset = table->elements; - FT_Byte** limit = offset + table->max_elems; - - - if ( delta ) - for ( ; offset < limit; offset++ ) - { - if ( offset[0] ) - offset[0] += delta; - } - } - - - static - FT_Error reallocate_t1_table( Z1_Table* table, - FT_Int new_size ) - { - FT_Memory memory = table->memory; - FT_Byte* old_base = table->block; - FT_Error error; - - - /* reallocate the base block */ - if ( REALLOC( table->block, table->capacity, new_size ) ) - return error; - - table->capacity = new_size; - - /* shift all offsets if necessary */ - if ( old_base ) - shift_elements( table, old_base ); - - return T1_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_Add_Table */ - /* */ - /* */ - /* Adds an object to a Z1_Table, possibly growing its memory block. */ - /* */ - /* */ - /* table :: The target table. */ - /* */ - /* */ - /* index :: The index of the object in the table. */ - /* */ - /* object :: The address of the object to copy in memory. */ - /* */ - /* length :: The length in bytes of the source object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. An error is returned if a */ - /* reallocation fails. */ - /* */ - LOCAL_FUNC - FT_Error Z1_Add_Table( Z1_Table* table, - FT_Int index, - void* object, - FT_Int length ) - { - if ( index < 0 || index > table->max_elems ) - { - FT_ERROR(( "Z1_Add_Table: invalid index\n" )); - return T1_Err_Syntax_Error; - } - - /* grow the base block if needed */ - if ( table->cursor + length > table->capacity ) - { - FT_Error error; - FT_Int new_size = table->capacity; - - - while ( new_size < table->cursor + length ) - new_size += 1024; - - error = reallocate_t1_table( table, new_size ); - if ( error ) - return error; - } - - /* add the object to the base block and adjust offset */ - table->elements[index] = table->block + table->cursor; - table->lengths [index] = length; - MEM_Copy( table->block + table->cursor, object, length ); - - table->cursor += length; - return T1_Err_Ok; - } - - -#if 0 - - /*************************************************************************/ - /* */ - /* */ - /* Z1_Done_Table */ - /* */ - /* */ - /* Finalizes a Z1_Table (i.e., reallocate it to its current cursor). */ - /* */ - /* */ - /* table :: The target table. */ - /* */ - /* */ - /* This function does NOT release the heap's memory block. It is up */ - /* to the caller to clean it, or reference it in its own structures. */ - /* */ - LOCAL_FUNC - void Z1_Done_Table( Z1_Table* table ) - { - FT_Memory memory = table->memory; - FT_Error error; - FT_Byte* old_base; - - - /* should never fail, as rec.cursor <= rec.size */ - old_base = table->block; - if ( !old_base ) - return; - - (void)REALLOC( table->block, table->capacity, table->cursor ); - table->capacity = table->cursor; - - if ( old_base != table->block ) - shift_elements( table, old_base ); - } - -#endif /* 0 */ - - - LOCAL_FUNC - void Z1_Release_Table( Z1_Table* table ) - { - FT_Memory memory = table->memory; - - - if ( table->init == (FT_Long)0xDEADBEEF ) - { - FREE( table->block ); - FREE( table->elements ); - FREE( table->lengths ); - table->init = 0; - } - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** INPUT STREAM PARSER *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - -#define IS_Z1_WHITESPACE( c ) ( (c) == ' ' || (c) == '\t' ) -#define IS_Z1_LINESPACE( c ) ( (c) == '\r' || (c) == '\n' ) - -#define IS_Z1_SPACE( c ) ( IS_Z1_WHITESPACE( c ) || IS_Z1_LINESPACE( c ) ) - - - LOCAL_FUNC - void Z1_Skip_Spaces( Z1_Parser* parser ) - { - FT_Byte* cur = parser->cursor; - FT_Byte* limit = parser->limit; - - - while ( cur < limit ) - { - FT_Byte c = *cur; - - - if ( !IS_Z1_SPACE( c ) ) - break; - cur++; - } - parser->cursor = cur; - } - - - LOCAL_FUNC - void Z1_ToToken( Z1_Parser* parser, - Z1_Token_Rec* token ) - { - FT_Byte* cur; - FT_Byte* limit; - FT_Byte starter, ender; - FT_Int embed; - - - token->type = t1_token_none; - token->start = 0; - token->limit = 0; - - /* first of all, skip space */ - Z1_Skip_Spaces( parser ); - - cur = parser->cursor; - limit = parser->limit; - - if ( cur < limit ) - { - switch ( *cur ) - { - /************* check for strings ***********************/ - case '(': - token->type = t1_token_string; - ender = ')'; - goto Lookup_Ender; - - /************* check for programs/array ****************/ - case '{': - token->type = t1_token_array; - ender = '}'; - goto Lookup_Ender; - - /************* check for table/array ******************/ - case '[': - token->type = t1_token_array; - ender = ']'; - - Lookup_Ender: - embed = 1; - starter = *cur++; - token->start = cur; - while ( cur < limit ) - { - if ( *cur == starter ) - embed++; - else if ( *cur == ender ) - { - embed--; - if ( embed <= 0 ) - { - token->limit = cur++; - break; - } - } - cur++; - } - break; - - /* **************** otherwise, it's any token **********/ - default: - token->start = cur++; - token->type = t1_token_any; - while ( cur < limit && !IS_Z1_SPACE( *cur ) ) - cur++; - - token->limit = cur; - } - - if ( !token->limit ) - { - token->start = 0; - token->type = t1_token_none; - } - - parser->cursor = cur; - } - } - - - LOCAL_FUNC - void Z1_ToTokenArray( Z1_Parser* parser, - Z1_Token_Rec* tokens, - FT_UInt max_tokens, - FT_Int* pnum_tokens ) - { - Z1_Token_Rec master; - - - *pnum_tokens = -1; - - Z1_ToToken( parser, &master ); - if ( master.type == t1_token_array ) - { - FT_Byte* old_cursor = parser->cursor; - FT_Byte* old_limit = parser->limit; - Z1_Token_Rec* cur = tokens; - Z1_Token_Rec* limit = cur + max_tokens; - - - parser->cursor = master.start; - parser->limit = master.limit; - - while ( parser->cursor < parser->limit ) - { - Z1_Token_Rec token; - - - Z1_ToToken( parser, &token ); - if ( !token.type ) - break; - - if ( cur < limit ) - *cur = token; - - cur++; - } - - *pnum_tokens = cur - tokens; - - parser->cursor = old_cursor; - parser->limit = old_limit; - } - } - - - static - FT_Long t1_toint( FT_Byte** cursor, - FT_Byte* limit ) - { - FT_Long result = 0; - FT_Byte* cur = *cursor; - FT_Byte c, d; - - - for ( ; cur < limit; cur++ ) - { - c = *cur; - d = (FT_Byte)( c - '0' ); - if ( d < 10 ) - break; - - if ( c == '-' ) - { - cur++; - break; - } - } - - if ( cur < limit ) - { - do - { - d = (FT_Byte)( cur[0] - '0' ); - if ( d >= 10 ) - break; - - result = result * 10 + d; - cur++; - - } while ( cur < limit ); - - if ( c == '-' ) - result = -result; - } - - *cursor = cur; - return result; - } - - - static - FT_Long t1_tofixed( FT_Byte** cursor, - FT_Byte* limit, - FT_Long power_ten ) - { - FT_Byte* cur = *cursor; - FT_Long num, divider, result; - FT_Int sign = 0; - FT_Byte d; - - - if ( cur >= limit ) - return 0; - - /* first of all, read the integer part */ - result = t1_toint( &cur, limit ) << 16; - num = 0; - divider = 1; - - if ( result < 0 ) - { - sign = 1; - result = -result; - } - - if ( cur >= limit ) - goto Exit; - - /* read decimal part, if any */ - if ( *cur == '.' && cur + 1 < limit ) - { - cur++; - - for (;;) - { - d = (FT_Byte)( *cur - '0' ); - if ( d >= 10 ) - break; - - if ( divider < 10000000L ) - { - num = num * 10 + d; - divider *= 10; - } - - cur++; - if ( cur >= limit ) - break; - } - } - - /* read exponent, if any */ - if ( cur + 1 < limit && ( *cur == 'e' || *cur == 'E' ) ) - { - cur++; - power_ten += t1_toint( &cur, limit ); - } - - Exit: - /* raise to power of ten if needed */ - while ( power_ten > 0 ) - { - result = result * 10; - num = num * 10; - power_ten--; - } - - while ( power_ten < 0 ) - { - result = result / 10; - divider = divider * 10; - power_ten++; - } - - if ( num ) - result += FT_DivFix( num, divider ); - - if ( sign ) - result = -result; - - *cursor = cur; - return result; - } - - - static - FT_Int t1_tocoordarray( FT_Byte** cursor, - FT_Byte* limit, - FT_Int max_coords, - FT_Short* coords ) - { - FT_Byte* cur = *cursor; - FT_Int count = 0; - FT_Byte c, ender; - - - if ( cur >= limit ) - goto Exit; - - /* check for the beginning of an array. If not, only one number will */ - /* be read */ - c = *cur; - ender = 0; - - if ( c == '[' ) - ender = ']'; - - if ( c == '{' ) - ender = '}'; - - if ( ender ) - cur++; - - /* now, read the coordinates */ - for ( ; cur < limit; ) - { - /* skip whitespace in front of data */ - for (;;) - { - c = *cur; - if ( c != ' ' && c != '\t' ) - break; - - cur++; - if ( cur >= limit ) - goto Exit; - } - - if ( count >= max_coords || c == ender ) - break; - - coords[count] = (FT_Short)( t1_tofixed( &cur, limit, 0 ) >> 16 ); - count++; - - if ( !ender ) - break; - } - - Exit: - *cursor = cur; - return count; - } - - - static - FT_Int t1_tofixedarray( FT_Byte** cursor, - FT_Byte* limit, - FT_Int max_values, - FT_Fixed* values, - FT_Int power_ten ) - { - FT_Byte* cur = *cursor; - FT_Int count = 0; - FT_Byte c, ender; - - - if ( cur >= limit ) goto Exit; - - /* check for the beginning of an array. If not, only one number will */ - /* be read */ - c = *cur; - ender = 0; - - if ( c == '[' ) - ender = ']'; - - if ( c == '{' ) - ender = '}'; - - if ( ender ) - cur++; - - /* now, read the values */ - for ( ; cur < limit; ) - { - /* skip whitespace in front of data */ - for (;;) - { - c = *cur; - if ( c != ' ' && c != '\t' ) - break; - - cur++; - if ( cur >= limit ) - goto Exit; - } - - if ( count >= max_values || c == ender ) - break; - - values[count] = t1_tofixed( &cur, limit, power_ten ); - count++; - - if ( !ender ) - break; - } - - Exit: - *cursor = cur; - return count; - } - - -#if 0 - - static - FT_String* t1_tostring( FT_Byte** cursor, - FT_Byte* limit, - FT_Memory memory ) - { - FT_Byte* cur = *cursor; - FT_Int len = 0; - FT_Int count; - FT_String* result; - FT_Error error; - - - /* XXX: some stupid fonts have a `Notice' or `Copyright' string */ - /* that simply doesn't begin with an opening parenthesis, even */ - /* though they have a closing one! E.g. "amuncial.pfb" */ - /* */ - /* We must deal with these ill-fated cases there. Note that */ - /* these fonts didn't work with the old Type 1 driver as the */ - /* notice/copyright was not recognized as a valid string token */ - /* and made the old token parser commit errors. */ - - while ( cur < limit && ( *cur == ' ' || *cur == '\t' ) ) - cur++; - if ( cur + 1 >= limit ) - return 0; - - if ( *cur == '(' ) - cur++; /* skip the opening parenthesis, if there is one */ - - *cursor = cur; - count = 0; - - /* then, count its length */ - for ( ; cur < limit; cur++ ) - { - if ( *cur == '(' ) - count++; - - else if ( *cur == ')' ) - { - count--; - if ( count < 0 ) - break; - } - } - - len = cur - *cursor; - if ( cur >= limit || ALLOC( result, len + 1 ) ) - return 0; - - /* now copy the string */ - MEM_Copy( result, *cursor, len ); - result[len] = '\0'; - *cursor = cur; - return result; - } - -#endif /* 0 */ - - - static - int t1_tobool( FT_Byte** cursor, - FT_Byte* limit ) - { - FT_Byte* cur = *cursor; - FT_Bool result = 0; - - - /* return 1 if we find `true', 0 otherwise */ - if ( cur + 3 < limit && - cur[0] == 't' && - cur[1] == 'r' && - cur[2] == 'u' && - cur[3] == 'e' ) - { - result = 1; - cur += 5; - } - else if ( cur + 4 < limit && - cur[0] == 'f' && - cur[1] == 'a' && - cur[2] == 'l' && - cur[3] == 's' && - cur[4] == 'e' ) - { - result = 0; - cur += 6; - } - - *cursor = cur; - return result; - } - - - /* Load a simple field (i.e. non-table) into the current list of objects */ - LOCAL_FUNC - FT_Error Z1_Load_Field( Z1_Parser* parser, - const Z1_Field_Rec* field, - void** objects, - FT_UInt max_objects, - FT_ULong* pflags ) - { - Z1_Token_Rec token; - FT_Byte* cur; - FT_Byte* limit; - FT_UInt count; - FT_UInt index; - FT_Error error; - - - Z1_ToToken( parser, &token ); - if ( !token.type ) - goto Fail; - - count = 1; - index = 0; - cur = token.start; - limit = token.limit; - - if ( token.type == t1_token_array ) - { - /* if this is an array, and we have no blend, an error occurs */ - if ( max_objects == 0 ) - goto Fail; - - count = max_objects; - index = 1; - } - - for ( ; count > 0; count--, index++ ) - { - FT_Byte* q = (FT_Byte*)objects[index] + field->offset; - FT_Long val; - FT_String* string; - - switch ( field->type ) - { - case t1_field_bool: - val = t1_tobool( &cur, limit ); - goto Store_Integer; - - case t1_field_fixed: - val = t1_tofixed( &cur, limit, 3 ); - goto Store_Integer; - - case t1_field_integer: - val = t1_toint( &cur, limit ); - - Store_Integer: - switch ( field->size ) - { - case 1: - *(FT_Byte*)q = (FT_Byte)val; - break; - - case 2: - *(FT_UShort*)q = (FT_UShort)val; - break; - - case 4: - *(FT_UInt32*)q = (FT_UInt32)val; - break; - - default: /* for 64-bit systems */ - *(FT_Long*)q = val; - } - break; - - case t1_field_string: - { - FT_Memory memory = parser->memory; - FT_UInt len = limit-cur; - - if ( ALLOC( string, len + 1 ) ) - goto Exit; - - MEM_Copy( string, cur, len ); - string[len] = 0; - - *(FT_String**)q = string; - } - break; - - default: - /* an error occured */ - goto Fail; - } - } - - if ( pflags ) - *pflags |= 1L << field->flag_bit; - - error = FT_Err_Ok; - - Exit: - return error; - - Fail: - error = T1_Err_Invalid_File_Format; - goto Exit; - } - - -#define T1_MAX_TABLE_ELEMENTS 32 - - - LOCAL_FUNC - FT_Error Z1_Load_Field_Table( Z1_Parser* parser, - const Z1_Field_Rec* field, - void** objects, - FT_UInt max_objects, - FT_ULong* pflags ) - { - Z1_Token_Rec elements[T1_MAX_TABLE_ELEMENTS]; - Z1_Token_Rec* token; - FT_Int num_elements; - FT_Error error = 0; - FT_Byte* old_cursor; - FT_Byte* old_limit; - Z1_Field_Rec fieldrec = *(Z1_Field_Rec*)field; - - - Z1_ToTokenArray( parser, elements, 32, &num_elements ); - if ( num_elements < 0 ) - goto Fail; - - if ( num_elements > T1_MAX_TABLE_ELEMENTS ) - num_elements = T1_MAX_TABLE_ELEMENTS; - - old_cursor = parser->cursor; - old_limit = parser->limit; - - /* we store the elements count */ - *(FT_Byte*)( (FT_Byte*)objects[0] + field->count_offset ) = num_elements; - - /* we now load each element, adjusting the field.offset on each one */ - token = elements; - for ( ; num_elements > 0; num_elements--, token++ ) - { - parser->cursor = token->start; - parser->limit = token->limit; - Z1_Load_Field( parser, &fieldrec, objects, max_objects, 0 ); - fieldrec.offset += fieldrec.size; - } - - if ( pflags ) - *pflags |= 1L << field->flag_bit; - - parser->cursor = old_cursor; - parser->limit = old_limit; - - Exit: - return error; - - Fail: - error = T1_Err_Invalid_File_Format; - goto Exit; - } - - - LOCAL_FUNC - FT_Long Z1_ToInt ( Z1_Parser* parser ) - { - return t1_toint( &parser->cursor, parser->limit ); - } - - - LOCAL_FUNC - FT_Long Z1_ToFixed( Z1_Parser* parser, - FT_Int power_ten ) - { - return t1_tofixed( &parser->cursor, parser->limit, power_ten ); - } - - - LOCAL_FUNC - FT_Int Z1_ToCoordArray( Z1_Parser* parser, - FT_Int max_coords, - FT_Short* coords ) - { - return t1_tocoordarray( &parser->cursor, parser->limit, - max_coords, coords ); - } - - - LOCAL_FUNC - FT_Int Z1_ToFixedArray( Z1_Parser* parser, - FT_Int max_values, - FT_Fixed* values, - FT_Int power_ten ) - { - return t1_tofixedarray( &parser->cursor, parser->limit, - max_values, values, power_ten ); - } - - -#if 0 - - LOCAL_FUNC - FT_String* Z1_ToString( Z1_Parser* parser ) - { - return t1_tostring( &parser->cursor, parser->limit, parser->memory ); - } - - - LOCAL_FUNC - FT_Bool Z1_ToBool( Z1_Parser* parser ) - { - return t1_tobool( &parser->cursor, parser->limit ); - } - -#endif /* 0 */ - - - static - FT_Error read_pfb_tag( FT_Stream stream, - FT_UShort* tag, - FT_Long* size ) - { - FT_Error error; - - - if ( READ_UShort( *tag ) ) - goto Exit; - - if ( *tag == 0x8001 || *tag == 0x8002 ) - { - FT_Long asize; - - - if ( READ_ULong( asize ) ) - goto Exit; - - /* swap between big and little endianness */ - *size = ( ( asize & 0xFF000000L ) >> 24 ) | - ( ( asize & 0x00FF0000L ) >> 8 ) | - ( ( asize & 0x0000FF00L ) << 8 ) | - ( ( asize & 0x000000FFL ) << 24 ); - } - - Exit: - return error; - } - - - LOCAL_FUNC - FT_Error Z1_New_Parser( Z1_Parser* parser, - FT_Stream stream, - FT_Memory memory ) - { - FT_Error error; - FT_UShort tag; - FT_Long size; - - - parser->stream = stream; - parser->memory = memory; - parser->base_len = 0; - parser->base_dict = 0; - parser->private_len = 0; - parser->private_dict = 0; - parser->in_pfb = 0; - parser->in_memory = 0; - parser->single_block = 0; - - parser->cursor = 0; - parser->limit = 0; - - /******************************************************************/ - /* */ - /* Here a short summary of what is going on: */ - /* */ - /* When creating a new Type 1 parser, we try to locate and load */ - /* the base dictionary if this is possible (i.e. for PFB */ - /* files). Otherwise, we load the whole font into memory. */ - /* */ - /* When `loading' the base dictionary, we only setup pointers */ - /* in the case of a memory-based stream. Otherwise, we */ - /* allocate and load the base dictionary in it. */ - /* */ - /* parser->in_pfb is set if we are in a binary (".pfb") font. */ - /* parser->in_memory is set if we have a memory stream. */ - /* */ - - /* try to compute the size of the base dictionary; */ - /* look for a Postscript binary file tag, i.e 0x8001 */ - if ( FILE_Seek( 0L ) ) - goto Exit; - - error = read_pfb_tag( stream, &tag, &size ); - if ( error ) - goto Exit; - - if ( tag != 0x8001 ) - { - /* assume that this is a PFA file for now; an error will */ - /* be produced later when more things are checked */ - (void)FILE_Seek( 0L ); - size = stream->size; - } - else - parser->in_pfb = 1; - - /* now, try to load `size' bytes of the `base' dictionary we */ - /* found previously */ - - /* if it is a memory-based resource, set up pointers */ - if ( !stream->read ) - { - parser->base_dict = (FT_Byte*)stream->base + stream->pos; - parser->base_len = size; - parser->in_memory = 1; - - /* check that the `size' field is valid */ - if ( FILE_Skip( size ) ) - goto Exit; - } - else - { - /* read segment in memory */ - if ( ALLOC( parser->base_dict, size ) || - FILE_Read( parser->base_dict, size ) ) - goto Exit; - parser->base_len = size; - } - - /* Now check font format; we must see `%!PS-AdobeFont-1' */ - /* or `%!FontType' */ - { - if ( size <= 16 || - ( strncmp( (const char*)parser->base_dict, - "%!PS-AdobeFont-1", 16 ) && - strncmp( (const char*)parser->base_dict, - "%!FontType", 10 ) ) ) - { - FT_TRACE2(( "[not a Type1 font]\n" )); - error = FT_Err_Unknown_File_Format; - } - else - { - parser->cursor = parser->base_dict; - parser->limit = parser->cursor + parser->base_len; - } - } - - Exit: - if ( error && !parser->in_memory ) - FREE( parser->base_dict ); - - return error; - } - - - LOCAL_FUNC - void Z1_Done_Parser( Z1_Parser* parser ) - { - FT_Memory memory = parser->memory; - - - /* always free the private dictionary */ - FREE( parser->private_dict ); - - /* free the base dictionary only when we have a disk stream */ - if ( !parser->in_memory ) - FREE( parser->base_dict ); - } - - - /* return the value of an hexadecimal digit */ - static - int hexa_value( char c ) - { - unsigned int d; - - - d = (unsigned int)( c - '0' ); - if ( d <= 9 ) - return (int)d; - - d = (unsigned int)( c - 'a' ); - if ( d <= 5 ) - return (int)( d + 10 ); - - d = (unsigned int)( c - 'A' ); - if ( d <= 5 ) - return (int)( d + 10 ); - - return -1; - } - - - LOCAL_FUNC - void Z1_Decrypt( FT_Byte* buffer, - FT_Int length, - FT_UShort seed ) - { - while ( length > 0 ) - { - FT_Byte plain; - - - plain = ( *buffer ^ ( seed >> 8 ) ); - seed = ( *buffer + seed ) * 52845 + 22719; - *buffer++ = plain; - length--; - } - } - - - LOCAL_FUNC - FT_Error Z1_Get_Private_Dict( Z1_Parser* parser ) - { - FT_Stream stream = parser->stream; - FT_Memory memory = parser->memory; - FT_Error error = 0; - FT_Long size; - - - if ( parser->in_pfb ) - { - /* in the case of the PFB format, the private dictionary can be */ - /* made of several segments. We thus first read the number of */ - /* segments to compute the total size of the private dictionary */ - /* then re-read them into memory. */ - FT_Long start_pos = FILE_Pos(); - FT_UShort tag; - FT_Long size; - - - parser->private_len = 0; - for (;;) - { - error = read_pfb_tag( stream, &tag, &size ); - if ( error ) - goto Fail; - - if ( tag != 0x8002 ) - break; - - parser->private_len += size; - - if ( FILE_Skip( size ) ) - goto Fail; - } - - /* Check that we have a private dictionary there */ - /* and allocate private dictionary buffer */ - if ( parser->private_len == 0 ) - { - FT_ERROR(( "Z1_Get_Private_Dict:" )); - FT_ERROR(( " invalid private dictionary section\n" )); - error = T1_Err_Invalid_File_Format; - goto Fail; - } - - if ( FILE_Seek( start_pos ) || - ALLOC( parser->private_dict, parser->private_len ) ) - goto Fail; - - parser->private_len = 0; - for (;;) - { - error = read_pfb_tag( stream, &tag, &size ); - if ( error || tag != 0x8002 ) - { - error = FT_Err_Ok; - break; - } - - if ( FILE_Read( parser->private_dict + parser->private_len, size ) ) - goto Fail; - - parser->private_len += size; - } - } - else - { - /* we have already `loaded' the whole PFA font file into memory; */ - /* if this is a memory resource, allocate a new block to hold */ - /* the private dict. Otherwise, simply overwrite into the base */ - /* dictionary block in the heap. */ - - /* first of all, look at the `eexec' keyword */ - FT_Byte* cur = parser->base_dict; - FT_Byte* limit = cur + parser->base_len; - FT_Byte c; - - - for (;;) - { - c = cur[0]; - if ( c == 'e' && cur + 9 < limit ) /* 9 = 5 letters for `eexec' + */ - /* newline + 4 chars */ - { - if ( cur[1] == 'e' && cur[2] == 'x' && - cur[3] == 'e' && cur[4] == 'c' ) - { - cur += 6; /* we skip the newling after the `eexec' */ - - /* XXX: Some fonts use DOS-linefeeds, i.e. \r\n; we need to */ - /* skip the extra \n if we find it */ - if ( cur[0] == '\n' ) - cur++; - - break; - } - } - cur++; - if ( cur >= limit ) - { - FT_ERROR(( "Z1_Get_Private_Dict:" )); - FT_ERROR(( " could not find `eexec' keyword\n" )); - error = T1_Err_Invalid_File_Format; - goto Exit; - } - } - - /* now determine where to write the _encrypted_ binary private */ - /* dictionary. We overwrite the base dictionary for disk-based */ - /* resources and allocate a new block otherwise */ - - size = parser->base_len - ( cur - parser->base_dict); - - if ( parser->in_memory ) - { - /* note that we allocate one more byte to put a terminating `0' */ - if ( ALLOC( parser->private_dict, size + 1 ) ) - goto Fail; - parser->private_len = size; - } - else - { - parser->single_block = 1; - parser->private_dict = parser->base_dict; - parser->private_len = size; - parser->base_dict = 0; - parser->base_len = 0; - } - - /* now determine whether the private dictionary is encoded in binary */ - /* or hexadecimal ASCII format -- decode it accordingly */ - - /* we need to access the next 4 bytes (after the final \r following */ - /* the `eexec' keyword); if they all are hexadecimal digits, then */ - /* we have a case of ASCII storage */ - - if ( ( hexa_value( cur[0] ) | hexa_value( cur[1] ) | - hexa_value( cur[2] ) | hexa_value( cur[3] ) ) < 0 ) - - /* binary encoding -- `simply' copy the private dict */ - MEM_Copy( parser->private_dict, cur, size ); - - else - { - /* ASCII hexadecimal encoding */ - - FT_Byte* write; - FT_Int count; - - - write = parser->private_dict; - count = 0; - - for ( ;cur < limit; cur++ ) - { - int hex1; - - - /* check for newline */ - if ( cur[0] == '\r' || cur[0] == '\n' ) - continue; - - /* exit if we have a non-hexadecimal digit that isn't a newline */ - hex1 = hexa_value( cur[0] ); - if ( hex1 < 0 || cur + 1 >= limit ) - break; - - /* otherwise, store byte */ - *write++ = ( hex1 << 4 ) | hexa_value( cur[1] ); - count++; - cur++; - } - - /* put a safeguard */ - parser->private_len = write - parser->private_dict; - *write++ = 0; - } - } - - /* we now decrypt the encoded binary private dictionary */ - Z1_Decrypt( parser->private_dict, parser->private_len, 55665 ); - parser->cursor = parser->private_dict; - parser->limit = parser->cursor + parser->private_len; - - Fail: - Exit: - return error; - } - - -/* END */ diff --git a/src/freetype/type1z/z1parse.h b/src/freetype/type1z/z1parse.h deleted file mode 100644 index d0b6a6503e..0000000000 --- a/src/freetype/type1z/z1parse.h +++ /dev/null @@ -1,363 +0,0 @@ -/***************************************************************************/ -/* */ -/* z1parse.h */ -/* */ -/* Experimental Type 1 parser (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifndef Z1PARSE_H -#define Z1PARSE_H - -#include - -#ifdef __cplusplus - extern "C" { -#endif - - - /* simple enumeration type used to identify token types */ - typedef enum Z1_Token_Type_ - { - t1_token_none = 0, - t1_token_any, - t1_token_string, - t1_token_array, - - /* do not remove */ - t1_token_max - - } Z1_Token_Type; - - - /* a simple structure used to identify tokens */ - typedef struct Z1_Token_Rec_ - { - FT_Byte* start; /* first character of token in input stream */ - FT_Byte* limit; /* first character after the token */ - Z1_Token_Type type; /* type of token.. */ - - } Z1_Token_Rec; - - - /* enumeration type used to identify object fields */ - typedef enum Z1_Field_Type_ - { - t1_field_none = 0, - t1_field_bool, - t1_field_integer, - t1_field_fixed, - t1_field_string, - t1_field_integer_array, - t1_field_fixed_array, - - /* do not remove */ - t1_field_max - - } Z1_Field_Type; - - - /* structure type used to model object fields */ - typedef struct Z1_Field_Rec_ - { - Z1_Field_Type type; /* type of field */ - FT_UInt offset; /* offset of field in object */ - FT_UInt size; /* size of field in bytes */ - FT_UInt array_max; /* maximum number of elements for array */ - FT_UInt count_offset; /* offset of element count for arrays */ - FT_Int flag_bit; /* bit number for field flag */ - - } Z1_Field_Rec; - - -#define Z1_FIELD_REF( s, f ) ( ((s*)0)->f ) - -#define Z1_FIELD_BOOL( _ftype, _fname ) \ - { \ - t1_field_bool, \ - (FT_UInt)(char*)&Z1_FIELD_REF( _ftype, _fname ), \ - sizeof ( Z1_FIELD_REF( _ftype, _fname ) ), \ - 0, 0, 0 \ - } - -#define Z1_FIELD_NUM( _ftype, _fname ) \ - { \ - t1_field_integer, \ - (FT_UInt)(char*)&Z1_FIELD_REF( _ftype, _fname ), \ - sizeof ( Z1_FIELD_REF( _ftype, _fname ) ), \ - 0, 0, 0 \ - } - -#define Z1_FIELD_FIXED( _ftype, _fname, _power ) \ - { \ - t1_field_fixed, \ - (FT_UInt)(char*)&Z1_FIELD_REF( _ftype, _fname ), \ - sizeof ( Z1_FIELD_REF( _ftype, _fname ) ), \ - 0, 0, 0 \ - } - -#define Z1_FIELD_STRING( _ftype, _fname ) \ - { \ - t1_field_string, \ - (FT_UInt)(char*)&Z1_FIELD_REF( _ftype, _fname ), \ - sizeof ( Z1_FIELD_REF( _ftype, _fname ) ), \ - 0, 0, 0 \ - } - -#define Z1_FIELD_NUM_ARRAY( _ftype, _fname, _fcount, _fmax ) \ - { \ - t1_field_integer, \ - (FT_UInt)(char*)&Z1_FIELD_REF( _ftype, _fname ), \ - sizeof ( Z1_FIELD_REF( _ftype, _fname )[0] ), \ - _fmax, \ - (FT_UInt)(char*)&Z1_FIELD_REF( _ftype, _fcount ), \ - 0 \ - } - -#define Z1_FIELD_FIXED_ARRAY( _ftype, _fname, _fcount, _fmax ) \ - { \ - t1_field_fixed, \ - (FT_UInt)(char*)&Z1_FIELD_REF( _ftype, _fname ), \ - sizeof ( Z1_FIELD_REF( _ftype, _fname )[0] ), \ - _fmax, \ - (FT_UInt)(char*)&Z1_FIELD_REF( _ftype, _fcount ), \ - 0 \ - } - -#define Z1_FIELD_NUM_ARRAY2( _ftype, _fname, _fmax ) \ - { \ - t1_field_integer, \ - (FT_UInt)(char*)&Z1_FIELD_REF( _ftype, _fname ), \ - sizeof ( Z1_FIELD_REF( _ftype, _fname )[0] ), \ - _fmax, \ - 0, 0 \ - } - -#define Z1_FIELD_FIXED_ARRAY2( _ftype, _fname, _fmax ) \ - { \ - t1_field_fixed, \ - (FT_UInt)(char*)&Z1_FIELD_REF( _ftype, _fname ), \ - sizeof ( Z1_FIELD_REF( _ftype, _fname )[0] ), \ - _fmax, \ - 0, 0 \ - } - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_Table */ - /* */ - /* */ - /* A Z1_Table is a simple object used to store an array of objects in */ - /* a single memory block. */ - /* */ - /* */ - /* block :: The address in memory of the growheap's block. This */ - /* can change between two object adds, due to the use of */ - /* reallocation. */ - /* */ - /* cursor :: The current top of the grow heap within its block. */ - /* */ - /* capacity :: The current size of the heap block. Increments in */ - /* 1kByte blocks. */ - /* */ - /* init :: A boolean. Set when the table has been initialized */ - /* (the table user should set this field). */ - /* */ - /* max_elems :: The maximum number of elements in the table. */ - /* */ - /* num_elems :: The current number of elements in the table. */ - /* */ - /* elements :: A table of element addresses within the block. */ - /* */ - /* lengths :: A table of element sizes within the block. */ - /* */ - /* memory :: The memory object used for memory operations */ - /* (allocation/reallocation). */ - /* */ - typedef struct Z1_Table_ - { - FT_Byte* block; /* current memory block */ - FT_Int cursor; /* current cursor in memory block */ - FT_Int capacity; /* current size of memory block */ - FT_Long init; - - FT_Int max_elems; - FT_Int num_elems; - FT_Byte** elements; /* addresses of table elements */ - FT_Int* lengths; /* lengths of table elements */ - - FT_Memory memory; - - } Z1_Table; - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_Parser */ - /* */ - /* */ - /* A Z1_Parser is an object used to parse a Type 1 fonts very */ - /* quickly. */ - /* */ - /* */ - /* stream :: The current input stream. */ - /* */ - /* memory :: The current memory object. */ - /* */ - /* base_dict :: A pointer to the top-level dictionary. */ - /* */ - /* base_len :: The length in bytes of the top dictionary. */ - /* */ - /* private_dict :: A pointer to the private dictionary. */ - /* */ - /* private_len :: The length in bytes of the private dictionary. */ - /* */ - /* in_pfb :: A boolean. Indicates that we are handling a PFB */ - /* file. */ - /* */ - /* in_memory :: A boolean. Indicates a memory-based stream. */ - /* */ - /* single_block :: A boolean. Indicates that the private dictionary */ - /* is stored in lieu of the base dictionary. */ - /* */ - /* cursor :: The current parser cursor. */ - /* */ - /* limit :: The current parser limit (first byte after the */ - /* current dictionary). */ - /* */ - /* error :: The current parsing error. */ - /* */ - typedef struct Z1_Parser_ - { - FT_Stream stream; - FT_Memory memory; - - FT_Byte* base_dict; - FT_Int base_len; - - FT_Byte* private_dict; - FT_Int private_len; - - FT_Byte in_pfb; - FT_Byte in_memory; - FT_Byte single_block; - - FT_Byte* cursor; - FT_Byte* limit; - FT_Error error; - - } Z1_Parser; - - - LOCAL_DEF - FT_Error Z1_New_Table( Z1_Table* table, - FT_Int count, - FT_Memory memory ); - - - LOCAL_DEF - FT_Error Z1_Add_Table( Z1_Table* table, - FT_Int index, - void* object, - FT_Int length ); - -#if 0 - LOCAL_DEF - void Z1_Done_Table( Z1_Table* table ); -#endif - - LOCAL_DEF - void Z1_Release_Table( Z1_Table* table ); - - LOCAL_DEF - FT_Long Z1_ToInt( Z1_Parser* parser ); - - LOCAL_DEF - FT_Long Z1_ToFixed( Z1_Parser* parser, - FT_Int power_ten ); - - LOCAL_DEF - FT_Int Z1_ToCoordArray( Z1_Parser* parser, - FT_Int max_coords, - FT_Short* coords ); - - LOCAL_DEF - FT_Int Z1_ToFixedArray( Z1_Parser* parser, - FT_Int max_values, - FT_Fixed* values, - FT_Int power_ten ); - -#if 0 - LOCAL_DEF - FT_String* Z1_ToString( Z1_Parser* parser ); - - LOCAL_DEF - FT_Bool Z1_ToBool( Z1_Parser* parser ); -#endif - - - LOCAL_DEF - void Z1_Skip_Spaces( Z1_Parser* parser ); - - LOCAL_DEF - void Z1_ToToken( Z1_Parser* parser, - Z1_Token_Rec* token ); - - LOCAL_FUNC - void Z1_ToTokenArray( Z1_Parser* parser, - Z1_Token_Rec* tokens, - FT_UInt max_tokens, - FT_Int* pnum_tokens ); - - LOCAL_DEF - FT_Error Z1_Load_Field( Z1_Parser* parser, - const Z1_Field_Rec* field, - void** objects, - FT_UInt max_objects, - FT_ULong* pflags ); - - LOCAL_DEF - FT_Error Z1_Load_Field_Table( Z1_Parser* parser, - const Z1_Field_Rec* field, - void** objects, - FT_UInt max_objects, - FT_ULong* pflags ); - - - LOCAL_DEF - FT_Error Z1_New_Parser( Z1_Parser* parser, - FT_Stream stream, - FT_Memory memory ); - - LOCAL_DEF - FT_Error Z1_Get_Private_Dict( Z1_Parser* parser ); - - LOCAL_DEF - void Z1_Decrypt( FT_Byte* buffer, - FT_Int length, - FT_UShort seed ); - - LOCAL_DEF - void Z1_Done_Parser( Z1_Parser* parser ); - -#ifdef __cplusplus - } -#endif - -#endif /* Z1PARSE_H */ - - -/* END */ diff --git a/src/freetype/type1z/z1tokens.h b/src/freetype/type1z/z1tokens.h deleted file mode 100644 index 73c0228e53..0000000000 --- a/src/freetype/type1z/z1tokens.h +++ /dev/null @@ -1,132 +0,0 @@ -/***************************************************************************/ -/* */ -/* z1tokens.h */ -/* */ -/* Experimental Type 1 tokenizer (specification). */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#undef T1TYPE -#define T1TYPE T1_FontInfo - - Z1_FONTINFO_STRING( "version", version ) - Z1_FONTINFO_STRING( "Notice", notice ) - Z1_FONTINFO_STRING( "FullName", full_name ) - Z1_FONTINFO_STRING( "FamilyName", family_name ) - Z1_FONTINFO_STRING( "Weight", weight ) - - Z1_FONTINFO_NUM ( "ItalicAngle", italic_angle ) - Z1_FONTINFO_BOOL ( "isFixedPitch", is_fixed_pitch ) - Z1_FONTINFO_NUM ( "UnderlinePosition", underline_position ) - Z1_FONTINFO_NUM ( "UnderlineThickness", underline_thickness ) - - -#undef T1TYPE -#define T1TYPE T1_Private - - Z1_PRIVATE_NUM ( "UniqueID", unique_id ) - Z1_PRIVATE_NUM ( "lenIV", lenIV ) - Z1_PRIVATE_NUM ( "LanguageGroup", language_group ) - Z1_PRIVATE_NUM ( "password", password ) - - Z1_PRIVATE_FIXED ( "BlueScale", blue_scale ) - Z1_PRIVATE_NUM ( "BlueShift", blue_shift ) - Z1_PRIVATE_NUM ( "BlueFuzz", blue_fuzz ) - - Z1_PRIVATE_NUM_TABLE ( "BlueValues", blue_values, 14, num_blue_values ) - Z1_PRIVATE_NUM_TABLE ( "OtherBlues", other_blues, 10, num_other_blues ) - Z1_PRIVATE_NUM_TABLE ( "FamilyBlues", family_blues, 14, num_family_blues ) - Z1_PRIVATE_NUM_TABLE ( "FamilyOtherBlues", family_other_blues, 10, \ - num_family_other_blues ) - - Z1_PRIVATE_NUM_TABLE2( "StdHW", standard_width, 1 ) - Z1_PRIVATE_NUM_TABLE2( "StdVW", standard_height, 1 ) - Z1_PRIVATE_NUM_TABLE2( "MinFeature", min_feature, 2 ) - - Z1_PRIVATE_NUM_TABLE ( "StemSnapH", snap_widths, 12, num_snap_widths ) - Z1_PRIVATE_NUM_TABLE ( "StemSnapV", snap_heights, 12, num_snap_heights ) - - -#undef T1TYPE -#define T1TYPE T1_Font - - Z1_TOPDICT_NUM( "PaintType", paint_type ) - Z1_TOPDICT_NUM( "FontType", font_type ) - Z1_TOPDICT_NUM( "StrokeWidth", stroke_width ) - - -#if 0 - - /* define the font info dictionary parsing callbacks */ -#undef FACE -#define FACE (face->type1.font_info) - - PARSE_STRING( "version", version ) - PARSE_STRING( "Notice", notice ) - PARSE_STRING( "FullName", full_name ) - PARSE_STRING( "FamilyName", family_name ) - PARSE_STRING( "Weight", weight ) - - PARSE_INT ( "ItalicAngle", italic_angle ) - PARSE_BOOL ( "isFixedPitch", is_fixed_pitch ) - PARSE_NUM ( "UnderlinePosition", underline_position, FT_Short ) - PARSE_NUM ( "UnderlineThickness", underline_thickness, FT_UShort ) - - - /* define the private dict parsing callbacks */ -#undef FACE -#define FACE (face->type1.private_dict) - - PARSE_INT ("UniqueID", unique_id ) - PARSE_INT ("lenIV", lenIV ) - - PARSE_COORDS ( "BlueValues", num_blues, 14, blue_values) - PARSE_COORDS ( "OtherBlues", num_other_blues, 10, other_blues) - - PARSE_COORDS ( "FamilyBlues", num_family_blues, 14, family_blues ) - PARSE_COORDS ( "FamilyOtherBlues", num_family_other_blues, 10, - family_other_blues ) - - PARSE_FIXED ( "BlueScale", blue_scale ) - PARSE_INT ( "BlueShift", blue_shift ) - - PARSE_INT ( "BlueFuzz", blue_fuzz ) - - PARSE_COORDS2( "StdHW", 1, standard_width ) - PARSE_COORDS2( "StdVW", 1, standard_height ) - - PARSE_COORDS ( "StemSnapH", num_snap_widths, 12, stem_snap_widths ) - PARSE_COORDS ( "StemSnapV", num_snap_heights, 12, stem_snap_heights ) - - PARSE_INT ( "LanguageGroup", language_group ) - PARSE_INT ( "password", password ) - PARSE_COORDS2( "MinFeature", 2, min_feature ) - - - /* define the top-level dictionary parsing callbacks */ -#undef FACE -#define FACE (face->type1) - -/*PARSE_STRING ( "FontName", font_name ) -- handled by special routine */ - PARSE_NUM ( "PaintType", paint_type, FT_Byte ) - PARSE_NUM ( "FontType", font_type, FT_Byte ) - PARSE_FIXEDS2( "FontMatrix", 4, font_matrix ) -/*PARSE_COORDS2( "FontBBox", 4, font_bbox ) -- handled by special routine */ - PARSE_INT ( "StrokeWidth", stroke_width ) - -#undef FACE - -#endif /* 0 */ - - -/* END */ diff --git a/src/freetype/unix/ftsystem.c b/src/freetype/unix/ftsystem.c deleted file mode 100644 index 9ecd95c7dc..0000000000 --- a/src/freetype/unix/ftsystem.c +++ /dev/null @@ -1,306 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftsystem.c */ -/* */ -/* Unix-specific FreeType low-level system interface (body). */ -/* */ -/* 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 -#include -#include -#include -#include - -#include -#include -#include - - - /* memory-mapping includes and definitions */ -#ifdef HAVE_UNISTD_H -#include -#endif - -#include -#ifndef MAP_FILE -#define MAP_FILE 0x00 -#endif - - /*************************************************************************/ - /* */ - /* The prototype for munmap() is not provided on SunOS. This needs to */ - /* have a check added later to see if the GNU C library is being used. */ - /* If so, then this prototype is not needed. */ - /* */ -#if defined( __sun__ ) && !defined( SVR4 ) && !defined( __SVR4 ) - extern int munmap( caddr_t addr, - int len ); -#endif - -#include - -#ifdef HAVE_FCNTL_H -#include -#endif - -#include -#include -#include - - - /*************************************************************************/ - /* */ - /* MEMORY MANAGEMENT INTERFACE */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* ft_alloc */ - /* */ - /* */ - /* The memory allocation function. */ - /* */ - /* */ - /* memory :: A pointer to the memory object. */ - /* size :: The requested size in bytes. */ - /* */ - /* */ - /* block :: The address of newly allocated block. */ - /* */ - static - void* ft_alloc( FT_Memory memory, - long size ) - { - FT_UNUSED( memory ); - - return malloc( size ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* ft_realloc */ - /* */ - /* */ - /* The memory reallocation function. */ - /* */ - /* */ - /* memory :: A pointer to the memory object. */ - /* */ - /* cur_size :: The current size of the allocated memory block. */ - /* */ - /* new_size :: The newly requested size in bytes. */ - /* */ - /* block :: The current address of the block in memory. */ - /* */ - /* */ - /* The address of the reallocated memory block. */ - /* */ - static - void* ft_realloc( FT_Memory memory, - long cur_size, - long new_size, - void* block ) - { - FT_UNUSED( memory ); - FT_UNUSED( cur_size ); - - return realloc( block, new_size ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* ft_free */ - /* */ - /* */ - /* The memory release function. */ - /* */ - /* */ - /* memory :: A pointer to the memory object. */ - /* */ - /* block :: The address of block in memory to be freed. */ - /* */ - static - void ft_free( FT_Memory memory, - void* block ) - { - FT_UNUSED( memory ); - - free( block ); - } - - - /*************************************************************************/ - /* */ - /* RESOURCE MANAGEMENT INTERFACE */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_io - - /* We use the macro STREAM_FILE for convenience to extract the */ - /* system-specific stream handle from a given FreeType stream object */ -#define STREAM_FILE( stream ) ( (FILE*)stream->descriptor.pointer ) - - - /*************************************************************************/ - /* */ - /* */ - /* ft_close_stream */ - /* */ - /* */ - /* The function to close a stream. */ - /* */ - /* */ - /* stream :: A pointer to the stream object. */ - /* */ - static - void ft_close_stream( FT_Stream stream ) - { - munmap ( stream->descriptor.pointer, stream->size ); - - stream->descriptor.pointer = NULL; - stream->size = 0; - stream->base = 0; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_New_Stream */ - /* */ - /* */ - /* Creates a new stream object. */ - /* */ - /* */ - /* filepathname :: The name of the stream (usually a file) to be */ - /* opened. */ - /* */ - /* stream :: A pointer to the stream object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_New_Stream( const char* filepathname, - FT_Stream stream ) - { - int file; - struct stat stat_buf; - - - if ( !stream ) - return FT_Err_Invalid_Stream_Handle; - - /* open the file */ - file = open( filepathname, O_RDONLY ); - if ( file < 0 ) - { - FT_ERROR(( "FT_New_Stream:" )); - FT_ERROR(( " could not open `%s'\n", filepathname )); - return FT_Err_Cannot_Open_Resource; - } - - if ( fstat( file, &stat_buf ) < 0 ) - { - FT_ERROR(( "FT_New_Stream:" )); - FT_ERROR(( " could not `fstat' file `%s'\n", filepathname )); - goto Fail_Map; - } - - stream->size = stat_buf.st_size; - stream->pos = 0; - stream->base = mmap( NULL, - stream->size, - PROT_READ, - MAP_FILE | MAP_PRIVATE, - file, - 0 ); - - if ( (long)stream->base == -1 ) - { - FT_ERROR(( "FT_New_Stream:" )); - FT_ERROR(( " could not `mmap' file `%s'\n", filepathname )); - goto Fail_Map; - } - - close( file ); - - stream->descriptor.pointer = stream->base; - stream->pathname.pointer = (char*)filepathname; - - stream->close = ft_close_stream; - stream->read = 0; - - FT_TRACE1(( "FT_New_Stream:" )); - FT_TRACE1(( " opened `%s' (%d bytes) successfully\n", - filepathname, stream->size )); - - return FT_Err_Ok; - - Fail_Map: - close( file ); - - stream->base = NULL; - stream->size = 0; - stream->pos = 0; - - return FT_Err_Cannot_Open_Stream; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_New_Memory */ - /* */ - /* */ - /* Creates a new memory object. */ - /* */ - /* */ - /* A pointer to the new memory object. 0 in case of error. */ - /* */ - FT_EXPORT_FUNC( FT_Memory ) FT_New_Memory( void ) - { - FT_Memory memory; - - - memory = (FT_Memory)malloc( sizeof ( *memory ) ); - if ( memory ) - { - memory->user = 0; - memory->alloc = ft_alloc; - memory->realloc = ft_realloc; - memory->free = ft_free; - } - - return memory; - } - - -/* END */ diff --git a/src/freetype/winfonts/module.mk b/src/freetype/winfonts/module.mk deleted file mode 100644 index 5c12eb6ee8..0000000000 --- a/src/freetype/winfonts/module.mk +++ /dev/null @@ -1,6 +0,0 @@ -make_module_list: add_windows_driver - -add_windows_driver: - $(OPEN_DRIVER)winfnt_driver_class$(CLOSE_DRIVER) - $(ECHO_DRIVER)winfnt $(ECHO_DRIVER_DESC)Windows bitmap fonts with extension *.fnt or *.fon$(ECHO_DRIVER_DONE) - diff --git a/src/freetype/winfonts/rules.mk b/src/freetype/winfonts/rules.mk deleted file mode 100644 index 8396894d97..0000000000 --- a/src/freetype/winfonts/rules.mk +++ /dev/null @@ -1,64 +0,0 @@ -# -# FreeType 2 Windows FNT/FON driver configuration rules -# - - -# 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. - - -# Windows driver directory -# -FNT_DIR := $(SRC_)winfonts -FNT_DIR_ := $(FNT_DIR)$(SEP) - - -FNT_COMPILE := $(FT_COMPILE) - - -# Windows driver sources (i.e., C files) -# -FNT_DRV_SRC := $(FNT_DIR_)winfnt.c - -# Windows driver headers -# -FNT_DRV_H := $(FNT_DRV_SRC:%.c=%.h) - - -# Windows driver object(s) -# -# FNT_DRV_OBJ_M is used during `multi' builds -# FNT_DRV_OBJ_S is used during `single' builds -# -FNT_DRV_OBJ_M := $(FNT_DRV_SRC:$(FNT_DIR_)%.c=$(OBJ_)%.$O) -FNT_DRV_OBJ_S := $(OBJ_)winfnt.$O - -# Windows driver source file for single build -# -FNT_DRV_SRC_S := $(FNT_DIR_)winfnt.c - - -# Windows driver - single object -# -$(FNT_DRV_OBJ_S): $(FNT_DRV_SRC_S) $(FNT_DRV_SRC) $(FREETYPE_H) $(FNT_DRV_H) - $(FNT_COMPILE) $T$@ $(FNT_DRV_SRC_S) - - -# Windows driver - multiple objects -# -$(OBJ_)%.$O: $(FNT_DIR_)%.c $(FREETYPE_H) $(FNT_DRV_H) - $(FNT_COMPILE) $T$@ $< - - -# update main driver object lists -# -DRV_OBJS_S += $(FNT_DRV_OBJ_S) -DRV_OBJS_M += $(FNT_DRV_OBJ_M) - -# EOF diff --git a/src/freetype/winfonts/winfnt.c b/src/freetype/winfonts/winfnt.c deleted file mode 100644 index 470440a2ca..0000000000 --- a/src/freetype/winfonts/winfnt.c +++ /dev/null @@ -1,623 +0,0 @@ -/***************************************************************************/ -/* */ -/* winfnt.c */ -/* */ -/* FreeType font driver for Windows FNT/FON files */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifdef FT_FLAT_COMPILE - -#include "winfnt.h" - -#else - -#include - -#endif - - -#include -#include -#include -#include - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_winfnt - - - static - const FT_Frame_Field winmz_header_fields[] = - { - FT_FRAME_START( 64 ), - FT_FRAME_USHORT_LE ( WinMZ_Header, magic ), - FT_FRAME_SKIP_BYTES( 29 * 2 ), - FT_FRAME_ULONG_LE ( WinMZ_Header, lfanew ), - FT_FRAME_END - }; - - static - const FT_Frame_Field winne_header_fields[] = - { - FT_FRAME_START( 40 ), - FT_FRAME_USHORT_LE ( WinNE_Header, magic ), - FT_FRAME_SKIP_BYTES( 34 ), - FT_FRAME_USHORT_LE ( WinNE_Header, resource_tab_offset ), - FT_FRAME_USHORT_LE ( WinNE_Header, rname_tab_offset ), - FT_FRAME_END - }; - - static - const FT_Frame_Field winfnt_header_fields[] = - { - FT_FRAME_START( 134 ), - FT_FRAME_USHORT_LE( WinFNT_Header, version ), - FT_FRAME_ULONG_LE ( WinFNT_Header, file_size ), - FT_FRAME_BYTES ( WinFNT_Header, copyright, 60 ), - FT_FRAME_USHORT_LE( WinFNT_Header, file_type ), - FT_FRAME_USHORT_LE( WinFNT_Header, nominal_point_size ), - FT_FRAME_USHORT_LE( WinFNT_Header, vertical_resolution ), - FT_FRAME_USHORT_LE( WinFNT_Header, horizontal_resolution ), - FT_FRAME_USHORT_LE( WinFNT_Header, ascent ), - FT_FRAME_USHORT_LE( WinFNT_Header, internal_leading ), - FT_FRAME_USHORT_LE( WinFNT_Header, external_leading ), - FT_FRAME_BYTE ( WinFNT_Header, italic ), - FT_FRAME_BYTE ( WinFNT_Header, underline ), - FT_FRAME_BYTE ( WinFNT_Header, strike_out ), - FT_FRAME_USHORT_LE( WinFNT_Header, weight ), - FT_FRAME_BYTE ( WinFNT_Header, charset ), - FT_FRAME_USHORT_LE( WinFNT_Header, pixel_width ), - FT_FRAME_USHORT_LE( WinFNT_Header, pixel_height ), - FT_FRAME_BYTE ( WinFNT_Header, pitch_and_family ), - FT_FRAME_USHORT_LE( WinFNT_Header, avg_width ), - FT_FRAME_USHORT_LE( WinFNT_Header, max_width ), - FT_FRAME_BYTE ( WinFNT_Header, first_char ), - FT_FRAME_BYTE ( WinFNT_Header, last_char ), - FT_FRAME_BYTE ( WinFNT_Header, default_char ), - FT_FRAME_BYTE ( WinFNT_Header, break_char ), - FT_FRAME_USHORT_LE( WinFNT_Header, bytes_per_row ), - FT_FRAME_ULONG_LE ( WinFNT_Header, device_offset ), - FT_FRAME_ULONG_LE ( WinFNT_Header, face_name_offset ), - FT_FRAME_ULONG_LE ( WinFNT_Header, bits_pointer ), - FT_FRAME_ULONG_LE ( WinFNT_Header, bits_offset ), - FT_FRAME_BYTE ( WinFNT_Header, reserved ), - FT_FRAME_ULONG_LE ( WinFNT_Header, flags ), - FT_FRAME_USHORT_LE( WinFNT_Header, A_space ), - FT_FRAME_USHORT_LE( WinFNT_Header, B_space ), - FT_FRAME_USHORT_LE( WinFNT_Header, C_space ), - FT_FRAME_USHORT_LE( WinFNT_Header, color_table_offset ), - FT_FRAME_BYTES ( WinFNT_Header, reserved, 4 ), - FT_FRAME_END - }; - - - static - void fnt_done_font( FT_Stream stream, - FNT_Font* font ) - { - if ( font->fnt_frame ) - RELEASE_Frame( font->fnt_frame ); - - font->fnt_size = 0; - font->fnt_frame = 0; - } - - - static - FT_Error fnt_load_font( FT_Stream stream, - FNT_Font* font ) - { - FT_Error error; - WinFNT_Header* header = &font->header; - - - /* first of all, read the FNT header */ - if ( FILE_Seek( font->offset ) || - READ_Fields( winfnt_header_fields, header ) ) - goto Exit; - - /* check header */ - if ( header->version != 0x200 && - header->version != 0x300 ) - { - FT_TRACE2(( "[not a valid FNT file]\n" )); - error = FT_Err_Unknown_File_Format; - goto Exit; - } - - if ( header->file_type & 1 ) - { - FT_TRACE2(( "can't handle vector FNT fonts\n" )); - error = FT_Err_Unknown_File_Format; - goto Exit; - } - - /* small fixup -- some fonts have the `pixel_width' field set to 0 */ - if ( header->pixel_width == 0 ) - header->pixel_width = header->pixel_height; - - /* this is a FNT file/table, we now extract its frame */ - if ( FILE_Seek( font->offset ) || - EXTRACT_Frame( header->file_size, font->fnt_frame ) ) - goto Exit; - - Exit: - return error; - } - - - static - void fnt_done_fonts( FNT_Face face ) - { - FT_Memory memory = FT_FACE(face)->memory; - FT_Stream stream = FT_FACE(face)->stream; - FNT_Font* cur = face->fonts; - FNT_Font* limit = cur + face->num_fonts; - - - for ( ; cur < limit; cur++ ) - fnt_done_font( stream, cur ); - - FREE( face->fonts ); - face->num_fonts = 0; - } - - static - FT_Error fnt_get_dll_fonts( FNT_Face face ) - { - FT_Error error; - FT_Stream stream = FT_FACE(face)->stream; - FT_Memory memory = FT_FACE(face)->memory; - WinMZ_Header mz_header; - - - face->fonts = 0; - face->num_fonts = 0; - - /* does it begin with a MZ header? */ - if ( FILE_Seek( 0 ) || - READ_Fields( winmz_header_fields, &mz_header ) ) - goto Exit; - - error = FT_Err_Unknown_File_Format; - if ( mz_header.magic == WINFNT_MZ_MAGIC ) - { - /* yes, now look for a NE header in the file */ - WinNE_Header ne_header; - - - if ( FILE_Seek( mz_header.lfanew ) || - READ_Fields( winne_header_fields, &ne_header ) ) - goto Exit; - - error = FT_Err_Unknown_File_Format; - if ( ne_header.magic == WINFNT_NE_MAGIC ) - { - /* good, now look in the resource table for each FNT resource */ - FT_ULong res_offset = mz_header.lfanew + - ne_header.resource_tab_offset; - - FT_UShort size_shift; - FT_UShort font_count = 0; - FT_ULong font_offset = 0; - - - if ( FILE_Seek( res_offset ) || - ACCESS_Frame( ne_header.rname_tab_offset - - ne_header.resource_tab_offset ) ) - goto Exit; - - size_shift = GET_UShortLE(); - - for (;;) - { - FT_UShort type_id, count; - - - type_id = GET_UShortLE(); - if ( !type_id ) - break; - - count = GET_UShortLE(); - - if ( type_id == 0x8008 ) - { - font_count = count; - font_offset = FILE_Pos() + 4 + ( stream->cursor - stream->limit ); - break; - } - - stream->cursor += 4 + count * 12; - } - FORGET_Frame(); - - if ( !font_count || !font_offset ) - { - FT_TRACE2(( "this file doesn't contain any FNT resources!\n" )); - error = FT_Err_Unknown_File_Format; - goto Exit; - } - - if ( FILE_Seek( font_offset ) || - ALLOC_ARRAY( face->fonts, font_count, FNT_Font ) ) - goto Exit; - - face->num_fonts = font_count; - - if ( ACCESS_Frame( (FT_Long)font_count * 12 ) ) - goto Exit; - - /* now read the offset and position of each FNT font */ - { - FNT_Font* cur = face->fonts; - FNT_Font* limit = cur + font_count; - - - for ( ; cur < limit; cur++ ) - { - cur->offset = (FT_ULong)GET_UShortLE() << size_shift; - cur->fnt_size = (FT_ULong)GET_UShortLE() << size_shift; - cur->size_shift = size_shift; - stream->cursor += 8; - } - } - FORGET_Frame(); - - /* finally, try to load each font there */ - { - FNT_Font* cur = face->fonts; - FNT_Font* limit = cur + font_count; - - - for ( ; cur < limit; cur++ ) - { - error = fnt_load_font( stream, cur ); - if ( error ) - goto Fail; - } - } - } - } - - Fail: - if ( error ) - fnt_done_fonts( face ); - - Exit: - return error; - } - - - static - void FNT_Done_Face( FNT_Face face ) - { - FT_Memory memory = FT_FACE_MEMORY( face ); - - - fnt_done_fonts( face ); - - FREE( face->root.available_sizes ); - face->root.num_fixed_sizes = 0; - } - - - static - FT_Error FNT_Init_Face( FT_Stream stream, - FNT_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ) - { - FT_Error error; - FT_Memory memory = FT_FACE_MEMORY( face ); - - FT_UNUSED( num_params ); - FT_UNUSED( params ); - FT_UNUSED( face_index ); - - - /* try to load several fonts from a DLL */ - error = fnt_get_dll_fonts( face ); - if ( error ) - { - /* this didn't work, now try to load a single FNT font */ - FT_Memory memory = FT_FACE_MEMORY( face ); - FNT_Font* font; - - if ( ALLOC( face->fonts, sizeof ( *face->fonts ) ) ) - goto Exit; - - face->num_fonts = 1; - font = face->fonts; - - font->offset = 0; - font->fnt_size = stream->size; - - error = fnt_load_font( stream, font ); - if ( error ) - goto Fail; - } - - /* all right, one or more fonts were loaded; we now need to */ - /* fill the root FT_Face fields with relevant information */ - { - FT_Face root = FT_FACE( face ); - FNT_Font* fonts = face->fonts; - FNT_Font* limit = fonts + face->num_fonts; - FNT_Font* cur; - - - root->num_faces = 1; - root->face_flags = FT_FACE_FLAG_FIXED_SIZES | - FT_FACE_FLAG_HORIZONTAL; - - if ( fonts->header.avg_width == fonts->header.max_width ) - root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; - - if ( fonts->header.italic ) - root->style_flags |= FT_STYLE_FLAG_ITALIC; - - if ( fonts->header.weight >= 800 ) - root->style_flags |= FT_STYLE_FLAG_BOLD; - - /* Setup the `fixed_sizes' array */ - if ( ALLOC_ARRAY( root->available_sizes, face->num_fonts, - FT_Bitmap_Size ) ) - goto Fail; - - root->num_fixed_sizes = face->num_fonts; - - { - FT_Bitmap_Size* size = root->available_sizes; - - - for ( cur = fonts; cur < limit; cur++, size++ ) - { - size->width = cur->header.pixel_width; - size->height = cur->header.pixel_height; - } - } - - /* Setup the `charmaps' array */ - root->charmaps = &face->charmap_handle; - root->num_charmaps = 1; - - face->charmap.encoding = ft_encoding_unicode; - face->charmap.platform_id = 3; - face->charmap.encoding_id = 1; - face->charmap.face = root; - - face->charmap_handle = &face->charmap; - - root->charmap = face->charmap_handle; - - /* setup remaining flags */ - root->num_glyphs = fonts->header.last_char - - fonts->header.first_char + 1; - - root->family_name = (FT_String*)fonts->fnt_frame + - fonts->header.face_name_offset; - root->style_name = "Regular"; - - if ( root->style_flags & FT_STYLE_FLAG_BOLD ) - { - if ( root->style_flags & FT_STYLE_FLAG_ITALIC ) - root->style_name = "Bold Italic"; - else - root->style_name = "Bold"; - } - else if ( root->style_flags & FT_STYLE_FLAG_ITALIC ) - root->style_name = "Italic"; - } - - Fail: - if ( error ) - FNT_Done_Face( face ); - - Exit: - return error; - } - - - static - FT_Error FNT_Set_Pixel_Size( FNT_Size size ) - { - /* look up a font corresponding to the current pixel size */ - FNT_Face face = (FNT_Face)FT_SIZE_FACE( size ); - FNT_Font* cur = face->fonts; - FNT_Font* limit = cur + face->num_fonts; - - - size->font = 0; - for ( ; cur < limit; cur++ ) - { - /* we only compare the character height, as fonts used some strange */ - /* values */ - if ( cur->header.pixel_height == size->root.metrics.y_ppem ) - { - size->font = cur; - - size->root.metrics.ascender = cur->header.ascent * 64; - size->root.metrics.descender = ( cur->header.pixel_height - - cur->header.ascent ) * 64; - size->root.metrics.height = cur->header.pixel_height * 64; - break; - } - } - - return ( size->font ? FT_Err_Ok : FT_Err_Invalid_Argument ); - } - - - static - FT_UInt FNT_Get_Char_Index( FT_CharMap charmap, - FT_ULong char_code ) - { - FT_UInt result = char_code; - - - if ( charmap ) - { - FNT_Font* font = ((FNT_Face)charmap->face)->fonts; - FT_UInt first = font->header.first_char; - FT_UInt count = font->header.last_char - first + 1; - - - char_code -= first; - if ( char_code < count ) - result = char_code + 1; - else - result = 0; - } - - return result; - } - - - static - FT_Error FNT_Load_Glyph( FT_GlyphSlot slot, - FNT_Size size, - FT_UInt glyph_index, - FT_Int load_flags ) - { - FNT_Font* font = size->font; - FT_Error error = 0; - FT_Byte* p; - FT_Int len; - FT_Bitmap* bitmap = &slot->bitmap; - FT_ULong offset; - FT_Bool new_format; - - FT_UNUSED( slot ); - FT_UNUSED( load_flags ); - - - if ( !font ) - { - error = FT_Err_Invalid_Argument; - goto Exit; - } - - if ( glyph_index > 0 ) - glyph_index--; - else - glyph_index = font->header.default_char - font->header.first_char; - - new_format = font->header.version == 0x300; - len = new_format ? 6 : 4; - - /* jump to glyph entry */ - p = font->fnt_frame + 118 + len * glyph_index; - - bitmap->width = NEXT_ShortLE(p); - - if ( new_format ) - offset = NEXT_ULongLE(p); - else - offset = NEXT_UShortLE(p); - - /* jump to glyph data */ - p = font->fnt_frame + /* font->header.bits_offset */ + offset; - - /* allocate and build bitmap */ - { - FT_Memory memory = FT_FACE_MEMORY( slot->face ); - FT_Int pitch = ( bitmap->width + 7 ) >> 3; - FT_Byte* column; - FT_Byte* write; - - - bitmap->pitch = pitch; - bitmap->rows = font->header.pixel_height; - bitmap->pixel_mode = ft_pixel_mode_mono; - - if ( ALLOC( bitmap->buffer, pitch * bitmap->rows ) ) - goto Exit; - - column = (FT_Byte*)bitmap->buffer; - - for ( ; pitch > 0; pitch--, column++ ) - { - FT_Byte* limit = p + bitmap->rows; - - - for ( write = column; p < limit; p++, write += bitmap->pitch ) - write[0] = p[0]; - } - } - - slot->flags = ft_glyph_own_bitmap; - slot->bitmap_left = 0; - slot->bitmap_top = font->header.ascent; - slot->format = ft_glyph_format_bitmap; - - /* now set up metrics */ - slot->metrics.horiAdvance = bitmap->width << 6; - slot->metrics.horiBearingX = 0; - slot->metrics.horiBearingY = slot->bitmap_top << 6; - - slot->linearHoriAdvance = (FT_Fixed)bitmap->width << 16; - - Exit: - return error; - } - - - const FT_Driver_Class winfnt_driver_class = - { - { - ft_module_font_driver, - sizeof ( FT_DriverRec ), - - "winfonts", - 0x10000L, - 0x20000L, - - 0, - - (FT_Module_Constructor)0, - (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 - }, - - sizeof( FNT_FaceRec ), - sizeof( FNT_SizeRec ), - sizeof( FT_GlyphSlotRec ), - - (FTDriver_initFace) FNT_Init_Face, - (FTDriver_doneFace) FNT_Done_Face, - (FTDriver_initSize) 0, - (FTDriver_doneSize) 0, - (FTDriver_initGlyphSlot)0, - (FTDriver_doneGlyphSlot)0, - - (FTDriver_setCharSizes) FNT_Set_Pixel_Size, - (FTDriver_setPixelSizes)FNT_Set_Pixel_Size, - - (FTDriver_loadGlyph) FNT_Load_Glyph, - (FTDriver_getCharIndex) FNT_Get_Char_Index, - - (FTDriver_getKerning) 0, - (FTDriver_attachFile) 0, - (FTDriver_getAdvances) 0 - }; - - -/* END */ diff --git a/src/freetype/winfonts/winfnt.h b/src/freetype/winfonts/winfnt.h deleted file mode 100644 index eaf308b875..0000000000 --- a/src/freetype/winfonts/winfnt.h +++ /dev/null @@ -1,150 +0,0 @@ -/***************************************************************************/ -/* */ -/* winfnt.h */ -/* */ -/* FreeType font driver for Windows FNT/FON files */ -/* */ -/* 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. */ -/* */ -/***************************************************************************/ - - -#ifndef WINFNT_H -#define WINFNT_H - -#include - - - typedef struct WinMZ_Header_ - { - FT_UShort magic; - /* skipped content */ - FT_UShort lfanew; - - } WinMZ_Header; - - - typedef struct WinNE_Header_ - { - FT_UShort magic; - /* skipped content */ - FT_UShort resource_tab_offset; - FT_UShort rname_tab_offset; - - } WinNE_Header; - - - typedef struct WinNameInfo_ - { - FT_UShort offset; - FT_UShort length; - FT_UShort flags; - FT_UShort id; - FT_UShort handle; - FT_UShort usage; - - } WinNameInfo; - - - typedef struct WinResourceInfo_ - { - FT_UShort type_id; - FT_UShort count; - - } WinResourceInfo; - - -#define WINFNT_MZ_MAGIC 0x5A4D -#define WINFNT_NE_MAGIC 0x454E - - - typedef struct WinFNT_Header_ - { - FT_UShort version; - FT_ULong file_size; - FT_Byte copyright[60]; - FT_UShort file_type; - FT_UShort nominal_point_size; - FT_UShort vertical_resolution; - FT_UShort horizontal_resolution; - FT_UShort ascent; - FT_UShort internal_leading; - FT_UShort external_leading; - FT_Byte italic; - FT_Byte underline; - FT_Byte strike_out; - FT_UShort weight; - FT_Byte charset; - FT_UShort pixel_width; - FT_UShort pixel_height; - FT_Byte pitch_and_family; - FT_UShort avg_width; - FT_UShort max_width; - FT_Byte first_char; - FT_Byte last_char; - FT_Byte default_char; - FT_Byte break_char; - FT_UShort bytes_per_row; - FT_ULong device_offset; - FT_ULong face_name_offset; - FT_ULong bits_pointer; - FT_ULong bits_offset; - FT_Byte reserved; - FT_ULong flags; - FT_UShort A_space; - FT_UShort B_space; - FT_UShort C_space; - FT_UShort color_table_offset; - FT_Byte reserved2[4]; - - } WinFNT_Header; - - - typedef struct FNT_Font_ - { - FT_ULong offset; - FT_Int size_shift; - - WinFNT_Header header; - - FT_Byte* fnt_frame; - FT_ULong fnt_size; - - } FNT_Font; - - - typedef struct FNT_SizeRec_ - { - FT_SizeRec root; - FNT_Font* font; - - } FNT_SizeRec, *FNT_Size; - - - typedef struct FNT_FaceRec_ - { - FT_FaceRec root; - - FT_UInt num_fonts; - FNT_Font* fonts; - - FT_CharMap charmap_handle; - FT_CharMapRec charmap; /* a single charmap per face */ - - } FNT_FaceRec, *FNT_Face; - - - FT_EXPORT_VAR( const FT_Driver_Class ) winfnt_driver_class; - - -#endif /* WINFNT_H */ - - -/* END */