Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/dwrite_private.h | 6 +- dlls/dwrite/font.c | 4 +- dlls/dwrite/opentype.c | 105 ++++++++++++++++++++--------------- 3 files changed, 67 insertions(+), 48 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 6eac1f4f33..3251e66dec 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -245,8 +245,10 @@ struct dwrite_colorglyph { 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; +extern HRESULT opentype_get_colr_glyph(const struct dwrite_fonttable *table, UINT16 glyph, + struct dwrite_colorglyph *color_glyph) DECLSPEC_HIDDEN; +extern void opentype_colr_next_glyph(const struct dwrite_fonttable *table, + struct dwrite_colorglyph *color_glyph) DECLSPEC_HIDDEN;
enum gasp_flags { GASP_GRIDFIT = 0x0001, diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 2c51674b0a..bb04df6bd2 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -5649,7 +5649,7 @@ static BOOL colorglyphenum_build_color_run(struct dwrite_colorglyphenum *glyphen /* offsets are relative to glyph origin, nothing to fix up */ if (glyphenum->color_offsets) glyphenum->color_offsets[index] = glyphenum->offsets[g]; - opentype_colr_next_glyph(glyphenum->colr.data, glyphenum->glyphs + g); + opentype_colr_next_glyph(&glyphenum->colr, glyphenum->glyphs + g); if (index) glyphenum->color_advances[index-1] += advance_adj; colorrun->glyphRun.glyphCount++; @@ -5755,7 +5755,7 @@ HRESULT create_colorglyphenum(float originX, float originY, const DWRITE_GLYPH_R has_colored_glyph = FALSE; colorglyphenum->has_regular_glyphs = FALSE; for (i = 0; i < run->glyphCount; i++) { - if (opentype_get_colr_glyph(colorglyphenum->colr.data, run->glyphIndices[i], colorglyphenum->glyphs + i) == S_OK) { + if (opentype_get_colr_glyph(&colorglyphenum->colr, run->glyphIndices[i], colorglyphenum->glyphs + i) == S_OK) { colorglyphenum->max_layer_num = max(colorglyphenum->max_layer_num, colorglyphenum->glyphs[i].num_layers); has_colored_glyph = TRUE; } diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index 647ac99597..82491dcc02 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -862,26 +862,26 @@ struct cpal_color_record };
/* COLR table */ -struct COLR_Header +struct colr_header { USHORT version; - USHORT numBaseGlyphRecords; - ULONG offsetBaseGlyphRecord; - ULONG offsetLayerRecord; - USHORT numLayerRecords; + USHORT num_baseglyph_records; + ULONG offset_baseglyph_records; + ULONG offset_layer_records; + USHORT num_layer_records; };
-struct COLR_BaseGlyphRecord +struct colr_baseglyph_record { - USHORT GID; - USHORT firstLayerIndex; - USHORT numLayers; + USHORT glyph; + USHORT first_layer_index; + USHORT num_layers; };
-struct COLR_LayerRecord +struct colr_layer_record { - USHORT GID; - USHORT paletteIndex; + USHORT glyph; + USHORT palette_index; };
static const void *table_read_ensure(const struct dwrite_fonttable *table, unsigned int offset, unsigned int size) @@ -2050,8 +2050,8 @@ HRESULT opentype_get_cpal_entries(const struct dwrite_fonttable *cpal, unsigned
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); + const struct colr_baseglyph_record *record = r; + UINT16 glyph = *(UINT16*)g, GID = GET_BE_WORD(record->glyph); int ret = 0;
if (glyph > GID) @@ -2062,51 +2062,68 @@ static int colr_compare_gid(const void *g, const void *r) 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; +HRESULT opentype_get_colr_glyph(const struct dwrite_fonttable *colr, UINT16 glyph, struct dwrite_colorglyph *ret) +{ + unsigned int num_baseglyph_records, offset_baseglyph_records; + const struct colr_baseglyph_record *record; + const struct colr_layer_record *layer; + const struct colr_header *header; + + memset(ret, 0, sizeof(*ret)); + ret->glyph = glyph; + ret->palette_index = 0xffff; + + header = table_read_ensure(colr, 0, sizeof(*header)); + if (!header) + return S_FALSE; + + num_baseglyph_records = GET_BE_WORD(header->num_baseglyph_records); + offset_baseglyph_records = GET_BE_DWORD(header->offset_baseglyph_records); + if (!table_read_ensure(colr, offset_baseglyph_records, num_baseglyph_records * sizeof(*record))) + { return S_FALSE; }
- ret->layer = 0; - ret->first_layer = GET_BE_WORD(record->firstLayerIndex); - ret->num_layers = GET_BE_WORD(record->numLayers); + record = bsearch(&glyph, colr->data + offset_baseglyph_records, num_baseglyph_records, + sizeof(*record), colr_compare_gid); + if (!record) + return S_FALSE; + + ret->first_layer = GET_BE_WORD(record->first_layer_index); + ret->num_layers = GET_BE_WORD(record->num_layers);
- 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); + if ((layer = table_read_ensure(colr, GET_BE_DWORD(header->offset_layer_records), + (ret->first_layer + ret->layer) * sizeof(*layer)))) + { + layer += ret->first_layer + ret->layer; + ret->glyph = GET_BE_WORD(layer->glyph); + ret->palette_index = GET_BE_WORD(layer->palette_index); + }
return S_OK; }
-void opentype_colr_next_glyph(const void *colr, struct dwrite_colorglyph *glyph) +void opentype_colr_next_glyph(const struct dwrite_fonttable *colr, struct dwrite_colorglyph *glyph) { - const struct COLR_Header *header = colr; - const struct COLR_LayerRecord *layer; - DWORD layerrecordoffset = GET_BE_DWORD(header->offsetLayerRecord); + const struct colr_layer_record *layer; + const struct colr_header *header;
/* iterated all the way through */ if (glyph->layer == glyph->num_layers) return;
+ if (!(header = table_read_ensure(colr, 0, sizeof(*header)))) + 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); + + if ((layer = table_read_ensure(colr, GET_BE_DWORD(header->offset_layer_records), + (glyph->first_layer + glyph->layer) * sizeof(*layer)))) + { + layer += glyph->first_layer + glyph->layer; + glyph->glyph = GET_BE_WORD(layer->glyph); + glyph->palette_index = GET_BE_WORD(layer->palette_index); + } }
BOOL opentype_has_vertical_variants(IDWriteFontFace4 *fontface)
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/dwrite_private.h | 3 ++ dlls/dwrite/font.c | 2 +- dlls/dwrite/opentype.c | 63 +++++++++++++++++++----------------- dlls/dwrite/tests/font.c | 2 +- 4 files changed, 39 insertions(+), 31 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 3251e66dec..2d20b41ea6 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -216,6 +216,9 @@ struct dwrite_fonttable BOOL exists; };
+extern const void* get_fontface_table(IDWriteFontFace4 *fontface, UINT32 tag, + struct dwrite_fonttable *table) DECLSPEC_HIDDEN; + extern HRESULT opentype_analyze_font(IDWriteFontFileStream*,BOOL*,DWRITE_FONT_FILE_TYPE*,DWRITE_FONT_FACE_TYPE*,UINT32*) DECLSPEC_HIDDEN; extern HRESULT opentype_get_font_table(struct file_stream_desc*,UINT32,const void**,void**,UINT32*,BOOL*) DECLSPEC_HIDDEN; extern HRESULT opentype_cmap_get_unicode_ranges(const struct dwrite_fonttable *table, unsigned int max_count, diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index bb04df6bd2..372578ec48 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -338,7 +338,7 @@ static HRESULT set_cached_glyph_metrics(struct dwrite_fontface *fontface, UINT16 return S_OK; }
-static const void* get_fontface_table(IDWriteFontFace4 *fontface, UINT32 tag, struct dwrite_fonttable *table) +const void* get_fontface_table(IDWriteFontFace4 *fontface, UINT32 tag, struct dwrite_fonttable *table) { HRESULT hr;
diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index 82491dcc02..261d00c8a8 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -268,17 +268,19 @@ typedef struct { WORD numGlyphs; } maxp;
-typedef struct { - WORD majorVersion; - WORD minorVersion; - DWORD numSizes; -} CBLCHeader; +struct cblc_header +{ + WORD major_version; + WORD minor_version; + DWORD num_sizes; +};
typedef struct { BYTE res[12]; } sbitLineMetrics;
-typedef struct { +struct cblc_bitmapsize_table +{ DWORD indexSubTableArrayOffset; DWORD indexTablesSize; DWORD numberofIndexSubTables; @@ -289,9 +291,9 @@ typedef struct { WORD endGlyphIndex; BYTE ppemX; BYTE ppemY; - BYTE bitDepth; + BYTE bit_depth; BYTE flags; -} CBLCBitmapSizeTable; +};
struct gasp_range { @@ -2284,36 +2286,39 @@ static DWORD opentype_get_sbix_formats(IDWriteFontFace4 *fontface) return ret; }
-static UINT32 opentype_get_cblc_formats(IDWriteFontFace4 *fontface) +static unsigned int opentype_get_cblc_formats(IDWriteFontFace4 *fontface) { - CBLCBitmapSizeTable *sizes; - UINT32 num_sizes, size, s; - BOOL exists = FALSE; - CBLCHeader *header; - UINT32 ret = 0; - void *context; - HRESULT hr; + const unsigned int format_mask = DWRITE_GLYPH_IMAGE_FORMATS_PNG | + DWRITE_GLYPH_IMAGE_FORMATS_PREMULTIPLIED_B8G8R8A8; + const struct cblc_bitmapsize_table *sizes; + struct dwrite_fonttable cblc = { 0 }; + unsigned int num_sizes, i, ret = 0; + const struct cblc_header *header;
- if (FAILED(hr = IDWriteFontFace4_TryGetFontTable(fontface, MS_CBLC_TAG, (const void **)&header, &size, - &context, &exists))) + cblc.exists = TRUE; + if (!get_fontface_table(fontface, MS_CBLC_TAG, &cblc)) return 0;
- if (!exists) - return 0; + num_sizes = table_read_be_dword(&cblc, FIELD_OFFSET(struct cblc_header, num_sizes)); + sizes = table_read_ensure(&cblc, sizeof(*header), num_sizes * sizeof(*sizes));
- num_sizes = GET_BE_DWORD(header->numSizes); - sizes = (CBLCBitmapSizeTable *)(header + 1); + if (sizes) + { + for (i = 0; i < num_sizes; ++i) + { + BYTE bpp = sizes[i].bit_depth;
- for (s = 0; s < num_sizes; s++) { - BYTE bpp = sizes->bitDepth; + if ((ret & format_mask) == format_mask) + break;
- if (bpp == 1 || bpp == 2 || bpp == 4 || bpp == 8) - ret |= DWRITE_GLYPH_IMAGE_FORMATS_PNG; - else if (bpp == 32) - ret |= DWRITE_GLYPH_IMAGE_FORMATS_PREMULTIPLIED_B8G8R8A8; + if (bpp == 1 || bpp == 2 || bpp == 4 || bpp == 8) + ret |= DWRITE_GLYPH_IMAGE_FORMATS_PNG; + else if (bpp == 32) + ret |= DWRITE_GLYPH_IMAGE_FORMATS_PREMULTIPLIED_B8G8R8A8; + } }
- IDWriteFontFace4_ReleaseFontTable(fontface, context); + IDWriteFontFace4_ReleaseFontTable(fontface, cblc.context);
return ret; } diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index 3e736c82b7..309c0a2b08 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -8755,7 +8755,7 @@ static DWORD get_cblc_formats(IDWriteFontFace4 *fontface) sizes = (CBLCBitmapSizeTable *)(header + 1);
for (s = 0; s < num_sizes; s++) { - BYTE bpp = sizes->bitDepth; + BYTE bpp = sizes[s].bitDepth;
if (bpp == 1 || bpp == 2 || bpp == 4 || bpp == 8) ret |= DWRITE_GLYPH_IMAGE_FORMATS_PNG;
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/opentype.c | 125 ++++++++++++++++++++++------------------- 1 file changed, 68 insertions(+), 57 deletions(-)
diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index 261d00c8a8..35cf838cf0 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -243,30 +243,34 @@ typedef struct { USHORT numberOfHMetrics; } TT_HHEA;
-typedef struct { +struct sbix_header +{ WORD version; WORD flags; - DWORD numStrikes; - DWORD strikeOffset[1]; -} sbix_header; + DWORD num_strikes; + DWORD strike_offset[1]; +};
-typedef struct { +struct sbix_strike +{ WORD ppem; WORD ppi; - DWORD glyphDataOffsets[1]; -} sbix_strike; + DWORD glyphdata_offsets[1]; +};
-typedef struct { +struct sbix_glyph_data +{ WORD originOffsetX; WORD originOffsetY; - DWORD graphicType; + DWORD graphic_type; BYTE data[1]; -} sbix_glyph_data; +};
-typedef struct { +struct maxp +{ DWORD version; - WORD numGlyphs; -} maxp; + WORD num_glyphs; +};
struct cblc_header { @@ -2221,67 +2225,74 @@ static BOOL opentype_has_font_table(IDWriteFontFace4 *fontface, UINT32 tag) return exists; }
-static DWORD opentype_get_sbix_formats(IDWriteFontFace4 *fontface) +static unsigned int opentype_get_sbix_formats(IDWriteFontFace4 *fontface) { - UINT32 size, s, num_strikes; - const sbix_header *header; - UINT16 g, num_glyphs; - BOOL exists = FALSE; - const maxp *maxp; - const void *data; - DWORD ret = 0; - void *context; - HRESULT hr; + unsigned int num_strikes, num_glyphs, i, j, ret = 0; + const struct sbix_header *sbix_header; + struct dwrite_fonttable table;
- hr = IDWriteFontFace4_TryGetFontTable(fontface, MS_MAXP_TAG, &data, &size, &context, &exists); - if (FAILED(hr) || !exists) + memset(&table, 0, sizeof(table)); + table.exists = TRUE; + + if (!get_fontface_table(fontface, MS_MAXP_TAG, &table)) return 0;
- maxp = data; - num_glyphs = GET_BE_WORD(maxp->numGlyphs); + num_glyphs = table_read_be_word(&table, FIELD_OFFSET(struct maxp, num_glyphs));
- IDWriteFontFace4_ReleaseFontTable(fontface, context); + IDWriteFontFace4_ReleaseFontTable(fontface, table.context);
- if (FAILED(IDWriteFontFace4_TryGetFontTable(fontface, MS_SBIX_TAG, &data, &size, &context, &exists))) { - WARN("Failed to get 'sbix' table, %#x\n", hr); - return 0; - } + memset(&table, 0, sizeof(table)); + table.exists = TRUE;
- header = data; - num_strikes = GET_BE_DWORD(header->numStrikes); + if (!get_fontface_table(fontface, MS_SBIX_TAG, &table)) + return 0;
- for (s = 0; s < num_strikes; s++) { - sbix_strike *strike = (sbix_strike *)((BYTE *)header + GET_BE_DWORD(header->strikeOffset[s])); + num_strikes = table_read_be_dword(&table, FIELD_OFFSET(struct sbix_header, num_strikes)); + sbix_header = table_read_ensure(&table, 0, FIELD_OFFSET(struct sbix_header, strike_offset[num_strikes]));
- for (g = 0; g < num_glyphs; g++) { - DWORD offset = GET_BE_DWORD(strike->glyphDataOffsets[g]); - DWORD offset_next = GET_BE_DWORD(strike->glyphDataOffsets[g + 1]); - sbix_glyph_data *glyph_data; - DWORD format; + if (sbix_header) + { + for (i = 0; i < num_strikes; ++i) + { + unsigned int strike_offset = GET_BE_DWORD(sbix_header->strike_offset[i]); + const struct sbix_strike *strike = table_read_ensure(&table, strike_offset, + FIELD_OFFSET(struct sbix_strike, glyphdata_offsets[num_glyphs + 1]));
- if (offset == offset_next) + if (!strike) continue;
- glyph_data = (sbix_glyph_data *)((BYTE *)strike + offset); - switch (format = glyph_data->graphicType) + for (j = 0; j < num_glyphs; j++) { - case MS_PNG__TAG: - ret |= DWRITE_GLYPH_IMAGE_FORMATS_PNG; - break; - case MS_JPG__TAG: - ret |= DWRITE_GLYPH_IMAGE_FORMATS_JPEG; - break; - case MS_TIFF_TAG: - ret |= DWRITE_GLYPH_IMAGE_FORMATS_TIFF; - break; - default: - format = GET_BE_DWORD(format); - FIXME("unexpected bitmap format %s\n", debugstr_an((char *)&format, 4)); + unsigned int offset = GET_BE_DWORD(strike->glyphdata_offsets[j]); + unsigned int next_offset = GET_BE_DWORD(strike->glyphdata_offsets[j + 1]); + const struct sbix_glyph_data *glyph_data; + + if (offset == next_offset) + continue; + + glyph_data = table_read_ensure(&table, strike_offset + offset, sizeof(*glyph_data)); + if (!glyph_data) + continue; + + switch (glyph_data->graphic_type) + { + case MS_PNG__TAG: + ret |= DWRITE_GLYPH_IMAGE_FORMATS_PNG; + break; + case MS_JPG__TAG: + ret |= DWRITE_GLYPH_IMAGE_FORMATS_JPEG; + break; + case MS_TIFF_TAG: + ret |= DWRITE_GLYPH_IMAGE_FORMATS_TIFF; + break; + default: + FIXME("unexpected bitmap format %s\n", debugstr_tag(GET_BE_DWORD(glyph_data->graphic_type))); + } } } }
- IDWriteFontFace4_ReleaseFontTable(fontface, context); + IDWriteFontFace4_ReleaseFontTable(fontface, table.context);
return ret; }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/dwrite_private.h | 3 +- dlls/dwrite/font.c | 5 ++- dlls/dwrite/opentype.c | 82 +++++++++++++++++++++--------------- 3 files changed, 54 insertions(+), 36 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 2d20b41ea6..3595503f1e 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -229,7 +229,8 @@ extern HRESULT opentype_get_font_info_strings(const void*,DWRITE_INFORMATIONAL_S extern HRESULT opentype_get_font_familyname(struct file_stream_desc*,IDWriteLocalizedStrings**) DECLSPEC_HIDDEN; extern HRESULT opentype_get_font_facename(struct file_stream_desc*,WCHAR*,IDWriteLocalizedStrings**) DECLSPEC_HIDDEN; extern HRESULT opentype_get_typographic_features(IDWriteFontFace*,UINT32,UINT32,UINT32,UINT32*,DWRITE_FONT_FEATURE_TAG*) DECLSPEC_HIDDEN; -extern BOOL opentype_get_vdmx_size(const void*,INT,UINT16*,UINT16*) DECLSPEC_HIDDEN; +extern BOOL opentype_get_vdmx_size(const struct dwrite_fonttable *table, INT ppem, UINT16 *ascent, + UINT16 *descent) DECLSPEC_HIDDEN; extern unsigned int opentype_get_cpal_palettecount(const struct dwrite_fonttable *table) DECLSPEC_HIDDEN; extern unsigned int opentype_get_cpal_paletteentrycount(const struct dwrite_fonttable *table) DECLSPEC_HIDDEN; extern HRESULT opentype_get_cpal_entries(const struct dwrite_fonttable *table, unsigned int palette, diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 372578ec48..d1e4fb9725 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -374,9 +374,10 @@ static FLOAT get_font_prop_vec_dotproduct(const struct dwrite_font_propvec *left return left->stretch * right->stretch + left->style * right->style + left->weight * right->weight; }
-static const void* get_fontface_vdmx(struct dwrite_fontface *fontface) +static const struct dwrite_fonttable *get_fontface_vdmx(struct dwrite_fontface *fontface) { - return get_fontface_table(&fontface->IDWriteFontFace4_iface, MS_VDMX_TAG, &fontface->vdmx); + get_fontface_table(&fontface->IDWriteFontFace4_iface, MS_VDMX_TAG, &fontface->vdmx); + return &fontface->vdmx; }
static const struct dwrite_fonttable *get_fontface_gasp(struct dwrite_fontface *fontface) diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index 35cf838cf0..f92febd2e0 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -343,14 +343,14 @@ typedef struct { TT_NameRecord nameRecord[1]; } TT_NAME_V0;
-struct VDMX_Header +struct vdmx_header { WORD version; - WORD numRecs; - WORD numRatios; + WORD num_recs; + WORD num_ratios; };
-struct VDMX_Ratio +struct vdmx_ratio { BYTE bCharSet; BYTE xRatio; @@ -358,20 +358,21 @@ struct VDMX_Ratio BYTE yEndRatio; };
-struct VDMX_group -{ - WORD recs; - BYTE startsz; - BYTE endsz; -}; - -struct VDMX_vTable +struct vdmx_vtable { WORD yPelHeight; SHORT yMax; SHORT yMin; };
+struct vdmx_group +{ + WORD recs; + BYTE startsz; + BYTE endsz; + struct vdmx_vtable entries[1]; +}; + typedef struct { CHAR FeatureTag[4]; WORD Feature; @@ -1911,13 +1912,14 @@ HRESULT opentype_get_typographic_features(IDWriteFontFace *fontface, UINT32 scri return *count > max_tagcount ? E_NOT_SUFFICIENT_BUFFER : S_OK; }
-static const struct VDMX_group *find_vdmx_group(const struct VDMX_Header *hdr) +static unsigned int find_vdmx_group(const struct vdmx_header *hdr) { - WORD num_ratios, i, group_offset = 0; - struct VDMX_Ratio *ratios = (struct VDMX_Ratio*)(hdr + 1); + WORD num_ratios, i; + const struct vdmx_ratio *ratios = (struct vdmx_ratio *)(hdr + 1); BYTE dev_x_ratio = 1, dev_y_ratio = 1; + unsigned int group_offset = 0;
- num_ratios = GET_BE_WORD(hdr->numRatios); + num_ratios = GET_BE_WORD(hdr->num_ratios);
for (i = 0; i < num_ratios; i++) {
@@ -1932,42 +1934,56 @@ static const struct VDMX_group *find_vdmx_group(const struct VDMX_Header *hdr) break; } } - if (group_offset) - return (const struct VDMX_group *)((BYTE *)hdr + group_offset); - return NULL; + + return group_offset; }
-BOOL opentype_get_vdmx_size(const void *data, INT emsize, UINT16 *ascent, UINT16 *descent) +BOOL opentype_get_vdmx_size(const struct dwrite_fonttable *vdmx, INT emsize, UINT16 *ascent, UINT16 *descent) { - const struct VDMX_Header *hdr = (const struct VDMX_Header*)data; - const struct VDMX_group *group; - const struct VDMX_vTable *tables; - WORD recs, i; + unsigned int num_ratios, num_recs, group_offset, i; + const struct vdmx_header *header; + const struct vdmx_group *group; + + if (!vdmx->exists) + return FALSE; + + num_ratios = table_read_be_word(vdmx, FIELD_OFFSET(struct vdmx_header, num_ratios)); + num_recs = table_read_be_word(vdmx, FIELD_OFFSET(struct vdmx_header, num_recs)); + + header = table_read_ensure(vdmx, 0, sizeof(*header) + num_ratios * sizeof(struct vdmx_ratio) + + num_recs * sizeof(*group)); + + if (!header) + return FALSE;
- if (!data) + group_offset = find_vdmx_group(header); + if (!group_offset) return FALSE;
- group = find_vdmx_group(hdr); + num_recs = table_read_be_word(vdmx, group_offset); + group = table_read_ensure(vdmx, group_offset, FIELD_OFFSET(struct vdmx_group, entries[num_recs])); + if (!group) return FALSE;
- recs = GET_BE_WORD(group->recs); - if (emsize < group->startsz || emsize >= group->endsz) return FALSE; + if (emsize < group->startsz || emsize >= group->endsz) + return FALSE;
- tables = (const struct VDMX_vTable *)(group + 1); - for (i = 0; i < recs; i++) { - WORD ppem = GET_BE_WORD(tables[i].yPelHeight); + for (i = 0; i < num_recs; ++i) + { + WORD ppem = GET_BE_WORD(group->entries[i].yPelHeight); if (ppem > emsize) { FIXME("interpolate %d\n", emsize); return FALSE; }
if (ppem == emsize) { - *ascent = (SHORT)GET_BE_WORD(tables[i].yMax); - *descent = -(SHORT)GET_BE_WORD(tables[i].yMin); + *ascent = (SHORT)GET_BE_WORD(group->entries[i].yMax); + *descent = -(SHORT)GET_BE_WORD(group->entries[i].yMin); return TRUE; } } + return FALSE; }