1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/ 2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* t1parse.c */ 4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Type 1 parser (body). */ 6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 7e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* Copyright 1996-2005, 2008, 2009, 2012-2014 by */ 8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* This file is part of the FreeType project, and may only be used, */ 11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* modified, and distributed under the terms of the FreeType project */ 12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* this file you indicate that you have read the license and */ 14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* understand and accept it fully. */ 15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/ 17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The Type 1 parser is in charge of the following: */ 22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* - provide an implementation of a growing sequence of objects called */ 24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* a `T1_Table' (used to build various tables needed by the loader). */ 25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* - opening .pfb and .pfa files to extract their top-level and private */ 27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* dictionaries. */ 28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* - read numbers, arrays & strings from any dictionary. */ 30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* See `t1load.c' to see how data is loaded from the font file. */ 32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 36e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include <ft2build.h> 37e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include FT_INTERNAL_DEBUG_H 38e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include FT_INTERNAL_STREAM_H 39e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include FT_INTERNAL_POSTSCRIPT_AUX_H 40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "t1parse.h" 42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "t1errors.h" 44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* messages during execution. */ 51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef FT_COMPONENT 53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_COMPONENT trace_t1parse 54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** INPUT STREAM PARSER *****/ 61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* see Adobe Technical Note 5040.Download_Fonts.pdf */ 68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov read_pfb_tag( FT_Stream stream, 71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UShort *atag, 72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong *asize ) 73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UShort tag; 76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong size; 77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *atag = 0; 80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *asize = 0; 81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !FT_READ_USHORT( tag ) ) 83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( tag == 0x8001U || tag == 0x8002U ) 85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !FT_READ_ULONG_LE( size ) ) 87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *asize = size; 88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *atag = tag; 91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov check_type1_format( FT_Stream stream, 99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const char* header_string, 100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov size_t header_length ) 101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UShort tag; 104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong dummy; 105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_STREAM_SEEK( 0 ) ) 108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = read_pfb_tag( stream, &tag, &dummy ); 111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* We assume that the first segment in a PFB is always encoded as */ 115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* text. This might be wrong (and the specification doesn't insist */ 116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* on that), but we have never seen a counterexample. */ 117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( tag != 0x8001U && FT_STREAM_SEEK( 0 ) ) 118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !FT_FRAME_ENTER( header_length ) ) 121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Err_Ok; 123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ft_memcmp( stream->cursor, header_string, header_length ) != 0 ) 125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Unknown_File_Format ); 126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_EXIT(); 128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_New_Parser( T1_Parser parser, 137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream, 138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory, 139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PSAux_Service psaux ) 140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UShort tag; 143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong size; 144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory ); 147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->stream = stream; 149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->base_len = 0; 150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->base_dict = 0; 151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->private_len = 0; 152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->private_dict = 0; 153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->in_pfb = 0; 154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->in_memory = 0; 155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->single_block = 0; 156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check the header format */ 158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = check_type1_format( stream, "%!PS-AdobeFont", 14 ); 159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_ERR_NEQ( error, Unknown_File_Format ) ) 162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = check_type1_format( stream, "%!FontType", 10 ); 165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE2(( " not a Type 1 font\n" )); 168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /******************************************************************/ 173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Here a short summary of what is going on: */ 175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* When creating a new Type 1 parser, we try to locate and load */ 177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* the base dictionary if this is possible (i.e., for PFB */ 178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* files). Otherwise, we load the whole font into memory. */ 179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* When `loading' the base dictionary, we only setup pointers */ 181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* in the case of a memory-based stream. Otherwise, we */ 182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* allocate and load the base dictionary in it. */ 183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* parser->in_pfb is set if we are in a binary (`.pfb') font. */ 185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* parser->in_memory is set if we have a memory stream. */ 186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* try to compute the size of the base dictionary; */ 189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* look for a Postscript binary file tag, i.e., 0x8001 */ 190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_STREAM_SEEK( 0L ) ) 191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = read_pfb_tag( stream, &tag, &size ); 194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( tag != 0x8001U ) 198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* assume that this is a PFA file for now; an error will */ 200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* be produced later when more things are checked */ 201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_STREAM_SEEK( 0L ) ) 202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov size = stream->size; 204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->in_pfb = 1; 207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* now, try to load `size' bytes of the `base' dictionary we */ 209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* found previously */ 210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* if it is a memory-based resource, set up pointers */ 212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !stream->read ) 213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->base_dict = (FT_Byte*)stream->base + stream->pos; 215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->base_len = size; 216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->in_memory = 1; 217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check that the `size' field is valid */ 219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_STREAM_SKIP( size ) ) 220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* read segment in memory -- this is clumsy, but so does the format */ 225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_ALLOC( parser->base_dict, size ) || 226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_STREAM_READ( parser->base_dict, size ) ) 227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->base_len = size; 229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->root.base = parser->base_dict; 232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->root.cursor = parser->base_dict; 233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->root.limit = parser->root.cursor + parser->base_len; 234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error && !parser->in_memory ) 237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( parser->base_dict ); 238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( void ) 244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_Finalize_Parser( T1_Parser parser ) 245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = parser->root.memory; 247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* always free the private dictionary */ 250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( parser->private_dict ); 251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* free the base dictionary only when we have a disk stream */ 253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !parser->in_memory ) 254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( parser->base_dict ); 255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->root.funcs.done( &parser->root ); 257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_Get_Private_Dict( T1_Parser parser, 262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PSAux_Service psaux ) 263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream = parser->stream; 265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = parser->root.memory; 266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_Err_Ok; 267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong size; 268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( parser->in_pfb ) 271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* in the case of the PFB format, the private dictionary can be */ 273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* made of several segments. We thus first read the number of */ 274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* segments to compute the total size of the private dictionary */ 275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* then re-read them into memory. */ 276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long start_pos = FT_STREAM_POS(); 277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UShort tag; 278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->private_len = 0; 281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (;;) 282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = read_pfb_tag( stream, &tag, &size ); 284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( tag != 0x8002U ) 288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->private_len += size; 291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_STREAM_SKIP( size ) ) 293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Check that we have a private dictionary there */ 297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* and allocate private dictionary buffer */ 298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( parser->private_len == 0 ) 299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "T1_Get_Private_Dict:" 301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " invalid private dictionary section\n" )); 302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_File_Format ); 303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_STREAM_SEEK( start_pos ) || 307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ALLOC( parser->private_dict, parser->private_len ) ) 308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->private_len = 0; 311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (;;) 312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = read_pfb_tag( stream, &tag, &size ); 314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error || tag != 0x8002U ) 315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Err_Ok; 317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_STREAM_READ( parser->private_dict + parser->private_len, 321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov size ) ) 322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->private_len += size; 325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* We have already `loaded' the whole PFA font file into memory; */ 330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* if this is a memory resource, allocate a new block to hold */ 331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* the private dict. Otherwise, simply overwrite into the base */ 332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* dictionary block in the heap. */ 333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* first of all, look at the `eexec' keyword */ 335e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_Byte* cur = parser->base_dict; 336e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_Byte* limit = cur + parser->base_len; 337e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_Byte c; 338e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_Pointer pos_lf; 339e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_Bool test_cr; 340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Again: 343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (;;) 344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov c = cur[0]; 346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( c == 'e' && cur + 9 < limit ) /* 9 = 5 letters for `eexec' + */ 347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* whitespace + 4 chars */ 348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur[1] == 'e' && 350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur[2] == 'x' && 351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur[3] == 'e' && 352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur[4] == 'c' ) 353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur++; 356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur >= limit ) 357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "T1_Get_Private_Dict:" 359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " could not find `eexec' keyword\n" )); 360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_File_Format ); 361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check whether `eexec' was real -- it could be in a comment */ 366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* or string (as e.g. in u003043t.gsf from ghostscript) */ 367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->root.cursor = parser->base_dict; 369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* set limit to `eexec' + whitespace + 4 characters */ 370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->root.limit = cur + 10; 371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur = parser->root.cursor; 373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov limit = parser->root.limit; 374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( cur < limit ) 376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( *cur == 'e' && ft_strncmp( (char*)cur, "eexec", 5 ) == 0 ) 378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Found; 379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_Skip_PS_Token( parser ); 381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( parser->root.error ) 382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_Skip_Spaces ( parser ); 384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur = parser->root.cursor; 385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we haven't found the correct `eexec'; go back and continue */ 388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* searching */ 389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur = limit; 391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov limit = parser->base_dict + parser->base_len; 392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Again; 393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* now determine where to write the _encrypted_ binary private */ 395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* dictionary. We overwrite the base dictionary for disk-based */ 396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* resources and allocate a new block otherwise */ 397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Found: 399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->root.limit = parser->base_dict + parser->base_len; 400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_Skip_PS_Token( parser ); 402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur = parser->root.cursor; 403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov limit = parser->root.limit; 404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 405e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* According to the Type 1 spec, the first cipher byte must not be */ 406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* an ASCII whitespace character code (blank, tab, carriage return */ 407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* or line feed). We have seen Type 1 fonts with two line feed */ 408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* characters... So skip now all whitespace character codes. */ 409e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* */ 410e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* On the other hand, Adobe's Type 1 parser handles fonts just */ 411e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* fine that are violating this limitation, so we add a heuristic */ 412e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* test to stop at \r only if it is not used for EOL. */ 413e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 414e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov pos_lf = ft_memchr( cur, '\n', limit - cur ); 415e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov test_cr = FT_BOOL( !pos_lf || 416e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov pos_lf > ft_memchr( cur, '\r', limit - cur ) ); 417e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 418e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov while ( cur < limit && 419e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov ( *cur == ' ' || 420e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov *cur == '\t' || 421e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov (test_cr && *cur == '\r' ) || 422e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov *cur == '\n' ) ) 423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ++cur; 424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur >= limit ) 425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "T1_Get_Private_Dict:" 427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " `eexec' not properly terminated\n" )); 428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_File_Format ); 429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov size = (FT_ULong)( parser->base_len - ( cur - parser->base_dict ) ); 433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( parser->in_memory ) 435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* note that we allocate one more byte to put a terminating `0' */ 437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_ALLOC( parser->private_dict, size + 1 ) ) 438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->private_len = size; 440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->single_block = 1; 444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->private_dict = parser->base_dict; 445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->private_len = size; 446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->base_dict = 0; 447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->base_len = 0; 448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* now determine whether the private dictionary is encoded in binary */ 451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* or hexadecimal ASCII format -- decode it accordingly */ 452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we need to access the next 4 bytes (after the final whitespace */ 454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* following the `eexec' keyword); if they all are hexadecimal */ 455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* digits, then we have a case of ASCII storage */ 456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur + 3 < limit && 458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_isxdigit( cur[0] ) && ft_isxdigit( cur[1] ) && 459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_isxdigit( cur[2] ) && ft_isxdigit( cur[3] ) ) 460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* ASCII hexadecimal encoding */ 462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long len; 463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->root.cursor = cur; 466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (void)psaux->ps_parser_funcs->to_bytes( &parser->root, 467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->private_dict, 468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->private_len, 469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov &len, 470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0 ); 471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->private_len = len; 472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* put a safeguard */ 474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->private_dict[len] = '\0'; 475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* binary encoding -- copy the private dict */ 478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MEM_MOVE( parser->private_dict, cur, size ); 479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we now decrypt the encoded binary private dictionary */ 482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov psaux->t1_decrypt( parser->private_dict, parser->private_len, 55665U ); 483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( parser->private_len < 4 ) 485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "T1_Get_Private_Dict:" 487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " invalid private dictionary section\n" )); 488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_File_Format ); 489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* replace the four random bytes at the beginning with whitespace */ 493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->private_dict[0] = ' '; 494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->private_dict[1] = ' '; 495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->private_dict[2] = ' '; 496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->private_dict[3] = ' '; 497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->root.base = parser->private_dict; 499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->root.cursor = parser->private_dict; 500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->root.limit = parser->root.cursor + parser->private_len; 501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Fail: 503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* END */ 509