summaryrefslogtreecommitdiff
path: root/src/smooth/ftgrays.c
diff options
context:
space:
mode:
authorAlexei Podtelezhnikov <apodtele@gmail.com>2021-03-11 22:40:19 -0500
committerAlexei Podtelezhnikov <apodtele@gmail.com>2021-03-11 22:40:19 -0500
commit80bda804d53e3f0df0ea20c639adc0e479c4ed47 (patch)
tree134f10df114602fc9175820fdc7fa070d5b73b62 /src/smooth/ftgrays.c
parentd5b7de5541040e027f6defdd1b93939624ff824c (diff)
downloadfreetype2-80bda804d53e3f0df0ea20c639adc0e479c4ed47.tar.gz
[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.
Diffstat (limited to 'src/smooth/ftgrays.c')
-rw-r--r--src/smooth/ftgrays.c109
1 files changed, 42 insertions, 67 deletions
diff --git a/src/smooth/ftgrays.c b/src/smooth/ftgrays.c
index 5e3d453c6..8ea723028 100644
--- a/src/smooth/ftgrays.c
+++ b/src/smooth/ftgrays.c
@@ -447,14 +447,10 @@ typedef ptrdiff_t FT_PtrDist;
{
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 @@ typedef ptrdiff_t FT_PtrDist;
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,59 +520,15 @@ typedef ptrdiff_t FT_PtrDist;
/**************************************************************************
*
- * 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
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 @@ typedef ptrdiff_t FT_PtrDist;
/* 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;
+ ex = FT_MAX( ex, ras.min_ex - 1 );
+
+ pcell = &ras.ycells[ey - ras.min_ey];
+ while ( ( cell = *pcell ) )
+ {
+ if ( cell->x > ex )
+ break;
- ras.invalid = ( ey >= ras.max_ey || ey < ras.min_ey ||
- ex >= ras.max_ex );
+ 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 @@ typedef ptrdiff_t FT_PtrDist;
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 @@ typedef ptrdiff_t FT_PtrDist;
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];