[PATCH 2/4] dwrite: Add simulated oblique faces
Nikolay Sivov
nsivov at codeweavers.com
Wed Sep 2 23:36:01 CDT 2015
---
-------------- next part --------------
>From 0ef3da45c3ba2ba9777abbbb1ebda709847d5899 Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <nsivov at codeweavers.com>
Date: Wed, 2 Sep 2015 23:21:23 +0300
Subject: [PATCH 2/4] dwrite: Add simulated oblique faces
---
dlls/dwrite/font.c | 116 +++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 87 insertions(+), 29 deletions(-)
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index 215546d..3daab79 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -87,7 +87,11 @@ struct dwrite_font_data {
WCHAR *facename;
- BOOL bold_sim_tested : 1; /* used to mark font as tested when scanning for bold simulation candidate */
+ USHORT simulations;
+
+ /* used to mark font as tested when scanning for simulation candidate */
+ BOOL bold_sim_tested : 1;
+ BOOL oblique_sim_tested : 1;
};
struct dwrite_fontfamily_data {
@@ -125,7 +129,6 @@ struct dwrite_font {
IDWriteFontFamily *family;
- USHORT simulations;
DWRITE_FONT_STYLE style;
struct dwrite_font_data *data;
};
@@ -1135,7 +1138,7 @@ static HRESULT get_fontface_from_font(struct dwrite_font *font, IDWriteFontFace2
*fontface = NULL;
hr = IDWriteFactory2_CreateFontFace(data->factory, data->face_type, 1, &data->file,
- data->face_index, font->simulations, &face);
+ data->face_index, font->data->simulations, &face);
if (FAILED(hr))
return hr;
@@ -1248,10 +1251,10 @@ static HRESULT WINAPI dwritefont_GetFaceNames(IDWriteFont2 *iface, IDWriteLocali
*names = NULL;
- if (This->simulations == DWRITE_FONT_SIMULATIONS_NONE)
+ if (This->data->simulations == DWRITE_FONT_SIMULATIONS_NONE)
return clone_localizedstring(This->data->names, names);
- switch (This->simulations) {
+ switch (This->data->simulations) {
case DWRITE_FONT_SIMULATIONS_BOLD|DWRITE_FONT_SIMULATIONS_OBLIQUE:
name = boldobliqueW;
break;
@@ -1262,7 +1265,7 @@ static HRESULT WINAPI dwritefont_GetFaceNames(IDWriteFont2 *iface, IDWriteLocali
name = obliqueW;
break;
default:
- ERR("unknown simulations %d\n", This->simulations);
+ ERR("unknown simulations %d\n", This->data->simulations);
return E_FAIL;
}
@@ -1331,7 +1334,7 @@ static DWRITE_FONT_SIMULATIONS WINAPI dwritefont_GetSimulations(IDWriteFont2 *if
{
struct dwrite_font *This = impl_from_IDWriteFont2(iface);
TRACE("(%p)\n", This);
- return This->simulations;
+ return This->data->simulations;
}
static void WINAPI dwritefont_GetMetrics(IDWriteFont2 *iface, DWRITE_FONT_METRICS *metrics)
@@ -1461,8 +1464,7 @@ static const IDWriteFont2Vtbl dwritefontvtbl = {
dwritefont2_IsColorFont
};
-static HRESULT create_font(struct dwrite_font_data *data, IDWriteFontFamily *family, DWRITE_FONT_SIMULATIONS simulations,
- IDWriteFont **font)
+static HRESULT create_font(struct dwrite_font_data *data, IDWriteFontFamily *family, IDWriteFont **font)
{
struct dwrite_font *This;
*font = NULL;
@@ -1474,15 +1476,10 @@ static HRESULT create_font(struct dwrite_font_data *data, IDWriteFontFamily *fam
This->ref = 1;
This->family = family;
IDWriteFontFamily_AddRef(family);
- This->simulations = simulations;
This->style = data->style;
This->data = data;
InterlockedIncrement(&This->data->ref);
- /* set oblique style from requested simulation */
- if ((simulations & DWRITE_FONT_SIMULATIONS_OBLIQUE) && data->style == DWRITE_FONT_STYLE_NORMAL)
- This->style = DWRITE_FONT_STYLE_OBLIQUE;
-
*font = (IDWriteFont*)&This->IDWriteFont2_iface;
return S_OK;
@@ -1562,7 +1559,7 @@ static HRESULT WINAPI dwritefontfamily_GetFont(IDWriteFontFamily *iface, UINT32
if (index >= This->data->font_count)
return E_INVALIDARG;
- return create_font(This->data->fonts[index], iface, DWRITE_FONT_SIMULATIONS_NONE, font);
+ return create_font(This->data->fonts[index], iface, font);
}
static HRESULT WINAPI dwritefontfamily_GetFamilyNames(IDWriteFontFamily *iface, IDWriteLocalizedStrings **names)
@@ -1616,7 +1613,6 @@ static HRESULT WINAPI dwritefontfamily_GetFirstMatchingFont(IDWriteFontFamily *i
DWRITE_FONT_STRETCH stretch, DWRITE_FONT_STYLE style, IDWriteFont **font)
{
struct dwrite_fontfamily *This = impl_from_IDWriteFontFamily(iface);
- DWRITE_FONT_SIMULATIONS simulations;
struct dwrite_font_propvec req;
struct dwrite_font_data *match;
UINT32 i;
@@ -1636,13 +1632,7 @@ static HRESULT WINAPI dwritefontfamily_GetFirstMatchingFont(IDWriteFontFamily *i
match = This->data->fonts[i];
}
- simulations = DWRITE_FONT_SIMULATIONS_NONE;
- if (((style == DWRITE_FONT_STYLE_ITALIC) || (style == DWRITE_FONT_STYLE_OBLIQUE)) &&
- match->style == DWRITE_FONT_STYLE_NORMAL) {
- simulations = DWRITE_FONT_SIMULATIONS_OBLIQUE;
- }
-
- return create_font(match, iface, simulations, font);
+ return create_font(match, iface, font);
}
static HRESULT WINAPI dwritefontfamily_GetMatchingFonts(IDWriteFontFamily *iface, DWRITE_FONT_WEIGHT weight,
@@ -1816,7 +1806,6 @@ static HRESULT WINAPI dwritefontcollection_GetFontFromFontFace(IDWriteFontCollec
struct dwrite_fontcollection *This = impl_from_IDWriteFontCollection(iface);
struct dwrite_fontfamily_data *found_family = NULL;
struct dwrite_font_data *found_font = NULL;
- DWRITE_FONT_SIMULATIONS simulations;
IDWriteFontFamily *family;
UINT32 i, j, face_index;
IDWriteFontFile *file;
@@ -1855,8 +1844,7 @@ static HRESULT WINAPI dwritefontcollection_GetFontFromFontFace(IDWriteFontCollec
if (FAILED(hr))
return hr;
- simulations = IDWriteFontFace_GetSimulations(face);
- hr = create_font(found_font, family, simulations, font);
+ hr = create_font(found_font, family, font);
IDWriteFontFamily_Release(family);
return hr;
}
@@ -2687,7 +2675,9 @@ static HRESULT init_font_data(IDWriteFactory2 *factory, IDWriteFontFile *file, D
data->file = file;
data->face_index = face_index;
data->face_type = face_type;
+ data->simulations = DWRITE_FONT_SIMULATIONS_NONE;
data->bold_sim_tested = FALSE;
+ data->oblique_sim_tested = FALSE;
IDWriteFontFile_AddRef(file);
IDWriteFactory2_AddRef(factory);
@@ -2722,7 +2712,7 @@ static HRESULT init_font_data(IDWriteFactory2 *factory, IDWriteFontFile *file, D
return S_OK;
}
-static HRESULT init_font_data_from_font(const struct dwrite_font_data *src, DWRITE_FONT_WEIGHT weight, const WCHAR *facenameW,
+static HRESULT init_font_data_from_font(const struct dwrite_font_data *src, DWRITE_FONT_SIMULATIONS sim, const WCHAR *facenameW,
struct dwrite_font_data **ret)
{
struct dwrite_font_data *data;
@@ -2734,7 +2724,11 @@ static HRESULT init_font_data_from_font(const struct dwrite_font_data *src, DWRI
*data = *src;
data->ref = 1;
- data->weight = weight;
+ data->simulations |= sim;
+ if (sim == DWRITE_FONT_SIMULATIONS_BOLD)
+ data->weight = DWRITE_FONT_WEIGHT_BOLD;
+ else if (sim == DWRITE_FONT_SIMULATIONS_OBLIQUE)
+ data->style = DWRITE_FONT_STYLE_OBLIQUE;
memset(data->info_strings, 0, sizeof(data->info_strings));
data->names = NULL;
IDWriteFactory2_AddRef(data->factory);
@@ -2837,7 +2831,7 @@ static void fontfamily_add_bold_simulated_face(struct dwrite_fontfamily_data *fa
strcatW(facenameW, spaceW);
strcatW(facenameW, boldW);
- if (init_font_data_from_font(family->fonts[heaviest], DWRITE_FONT_WEIGHT_BOLD, facenameW, &boldface) == S_OK) {
+ if (init_font_data_from_font(family->fonts[heaviest], DWRITE_FONT_SIMULATIONS_BOLD, facenameW, &boldface) == S_OK) {
boldface->bold_sim_tested = TRUE;
fontfamily_add_font(family, boldface);
}
@@ -2845,6 +2839,69 @@ static void fontfamily_add_bold_simulated_face(struct dwrite_fontfamily_data *fa
}
}
+static void fontfamily_add_oblique_simulated_face(struct dwrite_fontfamily_data *family)
+{
+ UINT32 i, j;
+
+ for (i = 0; i < family->font_count; i++) {
+ UINT32 regular = ~0u, oblique = ~0u;
+ struct dwrite_font_data *obliqueface;
+ WCHAR facenameW[255];
+
+ if (family->fonts[i]->oblique_sim_tested)
+ continue;
+
+ family->fonts[i]->oblique_sim_tested = TRUE;
+ if (family->fonts[i]->style == DWRITE_FONT_STYLE_NORMAL)
+ regular = i;
+ else if (family->fonts[i]->style == DWRITE_FONT_STYLE_OBLIQUE)
+ oblique = i;
+
+ /* find regular style with same weight/stretch values */
+ for (j = i; j < family->font_count; j++) {
+ if (family->fonts[j]->oblique_sim_tested)
+ continue;
+
+ if ((family->fonts[i]->weight == family->fonts[j]->weight) &&
+ (family->fonts[i]->stretch == family->fonts[j]->stretch)) {
+
+ family->fonts[j]->oblique_sim_tested = TRUE;
+ if (regular == ~0 && family->fonts[j]->style == DWRITE_FONT_STYLE_NORMAL)
+ regular = j;
+
+ if (oblique == ~0 && family->fonts[j]->style == DWRITE_FONT_STYLE_OBLIQUE)
+ oblique = j;
+ }
+
+ if (regular != ~0u && oblique != ~0u)
+ break;
+ }
+
+ /* no regular variant for this weight/stretch pair, nothing to base simulated face on */
+ if (regular == ~0u)
+ continue;
+
+ /* regular face exists, and corresponding oblique is present as well, nothing to do */
+ if (oblique != ~0u)
+ continue;
+
+ /* add oblique simulation based on this regular face */
+
+ /* remove regular term if any, append 'Oblique' */
+ fontstrings_get_en_string(family->fonts[regular]->names, facenameW, sizeof(facenameW)/sizeof(WCHAR));
+ facename_remove_regular_term(facenameW, -1);
+
+ if (*facenameW)
+ strcatW(facenameW, spaceW);
+ strcatW(facenameW, obliqueW);
+
+ if (init_font_data_from_font(family->fonts[regular], DWRITE_FONT_SIMULATIONS_OBLIQUE, facenameW, &obliqueface) == S_OK) {
+ obliqueface->oblique_sim_tested = TRUE;
+ fontfamily_add_font(family, obliqueface);
+ }
+ }
+}
+
HRESULT create_font_collection(IDWriteFactory2* factory, IDWriteFontFileEnumerator *enumerator, BOOL is_system, IDWriteFontCollection **ret)
{
struct dwrite_fontcollection *collection;
@@ -2935,6 +2992,7 @@ HRESULT create_font_collection(IDWriteFactory2* factory, IDWriteFontFileEnumerat
for (i = 0; i < collection->family_count; i++) {
fontfamily_add_bold_simulated_face(collection->family_data[i]);
+ fontfamily_add_oblique_simulated_face(collection->family_data[i]);
}
return hr;
--
2.1.4
More information about the wine-patches
mailing list