ref: 888706a317b930cb94314d7803a61426c0fbf46c
parent: b8a7a0bdea780ac43dc8c8495f9ef08c046e5ed8
author: David Turner <[email protected]>
date: Wed Aug 23 18:50:39 EDT 2000
removing obsolete files
--- a/src/type1/module.mk0
+++ /dev/null
@@ -1,6 +1,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)
-
--- a/src/type1/rules.mk0
+++ /dev/null
@@ -1,74 +1,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
--- a/src/type1/t1afm.c
+++ /dev/null
@@ -1,293 +1,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 <type1/t1afm.h>
-
-#endif
-
-
-#include <freetype/internal/ftstream.h>
-#include <freetype/internal/t1types.h>
-
-#include <stdlib.h> /* for qsort() */
-#include <string.h> /* for strcmp() */
-#include <ctype.h> /* 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 */
--- a/src/type1/t1afm.h
+++ /dev/null
@@ -1,70 +1,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 <freetype/internal/ftobjs.h>
-
-
-#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 */
--- a/src/type1/t1driver.c
+++ /dev/null
@@ -1,381 +1,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 <type1/t1driver.h>
-#include <type1/t1gload.h>
-#include <type1/t1afm.h>
-
-#endif
-
-
-#include <freetype/internal/ftdebug.h>
-#include <freetype/internal/ftstream.h>
-#include <freetype/internal/psnames.h>
-
-#include <string.h> /* 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
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* Get_Kerning */
- /* */
- /* <Description> */
- /* A driver method used to return the kerning vector between two */
- /* glyphs of the same face. */
- /* */
- /* <Input> */
- /* 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. */
- /* */
- /* <Output> */
- /* kerning :: The kerning vector. This is in font units for */
- /* scalable formats, and in pixels for fixed-sizes */
- /* formats. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means success. */
- /* */
- /* <Note> */
- /* 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;
- }
-
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* Set_Char_Sizes */
- /* */
- /* <Description> */
- /* A driver method used to reset a size's character sizes (horizontal */
- /* and vertical) expressed in fractional points. */
- /* */
- /* <Input> */
- /* 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. */
- /* */
- /* <InOut> */
- /* size :: A handle to the target size object. */
- /* */
- /* <Return> */
- /* 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 );
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* Set_Pixel_Sizes */
- /* */
- /* <Description> */
- /* A driver method used to reset a size's character sizes (horizontal */
- /* and vertical) expressed in integer pixels. */
- /* */
- /* <Input> */
- /* pixel_width :: The character width expressed in integer pixels. */
- /* */
- /* pixel_height :: The character height expressed in integer pixels. */
- /* */
- /* <InOut> */
- /* size :: A handle to the target size object. */
- /* */
- /* <Return> */
- /* 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 );
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* Get_Char_Index */
- /* */
- /* <Description> */
- /* Uses a charmap to return a given character code's glyph index. */
- /* */
- /* <Input> */
- /* charmap :: A handle to the source charmap object. */
- /* charcode :: The character code. */
- /* */
- /* <Return> */
- /* 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 */
--- a/src/type1/t1driver.h
+++ /dev/null
@@ -1,40 +1,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 <freetype/internal/ftdriver.h>
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-
- FT_EXPORT_VAR( const FT_Driver_Class ) t1_driver_class;
-
-
-#ifdef __cplusplus
- }
-#endif
-
-
-#endif /* T1DRIVER_H */
-
-
-/* END */
--- a/src/type1/t1gload.c
+++ /dev/null
@@ -1,1823 +1,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 <type1/t1gload.h>
-
-#ifndef T1_CONFIG_OPTION_DISABLE_HINTER
-#include <type1/t1hinter.h>
-#endif
-
-#endif /* FT_FLAT_COMPILE */
-
-
-#include <freetype/internal/ftdebug.h>
-#include <freetype/internal/ftstream.h>
-#include <freetype/ftoutln.h>
-
-#include <string.h> /* 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 );
- }
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* T1_Init_Builder */
- /* */
- /* <Description> */
- /* Initializes a given glyph builder. */
- /* */
- /* <InOut> */
- /* builder :: A pointer to the glyph builder to initialize. */
- /* */
- /* <Input> */
- /* 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 );
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* T1_Done_Builder */
- /* */
- /* <Description> */
- /* 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. */
- /* */
- /* <Input> */
- /* 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;
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* T1_Init_Decoder */
- /* */
- /* <Description> */
- /* Initializes a given glyph decoder. */
- /* */
- /* <InOut> */
- /* decoder :: A pointer to the glyph builder to initialize. */
- /* */
- /* <Input> */
- /* 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 ) );
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* lookup_glyph_by_stdcharcode */
- /* */
- /* <Description> */
- /* Looks up a given glyph by its StandardEncoding charcode. Used */
- /* to implement the SEAC Type 1 operator. */
- /* */
- /* <Input> */
- /* face :: The current face object. */
- /* */
- /* charcode :: The character code to look for. */
- /* */
- /* <Return> */
- /* 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;
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* t1operator_seac */
- /* */
- /* <Description> */
- /* Implements the `seac' Type 1 operator for a Type 1 decoder. */
- /* */
- /* <Input> */
- /* 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. */
- /* */
- /* <Return> */
- /* 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;
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* t1operator_flex */
- /* */
- /* <Description> */
- /* Implements the `flex' Type 1 operator for a Type 1 decoder. */
- /* */
- /* <Input> */
- /* 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. */
- /* */
- /* <Return> */
- /* 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 );
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* T1_Parse_CharStrings */
- /* */
- /* <Description> */
- /* Parses a given Type 1 charstrings program. */
- /* */
- /* <Input> */
- /* 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. */
- /* */
- /* <Return> */
- /* 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;
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* T1_Add_Points */
- /* */
- /* <Description> */
- /* 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. */
- /* */
- /* <Input> */
- /* builder :: A pointer to the glyph builder object. */
- /* */
- /* num_points :: The number of points that will be added later. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means success. */
- /* */
- /* <Note> */
- /* 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 );
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* T1_Add_Contours */
- /* */
- /* <Description> */
- /* 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. */
- /* */
- /* <Input> */
- /* builder :: A pointer to the glyph builder object. */
- /* */
- /* num_contours :: The number of contours that will be added later. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means success. */
- /* */
- /* <Note> */
- /* 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 */
--- a/src/type1/t1gload.h
+++ /dev/null
@@ -1,326 +1,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 <type1/t1objs.h>
-
-#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 );
-
-
- /*************************************************************************/
- /* */
- /* <Structure> */
- /* T1_Builder_Funcs */
- /* */
- /* <Description> */
- /* 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;
-
-
- /*************************************************************************/
- /* */
- /* <Structure> */
- /* T1_Builder */
- /* */
- /* <Description> */
- /* A structure used during glyph loading to store its outline. */
- /* */
- /* <Fields> */
- /* 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 );
-
-
- /*************************************************************************/
- /* */
- /* <Structure> */
- /* T1_Hinter_Funcs */
- /* */
- /* <Description> */
- /* 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 */
--- a/src/type1/t1hinter.c
+++ /dev/null
@@ -1,1347 +1,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 <freetype/internal/ftdebug.h>
-
-
-#ifdef FT_FLAT_COMPILE
-
-#include "t1objs.h"
-#include "t1hinter.h"
-
-#else
-
-#include <type1/t1objs.h>
-#include <type1/t1hinter.h>
-
-#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 );
- }
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* t1_set_blue_zones */
- /* */
- /* <Description> */
- /* Sets a size object's blue zones during reset. This will compute */
- /* the `snap' zone corresponding to each blue zone. */
- /* */
- /* <InOut> */
- /* size :: A handle to target size object. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means success. */
- /* */
- /* <Note> */
- /* 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;
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* t1_set_snap_zones */
- /* */
- /* <Description> */
- /* This function set a size object's stem snap zones. */
- /* */
- /* <InOut> */
- /* size :: A handle to the target size object. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means success. */
- /* */
- /* <Note> */
- /* 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;
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* T1_New_Size_Hinter */
- /* */
- /* <Description> */
- /* Allocates a new hinter structure for a given size object. */
- /* */
- /* <InOut> */
- /* size :: A handle to the target size object. */
- /* */
- /* <Return> */
- /* 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 ) );
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* T1_Done_Size_Hinter */
- /* */
- /* <Description> */
- /* Releases a given size object's hinter structure. */
- /* */
- /* <Input> */
- /* 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 );
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* T1_Reset_Size_Hinter */
- /* */
- /* <Description> */
- /* Recomputes hinting information when a given size object has */
- /* changed its resolutions/char sizes/pixel sizes. */
- /* */
- /* <InOut> */
- /* size :: A handle to the size object. */
- /* */
- /* <Return> */
- /* 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 );
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* T1_New_Glyph_Hinter */
- /* */
- /* <Description> */
- /* Allocates a new hinter structure for a given glyph slot. */
- /* */
- /* <InOut> */
- /* glyph :: A handle to the target glyph slot. */
- /* */
- /* <Return> */
- /* 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 ) );
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* T1_Done_Glyph_Hinter */
- /* */
- /* <Description> */
- /* Releases a given glyph slot's hinter structure. */
- /* */
- /* <Input> */
- /* 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. *********/
- /********** *********/
- /*************************************************************************/
- /*************************************************************************/
- /*************************************************************************/
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* t1_sort_hints */
- /* */
- /* <Description> */
- /* Sorta the list of active stems in increasing order, through the */
- /* `sort' indexing table. */
- /* */
- /* <InOut> */
- /* 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;
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* t1_hint_horizontal_stems */
- /* */
- /* <Description> */
- /* Computes the location of each scaled horizontal stem hint. This */
- /* takes care of the blue zones and the horizontal stem snap table. */
- /* */
- /* <Input> */
- /* 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. */
- /* */
- /* <Note> */
- /* 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;
- }
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* t1_hint_vertical_stems */
- /* */
- /* <Description> */
- /* Computes the location of each scaled vertical stem hint. This */
- /* takes care of the vertical stem snap table. */
- /* */
- /* <Input> */
- /* 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. */
- /* */
- /* <Note> */
- /* 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;
- }
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* t1_hint_point */
- /* */
- /* <Description> */
- /* Grid-fit a coordinate with regards to a given stem hints table. */
- /* */
- /* <Input> */
- /* 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. */
- /* */
- /* <Return> */
- /* The hinted/scaled value in 26.6 pixels. */
- /* */
- /* <Note> */
- /* 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 );
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* T1_Hint_Points */
- /* */
- /* <Description> */
- /* This function grid-fits several points in a given Type 1 builder */
- /* at once. */
- /* */
- /* <Input> */
- /* 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;
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* T1_Hint_Stems */
- /* */
- /* <Description> */
- /* 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. */
- /* */
- /* <Input> */
- /* 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 */
--- a/src/type1/t1hinter.h
+++ /dev/null
@@ -1,273 +1,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 <type1/t1objs.h>
-#include <type1/t1gload.h>
-
-#endif
-
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-
- /*************************************************************************/
- /* */
- /* <Struct> */
- /* T1_Snap_Zone */
- /* */
- /* <Description> */
- /* 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). */
- /* */
- /* <Fields> */
- /* 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;
-
-
- /*************************************************************************/
- /* */
- /* <Struct> */
- /* T1_Edge */
- /* */
- /* <Description> */
- /* A very simple structure used to model a stem edge. */
- /* */
- /* <Fields> */
- /* 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;
-
-
- /*************************************************************************/
- /* */
- /* <Struct> */
- /* T1_Stem_Hint */
- /* */
- /* <Description> */
- /* A simple structure used to model a stem hint. */
- /* */
- /* <Fields> */
- /* min_edge :: The hint's minimum edge. */
- /* */
- /* max_edge :: The hint's maximum edge. */
- /* */
- /* hint_flags :: Some flags describing the stem properties. */
- /* */
- /* <Note> */
- /* 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 */
-
-
- /*************************************************************************/
- /* */
- /* <Struct> */
- /* T1_Size_Hints */
- /* */
- /* <Description> */
- /* A structure used to model the hinting information related to a size */
- /* object. */
- /* */
- /* <Fields> */
- /* 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];
- };
-
-
- /*************************************************************************/
- /* */
- /* <Struct> */
- /* T1_Stem_Table */
- /* */
- /* <Description> */
- /* 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. */
- /* */
- /* <Fields> */
- /* 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;
-
-
- /*************************************************************************/
- /* */
- /* <Struct> */
- /* T1_Glyph_Hints */
- /* */
- /* <Description> */
- /* A structure used to model the stem hints of a given glyph outline */
- /* during glyph loading. */
- /* */
- /* <Fields> */
- /* 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;
- };
-
-
- /*************************************************************************/
- /* */
- /* <Data> */
- /* t1_hinter_funcs */
- /* */
- /* <Description> */
- /* 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 */
--- a/src/type1/t1load.c
+++ /dev/null
@@ -1,1594 +1,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 <freetype/config/ftconfig.h>
-#include <freetype/internal/ftdebug.h>
-#include <freetype/internal/t1types.h>
-
-
-#ifdef FT_FLAT_COMPILE
-
-#include "t1tokens.h"
-#include "t1parse.h"
-
-#else
-
-#include <type1/t1tokens.h>
-#include <type1/t1parse.h>
-
-#endif
-
-
-#include <stdio.h>
-
-#include <string.h> /* 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 );
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* Init_T1_Parser */
- /* */
- /* <Description> */
- /* Initializes a given parser object to build a given T1_Face. */
- /* */
- /* <InOut> */
- /* parser :: A handle to the newly built parser object. */
- /* */
- /* <Input> */
- /* 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? */
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* Next_T1_Token */
- /* */
- /* <Description> */
- /* 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. */
- /* */
- /* <Input> */
- /* parser :: A handle to the source parser. */
- /* */
- /* <Output> */
- /* token :: The extracted token descriptor. */
- /* */
- /* <Return> */
- /* 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 */
- /* */
- /* */
- /*************************************************************************/
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* Do_Def_Font */
- /* */
- /* <Description> */
- /* This function performs a `def' if in the Font dictionary. Its */
- /* purpose is to build the T1_Face attributes directly from the */
- /* stream. */
- /* */
- /* <InOut> */
- /* parser :: A handle to the current parser. */
- /* */
- /* <Return> */
- /* 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;
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* Do_Def_FontInfo */
- /* */
- /* <Description> */
- /* This function performs a `def' if in the FontInfo dictionary. Its */
- /* purpose is to build the T1_FontInfo structure directly from the */
- /* stream. */
- /* */
- /* <InOut> */
- /* parser :: A handle to the current parser. */
- /* */
- /* <Return> */
- /* 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;
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* Do_Def_Private */
- /* */
- /* <Description> */
- /* This function performs a `def' if in the Private dictionary. Its */
- /* purpose is to build the T1_Private structure directly from the */
- /* stream. */
- /* */
- /* <InOut> */
- /* parser :: A handle to the current parser. */
- /* */
- /* <Return> */
- /* 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;
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* Do_Def_Error */
- /* */
- /* <Description> */
- /* 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. */
- /* */
- /* <InOut> */
- /* parser :: A handle to the current parser. */
- /* */
- /* <Return> */
- /* 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 */
- /* */
- /* */
- /*************************************************************************/
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* Do_Put_Encoding */
- /* */
- /* <Description> */
- /* 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. */
- /* */
- /* <InOut> */
- /* parser :: A handle to the current parser. */
- /* */
- /* <Return> */
- /* 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 */
- /* */
- /* */
- /*************************************************************************/
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* Do_RD_Subrs */
- /* */
- /* <Description> */
- /* This function performs an `RD' if in the Subrs dictionary. It */
- /* simply records the array of bytecodes/charstrings corresponding to */
- /* the sub-routine. */
- /* */
- /* <InOut> */
- /* parser :: A handle to the current parser. */
- /* */
- /* <Return> */
- /* 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;
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* Do_RD_CharStrings */
- /* */
- /* <Description> */
- /* This function performs an `RD' if in the CharStrings dictionary. */
- /* It simply records the array of bytecodes/charstrings corresponding */
- /* to the glyph program string. */
- /* */
- /* <InOut> */
- /* parser :: A handle to the current parser. */
- /* */
- /* <Return> */
- /* 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;
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* Parse_T1_FontProgram */
- /* */
- /* <Description> */
- /* Parses a given Type 1 font file and builds its face object. */
- /* */
- /* <InOut> */
- /* parser :: A handle to the target parser object. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means success. */
- /* */
- /* <Note> */
- /* 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 */
--- a/src/type1/t1load.h
+++ /dev/null
@@ -1,57 +1,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 <freetype/internal/ftstream.h>
-
-
-#ifdef FT_FLAT_COMPILE
-
-#include "t1parse.h"
-
-#else
-
-#include <type1/t1parse.h>
-
-#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 */
--- a/src/type1/t1objs.c
+++ /dev/null
@@ -1,544 +1,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 <freetype/internal/ftdebug.h>
-#include <freetype/internal/ftstream.h>
-
-
-#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 <type1/t1gload.h>
-#include <type1/t1load.h>
-#include <type1/t1afm.h>
-
-#ifndef T1_CONFIG_OPTION_DISABLE_HINTER
-#include <type1/t1hinter.h>
-#endif
-
-#endif /* FT_FLAT_COMPILE */
-
-
-#include <freetype/internal/psnames.h>
-
-
- /*************************************************************************/
- /* */
- /* 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 */
- /* */
- /*************************************************************************/
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* T1_Done_Size */
- /* */
- /* <Description> */
- /* The Type 1 size object destructor. Used to discard a given size */
- /* object. */
- /* */
- /* <Input> */
- /* 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;
- }
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* T1_Init_Size */
- /* */
- /* <Description> */
- /* The size object initializer. */
- /* */
- /* <Input> */
- /* size :: A handle to the target size object. */
- /* */
- /* <Return> */
- /* 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
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* T1_Reset_Size */
- /* */
- /* <Description> */
- /* 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. */
- /* */
- /* <Input> */
- /* size :: The target size object. */
- /* */
- /* <Output> */
- /* 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 */
- /* */
- /*************************************************************************/
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* T1_Done_Face */
- /* */
- /* <Description> */
- /* The face object destructor. */
- /* */
- /* <Input> */
- /* 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;
- }
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* T1_Init_Face */
- /* */
- /* <Description> */
- /* The face object constructor. */
- /* */
- /* <Input> */
- /* 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. */
- /* */
- /* <InOut> */
- /* face :: The face record to build. */
- /* */
- /* <Return> */
- /* 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;
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* T1_Done_GlyphSlot */
- /* */
- /* <Description> */
- /* The glyph slot object destructor. */
- /* */
- /* <Input> */
- /* 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
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* T1_Init_GlyphSlot */
- /* */
- /* <Description> */
- /* The glyph slot object constructor. */
- /* */
- /* <Input> */
- /* 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 */
--- a/src/type1/t1objs.h
+++ /dev/null
@@ -1,172 +1,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 <freetype/config/ftconfig.h>
-#include <freetype/internal/ftobjs.h>
-#include <freetype/internal/t1types.h>
-
-#include <freetype/internal/t1errors.h>
-
-#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;
-
-
- /*************************************************************************/
- /* */
- /* <Type> */
- /* T1_Driver */
- /* */
- /* <Description> */
- /* A handle to a Type 1 driver object. */
- /* */
- typedef struct T1_DriverRec_* T1_Driver;
-
-
- /*************************************************************************/
- /* */
- /* <Type> */
- /* T1_Size */
- /* */
- /* <Description> */
- /* A handle to a Type 1 size object. */
- /* */
- typedef struct T1_SizeRec_* T1_Size;
-
-
- /*************************************************************************/
- /* */
- /* <Type> */
- /* T1_GlyphSlot */
- /* */
- /* <Description> */
- /* A handle to a Type 1 glyph slot object. */
- /* */
- typedef struct T1_GlyphSlotRec_* T1_GlyphSlot;
-
-
- /*************************************************************************/
- /* */
- /* <Type> */
- /* T1_CharMap */
- /* */
- /* <Description> */
- /* A handle to a Type 1 character mapping object. */
- /* */
- /* <Note> */
- /* 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 */
- /* */
- /*************************************************************************/
-
-
- /*************************************************************************/
- /* */
- /* <Type> */
- /* T1_SizeRec */
- /* */
- /* <Description> */
- /* 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;
-
-
- /*************************************************************************/
- /* */
- /* <Type> */
- /* T1_GlyphSlotRec */
- /* */
- /* <Description> */
- /* 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 */
--- a/src/type1/t1parse.c
+++ /dev/null
@@ -1,761 +1,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 <freetype/internal/ftdebug.h>
-#include <freetype/internal/t1types.h>
-
-
-#ifdef FT_FLAT_COMPILE
-
-#include "t1parse.h"
-
-#else
-
-#include <type1/t1parse.h>
-
-#endif
-
-
-#include <stdio.h> /* for sscanf() */
-#include <string.h> /* for strncpy() */
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* T1_New_Table */
- /* */
- /* <Description> */
- /* Initializes a T1_Table structure. */
- /* */
- /* <InOut> */
- /* table :: The address of the target table. */
- /* */
- /* <Input> */
- /* count :: The table size (i.e. maximum number of elements). */
- /* memory :: The memory object to use for all subsequent */
- /* reallocations. */
- /* */
- /* <Return> */
- /* 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;
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* T1_Add_Table */
- /* */
- /* <Description> */
- /* Adds an object to a T1_Table, possibly growing its memory block. */
- /* */
- /* <InOut> */
- /* table :: The target table. */
- /* */
- /* <Input> */
- /* 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. */
- /* */
- /* <Return> */
- /* 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;
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* T1_Done_Table */
- /* */
- /* <Description> */
- /* Finalize a T1_Table (reallocate it to its current cursor). */
- /* */
- /* <Input> */
- /* table :: The target table. */
- /* */
- /* <Note> */
- /* 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 */
--- a/src/type1/t1parse.h
+++ /dev/null
@@ -1,261 +1,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 <freetype/internal/ftstream.h>
-
-
-#ifdef FT_FLAT_COMPILE
-
-#include "t1tokens.h"
-
-#else
-
-#include <type1/t1tokens.h>
-
-#endif
-
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-
- /*************************************************************************/
- /* */
- /* <Enum> */
- /* T1_DictState */
- /* */
- /* <Description> */
- /* 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;
-
-
- /*************************************************************************/
- /* */
- /* <Struct> */
- /* T1_Table */
- /* */
- /* <Description> */
- /* A T1_Table is a simple object used to store an array of objects in */
- /* a single memory block. */
- /* */
- /* <Fields> */
- /* 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;
-
-
- /*************************************************************************/
- /* */
- /* <Struct> */
- /* T1_Parser */
- /* */
- /* <Description> */
- /* A Type 1 parser. This object is in charge of parsing Type 1 ASCII */
- /* streams and builds dictionaries for a T1_Face object. */
- /* */
- /* <Fields> */
- /* 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 */
--- a/src/type1/t1tokens.c
+++ /dev/null
@@ -1,1101 +1,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 <freetype/internal/ftstream.h>
-#include <freetype/internal/ftdebug.h>
-
-
-#ifdef FT_FLAT_COMPILE
-
-#include "t1tokens.h"
-#include "t1load.h"
-
-#else
-
-#include <type1/t1tokens.h>
-#include <type1/t1load.h>
-
-#endif
-
-
-#include <string.h> /* 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;
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* t1_decrypt */
- /* */
- /* <Description> */
- /* Performs the Type 1 charstring decryption process. */
- /* */
- /* <Input> */
- /* 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--;
- }
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* New_Tokenizer */
- /* */
- /* <Description> */
- /* 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. */
- /* */
- /* <Input> */
- /* stream :: The input stream. */
- /* */
- /* <Output> */
- /* tokenizer :: A handle to a new tokenizer object. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means success. */
- /* */
- /* <Note> */
- /* 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;
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* Done_Tokenizer */
- /* */
- /* <Description> */
- /* Closes a given tokenizer. This function will also close the */
- /* stream embedded in the object. */
- /* */
- /* <Input> */
- /* tokenizer :: The target tokenizer object. */
- /* */
- /* <Return> */
- /* 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;
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* Open_PrivateDict */
- /* */
- /* <Description> */
- /* 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). */
- /* */
- /* <Input> */
- /* tokenizer :: The target tokenizer object. */
- /* lenIV :: The value of the `lenIV' variable. */
- /* */
- /* <Return> */
- /* 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;
- }
-
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* Read_Token */
- /* */
- /* <Description> */
- /* 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. */
- /* */
- /* <Input> */
- /* tokenizer :: The target tokenizer object. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means success. */
- /* */
- /* <Note> */
- /* 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
-
- /*************************************************************************/
- /* */
- /* <Function> */
- /* Read_CharStrings */
- /* */
- /* <Description> */
- /* 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. */
- /* */
- /* <Input> */
- /* tokenizer :: The target tokenizer object. */
- /* num_chars :: The number of binary bytes to read. */
- /* */
- /* <Output> */
- /* buffer :: The target array of bytes. These are */
- /* eexec-decrypted. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means success. */
- /* */
- /* <Note> */
- /* 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 */
--- a/src/type1/t1tokens.h
+++ /dev/null
@@ -1,258 +1,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 <type1/t1objs.h>
-
-#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[];
-
-
- /*************************************************************************/
- /* */
- /* <Struct> */
- /* T1_Token */
- /* */
- /* <Description> */
- /* 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. */
- /* */
- /* <Fields> */
- /* 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;
-
-
- /*************************************************************************/
- /* */
- /* <Type> */
- /* T1_Tokenizer */
- /* */
- /* <Description> */
- /* 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 */
--- a/src/type1/type1.c
+++ /dev/null
@@ -1,59 +1,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 <type1/t1driver.c>
-#include <type1/t1objs.c>
-#include <type1/t1load.c>
-#include <type1/t1gload.c>
-#include <type1/t1tokens.c>
-#include <type1/t1parse.c>
-
-#ifndef T1_CONFIG_OPTION_DISABLE_HINTER
-#include <type1/t1hinter.c>
-#endif
-
-#ifndef T1_CONFIG_OPTION_NO_AFM
-#include <type1/t1afm.c>
-#endif
-
-#endif /* FT_FLAT_COMPILE */
-
-
-/* END */