dwrite: Partially implement newer TranslateColorGlyphRun() variant.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2022-01-21 15:57:16 +03:00 committed by Alexandre Julliard
parent d967200938
commit cb0b746f9a
4 changed files with 140 additions and 33 deletions

View File

@ -315,8 +315,9 @@ extern HRESULT get_local_refkey(const WCHAR*,const FILETIME*,void**,UINT32*) DEC
extern HRESULT get_filestream_from_file(IDWriteFontFile*,IDWriteFontFileStream**) DECLSPEC_HIDDEN;
extern BOOL is_face_type_supported(DWRITE_FONT_FACE_TYPE) DECLSPEC_HIDDEN;
extern HRESULT get_family_names_from_stream(IDWriteFontFileStream*,UINT32,DWRITE_FONT_FACE_TYPE,IDWriteLocalizedStrings**) DECLSPEC_HIDDEN;
extern HRESULT create_colorglyphenum(FLOAT,FLOAT,const DWRITE_GLYPH_RUN*,const DWRITE_GLYPH_RUN_DESCRIPTION*,DWRITE_MEASURING_MODE,
const DWRITE_MATRIX*,UINT32,IDWriteColorGlyphRunEnumerator**) DECLSPEC_HIDDEN;
extern HRESULT create_colorglyphenum(D2D1_POINT_2F origin, const DWRITE_GLYPH_RUN *run, const DWRITE_GLYPH_RUN_DESCRIPTION *desc,
DWRITE_GLYPH_IMAGE_FORMATS formats, DWRITE_MEASURING_MODE mode, const DWRITE_MATRIX *transform, UINT32 palette,
IDWriteColorGlyphRunEnumerator1 **enumerator) DECLSPEC_HIDDEN;
extern BOOL lb_is_newline_char(WCHAR) DECLSPEC_HIDDEN;
extern HRESULT create_system_fontfallback(IDWriteFactory7 *factory, IDWriteFontFallback1 **fallback) DECLSPEC_HIDDEN;
extern void release_system_fontfallback(IDWriteFontFallback1 *fallback) DECLSPEC_HIDDEN;

View File

