Commit 8a4db9fd authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

dwrite: Implement color glyph run decomposition.

parent 2e927af3
......@@ -165,6 +165,19 @@ extern UINT32 opentype_get_cpal_palettecount(const void*) DECLSPEC_HIDDEN;
extern UINT32 opentype_get_cpal_paletteentrycount(const void*) DECLSPEC_HIDDEN;
extern HRESULT opentype_get_cpal_entries(const void*,UINT32,UINT32,UINT32,DWRITE_COLOR_F*) DECLSPEC_HIDDEN;
struct dwrite_colorglyph {
USHORT layer; /* [0, num_layers) index indicating current layer */
/* base glyph record data, set once on initialization */
USHORT first_layer;
USHORT num_layers;
/* current layer record data, updated every time glyph is switched to next layer */
UINT16 glyph;
UINT16 palette_index;
};
extern HRESULT opentype_get_colr_glyph(const void*,UINT16,struct dwrite_colorglyph*) DECLSPEC_HIDDEN;
extern void opentype_colr_next_glyph(const void*,struct dwrite_colorglyph*) DECLSPEC_HIDDEN;
enum gasp_flags {
GASP_GRIDFIT = 0x0001,
GASP_DOGRAY = 0x0002,
......
......@@ -707,6 +707,29 @@ struct CPAL_ColorRecord
BYTE alpha;
};
/* COLR table */
struct COLR_Header
{
USHORT version;
USHORT numBaseGlyphRecords;
ULONG offsetBaseGlyphRecord;
ULONG offsetLayerRecord;
USHORT numLayerRecords;
};
struct COLR_BaseGlyphRecord
{
USHORT GID;
USHORT firstLayerIndex;
USHORT numLayers;
};
struct COLR_LayerRecord
{
USHORT GID;
USHORT paletteIndex;
};
BOOL is_face_type_supported(DWRITE_FONT_FACE_TYPE type)
{
return (type == DWRITE_FONT_FACE_TYPE_CFF) ||
......@@ -1692,3 +1715,64 @@ HRESULT opentype_get_cpal_entries(const void *cpal, UINT32 palette, UINT32 first
return S_OK;
}
static int colr_compare_gid(const void *g, const void *r)
{
const struct COLR_BaseGlyphRecord *record = r;
UINT16 glyph = *(UINT16*)g, GID = GET_BE_WORD(record->GID);
int ret = 0;
if (glyph > GID)
ret = 1;
else if (glyph < GID)
ret = -1;
return ret;
}
HRESULT opentype_get_colr_glyph(const void *colr, UINT16 glyph, struct dwrite_colorglyph *ret)
{
const struct COLR_BaseGlyphRecord *record;
const struct COLR_Header *header = colr;
const struct COLR_LayerRecord *layer;
DWORD layerrecordoffset = GET_BE_DWORD(header->offsetLayerRecord);
DWORD baserecordoffset = GET_BE_DWORD(header->offsetBaseGlyphRecord);
WORD numbaserecords = GET_BE_WORD(header->numBaseGlyphRecords);
record = bsearch(&glyph, (BYTE*)colr + baserecordoffset, numbaserecords, sizeof(struct COLR_BaseGlyphRecord),
colr_compare_gid);
if (!record) {
ret->layer = 0;
ret->first_layer = 0;
ret->num_layers = 0;
ret->glyph = glyph;
ret->palette_index = 0xffff;
return S_FALSE;
}
ret->layer = 0;
ret->first_layer = GET_BE_WORD(record->firstLayerIndex);
ret->num_layers = GET_BE_WORD(record->numLayers);
layer = (struct COLR_LayerRecord*)((BYTE*)colr + layerrecordoffset) + ret->first_layer + ret->layer;
ret->glyph = GET_BE_WORD(layer->GID);
ret->palette_index = GET_BE_WORD(layer->paletteIndex);
return S_OK;
}
void opentype_colr_next_glyph(const void *colr, struct dwrite_colorglyph *glyph)
{
const struct COLR_Header *header = colr;
const struct COLR_LayerRecord *layer;
DWORD layerrecordoffset = GET_BE_DWORD(header->offsetLayerRecord);
/* iterated all the way through */
if (glyph->layer == glyph->num_layers)
return;
glyph->layer++;
layer = (struct COLR_LayerRecord*)((BYTE*)colr + layerrecordoffset) + glyph->first_layer + glyph->layer;
glyph->glyph = GET_BE_WORD(layer->GID);
glyph->palette_index = GET_BE_WORD(layer->paletteIndex);
}
......@@ -5207,7 +5207,6 @@ static void test_TranslateColorGlyphRun(void)
while (1) {
hasrun = FALSE;
hr = IDWriteColorGlyphRunEnumerator_MoveNext(layers, &hasrun);
todo_wine
ok(hr == S_OK, "got 0x%08x\n", hr);
if (!hasrun)
......@@ -5216,7 +5215,6 @@ static void test_TranslateColorGlyphRun(void)
/* iterated all way through */
hr = IDWriteColorGlyphRunEnumerator_GetCurrentRun(layers, &colorrun);
todo_wine
ok(hr == E_NOT_VALID_STATE, "got 0x%08x\n", hr);
IDWriteColorGlyphRunEnumerator_Release(layers);
......@@ -5247,10 +5245,9 @@ todo_wine
layers = (void*)0xdeadbeef;
hr = IDWriteFactory2_TranslateColorGlyphRun(factory2, 0.0, 0.0, &run, NULL,
DWRITE_MEASURING_MODE_NATURAL, NULL, 0, &layers);
todo_wine {
ok(hr == DWRITE_E_NOCOLOR, "got 0x%08x\n", hr);
ok(layers == NULL, "got %p\n", layers);
}
/* one glyph with, one without */
codepoints[0] = 'A';
codepoints[1] = 0x26c4;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment