Edit

kc3-lang/freetype/src/autofit/afhints.c

Branch :

  • Show log

    Commit

  • Author : Werner Lemberg
    Date : 2004-02-03 21:34:29
    Hash : 6b3d00e1
    Message : * src/type1/t1load.c (parse_dict): Handle `RD' and `-|' commands outside of /Subrs or /CharStrings. This can happen if there is additional code manipulating those two arrays so that FreeType doesn't recognize them properly. (T1_Open_Face): Improve an error message. Remove CR/LF on many files.

  • src/autofit/afhints.c
  • #include "afhints.h"
    
    #ifdef AF_DEBUG
    
    #include <stdio.h>
    
      void
      af_glyph_hints_dump_edges( AF_GlyphHints  hints )
      {
        AF_Edge     edges;
        AF_Edge     edge_limit;
        AF_Segment  segments;
        FT_Int      dimension;
    
    
        edges      = hints->horz_edges;
        edge_limit = edges + hints->num_hedges;
        segments   = hints->horz_segments;
    
        for ( dimension = 1; dimension >= 0; dimension-- )
        {
          AF_Edge   edge;
    
    
          printf ( "Table of %s edges:\n",
                   !dimension ? "vertical" : "horizontal" );
          printf ( "  [ index |  pos |  dir  | link |"
                   " serif | blue | opos  |  pos  ]\n" );
    
          for ( edge = edges; edge < edge_limit; edge++ )
          {
            printf ( "  [ %5d | %4d | %5s | %4d | %5d |  %c  | %5.2f | %5.2f ]\n",
                     edge - edges,
                     (int)edge->fpos,
                     edge->dir == AF_DIR_UP
                       ? "up"
                       : ( edge->dir == AF_DIR_DOWN
                             ? "down"
                             : ( edge->dir == AF_DIR_LEFT
                                   ? "left"
                                   : ( edge->dir == AF_DIR_RIGHT
                                         ? "right"
                                         : "none" ) ) ),
                     edge->link ? ( edge->link - edges ) : -1,
                     edge->serif ? ( edge->serif - edges ) : -1,
                     edge->blue_edge ? 'y' : 'n',
                     edge->opos / 64.0,
                     edge->pos / 64.0 );
          }
    
          edges      = hints->vert_edges;
          edge_limit = edges + hints->num_vedges;
          segments   = hints->vert_segments;
        }
      }
    
    
      /* A function used to dump the array of linked segments */
      void
      af_glyph_hints_dump_segments( AF_GlyphHints  hints )
      {
        AF_Segment  segments;
        AF_Segment  segment_limit;
        AF_Point    points;
        FT_Int      dimension;
    
    
        points        = hints->points;
        segments      = hints->horz_segments;
        segment_limit = segments + hints->num_hsegments;
    
        for ( dimension = 1; dimension >= 0; dimension-- )
        {
          AF_Segment  seg;
    
    
          printf ( "Table of %s segments:\n",
                   !dimension ? "vertical" : "horizontal" );
          printf ( "  [ index |  pos |  dir  | link | serif |"
                   " numl | first | start ]\n" );
    
          for ( seg = segments; seg < segment_limit; seg++ )
          {
            printf ( "  [ %5d | %4d | %5s | %4d | %5d | %4d | %5d | %5d ]\n",
                     seg - segments,
                     (int)seg->pos,
                     seg->dir == AF_DIR_UP
                       ? "up"
                       : ( seg->dir == AF_DIR_DOWN
                             ? "down"
                             : ( seg->dir == AF_DIR_LEFT
                                   ? "left"
                                   : ( seg->dir == AF_DIR_RIGHT
                                         ? "right"
                                         : "none" ) ) ),
                     seg->link ? ( seg->link - segments ) : -1,
                     seg->serif ? ( seg->serif - segments ) : -1,
                     (int)seg->num_linked,
                     seg->first - points,
                     seg->last - points );
          }
    
          segments      = hints->vert_segments;
          segment_limit = segments + hints->num_vsegments;
        }
      }
    
    #endif /* AF_DEBUG */
    
    
      /* compute the direction value of a given vector */
      FT_LOCAL_DEF( AF_Direction )
      af_direction_compute( FT_Pos  dx,
                            FT_Pos  dy )
      {
        AF_Direction  dir;
        FT_Pos        ax = ABS( dx );
        FT_Pos        ay = ABS( dy );
    
    
        dir = AF_DIR_NONE;
    
        /* atan(1/12) == 4.7 degrees */
    
        /* test for vertical direction */
        if ( ax * 12 < ay )
        {
          dir = dy > 0 ? AF_DIR_UP : AF_DIR_DOWN;
        }
        /* test for horizontal direction */
        else if ( ay * 12 < ax )
        {
          dir = dx > 0 ? AF_DIR_RIGHT : AF_DIR_LEFT;
        }
    
        return dir;
      }
    
    
      /* compute all inflex points in a given glyph */
      static void
      af_glyph_hints_compute_inflections( AF_GlyphHints  hints )
      {
        AF_Point*  contour       = hints->contours;
        AF_Point*  contour_limit = contour + hints->num_contours;
    
    
        /* do each contour separately */
        for ( ; contour < contour_limit; contour++ )
        {
          AF_Point   point = contour[0];
          AF_Point   first = point;
          AF_Point   start = point;
          AF_Point   end   = point;
          AF_Point   before;
          AF_Point   after;
          AF_Angle   angle_in, angle_seg, angle_out;
          AF_Angle   diff_in, diff_out;
          FT_Int     finished = 0;
    
    
          /* compute first segment in contour */
          first = point;
    
          start = end = first;
          do
          {
            end = end->next;
            if ( end == first )
              goto Skip;
    
          } while ( end->fx == first->fx && end->fy == first->fy );
    
          angle_seg = af_angle_atan( end->fx - start->fx,
                                     end->fy - start->fy );
    
          /* extend the segment start whenever possible */
          before = start;
          do
          {
            do
            {
              start  = before;
              before = before->prev;
              if ( before == first )
                goto Skip;
    
            } while ( before->fx == start->fx && before->fy == start->fy );
    
            angle_in = af_angle_atan( start->fx - before->fx,
                                      start->fy - before->fy );
    
          } while ( angle_in == angle_seg );
    
          first   = start;
          diff_in = af_angle_diff( angle_in, angle_seg );
    
          /* now, process all segments in the contour */
          do
          {
            /* first, extend current segment's end whenever possible */
            after = end;
            do
            {
              do
              {
                end   = after;
                after = after->next;
                if ( after == first )
                  finished = 1;
    
              } while ( end->fx == after->fx && end->fy == after->fy );
    
              angle_out = af_angle_atan( after->fx - end->fx,
                                         after->fy - end->fy );
    
            } while ( angle_out == angle_seg );
    
            diff_out = af_angle_diff( angle_seg, angle_out );
    
            if ( ( diff_in ^ diff_out ) < 0 )
            {
              /* diff_in and diff_out have different signs, we have */
              /* inflection points here...                          */
              do
              {
                start->flags |= AF_FLAG_INFLECTION;
                start = start->next;
    
              } while ( start != end );
    
              start->flags |= AF_FLAG_INFLECTION;
            }
    
            start     = end;
            end       = after;
            angle_seg = angle_out;
            diff_in   = diff_out;
    
          } while ( !finished );
    
        Skip:
          ;
        }
      }
    
    
    
      FT_LOCAL_DEF( void )
      af_glyph_hints_init( AF_GlyphHints  hints,
                           FT_Memory      memory )
      {
        FT_ZERO( hints );
        hints->memory = memory;
      }
    
    
    
      FT_LOCAL_DEF( void )
      af_glyph_hints_done( AF_GlyphHints  hints )
      {
        if ( hints && hints->memory )
        {
          FT_Memory     memory = hints->memory;
          AF_Dimension  dim;
    
         /* note that we don't need to free the segment and edge
          * buffers, since they're really within the hints->points array
          */
          for ( dim = 0; dim < 2; dim++ )
          {
            AF_AxisHints  axis = &hints->axis[ dim ];
    
            axis->num_segments = 0;
            axis->num_edges    = 0;
            axis->segments     = NULL;
            axis->edges        = NULL;
          }
    
          FT_FREE( hints->contours );
          hints->max_contours = 0;
          hints->num_contours = 0;
    
          FT_FREE( hints->points );
          hints->num_points = 0;
          hints->max_points = 0;
    
          hints->memory = NULL;
        }
      }
    
    
    
      FT_LOCAL_DEF( FT_Error )
      af_glyph_hints_reset( AF_GlyphHints  hints,
                            AF_Scaler      scaler,
                            FT_Outline*    outline )
      {
        FT_Error     error        = FT_Err_Ok;
        AF_Point     points;
        FT_UInt      old_max, new_max;
        FT_Fixed     x_scale = scaler->x_scale;
        FT_Fixed     y_scale = scaler->y_scale;
        FT_Pos       x_delta = scaler->x_delta;
        FT_Pos       y_delta = scaler->y_delta;
        FT_Memory    memory  = hints->memory;
    
        hints->scaler_flags = scaler->flags;
        hints->other_flags  = 0;
    
        hints->num_points    = 0;
        hints->num_contours  = 0;
    
        hints->axis[0].num_segments = 0;
        hints->axis[0].num_edges    = 0;
        hints->axis[1].num_segments = 0;
        hints->axis[1].num_edges    = 0;
    
       /* first of all, reallocate the contours array when necessary
        */
        new_max = (FT_UInt) outline->n_contours;
        old_max = hints->max_contours;
        if ( new_max > old_max )
        {
          new_max = (new_max + 3) & ~3;
    
          if ( FT_RENEW_ARRAY( hints->contours, old_max, new_max ) )
            goto Exit;
    
          hints->max_contours = new_max;
        }
    
       /* then, reallocate the points, segments & edges arrays if needed --
        * note that we reserved two additional point positions, used to
        * hint metrics appropriately
        */
        new_max = (FT_UInt)( outline->n_points + 2 );
        old_max = hints->max_points;
        if ( new_max > old_max )
        {
          FT_Byte*    items;
          FT_ULong    off1, off2, off3;
    
         /* we store in a single buffer the following arrays:
          *
          *  - an array of   N  AF_PointRec   items
          *  - an array of 2*N  AF_SegmentRec items
          *  - an array of 2*N  AF_EdgeRec    items
          *
          */
    
          new_max = ( new_max + 2 + 7 ) & ~7;
    
    #undef  OFF_INCREMENT
    #define OFF_INCREMENT( _off, _type, _count )   \
         ( FT_PAD_CEIL( _off, sizeof(_type) ) + (_count)*sizeof(_type))
    
          off1 = OFF_INCREMENT( 0, AF_PointRec, new_max );
          off2 = OFF_INCREMENT( off1, AF_SegmentRec, new_max );
          off3 = OFF_INCREMENT( off2, AF_EdgeRec, new_max*2 );
    
          FT_FREE( hints->points );
    
          if ( FT_ALLOC( items, off3 ) )
          {
            hints->max_points       = 0;
            hints->axis[0].segments = NULL;
            hints->axis[0].edges    = NULL;
            hints->axis[1].segments = NULL;
            hints->axis[1].edges    = NULL;
            goto Exit;
          }
    
         /* readjust some pointers
          */
          hints->max_points       = new_max;
          hints->points           = (AF_Point) items;
    
          hints->axis[0].segments = (AF_Segment)( items + off1 );
          hints->axis[1].segments = hints->axis[0].segments + new_max;
    
          hints->axis[0].edges    = (AF_Edge)   ( items + off2 );
          hints->axis[1].edges    = hints->axis[0].edges + new_max;
        }
    
        hints->num_points   = outline->n_points;
        hints->num_contours = outline->n_contours;
    
    
        /* We can't rely on the value of `FT_Outline.flags' to know the fill  */
        /* direction used for a glyph, given that some fonts are broken (e.g. */
        /* the Arphic ones).  We thus recompute it each time we need to.      */
        /*                                                                    */
        hints->axis[ AF_DIMENSION_HORZ ].major_dir = AF_DIR_UP;
        hints->axis[ AF_DIMENSION_VERT ].major_dir = AF_DIR_LEFT;
    
        if ( FT_Outline_Get_Orientation( outline ) == FT_ORIENTATION_POSTSCRIPT )
        {
          hints->axis[ AF_DIMENSION_HORZ ].major_dir = AF_DIR_DOWN;
          hints->axis[ AF_DIMENSION_VERT ].major_dir = AF_DIR_RIGHT;
        }
    
        hints->x_scale = x_scale;
        hints->y_scale = y_scale;
        hints->x_delta = x_delta;
        hints->y_delta = y_delta;
    
        points = hints->points;
        if ( hints->num_points == 0 )
          goto Exit;
    
        {
          AF_Point  point;
          AF_Point  point_limit = points + hints->num_points;
    
    
          /* compute coordinates & bezier flags */
          {
            FT_Vector*  vec = outline->points;
            char*       tag = outline->tags;
    
    
            for ( point = points; point < point_limit; point++, vec++, tag++ )
            {
              point->fx = vec->x;
              point->fy = vec->y;
              point->ox = point->x = FT_MulFix( vec->x, x_scale ) + x_delta;
              point->oy = point->y = FT_MulFix( vec->y, y_scale ) + y_delta;
    
              switch ( FT_CURVE_TAG( *tag ) )
              {
              case FT_CURVE_TAG_CONIC:
                point->flags = AF_FLAG_CONIC;
                break;
              case FT_CURVE_TAG_CUBIC:
                point->flags = AF_FLAG_CUBIC;
                break;
              default:
                point->flags = 0;
                ;
              }
            }
          }
    
          /* compute `next' and `prev' */
          {
            FT_Int    contour_index;
            AF_Point  prev;
            AF_Point  first;
            AF_Point  end;
    
    
            contour_index = 0;
    
            first = points;
            end   = points + outline->contours[0];
            prev  = end;
    
            for ( point = points; point < point_limit; point++ )
            {
              point->prev = prev;
              if ( point < end )
              {
                point->next = point + 1;
                prev        = point;
              }
              else
              {
                point->next = first;
                contour_index++;
                if ( point + 1 < point_limit )
                {
                  end   = points + outline->contours[contour_index];
                  first = point + 1;
                  prev  = end;
                }
              }
            }
          }
    
          /* set-up the contours array */
          {
            AF_Point*  contour       = hints->contours;
            AF_Point*  contour_limit = contour + hints->num_contours;
            short*     end           = outline->contours;
            short      idx           = 0;
    
    
            for ( ; contour < contour_limit; contour++, end++ )
            {
              contour[0] = points + idx;
              idx        = (short)( end[0] + 1 );
            }
          }
    
          /* compute directions of in & out vectors */
          {
            for ( point = points; point < point_limit; point++ )
            {
              AF_Point   prev;
              AF_Point   next;
              FT_Pos     in_x, in_y, out_x, out_y;
    
    
              prev   = point->prev;
              in_x   = point->fx - prev->fx;
              in_y   = point->fy - prev->fy;
    
              point->in_dir = af_direction_compute( in_x, in_y );
    
              next   = point->next;
              out_x  = next->fx - point->fx;
              out_y  = next->fy - point->fy;
    
              point->out_dir = af_direction_compute( out_x, out_y );
    
              if ( point->flags & ( AF_FLAG_CONIC | AF_FLAG_CUBIC ) )
              {
              Is_Weak_Point:
                point->flags |= AF_FLAG_WEAK_INTERPOLATION;
              }
              else if ( point->out_dir == point->in_dir )
              {
                AF_Angle  angle_in, angle_out, delta;
    
    
                if ( point->out_dir != AF_DIR_NONE )
                  goto Is_Weak_Point;
    
                angle_in  = af_angle_atan( in_x, in_y );
                angle_out = af_angle_atan( out_x, out_y );
                delta     = af_angle_diff( angle_in, angle_out );
    
                if ( delta < 2 && delta > -2 )
                  goto Is_Weak_Point;
              }
              else if ( point->in_dir == -point->out_dir )
                goto Is_Weak_Point;
            }
          }
        }
    
       /* compute inflection points
        */
        af_glyph_hints_compute_inflections( hints );
    
      Exit:
        return error;
      }
    
    
    
    
     /*
      *
      *  E D G E   P O I N T   G R I D - F I T T I N G
      *
      */
    
    
      FT_LOCAL_DEF( void )
      af_glyph_hints_align_edge_points( AF_GlyphHints  hints,
                                        AF_Dimension   dim )
      {
        AF_AxisHints  axis       = & hints->axis[ dim ];
        AF_Edge       edges      = axis->edges;
        AF_Edge       edge_limit = edges + axis->num_edges;
        AF_Edge       edge;
    
        for ( edge = edges; edge < edge_limit; edge++ )
        {
          /* move the points of each segment     */
          /* in each edge to the edge's position */
          AF_Segment  seg = edge->first;
    
    
          do
          {
            AF_Point  point = seg->first;
    
    
            for (;;)
            {
              if ( dim == AF_DIMENSION_HORZ )
              {
                point->x      = edge->pos;
                point->flags |= AF_FLAG_TOUCH_X;
              }
              else
              {
                point->y      = edge->pos;
                point->flags |= AF_FLAG_TOUCH_Y;
              }
    
              if ( point == seg->last )
                break;
    
              point = point->next;
            }
    
            seg = seg->edge_next;
    
          } while ( seg != edge->first );
        }
      }
    
    
     /*
      *
      *  S T R O N G   P O I N T   I N T E R P O L A T I O N
      *
      */
    
    
      /* hint the strong points -- this is equivalent to the TrueType `IP' */
      /* hinting instruction                                               */
      FT_LOCAL_DEF( void )
      af_glyph_hints_align_strong_points( AF_GlyphHints  hints,
                                          AF_Dimension   dim )
      {
        AF_Point      points      = hints->points;
        AF_Point      point_limit = points + hints->num_points;
        AF_AxisHints  axis        = &hints->axis[dim];
        AF_Edge       edges       = axis->edges;
        AF_Edge       edge_limit  = edges + axis->num_edges;
        AF_Flags      touch_flag;
    
    
        if ( dim == AF_DIMENSION_HORZ )
          touch_flag = AF_FLAG_TOUCH_X;
        else
          touch_flag  = AF_FLAG_TOUCH_Y;
    
        if ( edges < edge_limit )
        {
          AF_Point  point;
          AF_Edge   edge;
    
          for ( point = points; point < point_limit; point++ )
          {
            FT_Pos  u, ou, fu;  /* point position */
            FT_Pos  delta;
    
    
            if ( point->flags & touch_flag )
              continue;
    
            /* if this point is candidate to weak interpolation, we will  */
            /* interpolate it after all strong points have been processed */
            if (  ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) &&
                 !( point->flags & AF_FLAG_INFLECTION )         )
              continue;
    
            if ( dim == AF_DIMENSION_VERT )
            {
              u  = point->fy;
              ou = point->oy;
            }
            else
            {
              u  = point->fx;
              ou = point->ox;
            }
    
            fu = u;
    
            /* is the point before the first edge? */
            edge  = edges;
            delta = edge->fpos - u;
            if ( delta >= 0 )
            {
              u = edge->pos - ( edge->opos - ou );
              goto Store_Point;
            }
    
            /* is the point after the last edge? */
            edge  = edge_limit - 1;
            delta = u - edge->fpos;
            if ( delta >= 0 )
            {
              u = edge->pos + ( ou - edge->opos );
              goto Store_Point;
            }
    
            {
              FT_UInt  min, max, mid;
              FT_Pos   fpos;
    
    
              /* find enclosing edges */
              min = 0;
              max = edge_limit - edges;
    
              while ( min < max )
              {
                mid  = ( max + min ) >> 1;
                edge = edges + mid;
                fpos = edge->fpos;
    
                if ( u < fpos )
                  max = mid;
                else if ( u > fpos )
                  min = mid + 1;
                else
                {
                  /* we are on the edge */
                  u = edge->pos;
                  goto Store_Point;
                }
              }
    
              {
                AF_Edge  before = edges + min - 1;
                AF_Edge  after  = edges + min + 0;
    
    
                /* assert( before && after && before != after ) */
                if ( before->scale == 0 )
                  before->scale = FT_DivFix( after->pos - before->pos,
                                             after->fpos - before->fpos );
    
                u = before->pos + FT_MulFix( fu - before->fpos,
                                             before->scale );
              }
            }
    
    
          Store_Point:
    
            /* save the point position */
            if ( dim == AF_DIMENSION_HORZ )
              point->x = u;
            else
              point->y = u;
    
            point->flags |= touch_flag;
          }
        }
      }
    
    
     /*
      *
      *  W E A K   P O I N T   I N T E R P O L A T I O N
      *
      */
    
      static void
      af_iup_shift( AF_Point  p1,
                    AF_Point  p2,
                    AF_Point  ref )
      {
        AF_Point  p;
        FT_Pos    delta = ref->u - ref->v;
    
    
        for ( p = p1; p < ref; p++ )
          p->u = p->v + delta;
    
        for ( p = ref + 1; p <= p2; p++ )
          p->u = p->v + delta;
      }
    
    
      static void
      af_iup_interp( AF_Point  p1,
                     AF_Point  p2,
                     AF_Point  ref1,
                     AF_Point  ref2 )
      {
        AF_Point  p;
        FT_Pos    u;
        FT_Pos    v1 = ref1->v;
        FT_Pos    v2 = ref2->v;
        FT_Pos    d1 = ref1->u - v1;
        FT_Pos    d2 = ref2->u - v2;
    
    
        if ( p1 > p2 )
          return;
    
        if ( v1 == v2 )
        {
          for ( p = p1; p <= p2; p++ )
          {
            u = p->v;
    
            if ( u <= v1 )
              u += d1;
            else
              u += d2;
    
            p->u = u;
          }
          return;
        }
    
        if ( v1 < v2 )
        {
          for ( p = p1; p <= p2; p++ )
          {
            u = p->v;
    
            if ( u <= v1 )
              u += d1;
            else if ( u >= v2 )
              u += d2;
            else
              u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 );
    
            p->u = u;
          }
        }
        else
        {
          for ( p = p1; p <= p2; p++ )
          {
            u = p->v;
    
            if ( u <= v2 )
              u += d2;
            else if ( u >= v1 )
              u += d1;
            else
              u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 );
    
            p->u = u;
          }
        }
      }
    
    
      FT_LOCAL_DEF( void )
      af_glyph_hints_align_weak_points( AF_GlyphHints  hints,
                                        AF_Dimension   dim )
      {
        AF_Point    points        = hints->points;
        AF_Point    point_limit   = points + hints->num_points;
        AF_Point*   contour       = hints->contours;
        AF_Point*   contour_limit = contour + hints->num_contours;
        AF_Flags    touch_flag;
        AF_Point    point;
        AF_Point    end_point;
        AF_Point    first_point;
    
    
        /* PASS 1: Move segment points to edge positions */
    
        if ( dim == AF_DIMENSION_HORZ )
        {
          touch_flag = AF_FLAG_TOUCH_X;
    
          for ( point = points; point < point_limit; point++ )
          {
            point->u = point->x;
            point->v = point->ox;
          }
        }
        else
        {
          touch_flag = AF_FLAG_TOUCH_Y;
    
          for ( point = points; point < point_limit; point++ )
          {
            point->u = point->y;
            point->v = point->oy;
          }
        }
    
        point   = points;
    
        for ( ; contour < contour_limit; contour++ )
        {
          point       = *contour;
          end_point   = point->prev;
          first_point = point;
    
          while ( point <= end_point && !( point->flags & touch_flag ) )
            point++;
    
          if ( point <= end_point )
          {
            AF_Point  first_touched = point;
            AF_Point  cur_touched   = point;
    
    
            point++;
            while ( point <= end_point )
            {
              if ( point->flags & touch_flag )
              {
                /* we found two successive touched points; we interpolate */
                /* all contour points between them                        */
                af_iup_interp( cur_touched + 1, point - 1,
                               cur_touched, point );
                cur_touched = point;
              }
              point++;
            }
    
            if ( cur_touched == first_touched )
            {
              /* this is a special case: only one point was touched in the */
              /* contour; we thus simply shift the whole contour           */
              af_iup_shift( first_point, end_point, cur_touched );
            }
            else
            {
              /* now interpolate after the last touched point to the end */
              /* of the contour                                          */
              af_iup_interp( cur_touched + 1, end_point,
                             cur_touched, first_touched );
    
              /* if the first contour point isn't touched, interpolate */
              /* from the contour start to the first touched point     */
              if ( first_touched > points )
                af_iup_interp( first_point, first_touched - 1,
                               cur_touched, first_touched );
            }
          }
        }
    
        /* now save the interpolated values back to x/y */
        if ( dim == AF_DIMENSION_HORZ )
        {
          for ( point = points; point < point_limit; point++ )
            point->x = point->u;
        }
        else
        {
          for ( point = points; point < point_limit; point++ )
            point->y = point->u;
        }
      }