dwrite: Add a helper to get shaped glyph positions.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
e020d6c99d
commit
d1c7348997
|
@ -1157,16 +1157,14 @@ static HRESULT WINAPI dwritetextanalyzer_GetGlyphs(IDWriteTextAnalyzer2 *iface,
|
|||
UINT16* clustermap, DWRITE_SHAPING_TEXT_PROPERTIES* text_props, UINT16* glyph_indices,
|
||||
DWRITE_SHAPING_GLYPH_PROPERTIES* glyph_props, UINT32* actual_glyph_count)
|
||||
{
|
||||
const struct dwritescript_properties *scriptprops;
|
||||
DWRITE_NUMBER_SUBSTITUTION_METHOD method;
|
||||
struct scriptshaping_context context;
|
||||
struct scriptshaping_cache *cache = NULL;
|
||||
struct dwrite_fontface *font_obj;
|
||||
WCHAR digits[NATIVE_DIGITS_LEN];
|
||||
BOOL update_cluster;
|
||||
WCHAR *string;
|
||||
UINT32 i, g;
|
||||
HRESULT hr = S_OK;
|
||||
UINT16 script;
|
||||
|
||||
TRACE("(%s:%u %p %d %d %s %s %p %p %p %u %u %p %p %p %p %p)\n", debugstr_wn(text, length),
|
||||
length, fontface, is_sideways, is_rtl, debugstr_sa_script(analysis->script), debugstr_w(locale), substitution,
|
||||
|
@ -1175,8 +1173,6 @@ static HRESULT WINAPI dwritetextanalyzer_GetGlyphs(IDWriteTextAnalyzer2 *iface,
|
|||
|
||||
analyzer_dump_user_features(features, feature_range_lengths, feature_ranges);
|
||||
|
||||
script = analysis->script > Script_LastId ? Script_Unknown : analysis->script;
|
||||
|
||||
if (max_glyph_count < length)
|
||||
return E_NOT_SUFFICIENT_BUFFER;
|
||||
|
||||
|
@ -1253,33 +1249,19 @@ static HRESULT WINAPI dwritetextanalyzer_GetGlyphs(IDWriteTextAnalyzer2 *iface,
|
|||
}
|
||||
*actual_glyph_count = g;
|
||||
|
||||
hr = create_scriptshaping_cache(fontface, &cache);
|
||||
if (FAILED(hr))
|
||||
goto done;
|
||||
font_obj = unsafe_impl_from_IDWriteFontFace(fontface);
|
||||
|
||||
context.cache = cache;
|
||||
context.cache = fontface_get_shaping_cache(font_obj);
|
||||
context.text = text;
|
||||
context.length = length;
|
||||
context.is_rtl = is_rtl;
|
||||
context.max_glyph_count = max_glyph_count;
|
||||
context.language_tag = get_opentype_language(locale);
|
||||
|
||||
scriptprops = &dwritescripts_properties[script];
|
||||
if (scriptprops->ops && scriptprops->ops->contextual_shaping) {
|
||||
hr = scriptprops->ops->contextual_shaping(&context, clustermap, glyph_indices, actual_glyph_count);
|
||||
if (FAILED(hr))
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* FIXME: apply default features */
|
||||
|
||||
if (scriptprops->ops && scriptprops->ops->set_text_glyphs_props)
|
||||
hr = scriptprops->ops->set_text_glyphs_props(&context, clustermap, glyph_indices, *actual_glyph_count, text_props, glyph_props);
|
||||
else
|
||||
hr = default_shaping_ops.set_text_glyphs_props(&context, clustermap, glyph_indices, *actual_glyph_count, text_props, glyph_props);
|
||||
hr = default_shaping_ops.set_text_glyphs_props(&context, clustermap, glyph_indices, *actual_glyph_count, text_props, glyph_props);
|
||||
|
||||
done:
|
||||
release_scriptshaping_cache(cache);
|
||||
heap_free(string);
|
||||
|
||||
return hr;
|
||||
|
@ -1288,14 +1270,14 @@ done:
|
|||
static HRESULT WINAPI dwritetextanalyzer_GetGlyphPlacements(IDWriteTextAnalyzer2 *iface,
|
||||
WCHAR const* text, UINT16 const* clustermap, DWRITE_SHAPING_TEXT_PROPERTIES* props,
|
||||
UINT32 text_len, UINT16 const* glyphs, DWRITE_SHAPING_GLYPH_PROPERTIES const* glyph_props,
|
||||
UINT32 glyph_count, IDWriteFontFace *fontface, FLOAT emSize, BOOL is_sideways, BOOL is_rtl,
|
||||
UINT32 glyph_count, IDWriteFontFace *fontface, float emSize, BOOL is_sideways, BOOL is_rtl,
|
||||
DWRITE_SCRIPT_ANALYSIS const* analysis, WCHAR const* locale, DWRITE_TYPOGRAPHIC_FEATURES const** features,
|
||||
UINT32 const* feature_range_lengths, UINT32 feature_ranges, FLOAT *advances, DWRITE_GLYPH_OFFSET *offsets)
|
||||
UINT32 const* feature_range_lengths, UINT32 feature_ranges, float *advances, DWRITE_GLYPH_OFFSET *offsets)
|
||||
{
|
||||
DWRITE_FONT_METRICS metrics;
|
||||
IDWriteFontFace1 *fontface1;
|
||||
HRESULT hr;
|
||||
UINT32 i;
|
||||
const struct dwritescript_properties *scriptprops;
|
||||
struct dwrite_fontface *font_obj;
|
||||
unsigned int i, script;
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
TRACE("(%s %p %p %u %p %p %u %p %.2f %d %d %s %s %p %p %u %p %p)\n", debugstr_wn(text, text_len),
|
||||
clustermap, props, text_len, glyphs, glyph_props, glyph_count, fontface, emSize, is_sideways,
|
||||
|
@ -1307,46 +1289,51 @@ static HRESULT WINAPI dwritetextanalyzer_GetGlyphPlacements(IDWriteTextAnalyzer2
|
|||
if (glyph_count == 0)
|
||||
return S_OK;
|
||||
|
||||
hr = IDWriteFontFace_QueryInterface(fontface, &IID_IDWriteFontFace1, (void**)&fontface1);
|
||||
if (FAILED(hr)) {
|
||||
WARN("failed to get IDWriteFontFace1.\n");
|
||||
return hr;
|
||||
}
|
||||
font_obj = unsafe_impl_from_IDWriteFontFace(fontface);
|
||||
|
||||
IDWriteFontFace_GetMetrics(fontface, &metrics);
|
||||
for (i = 0; i < glyph_count; i++) {
|
||||
for (i = 0; i < glyph_count; ++i)
|
||||
{
|
||||
if (glyph_props[i].isZeroWidthSpace)
|
||||
advances[i] = 0.0f;
|
||||
else {
|
||||
INT32 a;
|
||||
|
||||
hr = IDWriteFontFace1_GetDesignGlyphAdvances(fontface1, 1, &glyphs[i], &a, is_sideways);
|
||||
if (FAILED(hr))
|
||||
a = 0;
|
||||
advances[i] = get_scaled_advance_width(a, emSize, &metrics);
|
||||
}
|
||||
else
|
||||
advances[i] = fontface_get_scaled_design_advance(font_obj, DWRITE_MEASURING_MODE_NATURAL, emSize, 1.0f,
|
||||
NULL, glyphs[i], is_sideways);
|
||||
offsets[i].advanceOffset = 0.0f;
|
||||
offsets[i].ascenderOffset = 0.0f;
|
||||
}
|
||||
|
||||
/* FIXME: actually apply features */
|
||||
script = analysis->script > Script_LastId ? Script_Unknown : analysis->script;
|
||||
|
||||
IDWriteFontFace1_Release(fontface1);
|
||||
return S_OK;
|
||||
scriptprops = &dwritescripts_properties[script];
|
||||
if (scriptprops->ops && scriptprops->ops->gpos_features)
|
||||
{
|
||||
struct scriptshaping_context context;
|
||||
|
||||
context.cache = fontface_get_shaping_cache(font_obj);
|
||||
context.text = text;
|
||||
context.length = text_len;
|
||||
context.is_rtl = is_rtl;
|
||||
context.language_tag = get_opentype_language(locale);
|
||||
|
||||
hr = shape_get_positions(&context, scriptprops->scripttags, scriptprops->ops->gpos_features);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI dwritetextanalyzer_GetGdiCompatibleGlyphPlacements(IDWriteTextAnalyzer2 *iface,
|
||||
WCHAR const* text, UINT16 const* clustermap, DWRITE_SHAPING_TEXT_PROPERTIES* props,
|
||||
UINT32 text_len, UINT16 const* glyphs, DWRITE_SHAPING_GLYPH_PROPERTIES const* glyph_props,
|
||||
UINT32 glyph_count, IDWriteFontFace *fontface, FLOAT emSize, FLOAT ppdip,
|
||||
UINT32 glyph_count, IDWriteFontFace *fontface, float emSize, float ppdip,
|
||||
DWRITE_MATRIX const* transform, BOOL use_gdi_natural, BOOL is_sideways, BOOL is_rtl,
|
||||
DWRITE_SCRIPT_ANALYSIS const* analysis, WCHAR const* locale, DWRITE_TYPOGRAPHIC_FEATURES const** features,
|
||||
UINT32 const* feature_range_lengths, UINT32 feature_ranges, FLOAT *advances, DWRITE_GLYPH_OFFSET *offsets)
|
||||
UINT32 const* feature_range_lengths, UINT32 feature_ranges, float *advances, DWRITE_GLYPH_OFFSET *offsets)
|
||||
{
|
||||
DWRITE_FONT_METRICS metrics;
|
||||
IDWriteFontFace1 *fontface1;
|
||||
HRESULT hr;
|
||||
UINT32 i;
|
||||
const struct dwritescript_properties *scriptprops;
|
||||
DWRITE_MEASURING_MODE measuring_mode;
|
||||
struct dwrite_fontface *font_obj;
|
||||
unsigned int i, script;
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
TRACE("(%s %p %p %u %p %p %u %p %.2f %.2f %p %d %d %d %s %s %p %p %u %p %p)\n", debugstr_wn(text, text_len),
|
||||
clustermap, props, text_len, glyphs, glyph_props, glyph_count, fontface, emSize, ppdip,
|
||||
|
@ -1358,35 +1345,38 @@ static HRESULT WINAPI dwritetextanalyzer_GetGdiCompatibleGlyphPlacements(IDWrite
|
|||
if (glyph_count == 0)
|
||||
return S_OK;
|
||||
|
||||
hr = IDWriteFontFace_QueryInterface(fontface, &IID_IDWriteFontFace1, (void**)&fontface1);
|
||||
if (FAILED(hr)) {
|
||||
WARN("failed to get IDWriteFontFace1.\n");
|
||||
return hr;
|
||||
}
|
||||
font_obj = unsafe_impl_from_IDWriteFontFace(fontface);
|
||||
|
||||
hr = IDWriteFontFace_GetGdiCompatibleMetrics(fontface, emSize, ppdip, transform, &metrics);
|
||||
if (FAILED(hr)) {
|
||||
IDWriteFontFace1_Release(fontface1);
|
||||
WARN("failed to get compat metrics, 0x%08x\n", hr);
|
||||
return hr;
|
||||
}
|
||||
for (i = 0; i < glyph_count; i++) {
|
||||
INT32 a;
|
||||
measuring_mode = use_gdi_natural ? DWRITE_MEASURING_MODE_GDI_NATURAL : DWRITE_MEASURING_MODE_GDI_CLASSIC;
|
||||
|
||||
hr = IDWriteFontFace1_GetGdiCompatibleGlyphAdvances(fontface1, emSize, ppdip,
|
||||
transform, use_gdi_natural, is_sideways, 1, &glyphs[i], &a);
|
||||
if (FAILED(hr))
|
||||
for (i = 0; i < glyph_count; ++i)
|
||||
{
|
||||
if (glyph_props[i].isZeroWidthSpace)
|
||||
advances[i] = 0.0f;
|
||||
else
|
||||
advances[i] = floorf(a * emSize * ppdip / metrics.designUnitsPerEm + 0.5f) / ppdip;
|
||||
advances[i] = fontface_get_scaled_design_advance(font_obj, measuring_mode, emSize, ppdip,
|
||||
transform, glyphs[i], is_sideways);
|
||||
offsets[i].advanceOffset = 0.0f;
|
||||
offsets[i].ascenderOffset = 0.0f;
|
||||
}
|
||||
|
||||
/* FIXME: actually apply features */
|
||||
script = analysis->script > Script_LastId ? Script_Unknown : analysis->script;
|
||||
|
||||
IDWriteFontFace1_Release(fontface1);
|
||||
return S_OK;
|
||||
scriptprops = &dwritescripts_properties[script];
|
||||
if (scriptprops->ops && scriptprops->ops->gpos_features)
|
||||
{
|
||||
struct scriptshaping_context context;
|
||||
|
||||
context.cache = fontface_get_shaping_cache(font_obj);
|
||||
context.text = text;
|
||||
context.length = text_len;
|
||||
context.is_rtl = is_rtl;
|
||||
context.language_tag = get_opentype_language(locale);
|
||||
|
||||
hr = shape_get_positions(&context, scriptprops->scripttags, scriptprops->ops->gpos_features);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static inline FLOAT get_cluster_advance(const FLOAT *advances, UINT32 start, UINT32 end)
|
||||
|
|
|
@ -192,6 +192,12 @@ extern void factory_lock(IDWriteFactory5*) DECLSPEC_HIDDEN;
|
|||
extern void factory_unlock(IDWriteFactory5*) DECLSPEC_HIDDEN;
|
||||
extern HRESULT create_inmemory_fileloader(IDWriteFontFileLoader**) DECLSPEC_HIDDEN;
|
||||
|
||||
struct dwrite_fontface;
|
||||
|
||||
extern float fontface_get_scaled_design_advance(struct dwrite_fontface *fontface, DWRITE_MEASURING_MODE measuring_mode,
|
||||
float emsize, float ppdip, const DWRITE_MATRIX *transform, UINT16 glyph, BOOL is_sideways) DECLSPEC_HIDDEN;
|
||||
extern struct dwrite_fontface *unsafe_impl_from_IDWriteFontFace(IDWriteFontFace *iface) DECLSPEC_HIDDEN;
|
||||
|
||||
/* Opentype font table functions */
|
||||
struct dwrite_font_props {
|
||||
DWRITE_FONT_STYLE style;
|
||||
|
@ -320,7 +326,12 @@ enum SCRIPT_JUSTIFY
|
|||
SCRIPT_JUSTIFY_ARABIC_SEEN_M
|
||||
};
|
||||
|
||||
struct scriptshaping_cache;
|
||||
struct scriptshaping_cache
|
||||
{
|
||||
const struct shaping_font_ops *font;
|
||||
void *context;
|
||||
UINT16 upem;
|
||||
};
|
||||
|
||||
struct scriptshaping_context
|
||||
{
|
||||
|
@ -328,21 +339,38 @@ struct scriptshaping_context
|
|||
UINT32 language_tag;
|
||||
|
||||
const WCHAR *text;
|
||||
UINT32 length;
|
||||
unsigned int length;
|
||||
BOOL is_rtl;
|
||||
|
||||
UINT32 max_glyph_count;
|
||||
};
|
||||
|
||||
extern HRESULT create_scriptshaping_cache(IDWriteFontFace*,struct scriptshaping_cache**) DECLSPEC_HIDDEN;
|
||||
struct shaping_font_ops
|
||||
{
|
||||
void (*grab_font_table)(void *context, UINT32 table, const BYTE **data, UINT32 *size, void **data_context);
|
||||
void (*release_font_table)(void *context, void *data_context);
|
||||
UINT16 (*get_font_upem)(void *context);
|
||||
};
|
||||
|
||||
extern struct scriptshaping_cache *create_scriptshaping_cache(void *context,
|
||||
const struct shaping_font_ops *font_ops) DECLSPEC_HIDDEN;
|
||||
extern void release_scriptshaping_cache(struct scriptshaping_cache*) DECLSPEC_HIDDEN;
|
||||
extern struct scriptshaping_cache *fontface_get_shaping_cache(struct dwrite_fontface *fontface) DECLSPEC_HIDDEN;
|
||||
|
||||
struct shaping_features
|
||||
{
|
||||
const DWORD *tags;
|
||||
unsigned int count;
|
||||
};
|
||||
|
||||
struct scriptshaping_ops
|
||||
{
|
||||
HRESULT (*contextual_shaping)(struct scriptshaping_context *context, UINT16 *clustermap, UINT16 *glyph_indices, UINT32* actual_glyph_count);
|
||||
HRESULT (*set_text_glyphs_props)(struct scriptshaping_context *context, UINT16 *clustermap, UINT16 *glyph_indices,
|
||||
UINT32 glyphcount, DWRITE_SHAPING_TEXT_PROPERTIES *text_props, DWRITE_SHAPING_GLYPH_PROPERTIES *glyph_props);
|
||||
const struct shaping_features *gpos_features;
|
||||
};
|
||||
|
||||
extern const struct scriptshaping_ops default_shaping_ops DECLSPEC_HIDDEN;
|
||||
extern const struct scriptshaping_ops latn_shaping_ops DECLSPEC_HIDDEN;
|
||||
|
||||
extern HRESULT shape_get_positions(struct scriptshaping_context *context, const DWORD *scripts,
|
||||
const struct shaping_features *features) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -240,6 +240,8 @@ struct dwrite_fontface {
|
|||
FONTSIGNATURE fontsig;
|
||||
UINT32 glyph_image_formats;
|
||||
|
||||
struct scriptshaping_cache *shaping_cache;
|
||||
|
||||
LOGFONTW lf;
|
||||
};
|
||||
|
||||
|
@ -263,6 +265,47 @@ struct dwrite_fontfacereference {
|
|||
IDWriteFactory5 *factory;
|
||||
};
|
||||
|
||||
static void dwrite_grab_font_table(void *context, UINT32 table, const BYTE **data, UINT32 *size, void **data_context)
|
||||
{
|
||||
struct dwrite_fontface *fontface = context;
|
||||
BOOL exists = FALSE;
|
||||
|
||||
if (FAILED(IDWriteFontFace4_TryGetFontTable(&fontface->IDWriteFontFace4_iface, table, (const void **)data,
|
||||
size, data_context, &exists)) || !exists)
|
||||
{
|
||||
*data = NULL;
|
||||
*size = 0;
|
||||
*data_context = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void dwrite_release_font_table(void *context, void *data_context)
|
||||
{
|
||||
struct dwrite_fontface *fontface = context;
|
||||
IDWriteFontFace4_ReleaseFontTable(&fontface->IDWriteFontFace4_iface, data_context);
|
||||
}
|
||||
|
||||
static UINT16 dwrite_get_font_upem(void *context)
|
||||
{
|
||||
struct dwrite_fontface *fontface = context;
|
||||
return fontface->metrics.designUnitsPerEm;
|
||||
}
|
||||
|
||||
static const struct shaping_font_ops dwrite_font_ops =
|
||||
{
|
||||
dwrite_grab_font_table,
|
||||
dwrite_release_font_table,
|
||||
dwrite_get_font_upem,
|
||||
};
|
||||
|
||||
struct scriptshaping_cache *fontface_get_shaping_cache(struct dwrite_fontface *fontface)
|
||||
{
|
||||
if (fontface->shaping_cache)
|
||||
return fontface->shaping_cache;
|
||||
|
||||
return fontface->shaping_cache = create_scriptshaping_cache(fontface, &dwrite_font_ops);
|
||||
}
|
||||
|
||||
static inline struct dwrite_fontface *impl_from_IDWriteFontFace4(IDWriteFontFace4 *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, struct dwrite_fontface, IDWriteFontFace4_iface);
|
||||
|
@ -493,7 +536,7 @@ static ULONG WINAPI dwritefontface_Release(IDWriteFontFace4 *iface)
|
|||
factory_unlock(This->factory);
|
||||
heap_free(This->cached);
|
||||
}
|
||||
|
||||
release_scriptshaping_cache(This->shaping_cache);
|
||||
if (This->cmap.context)
|
||||
IDWriteFontFace4_ReleaseFontTable(iface, This->cmap.context);
|
||||
if (This->vdmx.context)
|
||||
|
@ -1775,7 +1818,7 @@ static struct dwrite_font *unsafe_impl_from_IDWriteFont(IDWriteFont *iface)
|
|||
return CONTAINING_RECORD(iface, struct dwrite_font, IDWriteFont3_iface);
|
||||
}
|
||||
|
||||
static struct dwrite_fontface *unsafe_impl_from_IDWriteFontFace(IDWriteFontFace *iface)
|
||||
struct dwrite_fontface *unsafe_impl_from_IDWriteFontFace(IDWriteFontFace *iface)
|
||||
{
|
||||
if (!iface)
|
||||
return NULL;
|
||||
|
@ -5363,7 +5406,7 @@ static inline void transform_point(D2D_POINT_2F *point, const DWRITE_MATRIX *m)
|
|||
*point = ret;
|
||||
}
|
||||
|
||||
static float fontface_get_scaled_design_advance(struct dwrite_fontface *fontface, DWRITE_MEASURING_MODE measuring_mode,
|
||||
float fontface_get_scaled_design_advance(struct dwrite_fontface *fontface, DWRITE_MEASURING_MODE measuring_mode,
|
||||
float emsize, float ppdip, const DWRITE_MATRIX *transform, UINT16 glyph, BOOL is_sideways)
|
||||
{
|
||||
unsigned int upem = fontface->metrics.designUnitsPerEm;
|
||||
|
|
|
@ -23,32 +23,26 @@
|
|||
|
||||
#include "dwrite_private.h"
|
||||
|
||||
struct scriptshaping_cache
|
||||
struct scriptshaping_cache *create_scriptshaping_cache(void *context, const struct shaping_font_ops *font_ops)
|
||||
{
|
||||
IDWriteFontFace *fontface;
|
||||
};
|
||||
struct scriptshaping_cache *cache;
|
||||
|
||||
HRESULT create_scriptshaping_cache(IDWriteFontFace *fontface, struct scriptshaping_cache **cache)
|
||||
{
|
||||
struct scriptshaping_cache *ret;
|
||||
cache = heap_alloc_zero(sizeof(*cache));
|
||||
if (!cache)
|
||||
return NULL;
|
||||
|
||||
ret = heap_alloc(sizeof(*ret));
|
||||
if (!ret)
|
||||
return E_OUTOFMEMORY;
|
||||
cache->font = font_ops;
|
||||
cache->context = context;
|
||||
|
||||
ret->fontface = fontface;
|
||||
IDWriteFontFace_AddRef(fontface);
|
||||
cache->upem = cache->font->get_font_upem(cache->context);
|
||||
|
||||
*cache = ret;
|
||||
|
||||
return S_OK;
|
||||
return cache;
|
||||
}
|
||||
|
||||
void release_scriptshaping_cache(struct scriptshaping_cache *cache)
|
||||
{
|
||||
if (!cache)
|
||||
return;
|
||||
IDWriteFontFace_Release(cache->fontface);
|
||||
heap_free(cache);
|
||||
}
|
||||
|
||||
|
@ -160,10 +154,24 @@ static HRESULT latn_set_text_glyphs_props(struct scriptshaping_context *context,
|
|||
return hr;
|
||||
}
|
||||
|
||||
static const DWORD std_gpos_tags[] =
|
||||
{
|
||||
DWRITE_FONT_FEATURE_TAG_KERNING,
|
||||
DWRITE_FONT_FEATURE_TAG_MARK_POSITIONING,
|
||||
DWRITE_FONT_FEATURE_TAG_MARK_TO_MARK_POSITIONING,
|
||||
};
|
||||
|
||||
static const struct shaping_features std_gpos_features =
|
||||
{
|
||||
std_gpos_tags,
|
||||
ARRAY_SIZE(std_gpos_tags),
|
||||
};
|
||||
|
||||
const struct scriptshaping_ops latn_shaping_ops =
|
||||
{
|
||||
NULL,
|
||||
latn_set_text_glyphs_props
|
||||
latn_set_text_glyphs_props,
|
||||
&std_gpos_features,
|
||||
};
|
||||
|
||||
const struct scriptshaping_ops default_shaping_ops =
|
||||
|
@ -171,3 +179,11 @@ const struct scriptshaping_ops default_shaping_ops =
|
|||
NULL,
|
||||
default_set_text_glyphs_props
|
||||
};
|
||||
|
||||
HRESULT shape_get_positions(struct scriptshaping_context *context, const DWORD *scripts,
|
||||
const struct shaping_features *features)
|
||||
{
|
||||
/* FIXME: stub */
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue