News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Font and LOGFONT

Started by LordAdef, May 08, 2017, 03:48:49 PM

Previous topic - Next topic

LordAdef

Hi guys,

I wonder if you could help.

I created a font:
Quoteinvoke CreateFont, 80,0,600,0,400,0,0,0,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,\
                                           CLEARTYPE_QUALITY, DEFAULT_PITCH or FF_SCRIPT, chr$("MapTst")   ;DEFAULT_QUALITY

But I want to change one of its values. I know I need to reach its LOGFONT.
I tried things like:
Quotemov eax, Font5.LOGFONT.lfEscapement
mov [eax],100
                                                       
or
invoke SelectObject, hdc, Font5          ;select font      
mov     (LOGFONT PTR [eax]).lfEscapement, 1002


Obviously none of them work, but I think it shows what I want to do.

Cheers in advance

TWell

Maybe you have create new fonts?
GetObject()
CreateFontIndirect()

jj2007

Line 5126 of \Masm32\MasmBasic\MasmBasic.inc does what you want, but it looks complicated ;-)

include \masm32\include\masm32rt.inc

.DATA?
MbLogFont LOGFONT <?>

.code
start:
mov edi, offset MbLogFont
TheFont equ [edi.LOGFONT]
invoke lstrcpy, addr TheFont.lfFaceName, chr$("Times New Roman")
mov TheFont.lfWeight, FW_SEMIBOLD
invoke CreateFontIndirect, edi
MsgBox 0, LastError$(), "Hi", MB_OK
  exit

end start


GuiParas equ "Fonts", x99, y99, w360, h200      ; OPT_Icon Globe
GuiMenu equ <@Action, Pick a font>              ; in RichMasm, hit F6 to build it
include \masm32\MasmBasic\Res\MbGui.asm
  MakeFont hFont, Height:28, "Times New Roman"
  GuiControl MyEdit, "edit", font:hFont, text cfm$("I like these old-fashioned fonts.\n我喜欢这些老式字体。\nМне нравятся эти старомодные шрифты.")

Event Menu
  .if MenuID==0
      PickFont addr hFont, hMyEdit
  .endif
GuiEnd



LordAdef

Thanks, but I wanted to change one of the font's structure item at runtime after the font is already created.
So, I want to get say lfHeight and iterate its value on the go.


jj2007

Just delete the font, change the parameter, recreate it. Or create a second one based on the same logfont.
You may have to unselect it from a DC.

LordAdef

Quote from: jj2007 on May 09, 2017, 07:31:16 AM
Just delete the font, change the parameter, recreate it. Or create a second one based on the same logfont.
You may have to unselect it from a DC.

This is sad. And from your comment I understand once the font is created with the given logfont, there is no way to change it unless recreating it, right?

This sounds too expensive and not worth it.

JJ, no hack for that?

fearless

LOCAL lfnt:LOGFONT
;or in .data section: lfnt LOGFONT <>

CreateFont ....
mov hFont, eax

Invoke GetObject, hFont, SIZEOF lfnt, Addr lfnt
mov lfnt.lfWeight, FW_BOLD
Invoke CreateFontIndirect, Addr lfnt
mov hFontBold, eax

Invoke GetObject, hFont, SIZEOF lfnt, Addr lfnt
mov lfnt.lfHeight, 30d
Invoke CreateFontIndirect, Addr lfnt
mov hBiggerFont, eax

jj2007

Quote from: LordAdef on May 09, 2017, 08:19:50 AMThis sounds too expensive and not worth it.

Test it...include \masm32\MasmBasic\MasmBasic.inc
.DATA?
MbLogFont LOGFONT <?>
hFonts dd 100000 dup(?)

  Init
  mov esi, offset MbLogFont
  TheFont equ [esi.LOGFONT]
  invoke lstrcpy, addr TheFont.lfFaceName, chr$("Times New Roman")
  mov edi, offset hFonts
  xor ebx, ebx
  NanoTimer()
  .Repeat
inc TheFont.lfWeight
invoke CreateFontIndirect, esi
stosd
inc  ebx
  .Until !eax || ebx>100000
  Inkey Str$("%i fonts created", ebx), Str$(" in %i ms", NanoTimer(ms))
EndOfCode


Full source & exe attached. I am curious to see where the limits of various Windows versions are...

newrobert


LordAdef

Here it´s mine.
QuoteA operação foi concluída com êxito.
9971 fonts created in 7 msLast settings: Height=23, Weight=708

Don´t you have to destroy these fonts?

LordAdef

Thanks fearless! I´m gonna try your code too.

So basically, whenever I need to change something in a font created, I´m going to have to create it again?

I need to rotate a char using lfEscapament, I thought it was as simple as changing the value of lfEscapament, in the already existing font.

jj2007

#11
Quote from: LordAdef on May 09, 2017, 05:02:11 PMSo basically, whenever I need to change something in a font created, I´m going to have to create it again?

Yes, but as my example above shows, this is not a big deal; if you can create 10,000 fonts without problems, than a handful of fonts will certainly not have an impact.

As to destroying, this may end up in a religious debate on proper programming practices :bgrin:

With very few exception (atoms, clipboard formats, ??), everything that you ask from the OS and get a handle for will exist until either 1) you delete it or 2) the OS kills it via ExitProcess. If you have an empirical character, make an application that creates a thousand fonts and forgets to delete them before Exit; then call the application in an endless loop and watch how your machine behaves. Save all important stuff before doing that - you have been warned 8)

OK, for the daredevils among you I attach a nice little toy. It contains one executable that creates as many fonts as Windows can stand, and exits without ( :dazzled:) deleting them. The other exe launches the font creator in an endless loop - only Ctrl C can stop it. Run Launch_Pick_a_font.exe and watch the disastrous consequences of unorthodox programming practices 8)

P.S.: If you have an exceptionally tolerant and robust OS like Win7-64, you will typically see this in the console:...
36945 launches, ex=0 +9971 fonts created in 11 ms
36946 launches, ex=0 +9971 fonts created in 11 ms
36947 launches, ex=0 +9971 fonts created in 11 ms
36948 launches, ex=0 +9971 fonts created in 11 ms
36949 launches, ex=0 +9971 fonts created in 11 ms
36950 launches, ex=0 +9971 fonts created in 11 ms
...

LordAdef

well, I know the aforementioned debate. I read the whole thread.

But my question wasn't purely rhetorical though, I was actually thinking outloud about a strategy to make this work.

How about that:

Create an array of 360 fonts, each one having a lfEscapament angle. This way, it's just a matter of selecting the font corresponding to the angle needed.

jj2007

Quote from: LordAdef on May 09, 2017, 07:01:00 PMCreate an array of 360 fonts, each one having a lfEscapament angle. This way, it's just a matter of selecting the font corresponding to the angle needed.

Demo attached.

LordAdef

Haha, thanks for the caption!

How would you compare this way against a rotation algo manipulating an image? I´ve never done it before, so I can´t have an opinion on this nor I have the code to compare.

But let´s say I have a graphic object in the font and I would wanted to use it instead of an image sprite.

I´m sure you know what I´m trying to achieve: Draw things as fonts and rotate them using this system.