Freeciv-3.3
Loading...
Searching...
No Matches
gui_string.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14/***********************************************************************
15 gui_string.c - description
16 -------------------
17 begin : June 30 2002
18 copyright : (C) 2002 by Rafał Bursig
19 email : Rafał Bursig <bursig@poczta.fm>
20***********************************************************************/
21
22#ifdef HAVE_CONFIG_H
23#include <fc_config.h>
24#endif
25
26/* SDL2 */
27#ifdef SDL2_PLAIN_INCLUDE
28#include <SDL.h>
29#else /* SDL2_PLAIN_INCLUDE */
30#include <SDL2/SDL.h>
31#endif /* SDL2_PLAIN_INCLUDE */
32
33/* utility */
34#include "fcintl.h"
35#include "log.h"
36#include "mem.h"
37
38/* client/gui-sdl2 */
39#include "colors.h"
40#include "graphics.h"
41#include "gui_main.h"
42#include "themespec.h"
43#include "utf8string.h"
44
45#include "gui_string.h"
46
47/* =================================================== */
48
49static struct ttf_font_chain {
52 Uint16 ptsize; /* size of font */
53 Uint16 count; /* number of strings alliased with this font */
55
57
59
62
63/* Adjust font sizes on 320x240 screen */
64#ifdef GUI_SDL2_SMALL_SCREEN
65 static int adj_font(int size);
66#else /* GUI_SDL2_SMALL_SCREEN */
67 #define adj_font(size) size
68#endif /* GUI_SDL2_SMALL_SCREEN */
69
70#define ptsize_default() adj_font(default_font_size(active_theme))
71
72/**********************************************************************/
75#ifdef GUI_SDL2_SMALL_SCREEN
76static int adj_font(int size)
77{
78 switch (size) {
79 case 24:
80 return 12;
81 case 20:
82 return 12;
83 case 16:
84 return 10;
85 case 14:
86 return 8;
87 case 13:
88 return 8;
89 case 12:
90 return 8;
91 case 11:
92 return 7;
93 case 10:
94 return 7;
95 case 8:
96 return 6;
97 default:
98 return size;
99 }
100}
101#endif /* GUI_SDL2_SMALL_SCREEN */
102
103/**********************************************************************/
107{
108 if (pstr != NULL && pstr->text != NULL && pstr->text[0] != '\0') {
109 char *current = pstr->text;
110 char c = *current;
111 bool new_line = FALSE;
112 int w, h;
113
114 /* find '\n' */
115 while (c != '\0') {
116 if (c == '\n') {
117 new_line = TRUE;
118 break;
119 }
120 current++;
121 c = *current;
122 }
123
124 if (!((pstr->style & 0x0F) & TTF_STYLE_NORMAL)) {
125 TTF_SetFontStyle(pstr->font, (pstr->style & 0x0F));
126 }
127
128 if (new_line) {
129 int ww, hh, count = 0;
131
132 w = 0;
133 h = 0;
134 while (utf8_texts[count]) {
135 if (TTF_SizeUTF8(pstr->font, utf8_texts[count], &ww, &hh) < 0) {
136 do {
138 count++;
139 } while (utf8_texts[count]);
140 log_error("TTF_SizeUTF8() return ERROR!");
141 }
142 w = MAX(w, ww);
143 h += hh;
145 count++;
146 }
147 } else {
148 if (TTF_SizeUTF8(pstr->font, pstr->text, &w, &h) < 0) {
149 log_error("TTF_SizeUTF8() return ERROR!");
150 }
151 }
152
153 if (!((pstr->style & 0x0F) & TTF_STYLE_NORMAL)) {
155 }
156
157 fill->w = w;
158 fill->h = h;
159 } else {
160 fill->w = 0;
161 fill->h = (pstr ? TTF_FontHeight(pstr->font) : 0);
162 }
163}
164
165/**********************************************************************/
168static Uint16 fonto_ptsize(enum font_origin origin)
169{
170 int def;
171
172 switch (origin) {
173 case FONTO_DEFAULT:
174 /* Rely on create_utf8_str() default */
175 return 0;
177 def = ptsize_default();
178 return adj_font(MAX(def + 0, def * 1.1)); /* Same as def, when def < 10 */
179 case FONTO_ATTENTION:
180 def = ptsize_default();
181 return adj_font(MAX(def + 1, def * 1.2));
183 def = ptsize_default();
184 return adj_font(MAX(def + 1, def * 1.2)); /* Same as FONTO_ATTENTION, when def < 10 */
185 case FONTO_HEADING:
186 def = ptsize_default();
187 return adj_font(MAX(def + 2, def * 1.4));
188 case FONTO_BIG:
189 def = ptsize_default();
190 return adj_font(MAX(def + 3, def * 1.6));
191 case FONTO_MAX:
192 def = ptsize_default();
193 return adj_font(MAX(def + 7, def * 2.4));
194 }
195
196 return 0;
197}
198
199/**********************************************************************/
207{
208 utf8_str *str = fc_calloc(1, sizeof(utf8_str));
209
210 if (ptsize == 0) {
211 str->ptsize = ptsize_default();
212 } else {
213 str->ptsize = ptsize;
214 }
215
216 if ((str->font = load_font(str->ptsize)) == NULL) {
217 log_error("create_utf8_str(): load_font() failed");
218 FC_FREE(str);
219
220 return NULL;
221 }
222
223 str->style = TTF_STYLE_NORMAL;
224 str->bgcol = (SDL_Color) {0, 0, 0, 0};
226 str->render = 2;
227
228 /* in_text must be allocated in memory (fc_malloc() / fc_calloc() ) */
229 str->text = in_text;
230 str->n_alloc = n_alloc;
231
232 return str;
233}
234
235/**********************************************************************/
242 enum font_origin origin)
243{
245}
246
247/**********************************************************************/
252{
253 size_t n;
254
257
258 n = (strlen(pchars) + 1);
259
260 if (n > pstr->n_alloc) {
261 /* allocated more if this is only a small increase on before: */
262 size_t n1 = (3 * pstr->n_alloc) / 2;
263
264 pstr->n_alloc = (n > n1) ? n : n1;
265 pstr->text = fc_realloc(pstr->text, pstr->n_alloc);
266 }
267
268 fc_snprintf(pstr->text, pstr->n_alloc, "%s", pchars);
269
270 return pstr;
271}
272
273/**********************************************************************/
277 utf8_str *pstr)
278{
279 SDL_Rect dst_rect = { x, y, 0, 0 };
281
282 if (alphablit(text, NULL, dest, &dst_rect, 255) < 0) {
283 log_error("write_utf8(): couldn't blit text to display: %s",
284 SDL_GetError());
285 FREESURFACE(text);
286
287 return -1;
288 }
289
290 FREESURFACE(text);
291
292 return 0;
293}
294
295/**********************************************************************/
299{
300 SDL_Surface *text = NULL;
301
302 if (pstr == NULL) {
303 return NULL;
304 }
305
306 if (!((pstr->style & 0x0F) & TTF_STYLE_NORMAL)) {
307 TTF_SetFontStyle(pstr->font, (pstr->style & 0x0F));
308 }
309
310 switch (pstr->render) {
311 case 0:
312 text = TTF_RenderUTF8_Shaded(pstr->font,
313 pstr->text, pstr->fgcol,
314 pstr->bgcol);
315 break;
316 case 1:
317 text = TTF_RenderUTF8_Solid(pstr->font, pstr->text, pstr->fgcol);
318 break;
319 case 2:
320 text = TTF_RenderUTF8_Blended(pstr->font, pstr->text, pstr->fgcol);
321 break;
322 }
323
324 if (text != NULL) {
325 log_debug("create_utf8_surf: Font is generally %d big, and "
326 "string is %d big", TTF_FontHeight(pstr->font), text->h);
327 log_debug("create_utf8_surf: String is %d length", text->w);
328 } else {
329 log_debug("create_utf8_surf: text NULL");
330 text = create_surf(0, 0, SDL_SWSURFACE);
331 }
332
333 if (!((pstr->style & 0x0F) & TTF_STYLE_NORMAL)) {
335 }
336
337 return text;
338}
339
340/**********************************************************************/
344{
345 SDL_Rect des = {0, 0, 0, 0};
346 SDL_Surface *text = NULL, **tmp = NULL;
347 Uint16 i, w = 0, count = 0;
349 char *buf = pstr->text;
351
352 while (utf8_texts[count]) {
353 count++;
354 }
355
356 tmp = fc_calloc(count, sizeof(SDL_Surface *));
357
358 for (i = 0; i < count; i++) {
359 pstr->text = utf8_texts[i];
361
362 /* Find max len */
363 if (tmp[i]->w > w) {
364 w = tmp[i]->w;
365 }
366 }
367
368 pstr->text = buf;
369
370 /* Create and fill surface */
371
372 if (SDL_GetColorKey(tmp[0], &color) < 0) {
373 color = SDL_MapRGBA(tmp[0]->format, 0, 0, 0, 0);
374 }
375
376 switch (pstr->render) {
377 case 1:
378 text = create_surf(w, count * tmp[0]->h, SDL_SWSURFACE);
379 SDL_FillRect(text, NULL, color);
381 break;
382 case 2:
383 text = create_surf_with_format(tmp[0]->format,
384 w, count * tmp[0]->h, tmp[0]->flags);
385 SDL_FillRect(text, NULL, color);
386 break;
387 default:
388 text = create_surf(w, count * tmp[0]->h, SDL_SWSURFACE);
389 SDL_FillRect(text, NULL, color);
390 break;
391 }
392
393 /* Blit (default: center left) */
394 for (i = 0; i < count; i++) {
395 if (pstr->style & SF_CENTER) {
396 des.x = (w - tmp[i]->w) / 2;
397 } else {
398 if (pstr->style & SF_CENTER_RIGHT) {
399 des.x = w - tmp[i]->w;
400 } else {
401 des.x = 0;
402 }
403 }
404
405 alphablit(tmp[i], NULL, text, &des, 255);
406 des.y += tmp[i]->h;
407 }
408
409
410 /* Free Memory */
411 for (i = 0; i < count; i++) {
413 FREESURFACE(tmp[i]);
414 }
415
416 FC_FREE(tmp);
417
418 return text;
419}
420
421/**********************************************************************/
426{
427 if (pstr != NULL && pstr->text != NULL) {
428 char *current = pstr->text;
429 char c = *(pstr->text);
430
431 /* find '\n' */
432 while (c != '\0') {
433 if (c == '\n') {
435 }
436 current++;
437 c = *current;
438 }
439
440 return create_utf8_surf(pstr);
441 }
442
443 return NULL;
444}
445
446/**********************************************************************/
450{
452 bool converted = FALSE;
453
455 fc_assert_ret_val(pstr->text != NULL, FALSE);
456
458 if (size.w > width) {
459 /* cut string length to w length by replacing space " " with new line "\n" */
460 bool resize = FALSE;
461 int len = 0;
462 char *ptr_rev, *ptr = pstr->text;
463
464 converted = TRUE;
465
466 do {
467 if (!resize) {
468 char utf8char[9];
469 int i;
470 int fw, fh;
471
472 if (*ptr == '\0') {
473 resize = TRUE;
474 continue;
475 }
476
477 if (*ptr == '\n') {
478 len = 0;
479 ptr++;
480 continue;
481 }
482
483 utf8char[0] = ptr[0];
484 for (i = 1; i < 8 && (ptr[i] & (128 + 64)) == 128; i++) {
485 utf8char[i] = ptr[i];
486 }
487 utf8char[i] = '\0';
488 if (!((pstr->style & 0x0F) & TTF_STYLE_NORMAL)) {
489 TTF_SetFontStyle(pstr->font, (pstr->style & 0x0F));
490 }
491 TTF_SizeUTF8(pstr->font, utf8char, &fw, &fh);
492 if (!((pstr->style & 0x0F) & TTF_STYLE_NORMAL)) {
494 }
495
496 len += fw;
497
498 if (len > width) {
499 ptr_rev = ptr;
500 while (ptr_rev != pstr->text) {
501 if (*ptr_rev == ' ') {
502 *ptr_rev = '\n';
504 len = 0;
505 break;
506 }
507 if (*ptr_rev == '\n') {
508 resize = TRUE;
509 break;
510 }
511 ptr_rev--;
512 }
513 if (ptr_rev == pstr->text) {
514 resize = TRUE;
515 }
516 }
517
518 ptr += i;
519 } else {
520 if (pstr->ptsize > 8) {
521 change_ptsize_utf8(pstr, pstr->ptsize - 1);
523 } else {
524 log_error("Can't convert string to const width");
525 break;
526 }
527 }
528
529 } while (size.w > width);
530 }
531
532 return converted;
533}
534
535/**********************************************************************/
540{
541 int ptsize;
542 SDL_Surface *text;
543
545
546 ptsize = pstr->ptsize;
549 if (pstr->ptsize != ptsize) {
551 }
552
553 return text;
554}
555
556/**********************************************************************/
560{
561 TTF_Font *buf;
562
563 if (new_ptsize == 0) {
565 }
566
567 if (pstr->ptsize == new_ptsize) {
568 return;
569 }
570
571 if ((buf = load_font(new_ptsize)) == NULL) {
572 log_error("change_ptsize: load_font() failed");
573 return;
574 }
575
576 unload_font(pstr->ptsize);
577 pstr->ptsize = new_ptsize;
578 pstr->font = buf;
579}
580
581/**********************************************************************/
585{
587}
588
589/* =================================================== */
590
591/**********************************************************************/
595{
598
599 /* Find existing font and return pointer to it */
600 if (font_tab != NULL) {
601
602 while (font_tab_tmp != NULL) {
603 if (font_tab_tmp->ptsize == ptsize) {
605
606 return font_tab_tmp->font;
607 }
608
610 }
611 }
612
613 if (!font_with_full_path) {
614 const char *path = theme_font_filename(active_theme);
615
618 }
619
620 /* Load Font */
622 log_error("load_font: Couldn't load %d pt font from %s: %s",
624 return NULL;
625 }
626
627 /* Add new font to list */
628 if (font_tab == NULL) {
629 font_tab_tmp = fc_calloc(1, sizeof(struct ttf_font_chain));
631 } else {
632 /* Go to end of chain */
634 while (font_tab_tmp->next) {
636 }
637
638 font_tab_tmp->next = fc_calloc(1, sizeof(struct ttf_font_chain));
640 }
641
642 font_tab_tmp->ptsize = ptsize;
643 font_tab_tmp->count = 1;
644 font_tab_tmp->font = font_tmp;
645 font_tab_tmp->next = NULL;
646
647 return font_tmp;
648}
649
650/**********************************************************************/
654{
657
658 if (font_tab == NULL) {
659 log_error("unload_font: Trying unload from empty Font ARRAY");
660 return;
661 }
662
663 while (font_tab_tmp != NULL) {
664 if (font_tab_tmp->ptsize == ptsize) {
665 break;
666 }
669 }
670
671 if (font_tab_tmp == NULL) {
672 log_error("unload_font: Trying unload Font which is "
673 "not included in Font ARRAY");
674 return;
675 }
676
677 if (--font_tab_tmp->count > 0) {
678 return;
679 }
680
682 font_tab_tmp->font = NULL;
683
684 if (font_tab_prev == NULL) {
686 } else {
688 }
689
691
693}
694
695/**********************************************************************/
699{
701
703 while (font_tab) {
704 if (font_tab->next) {
707 if (font_tab_tmp->font) {
709 }
711 } else {
712 if (font_tab->font) {
714 }
716 }
717 }
718}
#define n_alloc
Definition astring.c:78
#define str
Definition astring.c:76
#define n
Definition astring.c:77
struct canvas int int struct sprite int int int width
Definition canvas_g.h:44
char * incite_cost
Definition comments.c:76
SDL_Color * get_theme_color(enum theme_color themecolor)
Definition colors.c:47
SDL_Surface * create_surf_with_format(SDL_PixelFormat *pf, int width, int height, Uint32 flags)
Definition graphics.c:328
int alphablit(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect, unsigned char alpha_mod)
Definition graphics.c:199
SDL_Surface * create_surf(int width, int height, Uint32 flags)
Definition graphics.c:351
#define FREESURFACE(ptr)
Definition graphics.h:322
static TTF_Font * load_font(Uint16 ptsize)
Definition gui_string.c:594
#define ptsize_default()
Definition gui_string.c:70
void change_ptsize_utf8(utf8_str *pstr, Uint16 new_ptsize)
Definition gui_string.c:559
void utf8_str_size(utf8_str *pstr, SDL_Rect *fill)
Definition gui_string.c:106
utf8_str * copy_chars_to_utf8_str(utf8_str *pstr, const char *pchars)
Definition gui_string.c:251
SDL_Surface * create_text_surf_from_utf8(utf8_str *pstr)
Definition gui_string.c:425
void change_fonto_utf8(utf8_str *pstr, enum font_origin origin)
Definition gui_string.c:584
static char * font_with_full_path
Definition gui_string.c:56
void unload_font(Uint16 ptsize)
Definition gui_string.c:653
utf8_str * create_utf8_str(char *in_text, size_t n_alloc, Uint16 ptsize)
Definition gui_string.c:206
utf8_str * create_utf8_str_fonto(char *in_text, size_t n_alloc, enum font_origin origin)
Definition gui_string.c:241
static struct ttf_font_chain * font_tab
int write_utf8(SDL_Surface *dest, Sint16 x, Sint16 y, utf8_str *pstr)
Definition gui_string.c:276
static SDL_Surface * create_utf8_multi_surf(utf8_str *pstr)
Definition gui_string.c:343
bool convert_utf8_str_to_const_surface_width(utf8_str *pstr, int width)
Definition gui_string.c:449
static SDL_Surface * create_utf8_surf(utf8_str *pstr)
Definition gui_string.c:298
void free_font_system(void)
Definition gui_string.c:698
SDL_Surface * create_text_surf_smaller_than_w(utf8_str *pstr, int w)
Definition gui_string.c:539
#define adj_font(size)
Definition gui_string.c:67
static Uint16 fonto_ptsize(enum font_origin origin)
Definition gui_string.c:168
#define SF_CENTER
Definition gui_string.h:40
#define SF_CENTER_RIGHT
Definition gui_string.h:41
font_origin
Definition gui_string.h:64
@ FONTO_HEADING
Definition gui_string.h:69
@ FONTO_DEFAULT
Definition gui_string.h:65
@ FONTO_DEFAULT_PLUS
Definition gui_string.h:66
@ FONTO_BIG
Definition gui_string.h:70
@ FONTO_ATTENTION
Definition gui_string.h:67
@ FONTO_ATTENTION_PLUS
Definition gui_string.h:68
@ FONTO_MAX
Definition gui_string.h:71
@ COLOR_THEME_TEXT
Definition themecolors.h:38
const char * theme_font_filename(const struct theme *t)
Definition themespec.c:169
struct theme * active_theme
Definition themespec.c:154
char ** create_new_line_utf8strs(const char *pstr)
Definition utf8string.c:35
#define fc_assert_ret_val(condition, val)
Definition log.h:195
#define log_debug(message,...)
Definition log.h:116
#define log_error(message,...)
Definition log.h:104
#define fc_calloc(n, esz)
Definition mem.h:38
#define FC_FREE(ptr)
Definition mem.h:41
#define fc_strdup(str)
Definition mem.h:43
#define fc_realloc(ptr, sz)
Definition mem.h:36
int len
Definition packhand.c:127
#define MAX(x, y)
Definition shared.h:54
size_t size
Definition specvec.h:72
struct sprite int int y
Definition sprite_g.h:31
struct sprite int x
Definition sprite_g.h:31
Definition colors.h:21
TTF_Font * font
Definition gui_string.c:51
struct ttf_font_chain * next
Definition gui_string.c:50
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:960
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47