summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorWerner Lemberg <wl@gnu.org>2009-06-18 15:42:52 +0200
committerWerner Lemberg <wl@gnu.org>2009-06-18 15:42:52 +0200
commit72271140434028186a49a5dc5925f0727559e46f (patch)
tree090fc9322d5b80e215191a2da657a32b643964b7 /src
parent780d7e05e71635812efd3b3a19d70e2411803136 (diff)
downloadfreetype2-72271140434028186a49a5dc5925f0727559e46f.tar.gz
Fix B/W rasterization of subglyphs with different drop-out modes.
Normally, the SCANMODE instruction (if present) to set the drop-out mode in a TrueType font is located in the `prep' table only and thus valid for all glyphs. However, there are fonts like `pala.ttf' which additionally contain this instruction in the hinting code of some glyphs (but not all). As a result it can happen that a composite glyph needs multiple drop-out modes for its subglyphs since the rendering state gets reset for each subglyph. FreeType collects the hinted outlines from all subglyphs, then it sends the data to the rasterizer. It also sends the drop-out mode -- after hinting has been applied -- and here is the error: It sends the drop-out mode of the last subglyph only; drop-out modes of all other subglyphs are lost. This patch fixes the problem; it adds a second, alternative mechanism to pass the drop-out mode: For each contour, the rasterizer now checks the first `tags' array element. If bit 2 is set, bits 5-7 contain the contour's drop-out mode, overriding the global drop-out mode. * include/freetype/ftimage.h (FT_CURVE_TAG_HAS_SCANMODE): New macro. * src/truetype/ttgload.c (TT_Hint_Glyph): Store drop-out mode in `tags[0]'. * src/raster/ftraster.c (Flow_Up, Overshoot_Top, Overshoot_Bottom): Use bits 3-5 instead of 0-2. (New_Profile): Set the drop-out mode in the profile's `flags' field. (Decompose_Curve): Check `tags[0]' and set `dropOutControl' if necessary. (Vertical_Sweep_Drop, Horizontal_Sweep_Drop, Horizontal_Gray_Sweep_Drop, Draw_Sweep): Use the profile's drop-out mode.
Diffstat (limited to 'src')
-rw-r--r--src/raster/ftraster.c46
-rw-r--r--src/truetype/ttgload.c7
2 files changed, 40 insertions, 13 deletions
diff --git a/src/raster/ftraster.c b/src/raster/ftraster.c
index c8c13f22e..4547dc9bf 100644
--- a/src/raster/ftraster.c
+++ b/src/raster/ftraster.c
@@ -306,9 +306,9 @@
/* values for the `flags' bit field */
-#define Flow_Up 0x1
-#define Overshoot_Top 0x2
-#define Overshoot_Bottom 0x4
+#define Flow_Up 0x8
+#define Overshoot_Top 0x10
+#define Overshoot_Bottom 0x20
/* States of each line, arc, and profile */
@@ -330,8 +330,10 @@
FT_F26Dot6 X; /* current coordinate during sweep */
PProfile link; /* link to next profile (various purposes) */
PLong offset; /* start of profile's data in render pool */
- unsigned flags; /* Bit 0: profile orientation (up/down) */
- /* Bit 1, 2: profile overshoot (top/bottom) */
+ unsigned flags; /* Bit 0-2: drop-out mode */
+ /* Bit 3: profile orientation (up/down) */
+ /* Bit 4: is top profile? */
+ /* Bit 5: is bottom profile? */
long height; /* profile's height in scanlines */
long start; /* profile's starting scanline */
@@ -656,6 +658,7 @@
ras.cProfile->offset = ras.top;
ras.cProfile->link = (PProfile)0;
ras.cProfile->next = (PProfile)0;
+ ras.cProfile->flags = ras.dropOutControl;
switch ( aState )
{
@@ -1739,7 +1742,12 @@
point = points + first;
tags = ras.outline.tags + first;
- tag = FT_CURVE_TAG( tags[0] );
+
+ /* set scan mode if necessary */
+ if ( tags[0] & FT_CURVE_TAG_HAS_SCANMODE )
+ ras.dropOutControl = (Byte)tags[0] >> 5;
+
+ tag = FT_CURVE_TAG( tags[0] );
/* A contour cannot start with a cubic control point! */
if ( tag == FT_CURVE_TAG_CUBIC )
@@ -2269,9 +2277,12 @@
if ( e1 > e2 )
{
+ Int dropOutControl = left->flags & 7;
+
+
if ( e1 == e2 + ras.precision )
{
- switch ( ras.dropOutControl )
+ switch ( dropOutControl )
{
case 0: /* simple drop-outs including stubs */
pxl = e2;
@@ -2324,7 +2335,7 @@
x2 - x1 >= ras.precision_half ) )
return;
- if ( ras.dropOutControl == 1 )
+ if ( dropOutControl == 1 )
pxl = e2;
else
pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );
@@ -2467,9 +2478,12 @@
if ( e1 > e2 )
{
+ Int dropOutControl = left->flags & 7;
+
+
if ( e1 == e2 + ras.precision )
{
- switch ( ras.dropOutControl )
+ switch ( dropOutControl )
{
case 0: /* simple drop-outs including stubs */
pxl = e2;
@@ -2497,7 +2511,7 @@
x2 - x1 >= ras.precision_half ) )
return;
- if ( ras.dropOutControl == 1 )
+ if ( dropOutControl == 1 )
pxl = e2;
else
pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );
@@ -2723,9 +2737,12 @@
if ( e1 > e2 )
{
+ Int dropOutControl = left->flags & 7;
+
+
if ( e1 == e2 + ras.precision )
{
- switch ( ras.dropOutControl )
+ switch ( dropOutControl )
{
case 0: /* simple drop-outs including stubs */
e1 = e2;
@@ -2747,7 +2764,7 @@
if ( right->next == left && left->start == y )
return;
- if ( ras.dropOutControl == 1 )
+ if ( dropOutControl == 1 )
e1 = e2;
else
e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );
@@ -2928,7 +2945,10 @@
{
if ( e1 > e2 || e2 == e1 + ras.precision )
{
- if ( ras.dropOutControl != 2 )
+ Int dropOutControl = P_Left->flags & 7;
+
+
+ if ( dropOutControl != 2 )
{
/* a drop-out was detected */
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index ad2b62e74..38023b82c 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -680,6 +680,9 @@
FT_Bool debug;
FT_Error error;
+ FT_GlyphLoader gloader = loader->gloader;
+ FT_Outline current_outline = gloader->current.outline;
+
error = TT_Set_CodeRange( loader->exec, tt_coderange_glyph,
loader->exec->glyphIns, n_ins );
@@ -695,6 +698,10 @@
error = TT_Run_Context( loader->exec, debug );
if ( error && loader->exec->pedantic_hinting )
return error;
+
+ /* store drop-out mode in bits 5-7; set bit 2 also as a marker */
+ current_outline.tags[0] |=
+ ( loader->exec->GS.scan_type << 5 ) | FT_CURVE_TAG_HAS_SCANMODE;
}
#endif