[PATCH 3/4] dwrite: Implement GetFont() for matching list
Nikolay Sivov
nsivov at codeweavers.com
Tue Sep 8 03:41:28 CDT 2015
---
-------------- next part --------------
From c44114e4d8d0cc8c988f0c63164d0c6e2491c074 Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <nsivov at codeweavers.com>
Date: Tue, 8 Sep 2015 11:30:18 +0300
Subject: [PATCH 3/4] dwrite: Implement GetFont() for matching list
---
dlls/dwrite/font.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 89 insertions(+), 4 deletions(-)
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index 2129094..aea35c9 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -97,6 +97,10 @@ struct dwrite_font_data {
struct dwrite_fontlist {
IDWriteFontList IDWriteFontList_iface;
LONG ref;
+
+ IDWriteFontFamily *family;
+ struct dwrite_font_data **fonts;
+ UINT32 font_count;
};
struct dwrite_fontfamily_data {
@@ -1495,6 +1499,11 @@ static ULONG WINAPI dwritefontlist_Release(IDWriteFontList *iface)
TRACE("(%p)->(%d)\n", This, ref);
if (!ref) {
+ UINT32 i;
+
+ for (i = 0; i < This->font_count; i++)
+ release_font_data(This->fonts[i]);
+ IDWriteFontFamily_Release(This->family);
heap_free(This);
}
@@ -1513,19 +1522,25 @@ static HRESULT WINAPI dwritefontlist_GetFontCollection(IDWriteFontList *iface, I
static UINT32 WINAPI dwritefontlist_GetFontCount(IDWriteFontList *iface)
{
struct dwrite_fontlist *This = impl_from_IDWriteFontList(iface);
- FIXME("(%p): stub\n", This);
- return 0;
+ TRACE("(%p)\n", This);
+ return This->font_count;
}
static HRESULT WINAPI dwritefontlist_GetFont(IDWriteFontList *iface, UINT32 index, IDWriteFont **font)
{
struct dwrite_fontlist *This = impl_from_IDWriteFontList(iface);
- FIXME("(%p)->(%u %p): stub\n", This, index, font);
+ TRACE("(%p)->(%u %p)\n", This, index, font);
*font = NULL;
- return E_NOTIMPL;
+ if (This->font_count == 0)
+ return S_FALSE;
+
+ if (index >= This->font_count)
+ return E_INVALIDARG;
+
+ return create_font(This->fonts[index], This->family, font);
}
static const IDWriteFontListVtbl dwritefontlistvtbl = {
@@ -1687,11 +1702,48 @@ static HRESULT WINAPI dwritefontfamily_GetFirstMatchingFont(IDWriteFontFamily *i
return create_font(match, iface, font);
}
+typedef BOOL (*matching_filter_func)(const struct dwrite_font_data*);
+
+static BOOL is_font_acceptable_for_normal(const struct dwrite_font_data *font)
+{
+ return font->style == DWRITE_FONT_STYLE_NORMAL || font->style == DWRITE_FONT_STYLE_ITALIC;
+}
+
+static BOOL is_font_acceptable_for_oblique_italic(const struct dwrite_font_data *font)
+{
+ return font->style == DWRITE_FONT_STYLE_OBLIQUE || font->style == DWRITE_FONT_STYLE_ITALIC;
+}
+
+static void matchingfonts_sort(struct dwrite_fontlist *fonts, const struct dwrite_font_propvec *req)
+{
+ UINT32 b = fonts->font_count - 1, j, t;
+
+ while (1) {
+ t = b;
+
+ for (j = 0; j < b; j++) {
+ if (is_better_font_match(&fonts->fonts[j+1]->propvec, &fonts->fonts[j]->propvec, req)) {
+ struct dwrite_font_data *s = fonts->fonts[j];
+ fonts->fonts[j] = fonts->fonts[j+1];
+ fonts->fonts[j+1] = s;
+ t = j;
+ }
+ }
+
+ if (t == b)
+ break;
+ b = t;
+ };
+}
+
static HRESULT WINAPI dwritefontfamily_GetMatchingFonts(IDWriteFontFamily *iface, DWRITE_FONT_WEIGHT weight,
DWRITE_FONT_STRETCH stretch, DWRITE_FONT_STYLE style, IDWriteFontList **ret)
{
struct dwrite_fontfamily *This = impl_from_IDWriteFontFamily(iface);
+ matching_filter_func func = NULL;
+ struct dwrite_font_propvec req;
struct dwrite_fontlist *fonts;
+ UINT32 i;
TRACE("(%p)->(%d %d %d %p)\n", This, weight, stretch, style, ret);
@@ -1700,8 +1752,41 @@ static HRESULT WINAPI dwritefontfamily_GetMatchingFonts(IDWriteFontFamily *iface
fonts = heap_alloc(sizeof(*fonts));
if (!fonts)
return E_OUTOFMEMORY;
+
+ /* Allocate as many as family has, not all of them will be necessary used. */
+ fonts->fonts = heap_alloc(sizeof(*fonts->fonts) * This->data->font_count);
+ if (!fonts->fonts) {
+ heap_free(fonts);
+ return E_OUTOFMEMORY;
+ }
+
fonts->IDWriteFontList_iface.lpVtbl = &dwritefontlistvtbl;
fonts->ref = 1;
+ fonts->family = iface;
+ IDWriteFontFamily_AddRef(fonts->family);
+ fonts->font_count = 0;
+
+ /* Normal style accepts Normal or Italic, Oblique and Italic - both Oblique and Italic styles */
+ if (style == DWRITE_FONT_STYLE_NORMAL) {
+ if (This->data->has_normal_face || This->data->has_italic_face)
+ func = is_font_acceptable_for_normal;
+ }
+ else /* requested oblique or italic */ {
+ if (This->data->has_oblique_face || This->data->has_italic_face)
+ func = is_font_acceptable_for_oblique_italic;
+ }
+
+ for (i = 0; i < This->data->font_count; i++) {
+ if (!func || func(This->data->fonts[i])) {
+ fonts->fonts[fonts->font_count] = This->data->fonts[i];
+ InterlockedIncrement(&This->data->fonts[i]->ref);
+ fonts->font_count++;
+ }
+ }
+
+ /* now potential matches are sorted using same criteria GetFirstMatchingFont uses */
+ init_font_prop_vec(weight, stretch, style, &req);
+ matchingfonts_sort(fonts, &req);
*ret = &fonts->IDWriteFontList_iface;
return S_OK;
--
2.1.4
More information about the wine-patches
mailing list