freetype-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[freetype2] master 19d39f4 2/2: [smooth] Use direct rendering mode in Ha


From: Alexei Podtelezhnikov
Subject: [freetype2] master 19d39f4 2/2: [smooth] Use direct rendering mode in Harmony.
Date: Fri, 3 Jul 2020 09:19:49 -0400 (EDT)

branch: master
commit 19d39f43d25b375767b40b26aac7b2061d321ae2
Author: Alexei Podtelezhnikov <apodtele@gmail.com>
Commit: Alexei Podtelezhnikov <apodtele@gmail.com>

    [smooth] Use direct rendering mode in Harmony.
    
    Instead of rendering 3 bitmaps side by side and reshuffling, we use
    direct rendering to deliver the bitmaps on each third byte.
    
    * src/smooth/ftsmooth.c (ft_smooth_raster_lcd)
    [!FT_CONFIG_OPTION_SUBPIXEL_RENDERING]: Set up direct mode with...
    (ft_smooth_lcd_spans): ... new span function.
---
 ChangeLog             | 11 +++++++
 src/smooth/ftsmooth.c | 89 +++++++++++++++++++++++++++------------------------
 2 files changed, 59 insertions(+), 41 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 9af7080..f5045de 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
 2020-07-03  Alexei Podtelezhnikov  <apodtele@gmail.com>
 
+       [smooth] Use direct rendering mode in Harmony.
+
+       Instead of rendering 3 bitmaps side by side and reshuffling, we use
+       direct rendering to deliver the bitmaps on each third byte.
+
+       * src/smooth/ftsmooth.c (ft_smooth_raster_lcd)
+       [!FT_CONFIG_OPTION_SUBPIXEL_RENDERING]: Set up direct mode with...
+       (ft_smooth_lcd_spans): ... new span function.
+
+2020-07-03  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
        [smooth] Separate LCD paths from gray rendering.
 
        This makes `ft_smooth_render' a lot smaller and easier to follow. It
diff --git a/src/smooth/ftsmooth.c b/src/smooth/ftsmooth.c
index 945ff80..1e0d0a3 100644
--- a/src/smooth/ftsmooth.c
+++ b/src/smooth/ftsmooth.c
@@ -76,6 +76,13 @@
       FT_Outline_Get_CBox( &slot->outline, cbox );
   }
 
+  typedef struct TOrigin_
+  {
+    unsigned char*  origin;  /* pixmap origin at the bottom-left */
+    int             pitch;   /* pitch to go down one row */
+
+  } TOrigin;
+
 #ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
 
   /* initialize renderer -- init its raster */
@@ -99,24 +106,58 @@
   }
 
 
+  /* This function writes every third byte in direct rendering mode */
+  static void
+  ft_smooth_lcd_spans( int             y,
+                       int             count,
+                       const FT_Span*  spans,
+                       TOrigin*        target )
+  {
+    unsigned char*  dst_line = target->origin - y * target->pitch;
+    unsigned char*  dst;
+    unsigned short  w;
+
+
+    for ( ; count--; spans++ )
+      for ( dst = dst_line + spans->x * 3, w = spans->len; w--; dst += 3 )
+        *dst = spans->coverage;
+  }
+
+
   static FT_Error
   ft_smooth_raster_lcd( FT_Renderer  render,
                         FT_Outline*  outline,
                         FT_Bitmap*   bitmap )
   {
     FT_Error      error = FT_Err_Ok;
-    unsigned int  width = bitmap->width / 3;
     FT_Vector*    sub   = render->root.library->lcd_geometry;
     FT_Pos        x, y;
 
     FT_Raster_Params   params;
+    TOrigin            target;
 
 
-    params.target = bitmap;
-    params.source = outline;
-    params.flags  = FT_RASTER_FLAG_AA;
-
     /* Render 3 separate coverage bitmaps, shifting the outline.  */
+    /* Set up direct rendering to record them on each third byte. */
+    params.target     = bitmap;
+    params.source     = outline;
+    params.flags      = FT_RASTER_FLAG_AA | FT_RASTER_FLAG_DIRECT;
+    params.gray_spans = (FT_SpanFunc)ft_smooth_lcd_spans;
+    params.user       = &target;
+
+    params.clip_box.xMin = 0;
+    params.clip_box.yMin = 0;
+    params.clip_box.xMax = bitmap->width;
+    params.clip_box.yMax = bitmap->rows;
+
+    if ( bitmap->pitch < 0 )
+      target.origin = bitmap->buffer;
+    else
+      target.origin = bitmap->buffer
+                      + ( bitmap->rows - 1 ) * (unsigned int)bitmap->pitch;
+
+    target.pitch = bitmap->pitch;
+
     FT_Outline_Translate( outline,
                           -sub[0].x,
                           -sub[0].y );
@@ -126,57 +167,23 @@
     if ( error )
       goto Exit;
 
-    bitmap->buffer += width;
+    target.origin++;
     FT_Outline_Translate( outline,
                           sub[0].x - sub[1].x,
                           sub[0].y - sub[1].y );
     error = render->raster_render( render->raster, &params );
     x = sub[1].x;
     y = sub[1].y;
-    bitmap->buffer -= width;
     if ( error )
       goto Exit;
 
-    bitmap->buffer += 2 * width;
+    target.origin++;
     FT_Outline_Translate( outline,
                           sub[1].x - sub[2].x,
                           sub[1].y - sub[2].y );
     error = render->raster_render( render->raster, &params );
     x = sub[2].x;
     y = sub[2].y;
-    bitmap->buffer -= 2 * width;
-    if ( error )
-      goto Exit;
-
-    /* XXX: Rearrange the bytes according to FT_PIXEL_MODE_LCD.    */
-    /* XXX: It is more efficient to render every third byte above. */
-    {
-      FT_Memory  memory  = render->root.memory;
-      FT_Byte*   line;
-      FT_Byte*   temp = NULL;
-      FT_UInt    i, j;
-
-      unsigned int  height = bitmap->rows;
-      int           pitch  = bitmap->pitch;
-
-
-      if ( FT_ALLOC( temp, (FT_ULong)pitch ) )
-        goto Exit;
-
-      for ( i = 0; i < height; i++ )
-      {
-        line = bitmap->buffer + i * (FT_ULong)pitch;
-        for ( j = 0; j < width; j++ )
-        {
-          temp[3 * j    ] = line[j];
-          temp[3 * j + 1] = line[j + width];
-          temp[3 * j + 2] = line[j + width + width];
-        }
-        FT_MEM_COPY( line, temp, pitch );
-      }
-
-      FT_FREE( temp );
-    }
 
   Exit:
     FT_Outline_Translate( outline, x, y );



reply via email to

[Prev in Thread] Current Thread [Next in Thread]