Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygent1gload.c
Go to the documentation of this file.
00001 /***************************************************************************/ 00002 /* */ 00003 /* t1gload.c */ 00004 /* */ 00005 /* Type 1 Glyph Loader (body). */ 00006 /* */ 00007 /* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010 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 "t1gload.h" 00021 #include FT_INTERNAL_CALC_H 00022 #include FT_INTERNAL_DEBUG_H 00023 #include FT_INTERNAL_STREAM_H 00024 #include FT_OUTLINE_H 00025 #include FT_INTERNAL_POSTSCRIPT_AUX_H 00026 00027 #include "t1errors.h" 00028 00029 00030 /*************************************************************************/ 00031 /* */ 00032 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 00033 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 00034 /* messages during execution. */ 00035 /* */ 00036 #undef FT_COMPONENT 00037 #define FT_COMPONENT trace_t1gload 00038 00039 00040 /*************************************************************************/ 00041 /*************************************************************************/ 00042 /*************************************************************************/ 00043 /********** *********/ 00044 /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/ 00045 /********** *********/ 00046 /********** The following code is in charge of computing *********/ 00047 /********** the maximum advance width of the font. It *********/ 00048 /********** quickly processes each glyph charstring to *********/ 00049 /********** extract the value from either a `sbw' or `seac' *********/ 00050 /********** operator. *********/ 00051 /********** *********/ 00052 /*************************************************************************/ 00053 /*************************************************************************/ 00054 /*************************************************************************/ 00055 00056 00057 FT_LOCAL_DEF( FT_Error ) 00058 T1_Parse_Glyph_And_Get_Char_String( T1_Decoder decoder, 00059 FT_UInt glyph_index, 00060 FT_Data* char_string ) 00061 { 00062 T1_Face face = (T1_Face)decoder->builder.face; 00063 T1_Font type1 = &face->type1; 00064 FT_Error error = T1_Err_Ok; 00065 00066 #ifdef FT_CONFIG_OPTION_INCREMENTAL 00067 FT_Incremental_InterfaceRec *inc = 00068 face->root.internal->incremental_interface; 00069 #endif 00070 00071 00072 decoder->font_matrix = type1->font_matrix; 00073 decoder->font_offset = type1->font_offset; 00074 00075 #ifdef FT_CONFIG_OPTION_INCREMENTAL 00076 00077 /* For incremental fonts get the character data using the */ 00078 /* callback function. */ 00079 if ( inc ) 00080 error = inc->funcs->get_glyph_data( inc->object, 00081 glyph_index, char_string ); 00082 else 00083 00084 #endif /* FT_CONFIG_OPTION_INCREMENTAL */ 00085 00086 /* For ordinary fonts get the character data stored in the face record. */ 00087 { 00088 char_string->pointer = type1->charstrings[glyph_index]; 00089 char_string->length = (FT_Int)type1->charstrings_len[glyph_index]; 00090 } 00091 00092 if ( !error ) 00093 error = decoder->funcs.parse_charstrings( 00094 decoder, (FT_Byte*)char_string->pointer, 00095 char_string->length ); 00096 00097 #ifdef FT_CONFIG_OPTION_INCREMENTAL 00098 00099 /* Incremental fonts can optionally override the metrics. */ 00100 if ( !error && inc && inc->funcs->get_glyph_metrics ) 00101 { 00102 FT_Incremental_MetricsRec metrics; 00103 00104 00105 metrics.bearing_x = FIXED_TO_INT( decoder->builder.left_bearing.x ); 00106 metrics.bearing_y = 0; 00107 metrics.advance = FIXED_TO_INT( decoder->builder.advance.x ); 00108 metrics.advance_v = FIXED_TO_INT( decoder->builder.advance.y ); 00109 00110 error = inc->funcs->get_glyph_metrics( inc->object, 00111 glyph_index, FALSE, &metrics ); 00112 00113 decoder->builder.left_bearing.x = INT_TO_FIXED( metrics.bearing_x ); 00114 decoder->builder.advance.x = INT_TO_FIXED( metrics.advance ); 00115 decoder->builder.advance.y = INT_TO_FIXED( metrics.advance_v ); 00116 } 00117 00118 #endif /* FT_CONFIG_OPTION_INCREMENTAL */ 00119 00120 return error; 00121 } 00122 00123 00124 FT_CALLBACK_DEF( FT_Error ) 00125 T1_Parse_Glyph( T1_Decoder decoder, 00126 FT_UInt glyph_index ) 00127 { 00128 FT_Data glyph_data; 00129 FT_Error error = T1_Parse_Glyph_And_Get_Char_String( 00130 decoder, glyph_index, &glyph_data ); 00131 00132 00133 #ifdef FT_CONFIG_OPTION_INCREMENTAL 00134 00135 if ( !error ) 00136 { 00137 T1_Face face = (T1_Face)decoder->builder.face; 00138 00139 00140 if ( face->root.internal->incremental_interface ) 00141 face->root.internal->incremental_interface->funcs->free_glyph_data( 00142 face->root.internal->incremental_interface->object, 00143 &glyph_data ); 00144 } 00145 00146 #endif /* FT_CONFIG_OPTION_INCREMENTAL */ 00147 00148 return error; 00149 } 00150 00151 00152 FT_LOCAL_DEF( FT_Error ) 00153 T1_Compute_Max_Advance( T1_Face face, 00154 FT_Pos* max_advance ) 00155 { 00156 FT_Error error; 00157 T1_DecoderRec decoder; 00158 FT_Int glyph_index; 00159 T1_Font type1 = &face->type1; 00160 PSAux_Service psaux = (PSAux_Service)face->psaux; 00161 00162 00163 FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) ); 00164 00165 *max_advance = 0; 00166 00167 /* initialize load decoder */ 00168 error = psaux->t1_decoder_funcs->init( &decoder, 00169 (FT_Face)face, 00170 0, /* size */ 00171 0, /* glyph slot */ 00172 (FT_Byte**)type1->glyph_names, 00173 face->blend, 00174 0, 00175 FT_RENDER_MODE_NORMAL, 00176 T1_Parse_Glyph ); 00177 if ( error ) 00178 return error; 00179 00180 decoder.builder.metrics_only = 1; 00181 decoder.builder.load_points = 0; 00182 00183 decoder.num_subrs = type1->num_subrs; 00184 decoder.subrs = type1->subrs; 00185 decoder.subrs_len = type1->subrs_len; 00186 00187 decoder.buildchar = face->buildchar; 00188 decoder.len_buildchar = face->len_buildchar; 00189 00190 *max_advance = 0; 00191 00192 /* for each glyph, parse the glyph charstring and extract */ 00193 /* the advance width */ 00194 for ( glyph_index = 0; glyph_index < type1->num_glyphs; glyph_index++ ) 00195 { 00196 /* now get load the unscaled outline */ 00197 error = T1_Parse_Glyph( &decoder, glyph_index ); 00198 if ( glyph_index == 0 || decoder.builder.advance.x > *max_advance ) 00199 *max_advance = decoder.builder.advance.x; 00200 00201 /* ignore the error if one occurred - skip to next glyph */ 00202 } 00203 00204 psaux->t1_decoder_funcs->done( &decoder ); 00205 00206 return T1_Err_Ok; 00207 } 00208 00209 00210 FT_LOCAL_DEF( FT_Error ) 00211 T1_Get_Advances( T1_Face face, 00212 FT_UInt first, 00213 FT_UInt count, 00214 FT_ULong load_flags, 00215 FT_Fixed* advances ) 00216 { 00217 T1_DecoderRec decoder; 00218 T1_Font type1 = &face->type1; 00219 PSAux_Service psaux = (PSAux_Service)face->psaux; 00220 FT_UInt nn; 00221 FT_Error error; 00222 00223 00224 if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) 00225 { 00226 for ( nn = 0; nn < count; nn++ ) 00227 advances[nn] = 0; 00228 00229 return T1_Err_Ok; 00230 } 00231 00232 error = psaux->t1_decoder_funcs->init( &decoder, 00233 (FT_Face)face, 00234 0, /* size */ 00235 0, /* glyph slot */ 00236 (FT_Byte**)type1->glyph_names, 00237 face->blend, 00238 0, 00239 FT_RENDER_MODE_NORMAL, 00240 T1_Parse_Glyph ); 00241 if ( error ) 00242 return error; 00243 00244 decoder.builder.metrics_only = 1; 00245 decoder.builder.load_points = 0; 00246 00247 decoder.num_subrs = type1->num_subrs; 00248 decoder.subrs = type1->subrs; 00249 decoder.subrs_len = type1->subrs_len; 00250 00251 decoder.buildchar = face->buildchar; 00252 decoder.len_buildchar = face->len_buildchar; 00253 00254 for ( nn = 0; nn < count; nn++ ) 00255 { 00256 error = T1_Parse_Glyph( &decoder, first + nn ); 00257 if ( !error ) 00258 advances[nn] = FIXED_TO_INT( decoder.builder.advance.x ); 00259 else 00260 advances[nn] = 0; 00261 } 00262 00263 return T1_Err_Ok; 00264 } 00265 00266 00267 FT_LOCAL_DEF( FT_Error ) 00268 T1_Load_Glyph( T1_GlyphSlot glyph, 00269 T1_Size size, 00270 FT_UInt glyph_index, 00271 FT_Int32 load_flags ) 00272 { 00273 FT_Error error; 00274 T1_DecoderRec decoder; 00275 T1_Face face = (T1_Face)glyph->root.face; 00276 FT_Bool hinting; 00277 T1_Font type1 = &face->type1; 00278 PSAux_Service psaux = (PSAux_Service)face->psaux; 00279 const T1_Decoder_Funcs decoder_funcs = psaux->t1_decoder_funcs; 00280 00281 FT_Matrix font_matrix; 00282 FT_Vector font_offset; 00283 FT_Data glyph_data; 00284 FT_Bool must_finish_decoder = FALSE; 00285 #ifdef FT_CONFIG_OPTION_INCREMENTAL 00286 FT_Bool glyph_data_loaded = 0; 00287 #endif 00288 00289 00290 #ifdef FT_CONFIG_OPTION_INCREMENTAL 00291 if ( glyph_index >= (FT_UInt)face->root.num_glyphs && 00292 !face->root.internal->incremental_interface ) 00293 #else 00294 if ( glyph_index >= (FT_UInt)face->root.num_glyphs ) 00295 #endif /* FT_CONFIG_OPTION_INCREMENTAL */ 00296 { 00297 error = T1_Err_Invalid_Argument; 00298 goto Exit; 00299 } 00300 00301 FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) ); 00302 00303 if ( load_flags & FT_LOAD_NO_RECURSE ) 00304 load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; 00305 00306 if ( size ) 00307 { 00308 glyph->x_scale = size->root.metrics.x_scale; 00309 glyph->y_scale = size->root.metrics.y_scale; 00310 } 00311 else 00312 { 00313 glyph->x_scale = 0x10000L; 00314 glyph->y_scale = 0x10000L; 00315 } 00316 00317 glyph->root.outline.n_points = 0; 00318 glyph->root.outline.n_contours = 0; 00319 00320 hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 && 00321 ( load_flags & FT_LOAD_NO_HINTING ) == 0 ); 00322 00323 glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; 00324 00325 error = decoder_funcs->init( &decoder, 00326 (FT_Face)face, 00327 (FT_Size)size, 00328 (FT_GlyphSlot)glyph, 00329 (FT_Byte**)type1->glyph_names, 00330 face->blend, 00331 FT_BOOL( hinting ), 00332 FT_LOAD_TARGET_MODE( load_flags ), 00333 T1_Parse_Glyph ); 00334 if ( error ) 00335 goto Exit; 00336 00337 must_finish_decoder = TRUE; 00338 00339 decoder.builder.no_recurse = FT_BOOL( 00340 ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ); 00341 00342 decoder.num_subrs = type1->num_subrs; 00343 decoder.subrs = type1->subrs; 00344 decoder.subrs_len = type1->subrs_len; 00345 00346 decoder.buildchar = face->buildchar; 00347 decoder.len_buildchar = face->len_buildchar; 00348 00349 /* now load the unscaled outline */ 00350 error = T1_Parse_Glyph_And_Get_Char_String( &decoder, glyph_index, 00351 &glyph_data ); 00352 if ( error ) 00353 goto Exit; 00354 #ifdef FT_CONFIG_OPTION_INCREMENTAL 00355 glyph_data_loaded = 1; 00356 #endif 00357 00358 font_matrix = decoder.font_matrix; 00359 font_offset = decoder.font_offset; 00360 00361 /* save new glyph tables */ 00362 decoder_funcs->done( &decoder ); 00363 00364 must_finish_decoder = FALSE; 00365 00366 /* now, set the metrics -- this is rather simple, as */ 00367 /* the left side bearing is the xMin, and the top side */ 00368 /* bearing the yMax */ 00369 if ( !error ) 00370 { 00371 glyph->root.outline.flags &= FT_OUTLINE_OWNER; 00372 glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL; 00373 00374 /* for composite glyphs, return only left side bearing and */ 00375 /* advance width */ 00376 if ( load_flags & FT_LOAD_NO_RECURSE ) 00377 { 00378 FT_Slot_Internal internal = glyph->root.internal; 00379 00380 00381 glyph->root.metrics.horiBearingX = 00382 FIXED_TO_INT( decoder.builder.left_bearing.x ); 00383 glyph->root.metrics.horiAdvance = 00384 FIXED_TO_INT( decoder.builder.advance.x ); 00385 00386 internal->glyph_matrix = font_matrix; 00387 internal->glyph_delta = font_offset; 00388 internal->glyph_transformed = 1; 00389 } 00390 else 00391 { 00392 FT_BBox cbox; 00393 FT_Glyph_Metrics* metrics = &glyph->root.metrics; 00394 FT_Vector advance; 00395 00396 00397 /* copy the _unscaled_ advance width */ 00398 metrics->horiAdvance = 00399 FIXED_TO_INT( decoder.builder.advance.x ); 00400 glyph->root.linearHoriAdvance = 00401 FIXED_TO_INT( decoder.builder.advance.x ); 00402 glyph->root.internal->glyph_transformed = 0; 00403 00404 if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) 00405 { 00406 /* make up vertical ones */ 00407 metrics->vertAdvance = ( face->type1.font_bbox.yMax - 00408 face->type1.font_bbox.yMin ) >> 16; 00409 glyph->root.linearVertAdvance = metrics->vertAdvance; 00410 } 00411 else 00412 { 00413 metrics->vertAdvance = 00414 FIXED_TO_INT( decoder.builder.advance.y ); 00415 glyph->root.linearVertAdvance = 00416 FIXED_TO_INT( decoder.builder.advance.y ); 00417 } 00418 00419 glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; 00420 00421 if ( size && size->root.metrics.y_ppem < 24 ) 00422 glyph->root.outline.flags |= FT_OUTLINE_HIGH_PRECISION; 00423 00424 #if 1 00425 /* apply the font matrix, if any */ 00426 if ( font_matrix.xx != 0x10000L || font_matrix.yy != font_matrix.xx || 00427 font_matrix.xy != 0 || font_matrix.yx != 0 ) 00428 FT_Outline_Transform( &glyph->root.outline, &font_matrix ); 00429 00430 if ( font_offset.x || font_offset.y ) 00431 FT_Outline_Translate( &glyph->root.outline, 00432 font_offset.x, 00433 font_offset.y ); 00434 00435 advance.x = metrics->horiAdvance; 00436 advance.y = 0; 00437 FT_Vector_Transform( &advance, &font_matrix ); 00438 metrics->horiAdvance = advance.x + font_offset.x; 00439 advance.x = 0; 00440 advance.y = metrics->vertAdvance; 00441 FT_Vector_Transform( &advance, &font_matrix ); 00442 metrics->vertAdvance = advance.y + font_offset.y; 00443 #endif 00444 00445 if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ) 00446 { 00447 /* scale the outline and the metrics */ 00448 FT_Int n; 00449 FT_Outline* cur = decoder.builder.base; 00450 FT_Vector* vec = cur->points; 00451 FT_Fixed x_scale = glyph->x_scale; 00452 FT_Fixed y_scale = glyph->y_scale; 00453 00454 00455 /* First of all, scale the points, if we are not hinting */ 00456 if ( !hinting || ! decoder.builder.hints_funcs ) 00457 for ( n = cur->n_points; n > 0; n--, vec++ ) 00458 { 00459 vec->x = FT_MulFix( vec->x, x_scale ); 00460 vec->y = FT_MulFix( vec->y, y_scale ); 00461 } 00462 00463 /* Then scale the metrics */ 00464 metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); 00465 metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); 00466 } 00467 00468 /* compute the other metrics */ 00469 FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); 00470 00471 metrics->width = cbox.xMax - cbox.xMin; 00472 metrics->height = cbox.yMax - cbox.yMin; 00473 00474 metrics->horiBearingX = cbox.xMin; 00475 metrics->horiBearingY = cbox.yMax; 00476 00477 if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) 00478 { 00479 /* make up vertical ones */ 00480 ft_synthesize_vertical_metrics( metrics, 00481 metrics->vertAdvance ); 00482 } 00483 } 00484 00485 /* Set control data to the glyph charstrings. Note that this is */ 00486 /* _not_ zero-terminated. */ 00487 glyph->root.control_data = (FT_Byte*)glyph_data.pointer; 00488 glyph->root.control_len = glyph_data.length; 00489 } 00490 00491 00492 Exit: 00493 00494 #ifdef FT_CONFIG_OPTION_INCREMENTAL 00495 if ( glyph_data_loaded && face->root.internal->incremental_interface ) 00496 { 00497 face->root.internal->incremental_interface->funcs->free_glyph_data( 00498 face->root.internal->incremental_interface->object, 00499 &glyph_data ); 00500 00501 /* Set the control data to null - it is no longer available if */ 00502 /* loaded incrementally. */ 00503 glyph->root.control_data = 0; 00504 glyph->root.control_len = 0; 00505 } 00506 #endif 00507 00508 if ( must_finish_decoder ) 00509 decoder_funcs->done( &decoder ); 00510 00511 return error; 00512 } 00513 00514 00515 /* END */ Generated on Sun May 27 2012 04:34:04 for ReactOS by
1.7.6.1
|