[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[freetype2] master 3fa5c8456: [raster] Fix linked profiles in contour lo
From: |
Werner Lemberg |
Subject: |
[freetype2] master 3fa5c8456: [raster] Fix linked profiles in contour loops. |
Date: |
Wed, 18 Oct 2023 00:16:58 -0400 (EDT) |
branch: master
commit 3fa5c84565f2431a13247f055623508137dc5739
Author: Alexei Podtelezhnikov <apodtele@gmail.com>
Commit: Alexei Podtelezhnikov <apodtele@gmail.com>
[raster] Fix linked profiles in contour loops.
This fixes a subtle bug when the last profile in a contour was not
properly short-circuited if it was still empty at `End_Profile`.
We finalize all linking in `Finalize_Profile_List` now and do nothing
else there. The turns are added in `End_Profile`.
* src/raster/ftraster.c (Insert_Y_Turn): Moved up unchanged.
(End_Profile): Take care of turns but set only preliminary linking.
(Finalize_Profile_Table): Take care of linking and null-termination.
(Convert_Glyph): Adjusted accordingly.
---
src/raster/ftraster.c | 214 ++++++++++++++++++++++++--------------------------
1 file changed, 101 insertions(+), 113 deletions(-)
diff --git a/src/raster/ftraster.c b/src/raster/ftraster.c
index 55a24d73e..7991bb118 100644
--- a/src/raster/ftraster.c
+++ b/src/raster/ftraster.c
@@ -591,6 +591,62 @@
}
+ /**************************************************************************
+ *
+ * @Function:
+ * Insert_Y_Turn
+ *
+ * @Description:
+ * Insert a salient into the sorted list placed on top of the render
+ * pool.
+ *
+ * @Input:
+ * New y scanline position.
+ *
+ * @Return:
+ * SUCCESS on success. FAILURE in case of overflow.
+ */
+ static Bool
+ Insert_Y_Turn( RAS_ARGS Int y )
+ {
+ PLong y_turns;
+ Int n;
+
+
+ n = ras.numTurns - 1;
+ y_turns = ras.sizeBuff - ras.numTurns;
+
+ /* look for first y value that is <= */
+ while ( n >= 0 && y < y_turns[n] )
+ n--;
+
+ /* if it is <, simply insert it, ignore if == */
+ if ( n >= 0 && y > y_turns[n] )
+ do
+ {
+ Int y2 = (Int)y_turns[n];
+
+
+ y_turns[n] = y;
+ y = y2;
+ } while ( --n >= 0 );
+
+ if ( n < 0 )
+ {
+ ras.maxBuff--;
+ if ( ras.maxBuff <= ras.top )
+ {
+ ras.error = FT_THROW( Raster_Overflow );
+ return FAILURE;
+ }
+ ras.numTurns++;
+ ras.sizeBuff[-ras.numTurns] = y;
+ }
+
+ return SUCCESS;
+ }
+
+
/**************************************************************************
*
* @Function:
@@ -687,10 +743,10 @@
static Bool
End_Profile( RAS_ARGS Bool overshoot )
{
- Long h;
-
+ PProfile p = ras.cProfile;
+ Long h = (Long)( ras.top - p->offset );
+ Int bottom, top;
- h = (Long)( ras.top - ras.cProfile->offset );
if ( h < 0 )
{
@@ -701,82 +757,45 @@
if ( h > 0 )
{
- FT_TRACE7(( " ending profile %p, start = %ld, height = %ld\n",
- (void *)ras.cProfile, ras.cProfile->start, h ));
+ FT_TRACE7(( " ending profile %p, start = %2ld, height = %+3ld\n",
+ (void *)p, p->start, p->flags & Flow_Up ? h : -h ));
- ras.cProfile->height = h;
if ( overshoot )
{
- if ( ras.cProfile->flags & Flow_Up )
- ras.cProfile->flags |= Overshoot_Top;
+ if ( p->flags & Flow_Up )
+ p->flags |= Overshoot_Top;
else
- ras.cProfile->flags |= Overshoot_Bottom;
+ p->flags |= Overshoot_Bottom;
}
- /* premature, the last profile in the contour must loop */
- ras.cProfile->next = (PProfile)ras.top;
-
- ras.num_Profs++;
- }
-
- ras.joint = FALSE;
-
- return SUCCESS;
- }
-
+ p->height = h;
- /**************************************************************************
- *
- * @Function:
- * Insert_Y_Turn
- *
- * @Description:
- * Insert a salient into the sorted list placed on top of the render
- * pool.
- *
- * @Input:
- * New y scanline position.
- *
- * @Return:
- * SUCCESS on success. FAILURE in case of overflow.
- */
- static Bool
- Insert_Y_Turn( RAS_ARGS Int y )
- {
- PLong y_turns;
- Int n;
-
-
- n = ras.numTurns - 1;
- y_turns = ras.sizeBuff - ras.numTurns;
-
- /* look for first y value that is <= */
- while ( n >= 0 && y < y_turns[n] )
- n--;
-
- /* if it is <, simply insert it, ignore if == */
- if ( n >= 0 && y > y_turns[n] )
- do
+ if ( p->flags & Flow_Up )
{
- Int y2 = (Int)y_turns[n];
+ bottom = (Int)p->start;
+ top = (Int)( p->start + h - 1 );
+ }
+ else
+ {
+ bottom = (Int)( p->start - h + 1 );
+ top = (Int)p->start;
+ p->start = bottom;
+ p->offset += h - 1;
+ }
+ if ( Insert_Y_Turn( RAS_VARS bottom ) ||
+ Insert_Y_Turn( RAS_VARS top + 1 ) )
+ return FAILURE;
- y_turns[n] = y;
- y = y2;
- } while ( --n >= 0 );
+ /* preliminary values to be finalized */
+ p->link = (PProfile)ras.top;
+ p->next = ras.gProfile;
- if ( n < 0 )
- {
- ras.maxBuff--;
- if ( ras.maxBuff <= ras.top )
- {
- ras.error = FT_THROW( Raster_Overflow );
- return FAILURE;
- }
- ras.numTurns++;
- ras.sizeBuff[-ras.numTurns] = y;
+ ras.num_Profs++;
}
+ ras.joint = FALSE;
+
return SUCCESS;
}
@@ -788,56 +807,28 @@
*
* @Description:
* Adjust all links in the profiles list.
- *
- * @Return:
- * SUCCESS on success. FAILURE in case of overflow.
*/
- static Bool
+ static void
Finalize_Profile_Table( RAS_ARG )
{
- UShort n;
- PProfile p;
-
+ UShort n = ras.num_Profs;
+ PProfile p = ras.fProfile;
+ PProfile q;
- n = ras.num_Profs;
- p = ras.fProfile;
- if ( n > 1 && p )
+ while ( --n )
{
- do
- {
- Int bottom, top;
-
-
- if ( n > 1 )
- p->link = (PProfile)( p->offset + p->height );
- else
- p->link = NULL;
-
- if ( p->flags & Flow_Up )
- {
- bottom = (Int)p->start;
- top = (Int)( p->start + p->height - 1 );
- }
- else
- {
- bottom = (Int)( p->start - p->height + 1 );
- top = (Int)p->start;
- p->start = bottom;
- p->offset += p->height - 1;
- }
+ q = p->link;
- if ( Insert_Y_Turn( RAS_VARS bottom ) ||
- Insert_Y_Turn( RAS_VARS top + 1 ) )
- return FAILURE;
+ /* fix the contour loop */
+ if ( q->next == p->next )
+ p->next = q;
- p = p->link;
- } while ( --n );
+ p = q;
}
- else
- ras.fProfile = NULL;
- return SUCCESS;
+ /* null-terminate */
+ p->link = NULL;
}
@@ -2001,17 +1992,14 @@
if ( End_Profile( RAS_VARS o ) )
return FAILURE;
- /* loop the last profile in the contour */
- ras.cProfile->next = ras.gProfile;
-
- if ( !ras.fProfile )
+ if ( !ras.fProfile && ras.num_Profs )
ras.fProfile = ras.gProfile;
}
- if ( Finalize_Profile_Table( RAS_VAR ) )
- return FAILURE;
+ if ( ras.num_Profs )
+ Finalize_Profile_Table( RAS_VAR );
- return (Bool)( ras.top < ras.maxBuff ? SUCCESS : FAILURE );
+ return SUCCESS;
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [freetype2] master 3fa5c8456: [raster] Fix linked profiles in contour loops.,
Werner Lemberg <=