Commit d1c73489 authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

dwrite: Add a helper to get shaped glyph positions.

parent e020d6c9
...@@ -1157,16 +1157,14 @@ static HRESULT WINAPI dwritetextanalyzer_GetGlyphs(IDWriteTextAnalyzer2 *iface, ...@@ -1157,16 +1157,14 @@ static HRESULT WINAPI dwritetextanalyzer_GetGlyphs(IDWriteTextAnalyzer2 *iface,
UINT16* clustermap, DWRITE_SHAPING_TEXT_PROPERTIES* text_props, UINT16* glyph_indices, UINT16* clustermap, DWRITE_SHAPING_TEXT_PROPERTIES* text_props, UINT16* glyph_indices,
DWRITE_SHAPING_GLYPH_PROPERTIES* glyph_props, UINT32* actual_glyph_count) DWRITE_SHAPING_GLYPH_PROPERTIES* glyph_props, UINT32* actual_glyph_count)
{ {
const struct dwritescript_properties *scriptprops;
DWRITE_NUMBER_SUBSTITUTION_METHOD method; DWRITE_NUMBER_SUBSTITUTION_METHOD method;
struct scriptshaping_context context; struct scriptshaping_context context;
struct scriptshaping_cache *cache = NULL; struct dwrite_fontface *font_obj;
WCHAR digits[NATIVE_DIGITS_LEN]; WCHAR digits[NATIVE_DIGITS_LEN];
BOOL update_cluster; BOOL update_cluster;
WCHAR *string; WCHAR *string;
UINT32 i, g; UINT32 i, g;
HRESULT hr = S_OK; 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), 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, 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, ...@@ -1175,8 +1173,6 @@ static HRESULT WINAPI dwritetextanalyzer_GetGlyphs(IDWriteTextAnalyzer2 *iface,
analyzer_dump_user_features(features, feature_range_lengths, feature_ranges); analyzer_dump_user_features(features, feature_range_lengths, feature_ranges);
script = analysis->script > Script_LastId ? Script_Unknown : analysis->script;
if (max_glyph_count < length) if (max_glyph_count < length)
return E_NOT_SUFFICIENT_BUFFER; return E_NOT_SUFFICIENT_BUFFER;
...@@ -1253,33 +1249,19 @@ static HRESULT WINAPI dwritetextanalyzer_GetGlyphs(IDWriteTextAnalyzer2 *iface, ...@@ -1253,33 +1249,19 @@ static HRESULT WINAPI dwritetextanalyzer_GetGlyphs(IDWriteTextAnalyzer2 *iface,
} }
*actual_glyph_count = g; *actual_glyph_count = g;
hr = create_scriptshaping_cache(fontface, &cache); font_obj = unsafe_impl_from_IDWriteFontFace(fontface);
if (FAILED(hr))
goto done;
context.cache = cache; context.cache = fontface_get_shaping_cache(font_obj);
context.text = text; context.text = text;
context.length = length; context.length = length;
context.is_rtl = is_rtl; context.is_rtl = is_rtl;
context.max_glyph_count = max_glyph_count;
context.language_tag = get_opentype_language(locale); 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 */ /* 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: done:
release_scriptshaping_cache(cache);
heap_free(string); heap_free(string);
return hr; return hr;
...@@ -1288,14 +1270,14 @@ done: ...@@ -1288,14 +1270,14 @@ done:
static HRESULT WINAPI dwritetextanalyzer_GetGlyphPlacements(IDWriteTextAnalyzer2 *iface, static HRESULT WINAPI dwritetextanalyzer_GetGlyphPlacements(IDWriteTextAnalyzer2 *iface,
WCHAR const* text, UINT16 const* clustermap, DWRITE_SHAPING_TEXT_PROPERTIES* props, 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 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, 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; const struct dwritescript_properties *scriptprops;
IDWriteFontFace1 *fontface1; struct dwrite_fontface *font_obj;
HRESULT hr; unsigned int i, script;
UINT32 i; 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), 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, clustermap, props, text_len, glyphs, glyph_props, glyph_count, fontface, emSize, is_sideways,
...@@ -1307,46 +1289,51 @@ static HRESULT WINAPI dwritetextanalyzer_GetGlyphPlacements(IDWriteTextAnalyzer2 ...@@ -1307,46 +1289,51 @@ static HRESULT WINAPI dwritetextanalyzer_GetGlyphPlacements(IDWriteTextAnalyzer2
if (glyph_count == 0) if (glyph_count == 0)
return S_OK; return S_OK;
hr = IDWriteFontFace_QueryInterface(fontface, &IID_IDWriteFontFace1, (void**)&fontface1); font_obj = unsafe_impl_from_IDWriteFontFace(fontface);
if (FAILED(hr)) {
WARN("failed to get IDWriteFontFace1.\n");
return hr;
}
IDWriteFontFace_GetMetrics(fontface, &metrics); for (i = 0; i < glyph_count; ++i)
for (i = 0; i < glyph_count; i++) { {
if (glyph_props[i].isZeroWidthSpace) if (glyph_props[i].isZeroWidthSpace)
advances[i] = 0.0f; advances[i] = 0.0f;
else { else
INT32 a; advances[i] = fontface_get_scaled_design_advance(font_obj, DWRITE_MEASURING_MODE_NATURAL, emSize, 1.0f,
NULL, glyphs[i], is_sideways);
hr = IDWriteFontFace1_GetDesignGlyphAdvances(fontface1, 1, &glyphs[i], &a, is_sideways);
if (FAILED(hr))
a = 0;
advances[i] = get_scaled_advance_width(a, emSize, &metrics);
}
offsets[i].advanceOffset = 0.0f; offsets[i].advanceOffset = 0.0f;
offsets[i].ascenderOffset = 0.0f; offsets[i].ascenderOffset = 0.0f;
} }
/* FIXME: actually apply features */ script = analysis->script > Script_LastId ? Script_Unknown : analysis->script;
IDWriteFontFace1_Release(fontface1); scriptprops = &dwritescripts_properties[script];
return S_OK; 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, static HRESULT WINAPI dwritetextanalyzer_GetGdiCompatibleGlyphPlacements(IDWriteTextAnalyzer2 *iface,
WCHAR const* text, UINT16 const* clustermap, DWRITE_SHAPING_TEXT_PROPERTIES* props, 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 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_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, 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; const struct dwritescript_properties *scriptprops;
IDWriteFontFace1 *fontface1; DWRITE_MEASURING_MODE measuring_mode;
HRESULT hr; struct dwrite_fontface *font_obj;
UINT32 i; 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), 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, clustermap, props, text_len, glyphs, glyph_props, glyph_count, fontface, emSize, ppdip,
...@@ -1358,35 +1345,38 @@ static HRESULT WINAPI dwritetextanalyzer_GetGdiCompatibleGlyphPlacements(IDWrite ...@@ -1358,35 +1345,38 @@ static HRESULT WINAPI dwritetextanalyzer_GetGdiCompatibleGlyphPlacements(IDWrite
if (glyph_count == 0) if (glyph_count == 0)
return S_OK; return S_OK;
hr = IDWriteFontFace_QueryInterface(fontface, &IID_IDWriteFontFace1, (void**)&fontface1); font_obj = unsafe_impl_from_IDWriteFontFace(fontface);
if (FAILED(hr)) {
WARN("failed to get IDWriteFontFace1.\n");
return hr;
}
hr = IDWriteFontFace_GetGdiCompatibleMetrics(fontface, emSize, ppdip, transform, &metrics); measuring_mode = use_gdi_natural ? DWRITE_MEASURING_MODE_GDI_NATURAL : DWRITE_MEASURING_MODE_GDI_CLASSIC;
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;
hr = IDWriteFontFace1_GetGdiCompatibleGlyphAdvances(fontface1, emSize, ppdip, for (i = 0; i < glyph_count; ++i)
transform, use_gdi_natural, is_sideways, 1, &glyphs[i], &a); {
if (FAILED(hr)) if (glyph_props[i].isZeroWidthSpace)
advances[i] = 0.0f; advances[i] = 0.0f;
else 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].advanceOffset = 0.0f;
offsets[i].ascenderOffset = 0.0f; offsets[i].ascenderOffset = 0.0f;
} }
/* FIXME: actually apply features */ script = analysis->script > Script_LastId ? Script_Unknown : analysis->script;
IDWriteFontFace1_Release(fontface1); scriptprops = &dwritescripts_properties[script];
return S_OK; 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) static inline FLOAT get_cluster_advance(const FLOAT *advances, UINT32 start, UINT32 end)
......
...@@ -192,6 +192,12 @@ extern void factory_lock(IDWriteFactory5*) DECLSPEC_HIDDEN; ...@@ -192,6 +192,12 @@ extern void factory_lock(IDWriteFactory5*) DECLSPEC_HIDDEN;
extern void factory_unlock(IDWriteFactory5*) DECLSPEC_HIDDEN; extern void factory_unlock(IDWriteFactory5*) DECLSPEC_HIDDEN;
extern HRESULT create_inmemory_fileloader(IDWriteFontFileLoader**) 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 */ /* Opentype font table functions */
struct dwrite_font_props { struct dwrite_font_props {
DWRITE_FONT_STYLE style; DWRITE_FONT_STYLE style;
...@@ -320,7 +326,12 @@ enum SCRIPT_JUSTIFY ...@@ -320,7 +326,12 @@ enum SCRIPT_JUSTIFY
SCRIPT_JUSTIFY_ARABIC_SEEN_M SCRIPT_JUSTIFY_ARABIC_SEEN_M
}; };
struct scriptshaping_cache; struct scriptshaping_cache
{
const struct shaping_font_ops *font;
void *context;
UINT16 upem;
};
struct scriptshaping_context struct scriptshaping_context
{ {
...@@ -328,21 +339,38 @@ struct scriptshaping_context ...@@ -328,21 +339,38 @@ struct scriptshaping_context
UINT32 language_tag; UINT32 language_tag;
const WCHAR *text; const WCHAR *text;
UINT32 length; unsigned int length;
BOOL is_rtl; BOOL is_rtl;
};
UINT32 max_glyph_count; 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 HRESULT create_scriptshaping_cache(IDWriteFontFace*,struct scriptshaping_cache**) DECLSPEC_HIDDEN; 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 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 struct scriptshaping_ops
{ {
HRESULT (*contextual_shaping)(struct scriptshaping_context *context, UINT16 *clustermap, UINT16 *glyph_indices, UINT32* actual_glyph_count); 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, 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); 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 default_shaping_ops DECLSPEC_HIDDEN;
extern const struct scriptshaping_ops latn_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 { ...@@ -240,6 +240,8 @@ struct dwrite_fontface {
FONTSIGNATURE fontsig; FONTSIGNATURE fontsig;
UINT32 glyph_image_formats; UINT32 glyph_image_formats;
struct scriptshaping_cache *shaping_cache;
LOGFONTW lf; LOGFONTW lf;
}; };
...@@ -263,6 +265,47 @@ struct dwrite_fontfacereference { ...@@ -263,6 +265,47 @@ struct dwrite_fontfacereference {
IDWriteFactory5 *factory; 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) static inline struct dwrite_fontface *impl_from_IDWriteFontFace4(IDWriteFontFace4 *iface)
{ {
return CONTAINING_RECORD(iface, struct dwrite_fontface, IDWriteFontFace4_iface); return CONTAINING_RECORD(iface, struct dwrite_fontface, IDWriteFontFace4_iface);
...@@ -493,7 +536,7 @@ static ULONG WINAPI dwritefontface_Release(IDWriteFontFace4 *iface) ...@@ -493,7 +536,7 @@ static ULONG WINAPI dwritefontface_Release(IDWriteFontFace4 *iface)
factory_unlock(This->factory); factory_unlock(This->factory);
heap_free(This->cached); heap_free(This->cached);
} }
release_scriptshaping_cache(This->shaping_cache);
if (This->cmap.context) if (This->cmap.context)
IDWriteFontFace4_ReleaseFontTable(iface, This->cmap.context); IDWriteFontFace4_ReleaseFontTable(iface, This->cmap.context);
if (This->vdmx.context) if (This->vdmx.context)
...@@ -1775,7 +1818,7 @@ static struct dwrite_font *unsafe_impl_from_IDWriteFont(IDWriteFont *iface) ...@@ -1775,7 +1818,7 @@ static struct dwrite_font *unsafe_impl_from_IDWriteFont(IDWriteFont *iface)
return CONTAINING_RECORD(iface, struct dwrite_font, IDWriteFont3_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) if (!iface)
return NULL; return NULL;
...@@ -5363,7 +5406,7 @@ static inline void transform_point(D2D_POINT_2F *point, const DWRITE_MATRIX *m) ...@@ -5363,7 +5406,7 @@ static inline void transform_point(D2D_POINT_2F *point, const DWRITE_MATRIX *m)
*point = ret; *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) float emsize, float ppdip, const DWRITE_MATRIX *transform, UINT16 glyph, BOOL is_sideways)
{ {
unsigned int upem = fontface->metrics.designUnitsPerEm; unsigned int upem = fontface->metrics.designUnitsPerEm;
......
...@@ -23,32 +23,26 @@ ...@@ -23,32 +23,26 @@
#include "dwrite_private.h" #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;
ret = heap_alloc(sizeof(*ret)); cache = heap_alloc_zero(sizeof(*cache));
if (!ret) if (!cache)
return E_OUTOFMEMORY; return NULL;
ret->fontface = fontface; cache->font = font_ops;
IDWriteFontFace_AddRef(fontface); cache->context = context;
*cache = ret; cache->upem = cache->font->get_font_upem(cache->context);
return S_OK; return cache;
} }
void release_scriptshaping_cache(struct scriptshaping_cache *cache) void release_scriptshaping_cache(struct scriptshaping_cache *cache)
{ {
if (!cache) if (!cache)
return; return;
IDWriteFontFace_Release(cache->fontface);
heap_free(cache); heap_free(cache);
} }
...@@ -160,10 +154,24 @@ static HRESULT latn_set_text_glyphs_props(struct scriptshaping_context *context, ...@@ -160,10 +154,24 @@ static HRESULT latn_set_text_glyphs_props(struct scriptshaping_context *context,
return hr; 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 = const struct scriptshaping_ops latn_shaping_ops =
{ {
NULL, NULL,
latn_set_text_glyphs_props latn_set_text_glyphs_props,
&std_gpos_features,
}; };
const struct scriptshaping_ops default_shaping_ops = const struct scriptshaping_ops default_shaping_ops =
...@@ -171,3 +179,11 @@ const struct scriptshaping_ops default_shaping_ops = ...@@ -171,3 +179,11 @@ const struct scriptshaping_ops default_shaping_ops =
NULL, NULL,
default_set_text_glyphs_props 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment