[PATCH 3/3] dwrite: Implement grayscale rendering mode
Nikolay Sivov
nsivov at codeweavers.com
Thu Aug 27 00:39:45 CDT 2015
---
-------------- next part --------------
>From d38f365d7f0eaca1055ecab48beb184285438202 Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <nsivov at codeweavers.com>
Date: Thu, 27 Aug 2015 08:36:58 +0300
Subject: [PATCH 3/3] dwrite: Implement grayscale rendering mode
---
dlls/dwrite/dwrite_private.h | 3 +-
dlls/dwrite/font.c | 41 +++++++++----
dlls/dwrite/freetype.c | 136 +++++++++++++++++++++++++++++++------------
3 files changed, 129 insertions(+), 51 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index 39043d9..a7b8c46 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -199,6 +199,7 @@ struct dwrite_glyphbitmap {
INT pitch;
RECT bbox;
BYTE *buf;
+ DWRITE_TEXTURE_TYPE type;
};
extern BOOL init_freetype(void) DECLSPEC_HIDDEN;
@@ -212,7 +213,7 @@ extern UINT16 freetype_get_glyphindex(IDWriteFontFace2*,UINT32,INT) DECLSPEC_HID
extern BOOL freetype_has_kerning_pairs(IDWriteFontFace2*) DECLSPEC_HIDDEN;
extern INT32 freetype_get_kerning_pair_adjustment(IDWriteFontFace2*,UINT16,UINT16) DECLSPEC_HIDDEN;
extern void freetype_get_glyph_bbox(struct dwrite_glyphbitmap*) DECLSPEC_HIDDEN;
-extern void freetype_get_glyph_bitmap(struct dwrite_glyphbitmap*) DECLSPEC_HIDDEN;
+extern BOOL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap*) DECLSPEC_HIDDEN;
extern INT freetype_get_charmap_index(IDWriteFontFace2*,BOOL*) DECLSPEC_HIDDEN;
extern INT32 freetype_get_glyph_advance(IDWriteFontFace2*,FLOAT,UINT16,DWRITE_MEASURING_MODE) DECLSPEC_HIDDEN;
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index f66d49c..1b9b6a2 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -3622,6 +3622,7 @@ static void glyphrunanalysis_render(struct dwrite_glyphrunanalysis *analysis, DW
glyph_bitmap.emsize = analysis->run.fontEmSize * analysis->ppdip;
glyph_bitmap.nohint = analysis->rendering_mode == DWRITE_RENDERING_MODE_NATURAL ||
analysis->rendering_mode == DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC;
+ glyph_bitmap.type = type;
bbox = &glyph_bitmap.bbox;
for (i = 0; i < analysis->run.glyphCount; i++) {
@@ -3629,6 +3630,7 @@ static void glyphrunanalysis_render(struct dwrite_glyphrunanalysis *analysis, DW
FLOAT advance = analysis->advances[i];
int x, y, width, height;
BYTE *src, *dst;
+ BOOL is_1bpp;
glyph_bitmap.index = analysis->run.glyphIndices[i];
freetype_get_glyph_bbox(&glyph_bitmap);
@@ -3640,10 +3642,14 @@ static void glyphrunanalysis_render(struct dwrite_glyphrunanalysis *analysis, DW
width = bbox->right - bbox->left;
height = bbox->bottom - bbox->top;
- glyph_bitmap.pitch = ((width + 31) >> 5) << 2;
+
+ if (type == DWRITE_TEXTURE_CLEARTYPE_3x1)
+ glyph_bitmap.pitch = (width + 3) / 4 * 4;
+ else
+ glyph_bitmap.pitch = ((width + 31) >> 5) << 2;
glyph_bitmap.buf = src = heap_alloc_zero(height * glyph_bitmap.pitch);
- freetype_get_glyph_bitmap(&glyph_bitmap);
+ is_1bpp = freetype_get_glyph_bitmap(&glyph_bitmap);
if (is_rtl)
OffsetRect(bbox, origin_x - advance, 0);
@@ -3658,21 +3664,32 @@ static void glyphrunanalysis_render(struct dwrite_glyphrunanalysis *analysis, DW
/* blit to analysis bitmap */
dst = get_pixel_ptr(analysis->bitmap, type, bbox, &analysis->bounds);
- /* convert 1bpp to 8bpp/24bpp */
- if (type == DWRITE_TEXTURE_CLEARTYPE_3x1) {
- for (y = 0; y < height; y++) {
- for (x = 0; x < width; x++)
- dst[3*x] = dst[3*x+1] = dst[3*x+2] = (src[x / 8] & masks[x % 8]) ? DWRITE_ALPHA_MAX : 0;
- src += get_dib_stride(width, 1);
- dst += (analysis->bounds.right - analysis->bounds.left) * 3;
+ if (is_1bpp) {
+ /* convert 1bpp to 8bpp/24bpp */
+ if (type == DWRITE_TEXTURE_CLEARTYPE_3x1) {
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++)
+ dst[3*x] = dst[3*x+1] = dst[3*x+2] = (src[x / 8] & masks[x % 8]) ? DWRITE_ALPHA_MAX : 0;
+ src += glyph_bitmap.pitch;
+ dst += (analysis->bounds.right - analysis->bounds.left) * 3;
+ }
+ }
+ else {
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++)
+ dst[x] = (src[x / 8] & masks[x % 8]) ? DWRITE_ALPHA_MAX : 0;
+ src += get_dib_stride(width, 1);
+ dst += analysis->bounds.right - analysis->bounds.left;
+ }
}
}
else {
+ /* at this point it's DWRITE_TEXTURE_CLEARTYPE_3x1 with 8bpp src bitmap */
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++)
- dst[x] = (src[x / 8] & masks[x % 8]) ? DWRITE_ALPHA_MAX : 0;
- src += get_dib_stride(width, 1);
- dst += analysis->bounds.right - analysis->bounds.left;
+ dst[3*x] = dst[3*x+1] = dst[3*x+2] = src[x];
+ src += glyph_bitmap.pitch;
+ dst += (analysis->bounds.right - analysis->bounds.left) * 3;
}
}
diff --git a/dlls/dwrite/freetype.c b/dlls/dwrite/freetype.c
index 1f7e6a9..d10f370 100644
--- a/dlls/dwrite/freetype.c
+++ b/dlls/dwrite/freetype.c
@@ -510,10 +510,101 @@ void freetype_get_glyph_bbox(struct dwrite_glyphbitmap *bitmap)
bitmap->bbox.bottom = -bbox.yMin;
}
-void freetype_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap)
+static BOOL freetype_get_aliased_glyph_bitmap(struct dwrite_glyphbitmap *bitmap, FT_Glyph glyph)
{
const RECT *bbox = &bitmap->bbox;
+ int width = bbox->right - bbox->left;
+ int height = bbox->bottom - bbox->top;
+
+ if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
+ FT_OutlineGlyph outline = (FT_OutlineGlyph)glyph;
+ const FT_Outline *src = &outline->outline;
+ FT_Bitmap ft_bitmap;
+ FT_Outline copy;
+
+ ft_bitmap.width = width;
+ ft_bitmap.rows = height;
+ ft_bitmap.pitch = bitmap->pitch;
+ ft_bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
+ ft_bitmap.buffer = bitmap->buf;
+
+ /* Note: FreeType will only set 'black' bits for us. */
+ if (pFT_Outline_New(library, src->n_points, src->n_contours, ©) == 0) {
+ pFT_Outline_Copy(src, ©);
+ pFT_Outline_Translate(©, -bbox->left << 6, bbox->bottom << 6);
+ pFT_Outline_Get_Bitmap(library, ©, &ft_bitmap);
+ pFT_Outline_Done(library, ©);
+ }
+ }
+ else if (glyph->format == FT_GLYPH_FORMAT_BITMAP) {
+ FT_Bitmap *ft_bitmap = &((FT_BitmapGlyph)glyph)->bitmap;
+ BYTE *src = ft_bitmap->buffer, *dst = bitmap->buf;
+ int w = min(bitmap->pitch, (ft_bitmap->width + 7) >> 3);
+ int h = min(height, ft_bitmap->rows);
+
+ while (h--) {
+ memcpy(dst, src, w);
+ src += ft_bitmap->pitch;
+ dst += bitmap->pitch;
+ }
+ }
+ else
+ FIXME("format %x not handled\n", glyph->format);
+
+ return TRUE;
+}
+
+static BOOL freetype_get_aa_glyph_bitmap(struct dwrite_glyphbitmap *bitmap, FT_Glyph glyph)
+{
+ const RECT *bbox = &bitmap->bbox;
+ int width = bbox->right - bbox->left;
+ int height = bbox->bottom - bbox->top;
+ BOOL ret = FALSE;
+
+ if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
+ FT_OutlineGlyph outline = (FT_OutlineGlyph)glyph;
+ const FT_Outline *src = &outline->outline;
+ FT_Bitmap ft_bitmap;
+ FT_Outline copy;
+
+ ft_bitmap.width = width;
+ ft_bitmap.rows = height;
+ ft_bitmap.pitch = bitmap->pitch;
+ ft_bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
+ ft_bitmap.buffer = bitmap->buf;
+
+ /* Note: FreeType will only set 'black' bits for us. */
+ if (pFT_Outline_New(library, src->n_points, src->n_contours, ©) == 0) {
+ pFT_Outline_Copy(src, ©);
+ pFT_Outline_Translate(©, -bbox->left << 6, bbox->bottom << 6);
+ pFT_Outline_Get_Bitmap(library, ©, &ft_bitmap);
+ pFT_Outline_Done(library, ©);
+ }
+ }
+ else if (glyph->format == FT_GLYPH_FORMAT_BITMAP) {
+ FT_Bitmap *ft_bitmap = &((FT_BitmapGlyph)glyph)->bitmap;
+ BYTE *src = ft_bitmap->buffer, *dst = bitmap->buf;
+ int w = min(bitmap->pitch, (ft_bitmap->width + 7) >> 3);
+ int h = min(height, ft_bitmap->rows);
+
+ while (h--) {
+ memcpy(dst, src, w);
+ src += ft_bitmap->pitch;
+ dst += bitmap->pitch;
+ }
+
+ ret = TRUE;
+ }
+ else
+ FIXME("format %x not handled\n", glyph->format);
+
+ return ret;
+}
+
+BOOL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap)
+{
FTC_ImageTypeRec imagetype;
+ BOOL ret = FALSE;
FT_Glyph glyph;
imagetype.face_id = bitmap->fontface;
@@ -523,45 +614,14 @@ void freetype_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap)
EnterCriticalSection(&freetype_cs);
if (pFTC_ImageCache_Lookup(image_cache, &imagetype, bitmap->index, &glyph, NULL) == 0) {
- int width = bbox->right - bbox->left;
- int height = bbox->bottom - bbox->top;
-
- if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
- FT_OutlineGlyph outline = (FT_OutlineGlyph)glyph;
- const FT_Outline *src = &outline->outline;
- FT_Bitmap ft_bitmap;
- FT_Outline copy;
-
- ft_bitmap.width = width;
- ft_bitmap.rows = height;
- ft_bitmap.pitch = bitmap->pitch;
- ft_bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
- ft_bitmap.buffer = bitmap->buf;
-
- /* Note: FreeType will only set 'black' bits for us. */
- if (pFT_Outline_New(library, src->n_points, src->n_contours, ©) == 0) {
- pFT_Outline_Copy(src, ©);
- pFT_Outline_Translate(©, -bbox->left << 6, bbox->bottom << 6);
- pFT_Outline_Get_Bitmap(library, ©, &ft_bitmap);
- pFT_Outline_Done(library, ©);
- }
- }
- else if (glyph->format == FT_GLYPH_FORMAT_BITMAP) {
- FT_Bitmap *ft_bitmap = &((FT_BitmapGlyph)glyph)->bitmap;
- BYTE *src = ft_bitmap->buffer, *dst = bitmap->buf;
- int w = min(bitmap->pitch, (ft_bitmap->width + 7) >> 3);
- int h = min(height, ft_bitmap->rows);
-
- while (h--) {
- memcpy(dst, src, w);
- src += ft_bitmap->pitch;
- dst += bitmap->pitch;
- }
- }
+ if (bitmap->type == DWRITE_TEXTURE_CLEARTYPE_3x1)
+ ret = freetype_get_aa_glyph_bitmap(bitmap, glyph);
else
- FIXME("format %x not handled\n", glyph->format);
+ ret = freetype_get_aliased_glyph_bitmap(bitmap, glyph);
}
LeaveCriticalSection(&freetype_cs);
+
+ return ret;
}
INT freetype_get_charmap_index(IDWriteFontFace2 *fontface, BOOL *is_symbol)
@@ -675,7 +735,7 @@ void freetype_get_glyph_bbox(struct dwrite_glyphbitmap *bitmap)
memset(&bitmap->bbox, 0, sizeof(bitmap->bbox));
}
-void freetype_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap)
+BOOL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap)
{
}
--
2.1.4
More information about the wine-patches
mailing list