[PATCH 2/5] dwrite: Evaluate IsSymbolFont() flag at font level.
Nikolay Sivov
nsivov at codeweavers.com
Thu Jan 23 03:24:12 CST 2020
Signed-off-by: Nikolay Sivov <nsivov at 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);
--
2.24.1
More information about the wine-devel
mailing list