@ -397,8 +397,7 @@ struct dwrite_colorglyphenum
IDWriteColorGlyphRunEnumerator1 IDWriteColorGlyphRunEnumerator1_iface;
LONG refcount;
FLOAT origin_x; /* original run origin */
FLOAT origin_y;
D2D1_POINT_2F origin; /* original run origin */
IDWriteFontFace5 *fontface; /* for convenience */
DWRITE_COLOR_GLYPH_RUN1 colorrun; /* returned with GetCurrentRun() */
@ -6431,8 +6430,8 @@ static BOOL colorglyphenum_build_color_run(struct dwrite_colorglyphenum *glyphen
glyphenum->color_offsets[g] = glyphenum->offsets[g];
}
colorrun->baselineOriginX = glyphenum->origin_x + get_glyph_origin(glyphenum, first_glyph);
colorrun->baselineOriginY = glyphenum->origin_y;
colorrun->baselineOriginX = glyphenum->origin.x + get_glyph_origin(glyphenum, first_glyph);
colorrun->baselineOriginY = glyphenum->origin.y;
colorrun->glyphRun.glyphCount = glyphenum->run.glyphCount;
colorrun->paletteIndex = 0xffff;
memset(&colorrun->runColor, 0, sizeof(colorrun->runColor));
@ -6470,8 +6469,8 @@ static BOOL colorglyphenum_build_color_run(struct dwrite_colorglyphenum *glyphen
glyphenum->palette, colorrun->paletteIndex, hr);
}
/* found a glyph position new color run starts from, origin is "original origin + distance to this glyph" */
colorrun->baselineOriginX = glyphenum->origin_x + get_glyph_origin(glyphenum, g);
colorrun->baselineOriginY = glyphenum->origin_y;
colorrun->baselineOriginX = glyphenum->origin.x + get_glyph_origin(glyphenum, g);
colorrun->baselineOriginY = glyphenum->origin.y;
glyphenum->color_advances[index] = glyphenum->advances[g];
got_palette_index = TRUE;
}
@ -6562,9 +6561,9 @@ static const IDWriteColorGlyphRunEnumerator1Vtbl colorglyphenumvtbl =
colorglyphenum1_GetCurrentRun,
};
HRESULT create_colorglyphenum(float originX, float originY, const DWRITE_GLYPH_RUN *run,
const DWRITE_GLYPH_RUN_DESCRIPTION *rundescr, DWRITE_MEASURING_MODE measuring_mode,
const DWRITE_MATRIX *transform, unsigned int palette, IDWriteColorGlyphRunEnumerator **ret)
HRESULT create_colorglyphenum(D2D1_POINT_2F origin, const DWRITE_GLYPH_RUN *run,
const DWRITE_GLYPH_RUN_DESCRIPTION *rundescr, DWRITE_GLYPH_IMAGE_FORMATS formats, DWRITE_MEASURING_MODE measuring_mode,
const DWRITE_MATRIX *transform, unsigned int palette, IDWriteColorGlyphRunEnumerator1 **ret)
{
struct dwrite_colorglyphenum *colorglyphenum;
BOOL colorfont, has_colored_glyph;
@ -6580,13 +6579,28 @@ HRESULT create_colorglyphenum(float originX, float originY, const DWRITE_GLYPH_R
if (!colorfont)
return DWRITE_E_NOCOLOR;
if (!(formats & (DWRITE_GLYPH_IMAGE_FORMATS_COLR |
DWRITE_GLYPH_IMAGE_FORMATS_SVG |
DWRITE_GLYPH_IMAGE_FORMATS_PNG |
DWRITE_GLYPH_IMAGE_FORMATS_JPEG |
DWRITE_GLYPH_IMAGE_FORMATS_TIFF |
DWRITE_GLYPH_IMAGE_FORMATS_PREMULTIPLIED_B8G8R8A8)))
{
return DWRITE_E_NOCOLOR;
}
if (formats & ~(DWRITE_GLYPH_IMAGE_FORMATS_TRUETYPE | DWRITE_GLYPH_IMAGE_FORMATS_CFF | DWRITE_GLYPH_IMAGE_FORMATS_COLR))
{
FIXME("Unimplemented formats requested %#x.\n", formats);
return E_NOTIMPL;
}
if (!(colorglyphenum = calloc(1, sizeof(*colorglyphenum))))
return E_OUTOFMEMORY;
colorglyphenum->IDWriteColorGlyphRunEnumerator1_iface.lpVtbl = &colorglyphenumvtbl;
colorglyphenum->refcount = 1;
colorglyphenum->origin_x = originX;
colorglyphenum->origin_y = originY;
colorglyphenum->origin = origin;
colorglyphenum->fontface = &fontface->IDWriteFontFace5_iface;
IDWriteFontFace5_AddRef(colorglyphenum->fontface);
colorglyphenum->glyphs = NULL;
@ -6648,7 +6662,7 @@ HRESULT create_colorglyphenum(float originX, float originY, const DWRITE_GLYPH_R
run->fontEmSize, 1.0f, transform, run->glyphIndices[i], run->isSideways);
}
*ret = (IDWriteColorGlyphRunEnumerator *)&colorglyphenum->IDWriteColorGlyphRunEnumerator1_iface;
*ret = &colorglyphenum->IDWriteColorGlyphRunEnumerator1_iface;
return S_OK;
}

View File

