FLTK logo

Re: [fltk.general] Bundling TTF fonts with an FLTK application

FLTK matrix user chat room
(using Element browser app)   FLTK gitter user chat room   GitHub FLTK Project   FLTK News RSS Feed  
  FLTK Apps      FLTK Library      Forums      Links     Login 
 All Forums  |  Back to fltk.general  ]
 
Previous Message ]New Message | Reply ]Next Message ]

Re: Bundling TTF fonts with an FLTK application Webb Hinton Jul 27, 2021  
  I also ran into the problem of needing to embed a font. It'd be great if we could load a font from embedded bytes, just like we can load an svg from embedded bytes via Fl_SVG_Image(), without the need for platform specific code. 

Another use case: what if we needed to load a font from some kind of online font service (as Photoshop currently does)? Doing something like this would be very tricky with the current font loading setup. 


On Wednesday, January 24, 2018 at 11:42:42 AM UTC-5 Albrecht Schlosser wrote:
Hi Ian,

On 23.01.2018 23:43 Ian MacArthur wrote:
> Hi Albrecht,
>
> Well, I don’t really know the context of deech’s question, but I interpreted it as asking how to load some special application specific font...

And so did I. My case is similar, hence I tested your code to see if it
fits my purpose. I'm developing a private application with a potential
tiny user group (3 or 4 persons). The first person is me, and I'd like
to develop and use the application under Linux, the other potential
users must be assumed to know absolutely nothing about software
installation and such, and they are all Windows users. My app includes a
small sqlite3 database (i.e. one external file) and needs a special font
for printing and pdf generation. Basically printing can also use pdf
files, so I'm using libharu/hpdf for this. I found out that libharu can
embed a font in the pdf file, so this is all fine and working. The font
is the second external file my application needs.

I thought of embedding a font somehow (I'm still investigating this,
especially for Windows) and I believe I can manage to do this, but I'd
also like a cross platform solution with an external font file.

> The approach I show is a pretty rubbish way of loading fonts in the general case - you are far better putting them somewhere the OS will find them by “normal” means then, and just using the normal fltk font handling methods.

That would be fine if I could assume that my potential users could and
would install a special font under their Windows version. AFAICT the
current font in question (Palatino Linotype, see my example) is
available under Windows 10, but at least one user has Windows 7 and I
currently don't know if it is available under Win7, but I can likely
find this out.

> However if you have some special font that your application needs (e.g. in my original case some special musical notation glyphs...) then I’m proceeding on the assumption that you already know the name of your font file, and presumably also know the “given names” of the faces within the file (which is true in my case, at any rate!) and so this issue doesn’t really arise.

That's true in the special case I need. But I was wondering how it would
be in a more general case.

> I just hard code the actual name of the font face (occasionally with an ifdef to help out, if the OS presents the name differently.)

Yep, that's what I did now.

> Latterly, as with the "fltk-test-regular.otf” font used here, I’ve been using a font editor to collate my own collections of glyphs, and so I have control of the names too.
> How useful that is for other users though...

I wouldn't go so far. It's a very small application and what I need is
really only one ready-to-use font. But thanks for sharing your solution.

>> I used the Windows built-in font viewer to see/guess font names for Windows because the short Linux font name didn't work.

Maybe I should have written "because the short Linux font name didn't
_always_ work". One example is the "GFS Artemisia" font. Under Linux I
get with the utf8 demo (thanks for that and the hint in your other
posting, btw.):

$ bin/examples/utf8
idx 123
User name :GFS Artemisia:
FLTK name : GFS Artemisia:
size 16

idx 124
User name :GFS Artemisia bold:
FLTK name :BGFS Artemisia:
size 16

idx 125
User name :GFS Artemisia italic:
FLTK name :IGFS Artemisia:
size 16

BTW: I don't see "GFS Artemisia bold italic" in the list of fonts in the
utf8 font selector although I have all four font files (Ubuntu 16.04):

/usr/share/fonts/truetype/artemisia/GFSArtemisiaIt.otf
/usr/share/fonts/truetype/artemisia/GFSArtemisiaBold.otf
/usr/share/fonts/truetype/artemisia/GFSArtemisia.otf
/usr/share/fonts/truetype/artemisia/GFSArtemisiaBoldIt.otf

WRT Windows: I think I got the "FLTK font name" wrong with this
particular font. Windows shows something that looks like a font name in
the window title displaying the font when you double-click on the font
file in the explorer. It also shows the "font name" below in the window
which is in this case "GFS Artemisia" (with a space between "GFS" and
"A.."). I missed this space and used the font names from the window
title which seemed to work (see my posted example program) but now I see
that "GFS Artemisia" works well in all 4 font faces (regular, bold,
italics, and bold italics). So this issue is resolved. Thanks for your help.

