[quote=“jules”]
Or use LookAndFeel::getTypefaceForFont to apply your typeface to any fonts that you want to.[/quote]
OK, THAT’S the ticket. I now have platform independent fonts running in my plugin. Which means that I can start sending the Windows beta out to my beta testers. Huzzah!
For those that are as C++ impaired as I am, here’s how I did it, in excruciating detail (EDIT: now updated to use the correct reference counted pointer for the Typeface in the Look & Feel):
- In the new Jucer, create a new Console app, and call it Font Serializer
- Paste the following code into your Main.cpp file, overwriting everything else in there:
#include "../JuceLibraryCode/JuceHeader.h"
#include <iostream>
int main (int argc, char* argv[])
{
// This object makes sure that Juce is initialised and shut down correctly
// for the scope of this function call. Make sure this declaration is the
// first statement of this function.
const ScopedJuceInitialiser_NonGUI juceSystemInitialiser;
printf ("\n\n--------------------------------\n Font Serialiser by Niall Moody\n--------------------------------\n\n");
if (argc != 3)
{
printf (" Usage: FontSerialiser <filename> <fontname>\n\n");
printf (" FontSerialiser will turn a font into a compressed binary file.\n\n\n");
return 1;
}
// because we're not using the proper application startup procedure, we need to call
// this explicitly here to initialise some of the time-related stuff..
initialiseJuce_GUI();
// get file and font name from command line arguments
const File destFile (File::getCurrentWorkingDirectory().getChildFile (argv[1]));
String fontName(argv[2]);
// make sure the destination file can be written to
OutputStream *destStream = destFile.createOutputStream();
if (destStream == 0)
{
String error;
error << "\nError : Couldn't open " << destFile.getFullPathName() << " for writing.\n\n";
std::cout << error;
return 2;
}
// make sure the font is installed on the current system
StringArray fontNames = Font::findAllTypefaceNames();
if(!fontNames.contains(fontName))
{
String error ("\nError: The font " + fontName + " does not exist in the system\n");
std::cout << error;
return 3;
}
// load the font as a system-Typeface
Font font(fontName, 10, 0);
if(!Typeface::createSystemTypefaceFor (font))
{
String error ("\nError : Where's the font?\n\n");
std::cout << error;
return 4;
}
// copy the font-properties to a CustomTypeface
CustomTypeface customTypeface;
customTypeface.setCharacteristics(font.getTypefaceName(), font.getAscent(),
font.isBold(), font.isItalic(), ' ');
// Here's the important part: copy all glyphs to a new instance of CustomTypeface
customTypeface.addGlyphsFromOtherTypeface( *font.getTypeface(), 0, 256);
// finally write the typeface into the destination file
customTypeface.writeToStream(*destStream);
String op;
op << "\nWrote font " << fontName << " to file " << destFile.getFullPathName() << " successfully.\n\n";
std::cout << op;
delete destStream;
std::cout << "\n(You might want to use Binary Builder to turn this file into a c++ file now)\n\n ";
// this avoids leaking the LookAndFeel instance
shutdownJuce_GUI();
return 0;
}
- Figure out whatever type of shell magic is needed to run this program on your system. In OS 10.6, I had to run the following code in Terminal, after having an old friend of mine who is skilled in Unix hold my hand (he also gave me a Korg Monotron last week - now that’s a good friend):
I had previously copied the FontSerializer executable to the ~/SDKs/utilities folder.
- Run FontSerializer from the command window, using the proper arguments. Let’s say that you wanted to serialize a font called Helvetico. You would type something like this at the command prompt:
FontSerializer ~/SDKs/utilities/sourcefolder/HelveticoSerialized Helvetico
In this case, ~/SDKs/utilities/sourcefolder is the path to a folder called “sourcefolder” that we will be using in the next step. HelveticoSerialized is the name of the serialized font that we want to work with, and Helvetico is the source font located on our system.
- Next, use BinaryBuilder to turn the serialized font binary into a bunch of scrambled ASCII stored inside a .cpp/h pair. In order to do this, build the BinaryBuilder from the Juce distribution (look in the extras folder). You may need to do some shell magic to be able to run this program from the command prompt. Once you have this all figured out, at the command prompt type
BinaryBuilder ~/SDKs/utilities/sourcefolder ~/SDKs/utilities/destinationfolder HelveticoResource
where the first argument is the folder that contains the binary file(s) you want to put into code, the destination folder is where the code will be written, and the third argument is the name of your code.
-
In your project, edit the .h file of your Look and Feel class to include the .h file of the files you just generated. You should probably copy the files to some place you know that they will be safe.
-
In the LookAndFeel .h file, add the following line in the class declaration (I put it in Public):
- In the LookAndFeel .c file, add the following lines to the constuctor:
MemoryInputStream mis(HelveticoResource::helveticoserialized, HelveticoResource::helveticoserializedSize, false);
HelveticoTf = new CustomTypeface (mis);
-
In the destructor, be sure to delete HelveticoTf.
-
You will want to override the default getTypefaceForFont() function in your look in feel. The function can be as simple as
And that’s it. Custom typeface in your Juce project, platform independent.
Thanks for the help on this one.
Sean Costello