Adding setVariationAxis for variable fonts (#158)

This commit is contained in:
themancalledjakob 2022-09-09 09:05:02 +02:00 committed by GitHub
parent 3300ab6869
commit 4aba809e94
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 66 additions and 0 deletions

View File

@ -6,17 +6,22 @@
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_OUTLINE_H
#include FT_MULTIPLE_MASTERS_H
namespace msdfgen {
#define REQUIRE(cond) { if (!(cond)) return false; }
#define F26DOT6_TO_DOUBLE(x) (1/64.*double(x))
#define DOUBLE_TO_F16DOT16(x) (FT_Fixed(x*65536.))
#define F16DOT16_TO_DOUBLE(x) (1/65536.*double(x))
class FreetypeHandle {
friend FreetypeHandle * initializeFreetype();
friend void deinitializeFreetype(FreetypeHandle *library);
friend FontHandle * loadFont(FreetypeHandle *library, const char *filename);
friend FontHandle * loadFontData(FreetypeHandle *library, const byte *data, int length);
friend bool setVariationAxis(FontHandle *font, FreetypeHandle *library, const char *axisname, double coordinate);
friend bool getVariationAxes(std::vector<FontVariationAxis> &axes, FontHandle *font, FreetypeHandle *library);
FT_Library library;
@ -34,6 +39,8 @@ class FontHandle {
friend bool loadGlyph(Shape &output, FontHandle *font, unicode_t unicode, double *advance);
friend bool getKerning(double &output, FontHandle *font, GlyphIndex glyphIndex1, GlyphIndex glyphIndex2);
friend bool getKerning(double &output, FontHandle *font, unicode_t unicode1, unicode_t unicode2);
friend bool setVariationAxis(FontHandle *font, FreetypeHandle *library, const char *axisname, double coordinate);
friend bool getVariationAxes(std::vector<FontVariationAxis> &axes, FontHandle *font, FreetypeHandle *library);
FT_Face face;
bool ownership;
@ -215,4 +222,48 @@ bool getKerning(double &output, FontHandle *font, unicode_t unicode1, unicode_t
return getKerning(output, font, GlyphIndex(FT_Get_Char_Index(font->face, unicode1)), GlyphIndex(FT_Get_Char_Index(font->face, unicode2)));
}
bool setVariationAxis(FontHandle *font, FreetypeHandle *library, const char *name, double coordinate) {
bool success = false;
if (font->face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS) {
FT_MM_Var *amaster;
FT_Get_MM_Var(font->face, &amaster);
std::vector<FT_Fixed> coords;
coords.resize(amaster->num_axis);
FT_Get_Var_Design_Coordinates(font->face, coords.size(), coords.data());
for (FT_UInt i = 0; i < amaster->num_axis; i++) {
int strdiff = strcmp(name,amaster->axis[i].name);
if (strdiff == 0) {
coords[i] = DOUBLE_TO_F16DOT16(coordinate);
success = true;
break;
}
}
FT_Set_Var_Design_Coordinates(font->face, coords.size(), coords.data());
FT_Done_MM_Var(library->library, amaster);
}
return success;
}
bool getVariationAxes(std::vector<FontVariationAxis> &axes, FontHandle *font, FreetypeHandle *library) {
if (font->face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS) {
FT_MM_Var *amaster;
FT_Get_MM_Var(font->face, &amaster);
for (FT_UInt i = 0; i < amaster->num_axis; i++) {
FontVariationAxis axis{
amaster->axis[i].name,
F16DOT16_TO_DOUBLE(amaster->axis[i].minimum),
F16DOT16_TO_DOUBLE(amaster->axis[i].def),
F16DOT16_TO_DOUBLE(amaster->axis[i].maximum)
};
axes.push_back(axis);
}
FT_Done_MM_Var(library->library, amaster);
return true;
}
return false;
}
}

View File

@ -35,6 +35,18 @@ struct FontMetrics {
double underlineY, underlineThickness;
};
/// A structure to model a given axis for variation fonts.
struct FontVariationAxis {
/// The name of the variation axis.
const char * name;
/// The axis's minimum design coordinate.
double minimum;
/// The axis's default design coordinate. FreeType computes meaningful default values for Adobe MM fonts.
double def;
/// The axis's maximum design coordinate.
double maximum;
};
/// Initializes the FreeType library.
FreetypeHandle * initializeFreetype();
/// Deinitializes the FreeType library.
@ -62,5 +74,8 @@ bool loadGlyph(Shape &output, FontHandle *font, unicode_t unicode, double *advan
/// Outputs the kerning distance adjustment between two specific glyphs.
bool getKerning(double &output, FontHandle *font, GlyphIndex glyphIndex1, GlyphIndex glyphIndex2);
bool getKerning(double &output, FontHandle *font, unicode_t unicode1, unicode_t unicode2);
/// Sets variation axis of variable font.
bool setVariationAxis(FontHandle *font, FreetypeHandle *library, const char *name, double coordinate);
bool getVariationAxes(std::vector<FontVariationAxis> &axes, FontHandle *font, FreetypeHandle *library);
}