summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBehdad Esfahbod <behdad@behdad.org>2013-07-29 19:09:29 -0400
committerBehdad Esfahbod <behdad@behdad.org>2013-07-29 19:10:46 -0400
commit9444ef09ccde2735258cc1bd2f1912119a32dd88 (patch)
tree3fdf0994303f6fe68ff7b8134f2caf374b6f6bd2
parent274863be08f6c8df6d411df9db725d34f7fbabea (diff)
Support 2bit and 4bit embedded bitmaps
-rw-r--r--src/cairo-ft-font.c52
1 files changed, 51 insertions, 1 deletions
diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index 28e361c24..feef95bbd 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))