/[freetype]/freetype2/src/autofit/aflatin.c
ViewVC logotype

Diff of /freetype2/src/autofit/aflatin.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.12 by davidT, Fri Jun 4 17:41:59 2004 UTC revision 1.13 by freetype, Tue Mar 1 15:48:29 2005 UTC
# Line 58  Line 58 
58          FT_UInt       num_widths = 0;          FT_UInt       num_widths = 0;
59          FT_Pos        edge_distance_threshold = 32000;          FT_Pos        edge_distance_threshold = 32000;
60    
61          af_latin_hints_compute_segments( hints, dim );          error = af_latin_hints_compute_segments( hints, dim );
62            if ( error )
63              goto Exit;
64    
65          af_latin_hints_link_segments   ( hints, dim );          af_latin_hints_link_segments   ( hints, dim );
66    
67          seg   = axhints->segments;          seg   = axhints->segments;
# Line 506  Line 509 
509    af_latin_metrics_scale( AF_LatinMetrics  metrics,    af_latin_metrics_scale( AF_LatinMetrics  metrics,
510                            AF_Scaler        scaler )                            AF_Scaler        scaler )
511    {    {
     if ( AF_SCALER_EQUAL_SCALES( scaler, &metrics->root.scaler ) )  
       return;  
   
512      af_latin_metrics_scale_dim( metrics, scaler, AF_DIMENSION_HORZ );      af_latin_metrics_scale_dim( metrics, scaler, AF_DIMENSION_HORZ );
513      af_latin_metrics_scale_dim( metrics, scaler, AF_DIMENSION_VERT );      af_latin_metrics_scale_dim( metrics, scaler, AF_DIMENSION_VERT );
514    }    }
# Line 522  Line 522 
522   /***************************************************************************/   /***************************************************************************/
523   /***************************************************************************/   /***************************************************************************/
524    
525    FT_LOCAL_DEF( void )    FT_LOCAL_DEF( FT_Error )
526    af_latin_hints_compute_segments( AF_GlyphHints  hints,    af_latin_hints_compute_segments( AF_GlyphHints  hints,
527                                     AF_Dimension   dim )                                     AF_Dimension   dim )
528    {    {
529      AF_AxisHints  axis = &hints->axis[dim];      AF_AxisHints  axis          = &hints->axis[dim];
530      AF_Segment    segments = axis->segments;      FT_Memory     memory        = hints->memory;
531      AF_Segment    segment       =  segments;      FT_Error      error         = 0;
532      FT_Int        num_segments  =  0;      AF_Segment    segment       =  NULL;
533      AF_Point*     contour       =  hints->contours;      AF_Point*     contour       =  hints->contours;
534      AF_Point*     contour_limit =  contour + hints->num_contours;      AF_Point*     contour_limit =  contour + hints->num_contours;
535      AF_Direction  major_dir, segment_dir;      AF_Direction  major_dir, segment_dir;
# Line 544  Line 544 
544      major_dir   = FT_ABS( axis->major_dir );      major_dir   = FT_ABS( axis->major_dir );
545      segment_dir = major_dir;      segment_dir = major_dir;
546    
547        axis->num_segments = 0;
548    
549      /* set up (u,v) in each point */      /* set up (u,v) in each point */
550      if ( dim == AF_DIMENSION_HORZ )      if ( dim == AF_DIMENSION_HORZ )
551      {      {
# Line 656  Line 658 
658              segment->max_coord = max_pos;              segment->max_coord = max_pos;
659    
660              on_edge = 0;              on_edge = 0;
661              num_segments++;              segment = NULL;
             segment++;  
662              /* fallthrough */              /* fallthrough */
663            }            }
664          }          }
# Line 676  Line 677 
677            segment_dir = point->out_dir;            segment_dir = point->out_dir;
678    
679            /* clear all segment fields */            /* clear all segment fields */
680            FT_ZERO( segment );            error = af_axis_hints_new_segment( axis, memory, &segment );
681              if ( error )
682                goto Exit;
683    
684            segment->dir      = segment_dir;            segment->dir      = segment_dir;
685            segment->flags    = AF_EDGE_NORMAL;            segment->flags    = AF_EDGE_NORMAL;
# Line 740  Line 743 
743        if ( min_point )        if ( min_point )
744        {        {
745          /* clear all segment fields */          /* clear all segment fields */
746          FT_ZERO( segment );          error = af_axis_hints_new_segment( axis, memory, &segment );
747            if ( error )
748              goto Exit;
749    
750          segment->dir   = segment_dir;          segment->dir   = segment_dir;
751          segment->flags = AF_EDGE_NORMAL;          segment->flags = AF_EDGE_NORMAL;
# Line 750  Line 755 
755          segment->score = 32000;          segment->score = 32000;
756          segment->link  = NULL;          segment->link  = NULL;
757    
758          num_segments++;          segment = NULL;
         segment++;  
759        }        }
760    
761        /* insert maximum segment */        /* insert maximum segment */
762        if ( max_point )        if ( max_point )
763        {        {
764          /* clear all segment fields */          /* clear all segment fields */
765          FT_ZERO( segment );          error = af_axis_hints_new_segment( axis, memory, &segment );
766            if ( error)
767              goto Exit;
768    
769          segment->dir   = segment_dir;          segment->dir   = segment_dir;
770          segment->flags = AF_EDGE_NORMAL;          segment->flags = AF_EDGE_NORMAL;
# Line 768  Line 774 
774          segment->score = 32000;          segment->score = 32000;
775          segment->link  = NULL;          segment->link  = NULL;
776    
777          num_segments++;          segment = NULL;
         segment++;  
778        }        }
779      }      }
780  #endif /* AF_HINT_METRICS */  #endif /* AF_HINT_METRICS */
781    
782      axis->num_segments = num_segments;    Exit:
783        return error;
784    }    }
785    
786    
# Line 858  Line 864 
864    }    }
865    
866    
867    FT_LOCAL_DEF( void )    FT_LOCAL_DEF( FT_Error )
868    af_latin_hints_compute_edges( AF_GlyphHints  hints,    af_latin_hints_compute_edges( AF_GlyphHints  hints,
869                                  AF_Dimension   dim )                                  AF_Dimension   dim )
870    {    {
871      AF_AxisHints  axis = &hints->axis[dim];      AF_AxisHints  axis   = &hints->axis[dim];
872        FT_Error      error  = 0;
873        FT_Memory     memory = hints->memory;
874      AF_LatinAxis  laxis = &((AF_LatinMetrics)hints->metrics)->axis[dim];      AF_LatinAxis  laxis = &((AF_LatinMetrics)hints->metrics)->axis[dim];
     AF_Edge       edges = axis->edges;  
     AF_Edge       edge, edge_limit;  
875    
876      AF_Segment    segments = axis->segments;      AF_Segment    segments = axis->segments;
877      AF_Segment    segment_limit = segments + axis->num_segments;      AF_Segment    segment_limit = segments + axis->num_segments;
# Line 875  Line 881 
881      FT_Fixed      scale;      FT_Fixed      scale;
882      FT_Pos        edge_distance_threshold;      FT_Pos        edge_distance_threshold;
883    
884        axis->num_edges = 0;
885    
886      scale = ( dim == AF_DIMENSION_HORZ ) ? hints->x_scale      scale = ( dim == AF_DIMENSION_HORZ ) ? hints->x_scale
887                                           : hints->y_scale;                                           : hints->y_scale;
# Line 906  Line 913 
913      edge_distance_threshold = FT_DivFix( edge_distance_threshold,      edge_distance_threshold = FT_DivFix( edge_distance_threshold,
914                                           scale );                                           scale );
915    
     edge_limit = edges;  
916      for ( seg = segments; seg < segment_limit; seg++ )      for ( seg = segments; seg < segment_limit; seg++ )
917      {      {
918        AF_Edge  found = 0;        AF_Edge  found = 0;
919          FT_Int   ee;
920    
921        /* look for an edge corresponding to the segment */        /* look for an edge corresponding to the segment */
922        for ( edge = edges; edge < edge_limit; edge++ )        for ( ee = 0; ee < axis->num_edges; ee++ )
923        {        {
924          FT_Pos  dist;          AF_Edge  edge = axis->edges + ee;
925            FT_Pos   dist;
926    
927    
928          dist = seg->pos - edge->fpos;          dist = seg->pos - edge->fpos;
# Line 931  Line 938 
938    
939        if ( !found )        if ( !found )
940        {        {
941            AF_Edge   edge;
942    
943          /* insert a new edge in the list and */          /* insert a new edge in the list and */
944          /* sort according to the position    */          /* sort according to the position    */
945          while ( edge > edges && edge[-1].fpos > seg->pos )          error = af_axis_hints_new_edge( axis, seg->pos, memory, &edge );
946          {          if ( error )
947            edge[0] = edge[-1];            goto Exit;
           edge--;  
         }  
         edge_limit++;  
   
         /* clear all edge fields */  
         FT_ZERO( edge );  
948    
949          /* add the segment to the new edge's list */          /* add the segment to the new edge's list */
950            FT_ZERO(edge);
951    
952          edge->first    = seg;          edge->first    = seg;
953          edge->last     = seg;          edge->last     = seg;
954          edge->fpos     = seg->pos;          edge->fpos     = seg->pos;
# Line 954  Line 959 
959        {        {
960          /* if an edge was found, simply add the segment to the edge's */          /* if an edge was found, simply add the segment to the edge's */
961          /* list                                                       */          /* list                                                       */
962          seg->edge_next        = edge->first;          seg->edge_next         = found->first;
963          edge->last->edge_next = seg;          found->last->edge_next = seg;
964          edge->last            = seg;          found->last            = seg;
965        }        }
966      }      }
     axis->num_edges = (FT_Int)( edge_limit - edges );  
967    
968    
969      /*********************************************************************/      /*********************************************************************/
# Line 982  Line 986 
986       * code above.  For some reason, it slows down execution       * code above.  For some reason, it slows down execution
987       * speed -- on a Sun.       * speed -- on a Sun.
988       */       */
     for ( edge = edges; edge < edge_limit; edge++ )  
     {  
       seg = edge->first;  
       if ( seg )  
         do  
         {  
           seg->edge = edge;  
           seg       = seg->edge_next;  
         }  
         while ( seg != edge->first );  
     }  
   
     /* now, compute each edge properties */  
     for ( edge = edges; edge < edge_limit; edge++ )  
989      {      {
990        FT_Int  is_round    = 0;  /* does it contain round segments?    */        AF_Edge  edges      = axis->edges;
991        FT_Int  is_straight = 0;  /* does it contain straight segments? */        AF_Edge  edge_limit = edges + axis->num_edges;
992        FT_Pos  ups         = 0;  /* number of upwards segments         */        AF_Edge  edge;
       FT_Pos  downs       = 0;  /* number of downwards segments       */  
993    
994          for ( edge = edges; edge < edge_limit; edge++ )
995          {
996            seg = edge->first;
997            if ( seg )
998              do
999              {
1000                seg->edge = edge;
1001                seg       = seg->edge_next;
1002              }
1003              while ( seg != edge->first );
1004          }
1005    
1006        seg = edge->first;        /* now, compute each edge properties */
1007          for ( edge = edges; edge < edge_limit; edge++ )
       do  
1008        {        {
1009          FT_Bool  is_serif;          FT_Int  is_round    = 0;  /* does it contain round segments?    */
1010            FT_Int  is_straight = 0;  /* does it contain straight segments? */
1011            FT_Pos  ups         = 0;  /* number of upwards segments         */
1012            FT_Pos  downs       = 0;  /* number of downwards segments       */
1013    
1014    
1015          /* check for roundness of segment */          seg = edge->first;
         if ( seg->flags & AF_EDGE_ROUND )  
           is_round++;  
         else  
           is_straight++;  
1016    
1017          /* check for segment direction */          do
1018          if ( seg->dir == up_dir )          {
1019            ups   += seg->max_coord-seg->min_coord;            FT_Bool  is_serif;
         else  
           downs += seg->max_coord-seg->min_coord;  
1020    
         /* check for links -- if seg->serif is set, then seg->link must */  
         /* be ignored                                                   */  
         is_serif = (FT_Bool)( seg->serif && seg->serif->edge != edge );  
1021    
1022          if ( seg->link || is_serif )            /* check for roundness of segment */
1023          {            if ( seg->flags & AF_EDGE_ROUND )
1024            AF_Edge     edge2;              is_round++;
1025            AF_Segment  seg2;            else
1026                is_straight++;
1027    
1028              /* check for segment direction */
1029              if ( seg->dir == up_dir )
1030                ups   += seg->max_coord-seg->min_coord;
1031              else
1032                downs += seg->max_coord-seg->min_coord;
1033    
1034            edge2 = edge->link;            /* check for links -- if seg->serif is set, then seg->link must */
1035            seg2  = seg->link;            /* be ignored                                                   */
1036              is_serif = (FT_Bool)( seg->serif && seg->serif->edge != edge );
1037    
1038            if ( is_serif )            if ( seg->link || is_serif )
1039            {            {
1040              seg2  = seg->serif;              AF_Edge     edge2;
1041              edge2 = edge->serif;              AF_Segment  seg2;
           }  
1042    
           if ( edge2 )  
           {  
             FT_Pos  edge_delta;  
             FT_Pos  seg_delta;  
1043    
1044                edge2 = edge->link;
1045                seg2  = seg->link;
1046    
1047              edge_delta = edge->fpos - edge2->fpos;              if ( is_serif )
1048              if ( edge_delta < 0 )              {
1049                edge_delta = -edge_delta;                seg2  = seg->serif;
1050                  edge2 = edge->serif;
1051                }
1052    
1053              seg_delta = seg->pos - seg2->pos;              if ( edge2 )
1054              if ( seg_delta < 0 )              {
1055                seg_delta = -seg_delta;                FT_Pos  edge_delta;
1056                  FT_Pos  seg_delta;
1057    
1058    
1059                  edge_delta = edge->fpos - edge2->fpos;
1060                  if ( edge_delta < 0 )
1061                    edge_delta = -edge_delta;
1062    
1063              if ( seg_delta < edge_delta )                seg_delta = seg->pos - seg2->pos;
1064                  if ( seg_delta < 0 )
1065                    seg_delta = -seg_delta;
1066    
1067                  if ( seg_delta < edge_delta )
1068                    edge2 = seg2->edge;
1069                }
1070                else
1071                edge2 = seg2->edge;                edge2 = seg2->edge;
           }  
           else  
             edge2 = seg2->edge;  
1072    
1073            if ( is_serif )              if ( is_serif )
1074            {              {
1075              edge->serif   = edge2;                edge->serif   = edge2;
1076              edge2->flags |= AF_EDGE_SERIF;                edge2->flags |= AF_EDGE_SERIF;
1077                }
1078                else
1079                  edge->link  = edge2;
1080            }            }
           else  
             edge->link  = edge2;  
         }  
1081    
1082          seg = seg->edge_next;            seg = seg->edge_next;
1083    
1084        } while ( seg != edge->first );          } while ( seg != edge->first );
1085    
1086        /* set the round/straight flags */          /* set the round/straight flags */
1087        edge->flags = AF_EDGE_NORMAL;          edge->flags = AF_EDGE_NORMAL;
1088    
1089        if ( is_round > 0 && is_round >= is_straight )          if ( is_round > 0 && is_round >= is_straight )
1090          edge->flags |= AF_EDGE_ROUND;            edge->flags |= AF_EDGE_ROUND;
1091    
1092        /* set the edge's main direction */          /* set the edge's main direction */
1093        edge->dir = AF_DIR_NONE;          edge->dir = AF_DIR_NONE;
1094    
1095        if ( ups > downs )          if ( ups > downs )
1096          edge->dir = up_dir;            edge->dir = up_dir;
1097    
1098        else if ( ups < downs )          else if ( ups < downs )
1099          edge->dir = -up_dir;            edge->dir = -up_dir;
1100    
1101        else if ( ups == downs )          else if ( ups == downs )
1102          edge->dir = 0;  /* both up and down! */            edge->dir = 0;  /* both up and down! */
1103    
1104        /* gets rid of serifs if link is set                */          /* gets rid of serifs if link is set                */
1105        /* XXX: This gets rid of many unpleasant artefacts! */          /* XXX: This gets rid of many unpleasant artefacts! */
1106        /*      Example: the `c' in cour.pfa at size 13     */          /*      Example: the `c' in cour.pfa at size 13     */
1107    
1108        if ( edge->serif && edge->link )          if ( edge->serif && edge->link )
1109          edge->serif = 0;            edge->serif = 0;
1110          }
1111      }      }
1112    
1113      Exit:
1114        return error;
1115    }    }
1116    
1117    
1118    FT_LOCAL_DEF( void )    FT_LOCAL_DEF( FT_Error )
1119    af_latin_hints_detect_features( AF_GlyphHints  hints,    af_latin_hints_detect_features( AF_GlyphHints  hints,
1120                                    AF_Dimension   dim )                                    AF_Dimension   dim )
1121    {    {
1122      af_latin_hints_compute_segments( hints, dim );      FT_Error  error;
1123      af_latin_hints_link_segments   ( hints, dim );  
1124      af_latin_hints_compute_edges   ( hints, dim );      error = af_latin_hints_compute_segments( hints, dim );
1125        if ( !error )
1126        {
1127          af_latin_hints_link_segments   ( hints, dim );
1128          error = af_latin_hints_compute_edges   ( hints, dim );
1129        }
1130        return error;
1131    }    }
1132    
1133    
# Line 1812  Line 1831 
1831     /* analyze glyph outline     /* analyze glyph outline
1832      */      */
1833      if ( AF_HINTS_DO_HORIZONTAL(hints) )      if ( AF_HINTS_DO_HORIZONTAL(hints) )
1834        af_latin_hints_detect_features( hints, AF_DIMENSION_HORZ );      {
1835          error = af_latin_hints_detect_features( hints, AF_DIMENSION_HORZ );
1836          if ( error )
1837            goto Exit;
1838        }
1839    
1840      if ( AF_HINTS_DO_VERTICAL(hints) )      if ( AF_HINTS_DO_VERTICAL(hints) )
1841      {      {
1842        af_latin_hints_detect_features( hints, AF_DIMENSION_VERT );        error =  af_latin_hints_detect_features( hints, AF_DIMENSION_VERT );
1843          if ( error )
1844            goto Exit;
1845    
1846        af_latin_hints_compute_blue_edges( hints, metrics );        af_latin_hints_compute_blue_edges( hints, metrics );
1847      }      }
1848    

Legend:
Removed from v.1.12  
changed lines
  Added in v.1.13

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26