DarkPlaces
Game engine based on the Quake 1 engine by id Software, developed by LadyHavoc
 
ft2.c File Reference
#include "quakedef.h"
#include "ft2.h"
#include "ft2_defs.h"
#include "ft2_fontdefs.h"
#include "image.h"
+ Include dependency graph for ft2.c:

Go to the source code of this file.

Data Structures

struct  font_postprocess_t
 
struct  fontfilecache_t
 

Macros

#define bytes_per_pixel   4
 
#define bytes_per_pixel   4
 
#define calc_data_arguments(w, h)
 
#define fix_glyph_coords_tier1(glyph, order)
 
#define fix_glyph_coords_tier2(glyph, order)
 
#define M   FONT_CHARS_PER_LINE
 
#define MAX_FONTFILES   8
 
#define N   FONT_CHAR_LINES
 
#define POSTPROCESS_MAXRADIUS   8
 

Functions

static void alert_legacy_font_api (const char *name)
 
ft2_font_tFont_Alloc (void)
 
static qbool Font_Attach (ft2_font_t *font, ft2_attachment_t *attachment)
 
void Font_CloseLibrary (void)
 
qbool Font_GetKerningForMap (ft2_font_t *font, int map_index, float w, float h, Uchar left, Uchar right, float *outx, float *outy)
 
qbool Font_GetKerningForSize (ft2_font_t *font, float w, float h, Uchar left, Uchar right, float *outx, float *outy)
 
qbool Font_GetMapForChar (ft2_font_t *font, int map_index, Uchar ch, ft2_font_map_t **outmap, int *outmapch)
 Query for or load a font map for a character, with the character's place on it.
 
int Font_IndexForSize (ft2_font_t *font, float _fsize, float *outw, float *outh)
 
void Font_Init (void)
 
static qbool Font_LoadFile (const char *name, int _face, ft2_settings_t *settings, ft2_font_t *font)
 
qbool Font_LoadFont (const char *name, dp_font_t *dpfnt)
 
static qbool Font_LoadMap (ft2_font_t *font, ft2_font_map_t *mapstart, Uchar _ch, ft2_font_map_t **outmap, int *outmapch, qbool incmap_ok)
 
qbool Font_LoadMapForIndex (ft2_font_t *font, int map_index, Uchar ch, ft2_font_map_t **outmap)
 
static qbool Font_LoadSize (ft2_font_t *font, float size, qbool check_only)
 
ft2_font_map_t * Font_MapForIndex (ft2_font_t *font, int index)
 
void font_newmap (void)
 
qbool Font_OpenLibrary (void)
 
static void Font_Postprocess (ft2_font_t *fnt, unsigned char *imagedata, int pitch, int bpp, int w, int h, int *pad_l, int *pad_r, int *pad_t, int *pad_b)
 
static void Font_Postprocess_Update (ft2_font_t *fnt, int bpp, int w, int h)
 
static float Font_SearchSize (ft2_font_t *font, FT_Face fontface, float size)
 
static qbool Font_SetSize (ft2_font_t *font, float w, float h)
 
void font_shutdown (void)
 
float Font_SnapTo (float val, float snapwidth)
 
void font_start (void)
 
void Font_UnloadFont (ft2_font_t *font)
 
float Font_VirtualToRealSize (float sz)
 
static void fontfilecache_Free (const unsigned char *buf)
 
static void fontfilecache_FreeAll (void)
 
static const unsigned char * fontfilecache_LoadFile (const char *path, qbool quiet, fs_offset_t *filesizepointer)
 
ft2_font_map_t * FontMap_FindForChar (ft2_font_map_t *start, Uchar ch)
 
static qbool get_char_from_incmap (ft2_font_map_t *map, Uchar ch, ft2_font_map_t **outmap, int *outmapch)
 
static void incmap_post_process (font_incmap_t *incmap, Uchar ch, unsigned char *data, ft2_font_map_t **outmap, int *outmapch)
 
static void merge_single_map (ft2_font_map_t *targetmap, int targetindex, ft2_font_map_t *sourcemap, int sourceindex)
 
static qbool should_use_incmap (Uchar ch)
 
static void transform_glyph_coords (glyph_slot_t *glyph, float shiftx, float shifty, float scalex, float scaley)
 
static void UnloadMapChain (ft2_font_map_t *map)
 
static void update_pic_for_fontmap (ft2_font_map_t *fontmap, const char *identifier, int width, int height, unsigned char *data)
 

Variables

cvar_t developer_font = {CF_CLIENT | CF_ARCHIVE, "developer_font", "0", "prints debug messages about fonts"}
 
static FT_Library font_ft2lib = NULL
 FreeType library handle.
 
static mempool_tfont_mempool = NULL
 Memory pool for fonts.
 
static fontfilecache_t fontfiles [MAX_FONTFILES]
 
static dllhandle_t ft2_dll = NULL
 Handle for FreeType2 DLL.
 
static dllfunction_t ft2funcs []
 
static int img_fontmap [256]
 
static qbool legacy_font_loading_api_alerted = false
 
static font_postprocess_t pp
 
(* qFT_Attach_Stream )(FT_Face face, FT_Open_Args *parameters)
 
(* qFT_Done_Face )(FT_Face face)
 
(* qFT_Done_FreeType )(FT_Library library)
 
(* qFT_Get_Char_Index )(FT_Face face, FT_ULong charcode)
 
(* qFT_Get_Kerning )(FT_Face face, FT_UInt left_glyph, FT_UInt right_glyph, FT_UInt kern_mode, FT_Vector *akerning)
 
(* qFT_Init_FreeType )(FT_Library *alibrary)
 
(* qFT_Load_Char )(FT_Face face, FT_ULong char_code, FT_Int32 load_flags)
 
(* qFT_Load_Glyph )(FT_Face face, FT_UInt glyph_index, FT_Int32 load_flags)
 
(* qFT_New_Memory_Face )(FT_Library library, const FT_Byte *file_base, FT_Long file_size, FT_Long face_index, FT_Face *aface)
 
(* qFT_Render_Glyph )(FT_GlyphSlot slot, FT_Render_Mode render_mode)
 
(* qFT_Request_Size )(FT_Face face, FT_Size_Request req)
 
(* qFT_Select_Size )(FT_Face face, FT_Int strike_index)
 
(* qFT_Set_Char_Size )(FT_Face face, FT_F26Dot6 char_width, FT_F26Dot6 char_height, FT_UInt horz_resolution, FT_UInt vert_resolution)
 
(* qFT_Set_Pixel_Sizes )(FT_Face face, FT_UInt pixel_width, FT_UInt pixel_height)
 
cvar_t r_font_compress = {CF_CLIENT | CF_ARCHIVE, "r_font_compress", "0", "use texture compression on font textures to save video memory"}
 
cvar_t r_font_disable_freetype = {CF_CLIENT | CF_ARCHIVE, "r_font_disable_freetype", "0", "disable freetype support for fonts entirely"}
 
cvar_t r_font_disable_incmaps = {CF_CLIENT | CF_ARCHIVE, "r_font_disable_incmaps", "0", "always to load a full glyph map for individual unmapped character, even when it will mean extreme resources waste"}
 
cvar_t r_font_diskcache = {CF_CLIENT | CF_ARCHIVE, "r_font_diskcache", "0", "[deprecated, not effective] save font textures to disk for future loading rather than generating them every time"}
 
cvar_t r_font_kerning = {CF_CLIENT | CF_ARCHIVE, "r_font_kerning", "1", "Use kerning if available"}
 
cvar_t r_font_nonpoweroftwo = {CF_CLIENT | CF_ARCHIVE, "r_font_nonpoweroftwo", "1", "use nonpoweroftwo textures for font (saves memory, potentially slower)"}
 
cvar_t r_font_size_snapping = {CF_CLIENT | CF_ARCHIVE, "r_font_size_snapping", "1", "stick to good looking font sizes whenever possible - bad when the mod doesn't support it!"}
 
static const Uchar unicode_bigblocks []
 

Macro Definition Documentation

◆ bytes_per_pixel [1/2]

#define bytes_per_pixel   4

Referenced by Font_LoadMap().

◆ bytes_per_pixel [2/2]

#define bytes_per_pixel   4

◆ calc_data_arguments

#define calc_data_arguments ( w,
h )
Value:
width = startmap->glyphSize * w; \
height = startmap->glyphSize * h; \
pitch = width * bytes_per_pixel; \
datasize = height * pitch;
#define bytes_per_pixel
GLenum GLsizei width
Definition glquake.h:622
GLenum GLsizei GLsizei height
Definition glquake.h:622
GLubyte GLubyte GLubyte GLubyte w
Definition glquake.h:782

Definition at line 1276 of file ft2.c.

1276#define calc_data_arguments(w, h) \
1277 width = startmap->glyphSize * w; \
1278 height = startmap->glyphSize * h; \
1279 pitch = width * bytes_per_pixel; \
1280 datasize = height * pitch;

Referenced by incmap_post_process().

◆ fix_glyph_coords_tier1

#define fix_glyph_coords_tier1 ( glyph,
order )
Value:
transform_glyph_coords(glyph, order / (float)FONT_CHARS_PER_LINE, 0.0f, 1.0f / (float)FONT_CHARS_PER_LINE, 1.0f)
static void transform_glyph_coords(glyph_slot_t *glyph, float shiftx, float shifty, float scalex, float scaley)
Definition ft2.c:1259
#define FONT_CHARS_PER_LINE
Definition ft2_fontdefs.h:6

Definition at line 1266 of file ft2.c.

Referenced by incmap_post_process().

◆ fix_glyph_coords_tier2

#define fix_glyph_coords_tier2 ( glyph,
order )
Value:
transform_glyph_coords(glyph, 0.0f, order / (float)FONT_CHARS_PER_LINE, 1.0f, 1.0f / (float)FONT_CHARS_PER_LINE)

Definition at line 1267 of file ft2.c.

Referenced by incmap_post_process().

◆ M

◆ MAX_FONTFILES

#define MAX_FONTFILES   8

Definition at line 267 of file ft2.c.

Referenced by fontfilecache_Free(), fontfilecache_FreeAll(), and fontfilecache_LoadFile().

◆ N

#define N   FONT_CHAR_LINES

Referenced by incmap_post_process().

◆ POSTPROCESS_MAXRADIUS

#define POSTPROCESS_MAXRADIUS   8

Definition at line 246 of file ft2.c.

Referenced by Font_Postprocess(), and Font_Postprocess_Update().

Function Documentation

◆ alert_legacy_font_api()

static void alert_legacy_font_api ( const char * name)
inlinestatic

Definition at line 1889 of file ft2.c.

1890{
1892 {
1893 Con_DPrintf(CON_WARN "Warning: You are using an legacy API '%s', which have certain limitations; please use 'Font_GetMapForChar' instead\n", name);
1895 }
1896}
void Con_DPrintf(const char *fmt,...)
A Con_Printf that only shows up if the "developer" cvar is set.
Definition console.c:1544
#define CON_WARN
Definition console.h:101
static qbool legacy_font_loading_api_alerted
Definition ft2.c:1888
const GLchar * name
Definition glquake.h:601

References Con_DPrintf(), CON_WARN, legacy_font_loading_api_alerted, and name.

Referenced by Font_LoadMapForIndex(), and FontMap_FindForChar().

◆ Font_Alloc()

ft2_font_t * Font_Alloc ( void )

Definition at line 467 of file ft2.c.

468{
469#ifndef DP_FREETYPE_STATIC
470 if (!ft2_dll)
471#else
473#endif
474 return NULL;
475 return (ft2_font_t *)Mem_Alloc(font_mempool, sizeof(ft2_font_t));
476}
cvar_t r_font_disable_freetype
Definition ft2.c:55
static mempool_t * font_mempool
Memory pool for fonts.
Definition ft2.c:241
static dllhandle_t ft2_dll
Handle for FreeType2 DLL.
Definition ft2.c:159
#define NULL
Definition qtypes.h:12
int integer
Definition cvar.h:73
#define Mem_Alloc(pool, size)
Definition zone.h:92

References font_mempool, ft2_dll, cvar_t::integer, Mem_Alloc, NULL, and r_font_disable_freetype.

Referenced by Font_LoadFont().

◆ Font_Attach()

static qbool Font_Attach ( ft2_font_t * font,
ft2_attachment_t * attachment )
static

Definition at line 478 of file ft2.c.

479{
480 ft2_attachment_t *na;
481
482 font->attachmentcount++;
483 na = (ft2_attachment_t*)Mem_Alloc(font_mempool, sizeof(font->attachments[0]) * font->attachmentcount);
484 if (na == NULL)
485 return false;
486 if (font->attachments && font->attachmentcount > 1)
487 {
488 memcpy(na, font->attachments, sizeof(font->attachments[0]) * (font->attachmentcount - 1));
489 Mem_Free(font->attachments);
490 }
491 memcpy(na + sizeof(font->attachments[0]) * (font->attachmentcount - 1), attachment, sizeof(*attachment));
492 font->attachments = na;
493 return true;
494}
GLenum attachment
Definition glquake.h:612
size_t attachmentcount
Definition ft2.h:61
ft2_attachment_t * attachments
Definition ft2.h:62
#define Mem_Free(mem)
Definition zone.h:96

References attachment, ft2_font_t::attachmentcount, ft2_font_t::attachments, font_mempool, Mem_Alloc, Mem_Free, and NULL.

Referenced by Font_LoadFile().

◆ Font_CloseLibrary()

void Font_CloseLibrary ( void )

Definition at line 339 of file ft2.c.

340{
342 if (font_mempool)
345 {
348 }
349#ifndef DP_FREETYPE_STATIC
351#endif
352 pp.buf = NULL;
353}
(* qFT_Done_FreeType)(FT_Library library)
Definition ft2.c:77
static FT_Library font_ft2lib
FreeType library handle.
Definition ft2.c:244
static void fontfilecache_FreeAll(void)
Definition ft2.c:320
static font_postprocess_t pp
Definition ft2.c:257
unsigned char * buf
Definition ft2.c:249
void Sys_FreeLibrary(dllhandle_t *handle)
Definition sys_shared.c:245
#define Mem_FreePool(pool)
Definition zone.h:105

References font_postprocess_t::buf, font_ft2lib, font_mempool, fontfilecache_FreeAll(), ft2_dll, Mem_FreePool, NULL, pp, qFT_Done_FreeType, and Sys_FreeLibrary().

Referenced by font_shutdown(), and font_start().

◆ Font_GetKerningForMap()

qbool Font_GetKerningForMap ( ft2_font_t * font,
int map_index,
float w,
float h,
Uchar left,
Uchar right,
float * outx,
float * outy )

Definition at line 1085 of file ft2.c.

