Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygent42objs.c
Go to the documentation of this file.
00001 /***************************************************************************/ 00002 /* */ 00003 /* t42objs.c */ 00004 /* */ 00005 /* Type 42 objects manager (body). */ 00006 /* */ 00007 /* Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 */ 00008 /* by Roberto Alameda. */ 00009 /* */ 00010 /* This file is part of the FreeType project, and may only be used, */ 00011 /* modified, and distributed under the terms of the FreeType project */ 00012 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 00013 /* this file you indicate that you have read the license and */ 00014 /* understand and accept it fully. */ 00015 /* */ 00016 /***************************************************************************/ 00017 00018 00019 #include "t42objs.h" 00020 #include "t42parse.h" 00021 #include "t42error.h" 00022 #include FT_INTERNAL_DEBUG_H 00023 #include FT_LIST_H 00024 #include FT_TRUETYPE_IDS_H 00025 00026 00027 #undef FT_COMPONENT 00028 #define FT_COMPONENT trace_t42 00029 00030 00031 static FT_Error 00032 T42_Open_Face( T42_Face face ) 00033 { 00034 T42_LoaderRec loader; 00035 T42_Parser parser; 00036 T1_Font type1 = &face->type1; 00037 FT_Memory memory = face->root.memory; 00038 FT_Error error; 00039 00040 PSAux_Service psaux = (PSAux_Service)face->psaux; 00041 00042 00043 t42_loader_init( &loader, face ); 00044 00045 parser = &loader.parser; 00046 00047 if ( FT_ALLOC( face->ttf_data, 12 ) ) 00048 goto Exit; 00049 00050 error = t42_parser_init( parser, 00051 face->root.stream, 00052 memory, 00053 psaux); 00054 if ( error ) 00055 goto Exit; 00056 00057 error = t42_parse_dict( face, &loader, 00058 parser->base_dict, parser->base_len ); 00059 if ( error ) 00060 goto Exit; 00061 00062 if ( type1->font_type != 42 ) 00063 { 00064 error = T42_Err_Unknown_File_Format; 00065 goto Exit; 00066 } 00067 00068 /* now, propagate the charstrings and glyphnames tables */ 00069 /* to the Type1 data */ 00070 type1->num_glyphs = loader.num_glyphs; 00071 00072 if ( !loader.charstrings.init ) 00073 { 00074 FT_ERROR(( "T42_Open_Face: no charstrings array in face\n" )); 00075 error = T42_Err_Invalid_File_Format; 00076 } 00077 00078 loader.charstrings.init = 0; 00079 type1->charstrings_block = loader.charstrings.block; 00080 type1->charstrings = loader.charstrings.elements; 00081 type1->charstrings_len = loader.charstrings.lengths; 00082 00083 /* we copy the glyph names `block' and `elements' fields; */ 00084 /* the `lengths' field must be released later */ 00085 type1->glyph_names_block = loader.glyph_names.block; 00086 type1->glyph_names = (FT_String**)loader.glyph_names.elements; 00087 loader.glyph_names.block = 0; 00088 loader.glyph_names.elements = 0; 00089 00090 /* we must now build type1.encoding when we have a custom array */ 00091 if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY ) 00092 { 00093 FT_Int charcode, idx, min_char, max_char; 00094 FT_Byte* char_name; 00095 FT_Byte* glyph_name; 00096 00097 00098 /* OK, we do the following: for each element in the encoding */ 00099 /* table, look up the index of the glyph having the same name */ 00100 /* as defined in the CharStrings array. */ 00101 /* The index is then stored in type1.encoding.char_index, and */ 00102 /* the name in type1.encoding.char_name */ 00103 00104 min_char = 0; 00105 max_char = 0; 00106 00107 charcode = 0; 00108 for ( ; charcode < loader.encoding_table.max_elems; charcode++ ) 00109 { 00110 type1->encoding.char_index[charcode] = 0; 00111 type1->encoding.char_name [charcode] = (char *)".notdef"; 00112 00113 char_name = loader.encoding_table.elements[charcode]; 00114 if ( char_name ) 00115 for ( idx = 0; idx < type1->num_glyphs; idx++ ) 00116 { 00117 glyph_name = (FT_Byte*)type1->glyph_names[idx]; 00118 if ( ft_strcmp( (const char*)char_name, 00119 (const char*)glyph_name ) == 0 ) 00120 { 00121 type1->encoding.char_index[charcode] = (FT_UShort)idx; 00122 type1->encoding.char_name [charcode] = (char*)glyph_name; 00123 00124 /* Change min/max encoded char only if glyph name is */ 00125 /* not /.notdef */ 00126 if ( ft_strcmp( (const char*)".notdef", 00127 (const char*)glyph_name ) != 0 ) 00128 { 00129 if ( charcode < min_char ) 00130 min_char = charcode; 00131 if ( charcode >= max_char ) 00132 max_char = charcode + 1; 00133 } 00134 break; 00135 } 00136 } 00137 } 00138 00139 type1->encoding.code_first = min_char; 00140 type1->encoding.code_last = max_char; 00141 type1->encoding.num_chars = loader.num_chars; 00142 } 00143 00144 Exit: 00145 t42_loader_done( &loader ); 00146 return error; 00147 } 00148 00149 00150 /***************** Driver Functions *************/ 00151 00152 00153 FT_LOCAL_DEF( FT_Error ) 00154 T42_Face_Init( FT_Stream stream, 00155 T42_Face face, 00156 FT_Int face_index, 00157 FT_Int num_params, 00158 FT_Parameter* params ) 00159 { 00160 FT_Error error; 00161 FT_Service_PsCMaps psnames; 00162 PSAux_Service psaux; 00163 FT_Face root = (FT_Face)&face->root; 00164 T1_Font type1 = &face->type1; 00165 PS_FontInfo info = &type1->font_info; 00166 00167 FT_UNUSED( num_params ); 00168 FT_UNUSED( params ); 00169 FT_UNUSED( face_index ); 00170 FT_UNUSED( stream ); 00171 00172 00173 face->ttf_face = NULL; 00174 face->root.num_faces = 1; 00175 00176 FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); 00177 face->psnames = psnames; 00178 00179 face->psaux = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), 00180 "psaux" ); 00181 psaux = (PSAux_Service)face->psaux; 00182 00183 /* open the tokenizer, this will also check the font format */ 00184 error = T42_Open_Face( face ); 00185 if ( error ) 00186 goto Exit; 00187 00188 /* if we just wanted to check the format, leave successfully now */ 00189 if ( face_index < 0 ) 00190 goto Exit; 00191 00192 /* check the face index */ 00193 if ( face_index > 0 ) 00194 { 00195 FT_ERROR(( "T42_Face_Init: invalid face index\n" )); 00196 error = T42_Err_Invalid_Argument; 00197 goto Exit; 00198 } 00199 00200 /* Now load the font program into the face object */ 00201 00202 /* Init the face object fields */ 00203 /* Now set up root face fields */ 00204 00205 root->num_glyphs = type1->num_glyphs; 00206 root->num_charmaps = 0; 00207 root->face_index = 0; 00208 00209 root->face_flags = FT_FACE_FLAG_SCALABLE | 00210 FT_FACE_FLAG_HORIZONTAL | 00211 FT_FACE_FLAG_GLYPH_NAMES; 00212 00213 if ( info->is_fixed_pitch ) 00214 root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; 00215 00216 /* We only set this flag if we have the patented bytecode interpreter. */ 00217 /* There are no known `tricky' Type42 fonts that could be loaded with */ 00218 /* the unpatented interpreter. */ 00219 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER 00220 root->face_flags |= FT_FACE_FLAG_HINTER; 00221 #endif 00222 00223 /* XXX: TODO -- add kerning with .afm support */ 00224 00225 /* get style name -- be careful, some broken fonts only */ 00226 /* have a `/FontName' dictionary entry! */ 00227 root->family_name = info->family_name; 00228 /* assume "Regular" style if we don't know better */ 00229 root->style_name = (char *)"Regular"; 00230 if ( root->family_name ) 00231 { 00232 char* full = info->full_name; 00233 char* family = root->family_name; 00234 00235 00236 if ( full ) 00237 { 00238 while ( *full ) 00239 { 00240 if ( *full == *family ) 00241 { 00242 family++; 00243 full++; 00244 } 00245 else 00246 { 00247 if ( *full == ' ' || *full == '-' ) 00248 full++; 00249 else if ( *family == ' ' || *family == '-' ) 00250 family++; 00251 else 00252 { 00253 if ( !*family ) 00254 root->style_name = full; 00255 break; 00256 } 00257 } 00258 } 00259 } 00260 } 00261 else 00262 { 00263 /* do we have a `/FontName'? */ 00264 if ( type1->font_name ) 00265 root->family_name = type1->font_name; 00266 } 00267 00268 /* no embedded bitmap support */ 00269 root->num_fixed_sizes = 0; 00270 root->available_sizes = 0; 00271 00272 /* Load the TTF font embedded in the T42 font */ 00273 { 00274 FT_Open_Args args; 00275 00276 00277 args.flags = FT_OPEN_MEMORY; 00278 args.memory_base = face->ttf_data; 00279 args.memory_size = face->ttf_size; 00280 00281 if ( num_params ) 00282 { 00283 args.flags |= FT_OPEN_PARAMS; 00284 args.num_params = num_params; 00285 args.params = params; 00286 } 00287 00288 error = FT_Open_Face( FT_FACE_LIBRARY( face ), 00289 &args, 0, &face->ttf_face ); 00290 } 00291 00292 if ( error ) 00293 goto Exit; 00294 00295 FT_Done_Size( face->ttf_face->size ); 00296 00297 /* Ignore info in FontInfo dictionary and use the info from the */ 00298 /* loaded TTF font. The PostScript interpreter also ignores it. */ 00299 root->bbox = face->ttf_face->bbox; 00300 root->units_per_EM = face->ttf_face->units_per_EM; 00301 00302 root->ascender = face->ttf_face->ascender; 00303 root->descender = face->ttf_face->descender; 00304 root->height = face->ttf_face->height; 00305 00306 root->max_advance_width = face->ttf_face->max_advance_width; 00307 root->max_advance_height = face->ttf_face->max_advance_height; 00308 00309 root->underline_position = (FT_Short)info->underline_position; 00310 root->underline_thickness = (FT_Short)info->underline_thickness; 00311 00312 /* compute style flags */ 00313 root->style_flags = 0; 00314 if ( info->italic_angle ) 00315 root->style_flags |= FT_STYLE_FLAG_ITALIC; 00316 00317 if ( face->ttf_face->style_flags & FT_STYLE_FLAG_BOLD ) 00318 root->style_flags |= FT_STYLE_FLAG_BOLD; 00319 00320 if ( face->ttf_face->face_flags & FT_FACE_FLAG_VERTICAL ) 00321 root->face_flags |= FT_FACE_FLAG_VERTICAL; 00322 00323 { 00324 if ( psnames && psaux ) 00325 { 00326 FT_CharMapRec charmap; 00327 T1_CMap_Classes cmap_classes = psaux->t1_cmap_classes; 00328 FT_CMap_Class clazz; 00329 00330 00331 charmap.face = root; 00332 00333 /* first of all, try to synthesize a Unicode charmap */ 00334 charmap.platform_id = TT_PLATFORM_MICROSOFT; 00335 charmap.encoding_id = TT_MS_ID_UNICODE_CS; 00336 charmap.encoding = FT_ENCODING_UNICODE; 00337 00338 error = FT_CMap_New( cmap_classes->unicode, NULL, &charmap, NULL ); 00339 if ( error && FT_Err_No_Unicode_Glyph_Name != error ) 00340 goto Exit; 00341 error = FT_Err_Ok; 00342 00343 /* now, generate an Adobe Standard encoding when appropriate */ 00344 charmap.platform_id = TT_PLATFORM_ADOBE; 00345 clazz = NULL; 00346 00347 switch ( type1->encoding_type ) 00348 { 00349 case T1_ENCODING_TYPE_STANDARD: 00350 charmap.encoding = FT_ENCODING_ADOBE_STANDARD; 00351 charmap.encoding_id = TT_ADOBE_ID_STANDARD; 00352 clazz = cmap_classes->standard; 00353 break; 00354 00355 case T1_ENCODING_TYPE_EXPERT: 00356 charmap.encoding = FT_ENCODING_ADOBE_EXPERT; 00357 charmap.encoding_id = TT_ADOBE_ID_EXPERT; 00358 clazz = cmap_classes->expert; 00359 break; 00360 00361 case T1_ENCODING_TYPE_ARRAY: 00362 charmap.encoding = FT_ENCODING_ADOBE_CUSTOM; 00363 charmap.encoding_id = TT_ADOBE_ID_CUSTOM; 00364 clazz = cmap_classes->custom; 00365 break; 00366 00367 case T1_ENCODING_TYPE_ISOLATIN1: 00368 charmap.encoding = FT_ENCODING_ADOBE_LATIN_1; 00369 charmap.encoding_id = TT_ADOBE_ID_LATIN_1; 00370 clazz = cmap_classes->unicode; 00371 break; 00372 00373 default: 00374 ; 00375 } 00376 00377 if ( clazz ) 00378 error = FT_CMap_New( clazz, NULL, &charmap, NULL ); 00379 00380 #if 0 00381 /* Select default charmap */ 00382 if ( root->num_charmaps ) 00383 root->charmap = root->charmaps[0]; 00384 #endif 00385 } 00386 } 00387 Exit: 00388 return error; 00389 } 00390 00391 00392 FT_LOCAL_DEF( void ) 00393 T42_Face_Done( T42_Face face ) 00394 { 00395 T1_Font type1; 00396 PS_FontInfo info; 00397 FT_Memory memory; 00398 00399 00400 if ( !face ) 00401 return; 00402 00403 type1 = &face->type1; 00404 info = &type1->font_info; 00405 memory = face->root.memory; 00406 00407 /* delete internal ttf face prior to freeing face->ttf_data */ 00408 if ( face->ttf_face ) 00409 FT_Done_Face( face->ttf_face ); 00410 00411 /* release font info strings */ 00412 FT_FREE( info->version ); 00413 FT_FREE( info->notice ); 00414 FT_FREE( info->full_name ); 00415 FT_FREE( info->family_name ); 00416 FT_FREE( info->weight ); 00417 00418 /* release top dictionary */ 00419 FT_FREE( type1->charstrings_len ); 00420 FT_FREE( type1->charstrings ); 00421 FT_FREE( type1->glyph_names ); 00422 00423 FT_FREE( type1->charstrings_block ); 00424 FT_FREE( type1->glyph_names_block ); 00425 00426 FT_FREE( type1->encoding.char_index ); 00427 FT_FREE( type1->encoding.char_name ); 00428 FT_FREE( type1->font_name ); 00429 00430 FT_FREE( face->ttf_data ); 00431 00432 #if 0 00433 /* release afm data if present */ 00434 if ( face->afm_data ) 00435 T1_Done_AFM( memory, (T1_AFM*)face->afm_data ); 00436 #endif 00437 00438 /* release unicode map, if any */ 00439 FT_FREE( face->unicode_map.maps ); 00440 face->unicode_map.num_maps = 0; 00441 00442 face->root.family_name = 0; 00443 face->root.style_name = 0; 00444 } 00445 00446 00447 /*************************************************************************/ 00448 /* */ 00449 /* <Function> */ 00450 /* T42_Driver_Init */ 00451 /* */ 00452 /* <Description> */ 00453 /* Initializes a given Type 42 driver object. */ 00454 /* */ 00455 /* <Input> */ 00456 /* driver :: A handle to the target driver object. */ 00457 /* */ 00458 /* <Return> */ 00459 /* FreeType error code. 0 means success. */ 00460 /* */ 00461 FT_LOCAL_DEF( FT_Error ) 00462 T42_Driver_Init( T42_Driver driver ) 00463 { 00464 FT_Module ttmodule; 00465 00466 00467 ttmodule = FT_Get_Module( FT_MODULE(driver)->library, "truetype" ); 00468 driver->ttclazz = (FT_Driver_Class)ttmodule->clazz; 00469 00470 return T42_Err_Ok; 00471 } 00472 00473 00474 FT_LOCAL_DEF( void ) 00475 T42_Driver_Done( T42_Driver driver ) 00476 { 00477 FT_UNUSED( driver ); 00478 } 00479 00480 00481 FT_LOCAL_DEF( FT_Error ) 00482 T42_Size_Init( T42_Size size ) 00483 { 00484 FT_Face face = size->root.face; 00485 T42_Face t42face = (T42_Face)face; 00486 FT_Size ttsize; 00487 FT_Error error = T42_Err_Ok; 00488 00489 00490 error = FT_New_Size( t42face->ttf_face, &ttsize ); 00491 size->ttsize = ttsize; 00492 00493 FT_Activate_Size( ttsize ); 00494 00495 return error; 00496 } 00497 00498 00499 FT_LOCAL_DEF( FT_Error ) 00500 T42_Size_Request( T42_Size size, 00501 FT_Size_Request req ) 00502 { 00503 T42_Face face = (T42_Face)size->root.face; 00504 FT_Error error; 00505 00506 00507 FT_Activate_Size( size->ttsize ); 00508 00509 error = FT_Request_Size( face->ttf_face, req ); 00510 if ( !error ) 00511 ( (FT_Size)size )->metrics = face->ttf_face->size->metrics; 00512 00513 return error; 00514 } 00515 00516 00517 FT_LOCAL_DEF( FT_Error ) 00518 T42_Size_Select( T42_Size size, 00519 FT_ULong strike_index ) 00520 { 00521 T42_Face face = (T42_Face)size->root.face; 00522 FT_Error error; 00523 00524 00525 FT_Activate_Size( size->ttsize ); 00526 00527 error = FT_Select_Size( face->ttf_face, (FT_Int)strike_index ); 00528 if ( !error ) 00529 ( (FT_Size)size )->metrics = face->ttf_face->size->metrics; 00530 00531 return error; 00532 00533 } 00534 00535 00536 FT_LOCAL_DEF( void ) 00537 T42_Size_Done( T42_Size size ) 00538 { 00539 FT_Face face = size->root.face; 00540 T42_Face t42face = (T42_Face)face; 00541 FT_ListNode node; 00542 00543 00544 node = FT_List_Find( &t42face->ttf_face->sizes_list, size->ttsize ); 00545 if ( node ) 00546 { 00547 FT_Done_Size( size->ttsize ); 00548 size->ttsize = NULL; 00549 } 00550 } 00551 00552 00553 FT_LOCAL_DEF( FT_Error ) 00554 T42_GlyphSlot_Init( T42_GlyphSlot slot ) 00555 { 00556 FT_Face face = slot->root.face; 00557 T42_Face t42face = (T42_Face)face; 00558 FT_GlyphSlot ttslot; 00559 FT_Error error = T42_Err_Ok; 00560 00561 00562 if ( face->glyph == NULL ) 00563 { 00564 /* First glyph slot for this face */ 00565 slot->ttslot = t42face->ttf_face->glyph; 00566 } 00567 else 00568 { 00569 error = FT_New_GlyphSlot( t42face->ttf_face, &ttslot ); 00570 slot->ttslot = ttslot; 00571 } 00572 00573 return error; 00574 } 00575 00576 00577 FT_LOCAL_DEF( void ) 00578 T42_GlyphSlot_Done( T42_GlyphSlot slot ) 00579 { 00580 FT_Done_GlyphSlot( slot->ttslot ); 00581 } 00582 00583 00584 static void 00585 t42_glyphslot_clear( FT_GlyphSlot slot ) 00586 { 00587 /* free bitmap if needed */ 00588 ft_glyphslot_free_bitmap( slot ); 00589 00590 /* clear all public fields in the glyph slot */ 00591 FT_ZERO( &slot->metrics ); 00592 FT_ZERO( &slot->outline ); 00593 FT_ZERO( &slot->bitmap ); 00594 00595 slot->bitmap_left = 0; 00596 slot->bitmap_top = 0; 00597 slot->num_subglyphs = 0; 00598 slot->subglyphs = 0; 00599 slot->control_data = 0; 00600 slot->control_len = 0; 00601 slot->other = 0; 00602 slot->format = FT_GLYPH_FORMAT_NONE; 00603 00604 slot->linearHoriAdvance = 0; 00605 slot->linearVertAdvance = 0; 00606 } 00607 00608 00609 FT_LOCAL_DEF( FT_Error ) 00610 T42_GlyphSlot_Load( FT_GlyphSlot glyph, 00611 FT_Size size, 00612 FT_UInt glyph_index, 00613 FT_Int32 load_flags ) 00614 { 00615 FT_Error error; 00616 T42_GlyphSlot t42slot = (T42_GlyphSlot)glyph; 00617 T42_Size t42size = (T42_Size)size; 00618 FT_Driver_Class ttclazz = ((T42_Driver)glyph->face->driver)->ttclazz; 00619 00620 00621 t42_glyphslot_clear( t42slot->ttslot ); 00622 error = ttclazz->load_glyph( t42slot->ttslot, 00623 t42size->ttsize, 00624 glyph_index, 00625 load_flags | FT_LOAD_NO_BITMAP ); 00626 00627 if ( !error ) 00628 { 00629 glyph->metrics = t42slot->ttslot->metrics; 00630 00631 glyph->linearHoriAdvance = t42slot->ttslot->linearHoriAdvance; 00632 glyph->linearVertAdvance = t42slot->ttslot->linearVertAdvance; 00633 00634 glyph->format = t42slot->ttslot->format; 00635 glyph->outline = t42slot->ttslot->outline; 00636 00637 glyph->bitmap = t42slot->ttslot->bitmap; 00638 glyph->bitmap_left = t42slot->ttslot->bitmap_left; 00639 glyph->bitmap_top = t42slot->ttslot->bitmap_top; 00640 00641 glyph->num_subglyphs = t42slot->ttslot->num_subglyphs; 00642 glyph->subglyphs = t42slot->ttslot->subglyphs; 00643 00644 glyph->control_data = t42slot->ttslot->control_data; 00645 glyph->control_len = t42slot->ttslot->control_len; 00646 } 00647 00648 return error; 00649 } 00650 00651 00652 /* END */ Generated on Sat May 26 2012 04:32:59 for ReactOS by
1.7.6.1
|