ref: 80bda804d53e3f0df0ea20c639adc0e479c4ed47
parent: d5b7de5541040e027f6defdd1b93939624ff824c
author: Alexei Podtelezhnikov <[email protected]>
date: Thu Mar 11 17:40:19 EST 2021
[smooth] Reduce copying during integration phase. We now record `cover' and `area' directly into the linked list. This makes rendering faster by 10% or even more at larger sizes. * src/smooth/ftgrays.c (FT_INTEGRATE): Write directly. (gray_TWorker): Add direct cell reference and remove unused fields. (gray_set_cell): Consolidate the linked list management and pointers. (gray_convert_glyph, gray_convert_glyph_inner): Updated.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2021-03-11 Alexei Podtelezhnikov <[email protected]>
+
+ [smooth] Reduce copying during integration phase.
+
+ We now record `cover' and `area' directly into the linked list. This
+ makes rendering faster by 10% or even more at larger sizes.
+
+ * src/smooth/ftgrays.c (FT_INTEGRATE): Write directly.
+ (gray_TWorker): Add direct cell reference and remove unused fields.
+ (gray_set_cell): Consolidate the linked list management and pointers.
+ (gray_convert_glyph, gray_convert_glyph_inner): Updated.
+
2021-03-10 Alexei Podtelezhnikov <[email protected]>
* src/smooth/ftgrays.c (FT_INTEGRATE): New convenience macro.
--- a/src/smooth/ftgrays.c
+++ b/src/smooth/ftgrays.c
@@ -447,14 +447,10 @@
{
ft_jmp_buf jump_buffer;
- TCoord ex, ey;
TCoord min_ex, max_ex;
TCoord min_ey, max_ey;
- TArea area;
- TCoord cover;
- int invalid;
-
+ PCell cell;
PCell* ycells;
PCell cells;
FT_PtrDist max_cells;
@@ -483,8 +479,9 @@
static gray_TWorker ras;
#endif
-#define FT_INTEGRATE( ras, a, b ) \
- ras.cover += (a), ras.area += (a) * (TArea)(b)
+#define FT_INTEGRATE( ras, a, b ) \
+ if ( ras.cell ) \
+ ras.cell->cover += (a), ras.cell->area += (a) * (TArea)(b)
typedef struct gray_TRaster_
@@ -523,50 +520,6 @@
/**************************************************************************
*
- * Record the current cell in the linked list.
- */
- static void
- gray_record_cell( RAS_ARG )
- {
- PCell *pcell, cell;
- TCoord x = ras.ex;
-
-
- pcell = &ras.ycells[ras.ey - ras.min_ey];
- while ( ( cell = *pcell ) )
- {
- if ( cell->x > x )
- break;
-
- if ( cell->x == x )
- goto Found;
-
- pcell = &cell->next;
- }
-
- if ( ras.num_cells >= ras.max_cells )
- ft_longjmp( ras.jump_buffer, 1 );
-
- /* insert new cell */
- cell = ras.cells + ras.num_cells++;
- cell->x = x;
- cell->area = ras.area;
- cell->cover = ras.cover;
-
- cell->next = *pcell;
- *pcell = cell;
-
- return;
-
- Found:
- /* update old cell */
- cell->area += ras.area;
- cell->cover += ras.cover;
- }
-
-
- /**************************************************************************
- *
* Set the current cell to a new position.
*/
static void
@@ -573,9 +526,9 @@
gray_set_cell( RAS_ARG_ TCoord ex,
TCoord ey )
{
- /* Move the cell pointer to a new position. We set the `invalid' */
- /* flag to indicate that the cell isn't part of those we're interested */
- /* in during the render phase. This means that: */
+ /* Move the cell pointer to a new position in the linked list. We use */
+ /* NULL to indicate that the cell is outside of the clipping region */
+ /* during the render phase. This means that: */
/* */
/* . the new vertical position must be within min_ey..max_ey-1. */
/* . the new horizontal position must be strictly less than max_ex */
@@ -583,17 +536,42 @@
/* Note that if a cell is to the left of the clipping region, it is */
/* actually set to the (min_ex-1) horizontal position. */
- /* record the current one if it is valid and substantial */
- if ( !ras.invalid && ( ras.area || ras.cover ) )
- gray_record_cell( RAS_VAR );
+ if ( ey >= ras.max_ey || ey < ras.min_ey || ex >= ras.max_ex )
+ ras.cell = NULL;
+ else
+ {
+ PCell *pcell, cell;
- ras.area = 0;
- ras.cover = 0;
- ras.ex = FT_MAX( ex, ras.min_ex - 1 );
- ras.ey = ey;
- ras.invalid = ( ey >= ras.max_ey || ey < ras.min_ey ||
- ex >= ras.max_ex );
+ ex = FT_MAX( ex, ras.min_ex - 1 );
+
+ pcell = &ras.ycells[ey - ras.min_ey];
+ while ( ( cell = *pcell ) )
+ {
+ if ( cell->x > ex )
+ break;
+
+ if ( cell->x == ex )
+ goto Found;
+
+ pcell = &cell->next;
+ }
+
+ if ( ras.num_cells >= ras.max_cells )
+ ft_longjmp( ras.jump_buffer, 1 );
+
+ /* insert new cell */
+ cell = ras.cells + ras.num_cells++;
+ cell->x = ex;
+ cell->area = 0;
+ cell->cover = 0;
+
+ cell->next = *pcell;
+ *pcell = cell;
+
+ Found:
+ ras.cell = cell;
+ }
}
@@ -1631,9 +1609,6 @@
if ( continued )
FT_Trace_Enable();
- if ( !ras.invalid )
- gray_record_cell( RAS_VAR );
-
FT_TRACE7(( "band [%d..%d]: %ld cell%s\n",
ras.min_ey,
ras.max_ey,
@@ -1702,7 +1677,7 @@
FT_MEM_ZERO( ras.ycells, height * sizeof ( PCell ) );
ras.num_cells = 0;
- ras.invalid = 1;
+ ras.cell = NULL;
ras.min_ey = band[1];
ras.max_ey = band[0];