dwrite: Evaluate IsSymbolFont() flag at font level.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
107599531a
commit
0b0a2ce8fd
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue