Creating logical fonts with an outline border?

Windows specific forum
User avatar
Fluid Byte
Addict
Addict
Posts: 2336
Joined: Fri Jul 21, 2006 4:41 am
Location: Berlin, Germany

Creating logical fonts with an outline border?

Post by Fluid Byte »

Is it possible to asign a colored border around a font loaded with CreateFontIndirect_() or has this to be done manually? I tried messing around with the properties of the LOGFONT structure and it's pretty customizable but unfortuneatly no option to define an outline border for a font.
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

I don't think it's possible, but you can convert it to a path.
User avatar
Fluid Byte
Addict
Addict
Posts: 2336
Joined: Fri Jul 21, 2006 4:41 am
Location: Berlin, Germany

Post by Fluid Byte »

Although your answer is rather short and no code is provided you brought me at least on the right track. :wink:

However, I'm not satisfied with the final result so I should explain what I'm trying to do. In GLBasic you have a tool named "DiNGSFont.exe" wich let's you create image fonts on fly wich are intended for in-game usage. So I'm doing a similar aproach. I want to create a bitmap on wich a character set is drawn wich a choosen font. Addtionally you specify the quality of the font using the internal Windows font-smoothing feature (draft, anti-alias & cleartype).

All works well so far but I got two main problems now. When you run the code below you get outlined text but it draws a border around the whole text region and the interior of the text is not filled. The second problem would to figure out to draw outlined text wich is also smoothed (border + text).

Code: Select all

#DEFAULT_QUALITY = 0
#DRAFT_QUALITY = 1
#PROOF_QUALITY = 2
#NONANTIALIASED_QUALITY = 3
#ANTIALIASED_QUALITY = 4
#CLEARTYPE_QUALITY = 5
#CLEARTYPE_NATURAL_QUALITY = 6

