Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/dwrite_private.h | 2 ++ dlls/dwrite/opentype.c | 12 ++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 3d7884cb57f..0bb5455a677 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -543,6 +543,8 @@ struct scriptshaping_context
unsigned int cur; unsigned int glyph_count; + unsigned int nesting_level_left; + float emsize; DWRITE_MEASURING_MODE measuring_mode; float *advances; diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index 8853f3a4244..22ae1069240 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -67,6 +67,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(dwrite); #define GET_BE_DWORD(x) RtlUlongByteSwap(x) #endif
+#define GLYPH_CONTEXT_MAX_LENGTH 64 +#define SHAPE_MAX_NESTING_LEVEL 6 + typedef struct { CHAR TTCTag[4]; DWORD Version; @@ -4616,6 +4619,7 @@ void opentype_layout_apply_gpos_features(struct scriptshaping_context *context, unsigned int i; BOOL ret;
+ context->nesting_level_left = SHAPE_MAX_NESTING_LEVEL; context->u.buffer.apply_context_lookup = opentype_layout_apply_gpos_context_lookup; opentype_layout_collect_lookups(context, script_index, language_index, features, &context->cache->gpos, &lookups);
@@ -4993,8 +4997,6 @@ static BOOL opentype_layout_apply_gsub_lig_substitution(struct scriptshaping_con return FALSE; }
-#define GLYPH_CONTEXT_MAX_LENGTH 64 - static BOOL opentype_layout_context_match_input(const struct match_context *mc, unsigned int count, const UINT16 *input, unsigned int *end_offset, unsigned int *match_positions) { @@ -5081,6 +5083,9 @@ static BOOL opentype_layout_context_apply_lookup(struct scriptshaping_context *c unsigned int i, j; int end, delta;
+ if (!context->nesting_level_left) + return TRUE; + end = context->cur + match_length;
for (i = 0; i < lookup_count; ++i) @@ -5097,7 +5102,9 @@ static BOOL opentype_layout_context_apply_lookup(struct scriptshaping_context *c
lookup_index = GET_BE_WORD(lookup_records[i+1]);
+ --context->nesting_level_left; context->u.buffer.apply_context_lookup(context, lookup_index); + ++context->nesting_level_left;
delta = context->glyph_count - orig_len; if (!delta) @@ -5692,6 +5699,7 @@ void opentype_layout_apply_gsub_features(struct scriptshaping_context *context, unsigned int i; BOOL ret;
+ context->nesting_level_left = SHAPE_MAX_NESTING_LEVEL; context->u.buffer.apply_context_lookup = opentype_layout_apply_gsub_context_lookup; opentype_layout_collect_lookups(context, script_index, language_index, features, context->table, &lookups);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/opentype.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index 22ae1069240..e502be1e12b 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -5482,6 +5482,9 @@ static BOOL opentype_layout_apply_gsub_reverse_chain_context_substitution(struct unsigned int offset = subtable_offset; UINT16 glyph, format;
+ if (context->nesting_level_left != SHAPE_MAX_NESTING_LEVEL) + return FALSE; + glyph = context->u.subst.glyphs[context->cur];
format = table_read_be_word(table, offset);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/dwrite_private.h | 41 ++++++ dlls/dwrite/font.c | 41 ++---- dlls/dwrite/opentype.c | 257 +++++++++++++++++++++++++++++++++++ 3 files changed, 313 insertions(+), 26 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 0bb5455a677..2d736fdec3c 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -195,6 +195,47 @@ enum font_flags FONTFACE_HAS_VERTICAL_VARIANTS = 1 << 4 };
+struct dwrite_cmap; + +typedef UINT16 (*p_cmap_get_glyph_func)(const struct dwrite_cmap *cmap, unsigned int ch); + +struct dwrite_cmap +{ + const void *data; + union + { + struct + { + unsigned int seg_count; + unsigned int glyph_id_array_len; + + const UINT16 *ends; + const UINT16 *starts; + const UINT16 *id_delta; + const UINT16 *id_range_offset; + const UINT16 *glyph_id_array; + } format4; + struct + { + unsigned int first; + unsigned int last; + } format6_10; + struct + { + unsigned int group_count; + } format12_13; + } u; + p_cmap_get_glyph_func get_glyph; + unsigned short symbol : 1; + IDWriteFontFileStream *stream; + void *table_context; +}; + +extern void dwrite_cmap_init(struct dwrite_cmap *cmap, IDWriteFontFile *file, unsigned int face_index, + DWRITE_FONT_FACE_TYPE face_type) DECLSPEC_HIDDEN; +extern void dwrite_cmap_release(struct dwrite_cmap *cmap) DECLSPEC_HIDDEN; +extern UINT16 opentype_cmap_get_glyph(const struct dwrite_cmap *cmap, unsigned int ch) DECLSPEC_HIDDEN; + struct dwrite_fontface { IDWriteFontFace5 IDWriteFontFace5_iface; diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 75d2593e07e..dbb44327f26 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -80,6 +80,7 @@ struct dwrite_font_data FONTSIGNATURE fontsig; UINT32 flags; /* enum font_flags */ struct dwrite_font_propvec propvec; + struct dwrite_cmap cmap; /* Static axis for weight/width/italic. */ DWRITE_FONT_AXIS_VALUE axis[3];
@@ -469,6 +470,7 @@ static void release_font_data(struct dwrite_font_data *data) if (data->family_names) IDWriteLocalizedStrings_Release(data->family_names);
+ dwrite_cmap_release(&data->cmap); IDWriteFontFile_Release(data->file); heap_free(data->facename); heap_free(data); @@ -1958,35 +1960,23 @@ static void WINAPI dwritefont_GetMetrics(IDWriteFont3 *iface, DWRITE_FONT_METRIC memcpy(metrics, &This->data->metrics, sizeof(*metrics)); }
-static HRESULT font_has_character(struct dwrite_font *font, UINT32 ch, BOOL *exists) +static BOOL dwritefont_has_character(struct dwrite_font *font, UINT32 ch) { - IDWriteFontFace5 *fontface; - UINT16 index; - HRESULT hr; - - *exists = FALSE; - - hr = get_fontface_from_font(font, &fontface); - if (FAILED(hr)) - return hr; - - index = 0; - hr = IDWriteFontFace5_GetGlyphIndices(fontface, &ch, 1, &index); - IDWriteFontFace5_Release(fontface); - if (FAILED(hr)) - return hr; - - *exists = index != 0; - return S_OK; + UINT16 glyph; + dwrite_cmap_init(&font->data->cmap, font->data->file, font->data->face_index, font->data->face_type); + glyph = opentype_cmap_get_glyph(&font->data->cmap, ch); + return glyph != 0; }
static HRESULT WINAPI dwritefont_HasCharacter(IDWriteFont3 *iface, UINT32 ch, BOOL *exists) { - struct dwrite_font *This = impl_from_IDWriteFont3(iface); + struct dwrite_font *font = impl_from_IDWriteFont3(iface); + + TRACE("%p, %#x, %p.\n", iface, ch, exists);
- TRACE("(%p)->(%#x %p)\n", This, ch, exists); + *exists = dwritefont_has_character(font, ch);
- return font_has_character(This, ch, exists); + return S_OK; }
static HRESULT WINAPI dwritefont_CreateFontFace(IDWriteFont3 *iface, IDWriteFontFace **fontface) @@ -2088,12 +2078,11 @@ static HRESULT WINAPI dwritefont3_GetFontFaceReference(IDWriteFont3 *iface, IDWr
static BOOL WINAPI dwritefont3_HasCharacter(IDWriteFont3 *iface, UINT32 ch) { - struct dwrite_font *This = impl_from_IDWriteFont3(iface); - BOOL ret; + struct dwrite_font *font = impl_from_IDWriteFont3(iface);
- TRACE("(%p)->(%#x)\n", This, ch); + TRACE("%p, %#x.\n", iface, ch);
- return font_has_character(This, ch, &ret) == S_OK && ret; + return dwritefont_has_character(font, ch); }
static DWRITE_LOCALITY WINAPI dwritefont3_GetLocality(IDWriteFont3 *iface) diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index e502be1e12b..8e507158579 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -1565,6 +1565,263 @@ static HRESULT opentype_get_font_table(const struct file_stream_desc *stream_des * CMAP **********/
+static UINT16 opentype_cmap_format0_get_glyph(const struct dwrite_cmap *cmap, unsigned int ch) +{ + const UINT8 *glyphs = cmap->data; + return (ch < 0xff) ? glyphs[ch] : 0; +} + +struct cmap_format4_compare_context +{ + const struct dwrite_cmap *cmap; + unsigned int ch; +}; + +static int cmap_format4_compare_range(const void *a, const void *b) +{ + const struct cmap_format4_compare_context *key = a; + const UINT16 *end = b; + unsigned int idx; + + if (key->ch > GET_BE_WORD(*end)) + return 1; + + idx = end - key->cmap->u.format4.ends; + if (key->ch < GET_BE_WORD(key->cmap->u.format4.starts[idx])) + return -1; + + return 0; +} + +static UINT16 opentype_cmap_format4_get_glyph(const struct dwrite_cmap *cmap, unsigned int ch) +{ + struct cmap_format4_compare_context key = { .cmap = cmap, .ch = ch }; + unsigned int glyph, idx, range_offset; + const UINT16 *end_found; + + /* Look up range. */ + end_found = bsearch(&key, cmap->u.format4.ends, cmap->u.format4.seg_count, sizeof(*cmap->u.format4.ends), + cmap_format4_compare_range); + if (!end_found) + return 0; + + idx = end_found - cmap->u.format4.ends; + + range_offset = GET_BE_WORD(cmap->u.format4.id_range_offset[idx]); + + if (!range_offset) + { + glyph = ch + GET_BE_WORD(cmap->u.format4.id_delta[idx]); + } + else + { + unsigned int index = range_offset / 2 + (ch - GET_BE_WORD(cmap->u.format4.starts[idx])) + idx - cmap->u.format4.seg_count; + if (index >= cmap->u.format4.glyph_id_array_len) + return 0; + glyph = GET_BE_WORD(cmap->u.format4.glyph_id_array[index]); + if (!glyph) + return 0; + glyph += GET_BE_WORD(cmap->u.format4.id_delta[idx]); + } + + return glyph & 0xffff; +} + +static UINT16 opentype_cmap_format6_10_get_glyph(const struct dwrite_cmap *cmap, unsigned int ch) +{ + const UINT16 *glyphs = cmap->data; + if (ch < cmap->u.format6_10.first || ch > cmap->u.format6_10.last) return 0; + return glyphs[ch - cmap->u.format6_10.first]; +} + +static int cmap_format12_13_compare_group(const void *a, const void *b) +{ + const unsigned int *ch = a; + const UINT32 *group = b; + + if (*ch > GET_BE_DWORD(group[1])) + return 1; + + if (*ch < GET_BE_DWORD(group[0])) + return -1; + + return 0; +} + +static UINT16 opentype_cmap_format12_get_glyph(const struct dwrite_cmap *cmap, unsigned int ch) +{ + const UINT32 *groups = cmap->data; + const UINT32 *group_found; + + if (!(group_found = bsearch(&ch, groups, cmap->u.format12_13.group_count, 3 * sizeof(*groups), + cmap_format12_13_compare_group))) + return 0; + + return GET_BE_DWORD(group_found[0]) <= GET_BE_DWORD(group_found[1]) ? + GET_BE_DWORD(group_found[2]) + (ch - GET_BE_DWORD(group_found[0])) : 0; +} + +static UINT16 opentype_cmap_format13_get_glyph(const struct dwrite_cmap *cmap, unsigned int ch) +{ + const UINT32 *groups = cmap->data; + const UINT32 *group_found; + + if (!(group_found = bsearch(&ch, groups, cmap->u.format12_13.group_count, 3 * sizeof(*groups), + cmap_format12_13_compare_group))) + return 0; + + return GET_BE_DWORD(group_found[2]); +} + +static UINT16 opentype_cmap_dummy_get_glyph(const struct dwrite_cmap *cmap, unsigned int ch) +{ + return 0; +} + +UINT16 opentype_cmap_get_glyph(const struct dwrite_cmap *cmap, unsigned int ch) +{ + UINT16 glyph; + + if (!cmap->get_glyph) return 0; + glyph = cmap->get_glyph(cmap, ch); + if (!glyph && cmap->symbol && ch <= 0xff) + glyph = cmap->get_glyph(cmap, ch + 0xf000); + return glyph; +} + +static int cmap_header_compare(const void *a, const void *b) +{ + const UINT16 *key = a; + const UINT16 *record = b; + + /* Platform. */ + if (key[0] < GET_BE_WORD(record[0])) return -1; + if (key[0] > GET_BE_WORD(record[0])) return 1; + /* Encoding. */ + if (key[1] < GET_BE_WORD(record[1])) return -1; + if (key[1] > GET_BE_WORD(record[1])) return 1; + + return 0; +} + +void dwrite_cmap_init(struct dwrite_cmap *cmap, IDWriteFontFile *file, unsigned int face_index, + DWRITE_FONT_FACE_TYPE face_type) +{ + static const UINT16 encodings[][2] = + { + { 3, 0 }, /* MS Symbol encoding is preferred. */ + { 3, 10 }, + { 0, 6 }, + { 0, 4 }, + { 3, 1 }, + { 0, 3 }, + { 0, 2 }, + { 0, 1 }, + { 0, 0 }, + }; + const struct cmap_encoding_record *records, *found_record = NULL; + unsigned int length, offset, format, count, f, i, num_records; + struct file_stream_desc stream_desc; + struct dwrite_fonttable table; + const UINT16 *pair = NULL; + HRESULT hr; + + if (cmap->data) return; + + if (FAILED(hr = get_filestream_from_file(file, &stream_desc.stream))) + { + WARN("Failed to get file stream, hr %#x.\n", hr); + goto failed; + } + + stream_desc.face_type = face_type; + stream_desc.face_index = face_index; + + opentype_get_font_table(&stream_desc, MS_CMAP_TAG, &table); + if (!table.exists) + goto failed; + cmap->table_context = table.context; + + num_records = table_read_be_word(&table, 2); + records = table_read_ensure(&table, 4, sizeof(*records) * num_records); + + for (i = 0; i < ARRAY_SIZE(encodings); ++i) + { + pair = encodings[i]; + if ((found_record = bsearch(pair, records, num_records, sizeof(*records), cmap_header_compare))) + break; + } + + if (!found_record) + { + WARN("No suitable cmap table were found.\n"); + goto failed; + } + + /* Symbol encoding. */ + cmap->symbol = pair[0] == 3 && pair[1] == 0; + offset = GET_BE_DWORD(found_record->offset); + + format = table_read_be_word(&table, offset); + + switch (format) + { + case 0: + cmap->data = table_read_ensure(&table, offset + 6, 256); + cmap->get_glyph = opentype_cmap_format0_get_glyph; + break; + case 4: + length = table_read_be_word(&table, offset + 2); + cmap->u.format4.seg_count = count = table_read_be_word(&table, offset + 6) / 2; + cmap->u.format4.ends = table_read_ensure(&table, offset + 14, count * 2); + cmap->u.format4.starts = cmap->u.format4.ends + count + 1; + cmap->u.format4.id_delta = cmap->u.format4.starts + count; + cmap->u.format4.id_range_offset = cmap->u.format4.id_delta + count; + cmap->u.format4.glyph_id_array = cmap->data = cmap->u.format4.id_range_offset + count; + cmap->u.format4.glyph_id_array_len = (length - 16 - 8 * count) / 2; + cmap->get_glyph = opentype_cmap_format4_get_glyph; + break; + case 6: + case 10: + /* Format 10 uses 4 byte fields. */ + f = format == 6 ? 1 : 2; + cmap->u.format6_10.first = table_read_be_word(&table, offset + f * 6); + count = table_read_be_word(&table, offset + f * 8); + cmap->u.format6_10.last = cmap->u.format6_10.first + count; + cmap->data = table_read_ensure(&table, offset + f * 10, count * 2); + cmap->get_glyph = opentype_cmap_format6_10_get_glyph; + break; + case 12: + case 13: + cmap->u.format12_13.group_count = count = table_read_be_dword(&table, offset + 12); + cmap->data = table_read_ensure(&table, offset + 16, count * 3 * 4); + cmap->get_glyph = format == 12 ? opentype_cmap_format12_get_glyph : opentype_cmap_format13_get_glyph; + break; + default: + WARN("Unhandled subtable format %u.\n", format); + } + +failed: + + if (!cmap->data) + { + /* Dummy implementation, returns 0 unconditionally. */ + cmap->data = cmap; + cmap->get_glyph = opentype_cmap_dummy_get_glyph; + } +} + +void dwrite_cmap_release(struct dwrite_cmap *cmap) +{ + if (cmap->stream) + { + IDWriteFontFileStream_ReleaseFileFragment(cmap->stream, cmap->table_context); + IDWriteFontFileStream_Release(cmap->stream); + } + cmap->data = NULL; + cmap->stream = NULL; +} + static unsigned int opentype_cmap_get_unicode_ranges_count(const struct dwrite_fonttable *cmap) { unsigned int i, num_tables, count = 0;
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/dwrite_private.h | 1 - dlls/dwrite/font.c | 3 --- 2 files changed, 4 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 2d736fdec3c..5e6946717b3 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -262,7 +262,6 @@ struct dwrite_fontface INT charmap; UINT32 flags;
- struct dwrite_fonttable cmap; struct dwrite_fonttable vdmx; struct dwrite_fonttable gasp; struct dwrite_fonttable cpal; diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index dbb44327f26..f180ba765b8 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -585,8 +585,6 @@ static ULONG WINAPI dwritefontface_Release(IDWriteFontFace5 *iface) heap_free(fontface->cached); } release_scriptshaping_cache(fontface->shaping_cache); - if (fontface->cmap.context) - IDWriteFontFace5_ReleaseFontTable(iface, fontface->cmap.context); if (fontface->vdmx.context) IDWriteFontFace5_ReleaseFontTable(iface, fontface->vdmx.context); if (fontface->gasp.context) @@ -4906,7 +4904,6 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li fontface->refcount = 1; fontface->type = desc->face_type; fontface->file_count = desc->files_number; - fontface->cmap.exists = TRUE; fontface->vdmx.exists = TRUE; fontface->gasp.exists = TRUE; fontface->cpal.exists = TRUE;
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/dwrite_private.h | 8 ++--- dlls/dwrite/font.c | 37 ++++++++++------------ dlls/dwrite/freetype.c | 60 ------------------------------------ dlls/dwrite/opentype.c | 4 ++- 4 files changed, 22 insertions(+), 87 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 5e6946717b3..2a8a4d47414 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -259,9 +259,10 @@ struct dwrite_fontface unsigned int ascent; unsigned int descent; } typo_metrics; - INT charmap; UINT32 flags;
+ struct dwrite_cmap cmap; + struct dwrite_fonttable vdmx; struct dwrite_fonttable gasp; struct dwrite_fonttable cpal; @@ -340,8 +341,6 @@ extern void factory_unlock(IDWriteFactory7 *factory) DECLSPEC_HIDDEN; extern HRESULT create_inmemory_fileloader(IDWriteFontFileLoader**) DECLSPEC_HIDDEN; extern HRESULT create_font_resource(IDWriteFactory7 *factory, IDWriteFontFile *file, UINT32 face_index, IDWriteFontResource **resource) DECLSPEC_HIDDEN; -extern HRESULT fontface_get_glyphs(struct dwrite_fontface *fontface, UINT32 const *codepoints, - UINT32 count, UINT16 *glyphs);
struct dwrite_fontface;
@@ -462,13 +461,10 @@ extern HRESULT freetype_get_glyphrun_outline(IDWriteFontFace5 *fontface, float e float const *advances, DWRITE_GLYPH_OFFSET const *offsets, unsigned int count, BOOL is_rtl, IDWriteGeometrySink *sink) DECLSPEC_HIDDEN; extern UINT16 freetype_get_glyphcount(IDWriteFontFace5 *fontface) DECLSPEC_HIDDEN; -extern void freetype_get_glyphs(IDWriteFontFace5 *fontface, INT charmap, UINT32 const *codepoints, UINT32 count, - UINT16 *glyphs) DECLSPEC_HIDDEN; extern BOOL freetype_has_kerning_pairs(IDWriteFontFace5 *fontface) DECLSPEC_HIDDEN; 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) 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 f180ba765b8..7f5cce4e4b2 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -273,20 +273,22 @@ static UINT16 dwrite_get_font_upem(void *context) return fontface->metrics.designUnitsPerEm; }
+static UINT16 dwritefontface_get_glyph(struct dwrite_fontface *fontface, unsigned int ch) +{ + dwrite_cmap_init(&fontface->cmap, NULL, fontface->index, fontface->type); + return opentype_cmap_get_glyph(&fontface->cmap, ch); +} + static BOOL dwrite_has_glyph(void *context, unsigned int codepoint) { struct dwrite_fontface *fontface = context; - UINT16 index = 0; - fontface_get_glyphs(fontface, &codepoint, 1, &index); - return !!index; + return !!dwritefontface_get_glyph(fontface, codepoint); }
static UINT16 dwrite_get_glyph(void *context, unsigned int codepoint) { struct dwrite_fontface *fontface = context; - UINT16 index = 0; - fontface_get_glyphs(fontface, &codepoint, 1, &index); - return index; + return dwritefontface_get_glyph(fontface, codepoint); }
static const struct shaping_font_ops dwrite_font_ops = @@ -616,6 +618,7 @@ static ULONG WINAPI dwritefontface_Release(IDWriteFontFace5 *iface)
freetype_notify_cacheremove(iface);
+ dwrite_cmap_release(&fontface->cmap); IDWriteFactory7_Release(fontface->factory); heap_free(fontface); } @@ -732,17 +735,11 @@ static HRESULT WINAPI dwritefontface_GetDesignGlyphMetrics(IDWriteFontFace5 *ifa return S_OK; }
-HRESULT fontface_get_glyphs(struct dwrite_fontface *fontface, UINT32 const *codepoints, - UINT32 count, UINT16 *glyphs) -{ - freetype_get_glyphs(&fontface->IDWriteFontFace5_iface, fontface->charmap, codepoints, count, glyphs); - return S_OK; -} - static HRESULT WINAPI dwritefontface_GetGlyphIndices(IDWriteFontFace5 *iface, UINT32 const *codepoints, UINT32 count, UINT16 *glyphs) { struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface); + unsigned int i;
TRACE("%p, %p, %u, %p.\n", iface, codepoints, count, glyphs);
@@ -755,7 +752,10 @@ static HRESULT WINAPI dwritefontface_GetGlyphIndices(IDWriteFontFace5 *iface, UI return E_INVALIDARG; }
- return fontface_get_glyphs(fontface, codepoints, count, glyphs); + for (i = 0; i < count; ++i) + glyphs[i] = dwritefontface_get_glyph(fontface, codepoints[i]); + + return S_OK; }
static HRESULT WINAPI dwritefontface_TryGetFontTable(IDWriteFontFace5 *iface, UINT32 table_tag, @@ -1404,14 +1404,10 @@ static HRESULT WINAPI dwritefontface3_GetInformationalStrings(IDWriteFontFace5 * static BOOL WINAPI dwritefontface3_HasCharacter(IDWriteFontFace5 *iface, UINT32 ch) { struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface); - UINT16 index;
TRACE("%p, %#x.\n", iface, ch);
- index = 0; - fontface_get_glyphs(fontface, &ch, 1, &index); - - return index != 0; + return !!dwritefontface_get_glyph(fontface, ch); }
static HRESULT WINAPI dwritefontface3_GetRecommendedRenderingMode(IDWriteFontFace5 *iface, FLOAT emSize, FLOAT dpiX, FLOAT dpiY, @@ -4933,7 +4929,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 (opentype_has_vertical_variants(&fontface->IDWriteFontFace5_iface)) @@ -4979,6 +4974,8 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li if (fontface->info_strings[i]) IDWriteLocalizedStrings_AddRef(fontface->info_strings[i]); } + fontface->cmap.stream = fontface->stream; + IDWriteFontFileStream_AddRef(fontface->cmap.stream); release_font_data(font_data);
fontface->cached = factory_cache_fontface(fontface->factory, cached_list, &fontface->IDWriteFontFace5_iface); diff --git a/dlls/dwrite/freetype.c b/dlls/dwrite/freetype.c index 26b0d7bde1e..260d87b7ac6 100644 --- a/dlls/dwrite/freetype.c +++ b/dlls/dwrite/freetype.c @@ -52,7 +52,6 @@ static CRITICAL_SECTION freetype_cs = { &critsect_debug, -1, 0, 0, 0, 0 }; static void *ft_handle = NULL; static FT_Library library = 0; static FTC_Manager cache_manager = 0; -static FTC_CMapCache cmap_cache = 0; static FTC_ImageCache image_cache = 0; typedef struct { @@ -83,8 +82,6 @@ MAKE_FUNCPTR(FT_Outline_Get_Bitmap); MAKE_FUNCPTR(FT_Outline_New); MAKE_FUNCPTR(FT_Outline_Transform); MAKE_FUNCPTR(FT_Outline_Translate); -MAKE_FUNCPTR(FTC_CMapCache_Lookup); -MAKE_FUNCPTR(FTC_CMapCache_New); MAKE_FUNCPTR(FTC_ImageCache_Lookup); MAKE_FUNCPTR(FTC_ImageCache_New); MAKE_FUNCPTR(FTC_Manager_New); @@ -206,8 +203,6 @@ BOOL init_freetype(void) LOAD_FUNCPTR(FT_Outline_New) LOAD_FUNCPTR(FT_Outline_Transform) LOAD_FUNCPTR(FT_Outline_Translate) - LOAD_FUNCPTR(FTC_CMapCache_Lookup) - LOAD_FUNCPTR(FTC_CMapCache_New) LOAD_FUNCPTR(FTC_ImageCache_Lookup) LOAD_FUNCPTR(FTC_ImageCache_New) LOAD_FUNCPTR(FTC_Manager_New) @@ -228,7 +223,6 @@ BOOL init_freetype(void)
/* init cache manager */ if (pFTC_Manager_New(library, 0, 0, 0, &face_requester, NULL, &cache_manager) != 0 || - pFTC_CMapCache_New(cache_manager, &cmap_cache) != 0 || pFTC_ImageCache_New(cache_manager, &image_cache) != 0) {
ERR("Failed to init FreeType cache\n"); @@ -562,27 +556,6 @@ UINT16 freetype_get_glyphcount(IDWriteFontFace5 *fontface) return count; }
-void freetype_get_glyphs(IDWriteFontFace5 *fontface, INT charmap, UINT32 const *codepoints, UINT32 count, - UINT16 *glyphs) -{ - UINT32 i; - - EnterCriticalSection(&freetype_cs); - for (i = 0; i < count; i++) { - if (charmap == -1) - glyphs[i] = pFTC_CMapCache_Lookup(cmap_cache, fontface, charmap, codepoints[i]); - else { - UINT32 codepoint = codepoints[i]; - /* special handling for symbol fonts */ - if (codepoint < 0x100) codepoint += 0xf000; - glyphs[i] = pFTC_CMapCache_Lookup(cmap_cache, fontface, charmap, codepoint); - if (!glyphs[i]) - glyphs[i] = pFTC_CMapCache_Lookup(cmap_cache, fontface, charmap, codepoint - 0xf000); - } - } - LeaveCriticalSection(&freetype_cs); -} - BOOL freetype_has_kerning_pairs(IDWriteFontFace5 *fontface) { BOOL has_kerning_pairs = FALSE; @@ -841,28 +814,6 @@ BOOL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap) return ret; }
-INT freetype_get_charmap_index(IDWriteFontFace5 *fontface) -{ - INT charmap_index = -1; - FT_Face face; - - EnterCriticalSection(&freetype_cs); - if (pFTC_Manager_LookupFace(cache_manager, fontface, &face) == 0) - { - FT_Int i; - - for (i = 0; i < face->num_charmaps; i++) - if (face->charmaps[i]->encoding == FT_ENCODING_MS_SYMBOL) - { - charmap_index = i; - break; - } - } - LeaveCriticalSection(&freetype_cs); - - return charmap_index; -} - INT32 freetype_get_glyph_advance(IDWriteFontFace5 *fontface, FLOAT emSize, UINT16 index, DWRITE_MEASURING_MODE mode, BOOL *has_contours) { @@ -923,12 +874,6 @@ UINT16 freetype_get_glyphcount(IDWriteFontFace5 *fontface) return 0; }
-void freetype_get_glyphs(IDWriteFontFace5 *fontface, INT charmap, UINT32 const *codepoints, UINT32 count, - UINT16 *glyphs) -{ - memset(glyphs, 0, count * sizeof(*glyphs)); -} - BOOL freetype_has_kerning_pairs(IDWriteFontFace5 *fontface) { return FALSE; @@ -949,11 +894,6 @@ BOOL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap) return FALSE; }
-INT freetype_get_charmap_index(IDWriteFontFace5 *fontface) -{ - return -1; -} - INT32 freetype_get_glyph_advance(IDWriteFontFace5 *fontface, FLOAT emSize, UINT16 index, DWRITE_MEASURING_MODE mode, BOOL *has_contours) { diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index 8e507158579..563154992ab 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -1728,12 +1728,14 @@ void dwrite_cmap_init(struct dwrite_cmap *cmap, IDWriteFontFile *file, unsigned
if (cmap->data) return;
- if (FAILED(hr = get_filestream_from_file(file, &stream_desc.stream))) + /* For fontface stream is already available and preset. */ + if (!cmap->stream && FAILED(hr = get_filestream_from_file(file, &cmap->stream))) { WARN("Failed to get file stream, hr %#x.\n", hr); goto failed; }
+ stream_desc.stream = cmap->stream; stream_desc.face_type = face_type; stream_desc.face_index = face_index;