[PATCH 5/5] dwrite: Use current layout fallback when creating run font faces
Nikolay Sivov
nsivov at codeweavers.com
Sun Feb 14 10:05:10 CST 2016
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
dlls/dwrite/analyzer.c | 2 +-
dlls/dwrite/dwrite_private.h | 2 +
dlls/dwrite/layout.c | 127 ++++++++++++++++++++++++++++++-------------
3 files changed, 91 insertions(+), 40 deletions(-)
diff --git a/dlls/dwrite/analyzer.c b/dlls/dwrite/analyzer.c
index 10ff0a2..66fa29c 100644
--- a/dlls/dwrite/analyzer.c
+++ b/dlls/dwrite/analyzer.c
@@ -1745,7 +1745,7 @@ static const struct fallback_mapping *find_fallback_mapping(struct dwrite_fontfa
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)
{
IDWriteFontFamily *family;
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index 1e4cf59..5a01061 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -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 HRESULT create_system_fontfallback(IDWriteFactory2*,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 */
struct dwrite_font_props {
diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c
index b60f2ce..164ac48 100644
--- a/dlls/dwrite/layout.c
+++ b/dlls/dwrite/layout.c
@@ -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)
-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,
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)
{
+ IDWriteFontFallback *fallback;
IDWriteTextAnalyzer *analyzer;
struct layout_range *range;
struct layout_run *r;
@@ -808,6 +776,82 @@ static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
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 */
LIST_FOR_EACH_ENTRY(r, &layout->runs, struct layout_run, entry) {
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);
- 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->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;
struct layout_range *range;
IDWriteFontFace *fontface;
+ IDWriteFont *font;
HRESULT hr;
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))
return hr;
--
2.7.0
More information about the wine-patches
mailing list