OpenWindow(0,0,0,400,300,"untitled",#WS_OVERLAPPEDWINDOW | 1)

SetWindowColor(0,$00AAFF)

hdc = GetDC_(WindowID(0))

lplf.LOGFONT
lplf\lfHeight         = -MulDiv_(19,GetDeviceCaps_(hDC,#LOGPIXELSY),72)
lplf\lfWidth          = 0
lplf\lfEscapement     = 0
lplf\lfOrientation    = 0
lplf\lfWeight         = #FW_BOLD
lplf\lfItalic         = 0
lplf\lfUnderline      = 0
lplf\lfStrikeOut      = 0
lplf\lfCharSet        = #DEFAULT_CHARSET
lplf\lfOutPrecision   = #OUT_DEFAULT_PRECIS
lplf\lfClipPrecision  = #CLIP_DEFAULT_PRECIS
lplf\lfQuality = #ANTIALIASED_QUALITY
lplf\lfPitchAndFamily = #DEFAULT_PITCH | #FF_DONTCARE

PokeS(@lplf\lfFaceName,"Arial")

hFontPath = CreateFontIndirect_(lplf)

ReleaseDC_(WindowID(0),hdc)

Repeat 
	EventID = WaitWindowEvent()
	
	hdc = StartDrawing(WindowOutput(0))

	SelectObject_(hdc,hFontPath)
	
	BeginPath_(hdc)	
	TextOut_(hdc,10,10,"Defenestration can be hazardous",31)
	EndPath_(hdc)	

	SelectObject_(hdc,GetStockObject_(#WHITE_BRUSH))
	SelectObject_(hdc,GetStockObject_(#BLACK_PEN))	
	StrokeAndFillPath_(hdc)

	StopDrawing()
Until EventID = 16
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
User avatar
Fluid Byte
Addict
Addict
Posts: 2336
Joined: Fri Jul 21, 2006 4:41 am
Location: Berlin, Germany

Post by Fluid Byte »

I just tested a code snippet wich is included in the description for the TextOut_() command in the Platform SDK. You can use

Code: Select all

SetBkMode_(hdc,#TRANSPARENT)
wich will fill the border/interior with the currently selected pen/brush.

Still the second problem remains, drawing outlined text using the Windows font-smooting feature. :?
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
User avatar
Fluid Byte
Addict
Addict
Posts: 2336
Joined: Fri Jul 21, 2006 4:41 am
Location: Berlin, Germany

Post by Fluid Byte »

No one?
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
Xombie
Addict
Addict
Posts: 898
Joined: Thu Jul 01, 2004 2:51 am
Location: Tacoma, WA
Contact:

Post by Xombie »

There's another method you may consider...

Code: Select all

#DEFAULT_QUALITY = 0 
#DRAFT_QUALITY = 1 
#PROOF_QUALITY = 2 
#NONANTIALIASED_QUALITY = 3 
#ANTIALIASED_QUALITY = 4 
#CLEARTYPE_QUALITY = 5 
#CLEARTYPE_NATURAL_QUALITY = 6 

OpenWindow(0,0,0,450,300,"untitled",#WS_OVERLAPPEDWINDOW | 1) 

SetWindowColor(0,$00AAFF) 

hdc = GetDC_(WindowID(0)) 

lplf.LOGFONT 
lplf\lfHeight         = -MulDiv_(19,GetDeviceCaps_(hdc,#LOGPIXELSY),72) 
lplf\lfWidth          = 0 
lplf\lfEscapement     = 0 
lplf\lfOrientation    = 0 
lplf\lfWeight         = #FW_BOLD 
lplf\lfItalic         = 0 
lplf\lfUnderline      = 0 
lplf\lfStrikeOut      = 0 
lplf\lfCharSet        = #DEFAULT_CHARSET 
lplf\lfOutPrecision   = #OUT_DEFAULT_PRECIS 
lplf\lfClipPrecision  = #CLIP_DEFAULT_PRECIS 
lplf\lfQuality = #ANTIALIASED_QUALITY 
lplf\lfPitchAndFamily = #DEFAULT_PITCH | #FF_DONTCARE 

PokeS(@lplf\lfFaceName,"Arial") 

hFontPath = CreateFontIndirect_(lplf) 

ReleaseDC_(WindowID(0),hdc) 
   a.s = "Defenestration can be hazardous"
   b.l = Len(a)
Repeat 
   EventID = WaitWindowEvent() 
    
   hdc = StartDrawing(WindowOutput(0)) 
   SetBkMode_(hdc, #TRANSPARENT)
   SetTextAlign_(hdc, #TA_NOUPDATECP)
   SelectObject_(hdc,hFontPath) 
   ;
   SetTextColor_(hdc, #Black)
   ;
   TextOut_(hdc,9,9,@a,b)
   TextOut_(hdc,9,10,@a,b)
   TextOut_(hdc,9,11,@a,b)
   TextOut_(hdc,11,9,@a,b)
   TextOut_(hdc,11,11,@a,b)
   TextOut_(hdc,11,10,@a,b)
   TextOut_(hdc,10,9,@a,b)
   TextOut_(hdc,10,11,@a,b)
   ;
   SetTextColor_(hdc, #White)
   ;
   TextOut_(hdc,10,10,@a,b)
   ;
   StopDrawing() 
   ;
Until EventID = 16
... an old trick I messed with on VB a long time ago. From what I understand, using paths will make you lose anti-aliasing as it's not using the font rendering engine anymore.
User avatar
Fluid Byte
Addict
Addict
Posts: 2336
Joined: Fri Jul 21, 2006 4:41 am
Location: Berlin, Germany

Post by Fluid Byte »

There's another method you may consider, an old trick I messed with on VB a long time ago.
Yeah, I know that old cheesy trick too. ;) Used it to display debug info back in in the day with BlitzBasic and still use it in some game projects. But althought I already thought about using this method I think it has 2 main disadvantages. First, I doubt a border created with this technique is identical to anything a proper API command would produce (I know there seems to be no API call but maybe I'm just too blind). Second, I dislike the idea of calling TextOut_() (or a similar command) multile times (your code used 8 directional border). Normaly no big deal but you will notice slowdowns when scaling the display font to a large point size in realitme.
From what I understand, using paths will make you lose anti-aliasing as it's not using the font rendering engine anymore.
That's unfortuneatly true. Once converted to path the font loses it's typical properties.

However, I have to stick with this old work-a-round until something better arises.

PS: I just checked your X-Sub site and thought the design is a bit dull so I "pimped it up" a little 8)

http://codedreality.sam-host.net/temp/xsub
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
Post Reply