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

Generated on Tue Jul 5 14:13:44 2011 for ROOT_528-00b_version by  doxygen 1.5.1