Skip to content
⌘ NSIS Forum Archive

Installing Fonts

11 posts

kluck#

Installing Fonts

I understand and realize that there are multiple threads on this but after a few hours of this I need some personalized help and those threads are not helping.

i am trying to write an installer that installs some fonts I use in my application. I use the following code to do this


!include FontName.nsh
!include FontRegAdv.nsh

... ;more code in here

Section "Fonts"
!define KORIGANFONT "..\Fonts\KoriganITC TT Bold.ttf"
StrCpy $FONT_DIR $FONTS

!insertmacro FontName "JOKERMAN.TFF"
!insertmacro FontName ${KORIGANFONT}

SendMessage ${HWND_BROADCAST} ${WM_FONTCHANGE} 0 0 /TIMEOUT=5000
SectionEnd
I have two questions.
1) The installmacro FontName ${KORIGANFONT] line won't even compile. It says there are 4 parameters getting passed instead of 2. It must have something to do with the spaces in the name but I thought I handled that with the !define. I guess I don't know how to define a file name with spaces.
2) This code doesn't work. I'm using it straight from the examples but nothing gets installed. Has anyone created an install with a successfully working font install? Is this code no longer working for some reason? Have I messed up something I cannot see right now?

Thanks!
Anders#
1) Quote the parameter when using !insertmacro

2) Do you have RequestExecutionLevel in your script?
kluck#
Quoting the parameter doesn't fix the compilation error and I do have the RequestExecutionLevel written and assigned to admin.
demiller9#
Just to be clear, you tried
!insertmacro FontName "${KORIGANFONT}"
and it still said there were 4 parameters instead of 2?
Anders#
You could try modifying FontName.nsh by changing
push ${FONTFILE}
to
push "${FONTFILE}"
although I'm not sure if we are looking at the same macro because the one I'm looking at only takes a single parameter!

I don't claim to understand anything about installing fonts but if you just want the name from the .ttf file, why not just look it up on your local system and just use a string in the installer?

See also: http://nsis.sourceforge.net/Get_localised_font_name
Anders#
Here is some NSIS code to get the name but I did not do a lot of testing and it will only work on TTF files where the name is stored as Microsoft+UCS2.

#https://www.microsoft.com/typography...otspec/os2.htm
#http://developer.apple.com/fonts/ttr...Chap6name.html
#http://www.codeproject.com/KB/GDI/fontnamefromfile.aspx
#http://stackoverflow.com/questions/5...-from-ttf-file
#http://scripts.sil.org/cms/scripts/p...s-chapter08#An Introduction to TrueType Fonts: A look inside the TTF format
#https://autohotkey.com/board/topic/3...f-getfontname/
!macro Read16BE h out tmp
FileReadByte ${h} ${tmp}
FileReadByte ${h} ${out}
IntOp ${tmp} ${tmp} << 8
IntOp ${out} ${out} | ${tmp}
!macroend
!macro Read32BE h out tmp tmp2
!insertmacro Read16BE ${h} ${tmp} ${tmp2}
!insertmacro Read16BE ${h} ${out} ${tmp2}
IntOp ${tmp} ${tmp} << 16
IntOp ${out} ${out} | ${tmp}
!macroend

