20#include "../../os/unix/font_unix.h"
28#include FT_TRUETYPE_TABLES_H
37 void SetFontSize(
int pixels);
44 GlyphID
MapCharToGlyph(
char32_t key,
bool allow_fallback =
true)
override;
45 std::string
GetFontName()
override {
return fmt::format(
"{}, {}",
face->family_name,
face->style_name); }
58 assert(
face !=
nullptr);
60 this->SetFontSize(pixels);
63void FreeTypeFontCache::SetFontSize(
int pixels)
67 int scaled_height =
ScaleGUITrad(FontCache::GetDefaultFontHeight(this->
fs));
68 pixels = scaled_height;
70 TT_Header *head = (TT_Header *)FT_Get_Sfnt_Table(this->
face, ft_sfnt_head);
71 if (head !=
nullptr) {
83 FT_Error err = FT_Set_Pixel_Sizes(this->
face, 0, pixels);
84 if (err != FT_Err_Ok) {
87 FT_Bitmap_Size *bs = this->
face->available_sizes;
88 int i = this->
face->num_fixed_sizes;
93 if (
abs(pixels - bs->height) >=
abs(pixels - n))
continue;
95 chosen = this->
face->num_fixed_sizes - i;
100 err = FT_Select_Size(this->
face, chosen);
104 if (err == FT_Err_Ok) {
105 this->
ascender = this->
face->size->metrics.ascender >> 6;
110 Debug(fontcache, 0,
"Font size selection failed. Using FontCache defaults.");
119 FT_Done_Face(this->
face);
120 this->
face =
nullptr;
130 if (this->
face !=
nullptr) this->SetFontSize(this->
req_size);
138 FT_GlyphSlot slot = this->
face->glyph;
140 FT_Load_Glyph(this->
face, key, aa ? FT_LOAD_TARGET_NORMAL : FT_LOAD_TARGET_MONO);
141 FT_Render_Glyph(this->
face->glyph, aa ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO);
144 aa = (slot->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY);
148 uint width = std::max(1U, (uint)slot->bitmap.width + shadow);
149 uint
height = std::max(1U, (uint)slot->bitmap.rows + shadow);
160 sprite.
width = width;
162 sprite.
x_offs = slot->bitmap_left;
167 for (uint y = 0; y < (uint)slot->bitmap.rows; y++) {
168 for (uint x = 0; x < (uint)slot->bitmap.width; x++) {
169 if (
HasBit(slot->bitmap.buffer[(x / 8) + y * slot->bitmap.pitch], 7 - (x % 8))) {
170 sprite.
data[shadow + x + (shadow + y) * sprite.
width].
m = SHADOW_COLOUR;
171 sprite.
data[shadow + x + (shadow + y) * sprite.
width].
a = 0xFF;
177 for (uint y = 0; y < (uint)slot->bitmap.rows; y++) {
178 for (uint x = 0; x < (uint)slot->bitmap.width; x++) {
179 if (aa ? (slot->bitmap.buffer[x + y * slot->bitmap.pitch] > 0) :
HasBit(slot->bitmap.buffer[(x / 8) + y * slot->bitmap.pitch], 7 - (x % 8))) {
180 sprite.
data[x + y * sprite.
width].
m = FACE_COLOUR;
181 sprite.
data[x + y * sprite.
width].
a = aa ? slot->bitmap.buffer[x + y * slot->bitmap.pitch] : 0xFF;
190 new_glyph.
data = std::move(allocator.data);
191 new_glyph.
width = slot->advance.x >> 6;
193 return this->SetGlyphPtr(key, std::move(new_glyph)).GetSprite();
199 assert(IsPrintable(key));
201 FT_UInt glyph = FT_Get_Char_Index(this->
face, key);
203 if (glyph == 0 && allow_fallback && key >= SCC_SPRITE_START && key <= SCC_SPRITE_END) {
204 return this->
parent->MapCharToGlyph(key);
210FT_Library _ft_library =
nullptr;
212class FreeTypeFontCacheFactory :
public FontCacheFactory {
214 FreeTypeFontCacheFactory() : FontCacheFactory(
"freetype",
"FreeType font provider") {}
219 FT_Done_FreeType(_ft_library);
220 _ft_library =
nullptr;
239 if (font.empty())
return nullptr;
241 if (_ft_library ==
nullptr) {
242 if (FT_Init_FreeType(&_ft_library) != FT_Err_Ok) {
243 ShowInfo(
"Unable to initialize FreeType, using sprite fonts instead");
247 Debug(fontcache, 2,
"Initialized");
250 FT_Face face =
nullptr;
254 if (
settings->os_handle !=
nullptr) index = *
static_cast<const int32_t *
>(
settings->os_handle);
255 FT_Error error = FT_New_Face(_ft_library, font.c_str(), index, &face);
257 if (error != FT_Err_Ok) {
260 if (!full_font.empty()) {
261 error = FT_New_Face(_ft_library, full_font.c_str(), 0, &face);
265#ifdef WITH_FONTCONFIG
270 if (error != FT_Err_Ok) {
280#ifdef WITH_FONTCONFIG
281 if (FontConfigFindFallbackFont(
settings, language_isocode, callback))
return true;
288 static std::unique_ptr<FontCache>
LoadFont(
FontSize fs, FT_Face face, std::string_view font_name, uint size)
290 Debug(fontcache, 2,
"Requested '{}', using '{} {}'", font_name, face->family_name, face->style_name);
293 FT_Error error = FT_Select_Charmap(face, ft_encoding_unicode);
294 if (error == FT_Err_Invalid_CharMap_Handle) {
298 FT_CharMap found = face->charmaps[0];
300 for (
int i = 0; i < face->num_charmaps; ++i) {
301 FT_CharMap charmap = face->charmaps[i];
302 if (charmap->platform_id == 0 && charmap->encoding_id == 0) {
307 if (found !=
nullptr) {
308 error = FT_Set_Charmap(face, found);
312 if (error != FT_Err_Ok) {
315 ShowInfo(
"Unable to use '{}' for {} font, FreeType reported error 0x{:X}, using sprite font instead", font_name, FontSizeToName(fs), error);
319 return std::make_unique<FreeTypeFontCache>(fs, face, size);
323 static FreeTypeFontCacheFactory instance;
constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
constexpr Timpl & Set()
Set all bits.
static Blitter * GetCurrentBlitter()
Get the current active blitter (always set by calling SelectBlitter).
int height
The height of the font.
std::unique_ptr< FontCache > parent
The parent of this font cache.
const FontSize fs
The size of the font.
int descender
The descender value of the font.
int ascender
The ascender value of the font.
bool FindFallbackFont(struct FontCacheSettings *settings, const std::string &language_isocode, class MissingGlyphSearcher *callback) const override
We would like to have a fallback font as the current one doesn't contain all characters we need.
std::unique_ptr< FontCache > LoadFont(FontSize fs, FontType fonttype) const override
Loads the freetype font.
~FreeTypeFontCacheFactory() override
Close the freetype library.
const void * GetOSHandle() override
Get the native OS font handle, if there is one.
FreeTypeFontCache(FontSize fs, FT_Face face, int pixels)
Create a new FreeTypeFontCache.
const Sprite * InternalGetGlyph(GlyphID key, bool aa) override
Load the glyph as a sprite.
void ClearFontCache() override
Reset cached glyphs.
GlyphID MapCharToGlyph(char32_t key, bool allow_fallback=true) override
Map a character into a glyph.
FT_Face face
The font face associated with this font.
std::string GetFontName() override
Get the name of this font.
~FreeTypeFontCache() override
Free everything that was allocated for this font cache.
bool IsBuiltInFont() override
Is this a built-in sprite font?
A searcher for missing glyphs.
virtual Sprite * Encode(SpriteType sprite_type, const SpriteLoader::SpriteCollection &sprite, SpriteAllocator &allocator)=0
Convert a sprite from the loader to our own format.
SpriteCollMap< Sprite > SpriteCollection
Type defining a collection of sprites, one for each zoom level.
static constexpr int MAX_GLYPH_DIM
Maximum glyph dimensions.
int used_size
Used font size.
int req_size
Requested font size.
void ClearFontCache() override
Reset cached glyphs.
static constexpr uint MAX_FONT_MIN_REC_SIZE
Upper limit for the recommended font size in case a font file contains nonsensical values.
TrueTypeFontCache(FontSize fs, int pixels)
Create a new TrueTypeFontCache.
SpriteAllocator that allocates memory via a unique_ptr array.
Control codes that are embedded in the translation strings.
Functions related to debugging.
#define Debug(category, level, format_string,...)
Output a line of debugging information.
Error reporting related functions.
Factory to 'query' all available blitters.
std::string FioFindFullPath(Subdirectory subdir, std::string_view filename)
Find a path to the filename in one of the search directories.
Functions for standard in/out file operations.
@ BASE_DIR
Base directory for all subdirectories.
fluid_settings_t * settings
FluidSynth settings handle.
FT_Error GetFontByFaceName(std::string_view font_name, FT_Face *face)
Load a freetype font face with the given font name.
uint GetFontCacheFontSize(FontSize fs)
Get the scalable font size to use for a FontSize.
std::string GetFontCacheFontName(FontSize fs)
Get font to use for a given font size.
Functions to read fonts from files and cache them.
FontType
Different types of font that can be loaded.
@ TrueType
Scalable TrueType fonts.
FontCacheSubSetting * GetFontCacheSubSetting(FontSize fs)
Get the settings of a given font size.
@ Font
A sprite used for fonts.
FontSize
Available font sizes.
@ FS_SMALL
Index of the small font in the font tables.
@ FS_NORMAL
Index of the normal font in the font tables.
constexpr T abs(const T a)
Returns the absolute value of (scalar) variable.
A number of safeguards to prevent using unsafe methods.
@ Palette
Sprite has palette data.
Definition of base types and functions in a cross-platform compatible way.
Settings for the four different fonts.
Settings for a single font.
Structure for passing information from the sprite loader to the blitter.
SpriteComponents colours
The colour components of the sprite with useful information.
void AllocateData(ZoomLevel zoom, size_t size)
Allocate the sprite data of this sprite.
uint16_t width
Width of the sprite.
int16_t x_offs
The x-offset of where the sprite will be drawn.
SpriteLoader::CommonPixel * data
The sprite itself.
uint16_t height
Height of the sprite.
int16_t y_offs
The y-offset of where the sprite will be drawn.
Data structure describing a sprite.
Container for information about a glyph.
std::unique_ptr< std::byte[]> data
The loaded sprite.
uint8_t width
The width of the glyph.
Common base definition for font file based font caches.
static const int MAX_FONT_SIZE
Maximum font size.
Functions related to zooming.