Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/font.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 9232f29317f..8a5033ab64f 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -7226,9 +7226,6 @@ static HRESULT WINAPI dwritefontset_GetPropertyValues(IDWriteFontSet3 *iface, UI { static int once;
- if (!once++) - FIXME("%p: stub\n", iface); - if (!once++) FIXME("%p, %u, %d, %p, %p.\n", iface, index, id, exists, values);
Multiple files only existed in initial API version, formats using multiple files were never supported, and newer API often operates on a single file instance.
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/dwrite_private.h | 6 ++-- dlls/dwrite/font.c | 59 ++++++++++++------------------------ dlls/dwrite/main.c | 3 +- 3 files changed, 22 insertions(+), 46 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index d28c6cef870..4628a2a3704 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -154,9 +154,8 @@ struct fontface_desc { IDWriteFactory7 *factory; DWRITE_FONT_FACE_TYPE face_type; - IDWriteFontFile * const *files; + IDWriteFontFile *file; IDWriteFontFileStream *stream; - UINT32 files_number; UINT32 index; DWRITE_FONT_SIMULATIONS simulations; struct dwrite_font_data *font_data; /* could be NULL when face is created directly with IDWriteFactory::CreateFontFace() */ @@ -243,8 +242,7 @@ struct dwrite_fontface LONG refcount;
IDWriteFontFileStream *stream; - IDWriteFontFile **files; - UINT32 file_count; + IDWriteFontFile *file; UINT32 index;
IDWriteFactory7 *factory; diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 8a5033ab64f..9386e9bec3f 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -639,14 +639,10 @@ static ULONG WINAPI dwritefontface_Release(IDWriteFontFace5 *iface) IDWriteFontFace5_ReleaseFontTable(iface, fontface->cpal.context); if (fontface->colr.context) IDWriteFontFace5_ReleaseFontTable(iface, fontface->colr.context); - for (i = 0; i < fontface->file_count; i++) - { - if (fontface->files[i]) - IDWriteFontFile_Release(fontface->files[i]); - } + if (fontface->file) + IDWriteFontFile_Release(fontface->file); if (fontface->stream) IDWriteFontFileStream_Release(fontface->stream); - heap_free(fontface->files); if (fontface->names) IDWriteLocalizedStrings_Release(fontface->names); if (fontface->family_names) @@ -683,24 +679,20 @@ static HRESULT WINAPI dwritefontface_GetFiles(IDWriteFontFace5 *iface, UINT32 *n IDWriteFontFile **fontfiles) { struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface); - int i;
TRACE("%p, %p, %p.\n", iface, number_of_files, fontfiles);
- if (fontfiles == NULL) + if (!fontfiles) { - *number_of_files = fontface->file_count; + *number_of_files = 1; return S_OK; }
- if (*number_of_files < fontface->file_count) + if (!*number_of_files) return E_INVALIDARG;
- for (i = 0; i < fontface->file_count; i++) - { - IDWriteFontFile_AddRef(fontface->files[i]); - fontfiles[i] = fontface->files[i]; - } + IDWriteFontFile_AddRef(fontface->file); + *fontfiles = fontface->file;
return S_OK; } @@ -1603,7 +1595,7 @@ static HRESULT WINAPI dwritefontface5_GetFontResource(IDWriteFontFace5 *iface, I
TRACE("%p, %p.\n", iface, resource);
- return IDWriteFactory7_CreateFontResource(fontface->factory, fontface->files[0], fontface->index, resource); + return IDWriteFactory7_CreateFontResource(fontface->factory, fontface->file, fontface->index, resource); }
static BOOL WINAPI dwritefontface5_Equals(IDWriteFontFace5 *iface, IDWriteFontFace *other) @@ -1619,7 +1611,7 @@ static BOOL WINAPI dwritefontface5_Equals(IDWriteFontFace5 *iface, IDWriteFontFa
return fontface->index == other_face->index && fontface->simulations == other_face->simulations && - is_same_fontfile(fontface->files[0], other_face->files[0]); + is_same_fontfile(fontface->file, other_face->file); }
static const IDWriteFontFace5Vtbl dwritefontfacevtbl = @@ -1728,11 +1720,11 @@ static HRESULT WINAPI dwritefontface_reference_CreateFontFaceWithSimulations(IDW
TRACE("%p, %#x, %p.\n", iface, simulations, ret);
- hr = IDWriteFontFile_Analyze(fontface->files[0], &is_supported, &file_type, &face_type, &face_num); + hr = IDWriteFontFile_Analyze(fontface->file, &is_supported, &file_type, &face_type, &face_num); if (FAILED(hr)) return hr;
- hr = IDWriteFactory7_CreateFontFace(fontface->factory, face_type, 1, fontface->files, fontface->index, + hr = IDWriteFactory7_CreateFontFace(fontface->factory, face_type, 1, &fontface->file, fontface->index, simulations, &face); if (SUCCEEDED(hr)) { @@ -1774,7 +1766,7 @@ static HRESULT WINAPI dwritefontface_reference_GetFontFile(IDWriteFontFaceRefere
TRACE("%p, %p.\n", iface, file);
- *file = fontface->files[0]; + *file = fontface->file; IDWriteFontFile_AddRef(*file);
return S_OK; @@ -1879,8 +1871,7 @@ static HRESULT get_fontface_from_font(struct dwrite_font *font, IDWriteFontFace5
desc.factory = font->family->collection->factory; desc.face_type = data->face_type; - desc.files = &data->file; - desc.files_number = 1; + desc.file = data->file; desc.index = data->face_index; desc.simulations = data->simulations; desc.font_data = data; @@ -3979,7 +3970,7 @@ static HRESULT init_font_data(const struct fontface_desc *desc, struct dwrite_fo return E_OUTOFMEMORY;
data->ref = 1; - data->file = desc->files[0]; + data->file = desc->file; data->face_index = desc->index; data->face_type = desc->face_type; IDWriteFontFile_AddRef(data->file); @@ -4388,9 +4379,8 @@ HRESULT create_font_collection(IDWriteFactory7 *factory, IDWriteFontFileEnumerat
desc.factory = factory; desc.face_type = face_type; - desc.files = &file; + desc.file = file; desc.stream = stream; - desc.files_number = 1; desc.index = i; desc.simulations = DWRITE_FONT_SIMULATIONS_NONE; desc.font_data = NULL; @@ -4729,13 +4719,12 @@ static HRESULT eudc_collection_add_family(IDWriteFactory7 *factory, struct dwrit struct dwrite_font_data *font_data; struct fontface_desc desc;
- /* alloc and init new font data structure */ + /* Allocate new font data structure. */ desc.factory = factory; desc.face_type = face_type; desc.index = i; - desc.files = &file; + desc.file = file; desc.stream = stream; - desc.files_number = 1; desc.simulations = DWRITE_FONT_SIMULATIONS_NONE; desc.font_data = NULL;
@@ -4983,17 +4972,10 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li if (!fontface) return E_OUTOFMEMORY;
- fontface->files = heap_alloc_zero(sizeof(*fontface->files) * desc->files_number); - if (!fontface->files) { - heap_free(fontface); - return E_OUTOFMEMORY; - } - fontface->IDWriteFontFace5_iface.lpVtbl = &dwritefontfacevtbl; fontface->IDWriteFontFaceReference_iface.lpVtbl = &dwritefontface_reference_vtbl; fontface->refcount = 1; fontface->type = desc->face_type; - fontface->file_count = desc->files_number; fontface->vdmx.exists = TRUE; fontface->gasp.exists = TRUE; fontface->cpal.exists = TRUE; @@ -5002,11 +4984,8 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li fontface->simulations = desc->simulations; fontface->factory = desc->factory; IDWriteFactory7_AddRef(fontface->factory); - - for (i = 0; i < fontface->file_count; i++) { - fontface->files[i] = desc->files[i]; - IDWriteFontFile_AddRef(fontface->files[i]); - } + fontface->file = desc->file; + IDWriteFontFile_AddRef(fontface->file); fontface->stream = desc->stream; IDWriteFontFileStream_AddRef(fontface->stream);
diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c index 864a44936c1..d66a27d7f68 100644 --- a/dlls/dwrite/main.c +++ b/dlls/dwrite/main.c @@ -1033,9 +1033,8 @@ static HRESULT WINAPI dwritefactory_CreateFontFace(IDWriteFactory7 *iface, DWRIT
desc.factory = iface; desc.face_type = req_facetype; - desc.files = font_files; + desc.file = *font_files; desc.stream = stream; - desc.files_number = files_number; desc.index = index; desc.simulations = simulations; desc.font_data = NULL;
Same as 0e4172a0c22a6f293cc3c5e1de265b2a5b480880 but for another test file.
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/tests/font.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index 8fe59ca5a1e..39a11b8be9a 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -2179,8 +2179,8 @@ static void get_enus_string(IDWriteLocalizedStrings *strings, WCHAR *buff, UINT3
hr = IDWriteLocalizedStrings_FindLocaleName(strings, L"en-us", &index, &exists); ok(hr == S_OK, "Unexpected hr %#x.\n", hr); - ok(exists, "got %d\n", exists); - + if (!exists) + index = 0; hr = IDWriteLocalizedStrings_GetString(strings, index, buff, size); ok(hr == S_OK, "got 0x%08x\n", hr); }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/dwrite_private.h | 13 +++++++------ dlls/dwrite/font.c | 4 +--- dlls/dwrite/opentype.c | 12 ++++++++++-- 3 files changed, 18 insertions(+), 11 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 4628a2a3704..27f4906a00d 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -182,11 +182,12 @@ struct fontfacecached
enum font_flags { - FONT_IS_SYMBOL = 1 << 0, - FONT_IS_MONOSPACED = 1 << 1, - FONT_IS_COLORED = 1 << 2, /* CPAL/COLR support */ - FONTFACE_HAS_KERNING_PAIRS = 1 << 3, - FONTFACE_HAS_VERTICAL_VARIANTS = 1 << 4 + FONT_IS_SYMBOL = 0x00000001, + FONT_IS_MONOSPACED = 0x00000002, + FONT_IS_COLORED = 0x00000004, /* CPAL/COLR support */ + FONTFACE_HAS_KERNING_PAIRS = 0x00000008, + FONTFACE_VERTICAL_VARIANTS = 0x00000010, + FONTFACE_NO_VERTICAL_VARIANTS = 0x00000020, };
struct dwrite_cmap; @@ -257,7 +258,7 @@ struct dwrite_fontface unsigned int ascent; unsigned int descent; } typo_metrics; - UINT32 flags; + unsigned int flags;
struct dwrite_cmap cmap;
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 9386e9bec3f..5a96ccc71a0 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -1217,7 +1217,7 @@ static BOOL WINAPI dwritefontface1_HasVerticalGlyphVariants(IDWriteFontFace5 *if
TRACE("%p.\n", iface);
- return !!(fontface->flags & FONTFACE_HAS_VERTICAL_VARIANTS); + return opentype_has_vertical_variants(fontface); }
static BOOL WINAPI dwritefontface2_IsColorFont(IDWriteFontFace5 *iface) @@ -5004,8 +5004,6 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li
if (freetype_has_kerning_pairs(&fontface->IDWriteFontFace5_iface)) fontface->flags |= FONTFACE_HAS_KERNING_PAIRS; - if (opentype_has_vertical_variants(fontface)) - fontface->flags |= FONTFACE_HAS_VERTICAL_VARIANTS; fontface->glyph_image_formats = opentype_get_glyph_image_formats(&fontface->IDWriteFontFace5_iface);
/* Font properties are reused from font object when 'normal' face creation path is used: diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index 39943c52c9a..45967a12f0a 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -6342,6 +6342,9 @@ BOOL opentype_has_vertical_variants(struct dwrite_fontface *fontface) struct lookups lookups = { 0 }; UINT16 format;
+ if (fontface->flags & (FONTFACE_VERTICAL_VARIANTS | FONTFACE_NO_VERTICAL_VARIANTS)) + return !!(fontface->flags & FONTFACE_VERTICAL_VARIANTS); + context.cache = fontface_get_shaping_cache(fontface); context.table = &context.cache->gsub;
@@ -6384,7 +6387,12 @@ BOOL opentype_has_vertical_variants(struct dwrite_fontface *fontface)
heap_free(lookups.lookups);
- return !!count; + if (count) + fontface->flags |= FONTFACE_VERTICAL_VARIANTS; + else + fontface->flags |= FONTFACE_NO_VERTICAL_VARIANTS; + + return !!(fontface->flags & FONTFACE_VERTICAL_VARIANTS); }
HRESULT opentype_get_vertical_glyph_variants(struct dwrite_fontface *fontface, unsigned int glyph_count, @@ -6398,7 +6406,7 @@ HRESULT opentype_get_vertical_glyph_variants(struct dwrite_fontface *fontface, u
memcpy(glyphs, nominal_glyphs, glyph_count * sizeof(*glyphs));
- if (!(fontface->flags & FONTFACE_HAS_VERTICAL_VARIANTS)) + if (!opentype_has_vertical_variants(fontface)) return S_OK;
context.cache = fontface_get_shaping_cache(fontface);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/dwrite_private.h | 19 +++-- dlls/dwrite/font.c | 32 +++----- dlls/dwrite/freetype.c | 41 ---------- dlls/dwrite/opentype.c | 143 +++++++++++++++++++++++++++++++++++ 4 files changed, 165 insertions(+), 70 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 27f4906a00d..a91b8f99d70 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -182,12 +182,13 @@ struct fontfacecached
enum font_flags { - FONT_IS_SYMBOL = 0x00000001, - FONT_IS_MONOSPACED = 0x00000002, - FONT_IS_COLORED = 0x00000004, /* CPAL/COLR support */ - FONTFACE_HAS_KERNING_PAIRS = 0x00000008, - FONTFACE_VERTICAL_VARIANTS = 0x00000010, - FONTFACE_NO_VERTICAL_VARIANTS = 0x00000020, + FONT_IS_SYMBOL = 0x00000001, + FONT_IS_MONOSPACED = 0x00000002, + FONT_IS_COLORED = 0x00000004, /* CPAL/COLR support */ + FONTFACE_KERNING_PAIRS = 0x00000008, + FONTFACE_NO_KERNING_PAIRS = 0x00000010, + FONTFACE_VERTICAL_VARIANTS = 0x00000020, + FONTFACE_NO_VERTICAL_VARIANTS = 0x00000040, };
struct dwrite_cmap; @@ -266,6 +267,7 @@ struct dwrite_fontface struct dwrite_fonttable gasp; struct dwrite_fonttable cpal; struct dwrite_fonttable colr; + struct dwrite_fonttable kern; DWRITE_GLYPH_METRICS *glyphs[GLYPH_MAX/GLYPH_BLOCK_SIZE];
DWRITE_FONT_STYLE style; @@ -407,6 +409,9 @@ extern HRESULT opentype_get_cpal_entries(const struct dwrite_fonttable *table, u unsigned int first_entry_index, unsigned int entry_count, DWRITE_COLOR_F *entries) DECLSPEC_HIDDEN; extern UINT32 opentype_get_glyph_image_formats(IDWriteFontFace5 *fontface) DECLSPEC_HIDDEN; extern DWRITE_CONTAINER_TYPE opentype_analyze_container_type(void const *, UINT32) DECLSPEC_HIDDEN; +extern HRESULT opentype_get_kerning_pairs(struct dwrite_fontface *fontface, unsigned int count, + const UINT16 *glyphs, INT32 *values) DECLSPEC_HIDDEN; +extern BOOL opentype_has_kerning_pairs(struct dwrite_fontface *fontface) DECLSPEC_HIDDEN;
struct dwrite_colorglyph { USHORT layer; /* [0, num_layers) index indicating current layer */ @@ -460,8 +465,6 @@ 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 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 INT32 freetype_get_glyph_advance(IDWriteFontFace5 *fontface, FLOAT emsize, UINT16 index, diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 5a96ccc71a0..1afc72e22c5 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -639,6 +639,8 @@ static ULONG WINAPI dwritefontface_Release(IDWriteFontFace5 *iface) IDWriteFontFace5_ReleaseFontTable(iface, fontface->cpal.context); if (fontface->colr.context) IDWriteFontFace5_ReleaseFontTable(iface, fontface->colr.context); + if (fontface->kern.context) + IDWriteFontFace5_ReleaseFontTable(iface, fontface->kern.context); if (fontface->file) IDWriteFontFile_Release(fontface->file); if (fontface->stream) @@ -1155,32 +1157,22 @@ static HRESULT WINAPI dwritefontface1_GetGdiCompatibleGlyphAdvances(IDWriteFontF }
static HRESULT WINAPI dwritefontface1_GetKerningPairAdjustments(IDWriteFontFace5 *iface, UINT32 count, - const UINT16 *indices, INT32 *adjustments) + const UINT16 *glyphs, INT32 *values) { struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface); - UINT32 i;
- TRACE("%p, %u, %p, %p.\n", iface, count, indices, adjustments); + TRACE("%p, %u, %p, %p.\n", iface, count, glyphs, values);
- if (!(indices || adjustments) || !count) + if (!(glyphs || values) || !count) return E_INVALIDARG;
- if (!indices || count == 1) { - memset(adjustments, 0, count*sizeof(INT32)); - return E_INVALIDARG; - } - - if (!(fontface->flags & FONTFACE_HAS_KERNING_PAIRS)) + if (!glyphs || count == 1) { - memset(adjustments, 0, count*sizeof(INT32)); - return S_OK; + memset(values, 0, count * sizeof(*values)); + return E_INVALIDARG; }
- for (i = 0; i < count-1; i++) - adjustments[i] = freetype_get_kerning_pair_adjustment(iface, indices[i], indices[i+1]); - adjustments[count-1] = 0; - - return S_OK; + return opentype_get_kerning_pairs(fontface, count, glyphs, values); }
static BOOL WINAPI dwritefontface1_HasKerningPairs(IDWriteFontFace5 *iface) @@ -1189,7 +1181,7 @@ static BOOL WINAPI dwritefontface1_HasKerningPairs(IDWriteFontFace5 *iface)
TRACE("%p.\n", iface);
- return !!(fontface->flags & FONTFACE_HAS_KERNING_PAIRS); + return opentype_has_kerning_pairs(fontface); }
static HRESULT WINAPI dwritefontface1_GetRecommendedRenderingMode(IDWriteFontFace5 *iface, @@ -4980,6 +4972,7 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li fontface->gasp.exists = TRUE; fontface->cpal.exists = TRUE; fontface->colr.exists = TRUE; + fontface->kern.exists = TRUE; fontface->index = desc->index; fontface->simulations = desc->simulations; fontface->factory = desc->factory; @@ -5001,9 +4994,6 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li fontface->caret.slopeRun = fontface->caret.slopeRise / 3; } } - - if (freetype_has_kerning_pairs(&fontface->IDWriteFontFace5_iface)) - fontface->flags |= FONTFACE_HAS_KERNING_PAIRS; fontface->glyph_image_formats = opentype_get_glyph_image_formats(&fontface->IDWriteFontFace5_iface);
/* Font properties are reused from font object when 'normal' face creation path is used: diff --git a/dlls/dwrite/freetype.c b/dlls/dwrite/freetype.c index 32fa4cc97c3..b770caac479 100644 --- a/dlls/dwrite/freetype.c +++ b/dlls/dwrite/freetype.c @@ -562,37 +562,6 @@ UINT16 freetype_get_glyphcount(IDWriteFontFace5 *fontface) return count; }
-BOOL freetype_has_kerning_pairs(IDWriteFontFace5 *fontface) -{ - BOOL has_kerning_pairs = FALSE; - FT_Face face; - - EnterCriticalSection(&freetype_cs); - if (pFTC_Manager_LookupFace(cache_manager, fontface, &face) == 0) - has_kerning_pairs = !!FT_HAS_KERNING(face); - LeaveCriticalSection(&freetype_cs); - - return has_kerning_pairs; -} - -INT32 freetype_get_kerning_pair_adjustment(IDWriteFontFace5 *fontface, UINT16 left, UINT16 right) -{ - INT32 adjustment = 0; - FT_Face face; - - EnterCriticalSection(&freetype_cs); - if (pFTC_Manager_LookupFace(cache_manager, fontface, &face) == 0) { - FT_Vector kern; - if (FT_HAS_KERNING(face)) { - pFT_Get_Kerning(face, left, right, FT_KERNING_UNSCALED, &kern); - adjustment = kern.x; - } - } - LeaveCriticalSection(&freetype_cs); - - return adjustment; -} - static inline void ft_matrix_from_dwrite_matrix(const DWRITE_MATRIX *m, FT_Matrix *ft_matrix) { ft_matrix->xx = m->m11 * 0x10000; @@ -880,16 +849,6 @@ UINT16 freetype_get_glyphcount(IDWriteFontFace5 *fontface) return 0; }
-BOOL freetype_has_kerning_pairs(IDWriteFontFace5 *fontface) -{ - return FALSE; -} - -INT32 freetype_get_kerning_pair_adjustment(IDWriteFontFace5 *fontface, UINT16 left, UINT16 right) -{ - return 0; -} - void freetype_get_glyph_bbox(struct dwrite_glyphbitmap *bitmap) { SetRectEmpty(&bitmap->bbox); diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index 45967a12f0a..01bf1ce0a09 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -46,6 +46,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(dwrite); #define MS_CBLC_TAG DWRITE_MAKE_OPENTYPE_TAG('C','B','L','C') #define MS_CMAP_TAG DWRITE_MAKE_OPENTYPE_TAG('c','m','a','p') #define MS_META_TAG DWRITE_MAKE_OPENTYPE_TAG('m','e','t','a') +#define MS_KERN_TAG DWRITE_MAKE_OPENTYPE_TAG('k','e','r','n')
/* 'sbix' formats */ #define MS_PNG__TAG DWRITE_MAKE_OPENTYPE_TAG('p','n','g',' ') @@ -820,6 +821,19 @@ typedef struct { DWORD ExtensionOffset; } GSUB_ExtensionPosFormat1;
+struct kern_header +{ + WORD version; + WORD table_count; +}; + +struct kern_subtable_header +{ + WORD version; + WORD length; + WORD coverage; +}; + #include "poppack.h"
enum TT_NAME_WINDOWS_ENCODING_ID @@ -6451,3 +6465,132 @@ HRESULT opentype_get_vertical_glyph_variants(struct dwrite_fontface *fontface, u
return S_OK; } + +BOOL opentype_has_kerning_pairs(struct dwrite_fontface *fontface) +{ + const struct kern_subtable_header *subtable; + struct file_stream_desc stream_desc; + const struct kern_header *header; + unsigned int offset, count, i; + + if (fontface->flags & (FONTFACE_KERNING_PAIRS | FONTFACE_NO_KERNING_PAIRS)) + return !!(fontface->flags & FONTFACE_KERNING_PAIRS); + + fontface->flags |= FONTFACE_NO_KERNING_PAIRS; + + stream_desc.stream = fontface->stream; + stream_desc.face_type = fontface->type; + stream_desc.face_index = fontface->index; + + opentype_get_font_table(&stream_desc, MS_KERN_TAG, &fontface->kern); + if (fontface->kern.exists) + { + if ((header = table_read_ensure(&fontface->kern, 0, sizeof(*header)))) + { + count = GET_BE_WORD(header->table_count); + offset = sizeof(*header); + + /* Freetype limits table count this way. */ + count = min(count, 32); + + /* Check for presence of format 0 subtable with horizontal coverage. */ + for (i = 0; i < count; ++i) + { + if (!(subtable = table_read_ensure(&fontface->kern, offset, sizeof(*subtable)))) + break; + + if (subtable->version == 0 && GET_BE_WORD(subtable->coverage) & 1) + { + fontface->flags &= ~FONTFACE_NO_KERNING_PAIRS; + fontface->flags |= FONTFACE_KERNING_PAIRS; + break; + } + + offset += GET_BE_WORD(subtable->length); + } + } + } + + if (fontface->flags & FONTFACE_NO_KERNING_PAIRS && fontface->kern.data) + IDWriteFontFileStream_ReleaseFileFragment(stream_desc.stream, fontface->kern.context); + + return !!(fontface->flags & FONTFACE_KERNING_PAIRS); +} + +struct kern_format0_compare_key +{ + UINT16 left; + UINT16 right; +}; + +static int kern_format0_compare(const void *a, const void *b) +{ + const struct kern_format0_compare_key *key = a; + const WORD *data = b; + UINT16 left = GET_BE_WORD(data[0]), right = GET_BE_WORD(data[1]); + int ret; + + if ((ret = (int)key->left - (int)left)) return ret; + if ((ret = (int)key->right - (int)right)) return ret; + return 0; +} + +HRESULT opentype_get_kerning_pairs(struct dwrite_fontface *fontface, unsigned int count, + const UINT16 *glyphs, INT32 *values) +{ + const struct kern_subtable_header *subtable; + unsigned int i, s, offset, pair_count, subtable_count; + struct kern_format0_compare_key key; + const struct kern_header *header; + const WORD *data; + + if (!opentype_has_kerning_pairs(fontface)) + { + memset(values, 0, count * sizeof(*values)); + return S_OK; + } + + subtable_count = table_read_be_word(&fontface->kern, 2); + subtable_count = min(subtable_count, 32); + + for (i = 0; i < count - 1; ++i) + { + offset = sizeof(*header); + + key.left = glyphs[i]; + key.right = glyphs[i + 1]; + values[i] = 0; + + for (s = 0; s < subtable_count; ++s) + { + if (!(subtable = table_read_ensure(&fontface->kern, offset, sizeof(*subtable)))) + break; + + if (subtable->version == 0 && GET_BE_WORD(subtable->coverage) & 1) + { + if ((data = table_read_ensure(&fontface->kern, offset, GET_BE_WORD(subtable->length)))) + { + /* Skip subtable header */ + data += 3; + pair_count = GET_BE_WORD(*data); + data += 4; + /* Move to pair data */ + if ((data = table_read_ensure(&fontface->kern, offset + 7 * sizeof(*data), + pair_count * 3 * sizeof(*data)))) + { + if ((data = bsearch(&key, data, pair_count, 3 * sizeof(*data), kern_format0_compare))) + { + values[i] = (short)GET_BE_WORD(data[2]); + break; + } + } + } + } + + offset += GET_BE_WORD(subtable->length); + } + } + values[count - 1] = 0; + + return S_OK; +}
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/opentype.c | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-)
diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index 01bf1ce0a09..717b1ea0351 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -400,7 +400,7 @@ struct ot_script WORD default_langsys; WORD langsys_count; struct ot_langsys_record langsys[1]; -} OT_Script; +};
struct ot_script_record { @@ -802,25 +802,6 @@ struct ot_gpos_mark_to_mark_format1 WORD mark2_array; };
-typedef struct { - WORD SubstFormat; - WORD Coverage; - WORD DeltaGlyphID; -} GSUB_SingleSubstFormat1; - -typedef struct { - WORD SubstFormat; - WORD Coverage; - WORD GlyphCount; - WORD Substitute[1]; -} GSUB_SingleSubstFormat2; - -typedef struct { - WORD SubstFormat; - WORD ExtensionLookupType; - DWORD ExtensionOffset; -} GSUB_ExtensionPosFormat1; - struct kern_header { WORD version;