How to load fonts? | API Solution for C++
Overview
To answer the question, how to load fonts, first we need to learn that any font is physically an array of bytes in which data is represented in some format. Therefore, for correct font loading you need to know two key parameters:
- Font format. Fonts can have different formats like
TrueType
,Type1
, etc. - Storage, where the binary data that represents the font is being held. Each font is represented as binary data but the way this data is stored may differ. In most cases, the font is being stored as a file on a hard drive. But sometimes font binary data can be placed in a different file which is not a font itself. For example, files created by Microsoft Word or Adobe Acrobat. These are files with extensions
.docx
,.pdf
. They can include different fonts.
Objects and parameters required for font loading
Aspose.Font for C++ gives object FontDefiniton for notifying two key parameters demanded for font loading.
After creating and initiating FontDefiniton object you only need to call static method Aspose.Font.Font.Open() and pass just initialized object FontDefiniton as a parameter to load the desired font and get a reference on it.
Let’s describe it with the pseudocode:
1using Aspose::Font;
2 ...
3
4 // Initialize object FontDefinition with appropriate properties
5 System::SharedPtr<FontDefinition> fontDef = System::MakeObject<FontDefinition>();
6 System::SharedPtr<Font> desiredFont = Aspose::Font::Font::Open(fd);
The final result of the font loading is getting an object of Aspose.Font.Font type. Class Aspose.Font.Font is a base font class of Aspose.Font for the C++ library. It represents the main functionality of working with fonts.
Getting loaded a font into Aspose.Font.Font type object you will be able to render text with this font, get encoding data, and font metrics. You will also be able to modify or save this font and many more.
To initiate the FontDefiniton object we need to give FontDefinition() 2 font parameters, - the format type, and the object that describes the storage for font binary data. The first parameter is notified with FontType enumeration.
To simplify work with the second parameter, Aspose.Font offers a series of objects that gives universal access to the font binary data independently from where the font is placed.h
This universal access is linked with such a thing as a byte stream. So, independently from where the font is placed - into a file on a disk, inside another file, byte array in memory - in any case, special Aspose.Font objects will provide an access to the byte stream, related to the desired font.
Let’s describe these objects:
StreamSource class. This abstract base class defines the properties and methods that give access to the font byte stream. GetFontStream() method of this class returns a stream, related to binary font data. Property Offset points on the position at this stream, from where we must start to read data.
Two most used classes inherited from the base StreamSource:
- FileSystemStreamSource - designed to provide access to the stream, based on the file system. Property FileName returns the name of the font file. GetFontStream() method returns a byte stream, related to this file.
- ByteContentStreamSource - provides access to the stream, based on the byte array.
How to initiate classes?
Here are examples of the initiation of these classes.
- Let’s assume that the font is in the file named Lora.ttf. In this case, to get access to the byte stream of this font we need to create the object of type FileSystemStreamSource using this single constructor:
1 System::SharedPtr<FileSystemStreamSource> fontSource = System::MakeObject<FileSystemStreamSource>("Lora.ttf");
- If the font binary data is located in a binary array defined by the byte [] fontArray variable, then an object of type ByteContentStreamSource will provide an access to the font data stream, based on the fontArray variable. To get access to the font byte stream, we have to create an object of type ByteContentStreamSource to get access to the stream, related to the font byte array using code like this:
1 System::SharedPtr<ByteContentStreamSource> fontSource = System::MakeObject<ByteContentStreamSource>(fontArray);
So, to provide access to font binary data, use objects inherited from the base StreamSource class. Further, we will call such objects font stream sources.
FontFileDefinition object
Most fronts are located in regular files but at the same time, part of fonts may have different data sources. To join into one object terms file and font binary stream, Aspose.Font library provides special object FontFileDefinition.
This object has such properties:
- FileName - name of font file.
- FileExtension - extension of a font file.
- StreamSource - font stream source.
- Offset - offset inside the font byte stream.
The simplest and one of the most used constructors of this object is the constructor with the following signature: FontFileDefinition (System::SharedPtr System::IO::FileInfo fontFile), use this constructor for cases when the desired font is in a file on the hard drive.
Here is an example of initiating such an object for font Montserrat
which is located in the file C:\Windows\Fonts\Montserrat.ttf:
1 System::SharedPtr<FontFileDefinition> fileDef = System::MakeObject<FontFileDefinition>(System::MakeObject<System::IO::FileInfo>(u"C:\\Windows\\Fonts\\Montserrat.ttf"));
Also,
FontFileDefinition can reference Montserrat
font using the following constructors:
1 System::SharedPtr<FontFileDefinition> fileDef = System::MakeObject<FontFileDefinition>(System::MakeObject<FileSystemStreamSource>(u"C:\\Windows\\Fonts\\Montserrat.ttf"));
2
3 System::SharedPtr<FontFileDefinition> fileDef = System::MakeObject<FontFileDefinition>(u"ttf", System::MakeObject<FileSystemStreamSource>(u"C:\\Windows\\Fonts\\Montserrat.ttf"));
Parameter
fileExtension should match the standard, for the font format, extension. For example, if the font format is TrueType
, then the value of the
fileExtension parameter may be ttf
or ttc
(if the font file is a collection of TrueType
fonts).
If the font format is Embedded Open Type
, then the value of
fileExtension parameter should be eot
.
The table below shows the most often used in Aspose.Font for C++ font file formats. There they are with the matching values that the fileExtension parameter should take.
Font file Format | fileExtension |
---|---|
TrueType , single font | ttf |
TrueType font collection | ttc |
Web Open Font Format | woff |
Web Open Font Format version 2.0 | woff2 |
Embedded OpenType | eot |
Adobe Type 1 font | pfa , pfb , afm , pfm |
Compact Font Format | cff , can be null |
If font data starts not from the position 0 of the byte stream, use the following constructor with the offset parameter:
1 FontFileDefinition(System::String fileExtension, System::SharedPtr<Aspose::Font::Sources::StreamSource> streamSource, int64_t offset).
How to initiate FontDefinition object?
Now, when you’ve got an idea of the objects inherited from the StreamSource class and providing access to the font byte stream, and of the FontFileDefinition object, we will explain to you how to initiate FontDefiniton object with these objects properly for different situations.
FontDefiniton object provides you with many overloaded constructors. The common feature of all existing constructors is the FontType parameter. It describes the type of font format.
As it was mentioned before, apart from the FontType value, object FontDefiniton should be initialized with reference to the font binary data.
Next parameters of FontDefiniton constructors can be used in this case:
- fontName;
- fileExtension;
- object of the StreamSource type;
- object of the FontFileDefinition type.
You may have a question. Why would we pass the parameter fileExtension to the FontDefiniton or the FontFileDefinition object, when we always pass the parameter FontType which seems to coincide by its value with fileExtension?
The problem is that FontType does not always coincide with the value of fileExtension. FontType defines the common font format but not the font format of a specific file. Some fonts of one format can have different file formats.
For example, the value FontType.TTF defines TrueType
format. But at the same time TrueType
includes a few font formats and there are font files with extensions ttf
, eot
, ttc
, etc. in there. And if, for example, for the font of EOT
format we pass to
FontDefiniton only FontType.TTF value, then how will this object understand that the font belongs to EOT
format and not to TTF
?
In the same way, the value of FontType.Type1 is the common definition for fonts of this format. At the same time, Type1
format font files have extensions .pfa
, .pfb
, .afm
, .pfm
. So you cannot define font file format properly relying only on the FonType.Type1 value. Hence, to define font format correctly we need to specify the parameter
FontType with the value of the
fileExtension parameter.
Below you can learn examples of FontDefiniton object initialization and following font loading for different cases.
In all the cases the final font loading result is put into the variable of Aspose.Font.Font type. This type is the basic font class of Aspose.Font library and objects of this type provide common base functionality to work with fonts.
Loading the font into this object you will be able to render text with this font, get coding information, font metrics, etc.
Examples of how to load fonts
Let’s have as an example, loading font Montserrat
from the file C:\Windows\Fonts\Montserrat.ttf
Add the next namespaces at the head of the file:
1using Aspose::Font;
2using Aspose::Font::Sources;
3using System::IO;
You can load this font using FontDefiniton and FontFileDefinition objects in a few different ways:
Loading with the help of System::IO::FileInfo object
To fulfil loading do the next:
- Construct path to the file.
- Initiate
FontDefiniton object passing
TTF
as FontType value. - Get automatically calculated value fileExtension.
- Load the font.
1 // Construct path to the file
2 System::String fontPath = u"C:\\Windows\\Fonts\\Montserrat.ttf";
3
4 // Initialize FontDefinition object passing TTF as FontType value and using FontFileDefinition
5 System::SharedPtr<FontFileDefinition> fileDef = System::MakeObject<FontFileDefinition>(System::MakeObject<System::IO::FileInfo>(fontPath));
6
7 // Based on FileInfo object, fileExtension value is calculated automatically from FileInfo fields.
8 System::SharedPtr<FontDefinition> fontDef = System::MakeObject<FontDefinition>(Aspose::Font::FontType::TTF, fileDef);
9
10 // Load font
11 System::SharedPtr<Font> font = Font::Open(fontDef);
Loading with the help of FileSystemStreamSource type object
Take the next steps to fulfil the operation:
- Construct path to the file.
- Initiate FontDefiniton object.
- Set
fileExtension to
ttf
. - Load the font.
1 // Construct path to the file
2 System::String fontPath = u"C:\\Windows\\Fonts\\Montserrat.ttf";
3
4 // Initialize FontDefinition object passing TTF as FontType value and using FontFileDefinition
5 System::SharedPtr<FontFileDefinition> fileDef = System::MakeObject<FontFileDefinition>(u"ttf", System::MakeObject<FileSystemStreamSource>(fontPath));
6
7 // Based on FileSystemStreamSource object, set fileExtension to "ttf"
8 System::SharedPtr<FontDefinition> fontDef = System::MakeObject<FontDefinition>(Aspose::Font::FontType::TTF, fileDef);
9
10 // Load font
11 System::SharedPtr<Font> font = Font::Open(fontDef);
Font loading without FontFileDefinition object, with passing FileSystemStreamSource directly to FontDefinition
The next actions have to be taken for loading the font this way:
- Construct path to the file.
- Initiate
FontDefiniton object passing
TTF
as FontType value,ttf
as fileExtension value and FileSystemStreamSource object. Parameter fileExtension here is not a duplicate value for parameter FontType. - Load the font.
1 // Construct path to the file
2 System::String fontPath = u"C:\\Windows\\Fonts\\Montserrat.ttf";
3
4 // Initialize FontDefinition object passing TTF as FontType value, "ttf" as fileExtension value,
5 // and FileSystemStreamSource object. Parameter 'fileExtension' here is not duplicate value
6 // for parameter 'FontType' and it's needed for correct font format detection
7 System::SharedPtr<FontDefinition> fontDef = System::MakeObject<FontDefinition>(Aspose::Font::FontType::TTF, u"ttf", System::MakeObject<FileSystemStreamSource>(fontPath));
8
9 // Load font
10 System::SharedPtr<Font> font = Font::Open(fontDef);
Font loading with the byte[] type variable and with using ByteContentStreamSource type object
To load a font from the byte array you need to:
- Construct path to the file.
- Load font binary data into the byte array
- Initialize
FontDefiniton object passing
TTF
as FontType value,ttf
as fileExtension value, and ByteContentStreamSource object based on fontBytes array. - Load the font.
1 // Construct path to the file
2 System::String fontPath = u"C:\\Windows\\Fonts\\Montserrat.ttf";
3
4 // Load font binary data into byte array
5 System::ArrayPtr<uint8_t> fontBytes;
6
7 // Initialize FontDefinition object passing TTF as FontType value, "ttf" as fileExtension value,
8 // and ByteContentStreamSource object based on fontBytes array
9 System::SharedPtr<FontDefinition> fontDef = System::MakeObject<FontDefinition>(Aspose::Font::FontType::TTF, u"ttf", System::MakeObject<ByteContentStreamSource>(fontBytes));
10
11 // Load font
12 System::SharedPtr<Font> font = Font::Open(fontDef);
For getting more examples of using the Aspose.Font go to Aspose.Font.Examples.CPP.sln solution, in the cpp-examples of the Aspose.Font Documentation.
If you have any problems or questions left, you may post them at the Aspose.Font.Product Family section of the Free Support Forum and within a few hours our support team will clear everything up for you.