[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 = ⌖
+
+ 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, ¶ms );
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, ¶ms );
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 );
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [freetype2] master 19d39f4 2/2: [smooth] Use direct rendering mode in Harmony.,
Alexei Podtelezhnikov <=