@ -1398,13 +1398,17 @@ static HRESULT WINAPI dwritefactory2_CreateFontFallbackBuilder(IDWriteFactory7 *
}
static HRESULT WINAPI dwritefactory2_TranslateColorGlyphRun(IDWriteFactory7 *iface, FLOAT originX, FLOAT originY,
const DWRITE_GLYPH_RUN *run, const DWRITE_GLYPH_RUN_DESCRIPTION *rundescr, DWRITE_MEASURING_MODE mode,
const DWRITE_MATRIX *transform, UINT32 palette, IDWriteColorGlyphRunEnumerator **colorlayers)
const DWRITE_GLYPH_RUN *run, const DWRITE_GLYPH_RUN_DESCRIPTION *run_desc, DWRITE_MEASURING_MODE measuring_mode,
const DWRITE_MATRIX *transform, UINT32 palette, IDWriteColorGlyphRunEnumerator **layers)
{
TRACE("%p, %.8e, %.8e, %p, %p, %d, %p, %u, %p.\n", iface, originX, originY, run, rundescr, mode,
transform, palette, colorlayers);
D2D1_POINT_2F origin = { originX, originY };
return create_colorglyphenum(originX, originY, run, rundescr, mode, transform, palette, colorlayers);
TRACE("%p, %.8e, %.8e, %p, %p, %d, %p, %u, %p.\n", iface, originX, originY, run, run_desc, measuring_mode,
transform, palette, layers);
return create_colorglyphenum(origin, run, run_desc, DWRITE_GLYPH_IMAGE_FORMATS_TRUETYPE
| DWRITE_GLYPH_IMAGE_FORMATS_CFF | DWRITE_GLYPH_IMAGE_FORMATS_COLR,
measuring_mode, transform, palette, (IDWriteColorGlyphRunEnumerator1 **)layers);
}
static HRESULT WINAPI dwritefactory2_CreateCustomRenderingParams(IDWriteFactory7 *iface, FLOAT gamma, FLOAT contrast,
@ -1697,15 +1701,15 @@ static HRESULT WINAPI dwritefactory3_GetFontDownloadQueue(IDWriteFactory7 *iface
return E_NOTIMPL;
}
static HRESULT WINAPI dwritefactory4_TranslateColorGlyphRun(IDWriteFactory7 *iface, D2D1_POINT_2F baseline_origin,
static HRESULT WINAPI dwritefactory4_TranslateColorGlyphRun(IDWriteFactory7 *iface, D2D1_POINT_2F origin,
DWRITE_GLYPH_RUN const *run, DWRITE_GLYPH_RUN_DESCRIPTION const *run_desc,
DWRITE_GLYPH_IMAGE_FORMATS desired_formats, DWRITE_MEASURING_MODE measuring_mode, DWRITE_MATRIX const *transform,
UINT32 palette, IDWriteColorGlyphRunEnumerator1 **layers)
{
FIXME("%p, %p, %p, %u, %d, %p, %u, %p: stub\n", iface, run, run_desc, desired_formats, measuring_mode,
transform, palette, layers);
TRACE("%p, %.8e, %.8e, %p, %p, %u, %d, %p, %u, %p.\n", iface, origin.x, origin.y, run, run_desc, desired_formats,
measuring_mode, transform, palette, layers);
return E_NOTIMPL;
return create_colorglyphenum(origin, run, run_desc, desired_formats, measuring_mode, transform, palette, layers);
}
HRESULT compute_glyph_origins(DWRITE_GLYPH_RUN const *run, DWRITE_MEASURING_MODE measuring_mode,

View File

@ -7671,6 +7671,7 @@ static void test_TranslateColorGlyphRun(void)
const DWRITE_COLOR_GLYPH_RUN *colorrun;
IDWriteFontFace2 *fontface2;
IDWriteFontFace *fontface;
IDWriteFactory4 *factory4;
IDWriteFactory2 *factory;
DWRITE_GLYPH_RUN run;
UINT32 codepoints[2];
@ -7740,7 +7741,8 @@ static void test_TranslateColorGlyphRun(void)
win_skip("IDWriteColorGlyphRunEnumerator1 is not supported.\n");
}
for (;;) {
for (;;)
{
hasrun = FALSE;
hr = IDWriteColorGlyphRunEnumerator_MoveNext(layers, &hasrun);
ok(hr == S_OK, "got 0x%08x\n", hr);
@ -7749,22 +7751,24 @@ static void test_TranslateColorGlyphRun(void)
break;
hr = IDWriteColorGlyphRunEnumerator_GetCurrentRun(layers, &colorrun);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(colorrun->glyphRun.fontFace != NULL, "got fontface %p\n", colorrun->glyphRun.fontFace);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
ok(colorrun->glyphRun.fontFace == fontface, "Unexpected fontface %p.\n", colorrun->glyphRun.fontFace);
ok(colorrun->glyphRun.fontEmSize == 20.0f, "got wrong font size %f\n", colorrun->glyphRun.fontEmSize);
ok(colorrun->glyphRun.glyphCount > 0, "got wrong glyph count %u\n", colorrun->glyphRun.glyphCount);
ok(colorrun->glyphRun.glyphCount == 1, "Unexpected glyph count %u.\n", colorrun->glyphRun.glyphCount);
ok(colorrun->glyphRun.glyphIndices != NULL, "got null glyph indices %p\n", colorrun->glyphRun.glyphIndices);
ok(colorrun->glyphRun.glyphAdvances != NULL, "got null glyph advances %p\n", colorrun->glyphRun.glyphAdvances);
ok(!colorrun->glyphRunDescription, "Unexpected description pointer.\n");
if (layers1)
{
hr = IDWriteColorGlyphRunEnumerator1_GetCurrentRun(layers1, &colorrun1);
ok(hr == S_OK, "Failed to get color runt, hr %#x.\n", hr);
ok(colorrun1->glyphRun.fontFace != NULL, "Unexpected fontface %p.\n", colorrun1->glyphRun.fontFace);
ok(colorrun1->glyphRun.fontEmSize == 20.0f, "Unexpected font size %f.\n", colorrun1->glyphRun.fontEmSize);
ok(colorrun1->glyphRun.glyphCount > 0, "Unexpected glyph count %u\n", colorrun1->glyphRun.glyphCount);
ok(colorrun1->glyphRun.glyphIndices != NULL, "Unexpected indices array.\n");
ok(colorrun1->glyphRun.glyphAdvances != NULL, "Unexpected advances array.\n");
ok((const DWRITE_COLOR_GLYPH_RUN *)colorrun1 == colorrun, "Unexpected pointer.\n");
ok(colorrun1->glyphImageFormat == (DWRITE_GLYPH_IMAGE_FORMATS_TRUETYPE | DWRITE_GLYPH_IMAGE_FORMATS_COLR) ||
colorrun1->glyphImageFormat == DWRITE_GLYPH_IMAGE_FORMATS_NONE,
"Unexpected glyph image format %#x.\n", colorrun1->glyphImageFormat);
ok(colorrun1->measuringMode == DWRITE_MEASURING_MODE_NATURAL, "Unexpected measuring mode %d.\n",
colorrun1->measuringMode);
}
}
@ -7804,6 +7808,7 @@ static void test_TranslateColorGlyphRun(void)
codepoints[0] = 'A';
hr = IDWriteFontFace_GetGlyphIndices(fontface, codepoints, 1, glyphs);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(!!*glyphs, "Unexpected glyph.\n");
layers = (void*)0xdeadbeef;
hr = IDWriteFactory2_TranslateColorGlyphRun(factory, 0.0f, 0.0f, &run, NULL,
@ -7822,11 +7827,94 @@ static void test_TranslateColorGlyphRun(void)
layers = NULL;
hr = IDWriteFactory2_TranslateColorGlyphRun(factory, 0.0f, 0.0f, &run, NULL,
DWRITE_MEASURING_MODE_NATURAL, NULL, 0, &layers);
DWRITE_MEASURING_MODE_NATURAL, NULL, 0, &layers);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(layers != NULL, "got %p\n", layers);
hr = IDWriteColorGlyphRunEnumerator_QueryInterface(layers, &IID_IDWriteColorGlyphRunEnumerator1, (void **)&layers1);
if (SUCCEEDED(hr))
{
for (;;)
{
hasrun = FALSE;
hr = IDWriteColorGlyphRunEnumerator1_MoveNext(layers1, &hasrun);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
if (!hasrun)
break;
hr = IDWriteColorGlyphRunEnumerator1_GetCurrentRun(layers1, &colorrun1);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
ok(!!colorrun1->glyphRun.fontFace, "Unexpected fontface %p.\n", colorrun1->glyphRun.fontFace);
ok(colorrun1->glyphRun.fontEmSize == 20.0f, "got wrong font size %f\n", colorrun1->glyphRun.fontEmSize);
ok(colorrun1->glyphRun.glyphCount > 0, "Unexpected glyph count %u.\n", colorrun1->glyphRun.glyphCount);
ok(!!colorrun1->glyphRun.glyphIndices, "Unexpected indices %p.\n", colorrun1->glyphRun.glyphIndices);
ok(!!colorrun1->glyphRun.glyphAdvances, "Unexpected advances %p.\n", colorrun1->glyphRun.glyphAdvances);
ok(!colorrun1->glyphRunDescription, "Unexpected description pointer.\n");
todo_wine
ok(colorrun1->glyphImageFormat == (DWRITE_GLYPH_IMAGE_FORMATS_TRUETYPE | DWRITE_GLYPH_IMAGE_FORMATS_COLR) ||
colorrun1->glyphImageFormat == DWRITE_GLYPH_IMAGE_FORMATS_TRUETYPE, "Unexpected glyph image format %#x.\n",
colorrun1->glyphImageFormat);
ok(colorrun1->measuringMode == DWRITE_MEASURING_MODE_NATURAL, "Unexpected measuring mode %d.\n",
colorrun1->measuringMode);
}
IDWriteColorGlyphRunEnumerator1_Release(layers1);
}
IDWriteColorGlyphRunEnumerator_Release(layers);
if (SUCCEEDED(IDWriteFactory2_QueryInterface(factory, &IID_IDWriteFactory4, (void **)&factory4)))
{
D2D1_POINT_2F origin;
origin.x = origin.y = 0.0f;
hr = IDWriteFactory4_TranslateColorGlyphRun(factory4, origin, &run, NULL,
DWRITE_GLYPH_IMAGE_FORMATS_NONE, DWRITE_MEASURING_MODE_NATURAL, NULL, 0, &layers1);
ok(hr == DWRITE_E_NOCOLOR, "Unexpected hr %#x.\n", hr);
hr = IDWriteFactory4_TranslateColorGlyphRun(factory4, origin, &run, NULL,
DWRITE_GLYPH_IMAGE_FORMATS_TRUETYPE, DWRITE_MEASURING_MODE_NATURAL, NULL, 0, &layers1);
ok(hr == DWRITE_E_NOCOLOR, "Unexpected hr %#x.\n", hr);
hr = IDWriteFactory4_TranslateColorGlyphRun(factory4, origin, &run, NULL,
DWRITE_GLYPH_IMAGE_FORMATS_CFF, DWRITE_MEASURING_MODE_NATURAL, NULL, 0, &layers1);
ok(hr == DWRITE_E_NOCOLOR, "Unexpected hr %#x.\n", hr);
hr = IDWriteFactory4_TranslateColorGlyphRun(factory4, origin, &run, NULL,
DWRITE_GLYPH_IMAGE_FORMATS_COLR, DWRITE_MEASURING_MODE_NATURAL, NULL, 0, &layers1);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
for (;;)
{
hasrun = FALSE;
hr = IDWriteColorGlyphRunEnumerator1_MoveNext(layers1, &hasrun);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
if (!hasrun)
break;
hr = IDWriteColorGlyphRunEnumerator1_GetCurrentRun(layers1, &colorrun1);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
ok(!!colorrun1->glyphRun.fontFace, "Unexpected fontface %p.\n", colorrun1->glyphRun.fontFace);
ok(colorrun1->glyphRun.fontEmSize == 20.0f, "got wrong font size %f\n", colorrun1->glyphRun.fontEmSize);
ok(colorrun1->glyphRun.glyphCount > 0, "Unexpected glyph count %u.\n", colorrun1->glyphRun.glyphCount);
ok(!!colorrun1->glyphRun.glyphIndices, "Unexpected indices %p.\n", colorrun1->glyphRun.glyphIndices);
ok(!!colorrun1->glyphRun.glyphAdvances, "Unexpected advances %p.\n", colorrun1->glyphRun.glyphAdvances);
ok(!colorrun1->glyphRunDescription, "Unexpected description pointer.\n");
ok(colorrun1->glyphImageFormat == DWRITE_GLYPH_IMAGE_FORMATS_COLR ||
colorrun1->glyphImageFormat == DWRITE_GLYPH_IMAGE_FORMATS_NONE, "Unexpected glyph image format %#x.\n",
colorrun1->glyphImageFormat);
ok(colorrun1->measuringMode == DWRITE_MEASURING_MODE_NATURAL, "Unexpected measuring mode %d.\n",
colorrun1->measuringMode);
}
IDWriteColorGlyphRunEnumerator1_Release(layers1);
IDWriteFactory4_Release(factory4);
}
else
win_skip("IDWriteFactory4::TranslateColorGlyphRun() is not supported.\n");
IDWriteFontFace2_Release(fontface2);
IDWriteFontFace_Release(fontface);
ref = IDWriteFactory2_Release(factory);