Function TTF_GetEmbeddedFontName
System::Store S
Pop $0
StrCpy $9 "" ; Return "" on error/not found
FileOpen $0 $0 r
!insertmacro Read16BE $0 $1 $R0
IntCmpU $1 1 "" err err ; Version.Major = 1
!insertmacro Read16BE $0 $1 $R0
IntCmpU $1 0 "" err err ; Version.Minor = 0
!insertmacro Read16BE $0 $8 $R0 ; NumOfTables
FileSeek $0 12 SET
StrCpy $2 "" ; TblIdx
tbl_loop:
FileSeek $0 12 SET
IntOp $R0 $2 * 16
FileSeek $0 $R0 CUR
!insertmacro Read32BE $0 $3 $R0 $R1
IntOp $4 $3 & 0xff000000 ; szTag[0]
IntCmpU $4 0 err
FileSeek $0 4 CUR ; skip checksum
!insertmacro Read32BE $0 $4 $R0 $R1 ; offset
#!insertmacro Read32BE $0 $5 $R0 $R1 ; length
IntCmpU $3 0x6E616D65 nametbl ; "name"
IntOp $2 $2 + 1
IntCmpU $2 $8 err tbl_loop err
nametbl: ; $4=name table file offset
FileSeek $0 $4 SET
!insertmacro Read16BE $0 $1 $R0
IntCmpU $1 0 "" err err ; Format must be 0
!insertmacro Read16BE $0 $8 $R0 ; Name Records count
!insertmacro Read16BE $0 $3 $R0 ; Storage offset (From start of name table)
StrCpy $2 ""
nr_loop:
IntOp $R0 $2 * 12
IntOp $R0 $4 + $R0
IntOp $R0 $R0 + 6
FileSeek $0 $R0 SET
!insertmacro Read16BE $0 $1 $R0 ; Platform
!insertmacro Read16BE $0 $R1 $R0 ; Platform-specific encoding
!insertmacro Read16BE $0 $R2 $R0 ; LanguageID
StrCmp "$1$R1" "31" "" nr_next ; Only supports platform = 3,1 (Microsoft,UCS2)
!insertmacro Read16BE $0 $1 $R0 ; NameId
StrCmp $1 4 "" nr_next ; 4 is "Full name of the font"
!insertmacro Read16BE $0 $7 $R0 ; String length
!insertmacro Read16BE $0 $6 $R0 ; String offset
IntOp $6 $4 + $6
IntOp $6 $3 + $6
FileSeek $0 $6 SET
!ifdef NSIS_PACKEDVERSION
System::Call '*(&i$7)p.r6'
System::Call 'KERNEL32::ReadFile(p$0,p$6,i$7,*i,p0)'
!else
System::Call '*(&i$7)i.r6'
System::Call 'KERNEL32::ReadFile(i$0,i$6,i$7,*i,i0)'
!endif
StrCpy $5 0
toutf16le:
System::Call '*$6(&i$5,&i1.R3,&i1.R4)'
System::Call '*$6(&i$5,&i1R4,&i1R3)'
IntOp $5 $5 + 2
IntCmpU $5 $7 "" toutf16le
IntOp $7 $7 / 2
System::Call '*$6(&w$7.r9)'
System::Free $6
Goto err
nr_next:
IntOp $2 $2 + 1
IntCmpU $2 $8 err nr_loop err

err:
FileClose $0
Push $9
System::Store L
FunctionEnd

Section
Push "C:\Boot\Fonts\segoe_slboot.ttf"
Call TTF_GetEmbeddedFontName
Pop $0
DetailPrint |$0|
SectionEnd
kluck#
Let me try modifying the nsh file and see what happens. At first i got an error that said it takes only 1 parameter. Another time I got an error that says it takes two. I don't believe I changed what function I called.
stass#
Anders
Thank you for the useful function !
Please add to the function - detection of font version.
kluck#
Well good news and bad news.

I got the above to work. Here is the working version.

!include FontName.nsh
!include FontReg.nsh

... ;more code in here

Section "Fonts"

!define KORIGANFONT "..\Fonts\KoriganITC TT Bold.ttf"
StrCpy $FONT_DIR $FONTS
!insertmacro InstallTTFFont "JOKERMAN.TFF"
!insertmacro InstallTTFFont "${KORIGANFONT}"
SendMessage ${HWND_BROADCAST} ${WM_FONTCHANGE} 0 0 /TIMEOUT=5000

SectionEnd
The bad news is that I'm not 100% sure what I did differently here. Yes, the InstallTTFFont is different, but I tried that already and that wasn't working before. The only thing that really changed was Anders suggestion of going into the FontReg.nsh file and changing the line of code and place quotes around the ${FONTNAME} parameter. That worked flawlessly. Once I made that change not only did the KORIGAN font finally install but so did everything else. It makes me wonder if having that parameter quoted is the actual fix here. Not sure. If other people are able to get FontReg.nsh to work without this patch, then I really don't know what I did to make this work. That's the only explanation I have.

Thanks Anders!
Anders#
The quote patch fixes compiler errors for fonts that have a space in the name/path. Another workaround might be to just copy the name into a variable and just use that as the parameter.