More work on the initial font and showing styles. I have a feeling my current approach is a mistake.
This commit is contained in:
parent
84fc5dafaa
commit
ccfa3d41a3
|
@ -2,7 +2,6 @@
|
||||||
#import "uipriv_darwin.h"
|
#import "uipriv_darwin.h"
|
||||||
|
|
||||||
// TODO drag and drop fonts? what other interactions does NSColorWell allow that we can do for fonts?
|
// TODO drag and drop fonts? what other interactions does NSColorWell allow that we can do for fonts?
|
||||||
// TODO display style? or is it already displayed?
|
|
||||||
|
|
||||||
@interface fontButton : NSButton {
|
@interface fontButton : NSButton {
|
||||||
uiFontButton *libui_b;
|
uiFontButton *libui_b;
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
// 14 april 2016
|
// 14 april 2016
|
||||||
#include "uipriv_unix.h"
|
#include "uipriv_unix.h"
|
||||||
|
|
||||||
// TODO display style? or is it already displayed?
|
|
||||||
|
|
||||||
struct uiFontButton {
|
struct uiFontButton {
|
||||||
uiUnixControl c;
|
uiUnixControl c;
|
||||||
GtkWidget *widget;
|
GtkWidget *widget;
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
struct uiFontButton {
|
struct uiFontButton {
|
||||||
uiWindowsControl c;
|
uiWindowsControl c;
|
||||||
HWND hwnd;
|
HWND hwnd;
|
||||||
uiDrawTextFontDescriptor desc;
|
struct fontDialogParams params;
|
||||||
BOOL already;
|
BOOL already;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -23,8 +23,8 @@ static void updateFontButtonLabel(uiFontButton *b)
|
||||||
WCHAR text[1024];
|
WCHAR text[1024];
|
||||||
WCHAR *family;
|
WCHAR *family;
|
||||||
|
|
||||||
family = toUTF16(b->desc.Family);
|
family = toUTF16(b->params.desc.Family);
|
||||||
_snwprintf(text, 1024, L"%s %g", family, b->desc.Size);
|
_snwprintf(text, 1024, L"%s %s %g", family, b->params.outStyleName, b->params.desc.Size);
|
||||||
uiFree(family);
|
uiFree(family);
|
||||||
// TODO error check
|
// TODO error check
|
||||||
SendMessageW(b->hwnd, WM_SETTEXT, 0, (LPARAM) text);
|
SendMessageW(b->hwnd, WM_SETTEXT, 0, (LPARAM) text);
|
||||||
|
@ -37,17 +37,12 @@ static BOOL onWM_COMMAND(uiControl *c, HWND hwnd, WORD code, LRESULT *lResult)
|
||||||
{
|
{
|
||||||
uiFontButton *b = uiFontButton(c);
|
uiFontButton *b = uiFontButton(c);
|
||||||
HWND parent;
|
HWND parent;
|
||||||
char *oldFamily;
|
|
||||||
|
|
||||||
if (code != BN_CLICKED)
|
if (code != BN_CLICKED)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
parent = GetAncestor(b->hwnd, GA_ROOT); // TODO didn't we have a function for this
|
parent = GetAncestor(b->hwnd, GA_ROOT); // TODO didn't we have a function for this
|
||||||
oldFamily = (char *) (b->desc.Family);
|
if (showFontDialog(parent, &(b->params))) {
|
||||||
if (showFontDialog(parent, &(b->desc))) {
|
|
||||||
if (b->already) // don't free the static Arial string
|
|
||||||
uiFree(oldFamily);
|
|
||||||
b->already = TRUE;
|
|
||||||
updateFontButtonLabel(b);
|
updateFontButtonLabel(b);
|
||||||
// TODO event
|
// TODO event
|
||||||
}
|
}
|
||||||
|
@ -109,12 +104,7 @@ uiFontButton *uiNewFontButton(void)
|
||||||
hInstance, NULL,
|
hInstance, NULL,
|
||||||
TRUE);
|
TRUE);
|
||||||
|
|
||||||
// arbitrary defaults that will do
|
loadInitialFontDialogParams(&(b->params));
|
||||||
b->desc.Family = "Arial";
|
|
||||||
b->desc.Size = 10; // from the real font dialog
|
|
||||||
b->desc.Weight = uiDrawTextWeightNormal;
|
|
||||||
b->desc.Italic = uiDrawTextItalicNormal;
|
|
||||||
b->desc.Stretch = uiDrawTextStretchNormal;
|
|
||||||
updateFontButtonLabel(b);
|
updateFontButtonLabel(b);
|
||||||
|
|
||||||
uiWindowsRegisterWM_COMMANDHandler(b->hwnd, onWM_COMMAND, uiControl(b));
|
uiWindowsRegisterWM_COMMANDHandler(b->hwnd, onWM_COMMAND, uiControl(b));
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
// - quote the Choose Font sample here for reference
|
// - quote the Choose Font sample here for reference
|
||||||
// - the Choose Font sample defaults to Regular/Italic/Bold/Bold Italic in some case (no styles?); do we? find out what the case is
|
// - the Choose Font sample defaults to Regular/Italic/Bold/Bold Italic in some case (no styles?); do we? find out what the case is
|
||||||
// - do we set initial family and style topmost as well?
|
// - do we set initial family and style topmost as well?
|
||||||
|
// - this should probably just handle IDWriteFonts
|
||||||
|
|
||||||
struct fontDialog {
|
struct fontDialog {
|
||||||
HWND hwnd;
|
HWND hwnd;
|
||||||
|
@ -12,7 +13,7 @@ struct fontDialog {
|
||||||
HWND styleCombobox;
|
HWND styleCombobox;
|
||||||
HWND sizeCombobox;
|
HWND sizeCombobox;
|
||||||
|
|
||||||
uiDrawTextFontDescriptor *desc;
|
struct fontDialogParams *params;
|
||||||
|
|
||||||
fontCollection *fc;
|
fontCollection *fc;
|
||||||
|
|
||||||
|
@ -156,7 +157,7 @@ static void wipeStylesBox(struct fontDialog *f)
|
||||||
cbWipeAndReleaseData(f->styleCombobox);
|
cbWipeAndReleaseData(f->styleCombobox);
|
||||||
}
|
}
|
||||||
|
|
||||||
static WCHAR *fontStyleName(struct fontDialog *f, IDWriteFont *font)
|
static WCHAR *fontStyleName(struct fontCollection *fc, IDWriteFont *font)
|
||||||
{
|
{
|
||||||
IDWriteLocalizedStrings *str;
|
IDWriteLocalizedStrings *str;
|
||||||
WCHAR *wstr;
|
WCHAR *wstr;
|
||||||
|
@ -165,7 +166,7 @@ static WCHAR *fontStyleName(struct fontDialog *f, IDWriteFont *font)
|
||||||
hr = font->GetFaceNames(&str);
|
hr = font->GetFaceNames(&str);
|
||||||
if (hr != S_OK)
|
if (hr != S_OK)
|
||||||
logHRESULT("error getting font style name for font dialog in fontStyleName()", hr);
|
logHRESULT("error getting font style name for font dialog in fontStyleName()", hr);
|
||||||
wstr = fontCollectionCorrectString(f->fc, str);
|
wstr = fontCollectionCorrectString(fc, str);
|
||||||
str->Release();
|
str->Release();
|
||||||
return wstr;
|
return wstr;
|
||||||
}
|
}
|
||||||
|
@ -249,7 +250,7 @@ static void familyChanged(struct fontDialog *f)
|
||||||
hr = family->GetFont(i, &font);
|
hr = family->GetFont(i, &font);
|
||||||
if (hr != S_OK)
|
if (hr != S_OK)
|
||||||
logHRESULT("error getting font for filling styles box in familyChanged()", hr);
|
logHRESULT("error getting font for filling styles box in familyChanged()", hr);
|
||||||
label = fontStyleName(f, font);
|
label = fontStyleName(f->fc, font);
|
||||||
pos = cbAddString(f->styleCombobox, label);
|
pos = cbAddString(f->styleCombobox, label);
|
||||||
uiFree(label);
|
uiFree(label);
|
||||||
cbSetItemData(f->styleCombobox, (WPARAM) pos, (LPARAM) font);
|
cbSetItemData(f->styleCombobox, (WPARAM) pos, (LPARAM) font);
|
||||||
|
@ -428,15 +429,15 @@ static void setupInitialFontDialogState(struct fontDialog *f)
|
||||||
WCHAR wsize[512]; // this should be way more than enough
|
WCHAR wsize[512]; // this should be way more than enough
|
||||||
LRESULT pos;
|
LRESULT pos;
|
||||||
|
|
||||||
// first convert f->desc into a usable form
|
// first convert f->params->desc into a usable form
|
||||||
wfamily = toUTF16(f->desc->Family);
|
wfamily = toUTF16(f->params->desc.Family);
|
||||||
// see below for why we do this specifically
|
// see below for why we do this specifically
|
||||||
// TODO is 512 the correct number to pass to _snwprintf()?
|
// TODO is 512 the correct number to pass to _snwprintf()?
|
||||||
// TODO will this revert to scientific notation?
|
// TODO will this revert to scientific notation?
|
||||||
_snwprintf(wsize, 512, L"%g", f->desc->Size);
|
_snwprintf(wsize, 512, L"%g", f->params->desc.Size);
|
||||||
attr.weight = f->desc->Weight;
|
attr.weight = f->params.desc->Weight;
|
||||||
attr.italic = f->desc->Italic;
|
attr.italic = f->params.desc->Italic;
|
||||||
attr.stretch = f->desc->Stretch;
|
attr.stretch = f->params.desc->Stretch;
|
||||||
attrToDWriteAttr(&attr);
|
attrToDWriteAttr(&attr);
|
||||||
|
|
||||||
// first let's load the size
|
// first let's load the size
|
||||||
|
@ -475,7 +476,7 @@ static struct fontDialog *beginFontDialog(HWND hwnd, LPARAM lParam)
|
||||||
|
|
||||||
f = uiNew(struct fontDialog);
|
f = uiNew(struct fontDialog);
|
||||||
f->hwnd = hwnd;
|
f->hwnd = hwnd;
|
||||||
f->desc = (uiDrawTextFontDescriptor *) lParam;
|
f->params = (struct fontDialogParams *) lParam;
|
||||||
|
|
||||||
f->familyCombobox = GetDlgItem(f->hwnd, rcFontFamilyCombobox);
|
f->familyCombobox = GetDlgItem(f->hwnd, rcFontFamilyCombobox);
|
||||||
if (f->familyCombobox == NULL)
|
if (f->familyCombobox == NULL)
|
||||||
|
@ -540,17 +541,23 @@ static INT_PTR tryFinishDialog(struct fontDialog *f, WPARAM wParam)
|
||||||
|
|
||||||
// OK
|
// OK
|
||||||
wfamily = cbGetItemText(f->familyCombobox, f->curFamily);
|
wfamily = cbGetItemText(f->familyCombobox, f->curFamily);
|
||||||
f->desc->Family = toUTF8(wfamily);
|
uiFree(f->params->desc.Family);
|
||||||
|
f->params->desc.Family = toUTF8(wfamily);
|
||||||
uiFree(wfamily);
|
uiFree(wfamily);
|
||||||
f->desc->Size = f->curSize;
|
f->params->desc.Size = f->curSize;
|
||||||
font = (IDWriteFont *) cbGetItemData(f->styleCombobox, f->curStyle);
|
font = (IDWriteFont *) cbGetItemData(f->styleCombobox, f->curStyle);
|
||||||
attr.dweight = font->GetWeight();
|
attr.dweight = font->GetWeight();
|
||||||
attr.ditalic = font->GetStyle();
|
attr.ditalic = font->GetStyle();
|
||||||
attr.dstretch = font->GetStretch();
|
attr.dstretch = font->GetStretch();
|
||||||
dwriteAttrToAttr(&attr);
|
dwriteAttrToAttr(&attr);
|
||||||
f->desc->Weight = attr.weight;
|
f->params->desc.Weight = attr.weight;
|
||||||
f->desc->Italic = attr.italic;
|
f->params->desc.Italic = attr.italic;
|
||||||
f->desc->Stretch = attr.stretch;
|
f->params->desc.Stretch = attr.stretch;
|
||||||
|
uiFree(f->params->outStyleName);
|
||||||
|
// TODO rename to wstr
|
||||||
|
wfamily = fontStyleName(f->fc, font);
|
||||||
|
f->params->outStyleName = toUTF8(wfamily);
|
||||||
|
uiFree(wfamily);
|
||||||
endFontDialog(f, 2);
|
endFontDialog(f, 2);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -614,9 +621,9 @@ static INT_PTR CALLBACK fontDialogDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, L
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL showFontDialog(HWND parent, uiDrawTextFontDescriptor *desc)
|
BOOL showFontDialog(HWND parent, struct fontDialogParams *params)
|
||||||
{
|
{
|
||||||
switch (DialogBoxParamW(hInstance, MAKEINTRESOURCE(rcFontDialog), parent, fontDialogDlgProc, (LPARAM) desc)) {
|
switch (DialogBoxParamW(hInstance, MAKEINTRESOURCE(rcFontDialog), parent, fontDialogDlgProc, (LPARAM) params)) {
|
||||||
case 1: // cancel
|
case 1: // cancel
|
||||||
return FALSE;
|
return FALSE;
|
||||||
case 2: // ok
|
case 2: // ok
|
||||||
|
@ -627,3 +634,81 @@ BOOL showFontDialog(HWND parent, uiDrawTextFontDescriptor *desc)
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static IDWriteFontFamily *tryFindFamily(IDWriteFontCollection *fc, const WCHAR *name)
|
||||||
|
{
|
||||||
|
UINT32 index;
|
||||||
|
BOOL exists;
|
||||||
|
IDWriteFontFamily *family;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
hr = fc->FindFamilyName(name, &index, &exists);
|
||||||
|
if (hr != S_OK)
|
||||||
|
logHRESULT("error finding font family for font dialog in tryFindFamily()", hr);
|
||||||
|
if (!exists)
|
||||||
|
return NULL;
|
||||||
|
hr = fc->GetFontFamily(index, &family);
|
||||||
|
if (hr != S_OK)
|
||||||
|
logHRESULT("error extracting found font family for font dialog in tryFindFamily()", hr);
|
||||||
|
return family;
|
||||||
|
}
|
||||||
|
|
||||||
|
void loadInitialFontDialogParams(struct fontDialogParams *params)
|
||||||
|
{
|
||||||
|
struct fontCollection *fc;
|
||||||
|
IDWriteFontFamily *family;
|
||||||
|
IDWriteFont *font;
|
||||||
|
struct attr;
|
||||||
|
WCHAR *wstr;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
// Our preferred font is Arial 10 Regular.
|
||||||
|
// 10 comes from the official font dialog.
|
||||||
|
// Arial Regular is a reasonable, if arbitrary, default; it's similar to the defaults on other systems.
|
||||||
|
// If Arial isn't found, we'll use Helvetica and then MS Sans Serif as fallbacks, and if not, we'll just grab the first font family in the collection.
|
||||||
|
|
||||||
|
// We need the correct localized name for Regular (and possibly Arial too? let's say yes to be safe), so let's grab the strings from DirectWrite instead of hardcoding them.
|
||||||
|
fc = loadFontCollection();
|
||||||
|
family = tryFindFamily(fc->fonts, L"Arial");
|
||||||
|
if (family == NULL) {
|
||||||
|
family = tryFindFamily(fc->fonts, L"Helvetica");
|
||||||
|
if (family == NULL) {
|
||||||
|
family = tryFindFamily(fc->fonts, L"MS Sans Serif");
|
||||||
|
if (family == NULL) {
|
||||||
|
hr = fc->fonts->GetFontFamily(0, &family);
|
||||||
|
if (hr != S_OK)
|
||||||
|
logHRESULT("error getting first font out of font collection (worst case scenario) in loadInitialFontDialogParams()", hr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// next part is simple: just get the closest match to regular
|
||||||
|
hr = family->GetFirstMatchingFont(
|
||||||
|
DWRITE_FONT_WEIGHT_NORMAL,
|
||||||
|
DWRITE_FONT_STRETCH_NORMAL,
|
||||||
|
DWRITE_FONT_STYLE_NORMAL,
|
||||||
|
&font);
|
||||||
|
if (hr != S_OK)
|
||||||
|
logHRESULT("error getting Regular font from Arial in loadInitialFontDialogParams()", hr);
|
||||||
|
|
||||||
|
// now convert attributes in the actual font...
|
||||||
|
attr.dweight = font->GetWeight();
|
||||||
|
attr.ditalic = font->GetStyle();
|
||||||
|
attr.dstretch = font->GetStretch();
|
||||||
|
dwriteAttrToAttr(&attr);
|
||||||
|
|
||||||
|
// and finally fill the structure
|
||||||
|
wstr = fontCollectionFamilyName(fc, family);
|
||||||
|
params->desc.Family = toUTF8(wstr);
|
||||||
|
uiFree(wstr);
|
||||||
|
params->desc.Size = 10;
|
||||||
|
params->desc.Weight = attr.weight;
|
||||||
|
params->desc.Italic = attr.italic;
|
||||||
|
params->desc.Stretch = attr.stretch;
|
||||||
|
wstr = fontStyleName(fc, font);
|
||||||
|
params->outStyleName = toUTF8(wstr);
|
||||||
|
uiFree(wstr);
|
||||||
|
font->Release();
|
||||||
|
family->Release();
|
||||||
|
fontCollectionFree(fc);
|
||||||
|
}
|
||||||
|
|
|
@ -170,7 +170,12 @@ extern void dwriteAttrToAttr(struct dwriteAttr *attr);
|
||||||
extern void doDrawText(ID2D1RenderTarget *rt, ID2D1Brush *black, double x, double y, uiDrawTextLayout *layout);
|
extern void doDrawText(ID2D1RenderTarget *rt, ID2D1Brush *black, double x, double y, uiDrawTextLayout *layout);
|
||||||
|
|
||||||
// fontdialog.cpp
|
// fontdialog.cpp
|
||||||
extern BOOL showFontDialog(HWND parent, uiDrawTextFontDescriptor *desc);
|
struct fontDialogParams {
|
||||||
|
uiDrawTextFontDescriptor desc;
|
||||||
|
WCHAR *outStyleName;
|
||||||
|
};
|
||||||
|
extern BOOL showFontDialog(HWND parent, struct fontDialogParams *params);
|
||||||
|
extern void loadInitialFontDialogParams(struct fontDialogParams *params);
|
||||||
|
|
||||||
// d2dscratch.c
|
// d2dscratch.c
|
||||||
extern ATOM registerD2DScratchClass(HICON, HCURSOR);
|
extern ATOM registerD2DScratchClass(HICON, HCURSOR);
|
||||||
|
|
Loading…
Reference in New Issue