Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenbdfdrivr.c
Go to the documentation of this file.
00001 /* bdfdrivr.c 00002 00003 FreeType font driver for bdf files 00004 00005 Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by 00006 Francesco Zappa Nardelli 00007 00008 Permission is hereby granted, free of charge, to any person obtaining a copy 00009 of this software and associated documentation files (the "Software"), to deal 00010 in the Software without restriction, including without limitation the rights 00011 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00012 copies of the Software, and to permit persons to whom the Software is 00013 furnished to do so, subject to the following conditions: 00014 00015 The above copyright notice and this permission notice shall be included in 00016 all copies or substantial portions of the Software. 00017 00018 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00019 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00020 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00021 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00022 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00023 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00024 THE SOFTWARE. 00025 */ 00026 00027 #include <ft2build.h> 00028 00029 #include FT_INTERNAL_DEBUG_H 00030 #include FT_INTERNAL_STREAM_H 00031 #include FT_INTERNAL_OBJECTS_H 00032 #include FT_BDF_H 00033 #include FT_TRUETYPE_IDS_H 00034 00035 #include FT_SERVICE_BDF_H 00036 #include FT_SERVICE_XFREE86_NAME_H 00037 00038 #include "bdf.h" 00039 #include "bdfdrivr.h" 00040 00041 #include "bdferror.h" 00042 00043 00044 /*************************************************************************/ 00045 /* */ 00046 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 00047 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 00048 /* messages during execution. */ 00049 /* */ 00050 #undef FT_COMPONENT 00051 #define FT_COMPONENT trace_bdfdriver 00052 00053 00054 typedef struct BDF_CMapRec_ 00055 { 00056 FT_CMapRec cmap; 00057 FT_ULong num_encodings; /* ftobjs.h: FT_CMap->clazz->size */ 00058 BDF_encoding_el* encodings; 00059 00060 } BDF_CMapRec, *BDF_CMap; 00061 00062 00063 FT_CALLBACK_DEF( FT_Error ) 00064 bdf_cmap_init( FT_CMap bdfcmap, 00065 FT_Pointer init_data ) 00066 { 00067 BDF_CMap cmap = (BDF_CMap)bdfcmap; 00068 BDF_Face face = (BDF_Face)FT_CMAP_FACE( cmap ); 00069 FT_UNUSED( init_data ); 00070 00071 00072 cmap->num_encodings = face->bdffont->glyphs_used; 00073 cmap->encodings = face->en_table; 00074 00075 return BDF_Err_Ok; 00076 } 00077 00078 00079 FT_CALLBACK_DEF( void ) 00080 bdf_cmap_done( FT_CMap bdfcmap ) 00081 { 00082 BDF_CMap cmap = (BDF_CMap)bdfcmap; 00083 00084 00085 cmap->encodings = NULL; 00086 cmap->num_encodings = 0; 00087 } 00088 00089 00090 FT_CALLBACK_DEF( FT_UInt ) 00091 bdf_cmap_char_index( FT_CMap bdfcmap, 00092 FT_UInt32 charcode ) 00093 { 00094 BDF_CMap cmap = (BDF_CMap)bdfcmap; 00095 BDF_encoding_el* encodings = cmap->encodings; 00096 FT_ULong min, max, mid; /* num_encodings */ 00097 FT_UShort result = 0; /* encodings->glyph */ 00098 00099 00100 min = 0; 00101 max = cmap->num_encodings; 00102 00103 while ( min < max ) 00104 { 00105 FT_ULong code; 00106 00107 00108 mid = ( min + max ) >> 1; 00109 code = encodings[mid].enc; 00110 00111 if ( charcode == code ) 00112 { 00113 /* increase glyph index by 1 -- */ 00114 /* we reserve slot 0 for the undefined glyph */ 00115 result = encodings[mid].glyph + 1; 00116 break; 00117 } 00118 00119 if ( charcode < code ) 00120 max = mid; 00121 else 00122 min = mid + 1; 00123 } 00124 00125 return result; 00126 } 00127 00128 00129 FT_CALLBACK_DEF( FT_UInt ) 00130 bdf_cmap_char_next( FT_CMap bdfcmap, 00131 FT_UInt32 *acharcode ) 00132 { 00133 BDF_CMap cmap = (BDF_CMap)bdfcmap; 00134 BDF_encoding_el* encodings = cmap->encodings; 00135 FT_ULong min, max, mid; /* num_encodings */ 00136 FT_UShort result = 0; /* encodings->glyph */ 00137 FT_ULong charcode = *acharcode + 1; 00138 00139 00140 min = 0; 00141 max = cmap->num_encodings; 00142 00143 while ( min < max ) 00144 { 00145 FT_ULong code; /* same as BDF_encoding_el.enc */ 00146 00147 00148 mid = ( min + max ) >> 1; 00149 code = encodings[mid].enc; 00150 00151 if ( charcode == code ) 00152 { 00153 /* increase glyph index by 1 -- */ 00154 /* we reserve slot 0 for the undefined glyph */ 00155 result = encodings[mid].glyph + 1; 00156 goto Exit; 00157 } 00158 00159 if ( charcode < code ) 00160 max = mid; 00161 else 00162 min = mid + 1; 00163 } 00164 00165 charcode = 0; 00166 if ( min < cmap->num_encodings ) 00167 { 00168 charcode = encodings[min].enc; 00169 result = encodings[min].glyph + 1; 00170 } 00171 00172 Exit: 00173 if ( charcode > 0xFFFFFFFFUL ) 00174 { 00175 FT_TRACE1(( "bdf_cmap_char_next: charcode 0x%x > 32bit API" )); 00176 *acharcode = 0; 00177 /* XXX: result should be changed to indicate an overflow error */ 00178 } 00179 else 00180 *acharcode = (FT_UInt32)charcode; 00181 return result; 00182 } 00183 00184 00185 FT_CALLBACK_TABLE_DEF 00186 const FT_CMap_ClassRec bdf_cmap_class = 00187 { 00188 sizeof ( BDF_CMapRec ), 00189 bdf_cmap_init, 00190 bdf_cmap_done, 00191 bdf_cmap_char_index, 00192 bdf_cmap_char_next, 00193 00194 NULL, NULL, NULL, NULL, NULL 00195 }; 00196 00197 00198 static FT_Error 00199 bdf_interpret_style( BDF_Face bdf ) 00200 { 00201 FT_Error error = BDF_Err_Ok; 00202 FT_Face face = FT_FACE( bdf ); 00203 FT_Memory memory = face->memory; 00204 bdf_font_t* font = bdf->bdffont; 00205 bdf_property_t* prop; 00206 00207 char* strings[4] = { NULL, NULL, NULL, NULL }; 00208 size_t nn, len, lengths[4]; 00209 00210 00211 face->style_flags = 0; 00212 00213 prop = bdf_get_font_property( font, (char *)"SLANT" ); 00214 if ( prop && prop->format == BDF_ATOM && 00215 prop->value.atom && 00216 ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' || 00217 *(prop->value.atom) == 'I' || *(prop->value.atom) == 'i' ) ) 00218 { 00219 face->style_flags |= FT_STYLE_FLAG_ITALIC; 00220 strings[2] = ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' ) 00221 ? (char *)"Oblique" 00222 : (char *)"Italic"; 00223 } 00224 00225 prop = bdf_get_font_property( font, (char *)"WEIGHT_NAME" ); 00226 if ( prop && prop->format == BDF_ATOM && 00227 prop->value.atom && 00228 ( *(prop->value.atom) == 'B' || *(prop->value.atom) == 'b' ) ) 00229 { 00230 face->style_flags |= FT_STYLE_FLAG_BOLD; 00231 strings[1] = (char *)"Bold"; 00232 } 00233 00234 prop = bdf_get_font_property( font, (char *)"SETWIDTH_NAME" ); 00235 if ( prop && prop->format == BDF_ATOM && 00236 prop->value.atom && *(prop->value.atom) && 00237 !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) ) 00238 strings[3] = (char *)(prop->value.atom); 00239 00240 prop = bdf_get_font_property( font, (char *)"ADD_STYLE_NAME" ); 00241 if ( prop && prop->format == BDF_ATOM && 00242 prop->value.atom && *(prop->value.atom) && 00243 !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) ) 00244 strings[0] = (char *)(prop->value.atom); 00245 00246 len = 0; 00247 00248 for ( len = 0, nn = 0; nn < 4; nn++ ) 00249 { 00250 lengths[nn] = 0; 00251 if ( strings[nn] ) 00252 { 00253 lengths[nn] = ft_strlen( strings[nn] ); 00254 len += lengths[nn] + 1; 00255 } 00256 } 00257 00258 if ( len == 0 ) 00259 { 00260 strings[0] = (char *)"Regular"; 00261 lengths[0] = ft_strlen( strings[0] ); 00262 len = lengths[0] + 1; 00263 } 00264 00265 { 00266 char* s; 00267 00268 00269 if ( FT_ALLOC( face->style_name, len ) ) 00270 return error; 00271 00272 s = face->style_name; 00273 00274 for ( nn = 0; nn < 4; nn++ ) 00275 { 00276 char* src = strings[nn]; 00277 00278 00279 len = lengths[nn]; 00280 00281 if ( src == NULL ) 00282 continue; 00283 00284 /* separate elements with a space */ 00285 if ( s != face->style_name ) 00286 *s++ = ' '; 00287 00288 ft_memcpy( s, src, len ); 00289 00290 /* need to convert spaces to dashes for */ 00291 /* add_style_name and setwidth_name */ 00292 if ( nn == 0 || nn == 3 ) 00293 { 00294 size_t mm; 00295 00296 00297 for ( mm = 0; mm < len; mm++ ) 00298 if ( s[mm] == ' ' ) 00299 s[mm] = '-'; 00300 } 00301 00302 s += len; 00303 } 00304 *s = 0; 00305 } 00306 00307 return error; 00308 } 00309 00310 00311 FT_CALLBACK_DEF( void ) 00312 BDF_Face_Done( FT_Face bdfface ) /* BDF_Face */ 00313 { 00314 BDF_Face face = (BDF_Face)bdfface; 00315 FT_Memory memory; 00316 00317 00318 if ( !face ) 00319 return; 00320 00321 memory = FT_FACE_MEMORY( face ); 00322 00323 bdf_free_font( face->bdffont ); 00324 00325 FT_FREE( face->en_table ); 00326 00327 FT_FREE( face->charset_encoding ); 00328 FT_FREE( face->charset_registry ); 00329 FT_FREE( bdfface->family_name ); 00330 FT_FREE( bdfface->style_name ); 00331 00332 FT_FREE( bdfface->available_sizes ); 00333 00334 FT_FREE( face->bdffont ); 00335 00336 FT_TRACE4(( "BDF_Face_Done: done face\n" )); 00337 } 00338 00339 00340 FT_CALLBACK_DEF( FT_Error ) 00341 BDF_Face_Init( FT_Stream stream, 00342 FT_Face bdfface, /* BDF_Face */ 00343 FT_Int face_index, 00344 FT_Int num_params, 00345 FT_Parameter* params ) 00346 { 00347 FT_Error error = BDF_Err_Ok; 00348 BDF_Face face = (BDF_Face)bdfface; 00349 FT_Memory memory = FT_FACE_MEMORY( face ); 00350 00351 bdf_font_t* font = NULL; 00352 bdf_options_t options; 00353 00354 FT_UNUSED( num_params ); 00355 FT_UNUSED( params ); 00356 FT_UNUSED( face_index ); 00357 00358 00359 if ( FT_STREAM_SEEK( 0 ) ) 00360 goto Exit; 00361 00362 options.correct_metrics = 1; /* FZ XXX: options semantics */ 00363 options.keep_unencoded = 1; 00364 options.keep_comments = 0; 00365 options.font_spacing = BDF_PROPORTIONAL; 00366 00367 error = bdf_load_font( stream, memory, &options, &font ); 00368 if ( error == BDF_Err_Missing_Startfont_Field ) 00369 { 00370 FT_TRACE2(( "[not a valid BDF file]\n" )); 00371 goto Fail; 00372 } 00373 else if ( error ) 00374 goto Exit; 00375 00376 /* we have a bdf font: let's construct the face object */ 00377 face->bdffont = font; 00378 { 00379 bdf_property_t* prop = NULL; 00380 00381 00382 FT_TRACE4(( "number of glyphs: %d (%d)\n", 00383 font->glyphs_size, 00384 font->glyphs_used )); 00385 FT_TRACE4(( "number of unencoded glyphs: %d (%d)\n", 00386 font->unencoded_size, 00387 font->unencoded_used )); 00388 00389 bdfface->num_faces = 1; 00390 bdfface->face_index = 0; 00391 bdfface->face_flags = FT_FACE_FLAG_FIXED_SIZES | 00392 FT_FACE_FLAG_HORIZONTAL | 00393 FT_FACE_FLAG_FAST_GLYPHS; 00394 00395 prop = bdf_get_font_property( font, "SPACING" ); 00396 if ( prop && prop->format == BDF_ATOM && 00397 prop->value.atom && 00398 ( *(prop->value.atom) == 'M' || *(prop->value.atom) == 'm' || 00399 *(prop->value.atom) == 'C' || *(prop->value.atom) == 'c' ) ) 00400 bdfface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; 00401 00402 /* FZ XXX: TO DO: FT_FACE_FLAGS_VERTICAL */ 00403 /* FZ XXX: I need a font to implement this */ 00404 00405 prop = bdf_get_font_property( font, "FAMILY_NAME" ); 00406 if ( prop && prop->value.atom ) 00407 { 00408 if ( FT_STRDUP( bdfface->family_name, prop->value.atom ) ) 00409 goto Exit; 00410 } 00411 else 00412 bdfface->family_name = 0; 00413 00414 if ( ( error = bdf_interpret_style( face ) ) != 0 ) 00415 goto Exit; 00416 00417 /* the number of glyphs (with one slot for the undefined glyph */ 00418 /* at position 0 and all unencoded glyphs) */ 00419 bdfface->num_glyphs = font->glyphs_size + 1; 00420 00421 bdfface->num_fixed_sizes = 1; 00422 if ( FT_NEW_ARRAY( bdfface->available_sizes, 1 ) ) 00423 goto Exit; 00424 00425 { 00426 FT_Bitmap_Size* bsize = bdfface->available_sizes; 00427 FT_Short resolution_x = 0, resolution_y = 0; 00428 00429 00430 FT_MEM_ZERO( bsize, sizeof ( FT_Bitmap_Size ) ); 00431 00432 bsize->height = (FT_Short)( font->font_ascent + font->font_descent ); 00433 00434 prop = bdf_get_font_property( font, "AVERAGE_WIDTH" ); 00435 if ( prop ) 00436 bsize->width = (FT_Short)( ( prop->value.l + 5 ) / 10 ); 00437 else 00438 bsize->width = (FT_Short)( bsize->height * 2/3 ); 00439 00440 prop = bdf_get_font_property( font, "POINT_SIZE" ); 00441 if ( prop ) 00442 /* convert from 722.7 decipoints to 72 points per inch */ 00443 bsize->size = 00444 (FT_Pos)( ( prop->value.l * 64 * 7200 + 36135L ) / 72270L ); 00445 else 00446 bsize->size = bsize->width << 6; 00447 00448 prop = bdf_get_font_property( font, "PIXEL_SIZE" ); 00449 if ( prop ) 00450 bsize->y_ppem = (FT_Short)prop->value.l << 6; 00451 00452 prop = bdf_get_font_property( font, "RESOLUTION_X" ); 00453 if ( prop ) 00454 resolution_x = (FT_Short)prop->value.l; 00455 00456 prop = bdf_get_font_property( font, "RESOLUTION_Y" ); 00457 if ( prop ) 00458 resolution_y = (FT_Short)prop->value.l; 00459 00460 if ( bsize->y_ppem == 0 ) 00461 { 00462 bsize->y_ppem = bsize->size; 00463 if ( resolution_y ) 00464 bsize->y_ppem = bsize->y_ppem * resolution_y / 72; 00465 } 00466 if ( resolution_x && resolution_y ) 00467 bsize->x_ppem = bsize->y_ppem * resolution_x / resolution_y; 00468 else 00469 bsize->x_ppem = bsize->y_ppem; 00470 } 00471 00472 /* encoding table */ 00473 { 00474 bdf_glyph_t* cur = font->glyphs; 00475 unsigned long n; 00476 00477 00478 if ( FT_NEW_ARRAY( face->en_table, font->glyphs_size ) ) 00479 goto Exit; 00480 00481 face->default_glyph = 0; 00482 for ( n = 0; n < font->glyphs_size; n++ ) 00483 { 00484 (face->en_table[n]).enc = cur[n].encoding; 00485 FT_TRACE4(( "idx %d, val 0x%lX\n", n, cur[n].encoding )); 00486 (face->en_table[n]).glyph = (FT_Short)n; 00487 00488 if ( cur[n].encoding == font->default_char ) 00489 { 00490 if ( n < FT_UINT_MAX ) 00491 face->default_glyph = (FT_UInt)n; 00492 else 00493 FT_TRACE1(( "idx %d is too large for this system\n", n )); 00494 } 00495 } 00496 } 00497 00498 /* charmaps */ 00499 { 00500 bdf_property_t *charset_registry = 0, *charset_encoding = 0; 00501 FT_Bool unicode_charmap = 0; 00502 00503 00504 charset_registry = 00505 bdf_get_font_property( font, "CHARSET_REGISTRY" ); 00506 charset_encoding = 00507 bdf_get_font_property( font, "CHARSET_ENCODING" ); 00508 if ( charset_registry && charset_encoding ) 00509 { 00510 if ( charset_registry->format == BDF_ATOM && 00511 charset_encoding->format == BDF_ATOM && 00512 charset_registry->value.atom && 00513 charset_encoding->value.atom ) 00514 { 00515 const char* s; 00516 00517 00518 if ( FT_STRDUP( face->charset_encoding, 00519 charset_encoding->value.atom ) || 00520 FT_STRDUP( face->charset_registry, 00521 charset_registry->value.atom ) ) 00522 goto Exit; 00523 00524 /* Uh, oh, compare first letters manually to avoid dependency */ 00525 /* on locales. */ 00526 s = face->charset_registry; 00527 if ( ( s[0] == 'i' || s[0] == 'I' ) && 00528 ( s[1] == 's' || s[1] == 'S' ) && 00529 ( s[2] == 'o' || s[2] == 'O' ) ) 00530 { 00531 s += 3; 00532 if ( !ft_strcmp( s, "10646" ) || 00533 ( !ft_strcmp( s, "8859" ) && 00534 !ft_strcmp( face->charset_encoding, "1" ) ) ) 00535 unicode_charmap = 1; 00536 } 00537 00538 { 00539 FT_CharMapRec charmap; 00540 00541 00542 charmap.face = FT_FACE( face ); 00543 charmap.encoding = FT_ENCODING_NONE; 00544 /* initial platform/encoding should indicate unset status? */ 00545 charmap.platform_id = TT_PLATFORM_APPLE_UNICODE; 00546 charmap.encoding_id = TT_APPLE_ID_DEFAULT; 00547 00548 if ( unicode_charmap ) 00549 { 00550 charmap.encoding = FT_ENCODING_UNICODE; 00551 charmap.platform_id = TT_PLATFORM_MICROSOFT; 00552 charmap.encoding_id = TT_MS_ID_UNICODE_CS; 00553 } 00554 00555 error = FT_CMap_New( &bdf_cmap_class, NULL, &charmap, NULL ); 00556 00557 #if 0 00558 /* Select default charmap */ 00559 if ( bdfface->num_charmaps ) 00560 bdfface->charmap = bdfface->charmaps[0]; 00561 #endif 00562 } 00563 00564 goto Exit; 00565 } 00566 } 00567 00568 /* otherwise assume Adobe standard encoding */ 00569 00570 { 00571 FT_CharMapRec charmap; 00572 00573 00574 charmap.face = FT_FACE( face ); 00575 charmap.encoding = FT_ENCODING_ADOBE_STANDARD; 00576 charmap.platform_id = TT_PLATFORM_ADOBE; 00577 charmap.encoding_id = TT_ADOBE_ID_STANDARD; 00578 00579 error = FT_CMap_New( &bdf_cmap_class, NULL, &charmap, NULL ); 00580 00581 /* Select default charmap */ 00582 if ( bdfface->num_charmaps ) 00583 bdfface->charmap = bdfface->charmaps[0]; 00584 } 00585 } 00586 } 00587 00588 Exit: 00589 return error; 00590 00591 Fail: 00592 BDF_Face_Done( bdfface ); 00593 return BDF_Err_Unknown_File_Format; 00594 } 00595 00596 00597 FT_CALLBACK_DEF( FT_Error ) 00598 BDF_Size_Select( FT_Size size, 00599 FT_ULong strike_index ) 00600 { 00601 bdf_font_t* bdffont = ( (BDF_Face)size->face )->bdffont; 00602 00603 00604 FT_Select_Metrics( size->face, strike_index ); 00605 00606 size->metrics.ascender = bdffont->font_ascent << 6; 00607 size->metrics.descender = -bdffont->font_descent << 6; 00608 size->metrics.max_advance = bdffont->bbx.width << 6; 00609 00610 return BDF_Err_Ok; 00611 } 00612 00613 00614 FT_CALLBACK_DEF( FT_Error ) 00615 BDF_Size_Request( FT_Size size, 00616 FT_Size_Request req ) 00617 { 00618 FT_Face face = size->face; 00619 FT_Bitmap_Size* bsize = face->available_sizes; 00620 bdf_font_t* bdffont = ( (BDF_Face)face )->bdffont; 00621 FT_Error error = BDF_Err_Invalid_Pixel_Size; 00622 FT_Long height; 00623 00624 00625 height = FT_REQUEST_HEIGHT( req ); 00626 height = ( height + 32 ) >> 6; 00627 00628 switch ( req->type ) 00629 { 00630 case FT_SIZE_REQUEST_TYPE_NOMINAL: 00631 if ( height == ( ( bsize->y_ppem + 32 ) >> 6 ) ) 00632 error = BDF_Err_Ok; 00633 break; 00634 00635 case FT_SIZE_REQUEST_TYPE_REAL_DIM: 00636 if ( height == ( bdffont->font_ascent + 00637 bdffont->font_descent ) ) 00638 error = BDF_Err_Ok; 00639 break; 00640 00641 default: 00642 error = BDF_Err_Unimplemented_Feature; 00643 break; 00644 } 00645 00646 if ( error ) 00647 return error; 00648 else 00649 return BDF_Size_Select( size, 0 ); 00650 } 00651 00652 00653 00654 FT_CALLBACK_DEF( FT_Error ) 00655 BDF_Glyph_Load( FT_GlyphSlot slot, 00656 FT_Size size, 00657 FT_UInt glyph_index, 00658 FT_Int32 load_flags ) 00659 { 00660 BDF_Face bdf = (BDF_Face)FT_SIZE_FACE( size ); 00661 FT_Face face = FT_FACE( bdf ); 00662 FT_Error error = BDF_Err_Ok; 00663 FT_Bitmap* bitmap = &slot->bitmap; 00664 bdf_glyph_t glyph; 00665 int bpp = bdf->bdffont->bpp; 00666 00667 FT_UNUSED( load_flags ); 00668 00669 00670 if ( !face || glyph_index >= (FT_UInt)face->num_glyphs ) 00671 { 00672 error = BDF_Err_Invalid_Argument; 00673 goto Exit; 00674 } 00675 00676 /* index 0 is the undefined glyph */ 00677 if ( glyph_index == 0 ) 00678 glyph_index = bdf->default_glyph; 00679 else 00680 glyph_index--; 00681 00682 /* slot, bitmap => freetype, glyph => bdflib */ 00683 glyph = bdf->bdffont->glyphs[glyph_index]; 00684 00685 bitmap->rows = glyph.bbx.height; 00686 bitmap->width = glyph.bbx.width; 00687 if ( glyph.bpr > INT_MAX ) 00688 FT_TRACE1(( "BDF_Glyph_Load: too large pitch %d is truncated\n", 00689 glyph.bpr )); 00690 bitmap->pitch = (int)glyph.bpr; /* same as FT_Bitmap.pitch */ 00691 00692 /* note: we don't allocate a new array to hold the bitmap; */ 00693 /* we can simply point to it */ 00694 ft_glyphslot_set_bitmap( slot, glyph.bitmap ); 00695 00696 switch ( bpp ) 00697 { 00698 case 1: 00699 bitmap->pixel_mode = FT_PIXEL_MODE_MONO; 00700 break; 00701 case 2: 00702 bitmap->pixel_mode = FT_PIXEL_MODE_GRAY2; 00703 break; 00704 case 4: 00705 bitmap->pixel_mode = FT_PIXEL_MODE_GRAY4; 00706 break; 00707 case 8: 00708 bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; 00709 bitmap->num_grays = 256; 00710 break; 00711 } 00712 00713 slot->format = FT_GLYPH_FORMAT_BITMAP; 00714 slot->bitmap_left = glyph.bbx.x_offset; 00715 slot->bitmap_top = glyph.bbx.ascent; 00716 00717 slot->metrics.horiAdvance = glyph.dwidth << 6; 00718 slot->metrics.horiBearingX = glyph.bbx.x_offset << 6; 00719 slot->metrics.horiBearingY = glyph.bbx.ascent << 6; 00720 slot->metrics.width = bitmap->width << 6; 00721 slot->metrics.height = bitmap->rows << 6; 00722 00723 /* 00724 * XXX DWIDTH1 and VVECTOR should be parsed and 00725 * used here, provided such fonts do exist. 00726 */ 00727 ft_synthesize_vertical_metrics( &slot->metrics, 00728 bdf->bdffont->bbx.height << 6 ); 00729 00730 Exit: 00731 return error; 00732 } 00733 00734 00735 /* 00736 * 00737 * BDF SERVICE 00738 * 00739 */ 00740 00741 static FT_Error 00742 bdf_get_bdf_property( BDF_Face face, 00743 const char* prop_name, 00744 BDF_PropertyRec *aproperty ) 00745 { 00746 bdf_property_t* prop; 00747 00748 00749 FT_ASSERT( face && face->bdffont ); 00750 00751 prop = bdf_get_font_property( face->bdffont, prop_name ); 00752 if ( prop ) 00753 { 00754 switch ( prop->format ) 00755 { 00756 case BDF_ATOM: 00757 aproperty->type = BDF_PROPERTY_TYPE_ATOM; 00758 aproperty->u.atom = prop->value.atom; 00759 break; 00760 00761 case BDF_INTEGER: 00762 if ( prop->value.l > 0x7FFFFFFFL || prop->value.l < ( -1 - 0x7FFFFFFFL ) ) 00763 { 00764 FT_TRACE1(( "bdf_get_bdf_property: " )); 00765 FT_TRACE1(( "too large integer 0x%x is truncated\n" )); 00766 } 00767 aproperty->type = BDF_PROPERTY_TYPE_INTEGER; 00768 aproperty->u.integer = (FT_Int32)prop->value.l; 00769 break; 00770 00771 case BDF_CARDINAL: 00772 if ( prop->value.ul > 0xFFFFFFFFUL ) 00773 { 00774 FT_TRACE1(( "bdf_get_bdf_property: " )); 00775 FT_TRACE1(( "too large cardinal 0x%x is truncated\n" )); 00776 } 00777 aproperty->type = BDF_PROPERTY_TYPE_CARDINAL; 00778 aproperty->u.cardinal = (FT_UInt32)prop->value.ul; 00779 break; 00780 00781 default: 00782 goto Fail; 00783 } 00784 return 0; 00785 } 00786 00787 Fail: 00788 return BDF_Err_Invalid_Argument; 00789 } 00790 00791 00792 static FT_Error 00793 bdf_get_charset_id( BDF_Face face, 00794 const char* *acharset_encoding, 00795 const char* *acharset_registry ) 00796 { 00797 *acharset_encoding = face->charset_encoding; 00798 *acharset_registry = face->charset_registry; 00799 00800 return 0; 00801 } 00802 00803 00804 static const FT_Service_BDFRec bdf_service_bdf = 00805 { 00806 (FT_BDF_GetCharsetIdFunc)bdf_get_charset_id, 00807 (FT_BDF_GetPropertyFunc) bdf_get_bdf_property 00808 }; 00809 00810 00811 /* 00812 * 00813 * SERVICES LIST 00814 * 00815 */ 00816 00817 static const FT_ServiceDescRec bdf_services[] = 00818 { 00819 { FT_SERVICE_ID_BDF, &bdf_service_bdf }, 00820 { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_BDF }, 00821 { NULL, NULL } 00822 }; 00823 00824 00825 FT_CALLBACK_DEF( FT_Module_Interface ) 00826 bdf_driver_requester( FT_Module module, 00827 const char* name ) 00828 { 00829 FT_UNUSED( module ); 00830 00831 return ft_service_list_lookup( bdf_services, name ); 00832 } 00833 00834 00835 00836 FT_CALLBACK_TABLE_DEF 00837 const FT_Driver_ClassRec bdf_driver_class = 00838 { 00839 { 00840 FT_MODULE_FONT_DRIVER | 00841 FT_MODULE_DRIVER_NO_OUTLINES, 00842 sizeof ( FT_DriverRec ), 00843 00844 "bdf", 00845 0x10000L, 00846 0x20000L, 00847 00848 0, 00849 00850 (FT_Module_Constructor)0, 00851 (FT_Module_Destructor) 0, 00852 (FT_Module_Requester) bdf_driver_requester 00853 }, 00854 00855 sizeof ( BDF_FaceRec ), 00856 sizeof ( FT_SizeRec ), 00857 sizeof ( FT_GlyphSlotRec ), 00858 00859 BDF_Face_Init, 00860 BDF_Face_Done, 00861 0, /* FT_Size_InitFunc */ 00862 0, /* FT_Size_DoneFunc */ 00863 0, /* FT_Slot_InitFunc */ 00864 0, /* FT_Slot_DoneFunc */ 00865 00866 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS 00867 ft_stub_set_char_sizes, 00868 ft_stub_set_pixel_sizes, 00869 #endif 00870 BDF_Glyph_Load, 00871 00872 0, /* FT_Face_GetKerningFunc */ 00873 0, /* FT_Face_AttachFunc */ 00874 0, /* FT_Face_GetAdvancesFunc */ 00875 00876 BDF_Size_Request, 00877 BDF_Size_Select 00878 }; 00879 00880 00881 /* END */ Generated on Sat May 26 2012 04:32:39 for ReactOS by
1.7.6.1
|