> > This code loads (and unloads) a private font at runtime for the test
> > app to use. It works on WIN32, OSX, X11.
>
> Doh!
>
> Wrong version - this one doesn’t load the OSX font locally, it expects
> the private font to be loaded through the OSX bundle...
>
> WIN32 and X11 should be fine though!
>
> I'll see if I can find the version that loads the OSX private font
> directly; I don’t have it here, nor any Mac readily to hand...
>
Hah! Found it - I did have a copy of the Mac-compatible version after all.
Basically the same test harness as before, but with support for loading private fonts under OSX too.
In case anyone (other than me) actually wants this ability!
//////////////////////////////////////////////////////////////////////////////
/* Test the loading of application specific fonts.
* Uses platform-specific coding and API's. */
#ifdef _WIN32
# define _WIN32_WINNT 0x0501 /* need at least WinXP for this API, I think */
# include <windows.h>
#elif __APPLE__
# include <ApplicationServices/ApplicationServices.h>
#else /* Assume X11 with XFT/fontconfig - this will break on systems using legacy Xlib fonts */
# include <fontconfig/fontconfig.h>
# define USE_XFT 1
#endif
/* Fltk headers */
#include <FL/Fl.H>
#include <FL/x.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Box.H>
#include <FL/fl_draw.H>
/*************************************************************/
static int loaded_font = 0;
static Fl_Font test_font = (FL_FREE_FONT + 1);
/*************************************************************/
// Create some portability wrappers
#ifdef _WIN32
# define i_load_private_font(PATH) AddFontResourceEx((PATH),FR_PRIVATE,0)
# define v_unload_private_font(PATH) RemoveFontResourceEx((PATH),FR_PRIVATE,0)
#elif __APPLE__
# include <stdio.h> // I use printf for error reporting in the Apple specific code!
/* For the Apple case, we need to do a bit more work, since we need to convert
* the PATH into a CFURLRef before we can call CTFontManagerRegisterFontsForURL()
* with it.
* Otherwise, all three systems would have basically the same structure here! */
static int i_load_private_font (const char *pf)
{
int result = 0;
CFErrorRef err;
// Make a URL from the font name given
CFURLRef fontURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault,
(const UInt8*)pf,
strlen(pf),
false);
// Try to load the font file
if (CTFontManagerRegisterFontsForURL(fontURL, kCTFontManagerScopeProcess, &err))
{
result = 1; // OK, we loaded the font, set this non-zero
}
else
{
printf ("Failed loading font: %s\n", pf);
}
// discard the fontURL
if (fontURL) CFRelease (fontURL);
return result;
} // i_load_private_font
static void v_unload_private_font (const char *pf)
{
CFErrorRef err;
// Make a URL from the font name given
CFURLRef fontURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault,
(const UInt8*)pf,
strlen(pf),
false);
// Try to unregister the font
CTFontManagerUnregisterFontsForURL(fontURL, kCTFontManagerScopeProcess, &err);
if (fontURL) CFRelease (fontURL);
} // v_unload_private_font
#else /* Assume X11 with XFT/fontconfig - will break on systems using legacy Xlib fonts */
# define i_load_private_font(PATH) (int)FcConfigAppFontAddFile(NULL,(const FcChar8 *)(PATH))
# define v_unload_private_font(PATH) FcConfigAppFontClear(NULL)
#endif
/*************************************************************/
class page_view : public Fl_Box
{
public:
// constructor
page_view(int x, int y, int w, int h) : Fl_Box(x,y,w,h) {}
private:
void draw(void); // draw method
};
/*************************************************************/
void page_view::draw(void)
{
/* This is the "raw" UTF8 encoding for some symbols from the Supplementary Plane. Musical Notation in this case */
static const char notes[] = ":\xf0\x9d\x85\xa0-\xf0\x9d\x85\xa1-\xf0\x9d\x85\xa2-\xf0\x9d\x85\xa1-\xf0\x9d\x85\xa0:";
const char solo[] = "\xf0\x9d\x85\xa0";
char clefG[8]; // 1D11E
/* Convert a Unicode value, 0x1D11E in this case (a G clef), into a UTF8 string using the fltk helper function */
int ll = fl_utf8encode(0x1d11e, clefG);
clefG[ll] = 0; // make sure UTF8 string is NULL terminated
int x0 = x(); // origin is w.r.t. the Fl_Box
int y0 = y();
int w0 = w();
int h0 = h();
fl_push_clip (x0, y0, w0, h0); // clip to the current page view
// set the background colour
fl_color(FL_WHITE);
fl_rectf(x0, y0, w0, h0);
// Basic string in default font test
fl_font(FL_HELVETICA, 30);
fl_color(FL_BLACK);
fl_draw("This is the default font (FL_HELVETICA)", x0+25, y0+100);
// Test the "private" font the application has loaded for its own use
fl_font(test_font, 40);
fl_color(FL_BLACK);
fl_draw("This is the private font we loaded", x0+25, y0+200);
fl_font(test_font, 25);
fl_color(FL_DARK_RED);
fl_draw("Here are some glyphs from the SMP using the test font", x0+25, y0+250);
fl_font(test_font, 40);
fl_color(FL_BLACK);
// Special notes test
fl_draw(notes, x0+25, y0+300);
// SINGLE note test
fl_draw(solo, x0+225, y0+300);
// CLEF test
fl_draw(clefG, x0+300, y0+300); // clefG
fl_pop_clip(); // restore the default clip region
} // draw method
/*****************************************************************************/
static void load_extra_font(void)
{
/* Load the font using the appropriate platform API */
loaded_font = i_load_private_font("./font/fltk-test-regular.otf");
/* set the extra font */
if (loaded_font)
{
Fl::set_font(test_font, "fltk");
}
} // load_extra_font
/*****************************************************************************/
static void free_extra_font(void)
{
if (loaded_font)
{
v_unload_private_font("./font/fltk-test-regular.otf");
}
loaded_font = 0;
} // free_extra_font
/*****************************************************************************/
int main(int argc, char **argv)
{
Fl_Window *main_win = new Fl_Window(650, 400, "Load Special Font");
/* Load our additional font for musical symbols from the Supplementary Plane */
load_extra_font();
page_view *test_page = new page_view(5, 5, (main_win->w() - 10), (main_win->h() - 10));
test_page->type(FL_FLAT_BOX);
main_win->end();
main_win->resizable(test_page);
// Show the test window
main_win->show(argc, argv);
/* Run the fltk event loop */
int result = Fl::run();
/* Unload the private font we loaded earlier */
free_extra_font();
return result;
}
/* end of file */