|
Lines 933-950
Link Here
|
| 933 |
FT_EXPORT_DEF( FT_Orientation ) |
933 |
FT_EXPORT_DEF( FT_Orientation ) |
| 934 |
FT_Outline_Get_Orientation( FT_Outline* outline ) |
934 |
FT_Outline_Get_Orientation( FT_Outline* outline ) |
| 935 |
{ |
935 |
{ |
| 936 |
FT_Pos xmin = 32768L; |
936 |
FT_Pos xmin = 32768L; |
| 937 |
FT_Vector* xmin_point = NULL; |
937 |
FT_Pos xmin_ymin = 32768L; |
| 938 |
FT_Vector* xmin_first = NULL; |
938 |
FT_Pos xmin_ymax = -32768L; |
| 939 |
FT_Vector* xmin_last = NULL; |
939 |
|
|
|
940 |
FT_Vector* xmin_first = NULL; |
| 941 |
FT_Vector* xmin_last = NULL; |
| 940 |
|
942 |
|
| 941 |
short* contour; |
943 |
short* contour; |
| 942 |
|
944 |
|
| 943 |
FT_Vector* first; |
945 |
FT_Vector* first; |
| 944 |
FT_Vector* last; |
946 |
FT_Vector* last; |
| 945 |
FT_Vector* prev; |
947 |
FT_Vector* prev; |
| 946 |
FT_Vector* next; |
948 |
FT_Vector* point; |
| 947 |
|
949 |
|
|
|
950 |
int i; |
| 951 |
FT_Pos ray_y [3] = { 0, 0, 0 }; |
| 952 |
int result [3]; |
| 948 |
|
953 |
|
| 949 |
if ( !outline || outline->n_points <= 0 ) |
954 |
if ( !outline || outline->n_points <= 0 ) |
| 950 |
return FT_ORIENTATION_TRUETYPE; |
955 |
return FT_ORIENTATION_TRUETYPE; |
|
Lines 954-964
Link Here
|
| 954 |
contour < outline->contours + outline->n_contours; |
959 |
contour < outline->contours + outline->n_contours; |
| 955 |
contour++, first = last + 1 ) |
960 |
contour++, first = last + 1 ) |
| 956 |
{ |
961 |
{ |
| 957 |
FT_Vector* point; |
962 |
FT_Pos contour_xmin = 32768L; |
| 958 |
FT_Int on_curve; |
963 |
FT_Pos contour_xmax = -32768L; |
| 959 |
FT_Int on_curve_count = 0; |
964 |
FT_Pos contour_ymin = 32768L; |
| 960 |
FT_Pos tmp_xmin = 32768L; |
965 |
FT_Pos contour_ymax = -32768L; |
| 961 |
FT_Vector* tmp_xmin_point = NULL; |
|
|
| 962 |
|
966 |
|
| 963 |
last = outline->points + *contour; |
967 |
last = outline->points + *contour; |
| 964 |
|
968 |
|
|
Lines 968-1022
Link Here
|
| 968 |
|
972 |
|
| 969 |
for ( point = first; point <= last; ++point ) |
973 |
for ( point = first; point <= last; ++point ) |
| 970 |
{ |
974 |
{ |
| 971 |
/* Count on-curve points. If there are less than 3 on-curve */ |
975 |
if ( point->x < contour_xmin ) |
| 972 |
/* points, just bypass this contour. */ |
976 |
contour_xmin = point->x; |
| 973 |
on_curve = outline->tags[point - outline->points] & 1; |
|
|
| 974 |
on_curve_count += on_curve; |
| 975 |
|
977 |
|
| 976 |
if ( point->x < tmp_xmin && on_curve ) |
978 |
if ( point->x > contour_xmax ) |
| 977 |
{ |
979 |
contour_xmax = point->x; |
| 978 |
tmp_xmin = point->x; |
980 |
|
| 979 |
tmp_xmin_point = point; |
981 |
if ( point->y < contour_ymin ) |
| 980 |
} |
982 |
contour_ymin = point->y; |
|
|
983 |
|
| 984 |
if ( point->y > contour_ymax ) |
| 985 |
contour_ymax = point->y; |
| 981 |
} |
986 |
} |
| 982 |
|
987 |
|
| 983 |
if ( on_curve_count > 2 && tmp_xmin < xmin ) |
988 |
if ( contour_xmin < xmin && contour_xmin != contour_xmax && contour_ymin != contour_ymax) |
| 984 |
{ |
989 |
{ |
| 985 |
xmin = tmp_xmin; |
990 |
xmin = contour_xmin; |
| 986 |
xmin_point = tmp_xmin_point; |
991 |
xmin_ymin = contour_ymin; |
|
|
992 |
xmin_ymax = contour_ymax; |
| 987 |
xmin_first = first; |
993 |
xmin_first = first; |
| 988 |
xmin_last = last; |
994 |
xmin_last = last; |
| 989 |
} |
995 |
} |
| 990 |
} |
996 |
} |
| 991 |
|
997 |
|
| 992 |
if ( !xmin_point ) |
998 |
if ( xmin == 32768L ) |
| 993 |
return FT_ORIENTATION_TRUETYPE; |
999 |
return FT_ORIENTATION_TRUETYPE; |
| 994 |
|
1000 |
|
| 995 |
prev = ( xmin_point == xmin_first ) ? xmin_last : xmin_point - 1; |
1001 |
ray_y [0] = (xmin_ymin * 3 + xmin_ymax) >> 2; |
| 996 |
next = ( xmin_point == xmin_last ) ? xmin_first : xmin_point + 1; |
1002 |
ray_y [1] = (xmin_ymin + xmin_ymax) >> 1; |
|
|
1003 |
ray_y [2] = (xmin_ymin + xmin_ymax * 3) >> 2; |
| 997 |
|
1004 |
|
| 998 |
/* Skip off-curve points */ |
1005 |
for ( i = 0; i < 3; ++i ) |
| 999 |
while ( ( outline->tags[prev - outline->points] & 1 ) == 0 ) |
|
|
| 1000 |
{ |
1006 |
{ |
| 1001 |
if ( prev == xmin_first ) |
1007 |
FT_Pos left_is_x; |
| 1002 |
prev = xmin_last; |
1008 |
FT_Pos right_is_x; |
| 1003 |
else |
1009 |
FT_Vector* left_p1; |
| 1004 |
--prev; |
1010 |
FT_Vector* left_p2; |
| 1005 |
} |
1011 |
FT_Vector* right_p1; |
|
|
1012 |
FT_Vector* right_p2; |
| 1013 |
|
| 1014 |
redo_ray: |
| 1015 |
left_is_x = 32768L; |
| 1016 |
right_is_x = -32768L; |
| 1017 |
left_p1 = left_p2 = right_p1 = right_p2 = NULL; |
| 1006 |
|
1018 |
|
| 1007 |
while ( ( outline->tags[next - outline->points] & 1 ) == 0 ) |
1019 |
prev = xmin_last; |
| 1008 |
{ |
1020 |
for ( point = xmin_first; point <= xmin_last; prev = point, ++point ) |
| 1009 |
if ( next == xmin_last ) |
1021 |
{ |
| 1010 |
next = xmin_first; |
1022 |
FT_Pos tmp_x; |
|
|
1023 |
|
| 1024 |
if ( point->y == ray_y [i] || prev->y == ray_y [i]) |
| 1025 |
{ |
| 1026 |
++ ray_y [i]; |
| 1027 |
goto redo_ray; |
| 1028 |
} |
| 1029 |
else if ( (point->y < ray_y [i] && prev->y < ray_y [i]) || (point->y > ray_y [i] && prev->y > ray_y [i]) ) |
| 1030 |
continue; |
| 1031 |
|
| 1032 |
tmp_x = (point->x - prev->x) * (ray_y [i] - prev->y) / (point->y - prev->y) + prev->x; |
| 1033 |
|
| 1034 |
if ( tmp_x < left_is_x ) |
| 1035 |
{ |
| 1036 |
left_is_x = tmp_x; |
| 1037 |
left_p1 = prev; |
| 1038 |
left_p2 = point; |
| 1039 |
} |
| 1040 |
|
| 1041 |
if ( tmp_x > right_is_x ) |
| 1042 |
{ |
| 1043 |
right_is_x = tmp_x; |
| 1044 |
right_p1 = prev; |
| 1045 |
right_p2 = point; |
| 1046 |
} |
| 1047 |
} |
| 1048 |
|
| 1049 |
if ( left_p1 && left_p2 && right_p1 && right_p2 ) |
| 1050 |
{ |
| 1051 |
if ( left_p1->y < left_p2->y && right_p1->y > right_p2->y ) |
| 1052 |
result [i] = FT_ORIENTATION_TRUETYPE; |
| 1053 |
else if ( left_p1->y > left_p2->y && right_p1->y < right_p2->y ) |
| 1054 |
result [i] = FT_ORIENTATION_POSTSCRIPT; |
| 1055 |
else |
| 1056 |
result [i] = FT_ORIENTATION_NONE; |
| 1057 |
} |
| 1011 |
else |
1058 |
else |
| 1012 |
++next; |
1059 |
result [i] = FT_ORIENTATION_NONE; |
| 1013 |
} |
1060 |
} |
| 1014 |
|
1061 |
|
| 1015 |
if ( FT_Atan2( prev->x - xmin_point->x, prev->y - xmin_point->y ) > |
1062 |
if ((result [0] == result [1] || result [0] == result [2]) && result [0] != FT_ORIENTATION_NONE) |
| 1016 |
FT_Atan2( next->x - xmin_point->x, next->y - xmin_point->y ) ) |
1063 |
return result [0]; |
| 1017 |
return FT_ORIENTATION_POSTSCRIPT; |
1064 |
else if (result [1] == result [2] && result [1] != FT_ORIENTATION_NONE) |
| 1018 |
else |
1065 |
return result [1]; |
| 1019 |
return FT_ORIENTATION_TRUETYPE; |
1066 |
|
|
|
1067 |
return FT_ORIENTATION_TRUETYPE; |
| 1020 |
} |
1068 |
} |
| 1021 |
|
1069 |
|
| 1022 |
|
1070 |
|