13#include "../fontcache.h"
14#include "../blitter/factory.hpp"
15#include "../zoom_func.h"
16#include "../fileio_func.h"
17#include "../error_func.h"
18#include "../../os/unix/font_unix.h"
21#include "../table/control_codes.h"
23#include "../safeguards.h"
29#include FT_TRUETYPE_TABLES_H
36 void SetFontSize(
int pixels);
37 const Sprite *InternalGetGlyph(
GlyphID key,
bool aa)
override;
44 std::string
GetFontName()
override {
return fmt::format(
"{}, {}",
face->family_name,
face->style_name); }
57 assert(
face !=
nullptr);
59 this->SetFontSize(pixels);
62void FreeTypeFontCache::SetFontSize(
int pixels)
66 int scaled_height =
ScaleGUITrad(FontCache::GetDefaultFontHeight(this->
fs));
67 pixels = scaled_height;
69 TT_Header *head = (TT_Header *)FT_Get_Sfnt_Table(this->
face, ft_sfnt_head);
70 if (head !=
nullptr) {
82 FT_Error err = FT_Set_Pixel_Sizes(this->
face, 0, pixels);
83 if (err != FT_Err_Ok) {
86 FT_Bitmap_Size *bs = this->
face->available_sizes;
87 int i = this->
face->num_fixed_sizes;
92 if (
abs(pixels - bs->height) >=
abs(pixels - n))
continue;
94 chosen = this->
face->num_fixed_sizes - i;
99 err = FT_Select_Size(this->
face, chosen);
103 if (err == FT_Err_Ok) {
104 this->
ascender = this->
face->size->metrics.ascender >> 6;
109 Debug(fontcache, 0,
"Font size selection failed. Using FontCache defaults.");
118 FT_Done_Face(this->
face);
119 this->
face =
nullptr;
129 if (this->
face !=
nullptr) this->SetFontSize(this->
req_size);
135const Sprite *FreeTypeFontCache::InternalGetGlyph(
GlyphID key,
bool aa)
137 FT_GlyphSlot slot = this->
face->glyph;
139 FT_Load_Glyph(this->
face, key, aa ? FT_LOAD_TARGET_NORMAL : FT_LOAD_TARGET_MONO);
140 FT_Render_Glyph(this->
face->glyph, aa ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO);
143 aa = (slot->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY);
147 uint width = std::max(1U, (uint)slot->bitmap.width + shadow);
148 uint
height = std::max(1U, (uint)slot->bitmap.rows + shadow);
159 sprite.
width = width;
161 sprite.
x_offs = slot->bitmap_left;
166 for (uint y = 0; y < (uint)slot->bitmap.rows; y++) {
167 for (uint x = 0; x < (uint)slot->bitmap.width; x++) {
168 if (
HasBit(slot->bitmap.buffer[(x / 8) + y * slot->bitmap.pitch], 7 - (x % 8))) {
169 sprite.
data[shadow + x + (shadow + y) * sprite.
width].
m = SHADOW_COLOUR;
170 sprite.
data[shadow + x + (shadow + y) * sprite.
width].
a = 0xFF;
176 for (uint y = 0; y < (uint)slot->bitmap.rows; y++) {
177 for (uint x = 0; x < (uint)slot->bitmap.width; x++) {
178 if (aa ? (slot->bitmap.buffer[x + y * slot->bitmap.pitch] > 0) :
HasBit(slot->bitmap.buffer[(x / 8) + y * slot->bitmap.pitch], 7 - (x % 8))) {
179 sprite.
data[x + y * sprite.
width].
m = FACE_COLOUR;
180 sprite.
data[x + y * sprite.
width].
a = aa ? slot->bitmap.buffer[x + y * slot->bitmap.pitch] : 0xFF;
188 GlyphEntry new_glyph;
189 new_glyph.
data = std::move(allocator.data);
190 new_glyph.width = slot->advance.x >> 6;
192 return this->SetGlyphPtr(key, std::move(new_glyph)).GetSprite();
198 assert(IsPrintable(key));
200 FT_UInt glyph = FT_Get_Char_Index(this->
face, key);
202 if (glyph == 0 && allow_fallback && key >= SCC_SPRITE_START && key <= SCC_SPRITE_END) {
203 return this->
parent->MapCharToGlyph(key);
209FT_Library _ft_library =
nullptr;
217 FT_Done_FreeType(_ft_library);
218 _ft_library =
nullptr;
235 if (font.empty())
return nullptr;
237 if (_ft_library ==
nullptr) {
238 if (FT_Init_FreeType(&_ft_library) != FT_Err_Ok) {
239 ShowInfo(
"Unable to initialize FreeType, using sprite fonts instead");
243 Debug(fontcache, 2,
"Initialized");
246 FT_Face face =
nullptr;
250 if (
settings->os_handle !=
nullptr) index = *
static_cast<const int32_t *
>(
settings->os_handle);
251 FT_Error error = FT_New_Face(_ft_library, font.c_str(), index, &face);
253 if (error != FT_Err_Ok) {
256 if (!full_font.empty()) {
257 error = FT_New_Face(_ft_library, full_font.c_str(), 0, &face);
261#ifdef WITH_FONTCONFIG
266 if (error != FT_Err_Ok) {
276#ifdef WITH_FONTCONFIG
277 if (FontConfigFindFallbackFont(
settings, language_isocode, callback))
return true;
284 static std::unique_ptr<FontCache>
LoadFont(
FontSize fs, FT_Face face, std::string_view font_name, uint size)
286 Debug(fontcache, 2,
"Requested '{}', using '{} {}'", font_name, face->family_name, face->style_name);
289 FT_Error error = FT_Select_Charmap(face, ft_encoding_unicode);
290 if (error == FT_Err_Invalid_CharMap_Handle) {
294 FT_CharMap found = face->charmaps[0];
296 for (
int i = 0; i < face->num_charmaps; ++i) {
297 FT_CharMap charmap = face->charmaps[i];
298 if (charmap->platform_id == 0 && charmap->encoding_id == 0) {
303 if (found !=
nullptr) {
304 error = FT_Set_Charmap(face, found);
308 if (error != FT_Err_Ok) {
311 ShowInfo(
"Unable to use '{}' for {} font, FreeType reported error 0x{:X}, using sprite font instead", font_name, FontSizeToName(fs), error);
315 return std::make_unique<FreeTypeFontCache>(fs, face, size);
debug_inline 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.
std::unique_ptr< FontCache > LoadFont(FontSize fs, FontType fonttype) override
Loads the freetype font.
Font cache for fonts that are based on a freetype font.
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.
~FreeTypeFontCache()
Free everything that was allocated for this font cache.
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.
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.
Font cache for fonts that are based on a TrueType font.
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.
SpriteAllocator that allocates memory via a unique_ptr array.
#define Debug(category, level, format_string,...)
Output a line of debugging information.
std::string FioFindFullPath(Subdirectory subdir, std::string_view filename)
Find a path to the filename in one of the search directories.
@ 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.
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.
uint32_t GlyphID
Glyphs are characters from a font.
@ 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.
@ Palette
Sprite has palette data.
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.
std::byte data[]
Sprite data.
Common base definition for font file based font caches.
static const int MAX_FONT_SIZE
Maximum font size.