1086{
1087 ft2_font_map_t *fmap;
1088 if (!font->has_kerning || !r_font_kerning.integer)
1089 return false;
1090 if (map_index < 0 || map_index >= MAX_FONT_SIZES)
1091 return false;
1092 fmap = font->font_maps[map_index];
1093 if (!fmap)
1094 return false;
1095 if (left < 256 && right < 256)
1096 {
1097 //Con_Printf("%g : %f, %f, %f :: %f\n", (w / (float)fmap->size), w, fmap->size, fmap->intSize, Font_VirtualToRealSize(w));
1098 // quick-kerning, be aware of the size: scale it
1099 if (outx) *outx = fmap->kerning->kerning[left][right][0];// * (w / (float)fmap->size);
1100 if (outy) *outy = fmap->kerning->kerning[left][right][1];// * (h / (float)fmap->size);
1101 return true;
1102 }
1103 else
1104 {
1105 FT_Vector kernvec;
1106 FT_ULong ul, ur;
1107
1108 //if (qFT_Set_Pixel_Sizes((FT_Face)font->face, 0, fmap->size))
1109#if 0
1110 if (!Font_SetSize(font, w, h))
1111 {
1112 // this deserves an error message
1113 Con_Printf("Failed to get kerning for %s\n", font->name);
1114 return false;
1115 }
1116 ul = qFT_Get_Char_Index(font->face, left);
1117 ur = qFT_Get_Char_Index(font->face, right);
1118 if (qFT_Get_Kerning(font->face, ul, ur, FT_KERNING_DEFAULT, &kernvec))
1119 {
1120 if (outx) *outx = Font_SnapTo(kernvec.x * fmap->sfx, 1 / fmap->size);
1121 if (outy) *outy = Font_SnapTo(kernvec.y * fmap->sfy, 1 / fmap->size);
1122 return true;
1123 }
1124#endif
1125 if (!Font_SetSize(font, fmap->intSize, fmap->intSize))
1126 {
1127 // this deserves an error message
1128 Con_Printf(CON_ERROR "Failed to get kerning for %s\n", font->name);
1129 return false;
1130 }
1131 ul = qFT_Get_Char_Index((FT_Face)font->face, left);
1132 ur = qFT_Get_Char_Index((FT_Face)font->face, right);
1133 if (qFT_Get_Kerning((FT_Face)font->face, ul, ur, FT_KERNING_DEFAULT, &kernvec))
1134 {
1135 if (outx) *outx = Font_SnapTo(kernvec.x * fmap->sfx, 1 / fmap->size);// * (w / (float)fmap->size);
1136 if (outy) *outy = Font_SnapTo(kernvec.y * fmap->sfy, 1 / fmap->size);// * (h / (float)fmap->size);
1137 return true;
1138 }
1139 return false;
1140 }
1141}
void Con_Printf(const char *fmt,...)
Prints to all appropriate console targets.
Definition console.c:1514
#define CON_ERROR
Definition console.h:102
#define MAX_FONT_SIZES
Definition draw.h:94
(* qFT_Get_Char_Index)(FT_Face face, FT_ULong charcode)
Definition ft2.c:118
float Font_SnapTo(float val, float snapwidth)
Definition ft2.c:514
static qbool Font_SetSize(ft2_font_t *font, float w, float h)
Definition ft2.c:1059
cvar_t r_font_kerning
Definition ft2.c:57
(* qFT_Get_Kerning)(FT_Face face, FT_UInt left_glyph, FT_UInt right_glyph, FT_UInt kern_mode, FT_Vector *akerning)
Definition ft2.c:124
unsigned long FT_ULong
Definition ft2_defs.h:28
@ FT_KERNING_DEFAULT
Definition ft2_defs.h:495
struct FT_FaceRec_ * FT_Face
Definition ft2_defs.h:36
FT_Pos x
Definition ft2_defs.h:48
FT_Pos y
Definition ft2_defs.h:49
ft2_font_map_t * font_maps[MAX_FONT_SIZES]
Definition ft2.h:57
void * face
Definition ft2.h:54
char name[64]
Definition ft2.h:41
qbool has_kerning
Definition ft2.h:42
static vec3_t right
Definition sv_user.c:305

References CON_ERROR, Con_Printf(), ft2_font_t::face, ft2_font_t::font_maps, Font_SetSize(), Font_SnapTo(), FT_KERNING_DEFAULT, ft2_font_t::has_kerning, cvar_t::integer, MAX_FONT_SIZES, ft2_font_t::name, qFT_Get_Char_Index, qFT_Get_Kerning, r_font_kerning, right, w, FT_Vector::x, and FT_Vector::y.

Referenced by DrawQ_String_Scale(), DrawQ_TextWidth_UntilWidth_TrackColors_Scale(), and Font_GetKerningForSize().

◆ Font_GetKerningForSize()

qbool Font_GetKerningForSize ( ft2_font_t * font,
float w,
float h,
Uchar left,
Uchar right,
float * outx,
float * outy )

Definition at line 1143 of file ft2.c.

1144{
1145 return Font_GetKerningForMap(font, Font_IndexForSize(font, h, NULL, NULL), w, h, left, right, outx, outy);
1146}
qbool Font_GetKerningForMap(ft2_font_t *font, int map_index, float w, float h, Uchar left, Uchar right, float *outx, float *outy)
Definition ft2.c:1085
int Font_IndexForSize(ft2_font_t *font, float _fsize, float *outw, float *outh)
Definition ft2.c:999

References Font_GetKerningForMap(), Font_IndexForSize(), NULL, right, and w.

◆ Font_GetMapForChar()

qbool Font_GetMapForChar ( ft2_font_t * font,
int map_index,
Uchar ch,
ft2_font_map_t ** outmap,
int * outmapch )

Query for or load a font map for a character, with the character's place on it.

Supports the incremental map mechanism; returning if the operation is done successfully

Definition at line 1971 of file ft2.c.

1972{
1973 qbool use_incmap;
1974 ft2_font_map_t *map;
1975
1976 // startmap
1977 map = Font_MapForIndex(font, map_index);
1978
1979 // optimize: the first map must have been loaded already
1980 if (ch < FONT_CHARS_PER_MAP)
1981 {
1982 *outmapch = ch;
1983 *outmap = map;
1984 return true;
1985 }
1986
1987 // search for the character
1988
1989 use_incmap = should_use_incmap(ch);
1990
1991 if (!use_incmap)
1992 {
1993 // normal way
1994 *outmapch = ch % FONT_CHARS_PER_MAP;
1995 while (map && map->start + FONT_CHARS_PER_MAP <= ch)
1996 map = map->next;
1997 if (map && map->start <= ch)
1998 {
1999 *outmap = map;
2000 return true;
2001 }
2002 }
2003 else if (get_char_from_incmap(map, ch, outmap, outmapch))
2004 // got it
2005 return true;
2006
2007 // so no appropriate map was found, load one
2008
2009 if (map_index < 0 || map_index >= MAX_FONT_SIZES)
2010 return false;
2011 return Font_LoadMap(font, font->font_maps[map_index], ch, outmap, outmapch, use_incmap);
2012}
ft2_font_map_t * Font_MapForIndex(ft2_font_t *font, int index)
Definition ft2.c:1052
static qbool Font_LoadMap(ft2_font_t *font, ft2_font_map_t *mapstart, Uchar _ch, ft2_font_map_t **outmap, int *outmapch, qbool incmap_ok)
Definition ft2.c:1385
static qbool get_char_from_incmap(ft2_font_map_t *map, Uchar ch, ft2_font_map_t **outmap, int *outmapch)
Definition ft2.c:1936
static qbool should_use_incmap(Uchar ch)
Definition ft2.c:1922
#define FONT_CHARS_PER_MAP
Definition ft2_fontdefs.h:8
bool qbool
Definition qtypes.h:9

References FONT_CHARS_PER_MAP, Font_LoadMap(), Font_MapForIndex(), ft2_font_t::font_maps, get_char_from_incmap(), MAX_FONT_SIZES, and should_use_incmap().

Referenced by DrawQ_String_Scale(), and DrawQ_TextWidth_UntilWidth_TrackColors_Scale().

◆ Font_IndexForSize()

int Font_IndexForSize ( ft2_font_t * font,
float _fsize,
float * outw,
float * outh )

Definition at line 999 of file ft2.c.

1000{
1001 int match = -1;
1002 float value = 1000000;
1003 float nval;
1004 int matchsize = -10000;
1005 int m;
1006 float fsize_x, fsize_y;
1007 ft2_font_map_t **maps = font->font_maps;
1008
1009 fsize_x = fsize_y = _fsize * vid.mode.height / vid_conheight.value;
1010 if(outw && *outw)
1011 fsize_x = *outw * vid.mode.width / vid_conwidth.value;
1012 if(outh && *outh)
1013 fsize_y = *outh * vid.mode.height / vid_conheight.value;
1014
1015 if (fsize_x < 0)
1016 {
1017 if(fsize_y < 0)
1018 fsize_x = fsize_y = 16;
1019 else
1020 fsize_x = fsize_y;
1021 }
1022 else
1023 {
1024 if(fsize_y < 0)
1025 fsize_y = fsize_x;
1026 }
1027
1028 for (m = 0; m < MAX_FONT_SIZES; ++m)
1029 {
1030 if (!maps[m])
1031 continue;
1032 // "round up" to the bigger size if two equally-valued matches exist
1033 nval = 0.5 * (fabs(maps[m]->size - fsize_x) + fabs(maps[m]->size - fsize_y));
1034 if (match == -1 || nval < value || (nval == value && matchsize < maps[m]->size))
1035 {
1036 value = nval;
1037 match = m;
1038 matchsize = maps[m]->size;
1039 if (value == 0) // there is no better match
1040 break;
1041 }
1042 }
1044 {
1045 // do NOT keep the aspect for perfect rendering
1046 if (outh) *outh = maps[match]->size * vid_conheight.value / vid.mode.height;
1047 if (outw) *outw = maps[match]->size * vid_conwidth.value / vid.mode.width;
1048 }
1049 return match;
1050}
cvar_t vid_conheight
Definition cl_screen.c:57
cvar_t vid_conwidth
Definition cl_screen.c:56
vector size
cvar_t r_font_size_snapping
Definition ft2.c:56
GLsizei const GLfloat * value
Definition glquake.h:740
float fabs(float f)
float value
Definition cvar.h:74
int width
Definition vid.h:60
int height
Definition vid.h:61
viddef_mode_t mode
currently active video mode
Definition vid.h:73
viddef_t vid
global video state
Definition vid_shared.c:64

References fabs(), ft2_font_t::font_maps, viddef_mode_t::height, MAX_FONT_SIZES, viddef_t::mode, r_font_size_snapping, size, cvar_t::value, value, vid, vid_conheight, vid_conwidth, and viddef_mode_t::width.

Referenced by DrawQ_String_Scale(), DrawQ_TextWidth_UntilWidth_TrackColors_Scale(), and Font_GetKerningForSize().

◆ Font_Init()

void Font_Init ( void )

Definition at line 443 of file ft2.c.

444{
452
454
455 // let's open it at startup already
457}
void Cvar_RegisterVariable(cvar_t *variable)
registers a cvar that already has the name, string, and optionally the archive elements set.
Definition cvar.c:599
cvar_t r_font_disable_incmaps
Definition ft2.c:63
cvar_t r_font_nonpoweroftwo
Definition ft2.c:60
qbool Font_OpenLibrary(void)
Definition ft2.c:362
cvar_t r_font_compress
Definition ft2.c:59
cvar_t r_font_diskcache
Definition ft2.c:58
cvar_t developer_font
Definition ft2.c:61

References Cvar_RegisterVariable(), developer_font, Font_OpenLibrary(), r_font_compress, r_font_disable_freetype, r_font_disable_incmaps, r_font_diskcache, r_font_kerning, r_font_nonpoweroftwo, and r_font_size_snapping.

Referenced by Render_Init().

◆ Font_LoadFile()

static qbool Font_LoadFile ( const char * name,
int _face,
ft2_settings_t * settings,
ft2_font_t * font )
static

Definition at line 628 of file ft2.c.

629{
630 size_t namelen;
631 char filename[MAX_QPATH];
632 int status;
633 size_t i;
634 const unsigned char *data;
635 fs_offset_t datasize;
636
637 memset(font, 0, sizeof(*font));
638
639 if (!Font_OpenLibrary())
640 {
642 {
643 Con_Printf(CON_WARN "WARNING: can't open load font %s\n"
644 "You need the FreeType2 DLL to load font files\n",
645 name);
646 }
647 return false;
648 }
649
650 font->settings = settings;
651
652 namelen = strlen(name);
653 if (namelen + 5 > sizeof(filename))
654 {
655 Con_Printf(CON_WARN "WARNING: too long font name. Cannot load this.\n");
656 return false;
657 }
658
659 // try load direct file
660 memcpy(filename, name, namelen+1);
661 data = fontfilecache_LoadFile(filename, false, &datasize);
662 // try load .ttf
663 if (!data)
664 {
665 memcpy(filename + namelen, ".ttf", 5);
666 data = fontfilecache_LoadFile(filename, false, &datasize);
667 }
668 // try load .otf
669 if (!data)
670 {
671 memcpy(filename + namelen, ".otf", 5);
672 data = fontfilecache_LoadFile(filename, false, &datasize);
673 }
674 // try load .pfb/afm
675 if (!data)
676 {
677 ft2_attachment_t afm;
678
679 memcpy(filename + namelen, ".pfb", 5);
680 data = fontfilecache_LoadFile(filename, false, &datasize);
681
682 if (data)
683 {
684 memcpy(filename + namelen, ".afm", 5);
685 afm.data = fontfilecache_LoadFile(filename, false, &afm.size);
686
687 if (afm.data)
688 Font_Attach(font, &afm);
689 }
690 }
691 if (!data)
692 {
693 // FS_LoadFile being not-quiet should print an error :)
694 return false;
695 }
696 Con_DPrintf("Loading font %s face %i...\n", filename, _face);
697
698 status = qFT_New_Memory_Face(font_ft2lib, (FT_Bytes)data, datasize, _face, (FT_Face*)&font->face);
699 if (status && _face != 0)
700 {
701 Con_Printf(CON_ERROR "Failed to load face %i of %s. Falling back to face 0\n", _face, name);
702 _face = 0;
703 status = qFT_New_Memory_Face(font_ft2lib, (FT_Bytes)data, datasize, _face, (FT_Face*)&font->face);
704 }
705 font->data = data;
706 if (status)
707 {
708 Con_Printf(CON_ERROR "ERROR: can't create face for %s\n"
709 "Error %i\n", // TODO: error strings
710 name, status);
711 Font_UnloadFont(font);
712 return false;
713 }
714
715 // add the attachments
716 for (i = 0; i < font->attachmentcount; ++i)
717 {
718 FT_Open_Args args;
719 memset(&args, 0, sizeof(args));
720 args.flags = FT_OPEN_MEMORY;
721 args.memory_base = (const FT_Byte*)font->attachments[i].data;
722 args.memory_size = font->attachments[i].size;
723 if (qFT_Attach_Stream((FT_Face)font->face, &args))
724 Con_Printf(CON_ERROR "Failed to add attachment %u to %s\n", (unsigned)i, font->name);
725 }
726
727 dp_strlcpy(font->name, name, sizeof(font->name));
728 font->image_font = false;
729 font->has_kerning = !!(((FT_Face)(font->face))->face_flags & FT_FACE_FLAG_KERNING);
730 return true;
731}
#define dp_strlcpy(dst, src, dsize)
Definition common.h:303
int64_t fs_offset_t
Definition fs.h:37
static qbool Font_Attach(ft2_font_t *font, ft2_attachment_t *attachment)
Definition ft2.c:478
(* qFT_New_Memory_Face)(FT_Library library, const FT_Byte *file_base, FT_Long file_size, FT_Long face_index, FT_Face *aface)
Definition ft2.c:86
static const unsigned char * fontfilecache_LoadFile(const char *path, qbool quiet, fs_offset_t *filesizepointer)
Definition ft2.c:269
(* qFT_Attach_Stream)(FT_Face face, FT_Open_Args *parameters)
Definition ft2.c:130
void Font_UnloadFont(ft2_font_t *font)
Definition ft2.c:1184
#define FT_FACE_FLAG_KERNING
Definition ft2_defs.h:484
unsigned char FT_Byte
Definition ft2_defs.h:19
#define FT_OPEN_MEMORY
Definition ft2_defs.h:220
const FT_Byte * FT_Bytes
Definition ft2_defs.h:20
GLsizeiptr const GLvoid * data
Definition glquake.h:639
float strlen(string s)
int i
#define MAX_QPATH
max length of a quake game pathname
Definition qdefs.h:169
FT_UInt flags
Definition ft2_defs.h:234
FT_Long memory_size
Definition ft2_defs.h:236
const FT_Byte * memory_base
Definition ft2_defs.h:235
qbool image_font
Definition ft2.h:48
ft2_settings_t * settings
Definition ft2.h:64
const unsigned char * data
Definition ft2.h:52

