diff --git a/darwin/drawtext.m b/darwin/drawtext.m index c04b402b..64c4b255 100644 --- a/darwin/drawtext.m +++ b/darwin/drawtext.m @@ -212,3 +212,15 @@ void uiDrawTextLayoutExtents(uiDrawTextLayout *tl, double *width, double *height [tl->frame returnWidth:width height:NULL]; [tl->forLines returnWidth:NULL height:height]; } + +void uiLoadControlFont(uiFontDescriptor *f) +{ + CTFontRef ctfont; + CTFontDescriptorRef ctdesc; + + ctfont = (CTFontRef) [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSControlSizeRegular]]; + ctdesc = CTFontCopyFontDescriptor(ctfont); + uiprivFontDescriptorFromCTFontDescriptor(ctdesc, f); + CFRelease(ctdesc); + f->Size = CTFontGetSize(ctfont); +} diff --git a/examples/drawtext/main.c b/examples/drawtext/main.c index d94d2572..5f1a3712 100644 --- a/examples/drawtext/main.c +++ b/examples/drawtext/main.c @@ -8,6 +8,7 @@ uiArea *area; uiAreaHandler handler; uiFontButton *fontButton; uiCombobox *alignment; +uiCheckbox *systemFont; uiAttributedString *attrstr; @@ -97,15 +98,21 @@ static void handlerDraw(uiAreaHandler *a, uiArea *area, uiAreaDrawParams *p) uiDrawTextLayout *textLayout; uiFontDescriptor defaultFont; uiDrawTextLayoutParams params; + int useSystemFont = uiCheckboxChecked(systemFont); params.String = attrstr; - uiFontButtonFont(fontButton, &defaultFont); + if (useSystemFont) + uiLoadControlFont(&defaultFont); + else + uiFontButtonFont(fontButton, &defaultFont); params.DefaultFont = &defaultFont; params.Width = p->AreaWidth; params.Align = (uiDrawTextAlign) uiComboboxSelected(alignment); textLayout = uiDrawNewTextLayout(¶ms); uiDrawText(p->Context, textLayout, 0, 0); uiDrawFreeTextLayout(textLayout); + + //TODO RENAME? uiFreeFontButtonFont(&defaultFont); } @@ -140,6 +147,11 @@ static void onComboboxSelected(uiCombobox *b, void *data) uiAreaQueueRedrawAll(area); } +static void onCheckboxToggled(uiCheckbox *b, void *data) +{ + uiAreaQueueRedrawAll(area); +} + static int onClosing(uiWindow *w, void *data) { uiControlDestroy(uiControl(mainwin)); @@ -208,6 +220,10 @@ int main(void) uiComboboxOnSelected(alignment, onComboboxSelected, NULL); uiFormAppend(form, "Alignment", uiControl(alignment), 0); + systemFont = uiNewCheckbox(""); + uiCheckboxOnToggled(systemFont, onCheckboxToggled, NULL); + uiFormAppend(form, "System Font", uiControl(systemFont), 0); + area = uiNewArea(&handler); uiBoxAppend(hbox, uiControl(area), 1); diff --git a/ui.h b/ui.h index 40aea949..290d4006 100644 --- a/ui.h +++ b/ui.h @@ -923,6 +923,8 @@ struct uiFontDescriptor { uiTextStretch Stretch; }; +_UI_EXTERN void uiLoadControlFont(uiFontDescriptor *f); + // uiDrawTextLayout is a concrete representation of a // uiAttributedString that can be displayed in a uiDrawContext. // It includes information important for the drawing of a block of diff --git a/unix/drawtext.c b/unix/drawtext.c index 477e9ca3..f6f79ec5 100644 --- a/unix/drawtext.c +++ b/unix/drawtext.c @@ -79,3 +79,19 @@ void uiDrawTextLayoutExtents(uiDrawTextLayout *tl, double *width, double *height *width = pangoToCairo(logical.width); *height = pangoToCairo(logical.height); } + +void uiLoadControlFont(uiFontDescriptor *f) +{ + GtkWidget *widget; + GtkStyleContext *style; + PangoFontDescription *fontdesc; + + widget = g_object_ref_sink(gtk_label_new("")); + style = gtk_widget_get_style_context(widget); + gtk_style_context_get(style, GTK_STATE_FLAG_NORMAL, + "font", &fontdesc, NULL); + uiprivFontDescriptorFromPangoFontDescription(fontdesc, f); + // pdesc is transfer-full and thus is a copy + pango_font_description_free(fontdesc); + g_object_unref(widget); +} diff --git a/windows/drawtext.cpp b/windows/drawtext.cpp index ec2ae152..2bab793d 100644 --- a/windows/drawtext.cpp +++ b/windows/drawtext.cpp @@ -534,3 +534,53 @@ void uiDrawTextLayoutExtents(uiDrawTextLayout *tl, double *width, double *height // TODO make sure the behavior of this on empty strings is the same on all platforms (ideally should be 0-width, line height-height; TODO note this in the docs too) *height = metrics.height; } + +void uiLoadControlFont(uiFontDescriptor *f) +{ + fontCollection *collection; + IDWriteGdiInterop *gdi; + IDWriteFont *dwfont; + IDWriteFontFamily *dwfamily; + NONCLIENTMETRICSW metrics; + HDC dc; + WCHAR *family; + double size; + int pixels; + HRESULT hr; + + metrics.cbSize = sizeof(metrics); + if (!SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, metrics.cbSize, &metrics, 0)) + logLastError(L"error getting non-client metrics"); + hr = dwfactory->GetGdiInterop(&gdi); + if (hr != S_OK) + logHRESULT(L"error getting GDI interop", hr); + + hr = gdi->CreateFontFromLOGFONT(&metrics.lfMessageFont, &dwfont); + if (hr != S_OK) + logHRESULT(L"error loading font", hr); + + hr = dwfont->GetFontFamily(&dwfamily); + if (hr != S_OK) + logHRESULT(L"error loading font family", hr); + collection = uiprivLoadFontCollection(); + family = uiprivFontCollectionFamilyName(collection, dwfamily); + + dc = GetDC(NULL); + if (dc == NULL) + logLastError(L"error getting DC"); + pixels = GetDeviceCaps(dc, LOGPIXELSY); + if (pixels == 0) + logLastError(L"error getting device caps"); + size = abs(metrics.lfMessageFont.lfHeight) * 72 / pixels; + + uiprivFontDescriptorFromIDWriteFont(dwfont, f); + f->Family = toUTF8(family); + f->Size = size; + + uiprivFree(family); + uiprivFontCollectionFree(collection); + dwfamily->Release(); + gdi->Release(); + if (ReleaseDC(NULL, dc) == 0) + logLastError(L"error releasing DC"); +}