Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/dwrite_private.h | 3 +- dlls/dwrite/font.c | 2 +- dlls/dwrite/opentype.c | 95 ++++++++++++++++++++++-------------- 3 files changed, 61 insertions(+), 39 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index cc5c028fd2..875f12916b 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -310,7 +310,8 @@ extern const void* get_fontface_table(IDWriteFontFace5 *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_try_get_font_table(struct file_stream_desc *stream_desc, UINT32 tag, const void **data, + void **context, UINT32 *size, BOOL *exists) DECLSPEC_HIDDEN; extern HRESULT opentype_cmap_get_unicode_ranges(const struct dwrite_fonttable *table, unsigned int max_count, DWRITE_UNICODE_RANGE *ranges, unsigned int *count) DECLSPEC_HIDDEN; extern void opentype_get_font_properties(struct file_stream_desc*,struct dwrite_font_props*) DECLSPEC_HIDDEN; diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 9280b5d32a..25b09feb07 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -707,7 +707,7 @@ static HRESULT WINAPI dwritefontface_TryGetFontTable(IDWriteFontFace5 *iface, UI stream_desc.stream = fontface->stream; stream_desc.face_type = fontface->type; stream_desc.face_index = fontface->index; - return opentype_get_font_table(&stream_desc, table_tag, table_data, context, table_size, exists); + return opentype_try_get_font_table(&stream_desc, table_tag, table_data, context, table_size, exists); }
static void WINAPI dwritefontface_ReleaseFontTable(IDWriteFontFace5 *iface, void *table_context) diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index 09a9a861c3..c5f1d16fac 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -1366,7 +1366,7 @@ HRESULT opentype_analyze_font(IDWriteFontFileStream *stream, BOOL *supported, DW return S_OK; }
-HRESULT opentype_get_font_table(struct file_stream_desc *stream_desc, UINT32 tag, const void **table_data, +HRESULT opentype_try_get_font_table(struct file_stream_desc *stream_desc, UINT32 tag, const void **table_data, void **table_context, UINT32 *table_size, BOOL *found) { void *table_directory_context, *sfnt_context; @@ -1434,6 +1434,12 @@ HRESULT opentype_get_font_table(struct file_stream_desc *stream_desc, UINT32 tag return hr; }
+static HRESULT opentype_get_font_table(struct file_stream_desc *stream_desc, UINT32 tag, + struct dwrite_fonttable *table) +{ + return opentype_try_get_font_table(stream_desc, tag, (const void **)&table->data, &table->context, &table->size, &table->exists); +} + /********** * CMAP **********/ @@ -1555,15 +1561,15 @@ HRESULT opentype_cmap_get_unicode_ranges(const struct dwrite_fonttable *cmap, un
void opentype_get_font_typo_metrics(struct file_stream_desc *stream_desc, unsigned int *ascent, unsigned int *descent) { + struct dwrite_fonttable os2; const TT_OS2_V2 *data; - unsigned int size; - void *context;
- opentype_get_font_table(stream_desc, MS_OS2_TAG, (const void **)&data, &context, &size, NULL); + opentype_get_font_table(stream_desc, MS_OS2_TAG, &os2); + data = (const TT_OS2_V2 *)os2.data;
*ascent = *descent = 0;
- if (size >= FIELD_OFFSET(TT_OS2_V2, sTypoLineGap)) + if (os2.size >= FIELD_OFFSET(TT_OS2_V2, sTypoLineGap)) { SHORT value = GET_BE_WORD(data->sTypoDescender); *ascent = GET_BE_WORD(data->sTypoAscender); @@ -1571,12 +1577,12 @@ void opentype_get_font_typo_metrics(struct file_stream_desc *stream_desc, unsign }
if (data) - IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, context); + IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, os2.context); }
void opentype_get_font_metrics(struct file_stream_desc *stream_desc, DWRITE_FONT_METRICS1 *metrics, DWRITE_CARET_METRICS *caret) { - void *os2_context, *head_context, *post_context, *hhea_context; + struct dwrite_fonttable os2, head, post, hhea; const TT_OS2_V2 *tt_os2; const TT_HEAD *tt_head; const TT_POST *tt_post; @@ -1584,10 +1590,15 @@ void opentype_get_font_metrics(struct file_stream_desc *stream_desc, DWRITE_FONT
memset(metrics, 0, sizeof(*metrics));
- opentype_get_font_table(stream_desc, MS_OS2_TAG, (const void**)&tt_os2, &os2_context, NULL, NULL); - opentype_get_font_table(stream_desc, MS_HEAD_TAG, (const void**)&tt_head, &head_context, NULL, NULL); - opentype_get_font_table(stream_desc, MS_POST_TAG, (const void**)&tt_post, &post_context, NULL, NULL); - opentype_get_font_table(stream_desc, MS_HHEA_TAG, (const void**)&tt_hhea, &hhea_context, NULL, NULL); + opentype_get_font_table(stream_desc, MS_OS2_TAG, &os2); + opentype_get_font_table(stream_desc, MS_HEAD_TAG, &head); + opentype_get_font_table(stream_desc, MS_POST_TAG, &post); + opentype_get_font_table(stream_desc, MS_HHEA_TAG, &hhea); + + tt_head = (const TT_HEAD *)head.data; + tt_os2 = (const TT_OS2_V2 *)os2.data; + tt_post = (const TT_POST *)post.data; + tt_hhea = (const TT_HHEA *)hhea.data;
if (tt_head) { metrics->designUnitsPerEm = GET_BE_WORD(tt_head->unitsPerEm); @@ -1597,7 +1608,8 @@ void opentype_get_font_metrics(struct file_stream_desc *stream_desc, DWRITE_FONT metrics->glyphBoxBottom = GET_BE_WORD(tt_head->yMin); }
- if (caret) { + if (caret) + { if (tt_hhea) { caret->slopeRise = GET_BE_WORD(tt_hhea->caretSlopeRise); caret->slopeRun = GET_BE_WORD(tt_hhea->caretSlopeRun); @@ -1679,23 +1691,26 @@ void opentype_get_font_metrics(struct file_stream_desc *stream_desc, DWRITE_FONT metrics->capHeight = metrics->designUnitsPerEm * 7 / 10;
if (tt_os2) - IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, os2_context); + IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, os2.context); if (tt_head) - IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, head_context); + IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, head.context); if (tt_post) - IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, post_context); + IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, post.context); if (tt_hhea) - IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, hhea_context); + IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, hhea.context); }
void opentype_get_font_properties(struct file_stream_desc *stream_desc, struct dwrite_font_props *props) { - void *os2_context, *head_context; + struct dwrite_fonttable os2, head; const TT_OS2_V2 *tt_os2; const TT_HEAD *tt_head;
- opentype_get_font_table(stream_desc, MS_OS2_TAG, (const void**)&tt_os2, &os2_context, NULL, NULL); - opentype_get_font_table(stream_desc, MS_HEAD_TAG, (const void**)&tt_head, &head_context, NULL, NULL); + opentype_get_font_table(stream_desc, MS_OS2_TAG, &os2); + opentype_get_font_table(stream_desc, MS_HEAD_TAG, &head); + + tt_os2 = (const TT_OS2_V2 *)os2.data; + tt_head = (const TT_HEAD *)head.data;
/* default stretch, weight and style to normal */ props->stretch = DWRITE_FONT_STRETCH_NORMAL; @@ -1767,10 +1782,10 @@ void opentype_get_font_properties(struct file_stream_desc *stream_desc, struct d
TRACE("stretch=%d, weight=%d, style %d\n", props->stretch, props->weight, props->style);
- if (tt_os2) - IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, os2_context); - if (tt_head) - IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, head_context); + if (os2.data) + IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, os2.context); + if (head.data) + IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, head.context); }
static UINT get_name_record_codepage(enum OPENTYPE_PLATFORM_ID platform, USHORT encoding) @@ -2026,13 +2041,16 @@ HRESULT opentype_get_font_info_strings(const void *table_data, DWRITE_INFORMATIO have 'Preferred Family Name' in WWS format, then WWS name is not used. */ HRESULT opentype_get_font_familyname(struct file_stream_desc *stream_desc, IDWriteLocalizedStrings **names) { + struct dwrite_fonttable os2, name; const TT_OS2_V2 *tt_os2; - void *os2_context, *name_context; const void *name_table; HRESULT hr;
- opentype_get_font_table(stream_desc, MS_OS2_TAG, (const void**)&tt_os2, &os2_context, NULL, NULL); - opentype_get_font_table(stream_desc, MS_NAME_TAG, &name_table, &name_context, NULL, NULL); + opentype_get_font_table(stream_desc, MS_OS2_TAG, &os2); + opentype_get_font_table(stream_desc, MS_NAME_TAG, &name); + + tt_os2 = (const TT_OS2_V2 *)os2.data; + name_table = (const void *)name.data;
*names = NULL;
@@ -2047,10 +2065,10 @@ HRESULT opentype_get_font_familyname(struct file_stream_desc *stream_desc, IDWri if (FAILED(hr)) hr = opentype_get_font_strings_from_id(name_table, OPENTYPE_STRING_FAMILY_NAME, names);
- if (tt_os2) - IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, os2_context); - if (name_context) - IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, name_context); + if (os2.context) + IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, os2.context); + if (name.context) + IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, name.context);
return hr; } @@ -2059,14 +2077,17 @@ HRESULT opentype_get_font_familyname(struct file_stream_desc *stream_desc, IDWri have 'Preferred Face Name' in WWS format, then WWS name is not used. */ HRESULT opentype_get_font_facename(struct file_stream_desc *stream_desc, WCHAR *lfname, IDWriteLocalizedStrings **names) { + struct dwrite_fonttable os2, name; IDWriteLocalizedStrings *lfnames; - void *os2_context, *name_context; const TT_OS2_V2 *tt_os2; const void *name_table; HRESULT hr;
- opentype_get_font_table(stream_desc, MS_OS2_TAG, (const void**)&tt_os2, &os2_context, NULL, NULL); - opentype_get_font_table(stream_desc, MS_NAME_TAG, &name_table, &name_context, NULL, NULL); + opentype_get_font_table(stream_desc, MS_OS2_TAG, &os2); + opentype_get_font_table(stream_desc, MS_NAME_TAG, &name); + + tt_os2 = (const TT_OS2_V2 *)os2.data; + name_table = name.data;
*names = NULL;
@@ -2113,10 +2134,10 @@ HRESULT opentype_get_font_facename(struct file_stream_desc *stream_desc, WCHAR * IDWriteLocalizedStrings_Release(lfnames); }
- if (tt_os2) - IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, os2_context); - if (name_context) - IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, name_context); + if (os2.context) + IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, os2.context); + if (name.context) + IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, name.context);
return hr; }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/dwrite_private.h | 16 +++++++++-- dlls/dwrite/font.c | 42 +++++++++++---------------- dlls/dwrite/freetype.c | 23 ++++----------- dlls/dwrite/opentype.c | 55 ++++++++++++++++++++++++++++++++---- dlls/dwrite/tests/font.c | 13 +++------ 5 files changed, 88 insertions(+), 61 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 875f12916b..76cf40cd1f 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -183,6 +183,14 @@ struct fontfacecached #define GLYPH_BLOCK_MASK (GLYPH_BLOCK_SIZE - 1) #define GLYPH_MAX 65536
+enum font_flags +{ + FONT_IS_SYMBOL = 1 << 0, + FONTFACE_IS_MONOSPACED = 1 << 1, + FONTFACE_HAS_KERNING_PAIRS = 1 << 2, + FONTFACE_HAS_VERTICAL_VARIANTS = 1 << 3 +}; + struct dwrite_fontface { IDWriteFontFace5 IDWriteFontFace5_iface; @@ -206,7 +214,7 @@ struct dwrite_fontface unsigned int descent; } typo_metrics; INT charmap; - UINT16 flags; + UINT32 flags;
struct dwrite_fonttable cmap; struct dwrite_fonttable vdmx; @@ -291,13 +299,15 @@ extern float fontface_get_scaled_design_advance(struct dwrite_fontface *fontface extern struct dwrite_fontface *unsafe_impl_from_IDWriteFontFace(IDWriteFontFace *iface) DECLSPEC_HIDDEN;
/* Opentype font table functions */ -struct dwrite_font_props { +struct dwrite_font_props +{ DWRITE_FONT_STYLE style; DWRITE_FONT_STRETCH stretch; DWRITE_FONT_WEIGHT weight; DWRITE_PANOSE panose; FONTSIGNATURE fontsig; LOGFONTW lf; + UINT32 flags; };
struct file_stream_desc { @@ -392,7 +402,7 @@ extern BOOL freetype_has_kerning_pairs(IDWriteFontFace5 *fontface) DECLSPEC_HIDD extern INT32 freetype_get_kerning_pair_adjustment(IDWriteFontFace5 *fontface, UINT16 left, UINT16 right) DECLSPEC_HIDDEN; extern void freetype_get_glyph_bbox(struct dwrite_glyphbitmap *bitmap_desc) DECLSPEC_HIDDEN; extern BOOL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap*) DECLSPEC_HIDDEN; -extern INT freetype_get_charmap_index(IDWriteFontFace5 *fontface, BOOL *is_symbol) DECLSPEC_HIDDEN; +extern INT freetype_get_charmap_index(IDWriteFontFace5 *fontface) DECLSPEC_HIDDEN; extern INT32 freetype_get_glyph_advance(IDWriteFontFace5 *fontface, FLOAT emsize, UINT16 index, DWRITE_MEASURING_MODE measuring_mode, BOOL *has_contours) DECLSPEC_HIDDEN; extern void freetype_get_design_glyph_bbox(IDWriteFontFace4*,UINT16,UINT16,RECT*) DECLSPEC_HIDDEN; diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 25b09feb07..f2b8655003 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -69,7 +69,8 @@ struct dwrite_font_propvec { FLOAT weight; };
-struct dwrite_font_data { +struct dwrite_font_data +{ LONG ref;
DWRITE_FONT_STYLE style; @@ -77,6 +78,7 @@ struct dwrite_font_data { DWRITE_FONT_WEIGHT weight; DWRITE_PANOSE panose; FONTSIGNATURE fontsig; + UINT32 flags; /* enum font_flags */ struct dwrite_font_propvec propvec;
DWRITE_FONT_METRICS1 metrics; @@ -206,13 +208,6 @@ struct dwrite_colorglyphenum #define GLYPH_BLOCK_MASK (GLYPH_BLOCK_SIZE - 1) #define GLYPH_MAX 65536
-enum fontface_flags { - FONTFACE_IS_SYMBOL = 1 << 0, - FONTFACE_IS_MONOSPACED = 1 << 1, - FONTFACE_HAS_KERNING_PAIRS = 1 << 2, - FONTFACE_HAS_VERTICAL_VARIANTS = 1 << 3 -}; - struct dwrite_fontfile { IDWriteFontFile IDWriteFontFile_iface; LONG ref; @@ -621,7 +616,7 @@ static BOOL WINAPI dwritefontface_IsSymbolFont(IDWriteFontFace5 *iface)
TRACE("%p.\n", iface);
- return !!(fontface->flags & FONTFACE_IS_SYMBOL); + return !!(fontface->flags & FONT_IS_SYMBOL); }
static void WINAPI dwritefontface_GetMetrics(IDWriteFontFace5 *iface, DWRITE_FONT_METRICS *metrics) @@ -1618,19 +1613,10 @@ static DWRITE_FONT_STYLE WINAPI dwritefont_GetStyle(IDWriteFont3 *iface) static BOOL WINAPI dwritefont_IsSymbolFont(IDWriteFont3 *iface) { struct dwrite_font *font = impl_from_IDWriteFont3(iface); - IDWriteFontFace5 *fontface; - HRESULT hr; - BOOL ret;
TRACE("%p.\n", iface);
- hr = get_fontface_from_font(font, &fontface); - if (FAILED(hr)) - return FALSE; - - ret = IDWriteFontFace5_IsSymbolFont(fontface); - IDWriteFontFace5_Release(fontface); - return ret; + return !!(font->data->flags & FONT_IS_SYMBOL); }
static HRESULT WINAPI dwritefont_GetFaceNames(IDWriteFont3 *iface, IDWriteLocalizedStrings **names) @@ -3695,6 +3681,7 @@ static HRESULT init_font_data(const struct fontface_desc *desc, IDWriteLocalized data->panose = props.panose; data->fontsig = props.fontsig; data->lf = props.lf; + data->flags = props.flags;
fontstrings_get_en_string(*family_name, familyW, ARRAY_SIZE(familyW)); fontstrings_get_en_string(data->names, faceW, ARRAY_SIZE(faceW)); @@ -4651,8 +4638,7 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li { struct file_stream_desc stream_desc; struct dwrite_fontface *fontface; - HRESULT hr = S_OK; - BOOL is_symbol; + HRESULT hr; int i;
*ret = NULL; @@ -4701,9 +4687,7 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li } }
- fontface->charmap = freetype_get_charmap_index(&fontface->IDWriteFontFace5_iface, &is_symbol); - if (is_symbol) - fontface->flags |= FONTFACE_IS_SYMBOL; + fontface->charmap = freetype_get_charmap_index(&fontface->IDWriteFontFace5_iface); if (freetype_has_kerning_pairs(&fontface->IDWriteFontFace5_iface)) fontface->flags |= FONTFACE_HAS_KERNING_PAIRS; if (freetype_is_monospaced(&fontface->IDWriteFontFace5_iface)) @@ -4717,15 +4701,19 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li
If face is created directly from factory we have to go through properties resolution. */ - if (desc->font_data) { + if (desc->font_data) + { fontface->weight = desc->font_data->weight; fontface->style = desc->font_data->style; fontface->stretch = desc->font_data->stretch; fontface->panose = desc->font_data->panose; fontface->fontsig = desc->font_data->fontsig; fontface->lf = desc->font_data->lf; + if (desc->font_data->flags & FONT_IS_SYMBOL) + fontface->flags |= FONT_IS_SYMBOL; } - else { + else + { IDWriteLocalizedStrings *names; struct dwrite_font_data *data;
@@ -4742,6 +4730,8 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li fontface->panose = data->panose; fontface->fontsig = data->fontsig; fontface->lf = data->lf; + if (data->flags & FONT_IS_SYMBOL) + fontface->flags |= FONT_IS_SYMBOL;
IDWriteLocalizedStrings_Release(names); release_font_data(data); diff --git a/dlls/dwrite/freetype.c b/dlls/dwrite/freetype.c index ffc97f1d8a..3c54da27f9 100644 --- a/dlls/dwrite/freetype.c +++ b/dlls/dwrite/freetype.c @@ -855,29 +855,19 @@ BOOL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap) return ret; }
-INT freetype_get_charmap_index(IDWriteFontFace5 *fontface, BOOL *is_symbol) +INT freetype_get_charmap_index(IDWriteFontFace5 *fontface) { INT charmap_index = -1; FT_Face face;
- *is_symbol = FALSE; - EnterCriticalSection(&freetype_cs); - if (pFTC_Manager_LookupFace(cache_manager, fontface, &face) == 0) { - TT_OS2 *os2 = pFT_Get_Sfnt_Table(face, ft_sfnt_os2); + if (pFTC_Manager_LookupFace(cache_manager, fontface, &face) == 0) + { FT_Int i;
- if (os2) { - FT_UInt dummy; - if (os2->version == 0) - *is_symbol = pFT_Get_First_Char(face, &dummy) >= 0x100; - else - *is_symbol = !!(os2->ulCodePageRange1 & FS_SYMBOL); - } - for (i = 0; i < face->num_charmaps; i++) - if (face->charmaps[i]->encoding == FT_ENCODING_MS_SYMBOL) { - *is_symbol = TRUE; + if (face->charmaps[i]->encoding == FT_ENCODING_MS_SYMBOL) + { charmap_index = i; break; } @@ -978,9 +968,8 @@ BOOL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap) return FALSE; }
-INT freetype_get_charmap_index(IDWriteFontFace5 *fontface, BOOL *is_symbol) +INT freetype_get_charmap_index(IDWriteFontFace5 *fontface) { - *is_symbol = FALSE; return -1; }
diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index c5f1d16fac..02a71b3528 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -44,6 +44,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(dwrite); #define MS_SBIX_TAG DWRITE_MAKE_OPENTYPE_TAG('s','b','i','x') #define MS_MAXP_TAG DWRITE_MAKE_OPENTYPE_TAG('m','a','x','p') #define MS_CBLC_TAG DWRITE_MAKE_OPENTYPE_TAG('C','B','L','C') +#define MS_CMAP_TAG DWRITE_MAKE_OPENTYPE_TAG('c','m','a','p')
/* 'sbix' formats */ #define MS_PNG__TAG DWRITE_MAKE_OPENTYPE_TAG('p','n','g',' ') @@ -131,6 +132,18 @@ enum OPENTYPE_CMAP_TABLE_FORMAT OPENTYPE_CMAP_TABLE_SEGMENTED_COVERAGE = 12 };
+enum opentype_cmap_table_platform +{ + OPENTYPE_CMAP_TABLE_PLATFORM_WIN = 3, +}; + +enum opentype_cmap_table_encoding +{ + OPENTYPE_CMAP_TABLE_ENCODING_SYMBOL = 0, + OPENTYPE_CMAP_TABLE_ENCODING_UNICODE_BMP = 1, + OPENTYPE_CMAP_TABLE_ENCODING_UNICODE_FULL = 10, +}; + /* PANOSE is 10 bytes in size, need to pack the structure properly */ #include "pshpack2.h" typedef struct @@ -1705,6 +1718,7 @@ void opentype_get_font_properties(struct file_stream_desc *stream_desc, struct d struct dwrite_fonttable os2, head; const TT_OS2_V2 *tt_os2; const TT_HEAD *tt_head; + BOOL is_symbol;
opentype_get_font_table(stream_desc, MS_OS2_TAG, &os2); opentype_get_font_table(stream_desc, MS_HEAD_TAG, &head); @@ -1721,7 +1735,8 @@ void opentype_get_font_properties(struct file_stream_desc *stream_desc, struct d memset(&props->lf, 0, sizeof(props->lf));
/* DWRITE_FONT_STRETCH enumeration values directly match font data values */ - if (tt_os2) { + if (tt_os2) + { USHORT version = GET_BE_WORD(tt_os2->version); USHORT fsSelection = GET_BE_WORD(tt_os2->fsSelection); USHORT usWeightClass = GET_BE_WORD(tt_os2->usWeightClass); @@ -1752,11 +1767,8 @@ void opentype_get_font_properties(struct file_stream_desc *stream_desc, struct d props->fontsig.fsUsb[2] = GET_BE_DWORD(tt_os2->ulUnicodeRange3); props->fontsig.fsUsb[3] = GET_BE_DWORD(tt_os2->ulUnicodeRange4);
- if (GET_BE_WORD(tt_os2->version) == 0) { - props->fontsig.fsCsb[0] = 0; - props->fontsig.fsCsb[1] = 0; - } - else { + if (version) + { props->fontsig.fsCsb[0] = GET_BE_DWORD(tt_os2->ulCodePageRange1); props->fontsig.fsCsb[1] = GET_BE_DWORD(tt_os2->ulCodePageRange2); } @@ -1780,6 +1792,37 @@ void opentype_get_font_properties(struct file_stream_desc *stream_desc, struct d
props->lf.lfWeight = props->weight;
+ if (!(is_symbol = props->panose.familyKind == DWRITE_PANOSE_FAMILY_SYMBOL)) + { + struct dwrite_fonttable cmap; + int i, offset, num_tables; + + opentype_get_font_table(stream_desc, MS_CMAP_TAG, &cmap); + + if (cmap.data) + { + num_tables = table_read_be_word(&cmap, FIELD_OFFSET(struct cmap_header, num_tables)); + offset = FIELD_OFFSET(struct cmap_header, tables); + + for (i = 0; !is_symbol && i < num_tables; ++i) + { + WORD platform, encoding; + + platform = table_read_be_word(&cmap, offset + i * sizeof(struct cmap_encoding_record) + + FIELD_OFFSET(struct cmap_encoding_record, platformID)); + encoding = table_read_be_word(&cmap, offset + i * sizeof(struct cmap_encoding_record) + + FIELD_OFFSET(struct cmap_encoding_record, encodingID)); + + is_symbol = platform == OPENTYPE_CMAP_TABLE_PLATFORM_WIN && + encoding == OPENTYPE_CMAP_TABLE_ENCODING_SYMBOL; + } + + IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, cmap.context); + } + } + if (is_symbol) + props->flags |= FONT_IS_SYMBOL; + TRACE("stretch=%d, weight=%d, style %d\n", props->stretch, props->weight, props->style);
if (os2.data) diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index d7bcfb1f0a..33603f6571 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -406,7 +406,7 @@ struct cmap_encoding_record struct cmap_header { WORD version; - WORD numTables; + WORD num_tables; struct cmap_encoding_record tables[1]; };
@@ -3544,7 +3544,7 @@ static UINT32 opentype_cmap_get_unicode_ranges(const struct dwrite_fonttable *ta
*ranges = NULL;
- num_tables = table_read_be_word(table, 0, FIELD_OFFSET(struct cmap_header, numTables)); + num_tables = table_read_be_word(table, 0, FIELD_OFFSET(struct cmap_header, num_tables)); tables = table->data + FIELD_OFFSET(struct cmap_header, tables);
for (i = 0; i < num_tables; ++i) @@ -7260,10 +7260,7 @@ static BOOL get_expected_is_symbol(IDWriteFontFace *fontface)
if (tt_os2) { - if (tt_os2->version) - is_symbol = !!(GET_BE_DWORD(tt_os2->ulCodePageRange1) & FS_SYMBOL); - if (!is_symbol) - is_symbol = tt_os2->panose.bFamilyType == PAN_FAMILY_PICTORIAL; + is_symbol = tt_os2->panose.bFamilyType == PAN_FAMILY_PICTORIAL; IDWriteFontFace_ReleaseFontTable(fontface, os2_context); }
@@ -7275,7 +7272,7 @@ static BOOL get_expected_is_symbol(IDWriteFontFace *fontface) if (FAILED(hr) || !exists) return is_symbol;
- num_tables = table_read_be_word(&cmap, 0, FIELD_OFFSET(struct cmap_header, numTables)); + num_tables = table_read_be_word(&cmap, 0, FIELD_OFFSET(struct cmap_header, num_tables)); tables = cmap.data + FIELD_OFFSET(struct cmap_header, tables);
for (i = 0; i < num_tables; ++i) @@ -7345,9 +7342,7 @@ static void test_IsSymbolFont(void) is_symbol_face = IDWriteFontFace_IsSymbolFont(fontface); ok(is_symbol_font == is_symbol_face, "Unexpected symbol flag.\n");
- /* FIXME: failures disabled on Wine for now */ is_symbol_expected = get_expected_is_symbol(fontface); - todo_wine_if(is_symbol_expected != is_symbol_face) ok(is_symbol_expected == is_symbol_face, "Unexpected is_symbol flag %d for %s, font %d.\n", is_symbol_face, wine_dbgstr_w(nameW), j);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=63644
Your paranoid android.
=== debian10 (32 bit report) ===
dwrite: font.c:1103: Test failed: got 1 font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Tahoma", font 0. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Tahoma", font 1. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Tahoma", font 2. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Tahoma", font 3. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Times New Roman", font 0. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Times New Roman", font 1. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Times New Roman", font 2. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Times New Roman", font 3. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Times New Roman", font 4. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Times New Roman", font 5. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Trebuchet MS", font 0. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Trebuchet MS", font 1. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Trebuchet MS", font 2. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Trebuchet MS", font 3. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Trebuchet MS", font 4. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Trebuchet MS", font 5. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Verdana", font 0. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Verdana", font 1. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Verdana", font 2. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Verdana", font 3. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Verdana", font 4. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Verdana", font 5.
=== debian10 (32 bit French report) ===
dwrite: font.c:1103: Test failed: got 1 font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Tahoma", font 0. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Tahoma", font 1. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Tahoma", font 2. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Tahoma", font 3. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Times New Roman", font 0. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Times New Roman", font 1. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Times New Roman", font 2. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Times New Roman", font 3. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Times New Roman", font 4. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Times New Roman", font 5. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Trebuchet MS", font 0. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Trebuchet MS", font 1. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Trebuchet MS", font 2. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Trebuchet MS", font 3. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Trebuchet MS", font 4. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Trebuchet MS", font 5. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Verdana", font 0. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Verdana", font 1. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Verdana", font 2. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Verdana", font 3. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Verdana", font 4. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Verdana", font 5.
=== debian10 (32 bit Japanese:Japan report) ===
dwrite: font.c:1103: Test failed: got 1 font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Tahoma", font 0. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Tahoma", font 1. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Tahoma", font 2. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Tahoma", font 3. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Times New Roman", font 0. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Times New Roman", font 1. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Times New Roman", font 2. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Times New Roman", font 3. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Times New Roman", font 4. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Times New Roman", font 5. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Trebuchet MS", font 0. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Trebuchet MS", font 1. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Trebuchet MS", font 2. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Trebuchet MS", font 3. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Trebuchet MS", font 4. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Trebuchet MS", font 5. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Verdana", font 0. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Verdana", font 1. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Verdana", font 2. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Verdana", font 3. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Verdana", font 4. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Verdana", font 5.
=== debian10 (32 bit Chinese:China report) ===
dwrite: font.c:1103: Test failed: got 1 font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Tahoma", font 0. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Tahoma", font 1. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Tahoma", font 2. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Tahoma", font 3. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Times New Roman", font 0. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Times New Roman", font 1. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Times New Roman", font 2. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Times New Roman", font 3. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Times New Roman", font 4. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Times New Roman", font 5. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Trebuchet MS", font 0. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Trebuchet MS", font 1. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Trebuchet MS", font 2. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Trebuchet MS", font 3. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Trebuchet MS", font 4. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Trebuchet MS", font 5. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Verdana", font 0. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Verdana", font 1. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Verdana", font 2. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Verdana", font 3. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Verdana", font 4. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Verdana", font 5.
=== debian10 (32 bit WoW report) ===
dwrite: font.c:1103: Test failed: got 1 font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Tahoma", font 0. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Tahoma", font 1. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Tahoma", font 2. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Tahoma", font 3. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Times New Roman", font 0. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Times New Roman", font 1. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Times New Roman", font 2. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Times New Roman", font 3. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Times New Roman", font 4. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Times New Roman", font 5. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Trebuchet MS", font 0. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Trebuchet MS", font 1. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Trebuchet MS", font 2. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Trebuchet MS", font 3. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Trebuchet MS", font 4. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Trebuchet MS", font 5. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Verdana", font 0. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Verdana", font 1. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Verdana", font 2. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Verdana", font 3. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Verdana", font 4. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Verdana", font 5.
=== debian10 (64 bit WoW report) ===
dwrite: font.c:1103: Test failed: got 1 font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Tahoma", font 0. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Tahoma", font 1. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Tahoma", font 2. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Tahoma", font 3. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Times New Roman", font 0. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Times New Roman", font 1. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Times New Roman", font 2. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Times New Roman", font 3. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Times New Roman", font 4. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Times New Roman", font 5. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Trebuchet MS", font 0. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Trebuchet MS", font 1. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Trebuchet MS", font 2. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Trebuchet MS", font 3. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Trebuchet MS", font 4. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Trebuchet MS", font 5. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Verdana", font 0. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Verdana", font 1. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Verdana", font 2. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Verdana", font 3. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Verdana", font 4. font.c:7346: Test failed: Unexpected is_symbol flag 1 for L"Verdana", font 5.
Where these fonts are coming from? I'd expect at least Wine Tahoma to be used with wine. I tried adding Verdana too just in case, and it didn't fail for me.
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/dwrite_private.h | 3 +-- dlls/dwrite/font.c | 21 ++++----------------- dlls/dwrite/freetype.c | 18 ------------------ dlls/dwrite/opentype.c | 19 ++++++++++++++++++- dlls/dwrite/tests/font.c | 2 -- 5 files changed, 23 insertions(+), 40 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 76cf40cd1f..0705d43b1f 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -186,7 +186,7 @@ struct fontfacecached enum font_flags { FONT_IS_SYMBOL = 1 << 0, - FONTFACE_IS_MONOSPACED = 1 << 1, + FONT_IS_MONOSPACED = 1 << 1, FONTFACE_HAS_KERNING_PAIRS = 1 << 2, FONTFACE_HAS_VERTICAL_VARIANTS = 1 << 3 }; @@ -391,7 +391,6 @@ extern void release_freetype(void) DECLSPEC_HIDDEN; extern HRESULT freetype_get_design_glyph_metrics(struct dwrite_fontface *fontface, UINT16 glyph, DWRITE_GLYPH_METRICS *metrics) DECLSPEC_HIDDEN; extern void freetype_notify_cacheremove(IDWriteFontFace5 *fontface) DECLSPEC_HIDDEN; -extern BOOL freetype_is_monospaced(IDWriteFontFace5 *fontface) DECLSPEC_HIDDEN; extern HRESULT freetype_get_glyphrun_outline(IDWriteFontFace5 *fontface, float emsize, UINT16 const *glyphs, float const *advances, DWRITE_GLYPH_OFFSET const *offsets, unsigned int count, BOOL is_rtl, IDWriteGeometrySink *sink) DECLSPEC_HIDDEN; diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index f2b8655003..c1c9ce20fa 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -955,7 +955,7 @@ static BOOL WINAPI dwritefontface1_IsMonospacedFont(IDWriteFontFace5 *iface)
TRACE("%p.\n", iface);
- return !!(fontface->flags & FONTFACE_IS_MONOSPACED); + return !!(fontface->flags & FONT_IS_MONOSPACED); }
static int fontface_get_design_advance(struct dwrite_fontface *fontface, DWRITE_MEASURING_MODE measuring_mode, @@ -1765,19 +1765,10 @@ static HRESULT WINAPI dwritefont1_GetUnicodeRanges(IDWriteFont3 *iface, UINT32 m static BOOL WINAPI dwritefont1_IsMonospacedFont(IDWriteFont3 *iface) { struct dwrite_font *font = impl_from_IDWriteFont3(iface); - IDWriteFontFace5 *fontface; - HRESULT hr; - BOOL ret;
TRACE("%p.\n", iface);
- hr = get_fontface_from_font(font, &fontface); - if (FAILED(hr)) - return FALSE; - - ret = IDWriteFontFace5_IsMonospacedFont(fontface); - IDWriteFontFace5_Release(fontface); - return ret; + return !!(font->data->flags & FONT_IS_MONOSPACED); }
static BOOL WINAPI dwritefont2_IsColorFont(IDWriteFont3 *iface) @@ -4690,8 +4681,6 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li fontface->charmap = freetype_get_charmap_index(&fontface->IDWriteFontFace5_iface); if (freetype_has_kerning_pairs(&fontface->IDWriteFontFace5_iface)) fontface->flags |= FONTFACE_HAS_KERNING_PAIRS; - if (freetype_is_monospaced(&fontface->IDWriteFontFace5_iface)) - fontface->flags |= FONTFACE_IS_MONOSPACED; if (opentype_has_vertical_variants(&fontface->IDWriteFontFace5_iface)) fontface->flags |= FONTFACE_HAS_VERTICAL_VARIANTS; fontface->glyph_image_formats = opentype_get_glyph_image_formats(&fontface->IDWriteFontFace5_iface); @@ -4709,8 +4698,7 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li fontface->panose = desc->font_data->panose; fontface->fontsig = desc->font_data->fontsig; fontface->lf = desc->font_data->lf; - if (desc->font_data->flags & FONT_IS_SYMBOL) - fontface->flags |= FONT_IS_SYMBOL; + fontface->flags |= desc->font_data->flags & (FONT_IS_SYMBOL | FONT_IS_MONOSPACED); } else { @@ -4730,8 +4718,7 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li fontface->panose = data->panose; fontface->fontsig = data->fontsig; fontface->lf = data->lf; - if (data->flags & FONT_IS_SYMBOL) - fontface->flags |= FONT_IS_SYMBOL; + fontface->flags |= data->flags & (FONT_IS_SYMBOL | FONT_IS_MONOSPACED);
IDWriteLocalizedStrings_Release(names); release_font_data(data); diff --git a/dlls/dwrite/freetype.c b/dlls/dwrite/freetype.c index 3c54da27f9..86c8315e6a 100644 --- a/dlls/dwrite/freetype.c +++ b/dlls/dwrite/freetype.c @@ -303,19 +303,6 @@ HRESULT freetype_get_design_glyph_metrics(struct dwrite_fontface *fontface, UINT return S_OK; }
-BOOL freetype_is_monospaced(IDWriteFontFace5 *fontface) -{ - BOOL is_monospaced = FALSE; - FT_Face face; - - EnterCriticalSection(&freetype_cs); - if (pFTC_Manager_LookupFace(cache_manager, fontface, &face) == 0) - is_monospaced = !!FT_IS_FIXED_WIDTH(face); - LeaveCriticalSection(&freetype_cs); - - return is_monospaced; -} - struct decompose_context { IDWriteGeometrySink *sink; D2D1_POINT_2F offset; @@ -925,11 +912,6 @@ HRESULT freetype_get_design_glyph_metrics(struct dwrite_fontface *fontface, UINT return E_NOTIMPL; }
-BOOL freetype_is_monospaced(IDWriteFontFace5 *fontface) -{ - return FALSE; -} - HRESULT freetype_get_glyphrun_outline(IDWriteFontFace5 *fontface, float emSize, UINT16 const *glyphs, float const *advances, DWRITE_GLYPH_OFFSET const *offsets, unsigned int count, BOOL is_rtl, IDWriteGeometrySink *sink) diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index 02a71b3528..5f41a5764b 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -1716,9 +1716,9 @@ void opentype_get_font_metrics(struct file_stream_desc *stream_desc, DWRITE_FONT void opentype_get_font_properties(struct file_stream_desc *stream_desc, struct dwrite_font_props *props) { struct dwrite_fonttable os2, head; + BOOL is_symbol, is_monospaced; const TT_OS2_V2 *tt_os2; const TT_HEAD *tt_head; - BOOL is_symbol;
opentype_get_font_table(stream_desc, MS_OS2_TAG, &os2); opentype_get_font_table(stream_desc, MS_HEAD_TAG, &head); @@ -1733,6 +1733,7 @@ void opentype_get_font_properties(struct file_stream_desc *stream_desc, struct d memset(&props->panose, 0, sizeof(props->panose)); memset(&props->fontsig, 0, sizeof(props->fontsig)); memset(&props->lf, 0, sizeof(props->lf)); + props->flags = 0;
/* DWRITE_FONT_STRETCH enumeration values directly match font data values */ if (tt_os2) @@ -1823,6 +1824,22 @@ void opentype_get_font_properties(struct file_stream_desc *stream_desc, struct d if (is_symbol) props->flags |= FONT_IS_SYMBOL;
+ if (!(is_monospaced = props->panose.text.proportion == DWRITE_PANOSE_PROPORTION_MONOSPACED)) + { + struct dwrite_fonttable post; + + opentype_get_font_table(stream_desc, MS_POST_TAG, &post); + + if (post.data) + { + is_monospaced = !!table_read_dword(&post, FIELD_OFFSET(TT_POST, fixed_pitch)); + + IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, post.context); + } + } + if (is_monospaced) + props->flags |= FONT_IS_MONOSPACED; + TRACE("stretch=%d, weight=%d, style %d\n", props->stretch, props->weight, props->style);
if (os2.data) diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index 33603f6571..ac70a4c137 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -4990,9 +4990,7 @@ static void test_IsMonospacedFont(void)
IDWriteFont1_GetPanose(font1, &panose);
- /* FIXME: failures disabled on Wine for now */ is_monospaced_expected = get_expected_is_monospaced(fontface1, &panose); - todo_wine_if(is_monospaced_expected != is_monospaced_face) ok(is_monospaced_expected == is_monospaced_face, "Unexpected is_monospaced flag %d for %s, font %d.\n", is_monospaced_face, wine_dbgstr_w(nameW), j);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/dwrite_private.h | 5 +++-- dlls/dwrite/font.c | 22 ++++------------------ dlls/dwrite/opentype.c | 19 ++++++++++++++++++- 3 files changed, 25 insertions(+), 21 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 0705d43b1f..cf3f13b1c6 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -187,8 +187,9 @@ enum font_flags { FONT_IS_SYMBOL = 1 << 0, FONT_IS_MONOSPACED = 1 << 1, - FONTFACE_HAS_KERNING_PAIRS = 1 << 2, - FONTFACE_HAS_VERTICAL_VARIANTS = 1 << 3 + FONT_IS_COLORED = 1 << 2, /* CPAL/COLR support */ + FONTFACE_HAS_KERNING_PAIRS = 1 << 3, + FONTFACE_HAS_VERTICAL_VARIANTS = 1 << 4 };
struct dwrite_fontface diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index c1c9ce20fa..4e08b2f632 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -418,11 +418,6 @@ static const struct dwrite_fonttable *get_fontface_cpal(struct dwrite_fontface * return &fontface->cpal; }
-static const void* get_fontface_colr(struct dwrite_fontface *fontface) -{ - return get_fontface_table(&fontface->IDWriteFontFace5_iface, MS_COLR_TAG, &fontface->colr); -} - static void addref_font_data(struct dwrite_font_data *data) { InterlockedIncrement(&data->ref); @@ -1121,7 +1116,7 @@ static BOOL WINAPI dwritefontface2_IsColorFont(IDWriteFontFace5 *iface)
TRACE("%p.\n", iface);
- return get_fontface_cpal(fontface) && get_fontface_colr(fontface); + return !!(fontface->flags & FONT_IS_COLORED); }
static UINT32 WINAPI dwritefontface2_GetColorPaletteCount(IDWriteFontFace5 *iface) @@ -1774,19 +1769,10 @@ static BOOL WINAPI dwritefont1_IsMonospacedFont(IDWriteFont3 *iface) static BOOL WINAPI dwritefont2_IsColorFont(IDWriteFont3 *iface) { struct dwrite_font *font = impl_from_IDWriteFont3(iface); - IDWriteFontFace5 *fontface; - HRESULT hr; - BOOL ret;
TRACE("%p.\n", iface);
- hr = get_fontface_from_font(font, &fontface); - if (FAILED(hr)) - return FALSE; - - ret = IDWriteFontFace5_IsColorFont(fontface); - IDWriteFontFace5_Release(fontface); - return ret; + return !!(font->data->flags & FONT_IS_COLORED); }
static HRESULT WINAPI dwritefont3_CreateFontFace(IDWriteFont3 *iface, IDWriteFontFace3 **fontface) @@ -4698,7 +4684,7 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li fontface->panose = desc->font_data->panose; fontface->fontsig = desc->font_data->fontsig; fontface->lf = desc->font_data->lf; - fontface->flags |= desc->font_data->flags & (FONT_IS_SYMBOL | FONT_IS_MONOSPACED); + fontface->flags |= desc->font_data->flags & (FONT_IS_SYMBOL | FONT_IS_MONOSPACED | FONT_IS_COLORED); } else { @@ -4718,7 +4704,7 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li fontface->panose = data->panose; fontface->fontsig = data->fontsig; fontface->lf = data->lf; - fontface->flags |= data->flags & (FONT_IS_SYMBOL | FONT_IS_MONOSPACED); + fontface->flags |= data->flags & (FONT_IS_SYMBOL | FONT_IS_MONOSPACED | FONT_IS_COLORED);
IDWriteLocalizedStrings_Release(names); release_font_data(data); diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index 5f41a5764b..86716f615d 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -39,6 +39,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(dwrite); #define MS_GLYF_TAG DWRITE_MAKE_OPENTYPE_TAG('g','l','y','f') #define MS_CFF__TAG DWRITE_MAKE_OPENTYPE_TAG('C','F','F',' ') #define MS_CFF2_TAG DWRITE_MAKE_OPENTYPE_TAG('C','F','F','2') +#define MS_CPAL_TAG DWRITE_MAKE_OPENTYPE_TAG('C','P','A','L') #define MS_COLR_TAG DWRITE_MAKE_OPENTYPE_TAG('C','O','L','R') #define MS_SVG__TAG DWRITE_MAKE_OPENTYPE_TAG('S','V','G',' ') #define MS_SBIX_TAG DWRITE_MAKE_OPENTYPE_TAG('s','b','i','x') @@ -1715,7 +1716,7 @@ void opentype_get_font_metrics(struct file_stream_desc *stream_desc, DWRITE_FONT
void opentype_get_font_properties(struct file_stream_desc *stream_desc, struct dwrite_font_props *props) { - struct dwrite_fonttable os2, head; + struct dwrite_fonttable os2, head, colr, cpal; BOOL is_symbol, is_monospaced; const TT_OS2_V2 *tt_os2; const TT_HEAD *tt_head; @@ -1793,6 +1794,7 @@ void opentype_get_font_properties(struct file_stream_desc *stream_desc, struct d
props->lf.lfWeight = props->weight;
+ /* FONT_IS_SYMBOL */ if (!(is_symbol = props->panose.familyKind == DWRITE_PANOSE_FAMILY_SYMBOL)) { struct dwrite_fonttable cmap; @@ -1824,6 +1826,7 @@ void opentype_get_font_properties(struct file_stream_desc *stream_desc, struct d if (is_symbol) props->flags |= FONT_IS_SYMBOL;
+ /* FONT_IS_MONOSPACED */ if (!(is_monospaced = props->panose.text.proportion == DWRITE_PANOSE_PROPORTION_MONOSPACED)) { struct dwrite_fonttable post; @@ -1840,6 +1843,20 @@ void opentype_get_font_properties(struct file_stream_desc *stream_desc, struct d if (is_monospaced) props->flags |= FONT_IS_MONOSPACED;
+ /* FONT_IS_COLORED */ + opentype_get_font_table(stream_desc, MS_COLR_TAG, &colr); + if (colr.data) + { + opentype_get_font_table(stream_desc, MS_CPAL_TAG, &cpal); + if (cpal.data) + { + props->flags |= FONT_IS_COLORED; + IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, cpal.context); + } + + IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, colr.context); + } + TRACE("stretch=%d, weight=%d, style %d\n", props->stretch, props->weight, props->style);
if (os2.data)
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/opentype.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index 86716f615d..db277ae905 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -1089,8 +1089,8 @@ enum OPENTYPE_STRING_ID OPENTYPE_STRING_LICENSE_DESCRIPTION, OPENTYPE_STRING_LICENSE_INFO_URL, OPENTYPE_STRING_RESERVED_ID15, - OPENTYPE_STRING_PREFERRED_FAMILY_NAME, - OPENTYPE_STRING_PREFERRED_SUBFAMILY_NAME, + OPENTYPE_STRING_TYPOGRAPHIC_FAMILY_NAME, + OPENTYPE_STRING_TYPOGRAPHIC_SUBFAMILY_NAME, OPENTYPE_STRING_COMPATIBLE_FULLNAME, OPENTYPE_STRING_SAMPLE_TEXT, OPENTYPE_STRING_POSTSCRIPT_CID_NAME, @@ -1113,8 +1113,8 @@ static const UINT16 dwriteid_to_opentypeid[DWRITE_INFORMATIONAL_STRING_POSTSCRIP OPENTYPE_STRING_LICENSE_INFO_URL, OPENTYPE_STRING_FAMILY_NAME, OPENTYPE_STRING_SUBFAMILY_NAME, - OPENTYPE_STRING_PREFERRED_FAMILY_NAME, - OPENTYPE_STRING_PREFERRED_SUBFAMILY_NAME, + OPENTYPE_STRING_TYPOGRAPHIC_FAMILY_NAME, + OPENTYPE_STRING_TYPOGRAPHIC_SUBFAMILY_NAME, OPENTYPE_STRING_SAMPLE_TEXT, OPENTYPE_STRING_FULL_FONTNAME, OPENTYPE_STRING_POSTSCRIPT_FONTNAME, @@ -2138,7 +2138,7 @@ HRESULT opentype_get_font_familyname(struct file_stream_desc *stream_desc, IDWri hr = E_FAIL;
if (FAILED(hr)) - hr = opentype_get_font_strings_from_id(name_table, OPENTYPE_STRING_PREFERRED_FAMILY_NAME, names); + hr = opentype_get_font_strings_from_id(name_table, OPENTYPE_STRING_TYPOGRAPHIC_FAMILY_NAME, names); if (FAILED(hr)) hr = opentype_get_font_strings_from_id(name_table, OPENTYPE_STRING_FAMILY_NAME, names);
@@ -2175,7 +2175,7 @@ HRESULT opentype_get_font_facename(struct file_stream_desc *stream_desc, WCHAR * hr = E_FAIL;
if (FAILED(hr)) - hr = opentype_get_font_strings_from_id(name_table, OPENTYPE_STRING_PREFERRED_SUBFAMILY_NAME, names); + hr = opentype_get_font_strings_from_id(name_table, OPENTYPE_STRING_TYPOGRAPHIC_SUBFAMILY_NAME, names); if (FAILED(hr)) hr = opentype_get_font_strings_from_id(name_table, OPENTYPE_STRING_SUBFAMILY_NAME, names);