Recent

Author Topic: Font bundling or fallback  (Read 2606 times)

FRex

  • New Member
  • *
  • Posts: 20
Font bundling or fallback
« on: October 19, 2017, 12:43:04 am »
I use a custom font in one component.
The letters look like they are twice the width if it's missing from the user computer.
Putting the file next to the exe doesn't help.
If I put the file in C:\Windows\Fonts it works, but that's way too silly to ask people to do and too risky to do myself.

Is there a way to bundle a custom font to the exe, near it, in it, etc. or at least some easy (i.e. not checking C:\Windows\Fonts and /etc/share/fonts on Linux) way to detect that font is missing and then switch to some other one seamlessly, all on form creation time?
App to keep track of notes in a single plain text file tagged by hashtags: https://github.com/FRex/botes

RAW

  • Hero Member
  • *****
  • Posts: 868
Re: Font bundling or fallback
« Reply #1 on: October 19, 2017, 01:06:09 am »
SEARCH: "Embed font to use without installing" ....
Of course you can load the font from RES... (PROJECT, PROJECT OPTIONS, RESOURCES).

Code: Pascal  [Select][+][-]
  1. VAR
  2.   Form1: TForm1;
  3.  
  4.  
  5.  Function AddFont    (Dir : PAnsiChar;
  6.                       Flag: DWORD): LongBool; StdCall;
  7.                       External GDI32
  8.                       Name 'AddFontResourceExA';
  9.  
  10.  Function RemoveFont (Dir : PAnsiChar;
  11.                       Flag: DWORD): LongBool; StdCall;
  12.                       External GDI32
  13.                       Name 'RemoveFontResourceExA';
  14. Implementation
  15.  {$IFNDEF FPC}
  16.   {$R *.DFM}
  17.  {$ELSE}
  18.   {$R *.LFM}
  19.  {$ENDIF}
  20.  
  21.  
  22. Procedure TForm1.FormCreate(Sender: TObject);
  23.   Var
  24.    strAppPath: String;
  25.  Begin
  26.   strAppPath:= ExtractFilePath(Application.ExeName);
  27.  
  28.   If FileExists(strAppPath+'FONTS\MONT BLACK.otf')
  29.   Then
  30.    If AddFont(PAnsiChar(strAppPath+'FONTS\MONT BLACK.otf'), $10)
  31.    Then SendMessage(Handle, WM_FONTCHANGE, 0, 0);
  32.  End;
  33.  
  34.  
  35. Procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
  36.   Var
  37.    strAppPath: String;
  38.  Begin
  39.   strAppPath:= ExtractFilePath(Application.ExeName);
  40.  
  41.   If FileExists(strAppPath+'FONTS\MONT BLACK.otf')
  42.   Then
  43.    If RemoveFont(PAnsiChar(strAppPath+'FONTS\MONT BLACK.otf'), $10)
  44.    Then SendMessage(Handle, WM_FONTCHANGE, 0, 0);
  45.  End;
Windows 7 Pro (x64 Sp1) & Windows XP Pro (x86 Sp3).

FRex

  • New Member
  • *
  • Posts: 20
Re: Font bundling or fallback
« Reply #2 on: October 19, 2017, 01:21:04 am »
I've seen it. That thread and your code use GDI32 so they'll be Windows only. I'm back to Windows by now but I'd like my project to work on Linux too just in case I move again, I used to use it on my work laptop that was Linux, etc.

I also dislike it when there are projects that are in theory portable, made on portable toolkits, etc. but then have bit of code that makes them not portable after all..

Are resources in project options portable to both Linux and Windows with no code changes? That's what I aiming for.

If there is no nice way then it's okay and I just want to know that and I'll just bite the bullet and direct to font download as I do now or switch to some built in one by default and change it on load?
App to keep track of notes in a single plain text file tagged by hashtags: https://github.com/FRex/botes

RAW

  • Hero Member
  • *****
  • Posts: 868
Re: Font bundling or fallback
« Reply #3 on: October 19, 2017, 09:24:48 pm »
Quote
...and I'll just bite the bullet and direct to font download as I do now or switch to some built in one by default and change it on load?
Really? A font download....  :)

I don't see the problem here, on WINDOWS it's very nice to handle this so why not use {$IFDEF MSWINDOWS} and use the api?

And on LINUX play around with this:
Code: Pascal  [Select][+][-]
  1. if Screen.Fonts.IndexOf('DejaVu Sans Mono') <> -1 then
  2.    SynMailBody.Font.Name := 'DejaVu Sans Mono'
  3. else
  4.  if Screen.Fonts.IndexOf('Courier New') <> -1 then
  5.     SynMailBody.Font.Name := 'Courier New'
  6.  else if Screen.Fonts.IndexOf('Courier 10 pitch') <> -1 then
  7.     SynMailBody.Font.Name := 'Courier 10 pitch';
  8.  
  9. cp -rf fonts $HOME/.fonts  //Copy Font
  10. fc-cache -fv               //Cache Refresh
I don't have any LINUX computer here, so I cannot test this...  :)

I'm not a big fan of the word "crossplatform", in my eyes there is nothing out of the box like that. With LAZARUS you can code for WINDOWS, LINUX and so on only because people worked really hard to implement stuff that works on each platform...
I don't see that there is code that works on every platform without this background work...
"Crossplatform" is a stupid word...  Yes, I couldn't help myself...  :)
Windows 7 Pro (x64 Sp1) & Windows XP Pro (x86 Sp3).

Josh

  • Hero Member
  • *****
  • Posts: 1274
Re: Font bundling or fallback
« Reply #4 on: October 20, 2017, 02:51:24 am »
Hi
If your using windows, I tend to use innosetup to accomplish this.
using innosetup
Code: [Select]
#define MyLocation "C:\Folder to ompiled application on your machine\"
nb note the folder is with quotation marks and finishes with a \ 
ie "c:\my_projects\my_super_app\"
Then in the [files] section
Code: [Select]
[Files]
Source: "{#MyLocation}xxxxxxxxx.TTF"; DestDir: "{fonts}"; FontInstall: "FONT NAME"; Flags: onlyifdoesntexist uninsneveruninstall
ie Source: "{#MyLocation}Gill Sans MT.TTF"; DestDir: "{fonts}"; FontInstall: "Gill Sans MT"; Flags: onlyifdoesntexist uninsneveruninstall

Innosetup can do much more than this, you can create it so that it detects if your using x64 or x32 and then install the correct version of your application, with then the correct bitness of any dll's

if your targeting OSX then the fonts can be placed in your package file and will not be installed, to the system but will be available to the application in the bundle.

Obviously, make sure that you have the rights to distribute the font you are using.
The best way to get accurate information on the forum is to post something wrong and wait for corrections.

 

TinyPortal © 2005-2018