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

cffobjs.c
Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  cffobjs.c                                                              */
00004 /*                                                                         */
00005 /*    OpenType objects manager (body).                                     */
00006 /*                                                                         */
00007 /*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */
00008 /*            2010 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 #include <ft2build.h>
00021 #include FT_INTERNAL_DEBUG_H
00022 #include FT_INTERNAL_CALC_H
00023 #include FT_INTERNAL_STREAM_H
00024 #include FT_ERRORS_H
00025 #include FT_TRUETYPE_IDS_H
00026 #include FT_TRUETYPE_TAGS_H
00027 #include FT_INTERNAL_SFNT_H
00028 #include "cffobjs.h"
00029 #include "cffload.h"
00030 #include "cffcmap.h"
00031 #include "cfferrs.h"
00032 #include "cffpic.h"
00033 
00034 
00035   /*************************************************************************/
00036   /*                                                                       */
00037   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
00038   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
00039   /* messages during execution.                                            */
00040   /*                                                                       */
00041 #undef  FT_COMPONENT
00042 #define FT_COMPONENT  trace_cffobjs
00043 
00044 
00045   /*************************************************************************/
00046   /*                                                                       */
00047   /*                            SIZE FUNCTIONS                             */
00048   /*                                                                       */
00049   /*  Note that we store the global hints in the size's `internal' root    */
00050   /*  field.                                                               */
00051   /*                                                                       */
00052   /*************************************************************************/
00053 
00054 
00055   static PSH_Globals_Funcs
00056   cff_size_get_globals_funcs( CFF_Size  size )
00057   {
00058     CFF_Face          face     = (CFF_Face)size->root.face;
00059     CFF_Font          font     = (CFF_Font)face->extra.data;
00060     PSHinter_Service  pshinter = font->pshinter;
00061     FT_Module         module;
00062 
00063 
00064     module = FT_Get_Module( size->root.face->driver->root.library,
00065                             "pshinter" );
00066     return ( module && pshinter && pshinter->get_globals_funcs )
00067            ? pshinter->get_globals_funcs( module )
00068            : 0;
00069   }
00070 
00071 
00072   FT_LOCAL_DEF( void )
00073   cff_size_done( FT_Size  cffsize )        /* CFF_Size */
00074   {
00075     CFF_Size      size     = (CFF_Size)cffsize;
00076     CFF_Face      face     = (CFF_Face)size->root.face;
00077     CFF_Font      font     = (CFF_Font)face->extra.data;
00078     CFF_Internal  internal = (CFF_Internal)cffsize->internal;
00079 
00080 
00081     if ( internal )
00082     {
00083       PSH_Globals_Funcs  funcs;
00084 
00085 
00086       funcs = cff_size_get_globals_funcs( size );
00087       if ( funcs )
00088       {
00089         FT_UInt  i;
00090 
00091 
00092         funcs->destroy( internal->topfont );
00093 
00094         for ( i = font->num_subfonts; i > 0; i-- )
00095           funcs->destroy( internal->subfonts[i - 1] );
00096       }
00097 
00098       /* `internal' is freed by destroy_size (in ftobjs.c) */
00099     }
00100   }
00101 
00102 
00103   /* CFF and Type 1 private dictionaries have slightly different      */
00104   /* structures; we need to synthesize a Type 1 dictionary on the fly */
00105 
00106   static void
00107   cff_make_private_dict( CFF_SubFont  subfont,
00108                          PS_Private   priv )
00109   {
00110     CFF_Private  cpriv = &subfont->private_dict;
00111     FT_UInt      n, count;
00112 
00113 
00114     FT_MEM_ZERO( priv, sizeof ( *priv ) );
00115 
00116     count = priv->num_blue_values = cpriv->num_blue_values;
00117     for ( n = 0; n < count; n++ )
00118       priv->blue_values[n] = (FT_Short)cpriv->blue_values[n];
00119 
00120     count = priv->num_other_blues = cpriv->num_other_blues;
00121     for ( n = 0; n < count; n++ )
00122       priv->other_blues[n] = (FT_Short)cpriv->other_blues[n];
00123 
00124     count = priv->num_family_blues = cpriv->num_family_blues;
00125     for ( n = 0; n < count; n++ )
00126       priv->family_blues[n] = (FT_Short)cpriv->family_blues[n];
00127 
00128     count = priv->num_family_other_blues = cpriv->num_family_other_blues;
00129     for ( n = 0; n < count; n++ )
00130       priv->family_other_blues[n] = (FT_Short)cpriv->family_other_blues[n];
00131 
00132     priv->blue_scale = cpriv->blue_scale;
00133     priv->blue_shift = (FT_Int)cpriv->blue_shift;
00134     priv->blue_fuzz  = (FT_Int)cpriv->blue_fuzz;
00135 
00136     priv->standard_width[0]  = (FT_UShort)cpriv->standard_width;
00137     priv->standard_height[0] = (FT_UShort)cpriv->standard_height;
00138 
00139     count = priv->num_snap_widths = cpriv->num_snap_widths;
00140     for ( n = 0; n < count; n++ )
00141       priv->snap_widths[n] = (FT_Short)cpriv->snap_widths[n];
00142 
00143     count = priv->num_snap_heights = cpriv->num_snap_heights;
00144     for ( n = 0; n < count; n++ )
00145       priv->snap_heights[n] = (FT_Short)cpriv->snap_heights[n];
00146 
00147     priv->force_bold     = cpriv->force_bold;
00148     priv->language_group = cpriv->language_group;
00149     priv->lenIV          = cpriv->lenIV;
00150   }
00151 
00152 
00153   FT_LOCAL_DEF( FT_Error )
00154   cff_size_init( FT_Size  cffsize )         /* CFF_Size */
00155   {
00156     CFF_Size           size  = (CFF_Size)cffsize;
00157     FT_Error           error = CFF_Err_Ok;
00158     PSH_Globals_Funcs  funcs = cff_size_get_globals_funcs( size );
00159 
00160 
00161     if ( funcs )
00162     {
00163       CFF_Face      face     = (CFF_Face)cffsize->face;
00164       CFF_Font      font     = (CFF_Font)face->extra.data;
00165       CFF_Internal  internal;
00166 
00167       PS_PrivateRec  priv;
00168       FT_Memory      memory = cffsize->face->memory;
00169 
00170       FT_UInt  i;
00171 
00172 
00173       if ( FT_NEW( internal ) )
00174         goto Exit;
00175 
00176       cff_make_private_dict( &font->top_font, &priv );
00177       error = funcs->create( cffsize->face->memory, &priv,
00178                              &internal->topfont );
00179       if ( error )
00180         goto Exit;
00181 
00182       for ( i = font->num_subfonts; i > 0; i-- )
00183       {
00184         CFF_SubFont  sub = font->subfonts[i - 1];
00185 
00186 
00187         cff_make_private_dict( sub, &priv );
00188         error = funcs->create( cffsize->face->memory, &priv,
00189                                &internal->subfonts[i - 1] );
00190         if ( error )
00191           goto Exit;
00192       }
00193 
00194       cffsize->internal = (FT_Size_Internal)(void*)internal;
00195     }
00196 
00197     size->strike_index = 0xFFFFFFFFUL;
00198 
00199   Exit:
00200     return error;
00201   }
00202 
00203 
00204 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
00205 
00206   FT_LOCAL_DEF( FT_Error )
00207   cff_size_select( FT_Size   size,
00208                    FT_ULong  strike_index )
00209   {
00210     CFF_Size           cffsize = (CFF_Size)size;
00211     PSH_Globals_Funcs  funcs;
00212 
00213 
00214     cffsize->strike_index = strike_index;
00215 
00216     FT_Select_Metrics( size->face, strike_index );
00217 
00218     funcs = cff_size_get_globals_funcs( cffsize );
00219 
00220     if ( funcs )
00221     {
00222       CFF_Face      face     = (CFF_Face)size->face;
00223       CFF_Font      font     = (CFF_Font)face->extra.data;
00224       CFF_Internal  internal = (CFF_Internal)size->internal;
00225 
00226       FT_ULong  top_upm  = font->top_font.font_dict.units_per_em;
00227       FT_UInt   i;
00228 
00229 
00230       funcs->set_scale( internal->topfont,
00231                         size->metrics.x_scale, size->metrics.y_scale,
00232                         0, 0 );
00233 
00234       for ( i = font->num_subfonts; i > 0; i-- )
00235       {
00236         CFF_SubFont  sub     = font->subfonts[i - 1];
00237         FT_ULong     sub_upm = sub->font_dict.units_per_em;
00238         FT_Pos       x_scale, y_scale;
00239 
00240 
00241         if ( top_upm != sub_upm )
00242         {
00243           x_scale = FT_MulDiv( size->metrics.x_scale, top_upm, sub_upm );
00244           y_scale = FT_MulDiv( size->metrics.y_scale, top_upm, sub_upm );
00245         }
00246         else
00247         {
00248           x_scale = size->metrics.x_scale;
00249           y_scale = size->metrics.y_scale;
00250         }
00251 
00252         funcs->set_scale( internal->subfonts[i - 1],
00253                           x_scale, y_scale, 0, 0 );
00254       }
00255     }
00256 
00257     return CFF_Err_Ok;
00258   }
00259 
00260 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
00261 
00262 
00263   FT_LOCAL_DEF( FT_Error )
00264   cff_size_request( FT_Size          size,
00265                     FT_Size_Request  req )
00266   {
00267     CFF_Size           cffsize = (CFF_Size)size;
00268     PSH_Globals_Funcs  funcs;
00269 
00270 
00271 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
00272 
00273     if ( FT_HAS_FIXED_SIZES( size->face ) )
00274     {
00275       CFF_Face      cffface = (CFF_Face)size->face;
00276       SFNT_Service  sfnt    = (SFNT_Service)cffface->sfnt;
00277       FT_ULong      strike_index;
00278 
00279 
00280       if ( sfnt->set_sbit_strike( cffface, req, &strike_index ) )
00281         cffsize->strike_index = 0xFFFFFFFFUL;
00282       else
00283         return cff_size_select( size, strike_index );
00284     }
00285 
00286 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
00287 
00288     FT_Request_Metrics( size->face, req );
00289 
00290     funcs = cff_size_get_globals_funcs( cffsize );
00291 
00292     if ( funcs )
00293     {
00294       CFF_Face      cffface  = (CFF_Face)size->face;
00295       CFF_Font      font     = (CFF_Font)cffface->extra.data;
00296       CFF_Internal  internal = (CFF_Internal)size->internal;
00297 
00298       FT_ULong  top_upm  = font->top_font.font_dict.units_per_em;
00299       FT_UInt   i;
00300 
00301 
00302       funcs->set_scale( internal->topfont,
00303                         size->metrics.x_scale, size->metrics.y_scale,
00304                         0, 0 );
00305 
00306       for ( i = font->num_subfonts; i > 0; i-- )
00307       {
00308         CFF_SubFont  sub     = font->subfonts[i - 1];
00309         FT_ULong     sub_upm = sub->font_dict.units_per_em;
00310         FT_Pos       x_scale, y_scale;
00311 
00312 
00313         if ( top_upm != sub_upm )
00314         {
00315           x_scale = FT_MulDiv( size->metrics.x_scale, top_upm, sub_upm );
00316           y_scale = FT_MulDiv( size->metrics.y_scale, top_upm, sub_upm );
00317         }
00318         else
00319         {
00320           x_scale = size->metrics.x_scale;
00321           y_scale = size->metrics.y_scale;
00322         }
00323 
00324         funcs->set_scale( internal->subfonts[i - 1],
00325                           x_scale, y_scale, 0, 0 );
00326       }
00327     }
00328 
00329     return CFF_Err_Ok;
00330   }
00331 
00332 
00333   /*************************************************************************/
00334   /*                                                                       */
00335   /*                            SLOT  FUNCTIONS                            */
00336   /*                                                                       */
00337   /*************************************************************************/
00338 
00339   FT_LOCAL_DEF( void )
00340   cff_slot_done( FT_GlyphSlot  slot )
00341   {
00342     slot->internal->glyph_hints = 0;
00343   }
00344 
00345 
00346   FT_LOCAL_DEF( FT_Error )
00347   cff_slot_init( FT_GlyphSlot  slot )
00348   {
00349     CFF_Face          face     = (CFF_Face)slot->face;
00350     CFF_Font          font     = (CFF_Font)face->extra.data;
00351     PSHinter_Service  pshinter = font->pshinter;
00352 
00353 
00354     if ( pshinter )
00355     {
00356       FT_Module  module;
00357 
00358 
00359       module = FT_Get_Module( slot->face->driver->root.library,
00360                               "pshinter" );
00361       if ( module )
00362       {
00363         T2_Hints_Funcs  funcs;
00364 
00365 
00366         funcs = pshinter->get_t2_funcs( module );
00367         slot->internal->glyph_hints = (void*)funcs;
00368       }
00369     }
00370 
00371     return CFF_Err_Ok;
00372   }
00373 
00374 
00375   /*************************************************************************/
00376   /*                                                                       */
00377   /*                           FACE  FUNCTIONS                             */
00378   /*                                                                       */
00379   /*************************************************************************/
00380 
00381   static FT_String*
00382   cff_strcpy( FT_Memory         memory,
00383               const FT_String*  source )
00384   {
00385     FT_Error    error;
00386     FT_String*  result;
00387 
00388 
00389     (void)FT_STRDUP( result, source );
00390 
00391     FT_UNUSED( error );
00392 
00393     return result;
00394   }
00395 
00396 
00397   /* Strip all subset prefixes of the form `ABCDEF+'.  Usually, there */
00398   /* is only one, but font names like `APCOOG+JFABTD+FuturaBQ-Bold'   */
00399   /* have been seen in the wild.                                      */
00400 
00401   static void
00402   remove_subset_prefix( FT_String*  name )
00403   {
00404     FT_Int32  idx             = 0;
00405     FT_Int32  length          = strlen( name ) + 1;
00406     FT_Bool   continue_search = 1;
00407  
00408 
00409     while ( continue_search )
00410     {
00411       if ( length >= 7 && name[6] == '+' )
00412       {
00413         for ( idx = 0; idx < 6; idx++ )
00414         {
00415           /* ASCII uppercase letters */
00416           if ( !( 'A' <= name[idx] && name[idx] <= 'Z' ) )
00417             continue_search = 0;
00418         }
00419 
00420         if ( continue_search )
00421         {
00422           for ( idx = 7; idx < length; idx++ )
00423             name[idx - 7] = name[idx];
00424         }
00425       }
00426       else
00427         continue_search = 0;
00428     }
00429   }
00430 
00431 
00432   FT_LOCAL_DEF( FT_Error )
00433   cff_face_init( FT_Stream      stream,
00434                  FT_Face        cffface,        /* CFF_Face */
00435                  FT_Int         face_index,
00436                  FT_Int         num_params,
00437                  FT_Parameter*  params )
00438   {
00439     CFF_Face            face = (CFF_Face)cffface;
00440     FT_Error            error;
00441     SFNT_Service        sfnt;
00442     FT_Service_PsCMaps  psnames;
00443     PSHinter_Service    pshinter;
00444     FT_Bool             pure_cff    = 1;
00445     FT_Bool             sfnt_format = 0;
00446     FT_Library library = cffface->driver->root.library;
00447 
00448 
00449     sfnt = (SFNT_Service)FT_Get_Module_Interface(
00450              library, "sfnt" );
00451     if ( !sfnt )
00452       goto Bad_Format;
00453 
00454     FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
00455 
00456     pshinter = (PSHinter_Service)FT_Get_Module_Interface(
00457                  library, "pshinter" );
00458 
00459     /* create input stream from resource */
00460     if ( FT_STREAM_SEEK( 0 ) )
00461       goto Exit;
00462 
00463     /* check whether we have a valid OpenType file */
00464     error = sfnt->init_face( stream, face, face_index, num_params, params );
00465     if ( !error )
00466     {
00467       if ( face->format_tag != TTAG_OTTO )  /* `OTTO'; OpenType/CFF font */
00468       {
00469         FT_TRACE2(( "[not a valid OpenType/CFF font]\n" ));
00470         goto Bad_Format;
00471       }
00472 
00473       /* if we are performing a simple font format check, exit immediately */
00474       if ( face_index < 0 )
00475         return CFF_Err_Ok;
00476 
00477       /* UNDOCUMENTED!  A CFF in an SFNT can have only a single font. */
00478       if ( face_index > 0 )
00479       {
00480         FT_ERROR(( "cff_face_init: invalid face index\n" ));
00481         error = CFF_Err_Invalid_Argument;
00482         goto Exit;
00483       }
00484 
00485       sfnt_format = 1;
00486 
00487       /* now, the font can be either an OpenType/CFF font, or an SVG CEF */
00488       /* font; in the latter case it doesn't have a `head' table         */
00489       error = face->goto_table( face, TTAG_head, stream, 0 );
00490       if ( !error )
00491       {
00492         pure_cff = 0;
00493 
00494         /* load font directory */
00495         error = sfnt->load_face( stream, face, 0, num_params, params );
00496         if ( error )
00497           goto Exit;
00498       }
00499       else
00500       {
00501         /* load the `cmap' table explicitly */
00502         error = sfnt->load_cmap( face, stream );
00503         if ( error )
00504           goto Exit;
00505 
00506         /* XXX: we don't load the GPOS table, as OpenType Layout     */
00507         /* support will be added later to a layout library on top of */
00508         /* FreeType 2                                                */
00509       }
00510 
00511       /* now load the CFF part of the file */
00512       error = face->goto_table( face, TTAG_CFF, stream, 0 );
00513       if ( error )
00514         goto Exit;
00515     }
00516     else
00517     {
00518       /* rewind to start of file; we are going to load a pure-CFF font */
00519       if ( FT_STREAM_SEEK( 0 ) )
00520         goto Exit;
00521       error = CFF_Err_Ok;
00522     }
00523 
00524     /* now load and parse the CFF table in the file */
00525     {
00526       CFF_Font         cff;
00527       CFF_FontRecDict  dict;
00528       FT_Memory        memory = cffface->memory;
00529       FT_Int32         flags;
00530       FT_UInt          i;
00531 
00532 
00533       if ( FT_NEW( cff ) )
00534         goto Exit;
00535 
00536       face->extra.data = cff;
00537       error = cff_font_load( library, stream, face_index, cff, pure_cff );
00538       if ( error )
00539         goto Exit;
00540 
00541       cff->pshinter = pshinter;
00542       cff->psnames  = psnames;
00543 
00544       cffface->face_index = face_index;
00545 
00546       /* Complement the root flags with some interesting information. */
00547       /* Note that this is only necessary for pure CFF and CEF fonts; */
00548       /* SFNT based fonts use the `name' table instead.               */
00549 
00550       cffface->num_glyphs = cff->num_glyphs;
00551 
00552       dict = &cff->top_font.font_dict;
00553 
00554       /* we need the `PSNames' module for CFF and CEF formats */
00555       /* which aren't CID-keyed                               */
00556       if ( dict->cid_registry == 0xFFFFU && !psnames )
00557       {
00558         FT_ERROR(( "cff_face_init:"
00559                    " cannot open CFF & CEF fonts\n"
00560                    "              "
00561                    " without the `PSNames' module\n" ));
00562         goto Bad_Format;
00563       }
00564 
00565       if ( !dict->units_per_em )
00566         dict->units_per_em = pure_cff ? 1000 : face->root.units_per_EM;
00567 
00568       /* Normalize the font matrix so that `matrix->xx' is 1; the */
00569       /* scaling is done with `units_per_em' then (at this point, */
00570       /* it already contains the scaling factor, but without      */
00571       /* normalization of the matrix).                            */
00572       /*                                                          */
00573       /* Note that the offsets must be expressed in integer font  */
00574       /* units.                                                   */
00575 
00576       {
00577         FT_Matrix*  matrix = &dict->font_matrix;
00578         FT_Vector*  offset = &dict->font_offset;
00579         FT_ULong*   upm    = &dict->units_per_em;
00580         FT_Fixed    temp   = FT_ABS( matrix->yy );
00581 
00582 
00583         if ( temp != 0x10000L )
00584         {
00585           *upm = FT_DivFix( *upm, temp );
00586 
00587           matrix->xx = FT_DivFix( matrix->xx, temp );
00588           matrix->yx = FT_DivFix( matrix->yx, temp );
00589           matrix->xy = FT_DivFix( matrix->xy, temp );
00590           matrix->yy = FT_DivFix( matrix->yy, temp );
00591           offset->x  = FT_DivFix( offset->x,  temp );
00592           offset->y  = FT_DivFix( offset->y,  temp );
00593         }
00594 
00595         offset->x >>= 16;
00596         offset->y >>= 16;
00597       }
00598 
00599       for ( i = cff->num_subfonts; i > 0; i-- )
00600       {
00601         CFF_FontRecDict  sub = &cff->subfonts[i - 1]->font_dict;
00602         CFF_FontRecDict  top = &cff->top_font.font_dict;
00603 
00604         FT_Matrix*  matrix;
00605         FT_Vector*  offset;
00606         FT_ULong*   upm;
00607         FT_Fixed    temp;
00608 
00609 
00610         if ( sub->units_per_em )
00611         {
00612           FT_Long  scaling;
00613 
00614 
00615           if ( top->units_per_em > 1 && sub->units_per_em > 1 )
00616             scaling = FT_MIN( top->units_per_em, sub->units_per_em );
00617           else
00618             scaling = 1;
00619 
00620           FT_Matrix_Multiply_Scaled( &top->font_matrix,
00621                                      &sub->font_matrix,
00622                                      scaling );
00623           FT_Vector_Transform_Scaled( &sub->font_offset,
00624                                       &top->font_matrix,
00625                                       scaling );
00626 
00627           sub->units_per_em = FT_MulDiv( sub->units_per_em,
00628                                          top->units_per_em,
00629                                          scaling );
00630         }
00631         else
00632         {
00633           sub->font_matrix = top->font_matrix;
00634           sub->font_offset = top->font_offset;
00635 
00636           sub->units_per_em = top->units_per_em;
00637         }
00638 
00639         matrix = &sub->font_matrix;
00640         offset = &sub->font_offset;
00641         upm    = &sub->units_per_em;
00642         temp   = FT_ABS( matrix->yy );
00643 
00644         if ( temp != 0x10000L )
00645         {
00646           *upm = FT_DivFix( *upm, temp );
00647 
00648           /* if *upm is larger than 100*1000 we divide by 1000 --     */
00649           /* this can happen if e.g. there is no top-font FontMatrix  */
00650           /* and the subfont FontMatrix already contains the complete */
00651           /* scaling for the subfont (see section 5.11 of the PLRM)   */
00652 
00653           /* 100 is a heuristic value */
00654 
00655           if ( *upm > 100L * 1000L )
00656             *upm = ( *upm + 500 ) / 1000;
00657 
00658           matrix->xx = FT_DivFix( matrix->xx, temp );
00659           matrix->yx = FT_DivFix( matrix->yx, temp );
00660           matrix->xy = FT_DivFix( matrix->xy, temp );
00661           matrix->yy = FT_DivFix( matrix->yy, temp );
00662           offset->x  = FT_DivFix( offset->x,  temp );
00663           offset->y  = FT_DivFix( offset->y,  temp );
00664         }
00665 
00666         offset->x >>= 16;
00667         offset->y >>= 16;
00668       }
00669 
00670       if ( pure_cff )
00671       {
00672         char*  style_name = NULL;
00673 
00674 
00675         /* set up num_faces */
00676         cffface->num_faces = cff->num_faces;
00677 
00678         /* compute number of glyphs */
00679         if ( dict->cid_registry != 0xFFFFU )
00680           cffface->num_glyphs = cff->charset.max_cid + 1;
00681         else
00682           cffface->num_glyphs = cff->charstrings_index.count;
00683 
00684         /* set global bbox, as well as EM size */
00685         cffface->bbox.xMin =   dict->font_bbox.xMin            >> 16;
00686         cffface->bbox.yMin =   dict->font_bbox.yMin            >> 16;
00687         /* no `U' suffix here to 0xFFFF! */
00688         cffface->bbox.xMax = ( dict->font_bbox.xMax + 0xFFFF ) >> 16;
00689         cffface->bbox.yMax = ( dict->font_bbox.yMax + 0xFFFF ) >> 16;
00690 
00691         cffface->units_per_EM = (FT_UShort)( dict->units_per_em );
00692 
00693         cffface->ascender  = (FT_Short)( cffface->bbox.yMax );
00694         cffface->descender = (FT_Short)( cffface->bbox.yMin );
00695 
00696         cffface->height = (FT_Short)( ( cffface->units_per_EM * 12 ) / 10 );
00697         if ( cffface->height < cffface->ascender - cffface->descender )
00698           cffface->height = (FT_Short)( cffface->ascender - cffface->descender );
00699 
00700         cffface->underline_position  =
00701           (FT_Short)( dict->underline_position >> 16 );
00702         cffface->underline_thickness =
00703           (FT_Short)( dict->underline_thickness >> 16 );
00704 
00705         /* retrieve font family & style name */
00706         cffface->family_name = cff_index_get_name( cff, face_index );
00707         if ( cffface->family_name )
00708         {
00709           char*  full   = cff_index_get_sid_string( cff,
00710                                                     dict->full_name );
00711           char*  fullp  = full;
00712           char*  family = cffface->family_name;
00713           char*  family_name = NULL;
00714 
00715 
00716           remove_subset_prefix( cffface->family_name ); 
00717 
00718           if ( dict->family_name )
00719           {
00720             family_name = cff_index_get_sid_string( cff,
00721                                                     dict->family_name );
00722             if ( family_name )
00723               family = family_name;
00724           }
00725 
00726           /* We try to extract the style name from the full name.   */
00727           /* We need to ignore spaces and dashes during the search. */
00728           if ( full && family )
00729           {
00730             while ( *fullp )
00731             {
00732               /* skip common characters at the start of both strings */
00733               if ( *fullp == *family )
00734               {
00735                 family++;
00736                 fullp++;
00737                 continue;
00738               }
00739 
00740               /* ignore spaces and dashes in full name during comparison */
00741               if ( *fullp == ' ' || *fullp == '-' )
00742               {
00743                 fullp++;
00744                 continue;
00745               }
00746 
00747               /* ignore spaces and dashes in family name during comparison */
00748               if ( *family == ' ' || *family == '-' )
00749               {
00750                 family++;
00751                 continue;
00752               }
00753 
00754               if ( !*family && *fullp )
00755               {
00756                 /* The full name begins with the same characters as the  */
00757                 /* family name, with spaces and dashes removed.  In this */
00758                 /* case, the remaining string in `fullp' will be used as */
00759                 /* the style name.                                       */
00760                 style_name = cff_strcpy( memory, fullp );
00761               }
00762               break;
00763             }
00764           }
00765         }
00766         else
00767         {
00768           char  *cid_font_name =
00769                    cff_index_get_sid_string( cff,
00770                                              dict->cid_font_name );
00771 
00772 
00773           /* do we have a `/FontName' for a CID-keyed font? */
00774           if ( cid_font_name )
00775             cffface->family_name = cff_strcpy( memory, cid_font_name );
00776         }
00777 
00778         if ( style_name )
00779           cffface->style_name = style_name;
00780         else
00781           /* assume "Regular" style if we don't know better */
00782           cffface->style_name = cff_strcpy( memory, (char *)"Regular" );
00783 
00784         /*******************************************************************/
00785         /*                                                                 */
00786         /* Compute face flags.                                             */
00787         /*                                                                 */
00788         flags = (FT_UInt32)( FT_FACE_FLAG_SCALABLE   | /* scalable outlines */
00789                              FT_FACE_FLAG_HORIZONTAL | /* horizontal data   */
00790                              FT_FACE_FLAG_HINTER );    /* has native hinter */
00791 
00792         if ( sfnt_format )
00793           flags |= (FT_UInt32)FT_FACE_FLAG_SFNT;
00794 
00795         /* fixed width font? */
00796         if ( dict->is_fixed_pitch )
00797           flags |= (FT_UInt32)FT_FACE_FLAG_FIXED_WIDTH;
00798 
00799   /* XXX: WE DO NOT SUPPORT KERNING METRICS IN THE GPOS TABLE FOR NOW */
00800 #if 0
00801         /* kerning available? */
00802         if ( face->kern_pairs )
00803           flags |= (FT_UInt32)FT_FACE_FLAG_KERNING;
00804 #endif
00805 
00806         cffface->face_flags = flags;
00807 
00808         /*******************************************************************/
00809         /*                                                                 */
00810         /* Compute style flags.                                            */
00811         /*                                                                 */
00812         flags = 0;
00813 
00814         if ( dict->italic_angle )
00815           flags |= FT_STYLE_FLAG_ITALIC;
00816 
00817         {
00818           char  *weight = cff_index_get_sid_string( cff,
00819                                                     dict->weight );
00820 
00821 
00822           if ( weight )
00823             if ( !ft_strcmp( weight, "Bold"  ) ||
00824                  !ft_strcmp( weight, "Black" ) )
00825               flags |= FT_STYLE_FLAG_BOLD;
00826         }
00827 
00828         /* double check */
00829         if ( !(flags & FT_STYLE_FLAG_BOLD) && cffface->style_name )
00830           if ( !ft_strncmp( cffface->style_name, "Bold", 4 )  ||
00831                !ft_strncmp( cffface->style_name, "Black", 5 ) )
00832             flags |= FT_STYLE_FLAG_BOLD;
00833 
00834         cffface->style_flags = flags;
00835       }
00836 
00837 
00838 #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
00839       /* CID-keyed CFF fonts don't have glyph names -- the SFNT loader */
00840       /* has unset this flag because of the 3.0 `post' table.          */
00841       if ( dict->cid_registry == 0xFFFFU )
00842         cffface->face_flags |= FT_FACE_FLAG_GLYPH_NAMES;
00843 #endif
00844 
00845       if ( dict->cid_registry != 0xFFFFU && pure_cff )
00846         cffface->face_flags |= FT_FACE_FLAG_CID_KEYED;
00847 
00848 
00849       /*******************************************************************/
00850       /*                                                                 */
00851       /* Compute char maps.                                              */
00852       /*                                                                 */
00853 
00854       /* Try to synthesize a Unicode charmap if there is none available */
00855       /* already.  If an OpenType font contains a Unicode "cmap", we    */
00856       /* will use it, whatever be in the CFF part of the file.          */
00857       {
00858         FT_CharMapRec  cmaprec;
00859         FT_CharMap     cmap;
00860         FT_UInt        nn;
00861         CFF_Encoding   encoding = &cff->encoding;
00862 
00863 
00864         for ( nn = 0; nn < (FT_UInt)cffface->num_charmaps; nn++ )
00865         {
00866           cmap = cffface->charmaps[nn];
00867 
00868           /* Windows Unicode? */
00869           if ( cmap->platform_id == TT_PLATFORM_MICROSOFT &&
00870                cmap->encoding_id == TT_MS_ID_UNICODE_CS   )
00871             goto Skip_Unicode;
00872 
00873           /* Apple Unicode platform id? */
00874           if ( cmap->platform_id == TT_PLATFORM_APPLE_UNICODE )
00875             goto Skip_Unicode; /* Apple Unicode */
00876         }
00877 
00878         /* since CID-keyed fonts don't contain glyph names, we can't */
00879         /* construct a cmap                                          */
00880         if ( pure_cff && cff->top_font.font_dict.cid_registry != 0xFFFFU )
00881           goto Exit;
00882 
00883 #ifdef FT_MAX_CHARMAP_CACHEABLE
00884         if ( nn + 1 > FT_MAX_CHARMAP_CACHEABLE )
00885         {
00886           FT_ERROR(( "cff_face_init: no Unicode cmap is found, "
00887                      "and too many subtables (%d) to add synthesized cmap\n",
00888                      nn ));
00889           goto Exit;
00890         }
00891 #endif
00892 
00893         /* we didn't find a Unicode charmap -- synthesize one */
00894         cmaprec.face        = cffface;
00895         cmaprec.platform_id = TT_PLATFORM_MICROSOFT;
00896         cmaprec.encoding_id = TT_MS_ID_UNICODE_CS;
00897         cmaprec.encoding    = FT_ENCODING_UNICODE;
00898 
00899         nn = (FT_UInt)cffface->num_charmaps;
00900 
00901         error = FT_CMap_New( &FT_CFF_CMAP_UNICODE_CLASS_REC_GET, NULL,
00902                              &cmaprec, NULL );
00903         if ( error && FT_Err_No_Unicode_Glyph_Name != error )
00904           goto Exit;
00905         error = FT_Err_Ok;
00906 
00907         /* if no Unicode charmap was previously selected, select this one */
00908         if ( cffface->charmap == NULL && nn != (FT_UInt)cffface->num_charmaps )
00909           cffface->charmap = cffface->charmaps[nn];
00910 
00911       Skip_Unicode:
00912 #ifdef FT_MAX_CHARMAP_CACHEABLE
00913         if ( nn > FT_MAX_CHARMAP_CACHEABLE )
00914         {
00915           FT_ERROR(( "cff_face_init: Unicode cmap is found, "
00916                      "but too many preceding subtables (%d) to access\n",
00917                      nn - 1 ));
00918           goto Exit;
00919         }
00920 #endif
00921         if ( encoding->count > 0 )
00922         {
00923           FT_CMap_Class  clazz;
00924 
00925 
00926           cmaprec.face        = cffface;
00927           cmaprec.platform_id = TT_PLATFORM_ADOBE;  /* Adobe platform id */
00928 
00929           if ( encoding->offset == 0 )
00930           {
00931             cmaprec.encoding_id = TT_ADOBE_ID_STANDARD;
00932             cmaprec.encoding    = FT_ENCODING_ADOBE_STANDARD;
00933             clazz               = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET;
00934           }
00935           else if ( encoding->offset == 1 )
00936           {
00937             cmaprec.encoding_id = TT_ADOBE_ID_EXPERT;
00938             cmaprec.encoding    = FT_ENCODING_ADOBE_EXPERT;
00939             clazz               = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET;
00940           }
00941           else
00942           {
00943             cmaprec.encoding_id = TT_ADOBE_ID_CUSTOM;
00944             cmaprec.encoding    = FT_ENCODING_ADOBE_CUSTOM;
00945             clazz               = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET;
00946           }
00947 
00948           error = FT_CMap_New( clazz, NULL, &cmaprec, NULL );
00949         }
00950       }
00951     }
00952 
00953   Exit:
00954     return error;
00955 
00956   Bad_Format:
00957     error = CFF_Err_Unknown_File_Format;
00958     goto Exit;
00959   }
00960 
00961 
00962   FT_LOCAL_DEF( void )
00963   cff_face_done( FT_Face  cffface )         /* CFF_Face */
00964   {
00965     CFF_Face      face = (CFF_Face)cffface;
00966     FT_Memory     memory;
00967     SFNT_Service  sfnt;
00968 
00969 
00970     if ( !face )
00971       return;
00972 
00973     memory = cffface->memory;
00974     sfnt   = (SFNT_Service)face->sfnt;
00975 
00976     if ( sfnt )
00977       sfnt->done_face( face );
00978 
00979     {
00980       CFF_Font  cff = (CFF_Font)face->extra.data;
00981 
00982 
00983       if ( cff )
00984       {
00985         cff_font_done( cff );
00986         FT_FREE( face->extra.data );
00987       }
00988     }
00989   }
00990 
00991 
00992   FT_LOCAL_DEF( FT_Error )
00993   cff_driver_init( FT_Module  module )
00994   {
00995     FT_UNUSED( module );
00996 
00997     return CFF_Err_Ok;
00998   }
00999 
01000 
01001   FT_LOCAL_DEF( void )
01002   cff_driver_done( FT_Module  module )
01003   {
01004     FT_UNUSED( module );
01005   }
01006 
01007 
01008 /* END */

Generated on Sun May 27 2012 04:33:49 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.