diff --git a/patches/dwrite-8bpp_Grayscale_Mode/0001-dwrite-Handle-8bpp-gray-bitmaps-for-bitmap-target.patch b/patches/dwrite-8bpp_Grayscale_Mode/0001-dwrite-Handle-8bpp-gray-bitmaps-for-bitmap-target.patch new file mode 100644 index 00000000..0fc9ea65 --- /dev/null +++ b/patches/dwrite-8bpp_Grayscale_Mode/0001-dwrite-Handle-8bpp-gray-bitmaps-for-bitmap-target.patch @@ -0,0 +1,77 @@ +From 8156e6f36bc04da891cd2541d8ad6a65a89738ce Mon Sep 17 00:00:00 2001 +From: Nikolay Sivov +Date: Tue, 5 Sep 2017 13:35:27 +0300 +Subject: dwrite: Handle 8bpp gray bitmaps for bitmap target. + +Signed-off-by: Nikolay Sivov +Signed-off-by: Alexandre Julliard +--- + dlls/dwrite/gdiinterop.c | 38 ++++++++++++++++++++++++-------------- + 1 file changed, 24 insertions(+), 14 deletions(-) + +diff --git a/dlls/dwrite/gdiinterop.c b/dlls/dwrite/gdiinterop.c +index 5425b5c4aec..2e1811bd66d 100644 +--- a/dlls/dwrite/gdiinterop.c ++++ b/dlls/dwrite/gdiinterop.c +@@ -256,6 +256,25 @@ static inline DWORD *get_pixel_ptr_32(struct dib_data *dib, int x, int y) + return (DWORD *)((BYTE*)dib->ptr + y * dib->stride + x * 4); + } + ++static inline BYTE blend_color(BYTE dst, BYTE src, BYTE alpha) ++{ ++ return (src * alpha + dst * (255 - alpha) + 127) / 255; ++} ++ ++static inline DWORD blend_subpixel(BYTE r, BYTE g, BYTE b, DWORD text, const BYTE *alpha) ++{ ++ return blend_color(r, text >> 16, alpha[0]) << 16 | ++ blend_color(g, text >> 8, alpha[1]) << 8 | ++ blend_color(b, text, alpha[2]); ++} ++ ++static inline DWORD blend_pixel(BYTE r, BYTE g, BYTE b, DWORD text, BYTE alpha) ++{ ++ return blend_color(r, text >> 16, alpha) << 16 | ++ blend_color(g, text >> 8, alpha) << 8 | ++ blend_color(b, text, alpha); ++} ++ + static void blit_8(struct dib_data *dib, const BYTE *src, const RECT *rect, DWORD text_pixel) + { + DWORD *dst_ptr = get_pixel_ptr_32(dib, rect->left, rect->top); +@@ -263,8 +282,11 @@ static void blit_8(struct dib_data *dib, const BYTE *src, const RECT *rect, DWOR + + for (y = rect->top; y < rect->bottom; y++) { + for (x = 0; x < src_width; x++) { +- if (src[x] < DWRITE_ALPHA_MAX) continue; +- dst_ptr[x] = text_pixel; ++ if (src[x]) continue; ++ if (src[x] == DWRITE_ALPHA_MAX) ++ dst_ptr[x] = text_pixel; ++ else ++ dst_ptr[x] = blend_pixel(dst_ptr[x] >> 16, dst_ptr[x] >> 8, dst_ptr[x], text_pixel, src[x]); + } + + src += src_width; +@@ -272,18 +294,6 @@ static void blit_8(struct dib_data *dib, const BYTE *src, const RECT *rect, DWOR + } + } + +-static inline BYTE blend_color(BYTE dst, BYTE src, BYTE alpha) +-{ +- return (src * alpha + dst * (255 - alpha) + 127) / 255; +-} +- +-static inline DWORD blend_subpixel(BYTE r, BYTE g, BYTE b, DWORD text, const BYTE *alpha) +-{ +- return blend_color(r, text >> 16, alpha[0]) << 16 | +- blend_color(g, text >> 8, alpha[1]) << 8 | +- blend_color(b, text, alpha[2]); +-} +- + static void blit_subpixel_888(struct dib_data *dib, int dib_width, const BYTE *src, + const RECT *rect, DWORD text_pixel) + { +-- +2.14.1 + diff --git a/patches/dwrite-8bpp_Grayscale_Mode/0002-dwrite-Validate-buffer-size-passed-to-CreateAlphaTex.patch b/patches/dwrite-8bpp_Grayscale_Mode/0002-dwrite-Validate-buffer-size-passed-to-CreateAlphaTex.patch new file mode 100644 index 00000000..d89f9543 --- /dev/null +++ b/patches/dwrite-8bpp_Grayscale_Mode/0002-dwrite-Validate-buffer-size-passed-to-CreateAlphaTex.patch @@ -0,0 +1,28 @@ +From f4a73bdd781cfbfb371f07c0b37cde10a5ad0c17 Mon Sep 17 00:00:00 2001 +From: Nikolay Sivov +Date: Tue, 5 Sep 2017 13:35:28 +0300 +Subject: dwrite: Validate buffer size passed to CreateAlphaTexture() against + analysis texture type. + +Signed-off-by: Nikolay Sivov +Signed-off-by: Alexandre Julliard +--- + dlls/dwrite/font.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c +index 0b4717331cf..c15c941cc14 100644 +--- a/dlls/dwrite/font.c ++++ b/dlls/dwrite/font.c +@@ -5092,7 +5092,7 @@ static HRESULT WINAPI glyphrunanalysis_CreateAlphaTexture(IDWriteGlyphRunAnalysi + + /* make sure buffer is large enough for requested texture type */ + required = (bounds->right - bounds->left) * (bounds->bottom - bounds->top); +- if (type == DWRITE_TEXTURE_CLEARTYPE_3x1) ++ if (This->texture_type == DWRITE_TEXTURE_CLEARTYPE_3x1) + required *= 3; + + if (size < required) +-- +2.14.1 + diff --git a/patches/dwrite-8bpp_Grayscale_Mode/0003-dwrite-Use-8bpp-bitmaps-in-grayscale-mode.patch b/patches/dwrite-8bpp_Grayscale_Mode/0003-dwrite-Use-8bpp-bitmaps-in-grayscale-mode.patch new file mode 100644 index 00000000..9bd8fd56 --- /dev/null +++ b/patches/dwrite-8bpp_Grayscale_Mode/0003-dwrite-Use-8bpp-bitmaps-in-grayscale-mode.patch @@ -0,0 +1,312 @@ +From ed60832c952c8dbcae96d24a28f23d57df76daed Mon Sep 17 00:00:00 2001 +From: Nikolay Sivov +Date: Tue, 5 Sep 2017 13:35:29 +0300 +Subject: dwrite: Use 8bpp bitmaps in grayscale mode. + +Problem analyzed by Kimmo Myllyvirta. + +Signed-off-by: Nikolay Sivov +Signed-off-by: Alexandre Julliard +--- + dlls/dwrite/dwrite_private.h | 2 +- + dlls/dwrite/font.c | 37 +++++++----- + dlls/dwrite/freetype.c | 6 +- + dlls/dwrite/tests/font.c | 134 ++++++++++++++++++++++++++++++++++++++----- + 4 files changed, 148 insertions(+), 31 deletions(-) + +diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h +index 288da2cb43b..d12118c2580 100644 +--- a/dlls/dwrite/dwrite_private.h ++++ b/dlls/dwrite/dwrite_private.h +@@ -273,11 +273,11 @@ struct dwrite_glyphbitmap { + DWORD simulations; + FLOAT emsize; + BOOL nohint; ++ BOOL aliased; + UINT16 index; + INT pitch; + RECT bbox; + BYTE *buf; +- DWRITE_TEXTURE_TYPE type; + DWRITE_MATRIX *m; + }; + +diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c +index c15c941cc14..5ca4c8a5f96 100644 +--- a/dlls/dwrite/font.c ++++ b/dlls/dwrite/font.c +@@ -4872,10 +4872,9 @@ static BOOL is_natural_rendering_mode(DWRITE_RENDERING_MODE1 mode) + } + } + +-static UINT32 get_glyph_bitmap_pitch(DWRITE_TEXTURE_TYPE type, INT width) ++static UINT32 get_glyph_bitmap_pitch(DWRITE_RENDERING_MODE1 rendering_mode, INT width) + { +- return type == DWRITE_TEXTURE_CLEARTYPE_3x1 ? (width + 3) / 4 * 4 : +- ((width + 31) >> 5) << 2; ++ return rendering_mode == DWRITE_RENDERING_MODE1_ALIASED ? ((width + 31) >> 5) << 2 : (width + 3) / 4 * 4; + } + + static void glyphrunanalysis_get_texturebounds(struct dwrite_glyphrunanalysis *analysis, RECT *bounds) +@@ -4912,7 +4911,7 @@ static void glyphrunanalysis_get_texturebounds(struct dwrite_glyphrunanalysis *a + glyph_bitmap.index = analysis->run.glyphIndices[i]; + freetype_get_glyph_bbox(&glyph_bitmap); + +- bitmap_size = get_glyph_bitmap_pitch(analysis->texture_type, bbox->right - bbox->left) * ++ bitmap_size = get_glyph_bitmap_pitch(analysis->rendering_mode, bbox->right - bbox->left) * + (bbox->bottom - bbox->top); + if (bitmap_size > analysis->max_glyph_bitmap_size) + analysis->max_glyph_bitmap_size = bitmap_size; +@@ -4995,7 +4994,7 @@ static HRESULT glyphrunanalysis_render(struct dwrite_glyphrunanalysis *analysis) + glyph_bitmap.simulations = IDWriteFontFace4_GetSimulations(fontface); + glyph_bitmap.emsize = analysis->run.fontEmSize; + glyph_bitmap.nohint = is_natural_rendering_mode(analysis->rendering_mode); +- glyph_bitmap.type = analysis->texture_type; ++ glyph_bitmap.aliased = analysis->rendering_mode == DWRITE_RENDERING_MODE1_ALIASED; + if (analysis->flags & RUNANALYSIS_USE_TRANSFORM) + glyph_bitmap.m = &analysis->m; + if (!(glyph_bitmap.buf = heap_alloc(analysis->max_glyph_bitmap_size))) { +@@ -5019,7 +5018,7 @@ static HRESULT glyphrunanalysis_render(struct dwrite_glyphrunanalysis *analysis) + width = bbox->right - bbox->left; + height = bbox->bottom - bbox->top; + +- glyph_bitmap.pitch = get_glyph_bitmap_pitch(analysis->texture_type, width); ++ glyph_bitmap.pitch = get_glyph_bitmap_pitch(analysis->rendering_mode, width); + memset(src, 0, height * glyph_bitmap.pitch); + is_1bpp = freetype_get_glyph_bitmap(&glyph_bitmap); + +@@ -5044,18 +5043,27 @@ static HRESULT glyphrunanalysis_render(struct dwrite_glyphrunanalysis *analysis) + for (x = 0; x < width; x++) + if (src[x / 8] & masks[x % 8]) + dst[x] = DWRITE_ALPHA_MAX; +- src += get_dib_stride(width, 1); ++ src += glyph_bitmap.pitch; + 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[3*x] = dst[3*x+1] = dst[3*x+2] = src[x] | dst[3*x]; +- src += glyph_bitmap.pitch; +- dst += (analysis->bounds.right - analysis->bounds.left) * 3; ++ if (analysis->texture_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] | dst[3*x]; ++ 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]; ++ src += glyph_bitmap.pitch; ++ dst += analysis->bounds.right - analysis->bounds.left; ++ } + } + } + } +@@ -5223,7 +5231,8 @@ HRESULT create_glyphrunanalysis(const struct glyphrunanalysis_desc *desc, IDWrit + analysis->ref = 1; + analysis->rendering_mode = desc->rendering_mode; + +- if (desc->rendering_mode == DWRITE_RENDERING_MODE1_ALIASED) ++ if (desc->rendering_mode == DWRITE_RENDERING_MODE1_ALIASED ++ || desc->aa_mode == DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE) + analysis->texture_type = DWRITE_TEXTURE_ALIASED_1x1; + else + analysis->texture_type = DWRITE_TEXTURE_CLEARTYPE_3x1; +diff --git a/dlls/dwrite/freetype.c b/dlls/dwrite/freetype.c +index 571fa24c336..ffdd8a8f1e8 100644 +--- a/dlls/dwrite/freetype.c ++++ b/dlls/dwrite/freetype.c +@@ -860,10 +860,10 @@ BOOL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap) + else + glyph_copy = NULL; + +- if (bitmap->type == DWRITE_TEXTURE_CLEARTYPE_3x1) +- ret = freetype_get_aa_glyph_bitmap(bitmap, glyph); +- else ++ if (bitmap->aliased) + ret = freetype_get_aliased_glyph_bitmap(bitmap, glyph); ++ else ++ ret = freetype_get_aa_glyph_bitmap(bitmap, glyph); + + if (glyph_copy) + pFT_Done_Glyph(glyph_copy); +diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c +index 54dcc75c81f..813ce22abf3 100644 +--- a/dlls/dwrite/tests/font.c ++++ b/dlls/dwrite/tests/font.c +@@ -4732,6 +4732,7 @@ static void test_CreateGlyphRunAnalysis(void) + + IDWriteGlyphRunAnalysis *analysis, *analysis2; + IDWriteRenderingParams *params; ++ IDWriteFactory3 *factory3; + IDWriteFactory2 *factory2; + IDWriteFactory *factory; + DWRITE_GLYPH_RUN run; +@@ -4745,6 +4746,8 @@ static void test_CreateGlyphRunAnalysis(void) + DWRITE_GLYPH_METRICS metrics; + DWRITE_FONT_METRICS fm; + DWRITE_MATRIX m; ++ ULONG size; ++ BYTE *bits; + ULONG ref; + int i; + +@@ -5057,29 +5060,134 @@ static void test_CreateGlyphRunAnalysis(void) + 0.0f, 0.0f, &analysis); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + +- /* Natural mode, grayscale antialiased. */ ++ /* Win8 does not accept default grid fitting mode. */ + hr = IDWriteFactory2_CreateGlyphRunAnalysis(factory2, &run, NULL, DWRITE_RENDERING_MODE_NATURAL, + DWRITE_MEASURING_MODE_NATURAL, DWRITE_GRID_FIT_MODE_DEFAULT, DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE, + 0.0f, 0.0f, &analysis); +- ok(hr == S_OK || broken(hr == E_INVALIDARG) /* Win8 */, "Failed to create glyph run analysis, hr %#x.\n", hr); ++ ok(hr == S_OK || broken(hr == E_INVALIDARG) /* Win8 */, "Failed to create analysis, hr %#x.\n", hr); ++ if (hr == S_OK) ++ IDWriteGlyphRunAnalysis_Release(analysis); + +- if (hr == S_OK) { +- hr = IDWriteFactory_CreateCustomRenderingParams(factory, 0.1f, 0.0f, 1.0f, DWRITE_PIXEL_GEOMETRY_FLAT, +- DWRITE_RENDERING_MODE_NATURAL, ¶ms); +- ok(hr == S_OK, "Failed to create custom parameters, hr %#x.\n", hr); ++ /* Natural mode, grayscale antialiased. */ ++ hr = IDWriteFactory2_CreateGlyphRunAnalysis(factory2, &run, NULL, DWRITE_RENDERING_MODE_NATURAL, ++ DWRITE_MEASURING_MODE_NATURAL, DWRITE_GRID_FIT_MODE_DISABLED, DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE, ++ 0.0f, 0.0f, &analysis); ++ ok(hr == S_OK, "Failed to create analysis, hr %#x.\n", hr); + +- hr = IDWriteGlyphRunAnalysis_GetAlphaBlendParams(analysis, params, &gamma, &contrast, &cleartype_level); +- ok(hr == S_OK, "Failed to get alpha blend params, hr %#x.\n", hr); +- todo_wine +- ok(cleartype_level == 0.0f, "Unexpected cleartype level %f.\n", cleartype_level); ++ SetRect(&rect, 0, 1, 0, 1); ++ hr = IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis, DWRITE_TEXTURE_CLEARTYPE_3x1, &rect); ++ ok(hr == S_OK, "Failed to get texture bounds, hr %#x.\n", hr); ++ ok(IsRectEmpty(&rect), "Expected empty bbox.\n"); + +- IDWriteRenderingParams_Release(params); +- IDWriteGlyphRunAnalysis_Release(analysis); +- } ++ SetRectEmpty(&rect); ++ hr = IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis, DWRITE_TEXTURE_ALIASED_1x1, &rect); ++ ok(hr == S_OK, "Failed to get texture bounds, hr %#x.\n", hr); ++ ok(!IsRectEmpty(&rect), "Unexpected empty bbox.\n"); ++ ++ size = (rect.right - rect.left) * (rect.bottom - rect.top); ++ bits = HeapAlloc(GetProcessHeap(), 0, size); ++ ++ hr = IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis, DWRITE_TEXTURE_ALIASED_1x1, &rect, bits, size); ++ ok(hr == S_OK, "Failed to get alpha texture, hr %#x.\n", hr); ++ ++ hr = IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis, DWRITE_TEXTURE_ALIASED_1x1, &rect, bits, size - 1); ++ ok(hr == E_NOT_SUFFICIENT_BUFFER, "Unexpected hr %#x.\n", hr); ++ ++ hr = IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis, DWRITE_TEXTURE_CLEARTYPE_3x1, &rect, bits, size); ++ ok(hr == DWRITE_E_UNSUPPORTEDOPERATION, "Unexpected hr %#x.\n", hr); ++ ++ hr = IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis, DWRITE_TEXTURE_CLEARTYPE_3x1, &rect, bits, size - 1); ++ todo_wine ++ ok(hr == DWRITE_E_UNSUPPORTEDOPERATION, "Unexpected hr %#x.\n", hr); ++ ++ HeapFree(GetProcessHeap(), 0, bits); ++ ++ hr = IDWriteFactory_CreateCustomRenderingParams(factory, 0.1f, 0.0f, 1.0f, DWRITE_PIXEL_GEOMETRY_FLAT, ++ DWRITE_RENDERING_MODE_NATURAL, ¶ms); ++ ok(hr == S_OK, "Failed to create custom parameters, hr %#x.\n", hr); ++ ++ hr = IDWriteGlyphRunAnalysis_GetAlphaBlendParams(analysis, params, &gamma, &contrast, &cleartype_level); ++ ok(hr == S_OK, "Failed to get alpha blend params, hr %#x.\n", hr); ++ todo_wine ++ ok(cleartype_level == 0.0f, "Unexpected cleartype level %f.\n", cleartype_level); ++ ++ IDWriteRenderingParams_Release(params); ++ IDWriteGlyphRunAnalysis_Release(analysis); + + IDWriteFactory2_Release(factory2); + } + ++ if (IDWriteFactory_QueryInterface(factory, &IID_IDWriteFactory3, (void **)&factory3) == S_OK) { ++ ++ /* Invalid antialias mode. */ ++ hr = IDWriteFactory3_CreateGlyphRunAnalysis(factory3, &run, NULL, DWRITE_RENDERING_MODE1_ALIASED, ++ DWRITE_MEASURING_MODE_NATURAL, DWRITE_GRID_FIT_MODE_DEFAULT, DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE + 1, ++ 0.0f, 0.0f, &analysis); ++ ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); ++ ++ /* Invalid grid fit mode. */ ++ hr = IDWriteFactory3_CreateGlyphRunAnalysis(factory3, &run, NULL, DWRITE_RENDERING_MODE1_ALIASED, ++ DWRITE_MEASURING_MODE_NATURAL, DWRITE_GRID_FIT_MODE_ENABLED + 1, DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE, ++ 0.0f, 0.0f, &analysis); ++ ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); ++ ++ /* Invalid rendering mode. */ ++ hr = IDWriteFactory3_CreateGlyphRunAnalysis(factory3, &run, NULL, DWRITE_RENDERING_MODE1_OUTLINE, ++ DWRITE_MEASURING_MODE_NATURAL, DWRITE_GRID_FIT_MODE_ENABLED, DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE, ++ 0.0f, 0.0f, &analysis); ++ ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); ++ ++ /* Invalid measuring mode. */ ++ hr = IDWriteFactory3_CreateGlyphRunAnalysis(factory3, &run, NULL, DWRITE_RENDERING_MODE1_ALIASED, ++ DWRITE_MEASURING_MODE_GDI_NATURAL + 1, DWRITE_GRID_FIT_MODE_ENABLED, ++ DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE, 0.0f, 0.0f, &analysis); ++ ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); ++ ++ hr = IDWriteFactory3_CreateGlyphRunAnalysis(factory3, &run, NULL, DWRITE_RENDERING_MODE1_NATURAL, ++ DWRITE_MEASURING_MODE_NATURAL, DWRITE_GRID_FIT_MODE_DEFAULT, DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE, ++ 0.0f, 0.0f, &analysis); ++ ok(hr == S_OK, "Failed to create analysis, hr %#x.\n", hr); ++ IDWriteGlyphRunAnalysis_Release(analysis); ++ ++ /* Natural mode, grayscale antialiased. */ ++ hr = IDWriteFactory3_CreateGlyphRunAnalysis(factory3, &run, NULL, DWRITE_RENDERING_MODE1_NATURAL, ++ DWRITE_MEASURING_MODE_NATURAL, DWRITE_GRID_FIT_MODE_DISABLED, DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE, ++ 0.0f, 0.0f, &analysis); ++ ok(hr == S_OK, "Failed to create analysis, hr %#x.\n", hr); ++ ++ SetRect(&rect, 0, 1, 0, 1); ++ hr = IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis, DWRITE_TEXTURE_CLEARTYPE_3x1, &rect); ++ ok(hr == S_OK, "Failed to get texture bounds, hr %#x.\n", hr); ++ ok(IsRectEmpty(&rect), "Expected empty bbox.\n"); ++ ++ SetRectEmpty(&rect); ++ hr = IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis, DWRITE_TEXTURE_ALIASED_1x1, &rect); ++ ok(hr == S_OK, "Failed to get texture bounds, hr %#x.\n", hr); ++ ok(!IsRectEmpty(&rect), "Unexpected empty bbox.\n"); ++ ++ size = (rect.right - rect.left) * (rect.bottom - rect.top); ++ bits = HeapAlloc(GetProcessHeap(), 0, size); ++ ++ hr = IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis, DWRITE_TEXTURE_ALIASED_1x1, &rect, bits, size); ++ ok(hr == S_OK, "Failed to get alpha texture, hr %#x.\n", hr); ++ ++ hr = IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis, DWRITE_TEXTURE_ALIASED_1x1, &rect, bits, size - 1); ++ ok(hr == E_NOT_SUFFICIENT_BUFFER, "Unexpected hr %#x.\n", hr); ++ ++ hr = IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis, DWRITE_TEXTURE_CLEARTYPE_3x1, &rect, bits, size); ++ ok(hr == DWRITE_E_UNSUPPORTEDOPERATION, "Unexpected hr %#x.\n", hr); ++ ++ hr = IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis, DWRITE_TEXTURE_CLEARTYPE_3x1, &rect, bits, size - 1); ++ todo_wine ++ ok(hr == DWRITE_E_UNSUPPORTEDOPERATION, "Unexpected hr %#x.\n", hr); ++ ++ HeapFree(GetProcessHeap(), 0, bits); ++ ++ IDWriteGlyphRunAnalysis_Release(analysis); ++ ++ IDWriteFactory3_Release(factory3); ++ } ++ + IDWriteFontFace_Release(face); + ref = IDWriteFactory_Release(factory); + ok(ref == 0, "factory not released, %u\n", ref); +-- +2.14.1 + diff --git a/patches/dwrite-8bpp_Grayscale_Mode/0004-d2d1-Use-8bpp-text-bitmaps-for-grayscale-mode.patch b/patches/dwrite-8bpp_Grayscale_Mode/0004-d2d1-Use-8bpp-text-bitmaps-for-grayscale-mode.patch new file mode 100644 index 00000000..127803da --- /dev/null +++ b/patches/dwrite-8bpp_Grayscale_Mode/0004-d2d1-Use-8bpp-text-bitmaps-for-grayscale-mode.patch @@ -0,0 +1,28 @@ +From 733892bb06a198dcdc045afc5db7cfb6e1ce4d79 Mon Sep 17 00:00:00 2001 +From: Nikolay Sivov +Date: Tue, 5 Sep 2017 13:35:30 +0300 +Subject: d2d1: Use 8bpp text bitmaps for grayscale mode. + +Signed-off-by: Nikolay Sivov +Signed-off-by: Henri Verbeet +Signed-off-by: Alexandre Julliard +--- + dlls/d2d1/render_target.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dlls/d2d1/render_target.c b/dlls/d2d1/render_target.c +index f37565d4ee7..02f926fc42b 100644 +--- a/dlls/d2d1/render_target.c ++++ b/dlls/d2d1/render_target.c +@@ -1141,7 +1141,7 @@ static void d2d_rt_draw_glyph_run_bitmap(struct d2d_d3d_render_target *render_ta + return; + } + +- if (rendering_mode == DWRITE_RENDERING_MODE_ALIASED) ++ if (rendering_mode == DWRITE_RENDERING_MODE_ALIASED || antialias_mode == DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE) + texture_type = DWRITE_TEXTURE_ALIASED_1x1; + else + texture_type = DWRITE_TEXTURE_CLEARTYPE_3x1; +-- +2.14.1 + diff --git a/patches/dwrite-8bpp_Grayscale_Mode/definition b/patches/dwrite-8bpp_Grayscale_Mode/definition new file mode 100644 index 00000000..7b949f98 --- /dev/null +++ b/patches/dwrite-8bpp_Grayscale_Mode/definition @@ -0,0 +1 @@ +Fixes: [43319] Use 8bpp bitmaps in grayscale mode diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index e046da32..06e2760e 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -158,6 +158,7 @@ patch_enable_all () enable_dsound_Fast_Mixer="$1" enable_dsound_Revert_Cleanup="$1" enable_dwmapi_DwmSetIcon="$1" + enable_dwrite_8bpp_Grayscale_Mode="$1" enable_dxdiag_dontskip="$1" enable_dxdiagn_Display_Information="$1" enable_dxdiagn_Enumerate_DirectSound="$1" @@ -751,6 +752,9 @@ patch_enable () dwmapi-DwmSetIcon) enable_dwmapi_DwmSetIcon="$2" ;; + dwrite-8bpp_Grayscale_Mode) + enable_dwrite_8bpp_Grayscale_Mode="$2" + ;; dxdiag-dontskip) enable_dxdiag_dontskip="$2" ;; @@ -4688,6 +4692,28 @@ if test "$enable_dwmapi_DwmSetIcon" -eq 1; then ) >> "$patchlist" fi +# Patchset dwrite-8bpp_Grayscale_Mode +# | +# | This patchset fixes the following Wine bugs: +# | * [#43319] Use 8bpp bitmaps in grayscale mode +# | +# | Modified files: +# | * dlls/d2d1/render_target.c, dlls/dwrite/dwrite_private.h, dlls/dwrite/font.c, dlls/dwrite/freetype.c, +# | dlls/dwrite/gdiinterop.c, dlls/dwrite/tests/font.c +# | +if test "$enable_dwrite_8bpp_Grayscale_Mode" -eq 1; then + patch_apply dwrite-8bpp_Grayscale_Mode/0001-dwrite-Handle-8bpp-gray-bitmaps-for-bitmap-target.patch + patch_apply dwrite-8bpp_Grayscale_Mode/0002-dwrite-Validate-buffer-size-passed-to-CreateAlphaTex.patch + patch_apply dwrite-8bpp_Grayscale_Mode/0003-dwrite-Use-8bpp-bitmaps-in-grayscale-mode.patch + patch_apply dwrite-8bpp_Grayscale_Mode/0004-d2d1-Use-8bpp-text-bitmaps-for-grayscale-mode.patch + ( + printf '%s\n' '+ { "Nikolay Sivov", "dwrite: Handle 8bpp gray bitmaps for bitmap target.", 1 },'; + printf '%s\n' '+ { "Nikolay Sivov", "dwrite: Validate buffer size passed to CreateAlphaTexture() against analysis texture type.", 1 },'; + printf '%s\n' '+ { "Nikolay Sivov", "dwrite: Use 8bpp bitmaps in grayscale mode.", 1 },'; + printf '%s\n' '+ { "Nikolay Sivov", "d2d1: Use 8bpp text bitmaps for grayscale mode.", 1 },'; + ) >> "$patchlist" +fi + # Patchset dxdiag-dontskip # | # | Modified files: