Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygent1objs.c
Go to the documentation of this file.
00001 /***************************************************************************/ 00002 /* */ 00003 /* t1objs.c */ 00004 /* */ 00005 /* Type 1 objects manager (body). */ 00006 /* */ 00007 /* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ 00008 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 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 <ft2build.h> 00020 #include FT_INTERNAL_CALC_H 00021 #include FT_INTERNAL_DEBUG_H 00022 #include FT_INTERNAL_STREAM_H 00023 #include FT_TRUETYPE_IDS_H 00024 00025 #include "t1gload.h" 00026 #include "t1load.h" 00027 00028 #include "t1errors.h" 00029 00030 #ifndef T1_CONFIG_OPTION_NO_AFM 00031 #include "t1afm.h" 00032 #endif 00033 00034 #include FT_SERVICE_POSTSCRIPT_CMAPS_H 00035 #include FT_INTERNAL_POSTSCRIPT_AUX_H 00036 00037 00038 /*************************************************************************/ 00039 /* */ 00040 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 00041 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 00042 /* messages during execution. */ 00043 /* */ 00044 #undef FT_COMPONENT 00045 #define FT_COMPONENT trace_t1objs 00046 00047 00048 /*************************************************************************/ 00049 /* */ 00050 /* SIZE FUNCTIONS */ 00051 /* */ 00052 /* note that we store the global hints in the size's "internal" root */ 00053 /* field */ 00054 /* */ 00055 /*************************************************************************/ 00056 00057 00058 static PSH_Globals_Funcs 00059 T1_Size_Get_Globals_Funcs( T1_Size size ) 00060 { 00061 T1_Face face = (T1_Face)size->root.face; 00062 PSHinter_Service pshinter = (PSHinter_Service)face->pshinter; 00063 FT_Module module; 00064 00065 00066 module = FT_Get_Module( size->root.face->driver->root.library, 00067 "pshinter" ); 00068 return ( module && pshinter && pshinter->get_globals_funcs ) 00069 ? pshinter->get_globals_funcs( module ) 00070 : 0 ; 00071 } 00072 00073 00074 FT_LOCAL_DEF( void ) 00075 T1_Size_Done( T1_Size size ) 00076 { 00077 if ( size->root.internal ) 00078 { 00079 PSH_Globals_Funcs funcs; 00080 00081 00082 funcs = T1_Size_Get_Globals_Funcs( size ); 00083 if ( funcs ) 00084 funcs->destroy( (PSH_Globals)size->root.internal ); 00085 00086 size->root.internal = 0; 00087 } 00088 } 00089 00090 00091 FT_LOCAL_DEF( FT_Error ) 00092 T1_Size_Init( T1_Size size ) 00093 { 00094 FT_Error error = T1_Err_Ok; 00095 PSH_Globals_Funcs funcs = T1_Size_Get_Globals_Funcs( size ); 00096 00097 00098 if ( funcs ) 00099 { 00100 PSH_Globals globals; 00101 T1_Face face = (T1_Face)size->root.face; 00102 00103 00104 error = funcs->create( size->root.face->memory, 00105 &face->type1.private_dict, &globals ); 00106 if ( !error ) 00107 size->root.internal = (FT_Size_Internal)(void*)globals; 00108 } 00109 00110 return error; 00111 } 00112 00113 00114 FT_LOCAL_DEF( FT_Error ) 00115 T1_Size_Request( T1_Size size, 00116 FT_Size_Request req ) 00117 { 00118 PSH_Globals_Funcs funcs = T1_Size_Get_Globals_Funcs( size ); 00119 00120 00121 FT_Request_Metrics( size->root.face, req ); 00122 00123 if ( funcs ) 00124 funcs->set_scale( (PSH_Globals)size->root.internal, 00125 size->root.metrics.x_scale, 00126 size->root.metrics.y_scale, 00127 0, 0 ); 00128 00129 return T1_Err_Ok; 00130 } 00131 00132 00133 /*************************************************************************/ 00134 /* */ 00135 /* SLOT FUNCTIONS */ 00136 /* */ 00137 /*************************************************************************/ 00138 00139 FT_LOCAL_DEF( void ) 00140 T1_GlyphSlot_Done( T1_GlyphSlot slot ) 00141 { 00142 slot->root.internal->glyph_hints = 0; 00143 } 00144 00145 00146 FT_LOCAL_DEF( FT_Error ) 00147 T1_GlyphSlot_Init( T1_GlyphSlot slot ) 00148 { 00149 T1_Face face; 00150 PSHinter_Service pshinter; 00151 00152 00153 face = (T1_Face)slot->root.face; 00154 pshinter = (PSHinter_Service)face->pshinter; 00155 00156 if ( pshinter ) 00157 { 00158 FT_Module module; 00159 00160 00161 module = FT_Get_Module( slot->root.face->driver->root.library, "pshinter" ); 00162 if (module) 00163 { 00164 T1_Hints_Funcs funcs; 00165 00166 funcs = pshinter->get_t1_funcs( module ); 00167 slot->root.internal->glyph_hints = (void*)funcs; 00168 } 00169 } 00170 return 0; 00171 } 00172 00173 00174 /*************************************************************************/ 00175 /* */ 00176 /* FACE FUNCTIONS */ 00177 /* */ 00178 /*************************************************************************/ 00179 00180 00181 /*************************************************************************/ 00182 /* */ 00183 /* <Function> */ 00184 /* T1_Face_Done */ 00185 /* */ 00186 /* <Description> */ 00187 /* The face object destructor. */ 00188 /* */ 00189 /* <Input> */ 00190 /* face :: A typeless pointer to the face object to destroy. */ 00191 /* */ 00192 FT_LOCAL_DEF( void ) 00193 T1_Face_Done( T1_Face face ) 00194 { 00195 FT_Memory memory; 00196 T1_Font type1; 00197 00198 00199 if ( !face ) 00200 return; 00201 00202 memory = face->root.memory; 00203 type1 = &face->type1; 00204 00205 #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT 00206 /* release multiple masters information */ 00207 FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) ); 00208 00209 if ( face->buildchar ) 00210 { 00211 FT_FREE( face->buildchar ); 00212 00213 face->buildchar = NULL; 00214 face->len_buildchar = 0; 00215 } 00216 00217 T1_Done_Blend( face ); 00218 face->blend = 0; 00219 #endif 00220 00221 /* release font info strings */ 00222 { 00223 PS_FontInfo info = &type1->font_info; 00224 00225 00226 FT_FREE( info->version ); 00227 FT_FREE( info->notice ); 00228 FT_FREE( info->full_name ); 00229 FT_FREE( info->family_name ); 00230 FT_FREE( info->weight ); 00231 } 00232 00233 /* release top dictionary */ 00234 FT_FREE( type1->charstrings_len ); 00235 FT_FREE( type1->charstrings ); 00236 FT_FREE( type1->glyph_names ); 00237 00238 FT_FREE( type1->subrs ); 00239 FT_FREE( type1->subrs_len ); 00240 00241 FT_FREE( type1->subrs_block ); 00242 FT_FREE( type1->charstrings_block ); 00243 FT_FREE( type1->glyph_names_block ); 00244 00245 FT_FREE( type1->encoding.char_index ); 00246 FT_FREE( type1->encoding.char_name ); 00247 FT_FREE( type1->font_name ); 00248 00249 #ifndef T1_CONFIG_OPTION_NO_AFM 00250 /* release afm data if present */ 00251 if ( face->afm_data ) 00252 T1_Done_Metrics( memory, (AFM_FontInfo)face->afm_data ); 00253 #endif 00254 00255 /* release unicode map, if any */ 00256 #if 0 00257 FT_FREE( face->unicode_map_rec.maps ); 00258 face->unicode_map_rec.num_maps = 0; 00259 face->unicode_map = NULL; 00260 #endif 00261 00262 face->root.family_name = NULL; 00263 face->root.style_name = NULL; 00264 } 00265 00266 00267 /*************************************************************************/ 00268 /* */ 00269 /* <Function> */ 00270 /* T1_Face_Init */ 00271 /* */ 00272 /* <Description> */ 00273 /* The face object constructor. */ 00274 /* */ 00275 /* <Input> */ 00276 /* stream :: input stream where to load font data. */ 00277 /* */ 00278 /* face_index :: The index of the font face in the resource. */ 00279 /* */ 00280 /* num_params :: Number of additional generic parameters. Ignored. */ 00281 /* */ 00282 /* params :: Additional generic parameters. Ignored. */ 00283 /* */ 00284 /* <InOut> */ 00285 /* face :: The face record to build. */ 00286 /* */ 00287 /* <Return> */ 00288 /* FreeType error code. 0 means success. */ 00289 /* */ 00290 FT_LOCAL_DEF( FT_Error ) 00291 T1_Face_Init( FT_Stream stream, 00292 T1_Face face, 00293 FT_Int face_index, 00294 FT_Int num_params, 00295 FT_Parameter* params ) 00296 { 00297 FT_Error error; 00298 FT_Service_PsCMaps psnames; 00299 PSAux_Service psaux; 00300 T1_Font type1 = &face->type1; 00301 PS_FontInfo info = &type1->font_info; 00302 00303 FT_UNUSED( num_params ); 00304 FT_UNUSED( params ); 00305 FT_UNUSED( stream ); 00306 00307 00308 face->root.num_faces = 1; 00309 00310 FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); 00311 face->psnames = psnames; 00312 00313 face->psaux = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), 00314 "psaux" ); 00315 psaux = (PSAux_Service)face->psaux; 00316 00317 face->pshinter = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), 00318 "pshinter" ); 00319 00320 /* open the tokenizer; this will also check the font format */ 00321 error = T1_Open_Face( face ); 00322 if ( error ) 00323 goto Exit; 00324 00325 /* if we just wanted to check the format, leave successfully now */ 00326 if ( face_index < 0 ) 00327 goto Exit; 00328 00329 /* check the face index */ 00330 if ( face_index > 0 ) 00331 { 00332 FT_ERROR(( "T1_Face_Init: invalid face index\n" )); 00333 error = T1_Err_Invalid_Argument; 00334 goto Exit; 00335 } 00336 00337 /* now load the font program into the face object */ 00338 00339 /* initialize the face object fields */ 00340 00341 /* set up root face fields */ 00342 { 00343 FT_Face root = (FT_Face)&face->root; 00344 00345 00346 root->num_glyphs = type1->num_glyphs; 00347 root->face_index = 0; 00348 00349 root->face_flags = FT_FACE_FLAG_SCALABLE | 00350 FT_FACE_FLAG_HORIZONTAL | 00351 FT_FACE_FLAG_GLYPH_NAMES | 00352 FT_FACE_FLAG_HINTER; 00353 00354 if ( info->is_fixed_pitch ) 00355 root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; 00356 00357 if ( face->blend ) 00358 root->face_flags |= FT_FACE_FLAG_MULTIPLE_MASTERS; 00359 00360 /* XXX: TODO -- add kerning with .afm support */ 00361 00362 00363 /* The following code to extract the family and the style is very */ 00364 /* simplistic and might get some things wrong. For a full-featured */ 00365 /* algorithm you might have a look at the whitepaper given at */ 00366 /* */ 00367 /* http://blogs.msdn.com/text/archive/2007/04/23/wpf-font-selection-model.aspx */ 00368 00369 /* get style name -- be careful, some broken fonts only */ 00370 /* have a `/FontName' dictionary entry! */ 00371 root->family_name = info->family_name; 00372 root->style_name = NULL; 00373 00374 if ( root->family_name ) 00375 { 00376 char* full = info->full_name; 00377 char* family = root->family_name; 00378 00379 00380 if ( full ) 00381 { 00382 FT_Bool the_same = TRUE; 00383 00384 00385 while ( *full ) 00386 { 00387 if ( *full == *family ) 00388 { 00389 family++; 00390 full++; 00391 } 00392 else 00393 { 00394 if ( *full == ' ' || *full == '-' ) 00395 full++; 00396 else if ( *family == ' ' || *family == '-' ) 00397 family++; 00398 else 00399 { 00400 the_same = FALSE; 00401 00402 if ( !*family ) 00403 root->style_name = full; 00404 break; 00405 } 00406 } 00407 } 00408 00409 if ( the_same ) 00410 root->style_name = (char *)"Regular"; 00411 } 00412 } 00413 else 00414 { 00415 /* do we have a `/FontName'? */ 00416 if ( type1->font_name ) 00417 root->family_name = type1->font_name; 00418 } 00419 00420 if ( !root->style_name ) 00421 { 00422 if ( info->weight ) 00423 root->style_name = info->weight; 00424 else 00425 /* assume `Regular' style because we don't know better */ 00426 root->style_name = (char *)"Regular"; 00427 } 00428 00429 /* compute style flags */ 00430 root->style_flags = 0; 00431 if ( info->italic_angle ) 00432 root->style_flags |= FT_STYLE_FLAG_ITALIC; 00433 if ( info->weight ) 00434 { 00435 if ( !ft_strcmp( info->weight, "Bold" ) || 00436 !ft_strcmp( info->weight, "Black" ) ) 00437 root->style_flags |= FT_STYLE_FLAG_BOLD; 00438 } 00439 00440 /* no embedded bitmap support */ 00441 root->num_fixed_sizes = 0; 00442 root->available_sizes = 0; 00443 00444 root->bbox.xMin = type1->font_bbox.xMin >> 16; 00445 root->bbox.yMin = type1->font_bbox.yMin >> 16; 00446 /* no `U' suffix here to 0xFFFF! */ 00447 root->bbox.xMax = ( type1->font_bbox.xMax + 0xFFFF ) >> 16; 00448 root->bbox.yMax = ( type1->font_bbox.yMax + 0xFFFF ) >> 16; 00449 00450 /* Set units_per_EM if we didn't set it in parse_font_matrix. */ 00451 if ( !root->units_per_EM ) 00452 root->units_per_EM = 1000; 00453 00454 root->ascender = (FT_Short)( root->bbox.yMax ); 00455 root->descender = (FT_Short)( root->bbox.yMin ); 00456 00457 root->height = (FT_Short)( ( root->units_per_EM * 12 ) / 10 ); 00458 if ( root->height < root->ascender - root->descender ) 00459 root->height = (FT_Short)( root->ascender - root->descender ); 00460 00461 /* now compute the maximum advance width */ 00462 root->max_advance_width = 00463 (FT_Short)( root->bbox.xMax ); 00464 { 00465 FT_Pos max_advance; 00466 00467 00468 error = T1_Compute_Max_Advance( face, &max_advance ); 00469 00470 /* in case of error, keep the standard width */ 00471 if ( !error ) 00472 root->max_advance_width = (FT_Short)FIXED_TO_INT( max_advance ); 00473 else 00474 error = T1_Err_Ok; /* clear error */ 00475 } 00476 00477 root->max_advance_height = root->height; 00478 00479 root->underline_position = (FT_Short)info->underline_position; 00480 root->underline_thickness = (FT_Short)info->underline_thickness; 00481 } 00482 00483 { 00484 FT_Face root = &face->root; 00485 00486 00487 if ( psnames && psaux ) 00488 { 00489 FT_CharMapRec charmap; 00490 T1_CMap_Classes cmap_classes = psaux->t1_cmap_classes; 00491 FT_CMap_Class clazz; 00492 00493 00494 charmap.face = root; 00495 00496 /* first of all, try to synthesize a Unicode charmap */ 00497 charmap.platform_id = TT_PLATFORM_MICROSOFT; 00498 charmap.encoding_id = TT_MS_ID_UNICODE_CS; 00499 charmap.encoding = FT_ENCODING_UNICODE; 00500 00501 error = FT_CMap_New( cmap_classes->unicode, NULL, &charmap, NULL ); 00502 if ( error && FT_Err_No_Unicode_Glyph_Name != error ) 00503 goto Exit; 00504 error = FT_Err_Ok; 00505 00506 /* now, generate an Adobe Standard encoding when appropriate */ 00507 charmap.platform_id = TT_PLATFORM_ADOBE; 00508 clazz = NULL; 00509 00510 switch ( type1->encoding_type ) 00511 { 00512 case T1_ENCODING_TYPE_STANDARD: 00513 charmap.encoding = FT_ENCODING_ADOBE_STANDARD; 00514 charmap.encoding_id = TT_ADOBE_ID_STANDARD; 00515 clazz = cmap_classes->standard; 00516 break; 00517 00518 case T1_ENCODING_TYPE_EXPERT: 00519 charmap.encoding = FT_ENCODING_ADOBE_EXPERT; 00520 charmap.encoding_id = TT_ADOBE_ID_EXPERT; 00521 clazz = cmap_classes->expert; 00522 break; 00523 00524 case T1_ENCODING_TYPE_ARRAY: 00525 charmap.encoding = FT_ENCODING_ADOBE_CUSTOM; 00526 charmap.encoding_id = TT_ADOBE_ID_CUSTOM; 00527 clazz = cmap_classes->custom; 00528 break; 00529 00530 case T1_ENCODING_TYPE_ISOLATIN1: 00531 charmap.encoding = FT_ENCODING_ADOBE_LATIN_1; 00532 charmap.encoding_id = TT_ADOBE_ID_LATIN_1; 00533 clazz = cmap_classes->unicode; 00534 break; 00535 00536 default: 00537 ; 00538 } 00539 00540 if ( clazz ) 00541 error = FT_CMap_New( clazz, NULL, &charmap, NULL ); 00542 00543 #if 0 00544 /* Select default charmap */ 00545 if (root->num_charmaps) 00546 root->charmap = root->charmaps[0]; 00547 #endif 00548 } 00549 } 00550 00551 Exit: 00552 return error; 00553 } 00554 00555 00556 /*************************************************************************/ 00557 /* */ 00558 /* <Function> */ 00559 /* T1_Driver_Init */ 00560 /* */ 00561 /* <Description> */ 00562 /* Initializes a given Type 1 driver object. */ 00563 /* */ 00564 /* <Input> */ 00565 /* driver :: A handle to the target driver object. */ 00566 /* */ 00567 /* <Return> */ 00568 /* FreeType error code. 0 means success. */ 00569 /* */ 00570 FT_LOCAL_DEF( FT_Error ) 00571 T1_Driver_Init( T1_Driver driver ) 00572 { 00573 FT_UNUSED( driver ); 00574 00575 return T1_Err_Ok; 00576 } 00577 00578 00579 /*************************************************************************/ 00580 /* */ 00581 /* <Function> */ 00582 /* T1_Driver_Done */ 00583 /* */ 00584 /* <Description> */ 00585 /* Finalizes a given Type 1 driver. */ 00586 /* */ 00587 /* <Input> */ 00588 /* driver :: A handle to the target Type 1 driver. */ 00589 /* */ 00590 FT_LOCAL_DEF( void ) 00591 T1_Driver_Done( T1_Driver driver ) 00592 { 00593 FT_UNUSED( driver ); 00594 } 00595 00596 00597 /* END */ Generated on Fri May 25 2012 04:32:35 for ReactOS by
1.7.6.1
|