1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/ 2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* cidload.c */ 4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* CID-keyed Type1 font loader (body). */ 6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Copyright 1996-2006, 2009, 2011-2013 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#include "../../include/ft2build.h" 20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/ftdebug.h" 21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/config/ftconfig.h" 22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/ftmm.h" 23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/t1types.h" 24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "cidload.h" 26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "ciderrs.h" 28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* messages during execution. */ 35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef FT_COMPONENT 37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_COMPONENT trace_cidload 38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* read a single offset */ 41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Long ) 42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cid_get_offset( FT_Byte* *start, 43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte offsize ) 44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong result; 46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = *start; 47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( result = 0; offsize > 0; offsize-- ) 50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result <<= 8; 52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result |= *p++; 53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *start = p; 56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (FT_Long)result; 57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** TYPE 1 SYMBOL PARSING *****/ 64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cid_load_keyword( CID_Face face, 71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CID_Loader* loader, 72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const T1_Field keyword ) 73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CID_Parser* parser = &loader->parser; 76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* object; 77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void* dummy_object; 78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CID_FaceInfo cid = &face->cid; 79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* if the keyword has a dedicated callback, call it */ 82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( keyword->type == T1_FIELD_TYPE_CALLBACK ) 83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov keyword->reader( (FT_Face)face, parser ); 85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = parser->root.error; 86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we must now compute the address of our target object */ 90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch ( keyword->location ) 91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case T1_FIELD_LOCATION_CID_INFO: 93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov object = (FT_Byte*)cid; 94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case T1_FIELD_LOCATION_FONT_INFO: 97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov object = (FT_Byte*)&cid->font_info; 98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case T1_FIELD_LOCATION_FONT_EXTRA: 101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov object = (FT_Byte*)&face->font_extra; 102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case T1_FIELD_LOCATION_BBOX: 105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov object = (FT_Byte*)&cid->font_bbox; 106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: 109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CID_FaceDict dict; 111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( parser->num_dict < 0 || parser->num_dict >= cid->num_dicts ) 114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "cid_load_keyword: invalid use of `%s'\n", 116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov keyword->ident )); 117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Syntax_Error ); 118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dict = cid->font_dicts + parser->num_dict; 122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch ( keyword->location ) 123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case T1_FIELD_LOCATION_PRIVATE: 125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov object = (FT_Byte*)&dict->private_dict; 126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: 129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov object = (FT_Byte*)dict; 130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dummy_object = object; 135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* now, load the keyword data in the object's field(s) */ 137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( keyword->type == T1_FIELD_TYPE_INTEGER_ARRAY || 138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov keyword->type == T1_FIELD_TYPE_FIXED_ARRAY ) 139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = cid_parser_load_field_table( &loader->parser, keyword, 140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov &dummy_object ); 141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = cid_parser_load_field( &loader->parser, 143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov keyword, &dummy_object ); 144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_Error ) 150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cid_parse_font_matrix( CID_Face face, 151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CID_Parser* parser ) 152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Matrix* matrix; 154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector* offset; 155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CID_FaceDict dict; 156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face root = (FT_Face)&face->root; 157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Fixed temp[6]; 158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Fixed temp_scale; 159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( parser->num_dict >= 0 && parser->num_dict < face->cid.num_dicts ) 162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dict = face->cid.font_dicts + parser->num_dict; 164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov matrix = &dict->font_matrix; 165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offset = &dict->font_offset; 166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (void)cid_parser_to_fixed_array( parser, 6, temp, 3 ); 168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov temp_scale = FT_ABS( temp[3] ); 170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Set Units per EM based on FontMatrix values. We set the value to */ 172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* 1000 / temp_scale, because temp_scale was already multiplied by */ 173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* 1000 (in t1_tofixed, from psobjs.c). */ 174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov root->units_per_EM = (FT_UShort)FT_DivFix( 1000, temp_scale ); 176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we need to scale the values by 1.0/temp[3] */ 178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( temp_scale != 0x10000L ) 179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov temp[0] = FT_DivFix( temp[0], temp_scale ); 181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov temp[1] = FT_DivFix( temp[1], temp_scale ); 182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov temp[2] = FT_DivFix( temp[2], temp_scale ); 183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov temp[4] = FT_DivFix( temp[4], temp_scale ); 184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov temp[5] = FT_DivFix( temp[5], temp_scale ); 185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov temp[3] = 0x10000L; 186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov matrix->xx = temp[0]; 189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov matrix->yx = temp[1]; 190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov matrix->xy = temp[2]; 191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov matrix->yy = temp[3]; 192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* note that the font offsets are expressed in integer font units */ 194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offset->x = temp[4] >> 16; 195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offset->y = temp[5] >> 16; 196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; /* this is a callback function; */ 199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we must return an error code */ 200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_Error ) 204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parse_fd_array( CID_Face face, 205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CID_Parser* parser ) 206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CID_FaceInfo cid = &face->cid; 208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = face->root.memory; 209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_Err_Ok; 210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long num_dicts; 211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_dicts = cid_parser_to_int( parser ); 214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !cid->font_dicts ) 216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int n; 218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_NEW_ARRAY( cid->font_dicts, num_dicts ) ) 221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cid->num_dicts = (FT_UInt)num_dicts; 224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* don't forget to set a few defaults */ 226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( n = 0; n < cid->num_dicts; n++ ) 227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CID_FaceDict dict = cid->font_dicts + n; 229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* default value for lenIV */ 232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dict->private_dict.lenIV = 4; 233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* by mistake, `expansion_factor' appears both in PS_PrivateRec */ 242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* and CID_FaceDictRec (both are public header files and can't */ 243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* changed); we simply copy the value */ 244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_Error ) 246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parse_expansion_factor( CID_Face face, 247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CID_Parser* parser ) 248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CID_FaceDict dict; 250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( parser->num_dict >= 0 && parser->num_dict < face->cid.num_dicts ) 253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dict = face->cid.font_dicts + parser->num_dict; 255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dict->expansion_factor = cid_parser_to_fixed( parser, 0 ); 257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dict->private_dict.expansion_factor = dict->expansion_factor; 258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static 265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const T1_FieldRec cid_field_records[] = 266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "cidtoken.h" 269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_FIELD_CALLBACK( "FDArray", parse_fd_array, 0 ) 271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_FIELD_CALLBACK( "FontMatrix", cid_parse_font_matrix, 0 ) 272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_FIELD_CALLBACK( "ExpansionFactor", parse_expansion_factor, 0 ) 273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0, 0 } 275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov }; 276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cid_parse_dict( CID_Face face, 280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CID_Loader* loader, 281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* base, 282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long size ) 283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CID_Parser* parser = &loader->parser; 285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->root.cursor = base; 288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->root.limit = base + size; 289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->root.error = FT_Err_Ok; 290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* cur = base; 293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* limit = cur + size; 294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (;;) 297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* newlimit; 299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->root.cursor = cur; 302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cid_parser_skip_spaces( parser ); 303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( parser->root.cursor >= limit ) 305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov newlimit = limit - 1 - 17; 306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov newlimit = parser->root.cursor - 17; 308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* look for `%ADOBeginFontDict' */ 310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; cur < newlimit; cur++ ) 311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( *cur == '%' && 313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_strncmp( (char*)cur, "%ADOBeginFontDict", 17 ) == 0 ) 314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* if /FDArray was found, then cid->num_dicts is > 0, and */ 316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we can start increasing parser->num_dict */ 317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face->cid.num_dicts > 0 ) 318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->num_dict++; 319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur = parser->root.cursor; 323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* no error can occur in cid_parser_skip_spaces */ 324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur >= limit ) 325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cid_parser_skip_PS_token( parser ); 328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( parser->root.cursor >= limit || parser->root.error ) 329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* look for immediates */ 332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( *cur == '/' && cur + 2 < limit ) 333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_PtrDist len; 335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur++; 338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov len = parser->root.cursor - cur; 339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( len > 0 && len < 22 ) 341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* now compare the immediate name to the keyword table */ 343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T1_Field keyword = (T1_Field)cid_field_records; 344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (;;) 347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* name; 349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov name = (FT_Byte*)keyword->ident; 352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !name ) 353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur[0] == name[0] && 356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov len == (FT_PtrDist)ft_strlen( (const char*)name ) ) 357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_PtrDist n; 359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( n = 1; n < len; n++ ) 362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur[n] != name[n] ) 363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( n >= len ) 366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we found it - run the parsing callback */ 368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->root.error = cid_load_keyword( face, 369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov loader, 370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov keyword ); 371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( parser->root.error ) 372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return parser->root.error; 373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov keyword++; 377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur = parser->root.cursor; 382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return parser->root.error; 385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* read the subrmap and the subrs of each font dict */ 389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cid_read_subrs( CID_Face face ) 391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CID_FaceInfo cid = &face->cid; 393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = face->root.memory; 394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream = face->cid_stream; 395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int n; 397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CID_Subrs subr; 398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt max_offsets = 0; 399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong* offsets = 0; 400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PSAux_Service psaux = (PSAux_Service)face->psaux; 401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_NEW_ARRAY( face->subrs, cid->num_dicts ) ) 404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov subr = face->subrs; 407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( n = 0; n < cid->num_dicts; n++, subr++ ) 408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CID_FaceDict dict = cid->font_dicts + n; 410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int lenIV = dict->private_dict.lenIV; 411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt count, num_subrs = dict->num_subrs; 412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong data_len; 413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p; 414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Check for possible overflow. */ 417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( num_subrs == FT_UINT_MAX ) 418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Syntax_Error ); 420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* reallocate offsets array if needed */ 424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( num_subrs + 1 > max_offsets ) 425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt new_max = FT_PAD_CEIL( num_subrs + 1, 4 ); 427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( new_max <= max_offsets ) 430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Syntax_Error ); 432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_RENEW_ARRAY( offsets, max_offsets, new_max ) ) 436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov max_offsets = new_max; 439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* read the subrmap's offsets */ 442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_STREAM_SEEK( cid->data_offset + dict->subrmap_offset ) || 443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_ENTER( ( num_subrs + 1 ) * dict->sd_bytes ) ) 444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = (FT_Byte*)stream->cursor; 447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( count = 0; count <= num_subrs; count++ ) 448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offsets[count] = cid_get_offset( &p, (FT_Byte)dict->sd_bytes ); 449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FRAME_EXIT(); 451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* offsets must be ordered */ 453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( count = 1; count <= num_subrs; count++ ) 454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( offsets[count - 1] > offsets[count] ) 455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* now, compute the size of subrs charstrings, */ 458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* allocate, and read them */ 459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov data_len = offsets[num_subrs] - offsets[0]; 460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_NEW_ARRAY( subr->code, num_subrs + 1 ) || 462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ALLOC( subr->code[0], data_len ) ) 463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_STREAM_SEEK( cid->data_offset + offsets[0] ) || 466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_STREAM_READ( subr->code[0], data_len ) ) 467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* set up pointers */ 470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( count = 1; count <= num_subrs; count++ ) 471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong len; 473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov len = offsets[count] - offsets[count - 1]; 476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov subr->code[count] = subr->code[count - 1] + len; 477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* decrypt subroutines, but only if lenIV >= 0 */ 480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( lenIV >= 0 ) 481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( count = 0; count < num_subrs; count++ ) 483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong len; 485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov len = offsets[count + 1] - offsets[count]; 488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov psaux->t1_decrypt( subr->code[count], len, 4330 ); 489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov subr->num_subrs = num_subrs; 493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( offsets ); 497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Fail: 500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face->subrs ) 501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( n = 0; n < cid->num_dicts; n++ ) 503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face->subrs[n].code ) 505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( face->subrs[n].code[0] ); 506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( face->subrs[n].code ); 508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( face->subrs ); 510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cid_init_loader( CID_Loader* loader, 517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CID_Face face ) 518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( face ); 520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MEM_ZERO( loader, sizeof ( *loader ) ); 522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cid_done_loader( CID_Loader* loader ) 527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CID_Parser* parser = &loader->parser; 529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* finalize parser */ 532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cid_parser_done( parser ); 533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cid_hex_to_binary( FT_Byte* data, 538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long data_len, 539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong offset, 540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CID_Face face ) 541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream stream = face->root.stream; 543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte buffer[256]; 546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte *p, *plimit; 547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte *d, *dlimit; 548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte val; 549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bool upper_nibble, done; 551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_STREAM_SEEK( offset ) ) 554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov d = data; 557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dlimit = d + data_len; 558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = buffer; 559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov plimit = p; 560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov upper_nibble = 1; 562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov done = 0; 563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( d < dlimit ) 565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p >= plimit ) 567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong oldpos = FT_STREAM_POS(); 569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong size = stream->size - oldpos; 570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( size == 0 ) 573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Syntax_Error ); 575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_STREAM_READ( buffer, 256 > size ? size : 256 ) ) 579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = buffer; 581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov plimit = p + FT_STREAM_POS() - oldpos; 582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ft_isdigit( *p ) ) 585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov val = (FT_Byte)( *p - '0' ); 586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( *p >= 'a' && *p <= 'f' ) 587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov val = (FT_Byte)( *p - 'a' ); 588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( *p >= 'A' && *p <= 'F' ) 589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov val = (FT_Byte)( *p - 'A' + 10 ); 590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( *p == ' ' || 591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *p == '\t' || 592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *p == '\r' || 593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *p == '\n' || 594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *p == '\f' || 595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *p == '\0' ) 596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p++; 598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( *p == '>' ) 601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov val = 0; 603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov done = 1; 604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Syntax_Error ); 608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( upper_nibble ) 612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *d = (FT_Byte)( val << 4 ); 613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *d = (FT_Byte)( *d + val ); 616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov d++; 617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov upper_nibble = (FT_Byte)( 1 - upper_nibble ); 620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( done ) 622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p++; 625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Err_Ok; 628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cid_face_open( CID_Face face, 636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int face_index ) 637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CID_Loader loader; 639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CID_Parser* parser; 640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = face->root.memory; 641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cid_init_loader( &loader, face ); 645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser = &loader.parser; 647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = cid_parser_new( parser, face->root.stream, face->root.memory, 648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (PSAux_Service)face->psaux ); 649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = cid_parse_dict( face, &loader, 653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->postscript, 654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->postscript_len ); 655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face_index < 0 ) 659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_NEW( face->cid_stream ) ) 662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( parser->binary_length ) 665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we must convert the data section from hexadecimal to binary */ 667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_ALLOC( face->binary_data, parser->binary_length ) || 668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cid_hex_to_binary( face->binary_data, parser->binary_length, 669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov parser->data_offset, face ) ) 670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Stream_OpenMemory( face->cid_stream, 673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->binary_data, parser->binary_length ); 674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->cid.data_offset = 0; 675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *face->cid_stream = *face->root.stream; 679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov face->cid.data_offset = loader.parser.data_offset; 680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = cid_read_subrs( face ); 683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cid_done_loader( &loader ); 686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* END */ 691