[cairo-commit] src/cairo-ft-font.c

Behdad Esfahbod behdad at kemper.freedesktop.org
Mon Jul 29 16:12:07 PDT 2013


 src/cairo-ft-font.c |   52 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 51 insertions(+), 1 deletion(-)

New commits:
commit 9444ef09ccde2735258cc1bd2f1912119a32dd88
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Jul 29 19:09:29 2013 -0400

    Support 2bit and 4bit embedded bitmaps

diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index 28e361c..feef95b 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -1120,6 +1120,7 @@ _fill_xrender_bitmap(FT_Bitmap      *target,
  */
 static cairo_status_t
 _get_bitmap_surface (FT_Bitmap		     *bitmap,
+		     FT_Library		      library,
 		     cairo_bool_t	      own_buffer,
 		     cairo_font_options_t    *font_options,
 		     cairo_image_surface_t  **surface)
@@ -1222,6 +1223,54 @@ _get_bitmap_surface (FT_Bitmap		     *bitmap,
 #endif
     case FT_PIXEL_MODE_GRAY2:
     case FT_PIXEL_MODE_GRAY4:
+	if (!own_buffer && library)
+	{
+	    /* This is pretty much the only case that we can get in here. */
+	    /* Convert to 8bit grayscale. */
+
+	    FT_Bitmap  tmp;
+	    FT_Int     align;
+
+	    if ( bitmap->pixel_mode == FT_PIXEL_MODE_GRAY2 )
+	      align = ( bitmap->width + 3 ) / 4;
+	    else
+	      align = ( bitmap->width + 1 ) / 2;
+
+	    FT_Bitmap_New( &tmp );
+
+	    if (FT_Bitmap_Convert( library, bitmap, &tmp, align ))
+		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+	    FT_Bitmap_Done( library, bitmap );
+	    *bitmap = tmp;
+
+	    stride = bitmap->pitch;
+	    data = _cairo_malloc_ab (height, stride);
+	    if (!data)
+		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+	    if (bitmap->num_grays != 256)
+	    {
+	      unsigned int x, y;
+	      unsigned int shift;
+	      switch (bitmap->num_grays) {
+	      case 4:  shift = 6; break;
+	      case 16: shift = 4; break;
+              default: shift = 0; break;
+	      }
+	      FT_Byte *p = bitmap->buffer;
+	      for (y = 0; y < height; y++) {
+	        for (x = 0; x < width; x++)
+		  p[x] <<= shift;
+		p += bitmap->pitch;
+	      }
+	    }
+
+	    memcpy (data, bitmap->buffer, stride * height);
+
+	    format = CAIRO_FORMAT_A8;
+	    break;
+	}
 	/* These could be triggered by very rare types of TrueType fonts */
     default:
 	if (own_buffer)
@@ -1415,7 +1464,7 @@ _render_glyph_outline (FT_Face                    face,
 	/* Note:
 	 * _get_bitmap_surface will free bitmap.buffer if there is an error
 	 */
-	status = _get_bitmap_surface (&bitmap, TRUE, font_options, surface);
+	status = _get_bitmap_surface (&bitmap, NULL, TRUE, font_options, surface);
 	if (unlikely (status))
 	    return status;
 
@@ -1456,6 +1505,7 @@ _render_glyph_bitmap (FT_Face		      face,
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     status = _get_bitmap_surface (&glyphslot->bitmap,
+				  glyphslot->library,
 				  FALSE, font_options,
 				  surface);
     if (unlikely (status))


More information about the cairo-commit mailing list