Commit 5556dd21309171492c3c17275675b597a0a6ba9a

Werner Lemberg 2006-03-21T21:36:33

* src/base/ftoutln.c (FT_Outline_Get_Orientation): Improve algorithm.

diff --git a/ChangeLog b/ChangeLog
index 8888fbf..09681d2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2006-03-21  Zhe Su  <james.su@gmail.com>
+
+	* src/base/ftoutln.c (FT_Outline_Get_Orientation): Improve
+	algorithm.
+
 2006-03-21  Werner Lemberg  <wl@gnu.org>
 
 	* src/cff/cfftypes.h (CFF_CharsetRec): Add `max_cid' member.
diff --git a/src/base/ftoutln.c b/src/base/ftoutln.c
index affeaa6..b23b164 100644
--- a/src/base/ftoutln.c
+++ b/src/base/ftoutln.c
@@ -955,7 +955,10 @@
           contour++, first = last + 1 )
     {
       FT_Vector*  point;
-
+      FT_Int      on_curve;
+      FT_Int      on_curve_count = 0;
+      FT_Pos      tmp_xmin       = 32768L;
+      FT_Vector*  tmp_xmin_point = NULL;
 
       last = outline->points + *contour;
 
@@ -963,16 +966,27 @@
       if ( last < first + 2 )
         continue;
 
-      for ( point = first; point <= last; point++ )
+      for ( point = first; point <= last; ++point )
       {
-        if ( point->x < xmin )
+        /* Count on-curve points.  If there are less than 3 on-curve */
+        /* points, just bypass this contour.                         */
+        on_curve        = outline->tags[point - outline->points] & 1;
+        on_curve_count += on_curve;
+
+        if ( point->x < tmp_xmin && on_curve )
         {
-          xmin       = point->x;
-          xmin_point = point;
-          xmin_first = first;
-          xmin_last  = last;
+          tmp_xmin       = point->x;
+          tmp_xmin_point = point;
         }
       }
+
+      if ( on_curve_count > 2 && tmp_xmin < xmin )
+      {
+        xmin       = tmp_xmin;
+        xmin_point = tmp_xmin_point;
+        xmin_first = first;
+        xmin_last  = last;
+      }
     }
 
     if ( !xmin_point )
@@ -981,6 +995,23 @@
     prev = ( xmin_point == xmin_first ) ? xmin_last : xmin_point - 1;
     next = ( xmin_point == xmin_last ) ? xmin_first : xmin_point + 1;
 
+    /* Skip off-curve points */
+    while ( ( outline->tags[prev - outline->points] & 1 ) == 0 )
+    {
+      if ( prev == xmin_first )
+        prev = xmin_last;
+      else
+        --prev;
+    }
+
+    while ( ( outline->tags[next - outline->points] & 1 ) == 0 )
+    {
+      if ( next == xmin_last )
+        next = xmin_first;
+      else
+        ++next;
+    }
+
     if ( FT_Atan2( prev->x - xmin_point->x, prev->y - xmin_point->y ) >
          FT_Atan2( next->x - xmin_point->x, next->y - xmin_point->y ) )
       return FT_ORIENTATION_POSTSCRIPT;