Commit 1f271751a39e5bc9c639adc213183ed5e58a9401

Alexei Podtelezhnikov 2019-04-11T23:48:21

[smooth] Fix segfault in direct mode (#56092). * src/base/ftoutln.c (FT_Outline_Render): Set missing clip_box for direct mode. * src/smooth/ftgrays.c (gray_raster_render): Use it.

diff --git a/ChangeLog b/ChangeLog
index 7e38010..655e5ab 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2019-04-11  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+	[smooth] Fix segfault in direct mode (#56092).
+
+	* src/base/ftoutln.c (FT_Outline_Render): Set missing clip_box for
+	direct mode.
+	* src/smooth/ftgrays.c (gray_raster_render): Use it.
+
 2019-04-06  Werner Lemberg  <wl@gnu.org>
 
 	* src/sfnt/ttcmap.c (tt_get_glyph_name): Pacify compiler (#56061).
diff --git a/src/base/ftoutln.c b/src/base/ftoutln.c
index 00329b4..86fa1c2 100644
--- a/src/base/ftoutln.c
+++ b/src/base/ftoutln.c
@@ -621,6 +621,16 @@
 
     params->source = (void*)outline;
 
+    /* preset clip_box for direct mode */
+    if ( params->flags & FT_RASTER_FLAG_DIRECT    &&
+         !( params->flags & FT_RASTER_FLAG_CLIP ) )
+    {
+      params->clip_box.xMin = cbox.xMin >> 6;
+      params->clip_box.yMin = cbox.yMin >> 6;
+      params->clip_box.xMax = ( cbox.xMax + 63 ) >> 6;
+      params->clip_box.yMax = ( cbox.yMax + 63 ) >> 6;
+    }
+
     error = FT_ERR( Cannot_Render_Glyph );
     while ( renderer )
     {
diff --git a/src/smooth/ftgrays.c b/src/smooth/ftgrays.c
index 91293ac..20c6a34 100644
--- a/src/smooth/ftgrays.c
+++ b/src/smooth/ftgrays.c
@@ -1755,7 +1755,6 @@ typedef ptrdiff_t  FT_PtrDist;
   {
     const FT_Outline*  outline    = (const FT_Outline*)params->source;
     const FT_Bitmap*   target_map = params->target;
-    FT_BBox            clip;
 
 #ifndef FT_STATIC_RASTER
     gray_TWorker  worker[1];
@@ -1792,6 +1791,11 @@ typedef ptrdiff_t  FT_PtrDist;
 
       ras.render_span      = (FT_Raster_Span_Func)params->gray_spans;
       ras.render_span_data = params->user;
+
+      ras.min_ex = params->clip_box.xMin;
+      ras.min_ey = params->clip_box.yMin;
+      ras.max_ex = params->clip_box.xMax;
+      ras.max_ey = params->clip_box.yMax;
     }
     else
     {
@@ -1816,27 +1820,14 @@ typedef ptrdiff_t  FT_PtrDist;
 
       ras.render_span      = (FT_Raster_Span_Func)NULL;
       ras.render_span_data = NULL;
-    }
 
-    /* compute clipping box */
-    if ( params->flags & FT_RASTER_FLAG_DIRECT &&
-         params->flags & FT_RASTER_FLAG_CLIP   )
-      clip = params->clip_box;
-    else
-    {
-      /* compute clip box from target pixmap */
-      clip.xMin = 0;
-      clip.yMin = 0;
-      clip.xMax = (FT_Pos)target_map->width;
-      clip.yMax = (FT_Pos)target_map->rows;
+      ras.min_ex = 0;
+      ras.min_ey = 0;
+      ras.max_ex = (FT_Pos)target_map->width;
+      ras.max_ey = (FT_Pos)target_map->rows;
     }
 
-    /* clip to target bitmap, exit if nothing to do */
-    ras.min_ex = clip.xMin;
-    ras.min_ey = clip.yMin;
-    ras.max_ex = clip.xMax;
-    ras.max_ey = clip.yMax;
-
+    /* exit if nothing to do */
     if ( ras.max_ex <= ras.min_ex || ras.max_ey <= ras.min_ey )
       return 0;