10 #include "../stdafx.h"
12 #include "../fontcache.h"
13 #include "../fontdetection.h"
14 #include "../blitter/factory.hpp"
15 #include "../core/math_func.hpp"
16 #include "../zoom_func.h"
17 #include "../fileio_func.h"
18 #include "../error_func.h"
21 #include "../table/control_codes.h"
23 #include "../safeguards.h"
27 #include FT_FREETYPE_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); }
49 FT_Library _library =
nullptr;
60 assert(
face !=
nullptr);
62 this->SetFontSize(pixels);
65 void FreeTypeFontCache::SetFontSize(
int pixels)
69 int scaled_height =
ScaleGUITrad(FontCache::GetDefaultFontHeight(this->
fs));
70 pixels = scaled_height;
72 TT_Header *head = (TT_Header *)FT_Get_Sfnt_Table(this->
face, ft_sfnt_head);
73 if (head !=
nullptr) {
85 FT_Error err = FT_Set_Pixel_Sizes(this->
face, 0, pixels);
86 if (err != FT_Err_Ok) {
89 FT_Bitmap_Size *bs = this->
face->available_sizes;
90 int i = this->
face->num_fixed_sizes;
95 if (
abs(pixels - bs->height) >=
abs(pixels - n))
continue;
97 chosen = this->
face->num_fixed_sizes - i;
102 err = FT_Select_Size(this->
face, chosen);
106 if (err == FT_Err_Ok) {
107 this->
ascender = this->
face->size->metrics.ascender >> 6;
112 Debug(fontcache, 0,
"Font size selection failed. Using FontCache defaults.");
116 static FT_Error LoadFont(
FontSize fs, FT_Face face,
const char *font_name, uint size)
118 Debug(fontcache, 2,
"Requested '{}', using '{} {}'", font_name, face->family_name, face->style_name);
121 FT_Error error = FT_Select_Charmap(face, ft_encoding_unicode);
122 if (error == FT_Err_Ok)
goto found_face;
124 if (error == FT_Err_Invalid_CharMap_Handle) {
128 FT_CharMap found = face->charmaps[0];
131 for (i = 0; i < face->num_charmaps; i++) {
132 FT_CharMap charmap = face->charmaps[i];
133 if (charmap->platform_id == 0 && charmap->encoding_id == 0) {
138 if (found !=
nullptr) {
139 error = FT_Set_Charmap(face, found);
140 if (error == FT_Err_Ok)
goto found_face;
164 if (font.empty())
return;
166 if (_library ==
nullptr) {
167 if (FT_Init_FreeType(&_library) != FT_Err_Ok) {
168 ShowInfo(
"Unable to initialize FreeType, using sprite fonts instead");
172 Debug(fontcache, 2,
"Initialized");
175 const char *font_name = font.c_str();
176 FT_Face face =
nullptr;
180 if (
settings->os_handle !=
nullptr) index = *
static_cast<const int32_t *
>(
settings->os_handle);
181 FT_Error error = FT_New_Face(_library, font_name, index, &face);
183 if (error != FT_Err_Ok) {
186 if (!full_font.empty()) {
187 error = FT_New_Face(_library, full_font.c_str(), 0, &face);
194 if (error == FT_Err_Ok) {
196 if (error != FT_Err_Ok) {
197 ShowInfo(
"Unable to use '{}' for {} font, FreeType reported error 0x{:X}, using sprite font instead", font_name, FontSizeToName(fs), error);
209 FT_Done_Face(this->face);
210 this->face =
nullptr;
220 if (this->face !=
nullptr) this->SetFontSize(this->
req_size);
226 const Sprite *FreeTypeFontCache::InternalGetGlyph(
GlyphID key,
bool aa)
228 FT_GlyphSlot slot = this->face->glyph;
230 FT_Load_Glyph(this->face, key, aa ? FT_LOAD_TARGET_NORMAL : FT_LOAD_TARGET_MONO);
231 FT_Render_Glyph(this->face->glyph, aa ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO);
234 aa = (slot->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY);
238 uint width = std::max(1U, (uint)slot->bitmap.width + shadow);
239 uint
height = std::max(1U, (uint)slot->bitmap.rows + shadow);
250 sprite.
width = width;
252 sprite.
x_offs = slot->bitmap_left;
257 for (uint y = 0; y < (uint)slot->bitmap.rows; y++) {
258 for (uint x = 0; x < (uint)slot->bitmap.width; x++) {
259 if (
HasBit(slot->bitmap.buffer[(x / 8) + y * slot->bitmap.pitch], 7 - (x % 8))) {
260 sprite.
data[shadow + x + (shadow + y) * sprite.
width].
m = SHADOW_COLOUR;
261 sprite.
data[shadow + x + (shadow + y) * sprite.
width].
a = 0xFF;
267 for (uint y = 0; y < (uint)slot->bitmap.rows; y++) {
268 for (uint x = 0; x < (uint)slot->bitmap.width; x++) {
269 if (aa ? (slot->bitmap.buffer[x + y * slot->bitmap.pitch] > 0) :
HasBit(slot->bitmap.buffer[(x / 8) + y * slot->bitmap.pitch], 7 - (x % 8))) {
270 sprite.
data[x + y * sprite.
width].
m = FACE_COLOUR;
271 sprite.
data[x + y * sprite.
width].
a = aa ? slot->bitmap.buffer[x + y * slot->bitmap.pitch] : 0xFF;
279 GlyphEntry new_glyph;
280 new_glyph.
data = std::move(allocator.data);
281 new_glyph.width = slot->advance.x >> 6;
283 return this->SetGlyphPtr(key, std::move(new_glyph)).GetSprite();
289 assert(IsPrintable(key));
291 FT_UInt glyph = FT_Get_Char_Index(this->face, key);
293 if (glyph == 0 && allow_fallback && key >= SCC_SPRITE_START && key <= SCC_SPRITE_END) {
305 FT_Done_FreeType(_library);
309 #if !defined(WITH_FONTCONFIG)
311 FT_Error
GetFontByFaceName(
const char *font_name, FT_Face *face) {
return FT_Err_Cannot_Open_Resource; }
constexpr debug_inline bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
static Blitter * GetCurrentBlitter()
Get the current active blitter (always set by calling SelectBlitter).
int height
The height of the font.
FontCache * parent
The parent of this font cache.
virtual GlyphID MapCharToGlyph(char32_t key, bool fallback=true)=0
Map a character into a glyph.
const FontSize fs
The size of the font.
int descender
The descender value of the font.
int ascender
The ascender value of the font.
Font cache for fonts that are based on a freetype font.
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.
const void * GetOSHandle() override
Get the native OS font handle, if there is one.
bool IsBuiltInFont() override
Is this a built-in sprite font?
virtual Sprite * Encode(const SpriteLoader::SpriteCollection &sprite, SpriteAllocator &allocator)=0
Convert a sprite from the loader to our own format.
std::array< Sprite, ZOOM_LVL_END > SpriteCollection
Type defining a collection of sprites, one for each zoom level.
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,...)
Ouptut a line of debugging information.
std::string FioFindFullPath(Subdirectory subdir, const std::string &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.
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.
FontCacheSubSetting * GetFontCacheSubSetting(FontSize fs)
Get the settings of a given font size.
uint32_t GlyphID
Glyphs are characters from a font.
FT_Error GetFontByFaceName(const char *font_name, FT_Face *face)
Load a freetype font face with the given font name.
void UninitFreeType()
Free everything allocated w.r.t.
void LoadFreeTypeFont(FontSize fs)
Loads the freetype 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.
@ SCC_ALPHA
Sprite has alpha.
@ SCC_PAL
Sprite has palette data.
Settings for a single font.
Structure for passing information from the sprite loader to the blitter.
void AllocateData(ZoomLevel zoom, size_t size)
Allocate the sprite data of this sprite.
SpriteColourComponent colours
The colour components of the sprite with useful information.
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.
SpriteType type
The sprite type.
int16_t y_offs
The y-offset of where the sprite will be drawn.
Data structure describing a sprite.
uint8_t data[]
Sprite data.
Common base definition for font file based font caches.
static const int MAX_FONT_SIZE
Maximum font size.
int ScaleGUITrad(int value)
Scale traditional pixel dimensions to GUI zoom level.
@ ZOOM_LVL_MIN
Minimum zoom level.