>> Here is what I got so far:
>>
>> typedef struct fontdef_ {
>> const char *name; // FLTK font name (1st char = { ' ' | 'B' | 'I' | 'P' }
>> const char *file; // system font (file) name to load
>> } fontdef_t;
>
>
> There’s a bit of a trick to the fltk font name 1st character thing, in that the matching of the first glyph is case sensitive, but matching of the font face name generally appears not to be.

Interesting. I didn't know that the font name would match case insensitive.

> So you can’t, for example, ask for “Palatino” and get the right thing, since the leading “P” is interpreted as bold+italic, and so on.

That's why I always used one leading character, with a space for the
regular font. This seems to work always (Windows and Linux). I think
it's also documented this way, hence we should encourage users to do it
like this to avoid ambiguities.

> However, if you ask for “palatino” it doesn’t match the “P”, nor does it match “ “, “B”, or “I”, so then falls back to trying the whole name, which usually does then match OK... Well, it does for me at any rate.

See above. I think always using a space or B, I, P is to be preferred.

> If you look at the code, e.g. fl_font_xft.cxx, fl_font_win32.cxx, etc, are littered with variants of this switch:
>
> switch (*name++) {
> case 'I': italic = 1; break;
> case 'P': italic = 1;
> case 'B': weight = FW_BOLD; break;
> case ' ': break;
> default: name--;
> }
>
>
> Where basically we look for the “ “, I, P, B and if they are not present we step back to using the whole name and present that to the font engine verbatim.

I'd seen this, but I missed the "default: name--;" case so I got the
impression that you'd always need a leading character which is not true
as you pointed out, but I'll use it in my code anyway.

> Though I’m not sure if that helps with your question or not?

I knew that particular bit of your answer(s), but everything else really
helped. Thanks again.

>> Note that I load all fonts in all variants and select one (test_font + fn) for display. The GentiumPlus font doesn't have all four variants (only a regular and an italic variant). Under Linux the bold variants seem to be created on the fly (pretty well), whereas Windows seems to use the fonts as-is (no artificial bolding).
>
> The X11+XFT setup will fake bolding, in essence by “overstriking” the glyph, just like in the olden days!

Yep, that's what I saw in my tests.

> TBH, I thought Windows did too (I’m pretty sure it used to...) but haven’t really tried.

You're correct. I tested again, and (if you use the correct font names
and the regular font file, then) it does. Of course the original font
files have a much better quality, but Windows does it also with the
"regular" font file in all cases. Sorry for the noise...

>> This works so far (Windows and Linux), but I think there should be an easier way to retrieve the font name that is required to assign the FLTK font (under Windows) - or did I do anything wrong?
>>
>> How to get the "font name" from the font file if you have an arbitrary (maybe user-supplied) font file?
>>
>>
>> Do you know of a better way for Windows?
>
>
> I’ve never really tried to get the “actual” names under Windows from a raw font file, though I’m sure it must be possible!
>
> FLTK can do it for a font, once it is loaded, if you use Fl::get_font_name(...), it can return the name - I think our Fl_Fontdesc struct holds two names in effect, one in “fontname” and one in “name” where “fontname” is the “pretty” name extracted from the face, and “name” is what we load it as. Or something...

Thanks for this as well. I'll try that and investigate a little more.

> Anyway:
>
> The only time something similar came up, I let the user load their supplied “private” font file using basically the code I showed before, e.g. using AddFontResourceEx() etc under Windows, or FcConfigAppFontAddFile() under XFT, and then loaded *all* the fonts (basically using font_count = Fl::set_fonts("*”); and etc) and then displayed a font chooser widget (based on the same code as the one I hacked up for the utf8 test program) and allowed the user to select a font face from there.
>
> I then stored the selected name in an fl_preferences widget, so that I could use the name again next time. So I never actually extracted the name, I let the user find it...
>
> Anyway, worked well enough I guess.

Good approach. Would be at least a "Plan B".

> Is there some specific thing we need to fix here, or...?

Not really. But after all my struggling I could imagine to add a feature
(request) to set a FLTK font directly from a font file. Instead of using
platform specific code in the app and then to use the font name with

Fl::set_font(font_number, font_name);

I could imagine a new or overloaded function

Fl::set_font[_from_file](Fl_Font font_number, [int mode,] const char
*file_or_name);

Given your code for all major supported platforms this should be doable.

What do you and other devs (and users) think of such an extension?

Another option would be to embed a font (somehow) and load the font from
this embedded resource, just like we can open jpg and png images from
memory. Something like that, maybe...

--
You received this message because you are subscribed to the Google Groups "fltk.general" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fltkgeneral+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/fltkgeneral/ecb8f7b9-8a86-4953-911f-0cd233efc281n%40googlegroups.com.
Direct Link to Message ]
 
     
Previous Message ]New Message | Reply ]Next Message ]
 
 

Comments are owned by the poster. All other content is copyright 1998-2024 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.