Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/dwrite_private.h | 5 +++-- dlls/dwrite/format.c | 13 ++++++++----- dlls/dwrite/main.c | 34 ++++++++++++++++++++++++++++------ dlls/dwrite/tests/layout.c | 5 +---- 4 files changed, 40 insertions(+), 17 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index fdc916adc40..944f4cab635 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -286,8 +286,9 @@ struct dwrite_fontface };
extern HRESULT create_numbersubstitution(DWRITE_NUMBER_SUBSTITUTION_METHOD,const WCHAR *locale,BOOL,IDWriteNumberSubstitution**) DECLSPEC_HIDDEN; -extern HRESULT create_textformat(const WCHAR*,IDWriteFontCollection*,DWRITE_FONT_WEIGHT,DWRITE_FONT_STYLE,DWRITE_FONT_STRETCH, - FLOAT,const WCHAR*,IDWriteTextFormat**) DECLSPEC_HIDDEN; +extern HRESULT create_text_format(const WCHAR *family_name, IDWriteFontCollection *collection, DWRITE_FONT_WEIGHT weight, + DWRITE_FONT_STYLE style, DWRITE_FONT_STRETCH stretch, float size, const WCHAR *locale, REFIID riid, + void **out) DECLSPEC_HIDDEN; extern HRESULT create_textlayout(const struct textlayout_desc*,IDWriteTextLayout**) DECLSPEC_HIDDEN; extern HRESULT create_trimmingsign(IDWriteFactory7 *factory, IDWriteTextFormat *format, IDWriteInlineObject **sign) DECLSPEC_HIDDEN; diff --git a/dlls/dwrite/format.c b/dlls/dwrite/format.c index 133ca87e97f..dd120fe032e 100644 --- a/dlls/dwrite/format.c +++ b/dlls/dwrite/format.c @@ -711,12 +711,14 @@ struct dwrite_textformat *unsafe_impl_from_IDWriteTextFormat(IDWriteTextFormat * CONTAINING_RECORD(iface, struct dwrite_textformat, IDWriteTextFormat3_iface) : NULL; }
-HRESULT create_textformat(const WCHAR *family_name, IDWriteFontCollection *collection, DWRITE_FONT_WEIGHT weight, - DWRITE_FONT_STYLE style, DWRITE_FONT_STRETCH stretch, float size, const WCHAR *locale, IDWriteTextFormat **format) +HRESULT create_text_format(const WCHAR *family_name, IDWriteFontCollection *collection, DWRITE_FONT_WEIGHT weight, + DWRITE_FONT_STYLE style, DWRITE_FONT_STRETCH stretch, float size, const WCHAR *locale, + REFIID riid, void **out) { struct dwrite_textformat *object; + HRESULT hr;
- *format = NULL; + *out = NULL;
if (size <= 0.0f) return E_INVALIDARG; @@ -746,9 +748,10 @@ HRESULT create_textformat(const WCHAR *family_name, IDWriteFontCollection *colle object->format.collection = collection; IDWriteFontCollection_AddRef(object->format.collection);
- *format = (IDWriteTextFormat *)&object->IDWriteTextFormat3_iface; + hr = IDWriteTextFormat3_QueryInterface(&object->IDWriteTextFormat3_iface, riid, out); + IDWriteTextFormat3_Release(&object->IDWriteTextFormat3_iface);
- return S_OK; + return hr; }
static HRESULT WINAPI dwritetrimmingsign_QueryInterface(IDWriteInlineObject *iface, REFIID riid, void **obj) diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c index 01b47e673bb..c869ec3df54 100644 --- a/dlls/dwrite/main.c +++ b/dlls/dwrite/main.c @@ -1199,7 +1199,8 @@ static HRESULT WINAPI dwritefactory_CreateTextFormat(IDWriteFactory7 *iface, WCH return hr; }
- hr = create_textformat(family_name, collection, weight, style, stretch, size, locale, format); + hr = create_text_format(family_name, collection, weight, style, stretch, size, locale, + &IID_IDWriteTextFormat, (void **)format); IDWriteFontCollection_Release(collection); return hr; } @@ -1895,14 +1896,35 @@ static HRESULT WINAPI dwritefactory6_CreateFontSetBuilder(IDWriteFactory7 *iface return create_fontset_builder(iface, builder); }
-static HRESULT WINAPI dwritefactory6_CreateTextFormat(IDWriteFactory7 *iface, const WCHAR *familyname, +static HRESULT WINAPI dwritefactory6_CreateTextFormat(IDWriteFactory7 *iface, const WCHAR *family_name, IDWriteFontCollection *collection, DWRITE_FONT_AXIS_VALUE const *axis_values, UINT32 num_axis, - FLOAT fontsize, const WCHAR *localename, IDWriteTextFormat3 **format) + float size, const WCHAR *locale, IDWriteTextFormat3 **format) { - FIXME("%p, %s, %p, %p, %u, %.8e, %s, %p.\n", iface, debugstr_w(familyname), collection, axis_values, num_axis, - fontsize, debugstr_w(localename), format); + struct dwritefactory *factory = impl_from_IDWriteFactory7(iface); + HRESULT hr;
- return E_NOTIMPL; + TRACE("%p, %s, %p, %p, %u, %.8e, %s, %p.\n", iface, debugstr_w(family_name), collection, axis_values, num_axis, + size, debugstr_w(locale), format); + + *format = NULL; + + if (axis_values) + FIXME("Axis values are ignored.\n"); + + if (collection) + { + IDWriteFontCollection_AddRef(collection); + } + else if (FAILED(hr = factory_get_system_collection(factory, DWRITE_FONT_FAMILY_MODEL_TYPOGRAPHIC, + &IID_IDWriteFontCollection, (void **)&collection))) + { + return hr; + } + + hr = create_text_format(family_name, collection, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL, + DWRITE_FONT_STRETCH_NORMAL, size, locale, &IID_IDWriteTextFormat3, (void **)format); + IDWriteFontCollection_Release(collection); + return hr; }
static HRESULT WINAPI dwritefactory7_GetSystemFontSet(IDWriteFactory7 *iface, BOOL include_downloadable, diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c index 43b6efa107b..24ec3be7585 100644 --- a/dlls/dwrite/tests/layout.c +++ b/dlls/dwrite/tests/layout.c @@ -5986,11 +5986,8 @@ static void test_text_format_axes(void) }
hr = IDWriteFactory6_CreateTextFormat(factory, L"test_family", NULL, NULL, 0, 10.0f, L"en-us", &format3); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
-if (SUCCEEDED(hr)) -{ hr = IDWriteTextFormat3_GetFontCollection(format3, &collection); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
@@ -6025,7 +6022,7 @@ if (SUCCEEDED(hr)) ok(weight == DWRITE_FONT_WEIGHT_NORMAL, "Unexpected font weight %d.\n", weight);
IDWriteTextFormat3_Release(format3); -} + hr = IDWriteFactory_CreateTextFormat((IDWriteFactory *)factory, L"test_family", NULL, DWRITE_FONT_WEIGHT_BOLD, DWRITE_FONT_STYLE_ITALIC, DWRITE_FONT_STRETCH_EXPANDED, 10.0f, L"en-us", &format);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/font.c | 4 ++-- include/dwrite_3.idl | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 385c7fdeb03..ff95d3e57d9 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -7431,7 +7431,7 @@ static UINT32 WINAPI dwritefontresource_GetFontAxisCount(IDWriteFontResource *if }
static HRESULT WINAPI dwritefontresource_GetDefaultFontAxisValues(IDWriteFontResource *iface, - DWRITE_FONT_AXIS_VALUE const *values, UINT32 num_values) + DWRITE_FONT_AXIS_VALUE *values, UINT32 num_values) { FIXME("%p, %p, %u.\n", iface, values, num_values);
@@ -7439,7 +7439,7 @@ static HRESULT WINAPI dwritefontresource_GetDefaultFontAxisValues(IDWriteFontRes }
static HRESULT WINAPI dwritefontresource_GetFontAxisRanges(IDWriteFontResource *iface, - DWRITE_FONT_AXIS_RANGE const *ranges, UINT32 num_ranges) + DWRITE_FONT_AXIS_RANGE *ranges, UINT32 num_ranges) { FIXME("%p, %p, %u.\n", iface, ranges, num_ranges);
diff --git a/include/dwrite_3.idl b/include/dwrite_3.idl index 3542fbc8f1d..845754f6e3f 100644 --- a/include/dwrite_3.idl +++ b/include/dwrite_3.idl @@ -219,10 +219,10 @@ interface IDWriteFontResource : IUnknown UINT32 GetFontFaceIndex(); UINT32 GetFontAxisCount(); HRESULT GetDefaultFontAxisValues( - DWRITE_FONT_AXIS_VALUE const *values, + DWRITE_FONT_AXIS_VALUE *values, UINT32 num_values); HRESULT GetFontAxisRanges( - DWRITE_FONT_AXIS_RANGE const *ranges, + DWRITE_FONT_AXIS_RANGE *ranges, UINT32 num_ranges); DWRITE_FONT_AXIS_ATTRIBUTES GetFontAxisAttributes( UINT32 axis);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/dwrite_private.h | 15 ++- dlls/dwrite/font.c | 74 +++++++++++++-- dlls/dwrite/opentype.c | 174 +++++++++++++++++++++++++++++------ 3 files changed, 225 insertions(+), 38 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 944f4cab635..edb005b8b58 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -439,6 +439,7 @@ struct dwrite_font_props FONTSIGNATURE fontsig; LOGFONTW lf; UINT32 flags; + float slant_angle; };
struct file_stream_desc { @@ -465,10 +466,20 @@ struct ot_gsubgpos_table unsigned int lookup_list; };
+struct dwrite_var_axis +{ + DWRITE_FONT_AXIS_TAG tag; + float default_value; + float min_value; + float max_value; + unsigned int attributes; +}; + extern HRESULT opentype_analyze_font(IDWriteFontFileStream*,BOOL*,DWRITE_FONT_FILE_TYPE*,DWRITE_FONT_FACE_TYPE*,UINT32*) DECLSPEC_HIDDEN; extern HRESULT opentype_try_get_font_table(const struct file_stream_desc *stream_desc, UINT32 tag, const void **data, void **context, UINT32 *size, BOOL *exists) DECLSPEC_HIDDEN; -extern void opentype_get_font_properties(struct file_stream_desc*,struct dwrite_font_props*) DECLSPEC_HIDDEN; +extern void opentype_get_font_properties(const struct file_stream_desc *stream_desc, + struct dwrite_font_props *props) DECLSPEC_HIDDEN; extern void opentype_get_font_metrics(struct file_stream_desc*,DWRITE_FONT_METRICS1*,DWRITE_CARET_METRICS*) DECLSPEC_HIDDEN; extern void opentype_get_font_typo_metrics(struct file_stream_desc *stream_desc, unsigned int *ascent, unsigned int *descent) DECLSPEC_HIDDEN; @@ -490,6 +501,8 @@ extern DWRITE_CONTAINER_TYPE opentype_analyze_container_type(void const *, UINT3 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; +extern HRESULT opentype_get_font_var_axis(const struct file_stream_desc *stream_desc, struct dwrite_var_axis **axis, + unsigned int *axis_count) DECLSPEC_HIDDEN;
struct dwrite_colorglyph { USHORT layer; /* [0, num_layers) index indicating current layer */ diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index ff95d3e57d9..d2d2b7963f7 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -450,6 +450,9 @@ struct dwrite_fontresource IDWriteFontFile *file; UINT32 face_index; IDWriteFactory7 *factory; + + struct dwrite_var_axis *axis; + unsigned int axis_count; };
struct dwrite_fontset_entry_desc @@ -7396,6 +7399,7 @@ static ULONG WINAPI dwritefontresource_Release(IDWriteFontResource *iface) { IDWriteFactory7_Release(resource->factory); IDWriteFontFile_Release(resource->file); + free(resource->axis); free(resource); }
@@ -7425,33 +7429,62 @@ static UINT32 WINAPI dwritefontresource_GetFontFaceIndex(IDWriteFontResource *if
static UINT32 WINAPI dwritefontresource_GetFontAxisCount(IDWriteFontResource *iface) { - FIXME("%p.\n", iface); + struct dwrite_fontresource *resource = impl_from_IDWriteFontResource(iface);
- return 0; + TRACE("%p.\n", iface); + + return resource->axis_count; }
static HRESULT WINAPI dwritefontresource_GetDefaultFontAxisValues(IDWriteFontResource *iface, - DWRITE_FONT_AXIS_VALUE *values, UINT32 num_values) + DWRITE_FONT_AXIS_VALUE *values, UINT32 count) { - FIXME("%p, %p, %u.\n", iface, values, num_values); + struct dwrite_fontresource *resource = impl_from_IDWriteFontResource(iface); + unsigned int i;
- return E_NOTIMPL; + TRACE("%p, %p, %u.\n", iface, values, count); + + if (count < resource->axis_count) + return E_NOT_SUFFICIENT_BUFFER; + + for (i = 0; i < resource->axis_count; ++i) + { + values[i].axisTag = resource->axis[i].tag; + values[i].value = resource->axis[i].default_value; + } + + return S_OK; }
static HRESULT WINAPI dwritefontresource_GetFontAxisRanges(IDWriteFontResource *iface, - DWRITE_FONT_AXIS_RANGE *ranges, UINT32 num_ranges) + DWRITE_FONT_AXIS_RANGE *ranges, UINT32 count) { - FIXME("%p, %p, %u.\n", iface, ranges, num_ranges); + struct dwrite_fontresource *resource = impl_from_IDWriteFontResource(iface); + unsigned int i;
- return E_NOTIMPL; + TRACE("%p, %p, %u.\n", iface, ranges, count); + + if (count < resource->axis_count) + return E_NOT_SUFFICIENT_BUFFER; + + for (i = 0; i < resource->axis_count; ++i) + { + ranges[i].axisTag = resource->axis[i].tag; + ranges[i].minValue = resource->axis[i].min_value; + ranges[i].maxValue = resource->axis[i].max_value; + } + + return S_OK; }
static DWRITE_FONT_AXIS_ATTRIBUTES WINAPI dwritefontresource_GetFontAxisAttributes(IDWriteFontResource *iface, UINT32 axis) { - FIXME("%p, %u.\n", iface, axis); + struct dwrite_fontresource *resource = impl_from_IDWriteFontResource(iface); + + TRACE("%p, %u.\n", iface, axis);
- return DWRITE_FONT_AXIS_ATTRIBUTES_NONE; + return axis < resource->axis_count ? resource->axis[axis].attributes : 0; }
static HRESULT WINAPI dwritefontresource_GetAxisNames(IDWriteFontResource *iface, UINT32 axis, @@ -7540,9 +7573,21 @@ HRESULT create_font_resource(IDWriteFactory7 *factory, IDWriteFontFile *file, UI IDWriteFontResource **ret) { struct dwrite_fontresource *resource; + struct file_stream_desc stream_desc; + DWRITE_FONT_FILE_TYPE file_type; + DWRITE_FONT_FACE_TYPE face_type; + unsigned int face_count; + BOOL supported = FALSE; + HRESULT hr;
*ret = NULL;
+ if (FAILED(hr = IDWriteFontFile_Analyze(file, &supported, &file_type, &face_type, &face_count))) + return hr; + + if (!supported) + return DWRITE_E_FILEFORMAT; + if (!(resource = calloc(1, sizeof(*resource)))) return E_OUTOFMEMORY;
@@ -7554,6 +7599,15 @@ HRESULT create_font_resource(IDWriteFactory7 *factory, IDWriteFontFile *file, UI resource->factory = factory; IDWriteFactory7_AddRef(resource->factory);
+ get_filestream_from_file(file, &stream_desc.stream); + stream_desc.face_type = face_type; + stream_desc.face_index = face_index; + + opentype_get_font_var_axis(&stream_desc, &resource->axis, &resource->axis_count); + + if (stream_desc.stream) + IDWriteFontFileStream_Release(stream_desc.stream); + *ret = &resource->IDWriteFontResource_iface;
return S_OK; diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index c4b2177639b..36c38acb41d 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -21,6 +21,7 @@ #define COBJMACROS #define NONAMELESSUNION
+#include <stdint.h> #include "dwrite_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(dwrite); @@ -45,6 +46,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(dwrite); #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') +#define MS_FVAR_TAG DWRITE_MAKE_OPENTYPE_TAG('f','v','a','r')
/* 'sbix' formats */ #define MS_PNG__TAG DWRITE_MAKE_OPENTYPE_TAG('p','n','g',' ') @@ -61,9 +63,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(dwrite); #ifdef WORDS_BIGENDIAN #define GET_BE_WORD(x) (x) #define GET_BE_DWORD(x) (x) +#define GET_BE_FIXED(x) (x / 65536.0f) #else #define GET_BE_WORD(x) RtlUshortByteSwap(x) #define GET_BE_DWORD(x) RtlUlongByteSwap(x) +#define GET_BE_FIXED(x) ((int32_t)GET_BE_DWORD(x) / 65536.0f) #endif
#define GLYPH_CONTEXT_MAX_LENGTH 64 @@ -160,15 +164,15 @@ enum tt_head_macstyle
struct tt_post { - ULONG Version; - ULONG italicAngle; - SHORT underlinePosition; - SHORT underlineThickness; - ULONG fixed_pitch; - ULONG minmemType42; - ULONG maxmemType42; - ULONG minmemType1; - ULONG maxmemType1; + uint32_t Version; + int32_t italicAngle; + int16_t underlinePosition; + int16_t underlineThickness; + uint32_t fixed_pitch; + uint32_t minmemType42; + uint32_t maxmemType42; + uint32_t minmemType1; + uint32_t maxmemType1; };
struct tt_os2 @@ -1253,6 +1257,28 @@ struct meta_header struct meta_data_map maps[1]; };
+struct fvar_header +{ + uint16_t major_version; + uint16_t minor_version; + uint16_t axes_array_offset; + uint16_t reserved; + uint16_t axis_count; + uint16_t axis_size; + uint16_t instance_count; + uint16_t instance_size; +}; + +struct var_axis_record +{ + uint32_t tag; + int32_t min_value; + int32_t default_value; + int32_t max_value; + uint16_t flags; + uint16_t nameid; +}; + static const void *table_read_ensure(const struct dwrite_fonttable *table, unsigned int offset, unsigned int size) { if (size > table->size || offset > table->size - size) @@ -1273,6 +1299,11 @@ static DWORD table_read_be_dword(const struct dwrite_fonttable *table, unsigned return ptr ? GET_BE_DWORD(*ptr) : 0; }
+static float table_read_be_fixed(const struct dwrite_fonttable *table, unsigned int offset) +{ + return (int32_t)table_read_be_dword(table, offset) / 65536.0; +} + static DWORD table_read_dword(const struct dwrite_fonttable *table, unsigned int offset) { const DWORD *ptr = table_read_ensure(table, offset, sizeof(*ptr)); @@ -2022,22 +2053,20 @@ void opentype_get_font_metrics(struct file_stream_desc *stream_desc, DWRITE_FONT IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, hhea.context); }
-void opentype_get_font_properties(struct file_stream_desc *stream_desc, struct dwrite_font_props *props) +void opentype_get_font_properties(const struct file_stream_desc *stream_desc, struct dwrite_font_props *props) { - struct dwrite_fonttable os2, head, colr, cpal; + struct dwrite_fonttable os2, head, post, colr, cpal; BOOL is_symbol, is_monospaced;
opentype_get_font_table(stream_desc, MS_OS2_TAG, &os2); opentype_get_font_table(stream_desc, MS_HEAD_TAG, &head);
- /* default stretch, weight and style to normal */ + memset(props, 0, sizeof(*props)); + + /* Default stretch, weight and style to normal */ props->stretch = DWRITE_FONT_STRETCH_NORMAL; props->weight = DWRITE_FONT_WEIGHT_NORMAL; props->style = DWRITE_FONT_STYLE_NORMAL; - 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 (os2.data) @@ -2132,20 +2161,18 @@ 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)) + /* FONT_IS_MONOSPACED, slant angle */ + opentype_get_font_table(stream_desc, MS_POST_TAG, &post); + is_monospaced = props->panose.text.proportion == DWRITE_PANOSE_PROPORTION_MONOSPACED; + if (post.data) { - struct dwrite_fonttable post; - - opentype_get_font_table(stream_desc, MS_POST_TAG, &post); - - if (post.data) - { + if (!is_monospaced) is_monospaced = !!table_read_dword(&post, FIELD_OFFSET(struct tt_post, fixed_pitch)); - - IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, post.context); - } + props->slant_angle = table_read_be_fixed(&post, FIELD_OFFSET(struct tt_post, italicAngle)); } + if (post.context) + IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, post.context); + if (is_monospaced) props->flags |= FONT_IS_MONOSPACED;
@@ -6618,3 +6645,96 @@ HRESULT opentype_get_kerning_pairs(struct dwrite_fontface *fontface, unsigned in
return S_OK; } + +static void opentype_font_var_add_static_axis(struct dwrite_var_axis **axis, unsigned int *axis_count, + unsigned int tag, float value) +{ + struct dwrite_var_axis *entry = &(*axis)[(*axis_count)++]; + entry->tag = tag; + entry->min_value = entry->max_value = entry->default_value = value; + entry->attributes = 0; +} + +HRESULT opentype_get_font_var_axis(const struct file_stream_desc *stream_desc, struct dwrite_var_axis **axis, + unsigned int *axis_count) +{ + static const float width_axis_values[] = + { + 0.0f, /* DWRITE_FONT_STRETCH_UNDEFINED */ + 50.0f, /* DWRITE_FONT_STRETCH_ULTRA_CONDENSED */ + 62.5f, /* DWRITE_FONT_STRETCH_EXTRA_CONDENSED */ + 75.0f, /* DWRITE_FONT_STRETCH_CONDENSED */ + 87.5f, /* DWRITE_FONT_STRETCH_SEMI_CONDENSED */ + 100.0f, /* DWRITE_FONT_STRETCH_NORMAL */ + 112.5f, /* DWRITE_FONT_STRETCH_SEMI_EXPANDED */ + 125.0f, /* DWRITE_FONT_STRETCH_EXPANDED */ + 150.0f, /* DWRITE_FONT_STRETCH_EXTRA_EXPANDED */ + 200.0f, /* DWRITE_FONT_STRETCH_ULTRA_EXPANDED */ + }; + BOOL has_wght = FALSE, has_wdth = FALSE, has_slnt = FALSE, has_ital = FALSE; + const struct var_axis_record *records; + const struct fvar_header *header; + unsigned int i, count, tag, size; + struct dwrite_font_props props; + struct dwrite_fonttable fvar; + HRESULT hr = S_OK; + + *axis = NULL; + *axis_count = 0; + + opentype_get_font_table(stream_desc, MS_FVAR_TAG, &fvar); + + if (!(header = table_read_ensure(&fvar, 0, sizeof(*header)))) goto done; + if (!(GET_BE_WORD(header->major_version) == 1 && GET_BE_WORD(header->minor_version) == 0)) + { + WARN("Unexpected fvar version.\n"); + goto done; + } + + count = GET_BE_WORD(header->axis_count); + size = GET_BE_WORD(header->axis_size); + + if (!count || size != sizeof(*records)) goto done; + if (!(records = table_read_ensure(&fvar, GET_BE_WORD(header->axes_array_offset), size * count))) goto done; + + if (!(*axis = calloc(count + 4, sizeof(**axis)))) + { + hr = E_OUTOFMEMORY; + goto done; + } + + for (i = 0; i < count; ++i) + { + (*axis)[i].tag = tag = records[i].tag; + (*axis)[i].default_value = GET_BE_FIXED(records[i].default_value); + (*axis)[i].min_value = GET_BE_FIXED(records[i].min_value); + (*axis)[i].max_value = GET_BE_FIXED(records[i].max_value); + if (GET_BE_WORD(records[i].flags & 0x1)) + (*axis)[i].attributes |= DWRITE_FONT_AXIS_ATTRIBUTES_HIDDEN; + /* FIXME: set DWRITE_FONT_AXIS_ATTRIBUTES_VARIABLE */ + + if (tag == DWRITE_FONT_AXIS_TAG_WEIGHT) has_wght = TRUE; + if (tag == DWRITE_FONT_AXIS_TAG_WIDTH) has_wdth = TRUE; + if (tag == DWRITE_FONT_AXIS_TAG_SLANT) has_slnt = TRUE; + if (tag == DWRITE_FONT_AXIS_TAG_ITALIC) has_ital = TRUE; + } + + if (!has_wght || !has_wdth || !has_slnt || !has_ital) + { + opentype_get_font_properties(stream_desc, &props); + if (!has_wght) opentype_font_var_add_static_axis(axis, &count, DWRITE_FONT_AXIS_TAG_WEIGHT, props.weight); + if (!has_ital) opentype_font_var_add_static_axis(axis, &count, DWRITE_FONT_AXIS_TAG_ITALIC, + props.style == DWRITE_FONT_STYLE_ITALIC ? 1.0f : 0.0f); + if (!has_wdth) opentype_font_var_add_static_axis(axis, &count, DWRITE_FONT_AXIS_TAG_WIDTH, + width_axis_values[props.stretch]); + if (!has_slnt) opentype_font_var_add_static_axis(axis, &count, DWRITE_FONT_AXIS_TAG_SLANT, props.slant_angle); + } + + *axis_count = count; + +done: + if (fvar.context) + IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, fvar.context); + + return hr; +}
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/opentype.c | 318 +++++++++++++++++++++-------------------- 1 file changed, 160 insertions(+), 158 deletions(-)
diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index 36c38acb41d..195607aa67f 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -373,46 +373,46 @@ struct vdmx_group
struct ot_feature_record { - DWORD tag; - WORD offset; + uint32_t tag; + uint16_t offset; };
struct ot_feature_list { - WORD feature_count; + uint16_t feature_count; struct ot_feature_record features[1]; };
struct ot_langsys { - WORD lookup_order; /* Reserved */ - WORD required_feature_index; - WORD feature_count; - WORD feature_index[1]; + uint16_t lookup_order; /* Reserved */ + uint16_t required_feature_index; + uint16_t feature_count; + uint16_t feature_index[1]; };
struct ot_langsys_record { - CHAR tag[4]; - WORD langsys; + uint32_t tag; + uint16_t langsys; };
struct ot_script { - WORD default_langsys; - WORD langsys_count; + uint16_t default_langsys; + uint16_t langsys_count; struct ot_langsys_record langsys[1]; };
struct ot_script_record { - CHAR tag[4]; - WORD script; + uint32_t tag; + uint16_t script; };
struct ot_script_list { - WORD script_count; + uint16_t script_count; struct ot_script_record scripts[1]; };
@@ -428,42 +428,44 @@ enum ot_gdef_class
struct gdef_header { - DWORD version; - UINT16 classdef; - UINT16 attach_list; - UINT16 ligcaret_list; - UINT16 markattach_classdef; - UINT16 markglyphsetdef; + uint16_t major_version; + uint16_t minor_version; + uint16_t classdef; + uint16_t attach_list; + uint16_t ligcaret_list; + uint16_t markattach_classdef; + uint16_t markglyphsetdef; };
struct ot_gdef_classdef_format1 { - WORD format; - WORD start_glyph; - WORD glyph_count; - WORD classes[1]; + uint16_t format; + uint16_t start_glyph; + uint16_t glyph_count; + uint16_t classes[1]; };
struct ot_gdef_class_range { - WORD start_glyph; - WORD end_glyph; - WORD glyph_class; + uint16_t start_glyph; + uint16_t end_glyph; + uint16_t glyph_class; };
struct ot_gdef_classdef_format2 { - WORD format; - WORD range_count; + uint16_t format; + uint16_t range_count; struct ot_gdef_class_range ranges[1]; };
struct gpos_gsub_header { - DWORD version; - WORD script_list; - WORD feature_list; - WORD lookup_list; + uint16_t major_version; + uint16_t minor_version; + uint16_t script_list; + uint16_t feature_list; + uint16_t lookup_list; };
enum gsub_gpos_lookup_flags @@ -549,272 +551,272 @@ enum OPENTYPE_PLATFORM_ID
struct ot_gsubgpos_extension_format1 { - UINT16 format; - UINT16 lookup_type; - DWORD extension_offset; + uint16_t format; + uint16_t lookup_type; + uint32_t extension_offset; };
struct ot_gsub_singlesubst_format1 { - UINT16 format; - UINT16 coverage; - short delta; + uint16_t format; + uint16_t coverage; + int16_t delta; };
struct ot_gsub_singlesubst_format2 { - UINT16 format; - UINT16 coverage; - UINT16 count; - UINT16 substitutes[1]; + uint16_t format; + uint16_t coverage; + uint16_t count; + uint16_t substitutes[1]; };
struct ot_gsub_multsubst_format1 { - UINT16 format; - UINT16 coverage; - UINT16 seq_count; - UINT16 seq[1]; + uint16_t format; + uint16_t coverage; + uint16_t seq_count; + uint16_t seq[1]; };
struct ot_gsub_altsubst_format1 { - UINT16 format; - UINT16 coverage; - UINT16 count; - UINT16 sets[1]; + uint16_t format; + uint16_t coverage; + uint16_t count; + uint16_t sets[1]; };
struct ot_gsub_ligsubst_format1 { - UINT16 format; - UINT16 coverage; - UINT16 lig_set_count; - UINT16 lig_sets[1]; + uint16_t format; + uint16_t coverage; + uint16_t lig_set_count; + uint16_t lig_sets[1]; };
struct ot_gsub_ligset { - UINT16 count; - UINT16 offsets[1]; + uint16_t count; + uint16_t offsets[1]; };
struct ot_gsub_lig { - UINT16 lig_glyph; - UINT16 comp_count; - UINT16 components[1]; + uint16_t lig_glyph; + uint16_t comp_count; + uint16_t components[1]; };
struct ot_gsubgpos_context_format1 { - UINT16 format; - UINT16 coverage; - UINT16 ruleset_count; - UINT16 rulesets[1]; + uint16_t format; + uint16_t coverage; + uint16_t ruleset_count; + uint16_t rulesets[1]; };
struct ot_gsubgpos_ruleset { - UINT16 count; - UINT16 offsets[1]; + uint16_t count; + uint16_t offsets[1]; };
struct ot_feature { - WORD feature_params; - WORD lookup_count; - WORD lookuplist_index[1]; + uint16_t feature_params; + uint16_t lookup_count; + uint16_t lookuplist_index[1]; };
struct ot_lookup_list { - WORD lookup_count; - WORD lookup[1]; + uint16_t lookup_count; + uint16_t lookup[1]; };
struct ot_lookup_table { - WORD lookup_type; - WORD flags; - WORD subtable_count; - WORD subtable[1]; + uint16_t lookup_type; + uint16_t flags; + uint16_t subtable_count; + uint16_t subtable[1]; };
#define GLYPH_NOT_COVERED (~0u)
struct ot_coverage_format1 { - WORD format; - WORD glyph_count; - WORD glyphs[1]; + uint16_t format; + uint16_t glyph_count; + uint16_t glyphs[1]; };
struct ot_coverage_range { - WORD start_glyph; - WORD end_glyph; - WORD startcoverage_index; + uint16_t start_glyph; + uint16_t end_glyph; + uint16_t startcoverage_index; };
struct ot_coverage_format2 { - WORD format; - WORD range_count; + uint16_t format; + uint16_t range_count; struct ot_coverage_range ranges[1]; };
struct ot_gpos_device_table { - WORD start_size; - WORD end_size; - WORD format; - WORD values[1]; + uint16_t start_size; + uint16_t end_size; + uint16_t format; + uint16_t values[1]; };
struct ot_gpos_singlepos_format1 { - WORD format; - WORD coverage; - WORD value_format; - WORD value[1]; + uint16_t format; + uint16_t coverage; + uint16_t value_format; + uint16_t value[1]; };
struct ot_gpos_singlepos_format2 { - WORD format; - WORD coverage; - WORD value_format; - WORD value_count; - WORD values[1]; + uint16_t format; + uint16_t coverage; + uint16_t value_format; + uint16_t value_count; + uint16_t values[1]; };
struct ot_gpos_pairvalue { - WORD second_glyph; - BYTE data[1]; + uint16_t second_glyph; + uint8_t data[1]; };
struct ot_gpos_pairset { - WORD pairvalue_count; + uint16_t pairvalue_count; struct ot_gpos_pairvalue pairvalues[1]; };
struct ot_gpos_pairpos_format1 { - WORD format; - WORD coverage; - WORD value_format1; - WORD value_format2; - WORD pairset_count; - WORD pairsets[1]; + uint16_t format; + uint16_t coverage; + uint16_t value_format1; + uint16_t value_format2; + uint16_t pairset_count; + uint16_t pairsets[1]; };
struct ot_gpos_pairpos_format2 { - WORD format; - WORD coverage; - WORD value_format1; - WORD value_format2; - WORD class_def1; - WORD class_def2; - WORD class1_count; - WORD class2_count; - WORD values[1]; + uint16_t format; + uint16_t coverage; + uint16_t value_format1; + uint16_t value_format2; + uint16_t class_def1; + uint16_t class_def2; + uint16_t class1_count; + uint16_t class2_count; + uint16_t values[1]; };
struct ot_gpos_anchor_format1 { - WORD format; - short x_coord; - short y_coord; + uint16_t format; + int16_t x_coord; + int16_t y_coord; };
struct ot_gpos_anchor_format2 { - WORD format; - short x_coord; - short y_coord; - WORD anchor_point; + uint16_t format; + int16_t x_coord; + int16_t y_coord; + uint16_t anchor_point; };
struct ot_gpos_anchor_format3 { - WORD format; - short x_coord; - short y_coord; - WORD x_dev_offset; - WORD y_dev_offset; + uint16_t format; + int16_t x_coord; + int16_t y_coord; + uint16_t x_dev_offset; + uint16_t y_dev_offset; };
struct ot_gpos_cursive_format1 { - WORD format; - WORD coverage; - WORD count; - WORD anchors[1]; + uint16_t format; + uint16_t coverage; + uint16_t count; + uint16_t anchors[1]; };
struct ot_gpos_mark_record { - WORD mark_class; - WORD mark_anchor; + uint16_t mark_class; + uint16_t mark_anchor; };
struct ot_gpos_mark_array { - WORD count; + uint16_t count; struct ot_gpos_mark_record records[1]; };
struct ot_gpos_base_array { - WORD count; - WORD offsets[1]; + uint16_t count; + uint16_t offsets[1]; };
struct ot_gpos_mark_to_base_format1 { - WORD format; - WORD mark_coverage; - WORD base_coverage; - WORD mark_class_count; - WORD mark_array; - WORD base_array; + uint16_t format; + uint16_t mark_coverage; + uint16_t base_coverage; + uint16_t mark_class_count; + uint16_t mark_array; + uint16_t base_array; };
struct ot_gpos_mark_to_lig_format1 { - WORD format; - WORD mark_coverage; - WORD lig_coverage; - WORD mark_class_count; - WORD mark_array; - WORD lig_array; + uint16_t format; + uint16_t mark_coverage; + uint16_t lig_coverage; + uint16_t mark_class_count; + uint16_t mark_array; + uint16_t lig_array; };
struct ot_gpos_mark_to_mark_format1 { - WORD format; - WORD mark1_coverage; - WORD mark2_coverage; - WORD mark_class_count; - WORD mark1_array; - WORD mark2_array; + uint16_t format; + uint16_t mark1_coverage; + uint16_t mark2_coverage; + uint16_t mark_class_count; + uint16_t mark1_array; + uint16_t mark2_array; };
struct kern_header { - WORD version; - WORD table_count; + uint16_t version; + uint16_t table_count; };
struct kern_subtable_header { - WORD version; - WORD length; - WORD coverage; + uint16_t version; + uint16_t length; + uint16_t coverage; };
#include "poppack.h"