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

afwarp.c
Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  afwarp.c                                                               */
00004 /*                                                                         */
00005 /*    Auto-fitter warping algorithm (body).                                */
00006 /*                                                                         */
00007 /*  Copyright 2006, 2007 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 "afwarp.h"
00020 
00021 #ifdef AF_USE_WARPER
00022 
00023 #if 1
00024   static const AF_WarpScore
00025   af_warper_weights[64] =
00026   {
00027     35, 32, 30, 25, 20, 15, 12, 10,  5,  1,  0,  0,  0,  0,  0,  0,
00028      0,  0,  0,  0,  0,  0, -1, -2, -5, -8,-10,-10,-20,-20,-30,-30,
00029 
00030    -30,-30,-20,-20,-10,-10, -8, -5, -2, -1,  0,  0,  0,  0,  0,  0,
00031      0,  0,  0,  0,  0,  0,  0,  1,  5, 10, 12, 15, 20, 25, 30, 32,
00032   };
00033 #else
00034   static const AF_WarpScore
00035   af_warper_weights[64] =
00036   {
00037     30, 20, 10,  5,  4,  4,  3,  2,  1,  0,  0,  0,  0,  0,  0,  0,
00038      0,  0,  0,  0,  0,  0,  0, -1, -2, -2, -5, -5,-10,-10,-15,-20,
00039 
00040    -20,-15,-15,-10,-10, -5, -5, -2, -2, -1,  0,  0,  0,  0,  0,  0,
00041      0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,  4,  4,  5, 10, 20,
00042   };
00043 #endif
00044 
00045 
00046   static void
00047   af_warper_compute_line_best( AF_Warper     warper,
00048                                FT_Fixed      scale,
00049                                FT_Pos        delta,
00050                                FT_Pos        xx1,
00051                                FT_Pos        xx2,
00052                                AF_WarpScore  base_distort,
00053                                AF_Segment    segments,
00054                                FT_UInt       num_segments )
00055   {
00056     FT_Int        idx_min, idx_max, idx0;
00057     FT_UInt       nn;
00058     AF_WarpScore  scores[65];
00059 
00060 
00061     for ( nn = 0; nn < 65; nn++ )
00062       scores[nn] = 0;
00063 
00064     idx0 = xx1 - warper->t1;
00065 
00066     /* compute minimum and maximum indices */
00067     {
00068       FT_Pos  xx1min = warper->x1min;
00069       FT_Pos  xx1max = warper->x1max;
00070       FT_Pos  w      = xx2 - xx1;
00071 
00072 
00073       if ( xx1min + w < warper->x2min )
00074         xx1min = warper->x2min - w;
00075 
00076       xx1max = warper->x1max;
00077       if ( xx1max + w > warper->x2max )
00078         xx1max = warper->x2max - w;
00079 
00080       idx_min = xx1min - warper->t1;
00081       idx_max = xx1max - warper->t1;
00082 
00083       if ( idx_min < 0 || idx_min > idx_max || idx_max > 64 )
00084       {
00085         AF_LOG(( "invalid indices:\n"
00086                  "  min=%d max=%d, xx1=%ld xx2=%ld,\n"
00087                  "  x1min=%ld x1max=%ld, x2min=%ld x2max=%ld\n",
00088                  idx_min, idx_max, xx1, xx2,
00089                  warper->x1min, warper->x1max,
00090                  warper->x2min, warper->x2max ));
00091         return;
00092       }
00093     }
00094 
00095     for ( nn = 0; nn < num_segments; nn++ )
00096     {
00097       FT_Pos  len = segments[nn].max_coord - segments[nn].min_coord;
00098       FT_Pos  y0  = FT_MulFix( segments[nn].pos, scale ) + delta;
00099       FT_Pos  y   = y0 + ( idx_min - idx0 );
00100       FT_Int  idx;
00101 
00102 
00103       for ( idx = idx_min; idx <= idx_max; idx++, y++ )
00104         scores[idx] += af_warper_weights[y & 63] * len;
00105     }
00106 
00107     /* find best score */
00108     {
00109       FT_Int  idx;
00110 
00111 
00112       for ( idx = idx_min; idx <= idx_max; idx++ )
00113       {
00114         AF_WarpScore  score = scores[idx];
00115         AF_WarpScore  distort = base_distort + ( idx - idx0 );
00116 
00117 
00118         if ( score > warper->best_score           ||
00119              ( score == warper->best_score    &&
00120                distort < warper->best_distort )   )
00121         {
00122           warper->best_score   = score;
00123           warper->best_distort = distort;
00124           warper->best_scale   = scale;
00125           warper->best_delta   = delta + ( idx - idx0 );
00126         }
00127       }
00128     }
00129   }
00130 
00131 
00132   FT_LOCAL_DEF( void )
00133   af_warper_compute( AF_Warper      warper,
00134                      AF_GlyphHints  hints,
00135                      AF_Dimension   dim,
00136                      FT_Fixed      *a_scale,
00137                      FT_Pos        *a_delta )
00138   {
00139     AF_AxisHints  axis;
00140     AF_Point      points;
00141 
00142     FT_Fixed      org_scale;
00143     FT_Pos        org_delta;
00144 
00145     FT_UInt       nn, num_points, num_segments;
00146     FT_Int        X1, X2;
00147     FT_Int        w;
00148 
00149     AF_WarpScore  base_distort;
00150     AF_Segment    segments;
00151 
00152 
00153     /* get original scaling transformation */
00154     if ( dim == AF_DIMENSION_VERT )
00155     {
00156       org_scale = hints->y_scale;
00157       org_delta = hints->y_delta;
00158     }
00159     else
00160     {
00161       org_scale = hints->x_scale;
00162       org_delta = hints->x_delta;
00163     }
00164 
00165     warper->best_scale   = org_scale;
00166     warper->best_delta   = org_delta;
00167     warper->best_score   = INT_MIN;
00168     warper->best_distort = 0;
00169 
00170     axis         = &hints->axis[dim];
00171     segments     = axis->segments;
00172     num_segments = axis->num_segments;
00173     points       = hints->points;
00174     num_points   = hints->num_points;
00175 
00176     *a_scale = org_scale;
00177     *a_delta = org_delta;
00178 
00179     /* get X1 and X2, minimum and maximum in original coordinates */
00180     if ( num_segments < 1 )
00181       return;
00182 
00183 #if 1
00184     X1 = X2 = points[0].fx;
00185     for ( nn = 1; nn < num_points; nn++ )
00186     {
00187       FT_Int  X = points[nn].fx;
00188 
00189 
00190       if ( X < X1 )
00191         X1 = X;
00192       if ( X > X2 )
00193         X2 = X;
00194     }
00195 #else
00196     X1 = X2 = segments[0].pos;
00197     for ( nn = 1; nn < num_segments; nn++ )
00198     {
00199       FT_Int  X = segments[nn].pos;
00200 
00201 
00202       if ( X < X1 )
00203         X1 = X;
00204       if ( X > X2 )
00205         X2 = X;
00206     }
00207 #endif
00208 
00209     if ( X1 >= X2 )
00210       return;
00211 
00212     warper->x1 = FT_MulFix( X1, org_scale ) + org_delta;
00213     warper->x2 = FT_MulFix( X2, org_scale ) + org_delta;
00214 
00215     warper->t1 = AF_WARPER_FLOOR( warper->x1 );
00216     warper->t2 = AF_WARPER_CEIL( warper->x2 );
00217 
00218     warper->x1min = warper->x1 & ~31;
00219     warper->x1max = warper->x1min + 32;
00220     warper->x2min = warper->x2 & ~31;
00221     warper->x2max = warper->x2min + 32;
00222 
00223     if ( warper->x1max > warper->x2 )
00224       warper->x1max = warper->x2;
00225 
00226     if ( warper->x2min < warper->x1 )
00227       warper->x2min = warper->x1;
00228 
00229     warper->w0 = warper->x2 - warper->x1;
00230 
00231     if ( warper->w0 <= 64 )
00232     {
00233       warper->x1max = warper->x1;
00234       warper->x2min = warper->x2;
00235     }
00236 
00237     warper->wmin = warper->x2min - warper->x1max;
00238     warper->wmax = warper->x2max - warper->x1min;
00239 
00240 #if 1
00241     {
00242       int  margin = 16;
00243 
00244 
00245       if ( warper->w0 <= 128 )
00246       {
00247          margin = 8;
00248          if ( warper->w0 <= 96 )
00249            margin = 4;
00250       }
00251 
00252       if ( warper->wmin < warper->w0 - margin )
00253         warper->wmin = warper->w0 - margin;
00254 
00255       if ( warper->wmax > warper->w0 + margin )
00256         warper->wmax = warper->w0 + margin;
00257     }
00258 
00259     if ( warper->wmin < warper->w0 * 3 / 4 )
00260       warper->wmin = warper->w0 * 3 / 4;
00261 
00262     if ( warper->wmax > warper->w0 * 5 / 4 )
00263       warper->wmax = warper->w0 * 5 / 4;
00264 #else
00265     /* no scaling, just translation */
00266     warper->wmin = warper->wmax = warper->w0;
00267 #endif
00268 
00269     for ( w = warper->wmin; w <= warper->wmax; w++ )
00270     {
00271       FT_Fixed  new_scale;
00272       FT_Pos    new_delta;
00273       FT_Pos    xx1, xx2;
00274 
00275 
00276       xx1 = warper->x1;
00277       xx2 = warper->x2;
00278       if ( w >= warper->w0 )
00279       {
00280         xx1 -= w - warper->w0;
00281         if ( xx1 < warper->x1min )
00282         {
00283           xx2 += warper->x1min - xx1;
00284           xx1  = warper->x1min;
00285         }
00286       }
00287       else
00288       {
00289         xx1 -= w - warper->w0;
00290         if ( xx1 > warper->x1max )
00291         {
00292           xx2 -= xx1 - warper->x1max;
00293           xx1  = warper->x1max;
00294         }
00295       }
00296 
00297       if ( xx1 < warper->x1 )
00298         base_distort = warper->x1 - xx1;
00299       else
00300         base_distort = xx1 - warper->x1;
00301 
00302       if ( xx2 < warper->x2 )
00303         base_distort += warper->x2 - xx2;
00304       else
00305         base_distort += xx2 - warper->x2;
00306 
00307       base_distort *= 10;
00308 
00309       new_scale = org_scale + FT_DivFix( w - warper->w0, X2 - X1 );
00310       new_delta = xx1 - FT_MulFix( X1, new_scale );
00311 
00312       af_warper_compute_line_best( warper, new_scale, new_delta, xx1, xx2,
00313                                    base_distort,
00314                                    segments, num_segments );
00315     }
00316 
00317     {
00318       FT_Fixed  best_scale = warper->best_scale;
00319       FT_Pos    best_delta = warper->best_delta;
00320      
00321 
00322       hints->xmin_delta = FT_MulFix( X1, best_scale - org_scale )
00323                           + best_delta;
00324       hints->xmax_delta = FT_MulFix( X2, best_scale - org_scale )
00325                           + best_delta;
00326 
00327       *a_scale = best_scale;
00328       *a_delta = best_delta;
00329     }
00330   }
00331 
00332 #else /* !AF_USE_WARPER */
00333 
00334 char  af_warper_dummy = 0;  /* make compiler happy */
00335 
00336 #endif /* !AF_USE_WARPER */
00337 
00338 /* END */

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