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

pshglob.c
Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  pshglob.c                                                              */
00004 /*                                                                         */
00005 /*    PostScript hinter global hinting management (body).                  */
00006 /*    Inspired by the new auto-hinter module.                              */
00007 /*                                                                         */
00008 /*  Copyright 2001, 2002, 2003, 2004, 2006, 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_FREETYPE_H
00022 #include FT_INTERNAL_OBJECTS_H
00023 #include "pshglob.h"
00024 
00025 #ifdef DEBUG_HINTER
00026   PSH_Globals  ps_debug_globals = 0;
00027 #endif
00028 
00029 
00030   /*************************************************************************/
00031   /*************************************************************************/
00032   /*****                                                               *****/
00033   /*****                       STANDARD WIDTHS                         *****/
00034   /*****                                                               *****/
00035   /*************************************************************************/
00036   /*************************************************************************/
00037 
00038 
00039   /* scale the widths/heights table */
00040   static void
00041   psh_globals_scale_widths( PSH_Globals  globals,
00042                             FT_UInt      direction )
00043   {
00044     PSH_Dimension  dim   = &globals->dimension[direction];
00045     PSH_Widths     stdw  = &dim->stdw;
00046     FT_UInt        count = stdw->count;
00047     PSH_Width      width = stdw->widths;
00048     PSH_Width      stand = width;               /* standard width/height */
00049     FT_Fixed       scale = dim->scale_mult;
00050 
00051 
00052     if ( count > 0 )
00053     {
00054       width->cur = FT_MulFix( width->org, scale );
00055       width->fit = FT_PIX_ROUND( width->cur );
00056 
00057       width++;
00058       count--;
00059 
00060       for ( ; count > 0; count--, width++ )
00061       {
00062         FT_Pos  w, dist;
00063 
00064 
00065         w    = FT_MulFix( width->org, scale );
00066         dist = w - stand->cur;
00067 
00068         if ( dist < 0 )
00069           dist = -dist;
00070 
00071         if ( dist < 128 )
00072           w = stand->cur;
00073 
00074         width->cur = w;
00075         width->fit = FT_PIX_ROUND( w );
00076       }
00077     }
00078   }
00079 
00080 
00081 #if 0
00082 
00083   /* org_width is is font units, result in device pixels, 26.6 format */
00084   FT_LOCAL_DEF( FT_Pos )
00085   psh_dimension_snap_width( PSH_Dimension  dimension,
00086                             FT_Int         org_width )
00087   {
00088     FT_UInt  n;
00089     FT_Pos   width     = FT_MulFix( org_width, dimension->scale_mult );
00090     FT_Pos   best      = 64 + 32 + 2;
00091     FT_Pos   reference = width;
00092 
00093 
00094     for ( n = 0; n < dimension->stdw.count; n++ )
00095     {
00096       FT_Pos  w;
00097       FT_Pos  dist;
00098 
00099 
00100       w = dimension->stdw.widths[n].cur;
00101       dist = width - w;
00102       if ( dist < 0 )
00103         dist = -dist;
00104       if ( dist < best )
00105       {
00106         best      = dist;
00107         reference = w;
00108       }
00109     }
00110 
00111     if ( width >= reference )
00112     {
00113       width -= 0x21;
00114       if ( width < reference )
00115         width = reference;
00116     }
00117     else
00118     {
00119       width += 0x21;
00120       if ( width > reference )
00121         width = reference;
00122     }
00123 
00124     return width;
00125   }
00126 
00127 #endif /* 0 */
00128 
00129 
00130   /*************************************************************************/
00131   /*************************************************************************/
00132   /*****                                                               *****/
00133   /*****                       BLUE ZONES                              *****/
00134   /*****                                                               *****/
00135   /*************************************************************************/
00136   /*************************************************************************/
00137 
00138   static void
00139   psh_blues_set_zones_0( PSH_Blues       target,
00140                          FT_Bool         is_others,
00141                          FT_UInt         read_count,
00142                          FT_Short*       read,
00143                          PSH_Blue_Table  top_table,
00144                          PSH_Blue_Table  bot_table )
00145   {
00146     FT_UInt  count_top = top_table->count;
00147     FT_UInt  count_bot = bot_table->count;
00148     FT_Bool  first     = 1;
00149 
00150     FT_UNUSED( target );
00151 
00152 
00153     for ( ; read_count > 1; read_count -= 2 )
00154     {
00155       FT_Int         reference, delta;
00156       FT_UInt        count;
00157       PSH_Blue_Zone  zones, zone;
00158       FT_Bool        top;
00159 
00160 
00161       /* read blue zone entry, and select target top/bottom zone */
00162       top = 0;
00163       if ( first || is_others )
00164       {
00165         reference = read[1];
00166         delta     = read[0] - reference;
00167 
00168         zones = bot_table->zones;
00169         count = count_bot;
00170         first = 0;
00171       }
00172       else
00173       {
00174         reference = read[0];
00175         delta     = read[1] - reference;
00176 
00177         zones = top_table->zones;
00178         count = count_top;
00179         top   = 1;
00180       }
00181 
00182       /* insert into sorted table */
00183       zone = zones;
00184       for ( ; count > 0; count--, zone++ )
00185       {
00186         if ( reference < zone->org_ref )
00187           break;
00188 
00189         if ( reference == zone->org_ref )
00190         {
00191           FT_Int  delta0 = zone->org_delta;
00192 
00193 
00194           /* we have two zones on the same reference position -- */
00195           /* only keep the largest one                           */
00196           if ( delta < 0 )
00197           {
00198             if ( delta < delta0 )
00199               zone->org_delta = delta;
00200           }
00201           else
00202           {
00203             if ( delta > delta0 )
00204               zone->org_delta = delta;
00205           }
00206           goto Skip;
00207         }
00208       }
00209 
00210       for ( ; count > 0; count-- )
00211         zone[count] = zone[count-1];
00212 
00213       zone->org_ref   = reference;
00214       zone->org_delta = delta;
00215 
00216       if ( top )
00217         count_top++;
00218       else
00219         count_bot++;
00220 
00221     Skip:
00222       read += 2;
00223     }
00224 
00225     top_table->count = count_top;
00226     bot_table->count = count_bot;
00227   }
00228 
00229 
00230   /* Re-read blue zones from the original fonts and store them into out */
00231   /* private structure.  This function re-orders, sanitizes and         */
00232   /* fuzz-expands the zones as well.                                    */
00233   static void
00234   psh_blues_set_zones( PSH_Blues  target,
00235                        FT_UInt    count,
00236                        FT_Short*  blues,
00237                        FT_UInt    count_others,
00238                        FT_Short*  other_blues,
00239                        FT_Int     fuzz,
00240                        FT_Int     family )
00241   {
00242     PSH_Blue_Table  top_table, bot_table;
00243     FT_Int          count_top, count_bot;
00244 
00245 
00246     if ( family )
00247     {
00248       top_table = &target->family_top;
00249       bot_table = &target->family_bottom;
00250     }
00251     else
00252     {
00253       top_table = &target->normal_top;
00254       bot_table = &target->normal_bottom;
00255     }
00256 
00257     /* read the input blue zones, and build two sorted tables  */
00258     /* (one for the top zones, the other for the bottom zones) */
00259     top_table->count = 0;
00260     bot_table->count = 0;
00261 
00262     /* first, the blues */
00263     psh_blues_set_zones_0( target, 0,
00264                            count, blues, top_table, bot_table );
00265     psh_blues_set_zones_0( target, 1,
00266                            count_others, other_blues, top_table, bot_table );
00267 
00268     count_top = top_table->count;
00269     count_bot = bot_table->count;
00270 
00271     /* sanitize top table */
00272     if ( count_top > 0 )
00273     {
00274       PSH_Blue_Zone  zone = top_table->zones;
00275 
00276 
00277       for ( count = count_top; count > 0; count--, zone++ )
00278       {
00279         FT_Int  delta;
00280 
00281 
00282         if ( count > 1 )
00283         {
00284           delta = zone[1].org_ref - zone[0].org_ref;
00285           if ( zone->org_delta > delta )
00286             zone->org_delta = delta;
00287         }
00288 
00289         zone->org_bottom = zone->org_ref;
00290         zone->org_top    = zone->org_delta + zone->org_ref;
00291       }
00292     }
00293 
00294     /* sanitize bottom table */
00295     if ( count_bot > 0 )
00296     {
00297       PSH_Blue_Zone  zone = bot_table->zones;
00298 
00299 
00300       for ( count = count_bot; count > 0; count--, zone++ )
00301       {
00302         FT_Int  delta;
00303 
00304 
00305         if ( count > 1 )
00306         {
00307           delta = zone[0].org_ref - zone[1].org_ref;
00308           if ( zone->org_delta < delta )
00309             zone->org_delta = delta;
00310         }
00311 
00312         zone->org_top    = zone->org_ref;
00313         zone->org_bottom = zone->org_delta + zone->org_ref;
00314       }
00315     }
00316 
00317     /* expand top and bottom tables with blue fuzz */
00318     {
00319       FT_Int         dim, top, bot, delta;
00320       PSH_Blue_Zone  zone;
00321 
00322 
00323       zone  = top_table->zones;
00324       count = count_top;
00325 
00326       for ( dim = 1; dim >= 0; dim-- )
00327       {
00328         if ( count > 0 )
00329         {
00330           /* expand the bottom of the lowest zone normally */
00331           zone->org_bottom -= fuzz;
00332 
00333           /* expand the top and bottom of intermediate zones;    */
00334           /* checking that the interval is smaller than the fuzz */
00335           top = zone->org_top;
00336 
00337           for ( count--; count > 0; count-- )
00338           {
00339             bot   = zone[1].org_bottom;
00340             delta = bot - top;
00341 
00342             if ( delta < 2 * fuzz )
00343               zone[0].org_top = zone[1].org_bottom = top + delta / 2;
00344             else
00345             {
00346               zone[0].org_top    = top + fuzz;
00347               zone[1].org_bottom = bot - fuzz;
00348             }
00349 
00350             zone++;
00351             top = zone->org_top;
00352           }
00353 
00354           /* expand the top of the highest zone normally */
00355           zone->org_top = top + fuzz;
00356         }
00357         zone  = bot_table->zones;
00358         count = count_bot;
00359       }
00360     }
00361   }
00362 
00363 
00364   /* reset the blues table when the device transform changes */
00365   static void
00366   psh_blues_scale_zones( PSH_Blues  blues,
00367                          FT_Fixed   scale,
00368                          FT_Pos     delta )
00369   {
00370     FT_UInt         count;
00371     FT_UInt         num;
00372     PSH_Blue_Table  table = 0;
00373 
00374     /*                                                        */
00375     /* Determine whether we need to suppress overshoots or    */
00376     /* not.  We simply need to compare the vertical scale     */
00377     /* parameter to the raw bluescale value.  Here is why:    */
00378     /*                                                        */
00379     /*   We need to suppress overshoots for all pointsizes.   */
00380     /*   At 300dpi that satisfies:                            */
00381     /*                                                        */
00382     /*      pointsize < 240*bluescale + 0.49                  */
00383     /*                                                        */
00384     /*   This corresponds to:                                 */
00385     /*                                                        */
00386     /*      pixelsize < 1000*bluescale + 49/24                */
00387     /*                                                        */
00388     /*      scale*EM_Size < 1000*bluescale + 49/24            */
00389     /*                                                        */
00390     /*   However, for normal Type 1 fonts, EM_Size is 1000!   */
00391     /*   We thus only check:                                  */
00392     /*                                                        */
00393     /*      scale < bluescale + 49/24000                      */
00394     /*                                                        */
00395     /*   which we shorten to                                  */
00396     /*                                                        */
00397     /*      "scale < bluescale"                               */
00398     /*                                                        */
00399     /* Note that `blue_scale' is stored 1000 times its real   */
00400     /* value, and that `scale' converts from font units to    */
00401     /* fractional pixels.                                     */
00402     /*                                                        */
00403 
00404     /* 1000 / 64 = 125 / 8 */
00405     if ( scale >= 0x20C49BAL )
00406       blues->no_overshoots = FT_BOOL( scale < blues->blue_scale * 8 / 125 );
00407     else
00408       blues->no_overshoots = FT_BOOL( scale * 125 < blues->blue_scale * 8 );
00409 
00410     /*                                                        */
00411     /*  The blue threshold is the font units distance under   */
00412     /*  which overshoots are suppressed due to the BlueShift  */
00413     /*  even if the scale is greater than BlueScale.          */
00414     /*                                                        */
00415     /*  It is the smallest distance such that                 */
00416     /*                                                        */
00417     /*    dist <= BlueShift && dist*scale <= 0.5 pixels       */
00418     /*                                                        */
00419     {
00420       FT_Int  threshold = blues->blue_shift;
00421 
00422 
00423       while ( threshold > 0 && FT_MulFix( threshold, scale ) > 32 )
00424         threshold--;
00425 
00426       blues->blue_threshold = threshold;
00427     }
00428 
00429     for ( num = 0; num < 4; num++ )
00430     {
00431       PSH_Blue_Zone  zone;
00432 
00433 
00434       switch ( num )
00435       {
00436       case 0:
00437         table = &blues->normal_top;
00438         break;
00439       case 1:
00440         table = &blues->normal_bottom;
00441         break;
00442       case 2:
00443         table = &blues->family_top;
00444         break;
00445       default:
00446         table = &blues->family_bottom;
00447         break;
00448       }
00449 
00450       zone  = table->zones;
00451       count = table->count;
00452       for ( ; count > 0; count--, zone++ )
00453       {
00454         zone->cur_top    = FT_MulFix( zone->org_top,    scale ) + delta;
00455         zone->cur_bottom = FT_MulFix( zone->org_bottom, scale ) + delta;
00456         zone->cur_ref    = FT_MulFix( zone->org_ref,    scale ) + delta;
00457         zone->cur_delta  = FT_MulFix( zone->org_delta,  scale );
00458 
00459         /* round scaled reference position */
00460         zone->cur_ref = FT_PIX_ROUND( zone->cur_ref );
00461 
00462 #if 0
00463         if ( zone->cur_ref > zone->cur_top )
00464           zone->cur_ref -= 64;
00465         else if ( zone->cur_ref < zone->cur_bottom )
00466           zone->cur_ref += 64;
00467 #endif
00468       }
00469     }
00470 
00471     /* process the families now */
00472 
00473     for ( num = 0; num < 2; num++ )
00474     {
00475       PSH_Blue_Zone   zone1, zone2;
00476       FT_UInt         count1, count2;
00477       PSH_Blue_Table  normal, family;
00478 
00479 
00480       switch ( num )
00481       {
00482       case 0:
00483         normal = &blues->normal_top;
00484         family = &blues->family_top;
00485         break;
00486 
00487       default:
00488         normal = &blues->normal_bottom;
00489         family = &blues->family_bottom;
00490       }
00491 
00492       zone1  = normal->zones;
00493       count1 = normal->count;
00494 
00495       for ( ; count1 > 0; count1--, zone1++ )
00496       {
00497         /* try to find a family zone whose reference position is less */
00498         /* than 1 pixel far from the current zone                     */
00499         zone2  = family->zones;
00500         count2 = family->count;
00501 
00502         for ( ; count2 > 0; count2--, zone2++ )
00503         {
00504           FT_Pos  Delta;
00505 
00506 
00507           Delta = zone1->org_ref - zone2->org_ref;
00508           if ( Delta < 0 )
00509             Delta = -Delta;
00510 
00511           if ( FT_MulFix( Delta, scale ) < 64 )
00512           {
00513             zone1->cur_top    = zone2->cur_top;
00514             zone1->cur_bottom = zone2->cur_bottom;
00515             zone1->cur_ref    = zone2->cur_ref;
00516             zone1->cur_delta  = zone2->cur_delta;
00517             break;
00518           }
00519         }
00520       }
00521     }
00522   }
00523 
00524 
00525   FT_LOCAL_DEF( void )
00526   psh_blues_snap_stem( PSH_Blues      blues,
00527                        FT_Int         stem_top,
00528                        FT_Int         stem_bot,
00529                        PSH_Alignment  alignment )
00530   {
00531     PSH_Blue_Table  table;
00532     FT_UInt         count;
00533     FT_Pos          delta;
00534     PSH_Blue_Zone   zone;
00535     FT_Int          no_shoots;
00536 
00537 
00538     alignment->align = PSH_BLUE_ALIGN_NONE;
00539 
00540     no_shoots = blues->no_overshoots;
00541 
00542     /* look up stem top in top zones table */
00543     table = &blues->normal_top;
00544     count = table->count;
00545     zone  = table->zones;
00546 
00547     for ( ; count > 0; count--, zone++ )
00548     {
00549       delta = stem_top - zone->org_bottom;
00550       if ( delta < -blues->blue_fuzz )
00551         break;
00552 
00553       if ( stem_top <= zone->org_top + blues->blue_fuzz )
00554       {
00555         if ( no_shoots || delta <= blues->blue_threshold )
00556         {
00557           alignment->align    |= PSH_BLUE_ALIGN_TOP;
00558           alignment->align_top = zone->cur_ref;
00559         }
00560         break;
00561       }
00562     }
00563 
00564     /* look up stem bottom in bottom zones table */
00565     table = &blues->normal_bottom;
00566     count = table->count;
00567     zone  = table->zones + count-1;
00568 
00569     for ( ; count > 0; count--, zone-- )
00570     {
00571       delta = zone->org_top - stem_bot;
00572       if ( delta < -blues->blue_fuzz )
00573         break;
00574 
00575       if ( stem_bot >= zone->org_bottom - blues->blue_fuzz )
00576       {
00577         if ( no_shoots || delta < blues->blue_threshold )
00578         {
00579           alignment->align    |= PSH_BLUE_ALIGN_BOT;
00580           alignment->align_bot = zone->cur_ref;
00581         }
00582         break;
00583       }
00584     }
00585   }
00586 
00587 
00588   /*************************************************************************/
00589   /*************************************************************************/
00590   /*****                                                               *****/
00591   /*****                        GLOBAL HINTS                           *****/
00592   /*****                                                               *****/
00593   /*************************************************************************/
00594   /*************************************************************************/
00595 
00596   static void
00597   psh_globals_destroy( PSH_Globals  globals )
00598   {
00599     if ( globals )
00600     {
00601       FT_Memory  memory;
00602 
00603 
00604       memory = globals->memory;
00605       globals->dimension[0].stdw.count = 0;
00606       globals->dimension[1].stdw.count = 0;
00607 
00608       globals->blues.normal_top.count    = 0;
00609       globals->blues.normal_bottom.count = 0;
00610       globals->blues.family_top.count    = 0;
00611       globals->blues.family_bottom.count = 0;
00612 
00613       FT_FREE( globals );
00614 
00615 #ifdef DEBUG_HINTER
00616       ps_debug_globals = 0;
00617 #endif
00618     }
00619   }
00620 
00621 
00622   static FT_Error
00623   psh_globals_new( FT_Memory     memory,
00624                    T1_Private*   priv,
00625                    PSH_Globals  *aglobals )
00626   {
00627     PSH_Globals  globals = NULL;
00628     FT_Error     error;
00629 
00630 
00631     if ( !FT_NEW( globals ) )
00632     {
00633       FT_UInt    count;
00634       FT_Short*  read;
00635 
00636 
00637       globals->memory = memory;
00638 
00639       /* copy standard widths */
00640       {
00641         PSH_Dimension  dim   = &globals->dimension[1];
00642         PSH_Width      write = dim->stdw.widths;
00643 
00644 
00645         write->org = priv->standard_width[0];
00646         write++;
00647 
00648         read = priv->snap_widths;
00649         for ( count = priv->num_snap_widths; count > 0; count-- )
00650         {
00651           write->org = *read;
00652           write++;
00653           read++;
00654         }
00655 
00656         dim->stdw.count = priv->num_snap_widths + 1;
00657       }
00658 
00659       /* copy standard heights */
00660       {
00661         PSH_Dimension  dim = &globals->dimension[0];
00662         PSH_Width      write = dim->stdw.widths;
00663 
00664 
00665         write->org = priv->standard_height[0];
00666         write++;
00667         read = priv->snap_heights;
00668         for ( count = priv->num_snap_heights; count > 0; count-- )
00669         {
00670           write->org = *read;
00671           write++;
00672           read++;
00673         }
00674 
00675         dim->stdw.count = priv->num_snap_heights + 1;
00676       }
00677 
00678       /* copy blue zones */
00679       psh_blues_set_zones( &globals->blues, priv->num_blue_values,
00680                            priv->blue_values, priv->num_other_blues,
00681                            priv->other_blues, priv->blue_fuzz, 0 );
00682 
00683       psh_blues_set_zones( &globals->blues, priv->num_family_blues,
00684                            priv->family_blues, priv->num_family_other_blues,
00685                            priv->family_other_blues, priv->blue_fuzz, 1 );
00686 
00687       globals->blues.blue_scale = priv->blue_scale;
00688       globals->blues.blue_shift = priv->blue_shift;
00689       globals->blues.blue_fuzz  = priv->blue_fuzz;
00690 
00691       globals->dimension[0].scale_mult  = 0;
00692       globals->dimension[0].scale_delta = 0;
00693       globals->dimension[1].scale_mult  = 0;
00694       globals->dimension[1].scale_delta = 0;
00695 
00696 #ifdef DEBUG_HINTER
00697       ps_debug_globals = globals;
00698 #endif
00699     }
00700 
00701     *aglobals = globals;
00702     return error;
00703   }
00704 
00705 
00706   FT_LOCAL_DEF( FT_Error )
00707   psh_globals_set_scale( PSH_Globals  globals,
00708                          FT_Fixed     x_scale,
00709                          FT_Fixed     y_scale,
00710                          FT_Fixed     x_delta,
00711                          FT_Fixed     y_delta )
00712   {
00713     PSH_Dimension  dim = &globals->dimension[0];
00714 
00715 
00716     dim = &globals->dimension[0];
00717     if ( x_scale != dim->scale_mult  ||
00718          x_delta != dim->scale_delta )
00719     {
00720       dim->scale_mult  = x_scale;
00721       dim->scale_delta = x_delta;
00722 
00723       psh_globals_scale_widths( globals, 0 );
00724     }
00725 
00726     dim = &globals->dimension[1];
00727     if ( y_scale != dim->scale_mult  ||
00728          y_delta != dim->scale_delta )
00729     {
00730       dim->scale_mult  = y_scale;
00731       dim->scale_delta = y_delta;
00732 
00733       psh_globals_scale_widths( globals, 1 );
00734       psh_blues_scale_zones( &globals->blues, y_scale, y_delta );
00735     }
00736 
00737     return 0;
00738   }
00739 
00740 
00741   FT_LOCAL_DEF( void )
00742   psh_globals_funcs_init( PSH_Globals_FuncsRec*  funcs )
00743   {
00744     funcs->create    = psh_globals_new;
00745     funcs->set_scale = psh_globals_set_scale;
00746     funcs->destroy   = psh_globals_destroy;
00747   }
00748 
00749 
00750 /* END */

Generated on Sat May 26 2012 04:32:54 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.