|
|
|
@ -2150,8 +2150,10 @@ static const char count_table[256] = |
|
|
|
|
f1 = (Byte) ( 0xFF >> ( e1 & 7 ) ); |
|
|
|
|
f2 = (Byte) ~( 0x7F >> ( e2 & 7 ) ); |
|
|
|
|
|
|
|
|
|
if ( ras.gray_min_x > c1 ) ras.gray_min_x = (short)c1; |
|
|
|
|
if ( ras.gray_max_x < c2 ) ras.gray_max_x = (short)c2; |
|
|
|
|
if ( ras.gray_min_x > c1 ) |
|
|
|
|
ras.gray_min_x = (short)c1; |
|
|
|
|
if ( ras.gray_max_x < c2 ) |
|
|
|
|
ras.gray_max_x = (short)c2; |
|
|
|
|
|
|
|
|
|
target = ras.bTarget + ras.traceOfs + c1; |
|
|
|
|
c2 -= c1; |
|
|
|
@ -2184,14 +2186,43 @@ static const char count_table[256] = |
|
|
|
|
PProfile left, |
|
|
|
|
PProfile right ) |
|
|
|
|
{ |
|
|
|
|
Long e1, e2; |
|
|
|
|
Long e1, e2, pxl; |
|
|
|
|
Short c1, f1; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Drop-out control */ |
|
|
|
|
|
|
|
|
|
e1 = CEILING( x1 ); |
|
|
|
|
e2 = FLOOR ( x2 ); |
|
|
|
|
/* e2 x2 x1 e1 */ |
|
|
|
|
/* */ |
|
|
|
|
/* ^ | */ |
|
|
|
|
/* | | */ |
|
|
|
|
/* +-------------+---------------------+------------+ */ |
|
|
|
|
/* | | */ |
|
|
|
|
/* | v */ |
|
|
|
|
/* */ |
|
|
|
|
/* pixel contour contour pixel */ |
|
|
|
|
/* center center */ |
|
|
|
|
|
|
|
|
|
/* drop-out mode scan conversion rules (as defined in OpenType) */ |
|
|
|
|
/* --------------------------------------------------------------- */ |
|
|
|
|
/* 0 1, 2, 3 */ |
|
|
|
|
/* 1 1, 2, 4 */ |
|
|
|
|
/* 2 1, 2 */ |
|
|
|
|
/* 3 same as mode 2 */ |
|
|
|
|
/* 4 1, 2, 5 */ |
|
|
|
|
/* 5 1, 2, 6 */ |
|
|
|
|
/* 6, 7 same as mode 2 */ |
|
|
|
|
|
|
|
|
|
/* FIXXXME: The specification doesn't discuss the case where the */ |
|
|
|
|
/* intersections degenerate to a single point. */ |
|
|
|
|
#if 0 |
|
|
|
|
if ( x1 == x2 ) |
|
|
|
|
return; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
e1 = CEILING( x1 ); |
|
|
|
|
e2 = FLOOR ( x2 ); |
|
|
|
|
pxl = e1; |
|
|
|
|
|
|
|
|
|
if ( e1 > e2 ) |
|
|
|
|
{ |
|
|
|
@ -2199,19 +2230,20 @@ static const char count_table[256] = |
|
|
|
|
{ |
|
|
|
|
switch ( ras.dropOutControl ) |
|
|
|
|
{ |
|
|
|
|
case 1: |
|
|
|
|
e1 = e2; |
|
|
|
|
case 0: /* simple drop-outs including stubs */ |
|
|
|
|
pxl = e2; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case 4: |
|
|
|
|
e1 = CEILING( (x1 + x2 + 1) / 2 ); |
|
|
|
|
case 4: /* smart drop-outs including stubs */ |
|
|
|
|
pxl = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half ); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case 2: |
|
|
|
|
case 5: |
|
|
|
|
/* Drop-out Control Rule #4 */ |
|
|
|
|
case 1: /* simple drop-outs excluding stubs */ |
|
|
|
|
case 5: /* smart drop-outs excluding stubs */ |
|
|
|
|
|
|
|
|
|
/* The spec is not very clear regarding rule #4. It */ |
|
|
|
|
/* Drop-out Control Rules #4 and #6 */ |
|
|
|
|
|
|
|
|
|
/* The spec is not very clear regarding those rules. It */ |
|
|
|
|
/* presents a method that is way too costly to implement */ |
|
|
|
|
/* while the general idea seems to get rid of `stubs'. */ |
|
|
|
|
/* */ |
|
|
|
@ -2233,7 +2265,6 @@ static const char count_table[256] = |
|
|
|
|
/* FIXXXME: uncommenting this line solves the disappearing */ |
|
|
|
|
/* bit problem in the `7' of verdana 10pts, but */ |
|
|
|
|
/* makes a new one in the `C' of arial 14pts */ |
|
|
|
|
|
|
|
|
|
#if 0 |
|
|
|
|
if ( x2 - x1 < ras.precision_half ) |
|
|
|
|
#endif |
|
|
|
@ -2247,41 +2278,43 @@ static const char count_table[256] = |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* check that the rightmost pixel isn't set */ |
|
|
|
|
|
|
|
|
|
e1 = TRUNC( e1 ); |
|
|
|
|
if ( ras.dropOutControl == 1 ) |
|
|
|
|
pxl = e2; |
|
|
|
|
else |
|
|
|
|
pxl = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half ); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
c1 = (Short)( e1 >> 3 ); |
|
|
|
|
f1 = (Short)( e1 & 7 ); |
|
|
|
|
default: /* modes 2, 3, 6, 7 */ |
|
|
|
|
return; /* no drop-out control */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ( e1 >= 0 && e1 < ras.bWidth && |
|
|
|
|
ras.bTarget[ras.traceOfs + c1] & ( 0x80 >> f1 ) ) |
|
|
|
|
return; |
|
|
|
|
/* check that the other pixel isn't set */ |
|
|
|
|
e1 = pxl == e1 ? e2 : e1; |
|
|
|
|
|
|
|
|
|
if ( ras.dropOutControl == 2 ) |
|
|
|
|
e1 = e2; |
|
|
|
|
else |
|
|
|
|
e1 = CEILING( ( x1 + x2 + 1 ) / 2 ); |
|
|
|
|
e1 = TRUNC( e1 ); |
|
|
|
|
|
|
|
|
|
break; |
|
|
|
|
c1 = (Short)( e1 >> 3 ); |
|
|
|
|
f1 = (Short)( e1 & 7 ); |
|
|
|
|
|
|
|
|
|
default: |
|
|
|
|
return; /* unsupported mode */ |
|
|
|
|
} |
|
|
|
|
if ( e1 >= 0 && e1 < ras.bWidth && |
|
|
|
|
ras.bTarget[ras.traceOfs + c1] & ( 0x80 >> f1 ) ) |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
e1 = TRUNC( e1 ); |
|
|
|
|
e1 = TRUNC( pxl ); |
|
|
|
|
|
|
|
|
|
if ( e1 >= 0 && e1 < ras.bWidth ) |
|
|
|
|
{ |
|
|
|
|
c1 = (Short)( e1 >> 3 ); |
|
|
|
|
f1 = (Short)( e1 & 7 ); |
|
|
|
|
|
|
|
|
|
if ( ras.gray_min_x > c1 ) ras.gray_min_x = c1; |
|
|
|
|
if ( ras.gray_max_x < c1 ) ras.gray_max_x = c1; |
|
|
|
|
if ( ras.gray_min_x > c1 ) |
|
|
|
|
ras.gray_min_x = c1; |
|
|
|
|
if ( ras.gray_max_x < c1 ) |
|
|
|
|
ras.gray_max_x = c1; |
|
|
|
|
|
|
|
|
|
ras.bTarget[ras.traceOfs + c1] |= (char)( 0x80 >> f1 ); |
|
|
|
|
} |
|
|
|
@ -2365,15 +2398,33 @@ static const char count_table[256] = |
|
|
|
|
PProfile left, |
|
|
|
|
PProfile right ) |
|
|
|
|
{ |
|
|
|
|
Long e1, e2; |
|
|
|
|
Long e1, e2, pxl; |
|
|
|
|
PByte bits; |
|
|
|
|
Byte f1; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* During the horizontal sweep, we only take care of drop-outs */ |
|
|
|
|
|
|
|
|
|
e1 = CEILING( x1 ); |
|
|
|
|
e2 = FLOOR ( x2 ); |
|
|
|
|
/* e1 + <-- pixel center */ |
|
|
|
|
/* | */ |
|
|
|
|
/* x1 ---+--> <-- contour */ |
|
|
|
|
/* | */ |
|
|
|
|
/* | */ |
|
|
|
|
/* x2 <--+--- <-- contour */ |
|
|
|
|
/* | */ |
|
|
|
|
/* | */ |
|
|
|
|
/* e2 + <-- pixel center */ |
|
|
|
|
|
|
|
|
|
/* FIXXXME: The specification doesn't discuss the case where the */ |
|
|
|
|
/* intersections degenerate to a single point. */ |
|
|
|
|
#if 0 |
|
|
|
|
if ( x1 == x2 ) |
|
|
|
|
return; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
e1 = CEILING( x1 ); |
|
|
|
|
e2 = FLOOR ( x2 ); |
|
|
|
|
pxl = e1; |
|
|
|
|
|
|
|
|
|
if ( e1 > e2 ) |
|
|
|
|
{ |
|
|
|
@ -2381,23 +2432,17 @@ static const char count_table[256] = |
|
|
|
|
{ |
|
|
|
|
switch ( ras.dropOutControl ) |
|
|
|
|
{ |
|
|
|
|
case 1: |
|
|
|
|
e1 = e2; |
|
|
|
|
case 0: /* simple drop-outs including stubs */ |
|
|
|
|
pxl = e2; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case 4: |
|
|
|
|
e1 = CEILING( ( x1 + x2 + 1 ) / 2 ); |
|
|
|
|
case 4: /* smart drop-outs including stubs */ |
|
|
|
|
pxl = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half ); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case 2: |
|
|
|
|
case 5: |
|
|
|
|
|
|
|
|
|
/* Drop-out Control Rule #4 */ |
|
|
|
|
|
|
|
|
|
/* The spec is not very clear regarding rule #4. It */ |
|
|
|
|
/* presents a method that is way too costly to implement */ |
|
|
|
|
/* while the general idea seems to get rid of `stubs'. */ |
|
|
|
|
/* */ |
|
|
|
|
case 1: /* simple drop-outs excluding stubs */ |
|
|
|
|
case 5: /* smart drop-outs excluding stubs */ |
|
|
|
|
/* see Vertical_Sweep_Drop for details */ |
|
|
|
|
|
|
|
|
|
/* rightmost stub test */ |
|
|
|
|
if ( left->next == right && left->height <= 0 ) |
|
|
|
@ -2407,32 +2452,32 @@ static const char count_table[256] = |
|
|
|
|
if ( right->next == left && left->start == y ) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
/* check that the rightmost pixel isn't set */ |
|
|
|
|
|
|
|
|
|
e1 = TRUNC( e1 ); |
|
|
|
|
if ( ras.dropOutControl == 1 ) |
|
|
|
|
pxl = e2; |
|
|
|
|
else |
|
|
|
|
pxl = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half ); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
bits = ras.bTarget + ( y >> 3 ); |
|
|
|
|
f1 = (Byte)( 0x80 >> ( y & 7 ) ); |
|
|
|
|
default: /* modes 2, 3, 6, 7 */ |
|
|
|
|
return; /* no drop-out control */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bits -= e1 * ras.target.pitch; |
|
|
|
|
if ( ras.target.pitch > 0 ) |
|
|
|
|
bits += ( ras.target.rows - 1 ) * ras.target.pitch; |
|
|
|
|
/* check that the other pixel isn't set */ |
|
|
|
|
e1 = pxl == e1 ? e2 : e1; |
|
|
|
|
|
|
|
|
|
if ( e1 >= 0 && |
|
|
|
|
e1 < ras.target.rows && |
|
|
|
|
*bits & f1 ) |
|
|
|
|
return; |
|
|
|
|
e1 = TRUNC( e1 ); |
|
|
|
|
|
|
|
|
|
if ( ras.dropOutControl == 2 ) |
|
|
|
|
e1 = e2; |
|
|
|
|
else |
|
|
|
|
e1 = CEILING( ( x1 + x2 + 1 ) / 2 ); |
|
|
|
|
bits = ras.bTarget + ( y >> 3 ); |
|
|
|
|
f1 = (Byte)( 0x80 >> ( y & 7 ) ); |
|
|
|
|
|
|
|
|
|
break; |
|
|
|
|
bits -= e1 * ras.target.pitch; |
|
|
|
|
if ( ras.target.pitch > 0 ) |
|
|
|
|
bits += ( ras.target.rows - 1 ) * ras.target.pitch; |
|
|
|
|
|
|
|
|
|
default: |
|
|
|
|
return; /* unsupported mode */ |
|
|
|
|
} |
|
|
|
|
if ( e1 >= 0 && |
|
|
|
|
e1 < ras.target.rows && |
|
|
|
|
*bits & f1 ) |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
return; |
|
|
|
@ -2441,7 +2486,7 @@ static const char count_table[256] = |
|
|
|
|
bits = ras.bTarget + ( y >> 3 ); |
|
|
|
|
f1 = (Byte)( 0x80 >> ( y & 7 ) ); |
|
|
|
|
|
|
|
|
|
e1 = TRUNC( e1 ); |
|
|
|
|
e1 = TRUNC( pxl ); |
|
|
|
|
|
|
|
|
|
if ( e1 >= 0 && e1 < ras.target.rows ) |
|
|
|
|
{ |
|
|
|
@ -2627,6 +2672,14 @@ static const char count_table[256] = |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* During the horizontal sweep, we only take care of drop-outs */ |
|
|
|
|
|
|
|
|
|
/* FIXXXME: The specification doesn't discuss the case where the */ |
|
|
|
|
/* intersections degenerate to a single point. */ |
|
|
|
|
#if 0 |
|
|
|
|
if ( x1 == x2 ) |
|
|
|
|
return; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
e1 = CEILING( x1 ); |
|
|
|
|
e2 = FLOOR ( x2 ); |
|
|
|
|
|
|
|
|
@ -2636,23 +2689,17 @@ static const char count_table[256] = |
|
|
|
|
{ |
|
|
|
|
switch ( ras.dropOutControl ) |
|
|
|
|
{ |
|
|
|
|
case 1: |
|
|
|
|
case 0: /* simple drop-outs including stubs */ |
|
|
|
|
e1 = e2; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case 4: |
|
|
|
|
e1 = CEILING( ( x1 + x2 + 1 ) / 2 ); |
|
|
|
|
case 4: /* smart drop-outs including stubs */ |
|
|
|
|
e1 = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half ); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case 2: |
|
|
|
|
case 5: |
|
|
|
|
|
|
|
|
|
/* Drop-out Control Rule #4 */ |
|
|
|
|
|
|
|
|
|
/* The spec is not very clear regarding rule #4. It */ |
|
|
|
|
/* presents a method that is way too costly to implement */ |
|
|
|
|
/* while the general idea seems to get rid of `stubs'. */ |
|
|
|
|
/* */ |
|
|
|
|
case 1: /* simple drop-outs excluding stubs */ |
|
|
|
|
case 5: /* smart drop-outs excluding stubs */ |
|
|
|
|
/* see Vertical_Sweep_Drop for details */ |
|
|
|
|
|
|
|
|
|
/* rightmost stub test */ |
|
|
|
|
if ( left->next == right && left->height <= 0 ) |
|
|
|
@ -2662,15 +2709,15 @@ static const char count_table[256] = |
|
|
|
|
if ( right->next == left && left->start == y ) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
if ( ras.dropOutControl == 2 ) |
|
|
|
|
if ( ras.dropOutControl == 1 ) |
|
|
|
|
e1 = e2; |
|
|
|
|
else |
|
|
|
|
e1 = CEILING( ( x1 + x2 + 1 ) / 2 ); |
|
|
|
|
e1 = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half ); |
|
|
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
default: |
|
|
|
|
return; /* unsupported mode */ |
|
|
|
|
default: /* modes 2, 3, 6, 7 */ |
|
|
|
|
return; /* no drop-out control */ |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
@ -2742,8 +2789,10 @@ static const char count_table[256] = |
|
|
|
|
bottom = (Short)P->start; |
|
|
|
|
top = (Short)( P->start + P->height - 1 ); |
|
|
|
|
|
|
|
|
|
if ( min_Y > bottom ) min_Y = bottom; |
|
|
|
|
if ( max_Y < top ) max_Y = top; |
|
|
|
|
if ( min_Y > bottom ) |
|
|
|
|
min_Y = bottom; |
|
|
|
|
if ( max_Y < top ) |
|
|
|
|
max_Y = top; |
|
|
|
|
|
|
|
|
|
P->X = 0; |
|
|
|
|
InsNew( &waiting, P ); |
|
|
|
@ -3039,13 +3088,23 @@ static const char count_table[256] = |
|
|
|
|
|
|
|
|
|
Set_High_Precision( RAS_VARS ras.outline.flags & |
|
|
|
|
FT_OUTLINE_HIGH_PRECISION ); |
|
|
|
|
ras.scale_shift = ras.precision_shift; |
|
|
|
|
/* Drop-out mode 2 is hard-coded since this is the only mode used */ |
|
|
|
|
/* on Windows platforms. Using other modes, as specified by the */ |
|
|
|
|
/* font, results in misplaced pixels. */ |
|
|
|
|
ras.dropOutControl = 2; |
|
|
|
|
ras.second_pass = (FT_Byte)( !( ras.outline.flags & |
|
|
|
|
FT_OUTLINE_SINGLE_PASS ) ); |
|
|
|
|
ras.scale_shift = ras.precision_shift; |
|
|
|
|
|
|
|
|
|
if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS ) |
|
|
|
|
ras.dropOutControl = 2; |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS ) |
|
|
|
|
ras.dropOutControl = 4; |
|
|
|
|
else |
|
|
|
|
ras.dropOutControl = 0; |
|
|
|
|
|
|
|
|
|
if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) ) |
|
|
|
|
ras.dropOutControl += 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ras.second_pass = (FT_Byte)( !( ras.outline.flags & |
|
|
|
|
FT_OUTLINE_SINGLE_PASS ) ); |
|
|
|
|
|
|
|
|
|
/* Vertical Sweep */ |
|
|
|
|
ras.Proc_Sweep_Init = Vertical_Sweep_Init; |
|
|
|
@ -3106,12 +3165,22 @@ static const char count_table[256] = |
|
|
|
|
|
|
|
|
|
Set_High_Precision( RAS_VARS ras.outline.flags & |
|
|
|
|
FT_OUTLINE_HIGH_PRECISION ); |
|
|
|
|
ras.scale_shift = ras.precision_shift + 1; |
|
|
|
|
/* Drop-out mode 2 is hard-coded since this is the only mode used */ |
|
|
|
|
/* on Windows platforms. Using other modes, as specified by the */ |
|
|
|
|
/* font, results in misplaced pixels. */ |
|
|
|
|
ras.dropOutControl = 2; |
|
|
|
|
ras.second_pass = !( ras.outline.flags & FT_OUTLINE_SINGLE_PASS ); |
|
|
|
|
ras.scale_shift = ras.precision_shift + 1; |
|
|
|
|
|
|
|
|
|
if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS ) |
|
|
|
|
ras.dropOutControl = 2; |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS ) |
|
|
|
|
ras.dropOutControl = 4; |
|
|
|
|
else |
|
|
|
|
ras.dropOutControl = 0; |
|
|
|
|
|
|
|
|
|
if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) ) |
|
|
|
|
ras.dropOutControl += 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ras.second_pass = !( ras.outline.flags & FT_OUTLINE_SINGLE_PASS ); |
|
|
|
|
|
|
|
|
|
/* Vertical Sweep */ |
|
|
|
|
|
|
|
|
@ -3351,15 +3420,15 @@ static const char count_table[256] = |
|
|
|
|
if ( !target_map->buffer ) |
|
|
|
|
return Raster_Err_Invalid; |
|
|
|
|
|
|
|
|
|
ras.outline = *outline; |
|
|
|
|
ras.target = *target_map; |
|
|
|
|
ras.outline = *outline; |
|
|
|
|
ras.target = *target_map; |
|
|
|
|
|
|
|
|
|
worker->buff = (PLong) raster->buffer; |
|
|
|
|
worker->sizeBuff = worker->buff + |
|
|
|
|
raster->buffer_size / sizeof ( Long ); |
|
|
|
|
worker->buff = (PLong) raster->buffer; |
|
|
|
|
worker->sizeBuff = worker->buff + |
|
|
|
|
raster->buffer_size / sizeof ( Long ); |
|
|
|
|
#ifdef FT_RASTER_OPTION_ANTI_ALIASING |
|
|
|
|
worker->grays = raster->grays; |
|
|
|
|
worker->gray_width = raster->gray_width; |
|
|
|
|
worker->grays = raster->grays; |
|
|
|
|
worker->gray_width = raster->gray_width; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
return ( ( params->flags & FT_RASTER_FLAG_AA ) |
|
|
|
|