dwrite: Use current layout fallback when creating run font faces.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
5d17404287
commit
7fc7f2f074
|
@ -1745,7 +1745,7 @@ static const struct fallback_mapping *find_fallback_mapping(struct dwrite_fontfa
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT create_matching_font(IDWriteFontCollection *collection, const WCHAR *name,
|
HRESULT create_matching_font(IDWriteFontCollection *collection, const WCHAR *name,
|
||||||
DWRITE_FONT_WEIGHT weight, DWRITE_FONT_STYLE style, DWRITE_FONT_STRETCH stretch, IDWriteFont **font)
|
DWRITE_FONT_WEIGHT weight, DWRITE_FONT_STYLE style, DWRITE_FONT_STRETCH stretch, IDWriteFont **font)
|
||||||
{
|
{
|
||||||
IDWriteFontFamily *family;
|
IDWriteFontFamily *family;
|
||||||
|
|
|
@ -145,6 +145,8 @@ extern HRESULT create_colorglyphenum(FLOAT,FLOAT,const DWRITE_GLYPH_RUN*,const D
|
||||||
extern BOOL lb_is_newline_char(WCHAR) DECLSPEC_HIDDEN;
|
extern BOOL lb_is_newline_char(WCHAR) DECLSPEC_HIDDEN;
|
||||||
extern HRESULT create_system_fontfallback(IDWriteFactory2*,IDWriteFontFallback**) DECLSPEC_HIDDEN;
|
extern HRESULT create_system_fontfallback(IDWriteFactory2*,IDWriteFontFallback**) DECLSPEC_HIDDEN;
|
||||||
extern void release_system_fontfallback(IDWriteFontFallback*) DECLSPEC_HIDDEN;
|
extern void release_system_fontfallback(IDWriteFontFallback*) DECLSPEC_HIDDEN;
|
||||||
|
extern HRESULT create_matching_font(IDWriteFontCollection*,const WCHAR*,DWRITE_FONT_WEIGHT,DWRITE_FONT_STYLE,DWRITE_FONT_STRETCH,
|
||||||
|
IDWriteFont**) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
/* Opentype font table functions */
|
/* Opentype font table functions */
|
||||||
struct dwrite_font_props {
|
struct dwrite_font_props {
|
||||||
|
|
|
@ -696,39 +696,6 @@ static void layout_set_cluster_metrics(struct dwrite_textlayout *layout, const s
|
||||||
|
|
||||||
#define SCALE_FONT_METRIC(metric, emSize, metrics) ((FLOAT)(metric) * (emSize) / (FLOAT)(metrics)->designUnitsPerEm)
|
#define SCALE_FONT_METRIC(metric, emSize, metrics) ((FLOAT)(metric) * (emSize) / (FLOAT)(metrics)->designUnitsPerEm)
|
||||||
|
|
||||||
static HRESULT create_fontface_by_pos(struct dwrite_textlayout *layout, struct layout_range *range, IDWriteFontFace **fontface)
|
|
||||||
{
|
|
||||||
static DWRITE_GLYPH_RUN_DESCRIPTION descr = { 0 };
|
|
||||||
IDWriteFontFamily *family;
|
|
||||||
BOOL exists = FALSE;
|
|
||||||
IDWriteFont *font;
|
|
||||||
UINT32 index;
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
*fontface = NULL;
|
|
||||||
|
|
||||||
hr = IDWriteFontCollection_FindFamilyName(range->collection, range->fontfamily, &index, &exists);
|
|
||||||
if (FAILED(hr) || !exists) {
|
|
||||||
WARN("%s: family %s not found in collection %p\n", debugstr_rundescr(&descr), debugstr_w(range->fontfamily), range->collection);
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = IDWriteFontCollection_GetFontFamily(range->collection, index, &family);
|
|
||||||
if (FAILED(hr))
|
|
||||||
return hr;
|
|
||||||
|
|
||||||
hr = IDWriteFontFamily_GetFirstMatchingFont(family, range->weight, range->stretch, range->style, &font);
|
|
||||||
IDWriteFontFamily_Release(family);
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
WARN("%s: failed to get a matching font\n", debugstr_rundescr(&descr));
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = IDWriteFont_CreateFontFace(font, fontface);
|
|
||||||
IDWriteFont_Release(font);
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void layout_get_font_metrics(struct dwrite_textlayout *layout, IDWriteFontFace *fontface, FLOAT emsize,
|
static void layout_get_font_metrics(struct dwrite_textlayout *layout, IDWriteFontFace *fontface, FLOAT emsize,
|
||||||
DWRITE_FONT_METRICS *fontmetrics)
|
DWRITE_FONT_METRICS *fontmetrics)
|
||||||
{
|
{
|
||||||
|
@ -749,6 +716,7 @@ static void layout_get_font_height(FLOAT emsize, DWRITE_FONT_METRICS *fontmetric
|
||||||
|
|
||||||
static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
|
static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
|
||||||
{
|
{
|
||||||
|
IDWriteFontFallback *fallback;
|
||||||
IDWriteTextAnalyzer *analyzer;
|
IDWriteTextAnalyzer *analyzer;
|
||||||
struct layout_range *range;
|
struct layout_range *range;
|
||||||
struct layout_run *r;
|
struct layout_run *r;
|
||||||
|
@ -808,6 +776,82 @@ static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (layout->format.fallback) {
|
||||||
|
fallback = layout->format.fallback;
|
||||||
|
IDWriteFontFallback_AddRef(fallback);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hr = IDWriteFactory2_GetSystemFontFallback(layout->factory, &fallback);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* resolve run fonts */
|
||||||
|
LIST_FOR_EACH_ENTRY(r, &layout->runs, struct layout_run, entry) {
|
||||||
|
struct regular_layout_run *run = &r->u.regular;
|
||||||
|
UINT32 length;
|
||||||
|
|
||||||
|
if (r->kind == LAYOUT_RUN_INLINE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
range = get_layout_range_by_pos(layout, run->descr.textPosition);
|
||||||
|
length = run->descr.stringLength;
|
||||||
|
|
||||||
|
while (length) {
|
||||||
|
UINT32 mapped_length;
|
||||||
|
IDWriteFont *font;
|
||||||
|
FLOAT scale;
|
||||||
|
|
||||||
|
run = &r->u.regular;
|
||||||
|
|
||||||
|
hr = IDWriteFontFallback_MapCharacters(fallback,
|
||||||
|
(IDWriteTextAnalysisSource*)&layout->IDWriteTextAnalysisSource1_iface,
|
||||||
|
run->descr.textPosition,
|
||||||
|
run->descr.stringLength,
|
||||||
|
range->collection,
|
||||||
|
range->fontfamily,
|
||||||
|
range->weight,
|
||||||
|
range->style,
|
||||||
|
range->stretch,
|
||||||
|
&mapped_length,
|
||||||
|
&font,
|
||||||
|
&scale);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
WARN("%s: failed to map family %s, collection %p\n", debugstr_rundescr(&run->descr), debugstr_w(range->fontfamily), range->collection);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = IDWriteFont_CreateFontFace(font, &run->run.fontFace);
|
||||||
|
IDWriteFont_Release(font);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return hr;
|
||||||
|
run->run.fontEmSize = range->fontsize * scale;
|
||||||
|
|
||||||
|
if (mapped_length < length) {
|
||||||
|
struct regular_layout_run *nextrun = &r->u.regular;
|
||||||
|
struct layout_run *nextr;
|
||||||
|
|
||||||
|
/* keep mapped part for current run, add another run for the rest */
|
||||||
|
nextr = alloc_layout_run(LAYOUT_RUN_REGULAR);
|
||||||
|
if (!nextr)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
*nextr = *r;
|
||||||
|
nextrun = &nextr->u.regular;
|
||||||
|
nextrun->descr.textPosition = run->descr.textPosition + mapped_length;
|
||||||
|
nextrun->descr.stringLength = run->descr.stringLength - mapped_length;
|
||||||
|
nextrun->descr.string = &layout->str[nextrun->descr.textPosition];
|
||||||
|
run->descr.stringLength = mapped_length;
|
||||||
|
list_add_after(&r->entry, &nextr->entry);
|
||||||
|
r = nextr;
|
||||||
|
}
|
||||||
|
|
||||||
|
length -= mapped_length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IDWriteFontFallback_Release(fallback);
|
||||||
|
|
||||||
/* fill run info */
|
/* fill run info */
|
||||||
LIST_FOR_EACH_ENTRY(r, &layout->runs, struct layout_run, entry) {
|
LIST_FOR_EACH_ENTRY(r, &layout->runs, struct layout_run, entry) {
|
||||||
DWRITE_SHAPING_GLYPH_PROPERTIES *glyph_props = NULL;
|
DWRITE_SHAPING_GLYPH_PROPERTIES *glyph_props = NULL;
|
||||||
|
@ -850,11 +894,6 @@ static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
|
||||||
}
|
}
|
||||||
|
|
||||||
range = get_layout_range_by_pos(layout, run->descr.textPosition);
|
range = get_layout_range_by_pos(layout, run->descr.textPosition);
|
||||||
hr = create_fontface_by_pos(layout, range, &run->run.fontFace);
|
|
||||||
if (FAILED(hr))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
run->run.fontEmSize = range->fontsize;
|
|
||||||
run->descr.localeName = range->locale;
|
run->descr.localeName = range->locale;
|
||||||
run->clustermap = heap_alloc(run->descr.stringLength*sizeof(UINT16));
|
run->clustermap = heap_alloc(run->descr.stringLength*sizeof(UINT16));
|
||||||
|
|
||||||
|
@ -1606,10 +1645,20 @@ static HRESULT layout_set_dummy_line_metrics(struct dwrite_textlayout *layout, U
|
||||||
DWRITE_LINE_METRICS metrics;
|
DWRITE_LINE_METRICS metrics;
|
||||||
struct layout_range *range;
|
struct layout_range *range;
|
||||||
IDWriteFontFace *fontface;
|
IDWriteFontFace *fontface;
|
||||||
|
IDWriteFont *font;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
range = get_layout_range_by_pos(layout, pos);
|
range = get_layout_range_by_pos(layout, pos);
|
||||||
hr = create_fontface_by_pos(layout, range, &fontface);
|
hr = create_matching_font(range->collection,
|
||||||
|
range->fontfamily,
|
||||||
|
range->weight,
|
||||||
|
range->style,
|
||||||
|
range->stretch,
|
||||||
|
&font);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return hr;
|
||||||
|
hr = IDWriteFont_CreateFontFace(font, &fontface);
|
||||||
|
IDWriteFont_Release(font);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
return hr;
|
return hr;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue