extrafont

ABU 27-Sep-2022

ABU 10-Aug-2024 - Added compatibility with Tcl9

extrafont is a multi-platform binary package designed to provide "private fonts" for Tk apps.

  • 10-Aug-2024 extrafont 1.3.1 released - See changes below

"Private fonts" are fonts usually delivered with an app.
They don't need to be installed in some 'standard' system-wide directories; once these fonts are loaded, they can be used in the same way of pre-installed fonts.
These loaded fonts are only visible by the process (app) who loaded'em, and then disappear when the app terminates.

APN 2024-12-24 - Q: is there a reason there is no x86 build for Tcl 9?

ABU 2024-12-27
A: The main reason is that I'm too lazy to even maintain Tcl9-x86 environments (for Windows and Linux) and, honestly, who still uses TclTk 32 bit?
In practice, the only thing missing to restore support for x86 is the availability of tclstub90.dll (32-bit), and its Linux counterpart. APN About 15% of the magicsplat distribution downloads are for 32-bits so there are still some out there. But I understand your point about moving on at some stage.

Download

  • [L1 ] extrafont-1.3.1 Multi-platform package (Windows/Linux/MacOSX)
  • [L2 ] extrafont Development-Kit. For developers/maintainers.

Windows Sample

Image Img-PrivateFonts

Linux Sample

Image Img-PrivateFonts-Linux

Change History

1.0 - Initial Release

  • added extrafont::load , extrafont::isAvailable , extrafont::availableFamilies'

1.1

  • added extrafont::unload, extrafont::loaded, extrafont::cleanup
  • extrafont::load can now load a font-file from a mounted virtual filesystem like a startkit or a startpack.

1.2

  • enhanced extrafont::load - extrafont::load now returns the list of the loaded font-families.
  • added extrafont::nameinfo command
  • added extrafont::query command
  • added extrafont::nametable::nameIDs command
  • BUGFIX: (Linux-only) extrafont::unload. It may crash after loading/unloading 4 font-files.

1.3

  • BUGFIX: Better support for identifying familyName for more particular font-files (Symbol fonts, Windows only fonts, ...). The new logic is far to be perfect but it has been tested on more than 300 font files.

1.3.1

  • Added compatibility with Tcl9

SYNOPSYS

The extrafont package provides these commands:

extrafont::load filename
Loads all the fonts contained in filename.
These fonts will be visible to the current process only and they will automatically disappear when the process terminates. After loading filename, a new font-family will be available to the current Tk app.
This command returns the list of the font-families loaded.
An error is raised if filename represents an invalid font-file, or if filename has been already loaded as an extrafont.
extrafont::unload filename
Unloads all the fonts previosly loaded with filename.
Note that if a widget is using these fonts, it may display them correctly, as long text or font-properties (e.g. size) in not changed; in these latter cases, Tk will replace the displayed text using a default font.
extrafont::loaded
Returns a list containing the names of all currently loaded extrafont font-files.
This command is obsolete and its use is deprecated. See extrafont::query command
extrafont::nameinfo fontfile
Returns a list of font-details. One font-detail (a dictionary) for each font contained in fontfile'.
extrafont::query kind ?selector pattern?
Returns lists of different kinds (files, families, fullnames, details) about the loaded fonts (just about the extrafont-loaded fonts), matching the optional selection-pattern.
A selection-pattern is made by a selector (-file, -family, -fullname) and a glob-style pattern.
 Examples:
  * list all the (extrafont) loaded font-files:
  extrafont::query files
  * list all the (extrafont) loaded font-families from font-files "Ariel*.ttf""
  extrafont::query families -file "*/Ariel*.ttf"
  * list all the details of the font-family "Ariel*"
  extrafont::query details -family "Ariel*"
extrafont::nametable::nameIDs
Returns all the valid keys used for the font-details dictionary
extrafont::cleanup
Unloads all the loaded extrafonts.
extrafont::isAvailable fontFamily
Returns true is fontFamily is avaiable.
extrafont::availableFamilies fontFamilyPattern
Returns the list of font-families matching the glob-style fontFamilyPattern.

