freetype-commit
[Top][All Lists]
Advanced

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

[freetype2] color 953b368 3/3: Color glyph framework and rendering (3/3)


From: Alexei Podtelezhnikov
Subject: [freetype2] color 953b368 3/3: Color glyph framework and rendering (3/3).
Date: Tue, 11 Dec 2018 23:29:18 -0500 (EST)

branch: color
commit 953b3682b69b438ce7e6827628909788da25c373
Author: Alexei Podtelezhnikov <address@hidden>
Commit: Alexei Podtelezhnikov <address@hidden>

    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.
---
 ChangeLog                          |  12 ++++
 include/freetype/config/ftmodule.h |   1 +
 include/freetype/freetype.h        |   6 ++
 src/base/ftobjs.c                  |   8 +++
 src/smooth/ftsmooth.c              | 137 +++++++++++++++++++++++++++++++++++++
 src/smooth/ftsmooth.h              |   2 +
 src/smooth/module.mk               |   2 +
 7 files changed, 168 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index 4242a21..47bd887 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
 2018-12-11  Alexei Podtelezhnikov  <address@hidden>
 
+       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  <address@hidden>
+
        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 7c603e5..e3924e6 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 9398f39..7e054b0 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 9022d25..9358b5f 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 cdae253..44ceb09 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 782f11a..6b67a6a 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 5b8bc3b..1898f91 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



reply via email to

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