D2SetFont command

Requires: Direct2D.lg32

Purpose

Sets the current font for text operations.

Syntax

D2SetFont D2Font
D2SetFont hFont
D2SetFont fontstring$
D2SetFont fname$ [, height! , weight%][,italic?][,stretch%] [,locale$]

hFont: integer expression
fname$, fontstring$, locale$: string expression
height!: float expression
weight%: integer expression
italic?: boolean expression
stretch%: integer expression

Description

D2SetFont sets the font to be used with D2Text and D2DrawText.

D2SetFont D2Font takes an object created with D2Font(). For performance reasons it might be useful to cache a D2Font object and later use it with D2SetFont in the drawing operations.

The second form - D2SetFont hFont - D2SetFont takes a GDI font handle and converts it into a D2Font (IDWriteTextFormat) object. hFont may specify a GDI stockfont constant. The properties of the GDI font are converted to Direct2D font-properties that are used then used to create the D2Font object (IDWriteTextFormat). Note that not using the first form a D2Font has to be created each time D2SetFont is executed.

The third form takes a fontstring$ argument containing all the parameters of the current font (similar to _Font$, but the format is different). The format of the string is “fontname, height!, weight%, italic?, strectch%,localename”; all parts are optional (i.e. “,20,400,,10,” is allowed) with the missing parts taken from the current font.

The fourth form requires a font description. The parameters are passed to IDWriteFactory::CreateTextFormat directly. Most parameters use default values, but the application needs to specify the font's name.

The height must be specified in DIPs (1/96 inch == 1 logical pixel) can be a value that's also used for GDI fonts. The parameter is optional and defaults to 11 DIPs, which conforms to the default size of the DEFAULT_GUI_FONT stock font.

The height can be calculated using the D2PointsToDips() function that converts the required size in points to DIPs.

The font weight defaults to a normal font, but it can be one of the following values:

Set the italics boolean parameter to True for an intalics font (default is off).

The default for the stretch parameter is a normal stretch, but it can take one of these values:

The localename$ may specify the locale name, like "en-us".

Example

'

' Samples\Direct2D\D2SetFont.g32 (dpi-aware)

'

$Library "direct2d"

$Library "gfawinx"

DpiAwareness()

OpenW 1, 0, 0, 320, 300, 16 + 32

FormScaleForDpi(Me)

Global Object Win1RT

Set Win1RT = D2GetRT()

Global Float Width1, Height1  ' Use: for DPI change

D2GetSizeRT Win1RT, Width1, Height1

Global Object Fnt, FntBold   ' cache the fonts

Set Fnt = D2Font("Gabriola", D2PointsToDIPs(13))

Set FntBold = D2Font("Gabriola", D2PointsToDIPs(13), DWRITE_FONT_WEIGHT_BOLD)

Do

Sleep

Until Me Is Nothing

 

Sub Win_1_Paint

D2BeginDraw Win1RT, D2C_White

D2SetFont Fnt     ' high performance

D2Text 16, 16, "Hello Direct2D (Normal)"

D2SetFont FntBold

D2Text 16, 40, "DirectWrite (Bold)"

D2EndDraw

EndSub

 

Sub Win_1_ReSize

D2ResizeRT Win1RT, WorkWidth(), WorkHeight()           ' size from adjusted window

EndSub

 

Sub Win_1_MessageProc(hWnd%, Mess%, wParam%, lParam%, retval%, ValidRet?)

Local Int dpi

If Mess% == WM_DPICHANGED

