ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 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

ttmtx.c
Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  ttmtx.c                                                                */
00004 /*                                                                         */
00005 /*    Load the metrics tables common to TTF and OTF fonts (body).          */
00006 /*                                                                         */
00007 /*  Copyright 2006, 2007, 2008, 2009 by                                    */
00008 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
00009 /*                                                                         */
00010 /*  This file is part of the FreeType project, and may only be used,       */
00011 /*  modified, and distributed under the terms of the FreeType project      */
00012 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
00013 /*  this file you indicate that you have read the license and              */
00014 /*  understand and accept it fully.                                        */
00015 /*                                                                         */
00016 /***************************************************************************/
00017 
00018 
00019 #include <ft2build.h>
00020 #include FT_INTERNAL_DEBUG_H
00021 #include FT_INTERNAL_STREAM_H
00022 #include FT_TRUETYPE_TAGS_H
00023 #include "ttmtx.h"
00024 
00025 #include "sferrors.h"
00026 
00027 
00028   /*************************************************************************/
00029   /*                                                                       */
00030   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
00031   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
00032   /* messages during execution.                                            */
00033   /*                                                                       */
00034 #undef  FT_COMPONENT
00035 #define FT_COMPONENT  trace_ttmtx
00036 
00037 
00038   /*
00039    *  Unfortunately, we can't enable our memory optimizations if
00040    *  FT_CONFIG_OPTION_OLD_INTERNALS is defined.  This is because at least
00041    *  one rogue client (libXfont in the X.Org XServer) is directly accessing
00042    *  the metrics.
00043    */
00044 
00045   /*************************************************************************/
00046   /*                                                                       */
00047   /* <Function>                                                            */
00048   /*    tt_face_load_hmtx                                                  */
00049   /*                                                                       */
00050   /* <Description>                                                         */
00051   /*    Load the `hmtx' or `vmtx' table into a face object.                */
00052   /*                                                                       */
00053   /* <Input>                                                               */
00054   /*    face     :: A handle to the target face object.                    */
00055   /*                                                                       */
00056   /*    stream   :: The input stream.                                      */
00057   /*                                                                       */
00058   /*    vertical :: A boolean flag.  If set, load `vmtx'.                  */
00059   /*                                                                       */
00060   /* <Return>                                                              */
00061   /*    FreeType error code.  0 means success.                             */
00062   /*                                                                       */
00063 #ifndef FT_CONFIG_OPTION_OLD_INTERNALS
00064 
00065   FT_LOCAL_DEF( FT_Error )
00066   tt_face_load_hmtx( TT_Face    face,
00067                      FT_Stream  stream,
00068                      FT_Bool    vertical )
00069   {
00070     FT_Error   error;
00071     FT_ULong   tag, table_size;
00072     FT_ULong*  ptable_offset;
00073     FT_ULong*  ptable_size;
00074 
00075 
00076     if ( vertical )
00077     {
00078       tag           = TTAG_vmtx;
00079       ptable_offset = &face->vert_metrics_offset;
00080       ptable_size   = &face->vert_metrics_size;
00081     }
00082     else
00083     {
00084       tag           = TTAG_hmtx;
00085       ptable_offset = &face->horz_metrics_offset;
00086       ptable_size   = &face->horz_metrics_size;
00087     }
00088 
00089     error = face->goto_table( face, tag, stream, &table_size );
00090     if ( error )
00091       goto Fail;
00092 
00093     *ptable_size   = table_size;
00094     *ptable_offset = FT_STREAM_POS();
00095 
00096   Fail:
00097     return error;
00098   }
00099 
00100 #else /* !FT_CONFIG_OPTION_OLD_INTERNALS */
00101 
00102   FT_LOCAL_DEF( FT_Error )
00103   tt_face_load_hmtx( TT_Face    face,
00104                      FT_Stream  stream,
00105                      FT_Bool    vertical )
00106   {
00107     FT_Error   error;
00108     FT_Memory  memory = stream->memory;
00109 
00110     FT_ULong   table_len;
00111     FT_Long    num_shorts, num_longs, num_shorts_checked;
00112 
00113     TT_LongMetrics*    longs;
00114     TT_ShortMetrics**  shorts;
00115     FT_Byte*           p;
00116 
00117 
00118     if ( vertical )
00119     {
00120       void*   lm = &face->vertical.long_metrics;
00121       void**  sm = &face->vertical.short_metrics;
00122 
00123 
00124       error = face->goto_table( face, TTAG_vmtx, stream, &table_len );
00125       if ( error )
00126         goto Fail;
00127 
00128       num_longs = face->vertical.number_Of_VMetrics;
00129       if ( (FT_ULong)num_longs > table_len / 4 )
00130         num_longs = (FT_Long)( table_len / 4 );
00131 
00132       face->vertical.number_Of_VMetrics = 0;
00133 
00134       longs  = (TT_LongMetrics*)lm;
00135       shorts = (TT_ShortMetrics**)sm;
00136     }
00137     else
00138     {
00139       void*   lm = &face->horizontal.long_metrics;
00140       void**  sm = &face->horizontal.short_metrics;
00141 
00142 
00143       error = face->goto_table( face, TTAG_hmtx, stream, &table_len );
00144       if ( error )
00145         goto Fail;
00146 
00147       num_longs = face->horizontal.number_Of_HMetrics;
00148       if ( (FT_ULong)num_longs > table_len / 4 )
00149         num_longs = (FT_Long)( table_len / 4 );
00150 
00151       face->horizontal.number_Of_HMetrics = 0;
00152 
00153       longs  = (TT_LongMetrics*)lm;
00154       shorts = (TT_ShortMetrics**)sm;
00155     }
00156 
00157     /* never trust derived values */
00158 
00159     num_shorts         = face->max_profile.numGlyphs - num_longs;
00160     num_shorts_checked = ( table_len - num_longs * 4L ) / 2;
00161 
00162     if ( num_shorts < 0 )
00163     {
00164       FT_TRACE0(( "tt_face_load_hmtx:"
00165                   " %cmtx has more metrics than glyphs.\n",
00166                   vertical ? "v" : "h" ));
00167 
00168       /* Adobe simply ignores this problem.  So we shall do the same. */
00169 #if 0
00170       error = vertical ? SFNT_Err_Invalid_Vert_Metrics
00171                        : SFNT_Err_Invalid_Horiz_Metrics;
00172       goto Exit;
00173 #else
00174       num_shorts = 0;
00175 #endif
00176     }
00177 
00178     if ( FT_QNEW_ARRAY( *longs,  num_longs  ) ||
00179          FT_QNEW_ARRAY( *shorts, num_shorts ) )
00180       goto Fail;
00181 
00182     if ( FT_FRAME_ENTER( table_len ) )
00183       goto Fail;
00184 
00185     p = stream->cursor;
00186 
00187     {
00188       TT_LongMetrics  cur   = *longs;
00189       TT_LongMetrics  limit = cur + num_longs;
00190 
00191 
00192       for ( ; cur < limit; cur++ )
00193       {
00194         cur->advance = FT_NEXT_USHORT( p );
00195         cur->bearing = FT_NEXT_SHORT( p );
00196       }
00197     }
00198 
00199     /* do we have an inconsistent number of metric values? */
00200     {
00201       TT_ShortMetrics*  cur   = *shorts;
00202       TT_ShortMetrics*  limit = cur +
00203                                 FT_MIN( num_shorts, num_shorts_checked );
00204 
00205 
00206       for ( ; cur < limit; cur++ )
00207         *cur = FT_NEXT_SHORT( p );
00208 
00209       /* We fill up the missing left side bearings with the     */
00210       /* last valid value.  Since this will occur for buggy CJK */
00211       /* fonts usually only, nothing serious will happen.       */
00212       if ( num_shorts > num_shorts_checked && num_shorts_checked > 0 )
00213       {
00214         FT_Short  val = (*shorts)[num_shorts_checked - 1];
00215 
00216 
00217         limit = *shorts + num_shorts;
00218         for ( ; cur < limit; cur++ )
00219           *cur = val;
00220       }
00221     }
00222 
00223     FT_FRAME_EXIT();
00224 
00225     if ( vertical )
00226       face->vertical.number_Of_VMetrics = (FT_UShort)num_longs;
00227     else
00228       face->horizontal.number_Of_HMetrics = (FT_UShort)num_longs;
00229 
00230   Fail:
00231     return error;
00232   }
00233 
00234 #endif /* !FT_CONFIG_OPTION_OLD_INTERNALS */
00235 
00236 
00237   /*************************************************************************/
00238   /*                                                                       */
00239   /* <Function>                                                            */
00240   /*    tt_face_load_hhea                                                  */
00241   /*                                                                       */
00242   /* <Description>                                                         */
00243   /*    Load the `hhea' or 'vhea' table into a face object.                */
00244   /*                                                                       */
00245   /* <Input>                                                               */
00246   /*    face     :: A handle to the target face object.                    */
00247   /*                                                                       */
00248   /*    stream   :: The input stream.                                      */
00249   /*                                                                       */
00250   /*    vertical :: A boolean flag.  If set, load `vhea'.                  */
00251   /*                                                                       */
00252   /* <Return>                                                              */
00253   /*    FreeType error code.  0 means success.                             */
00254   /*                                                                       */
00255   FT_LOCAL_DEF( FT_Error )
00256   tt_face_load_hhea( TT_Face    face,
00257                      FT_Stream  stream,
00258                      FT_Bool    vertical )
00259   {
00260     FT_Error        error;
00261     TT_HoriHeader*  header;
00262 
00263     const FT_Frame_Field  metrics_header_fields[] =
00264     {
00265 #undef  FT_STRUCTURE
00266 #define FT_STRUCTURE  TT_HoriHeader
00267 
00268       FT_FRAME_START( 36 ),
00269         FT_FRAME_ULONG ( Version ),
00270         FT_FRAME_SHORT ( Ascender ),
00271         FT_FRAME_SHORT ( Descender ),
00272         FT_FRAME_SHORT ( Line_Gap ),
00273         FT_FRAME_USHORT( advance_Width_Max ),
00274         FT_FRAME_SHORT ( min_Left_Side_Bearing ),
00275         FT_FRAME_SHORT ( min_Right_Side_Bearing ),
00276         FT_FRAME_SHORT ( xMax_Extent ),
00277         FT_FRAME_SHORT ( caret_Slope_Rise ),
00278         FT_FRAME_SHORT ( caret_Slope_Run ),
00279         FT_FRAME_SHORT ( caret_Offset ),
00280         FT_FRAME_SHORT ( Reserved[0] ),
00281         FT_FRAME_SHORT ( Reserved[1] ),
00282         FT_FRAME_SHORT ( Reserved[2] ),
00283         FT_FRAME_SHORT ( Reserved[3] ),
00284         FT_FRAME_SHORT ( metric_Data_Format ),
00285         FT_FRAME_USHORT( number_Of_HMetrics ),
00286       FT_FRAME_END
00287     };
00288 
00289 
00290     if ( vertical )
00291     {
00292       void  *v = &face->vertical;
00293 
00294 
00295       error = face->goto_table( face, TTAG_vhea, stream, 0 );
00296       if ( error )
00297         goto Fail;
00298 
00299       header = (TT_HoriHeader*)v;
00300     }
00301     else
00302     {
00303       error = face->goto_table( face, TTAG_hhea, stream, 0 );
00304       if ( error )
00305         goto Fail;
00306 
00307       header = &face->horizontal;
00308     }
00309 
00310     if ( FT_STREAM_READ_FIELDS( metrics_header_fields, header ) )
00311       goto Fail;
00312 
00313     FT_TRACE3(( "Ascender:          %5d\n", header->Ascender ));
00314     FT_TRACE3(( "Descender:         %5d\n", header->Descender ));
00315     FT_TRACE3(( "number_Of_Metrics: %5u\n", header->number_Of_HMetrics ));
00316 
00317     header->long_metrics  = NULL;
00318     header->short_metrics = NULL;
00319 
00320   Fail:
00321     return error;
00322   }
00323 
00324 
00325   /*************************************************************************/
00326   /*                                                                       */
00327   /* <Function>                                                            */
00328   /*    tt_face_get_metrics                                                */
00329   /*                                                                       */
00330   /* <Description>                                                         */
00331   /*    Returns the horizontal or vertical metrics in font units for a     */
00332   /*    given glyph.  The metrics are the left side bearing (resp. top     */
00333   /*    side bearing) and advance width (resp. advance height).            */
00334   /*                                                                       */
00335   /* <Input>                                                               */
00336   /*    header  :: A pointer to either the horizontal or vertical metrics  */
00337   /*               structure.                                              */
00338   /*                                                                       */
00339   /*    idx     :: The glyph index.                                        */
00340   /*                                                                       */
00341   /* <Output>                                                              */
00342   /*    bearing :: The bearing, either left side or top side.              */
00343   /*                                                                       */
00344   /*    advance :: The advance width resp. advance height.                 */
00345   /*                                                                       */
00346 #ifndef FT_CONFIG_OPTION_OLD_INTERNALS
00347 
00348   FT_LOCAL_DEF( FT_Error )
00349   tt_face_get_metrics( TT_Face     face,
00350                        FT_Bool     vertical,
00351                        FT_UInt     gindex,
00352                        FT_Short   *abearing,
00353                        FT_UShort  *aadvance )
00354   {
00355     FT_Error        error;
00356     FT_Stream       stream = face->root.stream;
00357     TT_HoriHeader*  header;
00358     FT_ULong        table_pos, table_size, table_end;
00359     FT_UShort       k;
00360 
00361 
00362     if ( vertical )
00363     {
00364       void*  v = &face->vertical;
00365 
00366 
00367       header     = (TT_HoriHeader*)v;
00368       table_pos  = face->vert_metrics_offset;
00369       table_size = face->vert_metrics_size;
00370     }
00371     else
00372     {
00373       header     = &face->horizontal;
00374       table_pos  = face->horz_metrics_offset;
00375       table_size = face->horz_metrics_size;
00376     }
00377 
00378     table_end = table_pos + table_size;
00379 
00380     k = header->number_Of_HMetrics;
00381 
00382     if ( k > 0 )
00383     {
00384       if ( gindex < (FT_UInt)k )
00385       {
00386         table_pos += 4 * gindex;
00387         if ( table_pos + 4 > table_end )
00388           goto NoData;
00389 
00390         if ( FT_STREAM_SEEK( table_pos ) ||
00391              FT_READ_USHORT( *aadvance ) ||
00392              FT_READ_SHORT( *abearing )  )
00393           goto NoData;
00394       }
00395       else
00396       {
00397         table_pos += 4 * ( k - 1 );
00398         if ( table_pos + 4 > table_end )
00399           goto NoData;
00400 
00401         if ( FT_STREAM_SEEK( table_pos ) ||
00402              FT_READ_USHORT( *aadvance ) )
00403           goto NoData;
00404 
00405         table_pos += 4 + 2 * ( gindex - k );
00406         if ( table_pos + 2 > table_end )
00407           *abearing = 0;
00408         else
00409         {
00410           if ( !FT_STREAM_SEEK( table_pos ) )
00411             (void)FT_READ_SHORT( *abearing );
00412         }
00413       }
00414     }
00415     else
00416     {
00417     NoData:
00418       *abearing = 0;
00419       *aadvance = 0;
00420     }
00421 
00422     return SFNT_Err_Ok;
00423   }
00424 
00425 #else /* !FT_CONFIG_OPTION_OLD_INTERNALS */
00426 
00427   FT_LOCAL_DEF( FT_Error )
00428   tt_face_get_metrics( TT_Face     face,
00429                        FT_Bool     vertical,
00430                        FT_UInt     gindex,
00431                        FT_Short*   abearing,
00432                        FT_UShort*  aadvance )
00433   {
00434     void*           v = &face->vertical;
00435     void*           h = &face->horizontal;
00436     TT_HoriHeader*  header = vertical ? (TT_HoriHeader*)v
00437                                       : (TT_HoriHeader*)h;
00438     TT_LongMetrics  longs_m;
00439     FT_UShort       k = header->number_Of_HMetrics;
00440 
00441 
00442     if ( k == 0                                         ||
00443          !header->long_metrics                          ||
00444          gindex >= (FT_UInt)face->max_profile.numGlyphs )
00445     {
00446       *abearing = *aadvance = 0;
00447       return SFNT_Err_Ok;
00448     }
00449 
00450     if ( gindex < (FT_UInt)k )
00451     {
00452       longs_m   = (TT_LongMetrics)header->long_metrics + gindex;
00453       *abearing = longs_m->bearing;
00454       *aadvance = longs_m->advance;
00455     }
00456     else
00457     {
00458       *abearing = ((TT_ShortMetrics*)header->short_metrics)[gindex - k];
00459       *aadvance = ((TT_LongMetrics)header->long_metrics)[k - 1].advance;
00460     }
00461 
00462     return SFNT_Err_Ok;
00463   }
00464 
00465 #endif /* !FT_CONFIG_OPTION_OLD_INTERNALS */
00466 
00467 
00468 /* END */

Generated on Fri May 25 2012 04:32:32 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.