References ft2_font_t::attachmentcount, ft2_font_t::attachments, Con_DPrintf(), CON_ERROR, Con_Printf(), CON_WARN, data, ft2_font_t::data, dp_strlcpy, ft2_font_t::face, FT_Open_Args::flags, Font_Attach(), font_ft2lib, Font_OpenLibrary(), Font_UnloadFont(), fontfilecache_LoadFile(), FT_FACE_FLAG_KERNING, FT_OPEN_MEMORY, ft2_font_t::has_kerning, i, ft2_font_t::image_font, cvar_t::integer, MAX_QPATH, FT_Open_Args::memory_base, FT_Open_Args::memory_size, ft2_font_t::name, name, qFT_Attach_Stream, qFT_New_Memory_Face, r_font_disable_freetype, ft2_font_t::settings, and strlen().

Referenced by Font_LoadFont().

◆ Font_LoadFont()

qbool Font_LoadFont ( const char * name,
dp_font_t * dpfnt )

Definition at line 521 of file ft2.c.

522{
523 int s, count, i;
524 ft2_font_t *ft2, *fbfont, *fb;
525 char vabuf[1024];
526
527 ft2 = Font_Alloc();
528 if (!ft2)
529 {
530 dpfnt->ft2 = NULL;
531 return false;
532 }
533
534 // check if a fallback font has been specified, if it has been, and the
535 // font fails to load, use the image font as main font
536 for (i = 0; i < MAX_FONT_FALLBACKS; ++i)
537 {
538 if (dpfnt->fallbacks[i][0])
539 break;
540 }
541
542 if (!Font_LoadFile(name, dpfnt->req_face, &dpfnt->settings, ft2))
543 {
544 if (i >= MAX_FONT_FALLBACKS)
545 {
546 dpfnt->ft2 = NULL;
547 Mem_Free(ft2);
548 return false;
549 }
550 dp_strlcpy(ft2->name, name, sizeof(ft2->name));
551 ft2->image_font = true;
552 ft2->has_kerning = false;
553 }
554 else
555 {
556 ft2->image_font = false;
557 }
558
559 // attempt to load fallback fonts:
560 fbfont = ft2;
561 for (i = 0; i < MAX_FONT_FALLBACKS; ++i)
562 {
563 if (!dpfnt->fallbacks[i][0])
564 break;
565 if (! (fb = Font_Alloc()) )
566 {
567 Con_Printf(CON_ERROR "Failed to allocate font for fallback %i of font %s\n", i, name);
568 break;
569 }
570
571 if (!Font_LoadFile(dpfnt->fallbacks[i], dpfnt->fallback_faces[i], &dpfnt->settings, fb))
572 {
573 if(!FS_FileExists(va(vabuf, sizeof(vabuf), "%s.tga", dpfnt->fallbacks[i])))
574 if(!FS_FileExists(va(vabuf, sizeof(vabuf), "%s.png", dpfnt->fallbacks[i])))
575 if(!FS_FileExists(va(vabuf, sizeof(vabuf), "%s.jpg", dpfnt->fallbacks[i])))
576 if(!FS_FileExists(va(vabuf, sizeof(vabuf), "%s.pcx", dpfnt->fallbacks[i])))
577 Con_Printf(CON_ERROR "Failed to load font %s for fallback %i of font %s\n", dpfnt->fallbacks[i], i, name);
578 Mem_Free(fb);
579 continue;
580 }
581 count = 0;
582 for (s = 0; s < MAX_FONT_SIZES && dpfnt->req_sizes[s] >= 0; ++s)
583 {
584 if (Font_LoadSize(fb, Font_VirtualToRealSize(dpfnt->req_sizes[s]), true))
585 ++count;
586 }
587 if (!count)
588 {
589 Con_Printf(CON_ERROR "Failed to allocate font for fallback %i of font %s\n", i, name);
590 Font_UnloadFont(fb);
591 Mem_Free(fb);
592 break;
593 }
594 // at least one size of the fallback font loaded successfully
595 // link it:
596 fbfont->next = fb;
597 fbfont = fb;
598 }
599
600 if (fbfont == ft2 && ft2->image_font)
601 {
602 // no fallbacks were loaded successfully:
603 dpfnt->ft2 = NULL;
604 Mem_Free(ft2);
605 return false;
606 }
607
608 count = 0;
609 for (s = 0; s < MAX_FONT_SIZES && dpfnt->req_sizes[s] >= 0; ++s)
610 {
611 if (Font_LoadSize(ft2, Font_VirtualToRealSize(dpfnt->req_sizes[s]), false))
612 ++count;
613 }
614 if (!count)
615 {
616 // loading failed for every requested size
617 Font_UnloadFont(ft2);
618 Mem_Free(ft2);
619 dpfnt->ft2 = NULL;
620 return false;
621 }
622
623 //Con_Printf("%i sizes loaded\n", count);
624 dpfnt->ft2 = ft2;
625 return true;
626}
char * va(char *buf, size_t buflen, const char *format,...)
Definition common.c:972
#define MAX_FONT_FALLBACKS
Definition draw.h:95
const char * FS_FileExists(const char *filename)
Look for a file in the packages and in the filesystem Returns its canonical name (same case as used i...
Definition fs.c:3693
static qbool Font_LoadFile(const char *name, int _face, ft2_settings_t *settings, ft2_font_t *font)
Definition ft2.c:628
ft2_font_t * Font_Alloc(void)
Definition ft2.c:467
float Font_VirtualToRealSize(float sz)
Definition ft2.c:496
static qbool Font_LoadSize(ft2_font_t *font, float size, qbool check_only)
Definition ft2.c:911
GLenum GLenum GLsizei count
Definition glquake.h:656
struct ft2_font_s * ft2
Definition draw.h:110
int req_face
Definition draw.h:106
float req_sizes[MAX_FONT_SIZES]
Definition draw.h:107
int fallback_faces[MAX_FONT_FALLBACKS]
Definition draw.h:109
ft2_settings_t settings
Definition draw.h:112
char fallbacks[MAX_FONT_FALLBACKS][MAX_QPATH]
Definition draw.h:108
struct ft2_font_s * next
Definition ft2.h:67

References CON_ERROR, Con_Printf(), count, dp_strlcpy, dp_font_t::fallback_faces, dp_font_t::fallbacks, Font_Alloc(), Font_LoadFile(), Font_LoadSize(), Font_UnloadFont(), Font_VirtualToRealSize(), FS_FileExists(), dp_font_t::ft2, ft2_font_t::has_kerning, i, ft2_font_t::image_font, MAX_FONT_FALLBACKS, MAX_FONT_SIZES, Mem_Free, ft2_font_t::name, name, ft2_font_t::next, NULL, dp_font_t::req_face, dp_font_t::req_sizes, dp_font_t::settings, and va().

Referenced by LoadFont().

◆ Font_LoadMap()

static qbool Font_LoadMap ( ft2_font_t * font,
ft2_font_map_t * mapstart,
Uchar _ch,
ft2_font_map_t ** outmap,
int * outmapch,
qbool incmap_ok )
static

Definition at line 1385 of file ft2.c.

1387{
1388 #define bytes_per_pixel 4
1389
1390 char map_identifier[MAX_QPATH];
1391 unsigned long map_startglyph = _ch / FONT_CHARS_PER_MAP * FONT_CHARS_PER_MAP;
1392 unsigned char *data = NULL;
1393 FT_ULong ch = 0, mapch = 0;
1394 int status;
1395 int tp;
1396 FT_Int32 load_flags;
1397 int gpad_l, gpad_r, gpad_t, gpad_b;
1398
1399 int pitch;
1400 int width, height, datasize;
1401 int glyph_row, glyph_column;
1402
1403 int chars_per_line = FONT_CHARS_PER_LINE;
1404 int char_lines = FONT_CHAR_LINES;
1405 int chars_per_map = FONT_CHARS_PER_MAP;
1406
1407 ft2_font_t *usefont;
1408 ft2_font_map_t *map, *next;
1409 font_incmap_t *incmap;
1410
1411 FT_Face fontface;
1412
1413 incmap = mapstart->incmap;
1414 if (use_incmap)
1415 {
1416 // only render one character in this map;
1417 // such small maps will be merged together later in `incmap_post_process`
1418 chars_per_line = char_lines = chars_per_map = 1;
1419 // and the index is incremental
1420 map_startglyph = incmap ? incmap->newmap_start : INCMAP_START;
1421 }
1422
1423 if (font->image_font)
1424 fontface = (FT_Face)font->next->face;
1425 else
1426 fontface = (FT_Face)font->face;
1427
1428 switch(font->settings->antialias)
1429 {
1430 case 0:
1431 switch(font->settings->hinting)
1432 {
1433 case 0:
1435 break;
1436 case 1:
1437 case 2:
1439 break;
1440 default:
1441 case 3:
1443 break;
1444 }
1445 break;
1446 default:
1447 case 1:
1448 switch(font->settings->hinting)
1449 {
1450 case 0:
1452 break;
1453 case 1:
1455 break;
1456 case 2:
1458 break;
1459 default:
1460 case 3:
1461 load_flags = FT_LOAD_TARGET_NORMAL;
1462 break;
1463 }
1464 break;
1465 }
1466
1467 //status = qFT_Set_Pixel_Sizes((FT_Face)font->face, /*size*/0, mapstart->size);
1468 //if (status)
1469 if (font->image_font && mapstart->intSize < 0)
1470 mapstart->intSize = mapstart->size;
1471 if (mapstart->intSize < 0)
1472 {
1473 /*
1474 mapstart->intSize = mapstart->size;
1475 while (1)
1476 {
1477 if (!Font_SetSize(font, mapstart->intSize, mapstart->intSize))
1478 {
1479 Con_Printf("ERROR: can't set size for font %s: %f ((%f))\n", font->name, mapstart->size, mapstart->intSize);
1480 return false;
1481 }
1482 if ((fontface->size->metrics.height>>6) <= mapstart->size)
1483 break;
1484 if (mapstart->intSize < 2)
1485 {
1486 Con_Printf("ERROR: no appropriate size found for font %s: %f\n", font->name, mapstart->size);
1487 return false;
1488 }
1489 --mapstart->intSize;
1490 }
1491 */
1492 if ((mapstart->intSize = Font_SearchSize(font, fontface, mapstart->size)) <= 0)
1493 return false;
1494 Con_DPrintf("Using size: %f for requested size %f\n", mapstart->intSize, mapstart->size);
1495 }
1496
1497 if (!font->image_font && !Font_SetSize(font, mapstart->intSize, mapstart->intSize))
1498 {
1499 Con_Printf(CON_ERROR "ERROR: can't set sizes for font %s: %f\n", font->name, mapstart->size);
1500 return false;
1501 }
1502
1503 map = (ft2_font_map_t *)Mem_Alloc(font_mempool, sizeof(ft2_font_map_t));
1504 if (!map)
1505 {
1506 Con_Printf(CON_ERROR "ERROR: Out of memory when allocating fontmap for %s\n", font->name);
1507 return false;
1508 }
1509
1510 map->start = map_startglyph;
1511
1512 // create a unique name for this map, then we will use it to make a unique cachepic_t to avoid redundant textures
1513 /*
1514 dpsnprintf(map_identifier, sizeof(map_identifier),
1515 "%s_cache_%g_%d_%g_%g_%g_%g_%g_%u_%lx",
1516 font->name,
1517 (double) mapstart->intSize,
1518 (int) load_flags,
1519 (double) font->settings->blur,
1520 (double) font->settings->outline,
1521 (double) font->settings->shadowx,
1522 (double) font->settings->shadowy,
1523 (double) font->settings->shadowz,
1524 (unsigned) map_startglyph,
1525 // add pointer as a unique part to avoid earlier incmaps' state being trashed
1526 use_incmap ? (unsigned long)mapstart : 0x0);
1527 */
1528 /*
1529 * note 1: it appears that different font instances may have the same metrics, causing this pic being overwritten
1530 * will use startmap's pointer as a unique part to avoid earlier incmaps' dynamic pics being trashed
1531 * note 2: if this identifier is made too long, significient performance drop will take place
1532 * note 3: blur/outline/shadow are per-font settings, so a pointer to startmap & map size
1533 * already made these unique, hence they are omitted
1534 * note 4: font_diskcache is removed, this name can be less meaningful
1535 */
1536 dpsnprintf(map_identifier, sizeof(map_identifier), "%s_%g_%p_%u",
1537 font->name, mapstart->intSize, mapstart, (unsigned) map_startglyph);
1538
1539 // create a cachepic_t from the data now, or reuse an existing one
1541 Con_Printf("Generating font map %s (size: %.1f MB)\n", map_identifier, mapstart->glyphSize * (256 * 4 / 1048576.0) * mapstart->glyphSize);
1542
1543 Font_Postprocess(font, NULL, 0, bytes_per_pixel, mapstart->size*2, mapstart->size*2, &gpad_l, &gpad_r, &gpad_t, &gpad_b);
1544
1545 // copy over the information
1546 map->size = mapstart->size;
1547 map->intSize = mapstart->intSize;
1548 map->glyphSize = mapstart->glyphSize;
1549 map->sfx = mapstart->sfx;
1550 map->sfy = mapstart->sfy;
1551
1552 width = map->glyphSize * chars_per_line;
1553 height = map->glyphSize * char_lines;
1554 pitch = width * bytes_per_pixel;
1555 datasize = height * pitch;
1556 data = (unsigned char *)Mem_Alloc(font_mempool, datasize);
1557 if (!data)
1558 {
1559 Con_Printf(CON_ERROR "ERROR: Failed to allocate memory for font %s size %g\n", font->name, map->size);
1560 Mem_Free(map);
1561 return false;
1562 }
1563
1564 if (use_incmap)
1565 {
1566 if (mapstart->incmap == NULL)
1567 {
1568 // initial incmap
1569 incmap = mapstart->incmap = (font_incmap_t *)Mem_Alloc(font_mempool, sizeof(font_incmap_t));
1570 if (!incmap)
1571 {
1572 Con_Printf(CON_ERROR "ERROR: Out of memory when allocating incremental fontmap for %s\n", font->name);
1573 return false;
1574 }
1575 // this will be the startmap of incmap
1576 incmap->fontmap = map;
1577 incmap->newmap_start = INCMAP_START;
1578 }
1579 else
1580 {
1581 // new maps for incmap shall always be the last one
1582 next = incmap->fontmap;
1583 while (next->next != NULL)
1584 next = next->next;
1585 next->next = map;
1586 }
1587 }
1588 else
1589 {
1590 // insert this normal map
1591 next = use_incmap ? incmap->fontmap : mapstart;
1592 while(next->next && next->next->start < map->start)
1593 next = next->next;
1594 map->next = next->next;
1595 next->next = map;
1596 }
1597
1598 // initialize as white texture with zero alpha
1599 tp = 0;
1600 while (tp < datasize)
1601 {
1602 if (bytes_per_pixel == 4)
1603 {
1604 data[tp++] = 0xFF;
1605 data[tp++] = 0xFF;
1606 data[tp++] = 0xFF;
1607 }
1608 data[tp++] = 0x00;
1609 }
1610
1611 glyph_row = 0;
1612 glyph_column = 0;
1613 ch = (FT_ULong)(use_incmap ? _ch : map->start);
1614 mapch = 0;
1615 while (true)
1616 {
1617 FT_ULong glyphIndex;
1618 int w, h, x, y;
1619 FT_GlyphSlot glyph;
1620 FT_Bitmap *bmp;
1621 unsigned char *imagedata = NULL, *dst, *src;
1622 glyph_slot_t *mapglyph;
1623 FT_Face face;
1624 int pad_l, pad_r, pad_t, pad_b;
1625
1627 Con_DPrint("glyphinfo: ------------- GLYPH INFO -----------------\n");
1628
1629 map->glyphchars[mapch] = (Uchar)ch;
1630
1631 if (data)
1632 {
1633 imagedata = data + glyph_row * pitch * map->glyphSize + glyph_column * map->glyphSize * bytes_per_pixel;
1634 imagedata += gpad_t * pitch + gpad_l * bytes_per_pixel;
1635 }
1636 //status = qFT_Load_Char(face, ch, FT_LOAD_RENDER);
1637 // we need the glyphIndex
1638 face = (FT_Face)font->face;
1639 usefont = NULL;
1640 if (font->image_font && mapch == ch && img_fontmap[mapch])
1641 {
1642 map->glyphs[mapch].image = true;
1643 continue;
1644 }
1645 glyphIndex = qFT_Get_Char_Index(face, ch);
1646 if (glyphIndex == 0)
1647 {
1648 // by convention, 0 is the "missing-glyph"-glyph
1649 // try to load from a fallback font
1650 for(usefont = font->next; usefont != NULL; usefont = usefont->next)
1651 {
1652 if (!Font_SetSize(usefont, mapstart->intSize, mapstart->intSize))
1653 continue;
1654 // try that glyph
1655 face = (FT_Face)usefont->face;
1656 glyphIndex = qFT_Get_Char_Index(face, ch);
1657 if (glyphIndex == 0)
1658 continue;
1659 status = qFT_Load_Glyph(face, glyphIndex, FT_LOAD_RENDER | load_flags);
1660 if (status)
1661 continue;
1662 break;
1663 }
1664 if (!usefont)
1665 {
1666 //Con_Printf("failed to load fallback glyph for char %lx from font %s\n", (unsigned long)ch, font->name);
1667 // now we let it use the "missing-glyph"-glyph
1668 face = (FT_Face)font->face;
1669 glyphIndex = 0;
1670 }
1671 }
1672
1673 if (!usefont)
1674 {
1675 usefont = font;
1676 face = (FT_Face)font->face;
1677 status = qFT_Load_Glyph(face, glyphIndex, FT_LOAD_RENDER | load_flags);
1678 if (status)
1679 {
1680 //Con_Printf("failed to load glyph %lu for %s\n", glyphIndex, font->name);
1681 Con_DPrintf("failed to load glyph for char %lx from font %s\n", (unsigned long)ch, font->name);
1682 continue;
1683 }
1684 }
1685
1686 glyph = face->glyph;
1687 bmp = &glyph->bitmap;
1688
1689 w = bmp->width;
1690 h = bmp->rows;
1691
1692 if (w > (map->glyphSize - gpad_l - gpad_r) || h > (map->glyphSize - gpad_t - gpad_b)) {
1693 Con_Printf(CON_WARN "WARNING: Glyph %lu is too big in font %s, size %g: %i x %i\n", ch, font->name, map->size, w, h);
1694 if (w > map->glyphSize)
1695 w = map->glyphSize - gpad_l - gpad_r;
1696 if (h > map->glyphSize)
1697 h = map->glyphSize;
1698 }
1699
1700 if (imagedata)
1701 {
1702 switch (bmp->pixel_mode)
1703 {
1704 case FT_PIXEL_MODE_MONO:
1706 Con_DPrint("glyphinfo: Pixel Mode: MONO\n");
1707 break;
1710 Con_DPrint("glyphinfo: Pixel Mode: GRAY2\n");
1711 break;
1714 Con_DPrint("glyphinfo: Pixel Mode: GRAY4\n");
1715 break;
1716 case FT_PIXEL_MODE_GRAY:
1718 Con_DPrint("glyphinfo: Pixel Mode: GRAY\n");
1719 break;
1720 default:
1722 Con_DPrintf("glyphinfo: Pixel Mode: Unknown: %i\n", bmp->pixel_mode);
1723 Mem_Free(data);
1724 Con_Printf(CON_ERROR "ERROR: Unrecognized pixel mode for font %s size %f: %i\n", font->name, mapstart->size, bmp->pixel_mode);
1725 return false;
1726 }
1727 for (y = 0; y < h; ++y)
1728 {
1729 dst = imagedata + y * pitch;
1730 src = bmp->buffer + y * bmp->pitch;
1731
1732 switch (bmp->pixel_mode)
1733 {
1734 case FT_PIXEL_MODE_MONO:
1735 dst += bytes_per_pixel - 1; // shift to alpha byte
1736 for (x = 0; x < bmp->width; x += 8)
1737 {
1738 unsigned char c = *src++;
1739 *dst = 255 * !!((c & 0x80) >> 7); dst += bytes_per_pixel;
1740 *dst = 255 * !!((c & 0x40) >> 6); dst += bytes_per_pixel;
1741 *dst = 255 * !!((c & 0x20) >> 5); dst += bytes_per_pixel;
1742 *dst = 255 * !!((c & 0x10) >> 4); dst += bytes_per_pixel;
1743 *dst = 255 * !!((c & 0x08) >> 3); dst += bytes_per_pixel;
1744 *dst = 255 * !!((c & 0x04) >> 2); dst += bytes_per_pixel;
1745 *dst = 255 * !!((c & 0x02) >> 1); dst += bytes_per_pixel;
1746 *dst = 255 * !!((c & 0x01) >> 0); dst += bytes_per_pixel;
1747 }
1748 break;
1750 dst += bytes_per_pixel - 1; // shift to alpha byte
1751 for (x = 0; x < bmp->width; x += 4)
1752 {
1753 unsigned char c = *src++;
1754 *dst = ( ((c & 0xA0) >> 6) * 0x55 ); c <<= 2; dst += bytes_per_pixel;
1755 *dst = ( ((c & 0xA0) >> 6) * 0x55 ); c <<= 2; dst += bytes_per_pixel;
1756 *dst = ( ((c & 0xA0) >> 6) * 0x55 ); c <<= 2; dst += bytes_per_pixel;
1757 *dst = ( ((c & 0xA0) >> 6) * 0x55 ); c <<= 2; dst += bytes_per_pixel;
1758 }
1759 break;
1761 dst += bytes_per_pixel - 1; // shift to alpha byte
1762 for (x = 0; x < bmp->width; x += 2)
1763 {
1764 unsigned char c = *src++;
1765 *dst = ( ((c & 0xF0) >> 4) * 0x11); dst += bytes_per_pixel;
1766 *dst = ( ((c & 0x0F) ) * 0x11); dst += bytes_per_pixel;
1767 }
1768 break;
1769 case FT_PIXEL_MODE_GRAY:
1770 // in this case pitch should equal width
1771 for (tp = 0; tp < bmp->pitch; ++tp)
1772 dst[(bytes_per_pixel - 1) + tp*bytes_per_pixel] = src[tp]; // copy the grey value into the alpha bytes
1773
1774 //memcpy((void*)dst, (void*)src, bmp->pitch);
1775 //dst += bmp->pitch;
1776 break;
1777 default:
1778 break;
1779 }
1780 }
1781
1782 pad_l = gpad_l;
1783 pad_r = gpad_r;
1784 pad_t = gpad_t;
1785 pad_b = gpad_b;
1786 Font_Postprocess(font, imagedata, pitch, bytes_per_pixel, w, h, &pad_l, &pad_r, &pad_t, &pad_b);
1787 }
1788 else
1789 {
1790 pad_l = gpad_l;
1791 pad_r = gpad_r;
1792 pad_t = gpad_t;
1793 pad_b = gpad_b;
1794 Font_Postprocess(font, NULL, pitch, bytes_per_pixel, w, h, &pad_l, &pad_r, &pad_t, &pad_b);
1795 }
1796
1797
1798 // now fill map->glyphs[ch - map->start]
1799 mapglyph = &map->glyphs[mapch];
1800
1801 {
1802 // old way
1803 // double advance = (double)glyph->metrics.horiAdvance * map->sfx;
1804
1805 double bearingX = (glyph->metrics.horiBearingX / 64.0) / map->size;
1806 //double bearingY = (glyph->metrics.horiBearingY >> 6) / map->size;
1807 double advance = (glyph->advance.x / 64.0) / map->size;
1808 //double mWidth = (glyph->metrics.width >> 6) / map->size;
1809 //double mHeight = (glyph->metrics.height >> 6) / map->size;
1810
1811 mapglyph->txmin = ( (double)(glyph_column * map->glyphSize) + (double)(gpad_l - pad_l) ) / ( (double)(map->glyphSize * chars_per_line) );
1812 mapglyph->txmax = mapglyph->txmin + (double)(bmp->width + pad_l + pad_r) / ( (double)(map->glyphSize * chars_per_line) );
1813 mapglyph->tymin = ( (double)(glyph_row * map->glyphSize) + (double)(gpad_r - pad_r) ) / ( (double)(map->glyphSize * char_lines) );
1814 mapglyph->tymax = mapglyph->tymin + (double)(bmp->rows + pad_t + pad_b) / ( (double)(map->glyphSize * char_lines) );
1815 //mapglyph->vxmin = bearingX;
1816 //mapglyph->vxmax = bearingX + mWidth;
1817 mapglyph->vxmin = (glyph->bitmap_left - pad_l) / map->size;
1818 mapglyph->vxmax = mapglyph->vxmin + (bmp->width + pad_l + pad_r) / map->size; // don't ask
1819 //mapglyph->vymin = -bearingY;
1820 //mapglyph->vymax = mHeight - bearingY;
1821 mapglyph->vymin = (-glyph->bitmap_top - pad_t) / map->size;
1822 mapglyph->vymax = mapglyph->vymin + (bmp->rows + pad_t + pad_b) / map->size;
1823 //Con_Printf("dpi = %f %f (%f %d) %d %d\n", bmp->width / (mapglyph->vxmax - mapglyph->vxmin), bmp->rows / (mapglyph->vymax - mapglyph->vymin), map->size, map->glyphSize, (int)fontface->size->metrics.x_ppem, (int)fontface->size->metrics.y_ppem);
1824 //mapglyph->advance_x = advance * usefont->size;
1825 //mapglyph->advance_x = advance;
1826 mapglyph->advance_x = Font_SnapTo(advance, 1 / map->size);
1827 mapglyph->advance_y = 0;
1828
1830 {
1831 Con_DPrintf("glyphinfo: Glyph: %lu at (%i, %i)\n", (unsigned long)ch, glyph_column, glyph_row);
1832 Con_DPrintf("glyphinfo: %f, %f, %lu\n", bearingX, map->sfx, (unsigned long)glyph->metrics.horiBearingX);
1833 if (ch >= 32 && ch <= 128)
1834 Con_DPrintf("glyphinfo: Character: %c\n", (int)ch);
1835 Con_DPrintf("glyphinfo: Vertex info:\n");
1836 Con_DPrintf("glyphinfo: X: ( %f -- %f )\n", mapglyph->vxmin, mapglyph->vxmax);
1837 Con_DPrintf("glyphinfo: Y: ( %f -- %f )\n", mapglyph->vymin, mapglyph->vymax);
1838 Con_DPrintf("glyphinfo: Texture info:\n");
1839 Con_DPrintf("glyphinfo: S: ( %f -- %f )\n", mapglyph->txmin, mapglyph->txmax);
1840 Con_DPrintf("glyphinfo: T: ( %f -- %f )\n", mapglyph->tymin, mapglyph->tymax);
1841 Con_DPrintf("glyphinfo: Advance: %f, %f\n", mapglyph->advance_x, mapglyph->advance_y);
1842 }
1843 }
1844 map->glyphs[mapch].image = false;
1845
1846 ++mapch; ++ch;
1847 if ((int)mapch == chars_per_map)
1848 break;
1849 if (++glyph_column % chars_per_line == 0)
1850 {
1851 glyph_column = 0;
1852 ++glyph_row;
1853 }
1854 }
1855
1856 // update the pic returned by Draw_CachePic_Flags earlier to contain our texture
1857 update_pic_for_fontmap(map, map_identifier, width, height, data);
1858
1859 if (!Draw_IsPicLoaded(map->pic))
1860 {
1861 // if the first try isn't successful, keep it with a broken texture
1862 // otherwise we retry to load it every single frame where ft2 rendering is used
1863 // this would be bad...
1864 // only `data' must be freed
1865 Con_Printf(CON_ERROR "ERROR: Failed to generate texture for font %s size %f map %lu\n",
1866 font->name, mapstart->size, map_startglyph);
1867 return false;
1868 }
1869
1870 if (use_incmap)
1871 {
1872 *outmap = map;
1873 *outmapch = 0;
1874 // data will be kept in incmap for being merged later, freed afterward
1875 incmap_post_process(incmap, _ch, data, outmap, outmapch);
1876 }
1877 else if (data)
1878 {
1879 Mem_Free(data);
1880 *outmap = map;
1881 if (outmapch != NULL)
1882 *outmapch = _ch - map->start;
1883 }
1884
1885 return true;
1886}
int dpsnprintf(char *buffer, size_t buffersize, const char *format,...)
Returns the number of printed characters, excluding the final '\0' or returns -1 if the buffer isn't ...
Definition common.c:997
void Con_DPrint(const char *msg)
A Con_Print that only shows up if the "developer" cvar is set.
Definition console.c:1531
qbool Draw_IsPicLoaded(cachepic_t *pic)
Definition gl_draw.c:211
static void Font_Postprocess(ft2_font_t *fnt, unsigned char *imagedata, int pitch, int bpp, int w, int h, int *pad_l, int *pad_r, int *pad_t, int *pad_b)
Definition ft2.c:787
static int img_fontmap[256]
Definition ft2.c:11
static void incmap_post_process(font_incmap_t *incmap, Uchar ch, unsigned char *data, ft2_font_map_t **outmap, int *outmapch)
Definition ft2.c:1283
static float Font_SearchSize(ft2_font_t *font, FT_Face fontface, float size)
Definition ft2.c:1228
static void update_pic_for_fontmap(ft2_font_map_t *fontmap, const char *identifier, int width, int height, unsigned char *data)
Definition ft2.c:1251
(* qFT_Load_Glyph)(FT_Face face, FT_UInt glyph_index, FT_Int32 load_flags)
Definition ft2.c:110
#define FT_LOAD_RENDER
Definition ft2_defs.h:267
#define FT_LOAD_TARGET_MONO
Definition ft2_defs.h:284
#define FT_LOAD_TARGET_NORMAL
Definition ft2_defs.h:282
@ FT_PIXEL_MODE_GRAY2
Definition ft2_defs.h:63
@ FT_PIXEL_MODE_MONO
Definition ft2_defs.h:61
@ FT_PIXEL_MODE_GRAY
Definition ft2_defs.h:62
@ FT_PIXEL_MODE_GRAY4
Definition ft2_defs.h:64
#define FT_LOAD_NO_HINTING
Definition ft2_defs.h:266
#define FT_LOAD_FORCE_AUTOHINT
Definition ft2_defs.h:270
int32_t FT_Int32
Definition ft2_defs.h:12
#define FT_LOAD_MONOCHROME
Definition ft2_defs.h:276
struct FT_GlyphSlotRec_ * FT_GlyphSlot
Definition ft2_defs.h:40
#define FT_LOAD_NO_AUTOHINT
Definition ft2_defs.h:278
#define FT_LOAD_TARGET_LIGHT
Definition ft2_defs.h:283
#define INCMAP_START
#define FONT_CHAR_LINES
Definition ft2_fontdefs.h:7
GLint GLenum GLint GLint y
Definition glquake.h:651
GLint GLenum GLint x
Definition glquake.h:651
prvm_eval_t * src
int width
Definition ft2_defs.h:89
int rows
Definition ft2_defs.h:88
char pixel_mode
Definition ft2_defs.h:93
unsigned char * buffer
Definition ft2_defs.h:91
int pitch
Definition ft2_defs.h:90
int antialias
Definition draw.h:90
int hinting
Definition draw.h:90
int32_t Uchar
Definition utf8lib.h:35

References glyph_slot_t::advance_x, glyph_slot_t::advance_y, ft2_settings_t::antialias, FT_Bitmap::buffer, bytes_per_pixel, Con_DPrint(), Con_DPrintf(), CON_ERROR, Con_Printf(), CON_WARN, data, developer_font, dpsnprintf(), Draw_IsPicLoaded(), ft2_font_t::face, FONT_CHAR_LINES, FONT_CHARS_PER_LINE, FONT_CHARS_PER_MAP, font_mempool, Font_Postprocess(), Font_SearchSize(), Font_SetSize(), Font_SnapTo(), FT_LOAD_FORCE_AUTOHINT, FT_LOAD_MONOCHROME, FT_LOAD_NO_AUTOHINT, FT_LOAD_NO_HINTING, FT_LOAD_RENDER, FT_LOAD_TARGET_LIGHT, FT_LOAD_TARGET_MONO, FT_LOAD_TARGET_NORMAL, FT_PIXEL_MODE_GRAY, FT_PIXEL_MODE_GRAY2, FT_PIXEL_MODE_GRAY4, FT_PIXEL_MODE_MONO, height, ft2_settings_t::hinting, glyph_slot_t::image, ft2_font_t::image_font, img_fontmap, incmap_post_process(), INCMAP_START, cvar_t::integer, MAX_QPATH, Mem_Alloc, Mem_Free, ft2_font_t::name, ft2_font_t::next, NULL, FT_Bitmap::pitch, FT_Bitmap::pixel_mode, qFT_Get_Char_Index, qFT_Load_Glyph, FT_Bitmap::rows, ft2_font_t::settings, src, glyph_slot_t::txmax, glyph_slot_t::txmin, glyph_slot_t::tymax, glyph_slot_t::tymin, update_pic_for_fontmap(), glyph_slot_t::vxmax, glyph_slot_t::vxmin, glyph_slot_t::vymax, glyph_slot_t::vymin, w, FT_Bitmap::width, width, x, and y.

Referenced by Font_GetMapForChar(), Font_LoadMapForIndex(), and Font_LoadSize().

◆ Font_LoadMapForIndex()

qbool Font_LoadMapForIndex ( ft2_font_t * font,
int map_index,
Uchar ch,
ft2_font_map_t ** outmap )

Definition at line 1899 of file ft2.c.

1900{
1901 if (map_index < 0 || map_index >= MAX_FONT_SIZES)
1902 return false;
1903 // the first map must have been loaded already
1904 if (!font->font_maps[map_index])
1905 return false;
1906 alert_legacy_font_api("Font_LoadMapForIndex");
1907 return Font_LoadMap(font, font->font_maps[map_index], ch, outmap, NULL, false);
1908}
static void alert_legacy_font_api(const char *name)
Definition ft2.c:1889

References alert_legacy_font_api(), Font_LoadMap(), ft2_font_t::font_maps, MAX_FONT_SIZES, and NULL.

◆ Font_LoadSize()

static qbool Font_LoadSize ( ft2_font_t * font,
float size,
qbool check_only )
static

Definition at line 911 of file ft2.c.

912{
913 int map_index;
914 ft2_font_map_t *fmap, temp;
915 int gpad_l, gpad_r, gpad_t, gpad_b;
916
917 if (!(size > 0.001f && size < 1000.0f))
918 size = 0;
919
920 if (!size)
921 size = 16;
922 if (size < 2) // bogus sizes are not allowed - and they screw up our allocations
923 return false;
924
925 for (map_index = 0; map_index < MAX_FONT_SIZES; ++map_index)
926 {
927 if (!font->font_maps[map_index])
928 break;
929 // if a similar size has already been loaded, ignore this one
930 //abs(font->font_maps[map_index]->size - size) < 4
931 if (font->font_maps[map_index]->size == size)
932 return true;
933 }
934
935 if (map_index >= MAX_FONT_SIZES)
936 return false;
937
938 if (check_only) {
939 FT_Face fontface;
940 if (font->image_font)
941 fontface = (FT_Face)font->next->face;
942 else
943 fontface = (FT_Face)font->face;
944 return (Font_SearchSize(font, fontface, size) > 0);
945 }
946
947 Font_Postprocess(font, NULL, 0, 4, size*2, size*2, &gpad_l, &gpad_r, &gpad_t, &gpad_b);
948
949 memset(&temp, 0, sizeof(temp));
950 temp.size = size;
951 temp.glyphSize = size*2 + max(gpad_l + gpad_r, gpad_t + gpad_b);
953 temp.glyphSize = CeilPowerOf2(temp.glyphSize);
954 temp.sfx = (1.0/64.0)/(double)size;
955 temp.sfy = (1.0/64.0)/(double)size;
956 temp.intSize = -1; // negative value: LoadMap must search now :)
957 if (!Font_LoadMap(font, &temp, 0, &fmap, NULL, false))
958 {
959 Con_Printf(CON_ERROR "ERROR: can't load the first character map for %s\n"
960 "This is fatal\n",
961 font->name);
962 Font_UnloadFont(font);
963 return false;
964 }
965 font->font_maps[map_index] = temp.next;
966
967 fmap->sfx = temp.sfx;
968 fmap->sfy = temp.sfy;
969
970 // load the default kerning vector:
971 if (font->has_kerning)
972 {
973 Uchar l, r;
974 FT_Vector kernvec;
975 fmap->kerning = (ft2_kerning_t *)Mem_Alloc(font_mempool, sizeof(ft2_kerning_t));
976 for (l = 0; l < 256; ++l)
977 {
978 for (r = 0; r < 256; ++r)
979 {
980 FT_ULong ul, ur;
981 ul = qFT_Get_Char_Index((FT_Face)font->face, l);
982 ur = qFT_Get_Char_Index((FT_Face)font->face, r);
983 if (qFT_Get_Kerning((FT_Face)font->face, ul, ur, FT_KERNING_DEFAULT, &kernvec))
984 {
985 fmap->kerning->kerning[l][r][0] = 0;
986 fmap->kerning->kerning[l][r][1] = 0;
987 }
988 else
989 {
990 fmap->kerning->kerning[l][r][0] = Font_SnapTo((kernvec.x / 64.0) / fmap->size, 1 / fmap->size);
991 fmap->kerning->kerning[l][r][1] = Font_SnapTo((kernvec.y / 64.0) / fmap->size, 1 / fmap->size);
992 }
993 }
994 }
995 }
996 return true;
997}
unsigned int CeilPowerOf2(unsigned int value)
returns the smallest integer greater than or equal to "value", or 0 if "value" is too big
Definition mathlib.c:292
#define max(A, B)
Definition mathlib.h:38
dp_FragColor r

References CeilPowerOf2(), CON_ERROR, Con_Printf(), ft2_font_t::face, Font_LoadMap(), ft2_font_t::font_maps, font_mempool, Font_Postprocess(), Font_SearchSize(), Font_SnapTo(), Font_UnloadFont(), FT_KERNING_DEFAULT, ft2_font_t::has_kerning, ft2_font_t::image_font, cvar_t::integer, max, MAX_FONT_SIZES, Mem_Alloc, ft2_font_t::name, ft2_font_t::next, NULL, qFT_Get_Char_Index, qFT_Get_Kerning, r, r_font_nonpoweroftwo, size, FT_Vector::x, and FT_Vector::y.

Referenced by Font_LoadFont().

◆ Font_MapForIndex()

ft2_font_map_t * Font_MapForIndex ( ft2_font_t * font,
int index )

Definition at line 1052 of file ft2.c.

1053{
1055 return NULL;
1056 return font->font_maps[index];
1057}
GLuint index
Definition glquake.h:629

References ft2_font_t::font_maps, index, MAX_FONT_SIZES, and NULL.

Referenced by DrawQ_String_Scale(), DrawQ_TextWidth_UntilWidth_TrackColors_Scale(), Font_GetMapForChar(), and LoadFont().

◆ font_newmap()

void font_newmap ( void )

Definition at line 439 of file ft2.c.

440{
441}

Referenced by gl_draw_newmap().

◆ Font_OpenLibrary()

qbool Font_OpenLibrary ( void )

Definition at line 362 of file ft2.c.

363{
364#ifndef DP_FREETYPE_STATIC
365 const char* dllnames [] =
366 {
367#if defined(WIN32)
368 "libfreetype-6.dll",
369 "freetype6.dll",
370#elif defined(MACOSX)
371 "libfreetype.6.dylib",
372 "libfreetype.dylib",
373#else
374 "libfreetype.so.6",
375 "libfreetype.so",
376#endif
377 NULL
378 };
379#endif
380
382 return false;
383
384#ifndef DP_FREETYPE_STATIC
385 // Already loaded?
386 if (ft2_dll)
387 return true;
388
389 // Load the DLL
390 if (!Sys_LoadDependency (dllnames, &ft2_dll, ft2funcs))
391 return false;
392#endif
393 return true;
394}
static dllfunction_t ft2funcs[]
Definition ft2.c:138
qbool Sys_LoadDependency(const char **dllnames, dllhandle_t *handle, const dllfunction_t *fcts)
Definition sys_shared.c:131

References ft2_dll, ft2funcs, cvar_t::integer, NULL, r_font_disable_freetype, and Sys_LoadDependency().

Referenced by Font_Init(), Font_LoadFile(), and font_start().

◆ Font_Postprocess()

static void Font_Postprocess ( ft2_font_t * fnt,
unsigned char * imagedata,
int pitch,
int bpp,
int w,
int h,
int * pad_l,
int * pad_r,
int * pad_t,
int * pad_b )
static

Definition at line 787 of file ft2.c.

788{
789 int x, y;
790
791 // calculate gauss table
792 Font_Postprocess_Update(fnt, bpp, w, h);
793
794 if(imagedata)
795 {
796 // enlarge buffer
797 // perform operation, not exceeding the passed padding values,
798 // but possibly reducing them
799 *pad_l = min(*pad_l, pp.padding_l);
800 *pad_r = min(*pad_r, pp.padding_r);
801 *pad_t = min(*pad_t, pp.padding_t);
802 *pad_b = min(*pad_b, pp.padding_b);
803
804 // outline the font (RGBA only)
805 if(bpp == 4 && (pp.outline > 0 || pp.blur > 0 || pp.shadowx != 0 || pp.shadowy != 0 || pp.shadowz != 0)) // we can only do this in BGRA
806 {
807 // this is like mplayer subtitle rendering
808 // bbuffer, bitmap buffer: this is our font
809 // abuffer, alpha buffer: this is pp.buf
810 // tmp: this is pp.buf2
811
812 // create outline buffer
813 memset(pp.buf, 0, pp.bufwidth * pp.bufheight);
814 for(y = -*pad_t; y < h + *pad_b; ++y)
815 for(x = -*pad_l; x < w + *pad_r; ++x)
816 {
817 int x1 = max(-x, -pp.outlinepadding_r);
818 int y1 = max(-y, -pp.outlinepadding_b);
819 int x2 = min(pp.outlinepadding_l, w-1-x);
820 int y2 = min(pp.outlinepadding_t, h-1-y);
821 int mx, my;
822 int cur = 0;
823 int highest = 0;
824 for(my = y1; my <= y2; ++my)
825 for(mx = x1; mx <= x2; ++mx)
826 {
827 cur = pp.circlematrix[POSTPROCESS_MAXRADIUS+my][POSTPROCESS_MAXRADIUS+mx] * (int)imagedata[(x+mx) * bpp + pitch * (y+my) + (bpp - 1)];
828 if(cur > highest)
829 highest = cur;
830 }
831 pp.buf[((x + pp.padding_l) + pp.bufpitch * (y + pp.padding_t))] = (highest + 128) / 255;
832 }
833
834 // blur the outline buffer
835 if(pp.blur > 0 || pp.shadowz != 0)
836 {
837 // horizontal blur
838 for(y = 0; y < pp.bufheight; ++y)
839 for(x = 0; x < pp.bufwidth; ++x)
840 {
841 int x1 = max(-x, -pp.blurpadding_rb);
842 int x2 = min(pp.blurpadding_lt, pp.bufwidth-1-x);
843 int mx;
844 int blurred = 0;
845 for(mx = x1; mx <= x2; ++mx)
846 blurred += pp.gausstable[POSTPROCESS_MAXRADIUS+mx] * (int)pp.buf[(x+mx) + pp.bufpitch * y];
847 pp.buf2[x + pp.bufpitch * y] = bound(0, blurred, 65025) / 255;
848 }
849
850 // vertical blur
851 for(y = 0; y < pp.bufheight; ++y)
852 for(x = 0; x < pp.bufwidth; ++x)
853 {
854 int y1 = max(-y, -pp.blurpadding_rb);
855 int y2 = min(pp.blurpadding_lt, pp.bufheight-1-y);
856 int my;
857 int blurred = 0;
858 for(my = y1; my <= y2; ++my)
859 blurred += pp.gausstable[POSTPROCESS_MAXRADIUS+my] * (int)pp.buf2[x + pp.bufpitch * (y+my)];
860 pp.buf[x + pp.bufpitch * y] = bound(0, blurred, 65025) / 255;
861 }
862 }
863
864 // paste the outline below the font
865 for(y = -*pad_t; y < h + *pad_b; ++y)
866 for(x = -*pad_l; x < w + *pad_r; ++x)
867 {
868 unsigned char outlinealpha = pp.buf[(x + pp.padding_l) + pp.bufpitch * (y + pp.padding_t)];
869 if(outlinealpha > 0)
870 {
871 unsigned char oldalpha = imagedata[x * bpp + pitch * y + (bpp - 1)];
872 // a' = 1 - (1 - a1) (1 - a2)
873 unsigned char newalpha = 255 - ((255 - (int)outlinealpha) * (255 - (int)oldalpha)) / 255; // this is >= oldalpha
874 // c' = (a2 c2 - a1 a2 c1 + a1 c1) / a' = (a2 c2 + a1 (1 - a2) c1) / a'
875 unsigned char oldfactor = (255 * (int)oldalpha) / newalpha;
876 //unsigned char outlinefactor = ((255 - oldalpha) * (int)outlinealpha) / newalpha;
877 int i;
878 for(i = 0; i < bpp-1; ++i)
879 {
880 unsigned char c = imagedata[x * bpp + pitch * y + i];
881 c = (c * (int)oldfactor) / 255 /* + outlinecolor[i] * (int)outlinefactor */;
882 imagedata[x * bpp + pitch * y + i] = c;
883 }
884 imagedata[x * bpp + pitch * y + (bpp - 1)] = newalpha;
885 }
886 //imagedata[x * bpp + pitch * y + (bpp - 1)] |= 0x80;
887 }
888 }
889 }
890 else if(pitch)
891 {
892 // perform operation, not exceeding the passed padding values,
893 // but possibly reducing them
894 *pad_l = min(*pad_l, pp.padding_l);
895 *pad_r = min(*pad_r, pp.padding_r);
896 *pad_t = min(*pad_t, pp.padding_t);
897 *pad_b = min(*pad_b, pp.padding_b);
898 }
899 else
900 {
901 // just calculate parameters
902 *pad_l = pp.padding_l;
903 *pad_r = pp.padding_r;
904 *pad_t = pp.padding_t;
905 *pad_b = pp.padding_b;
906 }
907}
static int(ZEXPORT *qz_inflate)(z_stream *strm
static void Font_Postprocess_Update(ft2_font_t *fnt, int bpp, int w, int h)
Definition ft2.c:733
#define POSTPROCESS_MAXRADIUS
Definition ft2.c:246
#define min(A, B)
Definition mathlib.h:37
#define bound(min, num, max)
Definition mathlib.h:34
vec3 y2
vec3 x2
vec3 x1
int outlinepadding_t
Definition ft2.c:252
int outlinepadding_r
Definition ft2.c:252
float shadowx
Definition ft2.c:251
float outline
Definition ft2.c:251
unsigned char * buf2
Definition ft2.c:249
int outlinepadding_b
Definition ft2.c:252
int outlinepadding_l
Definition ft2.c:252
float shadowy
Definition ft2.c:251
float shadowz
Definition ft2.c:251
int blurpadding_rb
Definition ft2.c:252
int blurpadding_lt
Definition ft2.c:252
unsigned char circlematrix[2 *POSTPROCESS_MAXRADIUS+1][2 *POSTPROCESS_MAXRADIUS+1]
Definition ft2.c:253
unsigned char gausstable[2 *POSTPROCESS_MAXRADIUS+1]
Definition ft2.c:254

References font_postprocess_t::blur, font_postprocess_t::blurpadding_lt, font_postprocess_t::blurpadding_rb, bound, font_postprocess_t::buf, font_postprocess_t::buf2, font_postprocess_t::bufheight, font_postprocess_t::bufpitch, font_postprocess_t::bufwidth, font_postprocess_t::circlematrix, Font_Postprocess_Update(), font_postprocess_t::gausstable, i, int(), max, min, font_postprocess_t::outline, font_postprocess_t::outlinepadding_b, font_postprocess_t::outlinepadding_l, font_postprocess_t::outlinepadding_r, font_postprocess_t::outlinepadding_t, font_postprocess_t::padding_b, font_postprocess_t::padding_l, font_postprocess_t::padding_r, font_postprocess_t::padding_t, POSTPROCESS_MAXRADIUS, pp, font_postprocess_t::shadowx, font_postprocess_t::shadowy, font_postprocess_t::shadowz, w, x, x1, x2, y, and y2.

Referenced by Font_LoadMap(), and Font_LoadSize().

◆ Font_Postprocess_Update()

static void Font_Postprocess_Update ( ft2_font_t * fnt,
int bpp,
int w,
int h )
static

Definition at line 733 of file ft2.c.

734{
735 int needed, x, y;
736 float gausstable[2*POSTPROCESS_MAXRADIUS+1];
737 qbool need_gauss = (!pp.buf || pp.blur != fnt->settings->blur || pp.shadowz != fnt->settings->shadowz);
738 qbool need_circle = (!pp.buf || pp.outline != fnt->settings->outline || pp.shadowx != fnt->settings->shadowx || pp.shadowy != fnt->settings->shadowy);
739 pp.blur = fnt->settings->blur;
740 pp.outline = fnt->settings->outline;
741 pp.shadowx = fnt->settings->shadowx;
742 pp.shadowy = fnt->settings->shadowy;
743 pp.shadowz = fnt->settings->shadowz;
754 if(need_gauss)
755 {
756 float sum = 0;
758 gausstable[POSTPROCESS_MAXRADIUS+x] = (pp.blur > 0 ? exp(-(pow(x + pp.shadowz, 2))/(pp.blur*pp.blur * 2)) : (floor(x + pp.shadowz + 0.5) == 0));
759 for(x = -pp.blurpadding_rb; x <= pp.blurpadding_lt; ++x)
760 sum += gausstable[POSTPROCESS_MAXRADIUS+x];
762 pp.gausstable[POSTPROCESS_MAXRADIUS+x] = floor(gausstable[POSTPROCESS_MAXRADIUS+x] / sum * 255 + 0.5);
763 }
764 if(need_circle)
765 {
768 {
769 float d = pp.outline + 1 - sqrt(pow(x + pp.shadowx, 2) + pow(y + pp.shadowy, 2));
770 pp.circlematrix[POSTPROCESS_MAXRADIUS+y][POSTPROCESS_MAXRADIUS+x] = (d >= 1) ? 255 : (d <= 0) ? 0 : floor(d * 255 + 0.5);
771 }
772 }
776 needed = pp.bufwidth * pp.bufheight;
777 if(!pp.buf || pp.bufsize < needed * 2)
778 {
779 if(pp.buf)
780 Mem_Free(pp.buf);
781 pp.bufsize = needed * 4;
782 pp.buf = (unsigned char *)Mem_Alloc(font_mempool, pp.bufsize);
783 pp.buf2 = pp.buf + needed;
784 }
785}
float pow(float a, float b)
float ceil(float f)
float sqrt(float f)
float floor(float f)
float shadowy
Definition draw.h:91
float outline
Definition draw.h:91
float shadowz
Definition draw.h:91
float shadowx
Definition draw.h:91
float blur
Definition draw.h:91

References font_postprocess_t::blur, ft2_settings_t::blur, font_postprocess_t::blurpadding_lt, font_postprocess_t::blurpadding_rb, bound, font_postprocess_t::buf, font_postprocess_t::buf2, font_postprocess_t::bufheight, font_postprocess_t::bufpitch, font_postprocess_t::bufsize, font_postprocess_t::bufwidth, ceil(), font_postprocess_t::circlematrix, floor(), font_mempool, font_postprocess_t::gausstable, Mem_Alloc, Mem_Free, font_postprocess_t::outline, ft2_settings_t::outline, font_postprocess_t::outlinepadding_b, font_postprocess_t::outlinepadding_l, font_postprocess_t::outlinepadding_r, font_postprocess_t::outlinepadding_t, font_postprocess_t::padding_b, font_postprocess_t::padding_l, font_postprocess_t::padding_r, font_postprocess_t::padding_t, POSTPROCESS_MAXRADIUS, pow(), pp, ft2_font_t::settings, font_postprocess_t::shadowx, ft2_settings_t::shadowx, font_postprocess_t::shadowy, ft2_settings_t::shadowy, font_postprocess_t::shadowz, ft2_settings_t::shadowz, sqrt(), w, x, and y.

Referenced by Font_Postprocess().

◆ Font_SearchSize()

static float Font_SearchSize ( ft2_font_t * font,
FT_Face fontface,
float size )
static

Definition at line 1228 of file ft2.c.

1229{
1230 float intSize = size;
1231 while (1)
1232 {
1233 if (!Font_SetSize(font, intSize, intSize))
1234 {
1235 Con_Printf(CON_ERROR "ERROR: can't set size for font %s: %f ((%f))\n", font->name, size, intSize);
1236 return -1;
1237 }
1238 if ((fontface->size->metrics.height>>6) <= size)
1239 return intSize;
1240 if (intSize < 2)
1241 {
1242 Con_Printf(CON_ERROR "ERROR: no appropriate size found for font %s: %f\n", font->name, size);
1243 return -1;
1244 }
1245 --intSize;
1246 }
1247}

References CON_ERROR, Con_Printf(), Font_SetSize(), ft2_font_t::name, and size.

Referenced by Font_LoadMap(), and Font_LoadSize().

◆ Font_SetSize()

static qbool Font_SetSize ( ft2_font_t * font,
float w,
float h )
static

Definition at line 1059 of file ft2.c.

1060{
1061 if (font->currenth == h &&
1062 ((!w && (!font->currentw || font->currentw == font->currenth)) || // check if w==h when w is not set
1063 font->currentw == w)) // same size has been requested
1064 {
1065 return true;
1066 }
1067 // sorry, but freetype doesn't seem to care about other sizes
1068 w = (int)w;
1069 h = (int)h;
1070 if (font->image_font)
1071 {
1072 if (qFT_Set_Char_Size((FT_Face)font->next->face, (FT_F26Dot6)(w*64), (FT_F26Dot6)(h*64), 72, 72))
1073 return false;
1074 }
1075 else
1076 {
1077 if (qFT_Set_Char_Size((FT_Face)font->face, (FT_F26Dot6)(w*64), (FT_F26Dot6)(h*64), 72, 72))
1078 return false;
1079 }
1080 font->currentw = w;
1081 font->currenth = h;
1082 return true;
1083}
(* qFT_Set_Char_Size)(FT_Face face, FT_F26Dot6 char_width, FT_F26Dot6 char_height, FT_UInt horz_resolution, FT_UInt vert_resolution)
Definition ft2.c:100
signed long FT_F26Dot6
Definition ft2_defs.h:31
float currenth
Definition ft2.h:45
float currentw
Definition ft2.h:44

References ft2_font_t::currenth, ft2_font_t::currentw, ft2_font_t::face, ft2_font_t::image_font, int(), ft2_font_t::next, qFT_Set_Char_Size, and w.

Referenced by Font_GetKerningForMap(), Font_LoadMap(), and Font_SearchSize().

◆ font_shutdown()

void font_shutdown ( void )

Definition at line 425 of file ft2.c.

426{
427 int i;
428 for (i = 0; i < dp_fonts.maxsize; ++i)
429 {
430 if (dp_fonts.f[i].ft2)
431 {
433 dp_fonts.f[i].ft2 = NULL;
434 }
435 }
437}
dp_fonts_t dp_fonts
Definition gl_draw.c:50
void Font_CloseLibrary(void)
Definition ft2.c:339
int maxsize
Definition draw.h:121
dp_font_t * f
Definition draw.h:120

References dp_fonts, dp_fonts_t::f, Font_CloseLibrary(), Font_UnloadFont(), dp_font_t::ft2, i, dp_fonts_t::maxsize, and NULL.

Referenced by gl_draw_shutdown().

◆ Font_SnapTo()

float Font_SnapTo ( float val,
float snapwidth )

Definition at line 514 of file ft2.c.

515{
516 return floor(val / snapwidth + 0.5f) * snapwidth;
517}

References floor().

Referenced by Font_GetKerningForMap(), Font_LoadMap(), Font_LoadSize(), and LoadFont().

◆ font_start()

void font_start ( void )

Definition at line 404 of file ft2.c.

405{
406 if (!Font_OpenLibrary())
407 return;
408
410 {
411 Con_Print(CON_ERROR "ERROR: Failed to initialize the FreeType2 library!\n");
413 return;
414 }
415
416 font_mempool = Mem_AllocPool("FONT", 0, NULL);
417 if (!font_mempool)
418 {
419 Con_Print(CON_ERROR "ERROR: Failed to allocate FONT memory pool!\n");
421 return;
422 }
423}
void Con_Print(const char *msg)
Prints to all appropriate console targets, and adds timestamps.
Definition console.c:1504
(* qFT_Init_FreeType)(FT_Library *alibrary)
Definition ft2.c:75
#define Mem_AllocPool(name, flags, parent)
Definition zone.h:104

References CON_ERROR, Con_Print(), Font_CloseLibrary(), font_ft2lib, font_mempool, Font_OpenLibrary(), Mem_AllocPool, NULL, and qFT_Init_FreeType.

Referenced by gl_draw_start().

◆ Font_UnloadFont()

void Font_UnloadFont ( ft2_font_t * font)

Definition at line 1184 of file ft2.c.

1185{
1186 int i;
1187
1188 // unload fallbacks
1189 if(font->next)
1190 Font_UnloadFont(font->next);
1191
1192 if (font->attachments && font->attachmentcount)
1193 {
1194 for (i = 0; i < (int)font->attachmentcount; ++i) {
1195 if (font->attachments[i].data)
1196 fontfilecache_Free(font->attachments[i].data);
1197 }
1198 Mem_Free(font->attachments);
1199 font->attachmentcount = 0;
1200 font->attachments = NULL;
1201 }
1202 for (i = 0; i < MAX_FONT_SIZES; ++i)
1203 {
1204 if (font->font_maps[i])
1205 {
1206 UnloadMapChain(font->font_maps[i]);
1207 font->font_maps[i] = NULL;
1208 }
1209 }
1210#ifndef DP_FREETYPE_STATIC
1211 if (ft2_dll)
1212#else
1214#endif
1215 {
1216 if (font->face)
1217 {
1218 qFT_Done_Face((FT_Face)font->face);
1219 font->face = NULL;
1220 }
1221 }
1222 if (font->data) {
1223 fontfilecache_Free(font->data);
1224 font->data = NULL;
1225 }
1226}
static void UnloadMapChain(ft2_font_map_t *map)
Definition ft2.c:1150
static void fontfilecache_Free(const unsigned char *buf)
Definition ft2.c:301
(* qFT_Done_Face)(FT_Face face)
Definition ft2.c:92

References ft2_font_t::attachmentcount, ft2_font_t::attachments, ft2_font_t::data, ft2_font_t::face, ft2_font_t::font_maps, Font_UnloadFont(), fontfilecache_Free(), ft2_dll, i, int(), cvar_t::integer, MAX_FONT_SIZES, Mem_Free, ft2_font_t::next, NULL, qFT_Done_Face, r_font_disable_freetype, and UnloadMapChain().

Referenced by Font_LoadFile(), Font_LoadFont(), Font_LoadSize(), font_shutdown(), Font_UnloadFont(), and LoadFont().

◆ Font_VirtualToRealSize()

float Font_VirtualToRealSize ( float sz)

Definition at line 496 of file ft2.c.

497{
498 int vh;
499 //int vw;
500 int si;
501 float sn;
502 if(sz < 0)
503 return sz;
504 //vw = ((vid.width > 0) ? vid.width : vid_width.value);
505 vh = ((vid.mode.height > 0) ? vid.mode.height : vid_height.value);
506 // now try to scale to our actual size:
507 sn = sz * vh / vid_conheight.value;
508 si = (int)sn;
509 if ( sn - (float)si >= 0.5 )
510 ++si;
511 return si;
512}
cvar_t vid_height
Definition vid_shared.c:137

References viddef_mode_t::height, int(), viddef_t::mode, cvar_t::value, vid, vid_conheight, and vid_height.

Referenced by Font_LoadFont().

◆ fontfilecache_Free()

static void fontfilecache_Free ( const unsigned char * buf)
static

Definition at line 301 of file ft2.c.

302{
303 int i;
304 for(i = 0; i < MAX_FONTFILES; ++i)
305 {
306 if(fontfiles[i].refcount > 0)
307 if(fontfiles[i].buf == buf)
308 {
309 if(--fontfiles[i].refcount <= 0)
310 {
312 fontfiles[i].buf = NULL;
313 }
314 return;
315 }
316 }
317 // if we get here, it used regular allocation
318 Mem_Free((void *) buf);
319}
#define MAX_FONTFILES
Definition ft2.c:267
static fontfilecache_t fontfiles[MAX_FONTFILES]
Definition ft2.c:268
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition glquake.h:657
unsigned char * buf
Definition ft2.c:261

References buf, fontfilecache_t::buf, fontfiles, i, MAX_FONTFILES, Mem_Free, and NULL.

Referenced by Font_UnloadFont().

◆ fontfilecache_FreeAll()

static void fontfilecache_FreeAll ( void )
static

Definition at line 320 of file ft2.c.

321{
322 int i;
323 for(i = 0; i < MAX_FONTFILES; ++i)
324 {
325 if(fontfiles[i].refcount > 0)
327 fontfiles[i].buf = NULL;
328 fontfiles[i].refcount = 0;
329 }
330}
int refcount
Definition ft2.c:263

References buf, fontfilecache_t::buf, fontfiles, i, MAX_FONTFILES, Mem_Free, NULL, and fontfilecache_t::refcount.

Referenced by Font_CloseLibrary().

◆ fontfilecache_LoadFile()

static const unsigned char * fontfilecache_LoadFile ( const char * path,
qbool quiet,
fs_offset_t * filesizepointer )
static

Definition at line 269 of file ft2.c.

270{
271 int i;
272 unsigned char *buf;
273
274 for(i = 0; i < MAX_FONTFILES; ++i)
275 {
276 if(fontfiles[i].refcount > 0)
277 if(!strcmp(path, fontfiles[i].path))
278 {
279 *filesizepointer = fontfiles[i].len;
281 return fontfiles[i].buf;
282 }
283 }
284
285 buf = FS_LoadFile(path, font_mempool, quiet, filesizepointer);
286 if(buf)
287 {
288 for(i = 0; i < MAX_FONTFILES; ++i)
289 if(fontfiles[i].refcount <= 0)
290 {
291 dp_strlcpy(fontfiles[i].path, path, sizeof(fontfiles[i].path));
292 fontfiles[i].len = *filesizepointer;
293 fontfiles[i].buf = buf;
294 fontfiles[i].refcount = 1;
295 return buf;
296 }
297 }
298
299 return buf;
300}
unsigned char * FS_LoadFile(const char *path, mempool_t *pool, qbool quiet, fs_offset_t *filesizepointer)
Definition fs.c:3540
fs_offset_t len
Definition ft2.c:262

References buf, fontfilecache_t::buf, dp_strlcpy, font_mempool, fontfiles, FS_LoadFile(), i, fontfilecache_t::len, MAX_FONTFILES, and fontfilecache_t::refcount.

Referenced by Font_LoadFile().

◆ FontMap_FindForChar()

ft2_font_map_t * FontMap_FindForChar ( ft2_font_map_t * start,
Uchar ch )

Definition at line 1911 of file ft2.c.

1912{
1913 ft2_font_map_t *map = start;
1914 while (map && map->start + FONT_CHARS_PER_MAP <= ch)
1915 map = map->next;
1916 if (map && map->start > ch)
1917 return NULL;
1918 alert_legacy_font_api("FontMap_FindForChar");
1919 return map;
1920}

References alert_legacy_font_api(), FONT_CHARS_PER_MAP, and NULL.

◆ get_char_from_incmap()

static qbool get_char_from_incmap ( ft2_font_map_t * map,
Uchar ch,
ft2_font_map_t ** outmap,
int * outmapch )
inlinestatic

Definition at line 1936 of file ft2.c.

1937{
1938 int i;
1939 font_incmap_t *incmap;
1940
1941 incmap = map->incmap;
1942 *outmapch = 0;
1943
1944 if (incmap != NULL)
1945 {
1946 map = incmap->fontmap;
1947 while (map != NULL)
1948 {
1949 for (i = 0; i < FONT_CHARS_PER_MAP; ++i)
1950 {
1951 if (map->glyphchars[i] == ch)
1952 {
1953 *outmap = map;
1954 *outmapch = i;
1955 return true;
1956 }
1957 else if (map->glyphchars[i] == 0)
1958 // this tier0/tier1 map ends here
1959 break;
1960 }
1961 map = map->next;
1962 }
1963 }
1964 return false;
1965}

References FONT_CHARS_PER_MAP, i, and NULL.

Referenced by Font_GetMapForChar().

◆ incmap_post_process()

static void incmap_post_process ( font_incmap_t * incmap,
Uchar ch,
unsigned char * data,
ft2_font_map_t ** outmap,
int * outmapch )
inlinestatic

Definition at line 1283 of file ft2.c.

1285{
1286 #define bytes_per_pixel 4
1287
1288 int index, targetmap_at;
1289 // where will the next `data` be placed
1290 int tier1_data_index, tier2_data_index;
1291 // metrics of data to manipulate
1292 int width, height, pitch, datasize;
1293 int i, j, x, y;
1294 unsigned char *newdata, *chunk;
1295 ft2_font_map_t *startmap, *targetmap, *currentmap;
1296 #define M FONT_CHARS_PER_LINE
1297 #define N FONT_CHAR_LINES
1298
1299 startmap = incmap->fontmap;
1300 index = incmap->charcount;
1301 tier1_data_index = index % M;
1302 tier2_data_index = incmap->tier1_merged;
1303
1304 incmap->data_tier1[tier1_data_index] = data;
1305
1306 if (index % M == M - 1)
1307 {
1308 // tier 1 reduction, pieces to line
1309 calc_data_arguments(1, 1);
1310 targetmap_at = incmap->tier2_merged + incmap->tier1_merged;
1311 targetmap = startmap;
1312 for (i = 0; i < targetmap_at; ++i)
1313 targetmap = targetmap->next;
1314 currentmap = targetmap;
1315 newdata = (unsigned char *)Mem_Alloc(font_mempool, datasize * M);
1316 for (i = 0; i < M; ++i)
1317 {
1318 chunk = incmap->data_tier1[i];
1319 if (chunk == NULL)
1320 continue;
1321 for (y = 0; y < datasize; y += pitch)
1322 for (x = 0; x < pitch; ++x)
1323 newdata[y * M + i * pitch + x] = chunk[y + x];
1324 Mem_Free(chunk);
1325 incmap->data_tier1[i] = NULL;
1326 merge_single_map(targetmap, i, currentmap, 0);
1327 fix_glyph_coords_tier1(&targetmap->glyphs[i], (float)i);
1328 currentmap = currentmap->next;
1329 }
1330 update_pic_for_fontmap(targetmap, Draw_GetPicName(targetmap->pic), width * M, height, newdata);
1331 UnloadMapChain(targetmap->next);
1332 targetmap->next = NULL;
1333 incmap->data_tier2[tier2_data_index] = newdata;
1334 ++incmap->tier1_merged;
1335 incmap->tier1_merged %= M;
1336 incmap->newmap_start = INCMAP_START + targetmap_at + 1;
1337 // then give this merged map
1338 *outmap = targetmap;
1339 *outmapch = FONT_CHARS_PER_LINE - 1;
1340 }
1341 if (index % (M * N) == M * N - 1)
1342 {
1343 // tier 2 reduction, lines to full map
1345 targetmap_at = incmap->tier2_merged;
1346 targetmap = startmap;
1347 for (i = 0; i < targetmap_at; ++i)
1348 targetmap = targetmap->next;
1349 currentmap = targetmap;
1350 newdata = (unsigned char *)Mem_Alloc(font_mempool, datasize * N);
1351 for (i = 0; i < N; ++i)
1352 {
1353 chunk = incmap->data_tier2[i];
1354 if (chunk == NULL)
1355 continue;
1356 for (x = 0; x < datasize; ++x)
1357 newdata[i * datasize + x] = chunk[x];
1358 Mem_Free(chunk);
1359 incmap->data_tier2[i] = NULL;
1360 for (j = 0; j < M; ++j)
1361 {
1362 merge_single_map(targetmap, i * M + j, currentmap, j);
1363 fix_glyph_coords_tier2(&targetmap->glyphs[i * M + j], (float)i);
1364 }
1365 currentmap = currentmap->next;
1366 }
1367 update_pic_for_fontmap(targetmap, Draw_GetPicName(targetmap->pic), width, height * N, newdata);
1368 UnloadMapChain(targetmap->next);
1369 targetmap->next = NULL;
1370 Mem_Free(newdata);
1371 ++incmap->tier2_merged;
1372 incmap->newmap_start = INCMAP_START + targetmap_at + 1;
1373 // then give this merged map
1374 *outmap = targetmap;
1375 *outmapch = FONT_CHARS_PER_MAP - 1;
1376 }
1377
1378 ++incmap->charcount;
1379 ++incmap->newmap_start;
1380
1381 #undef M
1382 #undef N
1383}
const char * Draw_GetPicName(cachepic_t *pic)
Definition gl_draw.c:190
#define N
#define fix_glyph_coords_tier2(glyph, order)
Definition ft2.c:1267
#define M
static void merge_single_map(ft2_font_map_t *targetmap, int targetindex, ft2_font_map_t *sourcemap, int sourceindex)
Definition ft2.c:1270
#define calc_data_arguments(w, h)
Definition ft2.c:1276
#define fix_glyph_coords_tier1(glyph, order)
Definition ft2.c:1266

References calc_data_arguments, data, Draw_GetPicName(), fix_glyph_coords_tier1, fix_glyph_coords_tier2, FONT_CHARS_PER_LINE, FONT_CHARS_PER_MAP, font_mempool, height, i, INCMAP_START, index, M, Mem_Alloc, Mem_Free, merge_single_map(), N, NULL, UnloadMapChain(), update_pic_for_fontmap(), width, x, and y.

Referenced by Font_LoadMap().

◆ merge_single_map()

static void merge_single_map ( ft2_font_map_t * targetmap,
int targetindex,
ft2_font_map_t * sourcemap,
int sourceindex )
inlinestatic

Definition at line 1270 of file ft2.c.

1271{
1272 targetmap->glyphs[targetindex] = sourcemap->glyphs[sourceindex];
1273 targetmap->glyphchars[targetindex] = sourcemap->glyphchars[sourceindex];
1274}

Referenced by incmap_post_process().

◆ should_use_incmap()

static qbool should_use_incmap ( Uchar ch)
inlinestatic

Definition at line 1922 of file ft2.c.

1923{
1924 int i;
1925 // optimize: a simple check logic for usual conditions
1926 if (ch < unicode_bigblocks[0])
1927 return false;
1929 return false;
1930 for (i = 0; i < (int)(sizeof(unicode_bigblocks) / sizeof(Uchar)); i += 2)
1931 if (unicode_bigblocks[i] <= ch && ch <= unicode_bigblocks[i + 1])
1932 return true;
1933 return false;
1934}
static const Uchar unicode_bigblocks[]
Definition ft2.c:41

References i, int(), cvar_t::integer, r_font_disable_incmaps, and unicode_bigblocks.

Referenced by Font_GetMapForChar().

◆ transform_glyph_coords()

static void transform_glyph_coords ( glyph_slot_t * glyph,
float shiftx,
float shifty,
float scalex,
float scaley )
inlinestatic

Definition at line 1259 of file ft2.c.

1260{
1261 glyph->txmin = glyph->txmin * scalex + shiftx;
1262 glyph->txmax = glyph->txmax * scalex + shiftx;
1263 glyph->tymin = glyph->tymin * scaley + shifty;
1264 glyph->tymax = glyph->tymax * scaley + shifty;
1265}

References glyph_slot_t::txmax, glyph_slot_t::txmin, glyph_slot_t::tymax, and glyph_slot_t::tymin.

◆ UnloadMapChain()

static void UnloadMapChain ( ft2_font_map_t * map)
static

Definition at line 1150 of file ft2.c.

1151{
1152 int i;
1153 ft2_font_map_t *nextmap;
1154 // these may only be in a startmap
1155 if (map->kerning != NULL)
1156 Mem_Free(map->kerning);
1157 if (map->incmap != NULL)
1158 {
1159 for (i = 0; i < FONT_CHARS_PER_LINE; ++i)
1160 if (map->incmap->data_tier1[i] != NULL)
1161 Mem_Free(map->incmap->data_tier1[i]);
1162 else
1163 break;
1164 for (i = 0; i < FONT_CHAR_LINES; ++i)
1165 if (map->incmap->data_tier2[i] != NULL)
1166 Mem_Free(map->incmap->data_tier2[i]);
1167 else
1168 break;
1169 Mem_Free(map->incmap);
1170 }
1171 while (map != NULL)
1172 {
1173 if (map->pic)
1174 {
1175 //Draw_FreePic(map->pic); // FIXME: refcounting needed...
1176 map->pic = NULL;
1177 }
1178 nextmap = map->next;
1179 Mem_Free(map);
1180 map = nextmap;
1181 }
1182}

References FONT_CHAR_LINES, FONT_CHARS_PER_LINE, i, Mem_Free, and NULL.

Referenced by Font_UnloadFont(), and incmap_post_process().

◆ update_pic_for_fontmap()

static void update_pic_for_fontmap ( ft2_font_map_t * fontmap,
const char * identifier,
int width,
int height,
unsigned char * data )
inlinestatic

Definition at line 1251 of file ft2.c.

1253{
1254 fontmap->pic = Draw_NewPic(identifier, width, height, data, TEXTYPE_RGBA,
1256}
cachepic_t * Draw_NewPic(const char *picname, int width, int height, unsigned char *pixels, textype_t textype, int texflags)
Definition gl_draw.c:256
#define TEXF_ALPHA
Definition r_textures.h:9
#define TEXF_COMPRESS
Definition r_textures.h:23
@ TEXTYPE_RGBA
Definition r_textures.h:51
#define TEXF_CLAMP
Definition r_textures.h:15

References data, Draw_NewPic(), height, cvar_t::integer, r_font_compress, TEXF_ALPHA, TEXF_CLAMP, TEXF_COMPRESS, TEXTYPE_RGBA, and width.

Referenced by Font_LoadMap(), and incmap_post_process().

Variable Documentation

◆ developer_font

cvar_t developer_font = {CF_CLIENT | CF_ARCHIVE, "developer_font", "0", "prints debug messages about fonts"}

Definition at line 61 of file ft2.c.

61{CF_CLIENT | CF_ARCHIVE, "developer_font", "0", "prints debug messages about fonts"};
#define CF_CLIENT
cvar/command that only the client can change/execute
Definition cmd.h:48
#define CF_ARCHIVE
cvar should have its set value saved to config.cfg and persist across sessions
Definition cmd.h:53

Referenced by FindFont(), Font_Init(), and Font_LoadMap().

◆ font_ft2lib

FT_Library font_ft2lib = NULL
static

FreeType library handle.

Definition at line 244 of file ft2.c.

Referenced by Font_CloseLibrary(), Font_LoadFile(), and font_start().

◆ font_mempool

◆ fontfiles

fontfilecache_t fontfiles[MAX_FONTFILES]
static

Definition at line 268 of file ft2.c.

Referenced by fontfilecache_Free(), fontfilecache_FreeAll(), and fontfilecache_LoadFile().

◆ ft2_dll

dllhandle_t ft2_dll = NULL
static

Handle for FreeType2 DLL.

Definition at line 159 of file ft2.c.

Referenced by Font_Alloc(), Font_CloseLibrary(), Font_OpenLibrary(), and Font_UnloadFont().

◆ ft2funcs

dllfunction_t ft2funcs[]
static
Initial value:
=
{
{"FT_Init_FreeType", (void **) &qFT_Init_FreeType},
{"FT_Done_FreeType", (void **) &qFT_Done_FreeType},
{"FT_New_Memory_Face", (void **) &qFT_New_Memory_Face},
{"FT_Done_Face", (void **) &qFT_Done_Face},
{"FT_Select_Size", (void **) &qFT_Select_Size},
{"FT_Request_Size", (void **) &qFT_Request_Size},
{"FT_Set_Char_Size", (void **) &qFT_Set_Char_Size},
{"FT_Set_Pixel_Sizes", (void **) &qFT_Set_Pixel_Sizes},
{"FT_Load_Glyph", (void **) &qFT_Load_Glyph},
{"FT_Load_Char", (void **) &qFT_Load_Char},
{"FT_Get_Char_Index", (void **) &qFT_Get_Char_Index},
{"FT_Render_Glyph", (void **) &qFT_Render_Glyph},
{"FT_Get_Kerning", (void **) &qFT_Get_Kerning},
{"FT_Attach_Stream", (void **) &qFT_Attach_Stream},
}
(* qFT_Set_Pixel_Sizes)(FT_Face face, FT_UInt pixel_width, FT_UInt pixel_height)
Definition ft2.c:106
(* qFT_Select_Size)(FT_Face face, FT_Int strike_index)
Definition ft2.c:94
(* qFT_Render_Glyph)(FT_GlyphSlot slot, FT_Render_Mode render_mode)
Definition ft2.c:121
(* qFT_Load_Char)(FT_Face face, FT_ULong char_code, FT_Int32 load_flags)
Definition ft2.c:114
(* qFT_Request_Size)(FT_Face face, FT_Size_Request req)
Definition ft2.c:97

Definition at line 138 of file ft2.c.

139{
140 {"FT_Init_FreeType", (void **) &qFT_Init_FreeType},
141 {"FT_Done_FreeType", (void **) &qFT_Done_FreeType},
142 //{"FT_New_Face", (void **) &qFT_New_Face},
143 {"FT_New_Memory_Face", (void **) &qFT_New_Memory_Face},
144 {"FT_Done_Face", (void **) &qFT_Done_Face},
145 {"FT_Select_Size", (void **) &qFT_Select_Size},
146 {"FT_Request_Size", (void **) &qFT_Request_Size},
147 {"FT_Set_Char_Size", (void **) &qFT_Set_Char_Size},
148 {"FT_Set_Pixel_Sizes", (void **) &qFT_Set_Pixel_Sizes},
149 {"FT_Load_Glyph", (void **) &qFT_Load_Glyph},
150 {"FT_Load_Char", (void **) &qFT_Load_Char},
151 {"FT_Get_Char_Index", (void **) &qFT_Get_Char_Index},
152 {"FT_Render_Glyph", (void **) &qFT_Render_Glyph},
153 {"FT_Get_Kerning", (void **) &qFT_Get_Kerning},
154 {"FT_Attach_Stream", (void **) &qFT_Attach_Stream},
155 {NULL, NULL}
156};

Referenced by Font_OpenLibrary().

◆ img_fontmap

int img_fontmap[256]
static
Initial value:
= {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}

Definition at line 11 of file ft2.c.

11 {
12 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
13 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
14 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // shift+digit line
15 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // digits
16 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // caps
17 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // caps
18 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // small
19 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // small
20 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // specials
21 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // faces
22 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
23 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
24 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
25 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
26 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
27 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
28};

Referenced by Font_LoadMap().

◆ legacy_font_loading_api_alerted

qbool legacy_font_loading_api_alerted = false
static

Definition at line 1888 of file ft2.c.

Referenced by alert_legacy_font_api().

◆ pp

font_postprocess_t pp
static

Definition at line 257 of file ft2.c.

Referenced by Font_CloseLibrary(), Font_Postprocess(), and Font_Postprocess_Update().

◆ qFT_Attach_Stream

(* qFT_Attach_Stream) (FT_Face face, FT_Open_Args *parameters) ( FT_Face face,
FT_Open_Args * parameters )

Definition at line 63 of file ft2.c.

Referenced by Font_LoadFile().

◆ qFT_Done_Face

(* qFT_Done_Face) (FT_Face face) ( FT_Face face)

Definition at line 63 of file ft2.c.

Referenced by Font_UnloadFont().

◆ qFT_Done_FreeType

(* qFT_Done_FreeType) (FT_Library library) ( FT_Library library)

Definition at line 63 of file ft2.c.

Referenced by Font_CloseLibrary().

◆ qFT_Get_Char_Index

(* qFT_Get_Char_Index) (FT_Face face, FT_ULong charcode) ( FT_Face face,
FT_ULong charcode )

Definition at line 63 of file ft2.c.

Referenced by Font_GetKerningForMap(), Font_LoadMap(), and Font_LoadSize().

◆ qFT_Get_Kerning

(* qFT_Get_Kerning) (FT_Face face, FT_UInt left_glyph, FT_UInt right_glyph, FT_UInt kern_mode, FT_Vector *akerning) ( FT_Face face,
FT_UInt left_glyph,
FT_UInt right_glyph,
FT_UInt kern_mode,
FT_Vector * akerning )

Definition at line 63 of file ft2.c.

Referenced by Font_GetKerningForMap(), and Font_LoadSize().

◆ qFT_Init_FreeType

(* qFT_Init_FreeType) (FT_Library *alibrary) ( FT_Library * alibrary)

Definition at line 63 of file ft2.c.

Referenced by font_start().

◆ qFT_Load_Char

(* qFT_Load_Char) (FT_Face face, FT_ULong char_code, FT_Int32 load_flags) ( FT_Face face,
FT_ULong char_code,
FT_Int32 load_flags )

Definition at line 63 of file ft2.c.

◆ qFT_Load_Glyph

(* qFT_Load_Glyph) (FT_Face face, FT_UInt glyph_index, FT_Int32 load_flags) ( FT_Face face,
FT_UInt glyph_index,
FT_Int32 load_flags )

Definition at line 63 of file ft2.c.

Referenced by Font_LoadMap().

◆ qFT_New_Memory_Face

(* qFT_New_Memory_Face) (FT_Library library, const FT_Byte *file_base, FT_Long file_size, FT_Long face_index, FT_Face *aface) ( FT_Library library,
const FT_Byte * file_base,
FT_Long file_size,
FT_Long face_index,
FT_Face * aface )

Definition at line 63 of file ft2.c.

Referenced by Font_LoadFile().

◆ qFT_Render_Glyph

(* qFT_Render_Glyph) (FT_GlyphSlot slot, FT_Render_Mode render_mode) ( FT_GlyphSlot slot,
FT_Render_Mode render_mode )

Definition at line 63 of file ft2.c.

◆ qFT_Request_Size

(* qFT_Request_Size) (FT_Face face, FT_Size_Request req) ( FT_Face face,
FT_Size_Request req )

Definition at line 63 of file ft2.c.

◆ qFT_Select_Size

(* qFT_Select_Size) (FT_Face face, FT_Int strike_index) ( FT_Face face,
FT_Int strike_index )

Definition at line 63 of file ft2.c.

◆ qFT_Set_Char_Size

(* qFT_Set_Char_Size) (FT_Face face, FT_F26Dot6 char_width, FT_F26Dot6 char_height, FT_UInt horz_resolution, FT_UInt vert_resolution) ( FT_Face face,
FT_F26Dot6 char_width,
FT_F26Dot6 char_height,
FT_UInt horz_resolution,
FT_UInt vert_resolution )

Definition at line 63 of file ft2.c.

Referenced by Font_SetSize().

◆ qFT_Set_Pixel_Sizes

(* qFT_Set_Pixel_Sizes) (FT_Face face, FT_UInt pixel_width, FT_UInt pixel_height) ( FT_Face face,
FT_UInt pixel_width,
FT_UInt pixel_height )

Definition at line 63 of file ft2.c.

◆ r_font_compress

cvar_t r_font_compress = {CF_CLIENT | CF_ARCHIVE, "r_font_compress", "0", "use texture compression on font textures to save video memory"}

Definition at line 59 of file ft2.c.

59{CF_CLIENT | CF_ARCHIVE, "r_font_compress", "0", "use texture compression on font textures to save video memory"};

Referenced by Font_Init(), and update_pic_for_fontmap().

◆ r_font_disable_freetype

cvar_t r_font_disable_freetype = {CF_CLIENT | CF_ARCHIVE, "r_font_disable_freetype", "0", "disable freetype support for fonts entirely"}

Definition at line 55 of file ft2.c.

55{CF_CLIENT | CF_ARCHIVE, "r_font_disable_freetype", "0", "disable freetype support for fonts entirely"};

Referenced by Font_Alloc(), Font_Init(), Font_LoadFile(), Font_OpenLibrary(), and Font_UnloadFont().

◆ r_font_disable_incmaps

cvar_t r_font_disable_incmaps = {CF_CLIENT | CF_ARCHIVE, "r_font_disable_incmaps", "0", "always to load a full glyph map for individual unmapped character, even when it will mean extreme resources waste"}

Definition at line 63 of file ft2.c.

63{CF_CLIENT | CF_ARCHIVE, "r_font_disable_incmaps", "0", "always to load a full glyph map for individual unmapped character, even when it will mean extreme resources waste"};

Referenced by Font_Init(), and should_use_incmap().

◆ r_font_diskcache

cvar_t r_font_diskcache = {CF_CLIENT | CF_ARCHIVE, "r_font_diskcache", "0", "[deprecated, not effective] save font textures to disk for future loading rather than generating them every time"}

Definition at line 58 of file ft2.c.

58{CF_CLIENT | CF_ARCHIVE, "r_font_diskcache", "0", "[deprecated, not effective] save font textures to disk for future loading rather than generating them every time"};

Referenced by Font_Init().

◆ r_font_kerning

cvar_t r_font_kerning = {CF_CLIENT | CF_ARCHIVE, "r_font_kerning", "1", "Use kerning if available"}

Definition at line 57 of file ft2.c.

57{CF_CLIENT | CF_ARCHIVE, "r_font_kerning", "1", "Use kerning if available"};

Referenced by Font_GetKerningForMap(), and Font_Init().

◆ r_font_nonpoweroftwo

cvar_t r_font_nonpoweroftwo = {CF_CLIENT | CF_ARCHIVE, "r_font_nonpoweroftwo", "1", "use nonpoweroftwo textures for font (saves memory, potentially slower)"}

Definition at line 60 of file ft2.c.

60{CF_CLIENT | CF_ARCHIVE, "r_font_nonpoweroftwo", "1", "use nonpoweroftwo textures for font (saves memory, potentially slower)"};

Referenced by Font_Init(), and Font_LoadSize().

◆ r_font_size_snapping

cvar_t r_font_size_snapping = {CF_CLIENT | CF_ARCHIVE, "r_font_size_snapping", "1", "stick to good looking font sizes whenever possible - bad when the mod doesn't support it!"}

Definition at line 56 of file ft2.c.

56{CF_CLIENT | CF_ARCHIVE, "r_font_size_snapping", "1", "stick to good looking font sizes whenever possible - bad when the mod doesn't support it!"};

Referenced by Font_IndexForSize(), and Font_Init().

◆ unicode_bigblocks

const Uchar unicode_bigblocks[]
static
Initial value:
= {
0x3400, 0x4DBF,
0x4E00, 0x9FFF,
0xAC00, 0xD7AF,
0xE000, 0xF8FF,
0x10000, 0x10FFFF
}

Definition at line 41 of file ft2.c.

41 {
42 0x3400, 0x4DBF, // 6592 CJK Unified Ideographs Extension A
43 0x4E00, 0x9FFF, // 20992 CJK Unified Ideographs
44 0xAC00, 0xD7AF, // 11184 Hangul Syllables
45 0xE000, 0xF8FF, // 6400 Private Use Area
46 0x10000, 0x10FFFF // Everything above
47};

Referenced by should_use_incmap().