One important distinction to keep in mind is among

  • font-filename
  • font-family
  • tk-fontname

Font-filename is used just for loading an external font:

  set fontfamilies [extrafont::load "c:/tmp/Monoton-regular.ttf"]

This font-file contains just one font. The font-family-name can be extracted as result of the extrafont::load command

  foreach fontfamily $fontfamilies {
     puts "Loaded font-family: $fontfamily"
  }
   # just get the 1st font-familiy
  set myNewFontFamily [lindex $fontfamilies 0] ;#  -->  "Monoton"

Then, when you want to use this new font, you should create or configure a tk-fontname (using the standard 'font' command)

 set myfontname "tk_monoton"  ;#  ... choose the name you want ..
 font create $myfontname -family $myNewFontFamily -size 20
  # or, let tk choose a fontname for you ...
 set myfontname [font create -family $myNewFontFamily -size 20]
  # then use $myfontname for a new widget ...
 label .mylabel -font $myfontname .......  

MG This is awesome! I have a couple of suggestions/observations, though:

  • It would be super handy if extrafont::load returned the font family, so you could do
    font create myNewFont -family [extrafont::load $file]
  • In your pkgIndex.tcl, I think you're better off using info sharedlibextension rather than trying to guess it by platform
  • On Windows, I think it's better to check if $tcl_platform(machine) == amd64 to determine if it's 64bit rather than 32. (IIRC, I stole that from the source for the platform::generic command when I needed to do something similar before)
  • In your availableFamilies command, I'd suggest replacing the foreach with an lsearch, which I think should be slightly faster/more efficient
    lsearch -all -inline -glob -nocase [font families] $familyPattern

This is a really neat functionality to add, thank you. :)

APN I second that.

ABU - Extracting the font-family from a font-file, or better, as suggested by MG, let extrafont::load return the loaded font-family, is a very difficult task.
Windows/Linux/Mac have three very different font-management APIs, and as far as I googled I never found any hint about how to solve it.
Expert help is welcomed !

MG I had, naively, assumed it would be a fairly simple matter, but I can't find any related API calls for getting the info (on Windows). Without something intended specifically for it, all I can think of is looping through the list of installed font families first, storing the list of families, and comparing to the result after loading. However, that is both ridiculously inefficient, and potentially not even useful (since your new font may have the same name as, but be a different font to, something already installed). I'm sure you can extract the information from the font file directly, but given how many different font-file formats there are, that would be rather a pain to do...

beware 13/12/2017. I did this:

  set currentfonts [extrafont::availableFamilies]
  set currfontl [llength $currentfonts]

  set fontpairs [list]
  foreach f $fontlist {
        extrafont::load $f
        set nowfonts [extrafont::availableFamilies]
        lappend fontpairs [list $f [lindex $nowfonts $currfontl]]
        incr currfontl
  }
  tk_messageBox -message $fontpairs

Which seems to help. fontlist is the result of glob on my directory of local fonts. Basically, at least on my system, the new fonts are added to the end of the list of available families, so if you add the fonts individually you can tally the filename against the font name.

ABU 27-May-2018 See the recent release of extrafont ver 1.2 enhanced the extrafont::load command, so that it returns the loaded font-families. Be aware that the returned value is a *list* of family-names, not just a single family-name.

MG Congrats on solving it! Great to see. I don't currently have a legitimate use for it personally, but I'm looking forward to playing with it for the hell of it at some point soon.

LES 2025 I can't seem to find any information on the license.

ABU 2025-01-02
A: See the included license.terms.
== Extrafont == 
A multi-platform binary package for loading "private fonts"

Copyright (c) 2017,2024 by A.Buratti <[email protected]> 

This library is free software; you can use, modify, and redistribute it
for any purpose, provided that existing copyright notices are retained
in all copies and that this notice is included verbatim in any
distributions.

This software is distributed WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

extrafont has been ported to Python (with tkinter) and it's quite popular. Below are some projects using it