summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexei Podtelezhnikov <apodtele@gmail.com>2018-12-11 23:22:15 -0500
committerAlexei Podtelezhnikov <apodtele@gmail.com>2018-12-11 23:22:15 -0500
commit953b3682b69b438ce7e6827628909788da25c373 (patch)
tree72c0e5325db494f01b97e761cf1e9dc9a9fa176b
parent9569a5b2f21696c0535b3ecea2e391811a8995d2 (diff)
downloadfreetype2-953b3682b69b438ce7e6827628909788da25c373.tar.gz
Color glyph framework and rendering (3/3).
* include/freetype/config/ftmodule.h, src/smooth/module.mk: Register color renderer. * include/freetype/freetype.h (FT_RENDER_MODE_BGRA): Introduce it. * src/base/ftobjs.c (ft_glyphslot_preset_bitmap): Handle BGRA mode. * src/smooth/ftsmooth.c (ft_smooth_render_bgra): Implement it. (ft_smooth_bgra_renderer_class): Define it. * src/smooth/ftsmooth.h: Declare it.
-rw-r--r--ChangeLog12
-rw-r--r--include/freetype/config/ftmodule.h1
-rw-r--r--include/freetype/freetype.h6
-rw-r--r--src/base/ftobjs.c8
-rw-r--r--src/smooth/ftsmooth.c137
-rw-r--r--src/smooth/ftsmooth.h2
-rw-r--r--src/smooth/module.mk2
7 files changed, 168 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 4242a2179..47bd88705 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
2018-12-11 Alexei Podtelezhnikov <apodtele@gmail.com>
+ Color glyph framework and rendering (3/3).
+
+ * include/freetype/config/ftmodule.h, src/smooth/module.mk:
+ Register color renderer.
+ * include/freetype/freetype.h (FT_RENDER_MODE_BGRA): Introduce it.
+ * src/base/ftobjs.c (ft_glyphslot_preset_bitmap): Handle BGRA mode.
+ * src/smooth/ftsmooth.c (ft_smooth_render_bgra): Implement it.
+ (ft_smooth_bgra_renderer_class): Define it.
+ * src/smooth/ftsmooth.h: Declare it.
+
+2018-12-11 Alexei Podtelezhnikov <apodtele@gmail.com>
+
Color glyph framework and rendering (2/3).
* include/freetype/freetype.h (FT_GlyphSlotRec): Rename reserved
diff --git a/include/freetype/config/ftmodule.h b/include/freetype/config/ftmodule.h
index 7c603e532..e3924e658 100644
--- a/include/freetype/config/ftmodule.h
+++ b/include/freetype/config/ftmodule.h
@@ -27,6 +27,7 @@ FT_USE_MODULE( FT_Module_Class, sfnt_module_class )
FT_USE_MODULE( FT_Renderer_Class, ft_smooth_renderer_class )
FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcd_renderer_class )
FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcdv_renderer_class )
+FT_USE_MODULE( FT_Renderer_Class, ft_smooth_bgra_renderer_class )
FT_USE_MODULE( FT_Driver_ClassRec, bdf_driver_class )
/* EOF */
diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h
index 9398f39ee..7e054b0bc 100644
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -3239,6 +3239,11 @@ FT_BEGIN_HEADER
* bitmaps that are 3~times the height of the original glyph outline in
* pixels and use the @FT_PIXEL_MODE_LCD_V mode.
*
+ * FT_RENDER_MODE_BGRA ::
+ * This mode is intended for rendering color layered glyphs. It
+ * produces 32-bit premultiplied color images using @FT_PIXEL_MODE_BGRA
+ * mode.
+ *
* @note:
* Should you define `FT_CONFIG_OPTION_SUBPIXEL_RENDERING` in your
* `ftoption.h`, which enables patented ClearType-style rendering, the
@@ -3260,6 +3265,7 @@ FT_BEGIN_HEADER
FT_RENDER_MODE_MONO,
FT_RENDER_MODE_LCD,
FT_RENDER_MODE_LCD_V,
+ FT_RENDER_MODE_BGRA,
FT_RENDER_MODE_MAX
diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c
index 9022d2536..9358b5f24 100644
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -441,6 +441,10 @@
ft_lcd_padding( &cbox, slot, mode );
goto Adjust;
+ case FT_RENDER_MODE_BGRA:
+ pixel_mode = FT_PIXEL_MODE_BGRA;
+ goto Adjust;
+
case FT_RENDER_MODE_NORMAL:
case FT_RENDER_MODE_LIGHT:
default:
@@ -469,6 +473,10 @@
pitch = FT_PAD_CEIL( width, 4 );
break;
+ case FT_PIXEL_MODE_BGRA:
+ pitch = 4 * width;
+ break;
+
case FT_PIXEL_MODE_LCD_V:
height *= 3;
/* fall through */
diff --git a/src/smooth/ftsmooth.c b/src/smooth/ftsmooth.c
index cdae25391..44ceb09ed 100644
--- a/src/smooth/ftsmooth.c
+++ b/src/smooth/ftsmooth.c
@@ -20,6 +20,7 @@
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_OBJECTS_H
#include FT_OUTLINE_H
+#include FT_BITMAP_H
#include "ftsmooth.h"
#include "ftgrays.h"
@@ -419,6 +420,115 @@
}
+ /* convert a slot image into a BGRA bitmap using supplemental color array */
+ static FT_Error
+ ft_smooth_render_bgra( FT_Renderer render,
+ FT_GlyphSlot slot,
+ FT_Render_Mode mode,
+ const FT_Vector* origin )
+ {
+ FT_Error error = FT_Err_Ok;
+ FT_Memory memory = render->root.memory;
+ FT_Outline outline = slot->outline; /* hard copy */
+ FT_Bitmap target;
+ FT_Vector target_offset, offset;
+ short i, c_done, p_done;
+
+
+ /* check glyph image format */
+ if ( slot->format != render->glyph_format )
+ return FT_THROW( Invalid_Argument );
+
+ /* check mode */
+ if ( mode != FT_RENDER_MODE_BGRA ||
+ slot->color == NULL )
+ return FT_THROW( Cannot_Render_Glyph );
+
+ /* release old bitmap buffer */
+ if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
+ {
+ FT_FREE( slot->bitmap.buffer );
+ slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
+ }
+
+ if ( ft_glyphslot_preset_bitmap( slot, mode, origin ) )
+ return FT_THROW( Raster_Overflow );
+
+ target = slot->bitmap;
+ target_offset.x = slot->bitmap_left * 64;
+ target_offset.y = slot->bitmap_top * 64;
+
+ /* allocate new one */
+ if ( FT_ALLOC_MULT( target.buffer, target.rows, target.pitch ) )
+ goto Exit;
+
+ c_done = 0;
+ p_done = 0;
+ for ( i = 0; i < outline.n_contours; i++ )
+ {
+ /* grow layer */
+ slot->outline.n_contours = i - c_done + 1;
+ slot->outline.n_points = outline.contours[i] - p_done + 1;
+ slot->outline.contours[i - c_done] = outline.contours[i] - p_done;
+
+ if ( i == outline.n_contours - 1 ||
+ slot->color[i + 1].red != slot->color[c_done].red ||
+ slot->color[i + 1].green != slot->color[c_done].green ||
+ slot->color[i + 1].blue != slot->color[c_done].blue ||
+ slot->color[i + 1].alpha != slot->color[c_done].alpha )
+ {
+ /* render layer */
+ error = ft_smooth_render( render,
+ slot,
+ FT_RENDER_MODE_NORMAL,
+ origin );
+ if ( error )
+ break;
+
+ /* blend layer */
+ offset.x = slot->bitmap_left * 64;
+ offset.y = slot->bitmap_top * 64;
+ error = FT_Bitmap_Blend( slot->library,
+ &slot->bitmap,
+ offset,
+ &target,
+ &target_offset,
+ slot->color[c_done] );
+
+ if ( error )
+ break;
+
+ c_done += slot->outline.n_contours;
+ p_done += slot->outline.n_points;
+
+ /* start next layer */
+ slot->outline.contours = outline.contours + c_done;
+ slot->outline.points = outline.points + p_done;
+ slot->outline.tags = outline.tags + p_done;
+
+ slot->format = FT_GLYPH_FORMAT_OUTLINE;
+ }
+ }
+
+ /* restore pointers so that they can be freed */
+ slot->outline.contours = outline.contours;
+ slot->outline.points = outline.points;
+ slot->outline.tags = outline.tags;
+
+ if ( !error )
+ {
+ FT_FREE( slot->bitmap.buffer );
+ slot->bitmap = target;
+ slot->bitmap_left = target_offset.x >> 6;
+ slot->bitmap_top = target_offset.y >> 6;
+ slot->format = FT_GLYPH_FORMAT_BITMAP;
+ }
+
+ Exit:
+ return error;
+ }
+
+
FT_DEFINE_RENDERER(
ft_smooth_renderer_class,
@@ -500,4 +610,31 @@
)
+ FT_DEFINE_RENDERER(
+ ft_smooth_bgra_renderer_class,
+
+ FT_MODULE_RENDERER,
+ sizeof ( FT_RendererRec ),
+
+ "smooth-bgra",
+ 0x10000L,
+ 0x20000L,
+
+ NULL, /* module specific interface */
+
+ (FT_Module_Constructor)ft_smooth_init, /* module_init */
+ (FT_Module_Destructor) NULL, /* module_done */
+ (FT_Module_Requester) NULL, /* get_interface */
+
+ FT_GLYPH_FORMAT_OUTLINE,
+
+ (FT_Renderer_RenderFunc) ft_smooth_render_bgra, /* render_glyph */
+ (FT_Renderer_TransformFunc)ft_smooth_transform, /* transform_glyph */
+ (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, /* get_glyph_cbox */
+ (FT_Renderer_SetModeFunc) ft_smooth_set_mode, /* set_mode */
+
+ (FT_Raster_Funcs*)&ft_grays_raster /* raster_class */
+ )
+
+
/* END */
diff --git a/src/smooth/ftsmooth.h b/src/smooth/ftsmooth.h
index 782f11a60..6b67a6a3e 100644
--- a/src/smooth/ftsmooth.h
+++ b/src/smooth/ftsmooth.h
@@ -33,6 +33,8 @@ FT_BEGIN_HEADER
FT_DECLARE_RENDERER( ft_smooth_lcdv_renderer_class )
+ FT_DECLARE_RENDERER( ft_smooth_bgra_renderer_class )
+
FT_END_HEADER
diff --git a/src/smooth/module.mk b/src/smooth/module.mk
index 5b8bc3be3..1898f914f 100644
--- a/src/smooth/module.mk
+++ b/src/smooth/module.mk
@@ -22,6 +22,8 @@ $(OPEN_DRIVER) FT_Renderer_Class, ft_smooth_lcd_renderer_class $(CLOSE_DRIVER)
$(ECHO_DRIVER)smooth $(ECHO_DRIVER_DESC)anti-aliased bitmap renderer for LCDs$(ECHO_DRIVER_DONE)
$(OPEN_DRIVER) FT_Renderer_Class, ft_smooth_lcdv_renderer_class $(CLOSE_DRIVER)
$(ECHO_DRIVER)smooth $(ECHO_DRIVER_DESC)anti-aliased bitmap renderer for vertical LCDs$(ECHO_DRIVER_DONE)
+$(OPEN_DRIVER) FT_Renderer_Class, ft_smooth_bgra_renderer_class $(CLOSE_DRIVER)
+$(ECHO_DRIVER)smooth $(ECHO_DRIVER_DESC)color bitmap renderer for layered glyphs$(ECHO_DRIVER_DONE)
endef
# EOF