ReactOS Fundraising Campaign 2012
 
€ 4,060 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

ttsbit0.c
Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  ttsbit0.c                                                              */
00004 /*                                                                         */
00005 /*    TrueType and OpenType embedded bitmap support (body).                */
00006 /*    This is a heap-optimized version.                                    */
00007 /*                                                                         */
00008 /*  Copyright 2005, 2006, 2007, 2008, 2009 by                              */
00009 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
00010 /*                                                                         */
00011 /*  This file is part of the FreeType project, and may only be used,       */
00012 /*  modified, and distributed under the terms of the FreeType project      */
00013 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
00014 /*  this file you indicate that you have read the license and              */
00015 /*  understand and accept it fully.                                        */
00016 /*                                                                         */
00017 /***************************************************************************/
00018 
00019 
00020 /* This file is included by ttsbit.c */
00021 
00022 
00023 #include <ft2build.h>
00024 #include FT_INTERNAL_DEBUG_H
00025 #include FT_INTERNAL_STREAM_H
00026 #include FT_TRUETYPE_TAGS_H
00027 #include "ttsbit.h"
00028 
00029 #include "sferrors.h"
00030 
00031 
00032   /*************************************************************************/
00033   /*                                                                       */
00034   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
00035   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
00036   /* messages during execution.                                            */
00037   /*                                                                       */
00038 #undef  FT_COMPONENT
00039 #define FT_COMPONENT  trace_ttsbit
00040 
00041 
00042   FT_LOCAL_DEF( FT_Error )
00043   tt_face_load_eblc( TT_Face    face,
00044                      FT_Stream  stream )
00045   {
00046     FT_Error  error = SFNT_Err_Ok;
00047     FT_Fixed  version;
00048     FT_ULong  num_strikes, table_size;
00049     FT_Byte*  p;
00050     FT_Byte*  p_limit;
00051     FT_UInt   count;
00052 
00053 
00054     face->sbit_num_strikes = 0;
00055 
00056     /* this table is optional */
00057     error = face->goto_table( face, TTAG_EBLC, stream, &table_size );
00058     if ( error )
00059       error = face->goto_table( face, TTAG_bloc, stream, &table_size );
00060     if ( error )
00061       goto Exit;
00062 
00063     if ( table_size < 8 )
00064     {
00065       FT_ERROR(( "tt_face_load_sbit_strikes: table too short\n" ));
00066       error = SFNT_Err_Invalid_File_Format;
00067       goto Exit;
00068     }
00069 
00070     if ( FT_FRAME_EXTRACT( table_size, face->sbit_table ) )
00071       goto Exit;
00072 
00073     face->sbit_table_size = table_size;
00074 
00075     p       = face->sbit_table;
00076     p_limit = p + table_size;
00077 
00078     version     = FT_NEXT_ULONG( p );
00079     num_strikes = FT_NEXT_ULONG( p );
00080 
00081     if ( version != 0x00020000UL || num_strikes >= 0x10000UL )
00082     {
00083       FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" ));
00084       error = SFNT_Err_Invalid_File_Format;
00085       goto Fail;
00086     }
00087 
00088     /*
00089      *  Count the number of strikes available in the table.  We are a bit
00090      *  paranoid there and don't trust the data.
00091      */
00092     count = (FT_UInt)num_strikes;
00093     if ( 8 + 48UL * count > table_size )
00094       count = (FT_UInt)( ( p_limit - p ) / 48 );
00095 
00096     face->sbit_num_strikes = count;
00097 
00098     FT_TRACE3(( "sbit_num_strikes: %u\n", count ));
00099   Exit:
00100     return error;
00101 
00102   Fail:
00103     FT_FRAME_RELEASE( face->sbit_table );
00104     face->sbit_table_size = 0;
00105     goto Exit;
00106   }
00107 
00108 
00109   FT_LOCAL_DEF( void )
00110   tt_face_free_eblc( TT_Face  face )
00111   {
00112     FT_Stream  stream = face->root.stream;
00113 
00114 
00115     FT_FRAME_RELEASE( face->sbit_table );
00116     face->sbit_table_size  = 0;
00117     face->sbit_num_strikes = 0;
00118   }
00119 
00120 
00121   FT_LOCAL_DEF( FT_Error )
00122   tt_face_set_sbit_strike( TT_Face          face,
00123                            FT_Size_Request  req,
00124                            FT_ULong*        astrike_index )
00125   {
00126     return FT_Match_Size( (FT_Face)face, req, 0, astrike_index );
00127   }
00128 
00129 
00130   FT_LOCAL_DEF( FT_Error )
00131   tt_face_load_strike_metrics( TT_Face           face,
00132                                FT_ULong          strike_index,
00133                                FT_Size_Metrics*  metrics )
00134   {
00135     FT_Byte*  strike;
00136 
00137 
00138     if ( strike_index >= (FT_ULong)face->sbit_num_strikes )
00139       return SFNT_Err_Invalid_Argument;
00140 
00141     strike = face->sbit_table + 8 + strike_index * 48;
00142 
00143     metrics->x_ppem = (FT_UShort)strike[44];
00144     metrics->y_ppem = (FT_UShort)strike[45];
00145 
00146     metrics->ascender  = (FT_Char)strike[16] << 6;  /* hori.ascender  */
00147     metrics->descender = (FT_Char)strike[17] << 6;  /* hori.descender */
00148     metrics->height    = metrics->ascender - metrics->descender;
00149 
00150     /* XXX: Is this correct? */
00151     metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB  */
00152                                       strike[18] + /* max_width      */
00153                              (FT_Char)strike[23]   /* min_advance_SB */
00154                                                  ) << 6;
00155 
00156     return SFNT_Err_Ok;
00157   }
00158 
00159 
00160   typedef struct  TT_SBitDecoderRec_
00161   {
00162     TT_Face          face;
00163     FT_Stream        stream;
00164     FT_Bitmap*       bitmap;
00165     TT_SBit_Metrics  metrics;
00166     FT_Bool          metrics_loaded;
00167     FT_Bool          bitmap_allocated;
00168     FT_Byte          bit_depth;
00169 
00170     FT_ULong         ebdt_start;
00171     FT_ULong         ebdt_size;
00172 
00173     FT_ULong         strike_index_array;
00174     FT_ULong         strike_index_count;
00175     FT_Byte*         eblc_base;
00176     FT_Byte*         eblc_limit;
00177 
00178   } TT_SBitDecoderRec, *TT_SBitDecoder;
00179 
00180 
00181   static FT_Error
00182   tt_sbit_decoder_init( TT_SBitDecoder       decoder,
00183                         TT_Face              face,
00184                         FT_ULong             strike_index,
00185                         TT_SBit_MetricsRec*  metrics )
00186   {
00187     FT_Error   error;
00188     FT_Stream  stream = face->root.stream;
00189     FT_ULong   ebdt_size;
00190 
00191 
00192     error = face->goto_table( face, TTAG_EBDT, stream, &ebdt_size );
00193     if ( error )
00194       error = face->goto_table( face, TTAG_bdat, stream, &ebdt_size );
00195     if ( error )
00196       goto Exit;
00197 
00198     decoder->face    = face;
00199     decoder->stream  = stream;
00200     decoder->bitmap  = &face->root.glyph->bitmap;
00201     decoder->metrics = metrics;
00202 
00203     decoder->metrics_loaded   = 0;
00204     decoder->bitmap_allocated = 0;
00205 
00206     decoder->ebdt_start = FT_STREAM_POS();
00207     decoder->ebdt_size  = ebdt_size;
00208 
00209     decoder->eblc_base  = face->sbit_table;
00210     decoder->eblc_limit = face->sbit_table + face->sbit_table_size;
00211 
00212     /* now find the strike corresponding to the index */
00213     {
00214       FT_Byte*  p;
00215 
00216 
00217       if ( 8 + 48 * strike_index + 3 * 4 + 34 + 1 > face->sbit_table_size )
00218       {
00219         error = SFNT_Err_Invalid_File_Format;
00220         goto Exit;
00221       }
00222 
00223       p = decoder->eblc_base + 8 + 48 * strike_index;
00224 
00225       decoder->strike_index_array = FT_NEXT_ULONG( p );
00226       p                          += 4;
00227       decoder->strike_index_count = FT_NEXT_ULONG( p );
00228       p                          += 34;
00229       decoder->bit_depth          = *p;
00230 
00231       if ( decoder->strike_index_array > face->sbit_table_size             ||
00232            decoder->strike_index_array + 8 * decoder->strike_index_count >
00233              face->sbit_table_size                                         )
00234         error = SFNT_Err_Invalid_File_Format;
00235     }
00236 
00237   Exit:
00238     return error;
00239   }
00240 
00241 
00242   static void
00243   tt_sbit_decoder_done( TT_SBitDecoder  decoder )
00244   {
00245     FT_UNUSED( decoder );
00246   }
00247 
00248 
00249   static FT_Error
00250   tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder  decoder )
00251   {
00252     FT_Error    error = SFNT_Err_Ok;
00253     FT_UInt     width, height;
00254     FT_Bitmap*  map = decoder->bitmap;
00255     FT_Long     size;
00256 
00257 
00258     if ( !decoder->metrics_loaded )
00259     {
00260       error = SFNT_Err_Invalid_Argument;
00261       goto Exit;
00262     }
00263 
00264     width  = decoder->metrics->width;
00265     height = decoder->metrics->height;
00266 
00267     map->width = (int)width;
00268     map->rows  = (int)height;
00269 
00270     switch ( decoder->bit_depth )
00271     {
00272     case 1:
00273       map->pixel_mode = FT_PIXEL_MODE_MONO;
00274       map->pitch      = ( map->width + 7 ) >> 3;
00275       break;
00276 
00277     case 2:
00278       map->pixel_mode = FT_PIXEL_MODE_GRAY2;
00279       map->pitch      = ( map->width + 3 ) >> 2;
00280       break;
00281 
00282     case 4:
00283       map->pixel_mode = FT_PIXEL_MODE_GRAY4;
00284       map->pitch      = ( map->width + 1 ) >> 1;
00285       break;
00286 
00287     case 8:
00288       map->pixel_mode = FT_PIXEL_MODE_GRAY;
00289       map->pitch      = map->width;
00290       break;
00291 
00292     default:
00293       error = SFNT_Err_Invalid_File_Format;
00294       goto Exit;
00295     }
00296 
00297     size = map->rows * map->pitch;
00298 
00299     /* check that there is no empty image */
00300     if ( size == 0 )
00301       goto Exit;     /* exit successfully! */
00302 
00303     error = ft_glyphslot_alloc_bitmap( decoder->face->root.glyph, size );
00304     if ( error )
00305       goto Exit;
00306 
00307     decoder->bitmap_allocated = 1;
00308 
00309   Exit:
00310     return error;
00311   }
00312 
00313 
00314   static FT_Error
00315   tt_sbit_decoder_load_metrics( TT_SBitDecoder  decoder,
00316                                 FT_Byte*       *pp,
00317                                 FT_Byte*        limit,
00318                                 FT_Bool         big )
00319   {
00320     FT_Byte*         p       = *pp;
00321     TT_SBit_Metrics  metrics = decoder->metrics;
00322 
00323 
00324     if ( p + 5 > limit )
00325       goto Fail;
00326 
00327     metrics->height       = p[0];
00328     metrics->width        = p[1];
00329     metrics->horiBearingX = (FT_Char)p[2];
00330     metrics->horiBearingY = (FT_Char)p[3];
00331     metrics->horiAdvance  = p[4];
00332 
00333     p += 5;
00334     if ( big )
00335     {
00336       if ( p + 3 > limit )
00337         goto Fail;
00338 
00339       metrics->vertBearingX = (FT_Char)p[0];
00340       metrics->vertBearingY = (FT_Char)p[1];
00341       metrics->vertAdvance  = p[2];
00342 
00343       p += 3;
00344     }
00345 
00346     decoder->metrics_loaded = 1;
00347     *pp = p;
00348     return SFNT_Err_Ok;
00349 
00350   Fail:
00351     return SFNT_Err_Invalid_Argument;
00352   }
00353 
00354 
00355   /* forward declaration */
00356   static FT_Error
00357   tt_sbit_decoder_load_image( TT_SBitDecoder  decoder,
00358                               FT_UInt         glyph_index,
00359                               FT_Int          x_pos,
00360                               FT_Int          y_pos );
00361 
00362   typedef FT_Error  (*TT_SBitDecoder_LoadFunc)( TT_SBitDecoder  decoder,
00363                                                 FT_Byte*        p,
00364                                                 FT_Byte*        plimit,
00365                                                 FT_Int          x_pos,
00366                                                 FT_Int          y_pos );
00367 
00368 
00369   static FT_Error
00370   tt_sbit_decoder_load_byte_aligned( TT_SBitDecoder  decoder,
00371                                      FT_Byte*        p,
00372                                      FT_Byte*        limit,
00373                                      FT_Int          x_pos,
00374                                      FT_Int          y_pos )
00375   {
00376     FT_Error    error = SFNT_Err_Ok;
00377     FT_Byte*    line;
00378     FT_Int      bit_height, bit_width, pitch, width, height, h;
00379     FT_Bitmap*  bitmap;
00380 
00381 
00382     if ( !decoder->bitmap_allocated )
00383     {
00384       error = tt_sbit_decoder_alloc_bitmap( decoder );
00385       if ( error )
00386         goto Exit;
00387     }
00388 
00389     /* check that we can write the glyph into the bitmap */
00390     bitmap     = decoder->bitmap;
00391     bit_width  = bitmap->width;
00392     bit_height = bitmap->rows;
00393     pitch      = bitmap->pitch;
00394     line       = bitmap->buffer;
00395 
00396     width  = decoder->metrics->width;
00397     height = decoder->metrics->height;
00398 
00399     if ( x_pos < 0 || x_pos + width > bit_width   ||
00400          y_pos < 0 || y_pos + height > bit_height )
00401     {
00402       error = SFNT_Err_Invalid_File_Format;
00403       goto Exit;
00404     }
00405 
00406     if ( p + ( ( width + 7 ) >> 3 ) * height > limit )
00407     {
00408       error = SFNT_Err_Invalid_File_Format;
00409       goto Exit;
00410     }
00411 
00412     /* now do the blit */
00413     line  += y_pos * pitch + ( x_pos >> 3 );
00414     x_pos &= 7;
00415 
00416     if ( x_pos == 0 )  /* the easy one */
00417     {
00418       for ( h = height; h > 0; h--, line += pitch )
00419       {
00420         FT_Byte*  write = line;
00421         FT_Int    w;
00422 
00423 
00424         for ( w = width; w >= 8; w -= 8 )
00425         {
00426           write[0] = (FT_Byte)( write[0] | *p++ );
00427           write   += 1;
00428         }
00429 
00430         if ( w > 0 )
00431           write[0] = (FT_Byte)( write[0] | ( *p++ & ( 0xFF00U >> w ) ) );
00432       }
00433     }
00434     else  /* x_pos > 0 */
00435     {
00436       for ( h = height; h > 0; h--, line += pitch )
00437       {
00438         FT_Byte*  write = line;
00439         FT_Int    w;
00440         FT_UInt   wval = 0;
00441 
00442 
00443         for ( w = width; w >= 8; w -= 8 )
00444         {
00445           wval      = (FT_UInt)( wval | *p++ );
00446           write[0]  = (FT_Byte)( write[0] | ( wval >> x_pos ) );
00447           write    += 1;
00448           wval    <<= 8;
00449         }
00450 
00451         if ( w > 0 )
00452           wval = (FT_UInt)( wval | ( *p++ & ( 0xFF00U >> w ) ) );
00453 
00454         /* all bits read and there are `x_pos + w' bits to be written */
00455 
00456         write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) );
00457 
00458         if ( x_pos + w > 8 )
00459         {
00460           write++;
00461           wval   <<= 8;
00462           write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) );
00463         }
00464       }
00465     }
00466 
00467   Exit:
00468     return error;
00469   }
00470 
00471 
00472   /*
00473    * Load a bit-aligned bitmap (with pointer `p') into a line-aligned bitmap
00474    * (with pointer `write').  In the example below, the width is 3 pixel,
00475    * and `x_pos' is 1 pixel.
00476    *
00477    *       p                               p+1
00478    *     |                               |                               |
00479    *     | 7   6   5   4   3   2   1   0 | 7   6   5   4   3   2   1   0 |...
00480    *     |                               |                               |
00481    *       +-------+   +-------+   +-------+ ...
00482    *           .           .           .
00483    *           .           .           .
00484    *           v           .           .
00485    *       +-------+       .           .
00486    * |                               | .
00487    * | 7   6   5   4   3   2   1   0 | .
00488    * |                               | .
00489    *   write               .           .
00490    *                       .           .
00491    *                       v           .
00492    *                   +-------+       .
00493    *             |                               |
00494    *             | 7   6   5   4   3   2   1   0 |
00495    *             |                               |
00496    *               write+1             .
00497    *                                   .
00498    *                                   v
00499    *                               +-------+
00500    *                         |                               |
00501    *                         | 7   6   5   4   3   2   1   0 |
00502    *                         |                               |
00503    *                           write+2
00504    *
00505    */
00506 
00507   static FT_Error
00508   tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder  decoder,
00509                                     FT_Byte*        p,
00510                                     FT_Byte*        limit,
00511                                     FT_Int          x_pos,
00512                                     FT_Int          y_pos )
00513   {
00514     FT_Error    error = SFNT_Err_Ok;
00515     FT_Byte*    line;
00516     FT_Int      bit_height, bit_width, pitch, width, height, h, nbits;
00517     FT_Bitmap*  bitmap;
00518     FT_UShort   rval;
00519 
00520 
00521     if ( !decoder->bitmap_allocated )
00522     {
00523       error = tt_sbit_decoder_alloc_bitmap( decoder );
00524       if ( error )
00525         goto Exit;
00526     }
00527 
00528     /* check that we can write the glyph into the bitmap */
00529     bitmap     = decoder->bitmap;
00530     bit_width  = bitmap->width;
00531     bit_height = bitmap->rows;
00532     pitch      = bitmap->pitch;
00533     line       = bitmap->buffer;
00534 
00535     width  = decoder->metrics->width;
00536     height = decoder->metrics->height;
00537 
00538     if ( x_pos < 0 || x_pos + width  > bit_width  ||
00539          y_pos < 0 || y_pos + height > bit_height )
00540     {
00541       error = SFNT_Err_Invalid_File_Format;
00542       goto Exit;
00543     }
00544 
00545     if ( p + ( ( width * height + 7 ) >> 3 ) > limit )
00546     {
00547       error = SFNT_Err_Invalid_File_Format;
00548       goto Exit;
00549     }
00550 
00551     /* now do the blit */
00552 
00553     /* adjust `line' to point to the first byte of the bitmap */
00554     line  += y_pos * pitch + ( x_pos >> 3 );
00555     x_pos &= 7;
00556 
00557     /* the higher byte of `rval' is used as a buffer */
00558     rval  = 0;
00559     nbits = 0;
00560 
00561     for ( h = height; h > 0; h--, line += pitch )
00562     {
00563       FT_Byte*  write = line;
00564       FT_Int    w     = width;
00565 
00566 
00567       /* handle initial byte (in target bitmap) specially if necessary */
00568       if ( x_pos )
00569       {
00570         w = ( width < 8 - x_pos ) ? width : 8 - x_pos;
00571 
00572         if ( h == height )
00573         {
00574           rval  = *p++;
00575           nbits = x_pos;
00576         }
00577         else if ( nbits < w )
00578         {
00579           if ( p < limit )
00580             rval |= *p++;
00581           nbits += 8 - w;
00582         }
00583         else
00584         {
00585           rval  >>= 8;
00586           nbits  -= w;
00587         }
00588 
00589         *write++ |= ( ( rval >> nbits ) & 0xFF ) &
00590                     ( ~( 0xFF << w ) << ( 8 - w - x_pos ) );
00591         rval    <<= 8;
00592 
00593         w = width - w;
00594       }
00595 
00596       /* handle medial bytes */
00597       for ( ; w >= 8; w -= 8 )
00598       {
00599         rval     |= *p++;
00600         *write++ |= ( rval >> nbits ) & 0xFF;
00601 
00602         rval <<= 8;
00603       }
00604 
00605       /* handle final byte if necessary */
00606       if ( w > 0 )
00607       {
00608         if ( nbits < w )
00609         {
00610           if ( p < limit )
00611             rval |= *p++;
00612           *write |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w );
00613           nbits  += 8 - w;
00614 
00615           rval <<= 8;
00616         }
00617         else
00618         {
00619           *write |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w );
00620           nbits  -= w;
00621         }
00622       }
00623     }
00624 
00625   Exit:
00626     return error;
00627   }
00628 
00629 
00630   static FT_Error
00631   tt_sbit_decoder_load_compound( TT_SBitDecoder  decoder,
00632                                  FT_Byte*        p,
00633                                  FT_Byte*        limit,
00634                                  FT_Int          x_pos,
00635                                  FT_Int          y_pos )
00636   {
00637     FT_Error  error = SFNT_Err_Ok;
00638     FT_UInt   num_components, nn;
00639 
00640     FT_Char  horiBearingX = decoder->metrics->horiBearingX;
00641     FT_Char  horiBearingY = decoder->metrics->horiBearingY;
00642     FT_Byte  horiAdvance  = decoder->metrics->horiAdvance;
00643     FT_Char  vertBearingX = decoder->metrics->vertBearingX;
00644     FT_Char  vertBearingY = decoder->metrics->vertBearingY;
00645     FT_Byte  vertAdvance  = decoder->metrics->vertAdvance;
00646 
00647 
00648     if ( p + 2 > limit )
00649       goto Fail;
00650 
00651     num_components = FT_NEXT_USHORT( p );
00652     if ( p + 4 * num_components > limit )
00653       goto Fail;
00654 
00655     if ( !decoder->bitmap_allocated )
00656     {
00657       error = tt_sbit_decoder_alloc_bitmap( decoder );
00658       if ( error )
00659         goto Exit;
00660     }
00661 
00662     for ( nn = 0; nn < num_components; nn++ )
00663     {
00664       FT_UInt  gindex = FT_NEXT_USHORT( p );
00665       FT_Byte  dx     = FT_NEXT_BYTE( p );
00666       FT_Byte  dy     = FT_NEXT_BYTE( p );
00667 
00668 
00669       /* NB: a recursive call */
00670       error = tt_sbit_decoder_load_image( decoder, gindex,
00671                                           x_pos + dx, y_pos + dy );
00672       if ( error )
00673         break;
00674     }
00675 
00676     decoder->metrics->horiBearingX = horiBearingX;
00677     decoder->metrics->horiBearingY = horiBearingY;
00678     decoder->metrics->horiAdvance  = horiAdvance;
00679     decoder->metrics->vertBearingX = vertBearingX;
00680     decoder->metrics->vertBearingY = vertBearingY;
00681     decoder->metrics->vertAdvance  = vertAdvance;
00682     decoder->metrics->width        = (FT_UInt)decoder->bitmap->width;
00683     decoder->metrics->height       = (FT_UInt)decoder->bitmap->rows;
00684 
00685   Exit:
00686     return error;
00687 
00688   Fail:
00689     error = SFNT_Err_Invalid_File_Format;
00690     goto Exit;
00691   }
00692 
00693 
00694   static FT_Error
00695   tt_sbit_decoder_load_bitmap( TT_SBitDecoder  decoder,
00696                                FT_UInt         glyph_format,
00697                                FT_ULong        glyph_start,
00698                                FT_ULong        glyph_size,
00699                                FT_Int          x_pos,
00700                                FT_Int          y_pos )
00701   {
00702     FT_Error   error;
00703     FT_Stream  stream = decoder->stream;
00704     FT_Byte*   p;
00705     FT_Byte*   p_limit;
00706     FT_Byte*   data;
00707 
00708 
00709     /* seek into the EBDT table now */
00710     if ( glyph_start + glyph_size > decoder->ebdt_size )
00711     {
00712       error = SFNT_Err_Invalid_Argument;
00713       goto Exit;
00714     }
00715 
00716     if ( FT_STREAM_SEEK( decoder->ebdt_start + glyph_start ) ||
00717          FT_FRAME_EXTRACT( glyph_size, data )                )
00718       goto Exit;
00719 
00720     p       = data;
00721     p_limit = p + glyph_size;
00722 
00723     /* read the data, depending on the glyph format */
00724     switch ( glyph_format )
00725     {
00726     case 1:
00727     case 2:
00728     case 8:
00729       error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 0 );
00730       break;
00731 
00732     case 6:
00733     case 7:
00734     case 9:
00735       error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 );
00736       break;
00737 
00738     default:
00739       error = SFNT_Err_Ok;
00740     }
00741 
00742     if ( error )
00743       goto Fail;
00744 
00745     {
00746       TT_SBitDecoder_LoadFunc  loader;
00747 
00748 
00749       switch ( glyph_format )
00750       {
00751       case 1:
00752       case 6:
00753         loader = tt_sbit_decoder_load_byte_aligned;
00754         break;
00755 
00756       case 2:
00757       case 5:
00758       case 7:
00759         loader = tt_sbit_decoder_load_bit_aligned;
00760         break;
00761 
00762       case 8:
00763         if ( p + 1 > p_limit )
00764           goto Fail;
00765 
00766         p += 1;  /* skip padding */
00767         /* fall-through */
00768 
00769       case 9:
00770         loader = tt_sbit_decoder_load_compound;
00771         break;
00772 
00773       default:
00774         goto Fail;
00775       }
00776 
00777       error = loader( decoder, p, p_limit, x_pos, y_pos );
00778     }
00779 
00780   Fail:
00781     FT_FRAME_RELEASE( data );
00782 
00783   Exit:
00784     return error;
00785   }
00786 
00787 
00788   static FT_Error
00789   tt_sbit_decoder_load_image( TT_SBitDecoder  decoder,
00790                               FT_UInt         glyph_index,
00791                               FT_Int          x_pos,
00792                               FT_Int          y_pos )
00793   {
00794     /*
00795      *  First, we find the correct strike range that applies to this
00796      *  glyph index.
00797      */
00798 
00799     FT_Byte*  p          = decoder->eblc_base + decoder->strike_index_array;
00800     FT_Byte*  p_limit    = decoder->eblc_limit;
00801     FT_ULong  num_ranges = decoder->strike_index_count;
00802     FT_UInt   start, end, index_format, image_format;
00803     FT_ULong  image_start = 0, image_end = 0, image_offset;
00804 
00805 
00806     for ( ; num_ranges > 0; num_ranges-- )
00807     {
00808       start = FT_NEXT_USHORT( p );
00809       end   = FT_NEXT_USHORT( p );
00810 
00811       if ( glyph_index >= start && glyph_index <= end )
00812         goto FoundRange;
00813 
00814       p += 4;  /* ignore index offset */
00815     }
00816     goto NoBitmap;
00817 
00818   FoundRange:
00819     image_offset = FT_NEXT_ULONG( p );
00820 
00821     /* overflow check */
00822     if ( decoder->eblc_base + decoder->strike_index_array + image_offset <
00823            decoder->eblc_base )
00824       goto Failure;
00825 
00826     p = decoder->eblc_base + decoder->strike_index_array + image_offset;
00827     if ( p + 8 > p_limit )
00828       goto NoBitmap;
00829 
00830     /* now find the glyph's location and extend within the ebdt table */
00831     index_format = FT_NEXT_USHORT( p );
00832     image_format = FT_NEXT_USHORT( p );
00833     image_offset = FT_NEXT_ULONG ( p );
00834 
00835     switch ( index_format )
00836     {
00837     case 1: /* 4-byte offsets relative to `image_offset' */
00838       {
00839         p += 4 * ( glyph_index - start );
00840         if ( p + 8 > p_limit )
00841           goto NoBitmap;
00842 
00843         image_start = FT_NEXT_ULONG( p );
00844         image_end   = FT_NEXT_ULONG( p );
00845 
00846         if ( image_start == image_end )  /* missing glyph */
00847           goto NoBitmap;
00848       }
00849       break;
00850 
00851     case 2: /* big metrics, constant image size */
00852       {
00853         FT_ULong  image_size;
00854 
00855 
00856         if ( p + 12 > p_limit )
00857           goto NoBitmap;
00858 
00859         image_size = FT_NEXT_ULONG( p );
00860 
00861         if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )
00862           goto NoBitmap;
00863 
00864         image_start = image_size * ( glyph_index - start );
00865         image_end   = image_start + image_size;
00866       }
00867       break;
00868 
00869     case 3: /* 2-byte offsets relative to 'image_offset' */
00870       {
00871         p += 2 * ( glyph_index - start );
00872         if ( p + 4 > p_limit )
00873           goto NoBitmap;
00874 
00875         image_start = FT_NEXT_USHORT( p );
00876         image_end   = FT_NEXT_USHORT( p );
00877 
00878         if ( image_start == image_end )  /* missing glyph */
00879           goto NoBitmap;
00880       }
00881       break;
00882 
00883     case 4: /* sparse glyph array with (glyph,offset) pairs */
00884       {
00885         FT_ULong  mm, num_glyphs;
00886 
00887 
00888         if ( p + 4 > p_limit )
00889           goto NoBitmap;
00890 
00891         num_glyphs = FT_NEXT_ULONG( p );
00892 
00893         /* overflow check */
00894         if ( p + ( num_glyphs + 1 ) * 4 < p )
00895           goto Failure;
00896 
00897         if ( p + ( num_glyphs + 1 ) * 4 > p_limit )
00898           goto NoBitmap;
00899 
00900         for ( mm = 0; mm < num_glyphs; mm++ )
00901         {
00902           FT_UInt  gindex = FT_NEXT_USHORT( p );
00903 
00904 
00905           if ( gindex == glyph_index )
00906           {
00907             image_start = FT_NEXT_USHORT( p );
00908             p          += 2;
00909             image_end   = FT_PEEK_USHORT( p );
00910             break;
00911           }
00912           p += 2;
00913         }
00914 
00915         if ( mm >= num_glyphs )
00916           goto NoBitmap;
00917       }
00918       break;
00919 
00920     case 5: /* constant metrics with sparse glyph codes */
00921       {
00922         FT_ULong  image_size, mm, num_glyphs;
00923 
00924 
00925         if ( p + 16 > p_limit )
00926           goto NoBitmap;
00927 
00928         image_size = FT_NEXT_ULONG( p );
00929 
00930         if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )
00931           goto NoBitmap;
00932 
00933         num_glyphs = FT_NEXT_ULONG( p );
00934 
00935         /* overflow check */
00936         if ( p + 2 * num_glyphs < p )
00937           goto Failure;
00938 
00939         if ( p + 2 * num_glyphs > p_limit )
00940           goto NoBitmap;
00941 
00942         for ( mm = 0; mm < num_glyphs; mm++ )
00943         {
00944           FT_UInt  gindex = FT_NEXT_USHORT( p );
00945 
00946 
00947           if ( gindex == glyph_index )
00948             break;
00949         }
00950 
00951         if ( mm >= num_glyphs )
00952           goto NoBitmap;
00953 
00954         image_start = image_size * mm;
00955         image_end   = image_start + image_size;
00956       }
00957       break;
00958 
00959     default:
00960       goto NoBitmap;
00961     }
00962 
00963     if ( image_start > image_end )
00964       goto NoBitmap;
00965 
00966     image_end  -= image_start;
00967     image_start = image_offset + image_start;
00968 
00969     return tt_sbit_decoder_load_bitmap( decoder,
00970                                         image_format,
00971                                         image_start,
00972                                         image_end,
00973                                         x_pos,
00974                                         y_pos );
00975 
00976   Failure:
00977     return SFNT_Err_Invalid_Table;
00978 
00979   NoBitmap:
00980     return SFNT_Err_Invalid_Argument;
00981   }
00982 
00983 
00984   FT_LOCAL( FT_Error )
00985   tt_face_load_sbit_image( TT_Face              face,
00986                            FT_ULong             strike_index,
00987                            FT_UInt              glyph_index,
00988                            FT_UInt              load_flags,
00989                            FT_Stream            stream,
00990                            FT_Bitmap           *map,
00991                            TT_SBit_MetricsRec  *metrics )
00992   {
00993     TT_SBitDecoderRec  decoder[1];
00994     FT_Error           error;
00995 
00996     FT_UNUSED( load_flags );
00997     FT_UNUSED( stream );
00998     FT_UNUSED( map );
00999 
01000 
01001     error = tt_sbit_decoder_init( decoder, face, strike_index, metrics );
01002     if ( !error )
01003     {
01004       error = tt_sbit_decoder_load_image( decoder, glyph_index, 0, 0 );
01005       tt_sbit_decoder_done( decoder );
01006     }
01007 
01008     return error;
01009   }
01010 
01011 /* EOF */

Generated on Tue May 22 2012 04:38:07 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.