If FormScaleForDpi(Me, wParam%, lParam%' scale (resize) form and it's Ocx-es

' Here: Update other Dpi dependent resources (toolbar, bitmaps, Direct2D)

dpi = LoWord(wParam%)             ' new Dpi for form

D2SetDpiRT Win1RT, dpi            ' update D2 rendertarget's dpi

EndIf

retval% = 0 : ValidRet? = True    ' tell OS we handled it

EndIf

EndSub

 

Function FormScaleForDpi(ByVal frm As Form, Optional newdpi As Int, Optional lParam As Int) As Bool

Local i As Int, c As Control, rc As RECT, prevDpi As Int, newrc As Pointer To RECT, _

tb As Tab, w As Int, h As Int

With frm

' Set initial newdpi for the form and the scale factors for a LoadForm

If .WhatsThisHelpID == 0

If Exist(":{" + .Name)                    ' a Form-Editor form

.WhatsThisHelpID = WinDpi(0)            ' initial dpi is system newdpi

.ScaleWidth = .ScaleWidth * 96 / .WhatsThisHelpID   ' set initial scale factors

.ScaleHeight = .ScaleHeight * 96 / .WhatsThisHelpID

Else                                      ' created by OpenW or Form command

.WhatsThisHelpID = 96                   ' coord space is 96

EndIf

EndIf

prevDpi = .WhatsThisHelpID

newdpi = LoWord(newdpi)

If newdpi == 0 Then newdpi = WinDpi(.hWnd)

Exit Func If newdpi == prevDpi              ' don't continue if equal

' Size the form, except if it is a child window

If !(GetWindowLong(.hWnd, GWL_STYLE) %& WS_CHILD)

If lParam                                 ' size to the OS suggested size

Pointer newrc = lParam                  ' ptr to RECT in lParam

SizeW .hWnd, newrc.Right - newrc.Left, newrc.Bottom - newrc.Top

Else                                      ' scale based on the current client size

GetClientSize .hWnd, w, h               ' can't use _X _Y, they are for ME only

AdjustW .hWnd, Scale(w, newdpi, prevDpi), Scale(h, newdpi, prevDpi)

EndIf

EndIf

.FontSize = .FontSize * newdpi / prevDpi

.ScaleWidth = .ScaleWidth * prevDpi / newdpi

.ScaleHeight = .ScaleHeight * prevDpi / newdpi

' Scale position and size of the Ocx windowed controls

For Each c In frm.Controls

If !(TypeOf(c) Is ImageList || TypeOf(c) Is Timer || _

TypeOf(c) Is CommDlg || TypeOf(c) Is TrayIcon' not the windowless OCX-es

' First set fontsize, but not all OCX-es have a Font property

If !(TypeOf(c) Is ProgressBar || TypeOf(c) Is Slider || TypeOf(c) Is Image || TypeOf(c) Is RichEdit)

c.fontsize = c.fontsize * newdpi / prevDpi

ElseIf TypeOf(c) Is RichEdit            ' Requires LoadRichEdit50W!

SendMessage c.hwnd, WM_DPICHANGED, MakeLong(newdpi, newdpi), 0

EndIf

' Set new position and size for OCX-controls

GetWinPos(c.hwnd, rc)                   ' relative to parent

~SetWindowPos(c.hwnd, 0, _

Scale(rc.Left, newdpi, prevDpi), Scale(rc.Top, newdpi, prevDpi), _

Scale(rc.Right - rc.Left, newdpi, prevDpi), _

Scale(rc.Bottom - rc.Top, newdpi, prevDpi),  SWP_NOZORDER) ' new pos and size

If TypeOf(c) Is Form                    ' Scale OCX-es of a child Form Ocx

c.WhatsThisHelpID = prevDpi

~FormScaleForDpi(c, newdpi)

ElseIf TypeOf(c) Is TabStrip            ' Scale TabStrip's attached forms

For Each tb In c.Tabs

If TypeOf(tb.Ocx) Is Form

tb.Ocx.WhatsThisHelpID = prevDpi

~FormScaleForDpi(tb.Ocx, newdpi)

EndIf

Next

EndIf

EndIf

Next

.WhatsThisHelpID = newdpi     ' store new newdpi

EndWith

FormScaleForDpi = True

EndFunc

NOTE: The above example will not run as it relies on an embedded file which is not present in the syntax. The programme with full resources can be found in GFABASIC/Samples/Direct2D/D2SetFont.g32.

Remarks

If D2SetFont isn't used D2Text and D2DrawText will use the stock font DEFAULT_GUI_FONT.

A D2Font object does not require a render target and it is not a device-dependent resource like brush and bitmap. In addition, the global font setting isn't released in D2EndDraw. D2SetFont may be used outside the D2BeginDraw/D2EndDraw pair, for instance to calculate the textsize using D2TextSize. There is always one font object the current one; the font last set with D2SetFont.

D2SetFont invokes IDWriteFactory::CreateTextFormat which is part of DirectWrite. The IDWriteTextFormat object is used in the render target object method ID2D1RenderTarget::DrawText (used by D2Text and D2DrawText).

See Also

D2FontD2FontSize, D2FontBold, D2FontItalic, D2FontStretch, D2FontName, D2FontLocaleName,, D2GetFontObj, D2RFont, D2Text, D2DrawText, D2TextSize, D2PointsToDips

{Created by Sjouke Hamstra; Last updated: 03/03/2022 by James Gaite}