From 1504d78e076b496b35770eb1326b933684a2a62b Mon Sep 17 00:00:00 2001 From: David Turner Date: Wed, 23 Aug 2000 22:50:39 +0000 Subject: [PATCH] removing obsolete files --- src/type1/module.mk0 | 6 - src/type1/rules.mk0 | 74 -- src/type1/t1afm.c | 293 ------- src/type1/t1afm.h | 70 -- src/type1/t1driver.c | 381 --------- src/type1/t1driver.h | 40 - src/type1/t1gload.c | 1823 ------------------------------------------ src/type1/t1gload.h | 326 -------- src/type1/t1hinter.c | 1347 ------------------------------- src/type1/t1hinter.h | 273 ------- src/type1/t1load.c | 1594 ------------------------------------ src/type1/t1load.h | 57 -- src/type1/t1objs.c | 544 ------------- src/type1/t1objs.h | 172 ---- src/type1/t1parse.c | 761 ------------------ src/type1/t1parse.h | 261 ------ src/type1/t1tokens.c | 1101 ------------------------- src/type1/t1tokens.h | 258 ------ src/type1/type1.c | 59 -- 19 files changed, 9440 deletions(-) delete mode 100644 src/type1/module.mk0 delete mode 100644 src/type1/rules.mk0 delete mode 100644 src/type1/t1afm.c delete mode 100644 src/type1/t1afm.h delete mode 100644 src/type1/t1driver.c delete mode 100644 src/type1/t1driver.h delete mode 100644 src/type1/t1gload.c delete mode 100644 src/type1/t1gload.h delete mode 100644 src/type1/t1hinter.c delete mode 100644 src/type1/t1hinter.h delete mode 100644 src/type1/t1load.c delete mode 100644 src/type1/t1load.h delete mode 100644 src/type1/t1objs.c delete mode 100644 src/type1/t1objs.h delete mode 100644 src/type1/t1parse.c delete mode 100644 src/type1/t1parse.h delete mode 100644 src/type1/t1tokens.c delete mode 100644 src/type1/t1tokens.h delete mode 100644 src/type1/type1.c diff --git a/src/type1/module.mk0 b/src/type1/module.mk0 deleted file mode 100644 index af99eae25..000000000 --- a/src/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/type1/rules.mk0 b/src/type1/rules.mk0 deleted file mode 100644 index b544446ae..000000000 --- a/src/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/type1/t1afm.c b/src/type1/t1afm.c deleted file mode 100644 index a6ac1b98a..000000000 --- a/src/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/type1/t1afm.h b/src/type1/t1afm.h deleted file mode 100644 index 709154ec7..000000000 --- a/src/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/type1/t1driver.c b/src/type1/t1driver.c deleted file mode 100644 index 764f0806f..000000000 --- a/src/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; - } - - - - FT_CPLUSPLUS( 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/type1/t1driver.h b/src/type1/t1driver.h deleted file mode 100644 index 8744b966c..000000000 --- a/src/type1/t1driver.h +++ /dev/null @@ -1,40 +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 - -#ifdef __cplusplus - extern "C" { -#endif - - - FT_EXPORT_VAR( const FT_Driver_Class ) t1_driver_class; - - -#ifdef __cplusplus - } -#endif - - -#endif /* T1DRIVER_H */ - - -/* END */ diff --git a/src/type1/t1gload.c b/src/type1/t1gload.c deleted file mode 100644 index 37cfc8c5d..000000000 --- a/src/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/type1/t1gload.h b/src/type1/t1gload.h deleted file mode 100644 index 658a929d0..000000000 --- a/src/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/type1/t1hinter.c b/src/type1/t1hinter.c deleted file mode 100644 index 7ce746228..000000000 --- a/src/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/type1/t1hinter.h b/src/type1/t1hinter.h deleted file mode 100644 index a82882e09..000000000 --- a/src/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/type1/t1load.c b/src/type1/t1load.c deleted file mode 100644 index 00a56a246..000000000 --- a/src/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/type1/t1load.h b/src/type1/t1load.h deleted file mode 100644 index d278374f0..000000000 --- a/src/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/type1/t1objs.c b/src/type1/t1objs.c deleted file mode 100644 index 1e6f9ca2a..000000000 --- a/src/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/type1/t1objs.h b/src/type1/t1objs.h deleted file mode 100644 index 47b0a37be..000000000 --- a/src/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/type1/t1parse.c b/src/type1/t1parse.c deleted file mode 100644 index 8b7ca2524..000000000 --- a/src/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/type1/t1parse.h b/src/type1/t1parse.h deleted file mode 100644 index 2c42b8cec..000000000 --- a/src/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/type1/t1tokens.c b/src/type1/t1tokens.c deleted file mode 100644 index 2953322c9..000000000 --- a/src/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/type1/t1tokens.h b/src/type1/t1tokens.h deleted file mode 100644 index 119c54ba1..000000000 --- a/src/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/type1/type1.c b/src/type1/type1.c deleted file mode 100644 index d2058d620..000000000 --- a/src/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 */