1 /**
2 * @file
3 */
4
5 /*
6 Copyright (C) 2002-2013 UFO: Alien Invasion.
7
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
17 See the GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22
23 */
24
25 #include "ui_main.h"
26 #include "ui_internal.h"
27 #include "ui_font.h"
28 #include "ui_parse.h"
29
30 #include "../cl_shared.h"
31 #include "../../shared/parse.h"
32 #include "../renderer/r_font.h"
33
34 #define MAX_FONTS 16
35 static int numFonts = 0;
36 static uiFont_t fonts[MAX_FONTS];
37
38 static const value_t fontValues[] = {
39 {"font", V_TRANSLATION_STRING, offsetof(uiFont_t, path), 0},
40 {"size", V_INT, offsetof(uiFont_t, size), MEMBER_SIZEOF(uiFont_t, size)},
41 {"style", V_HUNK_STRING, offsetof(uiFont_t, style), 0},
42
43 {nullptr, V_NULL, 0, 0}
44 };
45
46 /**
47 * @brief Registers a new TTF font
48 * @note The TTF font path is translated via gettext to be able to use different
49 * fonts for every translation
50 * @param[in] font Font to register
51 */
UI_RegisterFont(const uiFont_t * font)52 static void UI_RegisterFont (const uiFont_t* font)
53 {
54 const char* path = _(font->path);
55
56 if (!path)
57 Com_Error(ERR_FATAL, "...font without path (font %s)", font->name);
58
59 if (FS_CheckFile("%s", path) == -1)
60 Com_Error(ERR_FATAL, "...font file %s does not exist (font %s)", path, font->name);
61
62 R_FontRegister(font->name, font->size, path, font->style);
63 }
64
65 /**
66 * @sa CL_ParseClientData
67 */
UI_ParseFont(const char * name,const char ** text)68 bool UI_ParseFont (const char* name, const char** text)
69 {
70 uiFont_t* font;
71 const char* errhead = "UI_ParseFont: unexpected end of file (font";
72 const char* token;
73 const value_t* v = nullptr;
74
75 /* search for font with same name */
76 if (UI_GetFontByID(name)) {
77 Com_Printf("UI_ParseFont: font \"%s\" with same name found, second ignored\n", name);
78 return false;
79 }
80
81 if (numFonts >= MAX_FONTS) {
82 Com_Printf("UI_ParseFont: Max fonts reached\n");
83 return false;
84 }
85
86 /* initialize the UI */
87 font = &fonts[numFonts];
88 OBJZERO(*font);
89
90 font->name = Mem_PoolStrDup(name, ui_sysPool, 0);
91
92 Com_DPrintf(DEBUG_CLIENT, "...found font %s (%i)\n", font->name, numFonts);
93
94 /* get it's body */
95 token = Com_Parse(text);
96
97 if (!*text || *token != '{') {
98 Com_Printf("UI_ParseFont: font \"%s\" without body ignored\n", name);
99 return false;
100 }
101
102 numFonts++;
103
104 do {
105 /* get the name type */
106 token = Com_EParse(text, errhead, name);
107 if (!*text)
108 return false;
109 if (*token == '}')
110 break;
111
112 for (v = fontValues; v->string; v++)
113 if (Q_streq(token, v->string)) {
114 /* found a definition */
115 token = Com_EParse(text, errhead, name);
116 if (!*text)
117 return false;
118
119 switch (v->type) {
120 case V_TRANSLATION_STRING:
121 token++;
122 case V_HUNK_STRING:
123 Mem_PoolStrDupTo(token, &Com_GetValue<char*>(font, v), ui_sysPool, 0);
124 break;
125 default:
126 Com_EParseValue(font, token, v->type, v->ofs, v->size);
127 break;
128 }
129 break;
130 }
131
132 if (!v->string)
133 Com_Printf("UI_ParseFont: unknown token \"%s\" ignored (font %s)\n", token, name);
134 } while (*text);
135
136 UI_RegisterFont(font);
137 return true;
138 }
139
140 /**
141 * @brief Return the font for a specific node or default font
142 * @param[in] node Context node
143 * @return char pointer with font name (default is f_small)
144 */
UI_GetFontFromNode(const uiNode_t * const node)145 const char* UI_GetFontFromNode (const uiNode_t* const node)
146 {
147 if (node && node->font) {
148 return UI_GetReferenceString(node, node->font);
149 }
150 return "f_small";
151 }
152
153
154 /**
155 * @brief Return the font for a specific id
156 */
UI_GetFontByID(const char * name)157 const uiFont_t* UI_GetFontByID (const char* name)
158 {
159 int i;
160
161 for (i = 0; i < numFonts; i++)
162 if (Q_streq(fonts[i].name, name))
163 return &fonts[i];
164
165 return nullptr;
166 }
167
UI_FontGetHeight(const char * fontID)168 int UI_FontGetHeight (const char* fontID)
169 {
170 font_t* font = R_GetFont(fontID);
171 if (font != nullptr)
172 return font->height;
173 return -1;
174 }
175
176 /**
177 * @brief after a video restart we have to reinitialize the fonts
178 */
UI_InitFonts(void)179 void UI_InitFonts (void)
180 {
181 int i;
182
183 Com_Printf("...registering %i fonts\n", numFonts);
184 for (i = 0; i < numFonts; i++)
185 UI_RegisterFont(&fonts[i]);
186 }
187
UI_FontShutdown(void)188 void UI_FontShutdown (void)
189 {
190 numFonts = 0;
191 }
192