| 078900fe |
sago007 |
2015-12-05 15:31 |
1 |
/* |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2 |
SDL_FontCache v0.0.1: A font cache for SDL and SDL_ttf |
| 078900fe |
sago007 |
2015-12-05 15:31 |
3 |
by Jonathan Dearborn |
| 078900fe |
sago007 |
2015-12-05 15:31 |
4 |
Dedicated to the memory of Florian Hufsky |
| 078900fe |
sago007 |
2015-12-05 15:31 |
5 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
6 |
License: |
| 078900fe |
sago007 |
2015-12-05 15:31 |
7 |
The short: |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
8 |
Use it however you'd like, but keep the copyright and license notice |
| 078900fe |
sago007 |
2015-12-05 15:31 |
9 |
whenever these files or parts of them are distributed in uncompiled form. |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
10 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
11 |
The long: |
| 078900fe |
sago007 |
2015-12-05 15:31 |
12 |
Copyright (c) 2015 Jonathan Dearborn |
| 078900fe |
sago007 |
2015-12-05 15:31 |
13 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
14 |
Permission is hereby granted, free of charge, to any person obtaining a copy |
| 078900fe |
sago007 |
2015-12-05 15:31 |
15 |
of this software and associated documentation files (the "Software"), to deal |
| 078900fe |
sago007 |
2015-12-05 15:31 |
16 |
in the Software without restriction, including without limitation the rights |
| 078900fe |
sago007 |
2015-12-05 15:31 |
17 |
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| 078900fe |
sago007 |
2015-12-05 15:31 |
18 |
copies of the Software, and to permit persons to whom the Software is |
| 078900fe |
sago007 |
2015-12-05 15:31 |
19 |
furnished to do so, subject to the following conditions: |
| 078900fe |
sago007 |
2015-12-05 15:31 |
20 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
21 |
The above copyright notice and this permission notice shall be included in |
| 078900fe |
sago007 |
2015-12-05 15:31 |
22 |
all copies or substantial portions of the Software. |
| 078900fe |
sago007 |
2015-12-05 15:31 |
23 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
24 |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 078900fe |
sago007 |
2015-12-05 15:31 |
25 |
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 078900fe |
sago007 |
2015-12-05 15:31 |
26 |
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| 078900fe |
sago007 |
2015-12-05 15:31 |
27 |
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 078900fe |
sago007 |
2015-12-05 15:31 |
28 |
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 078900fe |
sago007 |
2015-12-05 15:31 |
29 |
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| 078900fe |
sago007 |
2015-12-05 15:31 |
30 |
THE SOFTWARE. |
| 078900fe |
sago007 |
2015-12-05 15:31 |
31 |
*/ |
| 078900fe |
sago007 |
2015-12-05 15:31 |
32 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
33 |
#include "SDL_FontCache.h" |
| 078900fe |
sago007 |
2015-12-05 15:31 |
34 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
35 |
#include <stdio.h> |
| 078900fe |
sago007 |
2015-12-05 15:31 |
36 |
#include <stdlib.h> |
| 078900fe |
sago007 |
2015-12-05 15:31 |
37 |
#include <string.h> |
| 078900fe |
sago007 |
2015-12-05 15:31 |
38 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
39 |
// Visual C does not support static inline |
| 078900fe |
sago007 |
2015-12-05 15:31 |
40 |
#ifndef static_inline |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
41 |
#ifdef _MSC_VER |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
42 |
#define static_inline static |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
43 |
#else |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
44 |
#define static_inline static inline |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
45 |
#endif |
| 078900fe |
sago007 |
2015-12-05 15:31 |
46 |
#endif |
| 078900fe |
sago007 |
2015-12-05 15:31 |
47 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
48 |
#if SDL_VERSION_ATLEAST(2,0,0) |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
49 |
#define FC_GET_ALPHA(sdl_color) ((sdl_color).a) |
| 078900fe |
sago007 |
2015-12-05 15:31 |
50 |
#else |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
51 |
#define FC_GET_ALPHA(sdl_color) ((sdl_color).unused) |
| 078900fe |
sago007 |
2015-12-05 15:31 |
52 |
#endif |
| 078900fe |
sago007 |
2015-12-05 15:31 |
53 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
54 |
// Need SDL_RenderIsClipEnabled() for proper clipping support |
| 078900fe |
sago007 |
2015-12-05 15:31 |
55 |
#if SDL_VERSION_ATLEAST(2,0,4) |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
56 |
#define ENABLE_SDL_CLIPPING |
| 078900fe |
sago007 |
2015-12-05 15:31 |
57 |
#endif |
| 078900fe |
sago007 |
2015-12-05 15:31 |
58 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
59 |
#define FC_MIN(a,b) ((a) < (b)? (a) : (b)) |
| 078900fe |
sago007 |
2015-12-05 15:31 |
60 |
#define FC_MAX(a,b) ((a) > (b)? (a) : (b)) |
| 078900fe |
sago007 |
2015-12-05 15:31 |
61 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
62 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
63 |
#define FC_EXTRACT_VARARGS(buffer, start_args) \ |
| 078900fe |
sago007 |
2015-12-05 15:31 |
64 |
{ \ |
| 078900fe |
sago007 |
2015-12-05 15:31 |
65 |
va_list lst; \ |
| 078900fe |
sago007 |
2015-12-05 15:31 |
66 |
va_start(lst, start_args); \ |
| 078900fe |
sago007 |
2015-12-05 15:31 |
67 |
vsprintf(buffer, start_args, lst); \ |
| 078900fe |
sago007 |
2015-12-05 15:31 |
68 |
va_end(lst); \ |
| 078900fe |
sago007 |
2015-12-05 15:31 |
69 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
70 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
71 |
// Extra pixels of padding around each glyph to avoid linear filtering artifacts |
| 078900fe |
sago007 |
2015-12-05 15:31 |
72 |
#define FC_CACHE_PADDING 1 |
| 078900fe |
sago007 |
2015-12-05 15:31 |
73 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
74 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
75 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
76 |
static Uint8 has_clip(FC_Target* dest) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
77 |
#ifdef FC_USE_SDL_GPU |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
78 |
return dest->use_clip_rect; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
79 |
#elif defined(ENABLE_SDL_CLIPPING) |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
80 |
return SDL_RenderIsClipEnabled(dest); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
81 |
#else |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
82 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
83 |
#endif |
| 078900fe |
sago007 |
2015-12-05 15:31 |
84 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
85 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
86 |
static FC_Rect get_clip(FC_Target* dest) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
87 |
#ifdef FC_USE_SDL_GPU |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
88 |
return dest->clip_rect; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
89 |
#elif defined(ENABLE_SDL_CLIPPING) |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
90 |
SDL_Rect r; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
91 |
SDL_RenderGetClipRect(dest, &r); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
92 |
return r; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
93 |
#else |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
94 |
SDL_Rect r = {0, 0, 0, 0}; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
95 |
return r; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
96 |
#endif |
| 078900fe |
sago007 |
2015-12-05 15:31 |
97 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
98 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
99 |
static void set_clip(FC_Target* dest, FC_Rect* rect) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
100 |
#ifdef FC_USE_SDL_GPU |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
101 |
if (rect != NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
102 |
GPU_SetClipRect(dest, *rect); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
103 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
104 |
else { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
105 |
GPU_UnsetClip(dest); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
106 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
107 |
#elif defined(ENABLE_SDL_CLIPPING) |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
108 |
SDL_RenderSetClipRect(dest, rect); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
109 |
#endif |
| 078900fe |
sago007 |
2015-12-05 15:31 |
110 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
111 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
112 |
static void set_color(FC_Image* src, Uint8 r, Uint8 g, Uint8 b, Uint8 a) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
113 |
#ifdef FC_USE_SDL_GPU |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
114 |
GPU_SetRGBA(src, r, g, b, a); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
115 |
#else |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
116 |
SDL_SetTextureColorMod(src, r, g, b); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
117 |
SDL_SetTextureAlphaMod(src, a); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
118 |
#endif |
| 078900fe |
sago007 |
2015-12-05 15:31 |
119 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
120 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
121 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
122 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
123 |
static char* new_concat(const char* a, const char* b) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
124 |
// Create new buffer |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
125 |
unsigned int size = strlen(a) + strlen(b); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
126 |
char* new_string = (char*)malloc(size+1); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
127 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
128 |
// Concatenate strings in the new buffer |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
129 |
strcpy(new_string, a); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
130 |
strcat(new_string, b); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
131 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
132 |
return new_string; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
133 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
134 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
135 |
static char* replace_concat(char** a, const char* b) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
136 |
char* new_string = new_concat(*a, b); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
137 |
free(*a); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
138 |
*a = new_string; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
139 |
return *a; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
140 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
141 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
142 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
143 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
144 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
145 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
146 |
// Shared buffer for variadic text |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
147 |
static char* fc_buffer = NULL; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
148 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
149 |
static Uint8 fc_has_render_target_support = 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
150 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
151 |
const char* FC_GetStringASCII(void) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
152 |
static char* buffer = NULL; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
153 |
if (buffer == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
154 |
int i; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
155 |
char c; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
156 |
buffer = (char*)malloc(512); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
157 |
memset(buffer, 0, 512); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
158 |
i = 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
159 |
c = 32; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
160 |
while (1) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
161 |
buffer[i] = c; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
162 |
if (c == 126) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
163 |
break; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
164 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
165 |
++i; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
166 |
++c; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
167 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
168 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
169 |
return buffer; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
170 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
171 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
172 |
const char* FC_GetStringLatin1(void) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
173 |
static char* buffer = NULL; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
174 |
if (buffer == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
175 |
int i; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
176 |
unsigned char c; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
177 |
buffer = (char*)malloc(512); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
178 |
memset(buffer, 0, 512); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
179 |
i = 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
180 |
c = 0xA0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
181 |
while (1) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
182 |
buffer[i] = 0xC2; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
183 |
buffer[i+1] = c; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
184 |
if (c == 0xBF) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
185 |
break; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
186 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
187 |
i += 2; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
188 |
++c; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
189 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
190 |
i += 2; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
191 |
c = 0x80; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
192 |
while (1) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
193 |
buffer[i] = 0xC3; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
194 |
buffer[i+1] = c; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
195 |
if (c == 0xBF) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
196 |
break; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
197 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
198 |
i += 2; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
199 |
++c; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
200 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
201 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
202 |
return buffer; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
203 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
204 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
205 |
const char* FC_GetStringASCII_Latin1(void) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
206 |
static char* buffer = NULL; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
207 |
if (buffer == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
208 |
buffer = new_concat(FC_GetStringASCII(), FC_GetStringLatin1()); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
209 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
210 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
211 |
return buffer; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
212 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
213 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
214 |
FC_Rect FC_MakeRect(float x, float y, float w, float h) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
215 |
FC_Rect r = {x, y, w, h}; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
216 |
return r; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
217 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
218 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
219 |
FC_Scale FC_MakeScale(float x, float y) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
220 |
FC_Scale s = {x, y}; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
221 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
222 |
return s; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
223 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
224 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
225 |
SDL_Color FC_MakeColor(Uint8 r, Uint8 g, Uint8 b, Uint8 a) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
226 |
SDL_Color c = {r, g, b, a}; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
227 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
228 |
return c; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
229 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
230 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
231 |
FC_Effect FC_MakeEffect(FC_AlignEnum alignment, FC_Scale scale, SDL_Color color) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
232 |
FC_Effect e; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
233 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
234 |
e.alignment = alignment; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
235 |
e.scale = scale; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
236 |
e.color = color; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
237 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
238 |
return e; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
239 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
240 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
241 |
FC_GlyphData FC_MakeGlyphData(int cache_level, Sint16 x, Sint16 y, Uint16 w, Uint16 h) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
242 |
FC_GlyphData gd; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
243 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
244 |
gd.rect.x = x; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
245 |
gd.rect.y = y; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
246 |
gd.rect.w = w; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
247 |
gd.rect.h = h; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
248 |
gd.cache_level = cache_level; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
249 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
250 |
return gd; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
251 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
252 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
253 |
// Enough to hold all of the ascii characters and some. |
| 078900fe |
sago007 |
2015-12-05 15:31 |
254 |
#define FC_DEFAULT_NUM_BUCKETS 300 |
| 078900fe |
sago007 |
2015-12-05 15:31 |
255 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
256 |
typedef struct FC_MapNode { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
257 |
Uint32 key; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
258 |
FC_GlyphData value; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
259 |
struct FC_MapNode* next; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
260 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
261 |
} FC_MapNode; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
262 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
263 |
typedef struct FC_Map { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
264 |
int num_buckets; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
265 |
FC_MapNode** buckets; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
266 |
} FC_Map; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
267 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
268 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
269 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
270 |
static FC_Map* FC_MapCreate(int num_buckets) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
271 |
int i; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
272 |
FC_Map* map = (FC_Map*)malloc(sizeof(FC_Map)); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
273 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
274 |
map->num_buckets = num_buckets; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
275 |
map->buckets = (FC_MapNode**)malloc(num_buckets * sizeof(FC_MapNode*)); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
276 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
277 |
for (i = 0; i < num_buckets; ++i) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
278 |
map->buckets[i] = NULL; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
279 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
280 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
281 |
return map; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
282 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
283 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
284 |
/*static void FC_MapClear(FC_Map* map) |
| 078900fe |
sago007 |
2015-12-05 15:31 |
285 |
{ |
| 078900fe |
sago007 |
2015-12-05 15:31 |
286 |
int i; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
287 |
if(map == NULL) |
| 078900fe |
sago007 |
2015-12-05 15:31 |
288 |
return; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
289 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
290 |
// Go through each bucket |
| 078900fe |
sago007 |
2015-12-05 15:31 |
291 |
for(i = 0; i < map->num_buckets; ++i) |
| 078900fe |
sago007 |
2015-12-05 15:31 |
292 |
{ |
| 078900fe |
sago007 |
2015-12-05 15:31 |
293 |
// Delete the nodes in order |
| 078900fe |
sago007 |
2015-12-05 15:31 |
294 |
FC_MapNode* node = map->buckets[i]; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
295 |
while(node != NULL) |
| 078900fe |
sago007 |
2015-12-05 15:31 |
296 |
{ |
| 078900fe |
sago007 |
2015-12-05 15:31 |
297 |
FC_MapNode* last = node; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
298 |
node = node->next; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
299 |
free(last); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
300 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
301 |
// Set the bucket to empty |
| 078900fe |
sago007 |
2015-12-05 15:31 |
302 |
map->buckets[i] = NULL; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
303 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
304 |
}*/ |
| 078900fe |
sago007 |
2015-12-05 15:31 |
305 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
306 |
static void FC_MapFree(FC_Map* map) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
307 |
int i; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
308 |
if (map == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
309 |
return; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
310 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
311 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
312 |
// Go through each bucket |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
313 |
for (i = 0; i < map->num_buckets; ++i) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
314 |
// Delete the nodes in order |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
315 |
FC_MapNode* node = map->buckets[i]; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
316 |
while (node != NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
317 |
FC_MapNode* last = node; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
318 |
node = node->next; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
319 |
free(last); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
320 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
321 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
322 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
323 |
free(map->buckets); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
324 |
free(map); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
325 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
326 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
327 |
// Note: Does not handle duplicates in any special way. |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
328 |
static FC_GlyphData* FC_MapInsert(FC_Map* map, Uint32 codepoint, FC_GlyphData glyph) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
329 |
Uint32 index; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
330 |
FC_MapNode* node; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
331 |
if (map == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
332 |
return NULL; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
333 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
334 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
335 |
// Get index for bucket |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
336 |
index = codepoint % map->num_buckets; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
337 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
338 |
// If this bucket is empty, create a node and return its value |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
339 |
if (map->buckets[index] == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
340 |
node = map->buckets[index] = (FC_MapNode*)malloc(sizeof(FC_MapNode)); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
341 |
node->key = codepoint; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
342 |
node->value = glyph; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
343 |
node->next = NULL; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
344 |
return &node->value; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
345 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
346 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
347 |
for (node = map->buckets[index]; node != NULL; node = node->next) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
348 |
// Find empty node and add a new one on. |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
349 |
if (node->next == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
350 |
node->next = (FC_MapNode*)malloc(sizeof(FC_MapNode)); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
351 |
node = node->next; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
352 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
353 |
node->key = codepoint; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
354 |
node->value = glyph; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
355 |
node->next = NULL; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
356 |
return &node->value; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
357 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
358 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
359 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
360 |
return NULL; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
361 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
362 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
363 |
static FC_GlyphData* FC_MapFind(FC_Map* map, Uint32 codepoint) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
364 |
Uint32 index; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
365 |
FC_MapNode* node; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
366 |
if (map == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
367 |
return NULL; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
368 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
369 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
370 |
// Get index for bucket |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
371 |
index = codepoint % map->num_buckets; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
372 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
373 |
// Go through list until we find a match |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
374 |
for (node = map->buckets[index]; node != NULL; node = node->next) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
375 |
if (node->key == codepoint) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
376 |
return &node->value; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
377 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
378 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
379 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
380 |
return NULL; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
381 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
382 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
383 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
384 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
385 |
struct FC_Font { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
386 |
#ifndef FC_USE_SDL_GPU |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
387 |
SDL_Renderer* renderer; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
388 |
#endif |
| 078900fe |
sago007 |
2015-12-05 15:31 |
389 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
390 |
TTF_Font* ttf_source; // TTF_Font source of characters |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
391 |
Uint8 owns_ttf_source; // Can we delete the TTF_Font ourselves? |
| 078900fe |
sago007 |
2015-12-05 15:31 |
392 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
393 |
FC_FilterEnum filter; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
394 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
395 |
SDL_Color default_color; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
396 |
Uint16 height; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
397 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
398 |
Uint16 maxWidth; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
399 |
Uint16 baseline; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
400 |
int ascent; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
401 |
int descent; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
402 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
403 |
int lineSpacing; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
404 |
int letterSpacing; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
405 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
406 |
// Uses 32-bit (4-byte) Unicode codepoints to refer to each glyph |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
407 |
// Codepoints are little endian (reversed from UTF-8) so that something like 0x00000005 is ASCII 5 and the map can be indexed by ASCII values |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
408 |
FC_Map* glyphs; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
409 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
410 |
FC_GlyphData last_glyph; // Texture packing cursor |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
411 |
int glyph_cache_size; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
412 |
int glyph_cache_count; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
413 |
FC_Image** glyph_cache; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
414 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
415 |
char* loading_string; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
416 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
417 |
}; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
418 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
419 |
// Private |
| 078900fe |
sago007 |
2015-12-05 15:31 |
420 |
static FC_GlyphData* FC_PackGlyphData(FC_Font* font, Uint32 codepoint, Uint16 width, Uint16 maxWidth, Uint16 maxHeight); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
421 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
422 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
423 |
static FC_Rect FC_RenderLeft(FC_Font* font, FC_Target* dest, float x, float y, FC_Scale scale, const char* text); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
424 |
static FC_Rect FC_RenderCenter(FC_Font* font, FC_Target* dest, float x, float y, FC_Scale scale, const char* text); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
425 |
static FC_Rect FC_RenderRight(FC_Font* font, FC_Target* dest, float x, float y, FC_Scale scale, const char* text); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
426 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
427 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
428 |
static_inline SDL_Surface* FC_CreateSurface32(Uint32 width, Uint32 height) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
429 |
#if SDL_BYTEORDER == SDL_BIG_ENDIAN |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
430 |
return SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
431 |
#else |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
432 |
return SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
433 |
#endif |
| 078900fe |
sago007 |
2015-12-05 15:31 |
434 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
435 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
436 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
437 |
char* U8_alloc(unsigned int size) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
438 |
char* result; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
439 |
if (size == 0) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
440 |
return NULL; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
441 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
442 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
443 |
result = (char*)malloc(size); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
444 |
result[0] = '\0'; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
445 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
446 |
return result; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
447 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
448 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
449 |
void U8_free(char* string) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
450 |
free(string); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
451 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
452 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
453 |
char* U8_strdup(const char* string) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
454 |
char* result; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
455 |
if (string == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
456 |
return NULL; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
457 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
458 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
459 |
result = (char*)malloc(strlen(string)+1); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
460 |
strcpy(result, string); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
461 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
462 |
return result; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
463 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
464 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
465 |
int U8_strlen(const char* string) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
466 |
int length = 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
467 |
if (string == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
468 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
469 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
470 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
471 |
while (*string != '\0') { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
472 |
string = U8_next(string); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
473 |
++length; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
474 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
475 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
476 |
return length; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
477 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
478 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
479 |
int U8_charsize(const char* character) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
480 |
if (character == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
481 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
482 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
483 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
484 |
if ((unsigned char)*character <= 0x7F) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
485 |
return 1; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
486 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
487 |
else if ((unsigned char)*character < 0xE0) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
488 |
return 2; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
489 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
490 |
else if ((unsigned char)*character < 0xF0) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
491 |
return 3; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
492 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
493 |
else { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
494 |
return 4; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
495 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
496 |
return 1; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
497 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
498 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
499 |
int U8_charcpy(char* buffer, const char* source, int buffer_size) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
500 |
int charsize; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
501 |
if (buffer == NULL || source == NULL || buffer_size < 1) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
502 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
503 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
504 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
505 |
charsize = U8_charsize(source); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
506 |
if (charsize > buffer_size) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
507 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
508 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
509 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
510 |
memcpy(buffer, source, charsize); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
511 |
return charsize; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
512 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
513 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
514 |
const char* U8_next(const char* string) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
515 |
return string + U8_charsize(string); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
516 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
517 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
518 |
int U8_strinsert(char* string, int position, const char* source, int max_bytes) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
519 |
int pos_bytes; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
520 |
int len = strlen(string); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
521 |
int add_len = strlen(source); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
522 |
int ulen = U8_strlen(string); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
523 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
524 |
if (position == -1) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
525 |
position = ulen; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
526 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
527 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
528 |
if (string == NULL || source == NULL || position < 0 || position > ulen || len + add_len + 1 > max_bytes) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
529 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
530 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
531 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
532 |
// Move string pointer to the proper position |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
533 |
pos_bytes = 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
534 |
while (*string != '\0' && pos_bytes < position) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
535 |
string = (char*)U8_next(string); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
536 |
++pos_bytes; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
537 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
538 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
539 |
// Move the rest of the string out of the way |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
540 |
memmove(string + add_len, string, len - pos_bytes + 1); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
541 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
542 |
// Copy in the new characters |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
543 |
memcpy(string, source, add_len); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
544 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
545 |
return 1; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
546 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
547 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
548 |
void U8_strdel(char* string, int position) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
549 |
if (string == NULL || position < 0) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
550 |
return; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
551 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
552 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
553 |
while (*string != '\0') { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
554 |
if (position == 0) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
555 |
int chars_to_erase = U8_charsize(string); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
556 |
int remaining_bytes = strlen(string) + 1; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
557 |
memmove(string, string + chars_to_erase, remaining_bytes); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
558 |
break; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
559 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
560 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
561 |
string = (char*)U8_next(string); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
562 |
--position; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
563 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
564 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
565 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
566 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
567 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
568 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
569 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
570 |
static_inline FC_Rect FC_RectUnion(FC_Rect A, FC_Rect B) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
571 |
float x,x2,y,y2; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
572 |
x = FC_MIN(A.x, B.x); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
573 |
y = FC_MIN(A.y, B.y); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
574 |
x2 = FC_MAX(A.x+A.w, B.x+B.w); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
575 |
y2 = FC_MAX(A.y+A.h, B.y+B.h); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
576 |
{ |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
577 |
FC_Rect result = {x, y, FC_MAX(0, x2 - x), FC_MAX(0, y2 - y)}; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
578 |
return result; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
579 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
580 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
581 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
582 |
// Adapted from SDL_IntersectRect |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
583 |
static_inline FC_Rect FC_RectIntersect(FC_Rect A, FC_Rect B) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
584 |
FC_Rect result; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
585 |
float Amin, Amax, Bmin, Bmax; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
586 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
587 |
// Horizontal intersection |
| 078900fe |
sago007 |
2015-12-05 15:31 |
588 |
Amin = A.x; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
589 |
Amax = Amin + A.w; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
590 |
Bmin = B.x; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
591 |
Bmax = Bmin + B.w; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
592 |
if (Bmin > Amin) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
593 |
Amin = Bmin; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
594 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
595 |
result.x = Amin; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
596 |
if (Bmax < Amax) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
597 |
Amax = Bmax; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
598 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
599 |
result.w = Amax - Amin > 0 ? Amax - Amin : 0; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
600 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
601 |
// Vertical intersection |
| 078900fe |
sago007 |
2015-12-05 15:31 |
602 |
Amin = A.y; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
603 |
Amax = Amin + A.h; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
604 |
Bmin = B.y; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
605 |
Bmax = Bmin + B.h; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
606 |
if (Bmin > Amin) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
607 |
Amin = Bmin; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
608 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
609 |
result.y = Amin; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
610 |
if (Bmax < Amax) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
611 |
Amax = Bmax; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
612 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
613 |
result.h = Amax - Amin > 0 ? Amax - Amin : 0; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
614 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
615 |
return result; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
616 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
617 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
618 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
619 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
620 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
621 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
622 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
623 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
624 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
625 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
626 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
627 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
628 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
629 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
630 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
631 |
FC_Rect FC_DefaultRenderCallback(FC_Image* src, FC_Rect* srcrect, FC_Target* dest, float x, float y, float xscale, float yscale) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
632 |
float w = srcrect->w * xscale; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
633 |
float h = srcrect->h * yscale; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
634 |
FC_Rect result; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
635 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
636 |
// FIXME: Why does the scaled offset look so wrong? |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
637 |
#ifdef FC_USE_SDL_GPU |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
638 |
{ |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
639 |
GPU_Rect r = *srcrect; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
640 |
GPU_BlitScale(src, &r, dest, x + xscale*r.w/2.0f, y + r.h/2.0f, xscale, yscale); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
641 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
642 |
#else |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
643 |
{ |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
644 |
int flip = SDL_FLIP_NONE; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
645 |
if (xscale < 0) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
646 |
xscale = -xscale; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
647 |
flip |= SDL_FLIP_HORIZONTAL; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
648 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
649 |
if (yscale < 0) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
650 |
yscale = -yscale; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
651 |
flip |= SDL_FLIP_VERTICAL; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
652 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
653 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
654 |
SDL_Rect r = *srcrect; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
655 |
SDL_Rect dr = {(int)x, (int)y, (int)(xscale*r.w), (int)(yscale*r.h)}; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
656 |
SDL_RenderCopyEx(dest, src, &r, &dr, 0, NULL, (SDL_RendererFlip)flip); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
657 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
658 |
#endif |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
659 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
660 |
result.x = x; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
661 |
result.y = y; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
662 |
result.w = w; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
663 |
result.h = h; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
664 |
return result; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
665 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
666 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
667 |
static FC_Rect (*fc_render_callback)(FC_Image* src, FC_Rect* srcrect, FC_Target* dest, float x, float y, float xscale, float yscale) = &FC_DefaultRenderCallback; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
668 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
669 |
void FC_SetRenderCallback(FC_Rect (*callback)(FC_Image* src, FC_Rect* srcrect, FC_Target* dest, float x, float y, float xscale, float yscale)) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
670 |
if (callback == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
671 |
fc_render_callback = &FC_DefaultRenderCallback; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
672 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
673 |
else { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
674 |
fc_render_callback = callback; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
675 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
676 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
677 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
678 |
void FC_GetUTF8FromCodepoint(char* result, Uint32 codepoint) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
679 |
char a, b, c, d; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
680 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
681 |
if (result == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
682 |
return; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
683 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
684 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
685 |
a = (codepoint >> 24) & 0xFF; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
686 |
b = (codepoint >> 16) & 0xFF; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
687 |
c = (codepoint >> 8) & 0xFF; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
688 |
d = codepoint & 0xFF; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
689 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
690 |
if (a == 0) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
691 |
if (b == 0) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
692 |
if (c == 0) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
693 |
result[0] = d; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
694 |
result[1] = '\0'; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
695 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
696 |
else { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
697 |
result[0] = c; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
698 |
result[1] = d; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
699 |
result[2] = '\0'; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
700 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
701 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
702 |
else { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
703 |
result[0] = b; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
704 |
result[1] = c; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
705 |
result[2] = d; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
706 |
result[3] = '\0'; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
707 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
708 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
709 |
else { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
710 |
result[0] = a; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
711 |
result[1] = b; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
712 |
result[2] = c; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
713 |
result[3] = d; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
714 |
result[4] = '\0'; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
715 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
716 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
717 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
718 |
Uint32 FC_GetCodepointFromUTF8(const char** c, Uint8 advance_pointer) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
719 |
Uint32 result = 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
720 |
const char* str; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
721 |
if (c == NULL || *c == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
722 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
723 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
724 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
725 |
str = *c; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
726 |
if ((unsigned char)*str <= 0x7F) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
727 |
result = *str; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
728 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
729 |
else if ((unsigned char)*str < 0xE0) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
730 |
result |= (unsigned char)(*str) << 8; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
731 |
result |= (unsigned char)(*(str+1)); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
732 |
if (advance_pointer) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
733 |
*c += 1; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
734 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
735 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
736 |
else if ((unsigned char)*str < 0xF0) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
737 |
result |= (unsigned char)(*str) << 16; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
738 |
result |= (unsigned char)(*(str+1)) << 8; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
739 |
result |= (unsigned char)(*(str+2)); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
740 |
if (advance_pointer) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
741 |
*c += 2; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
742 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
743 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
744 |
else { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
745 |
result |= (unsigned char)(*str) << 24; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
746 |
result |= (unsigned char)(*(str+1)) << 16; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
747 |
result |= (unsigned char)(*(str+2)) << 8; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
748 |
result |= (unsigned char)(*(str+3)); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
749 |
if (advance_pointer) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
750 |
*c += 3; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
751 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
752 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
753 |
return result; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
754 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
755 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
756 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
757 |
void FC_SetLoadingString(FC_Font* font, const char* string) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
758 |
if (font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
759 |
return; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
760 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
761 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
762 |
free(font->loading_string); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
763 |
font->loading_string = U8_strdup(string); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
764 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
765 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
766 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
767 |
void FC_SetBufferSize(unsigned int size) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
768 |
free(fc_buffer); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
769 |
if (size > 0) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
770 |
fc_buffer = (char*)malloc(size); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
771 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
772 |
else { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
773 |
fc_buffer = (char*)malloc(1024); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
774 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
775 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
776 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
777 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
778 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
779 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
780 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
781 |
// Constructors |
| 078900fe |
sago007 |
2015-12-05 15:31 |
782 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
783 |
static void FC_Init(FC_Font* font) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
784 |
if (font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
785 |
return; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
786 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
787 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
788 |
#ifndef FC_USE_SDL_GPU |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
789 |
font->renderer = NULL; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
790 |
#endif |
| 078900fe |
sago007 |
2015-12-05 15:31 |
791 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
792 |
font->ttf_source = NULL; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
793 |
font->owns_ttf_source = 0; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
794 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
795 |
font->filter = FC_FILTER_NEAREST; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
796 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
797 |
font->default_color.r = 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
798 |
font->default_color.g = 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
799 |
font->default_color.b = 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
800 |
FC_GET_ALPHA(font->default_color) = 255; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
801 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
802 |
font->height = 0; // ascent+descent |
| 078900fe |
sago007 |
2015-12-05 15:31 |
803 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
804 |
font->maxWidth = 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
805 |
font->baseline = 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
806 |
font->ascent = 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
807 |
font->descent = 0; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
808 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
809 |
font->lineSpacing = 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
810 |
font->letterSpacing = 0; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
811 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
812 |
// Give a little offset for when filtering/mipmaps are used. Depending on mipmap level, this will still not be enough. |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
813 |
font->last_glyph.rect.x = FC_CACHE_PADDING; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
814 |
font->last_glyph.rect.y = FC_CACHE_PADDING; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
815 |
font->last_glyph.rect.w = 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
816 |
font->last_glyph.rect.h = 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
817 |
font->last_glyph.cache_level = 0; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
818 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
819 |
if (font->glyphs != NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
820 |
FC_MapFree(font->glyphs); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
821 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
822 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
823 |
font->glyphs = FC_MapCreate(FC_DEFAULT_NUM_BUCKETS); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
824 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
825 |
font->glyph_cache_size = 3; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
826 |
font->glyph_cache_count = 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
827 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
828 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
829 |
font->glyph_cache = (FC_Image**)malloc(font->glyph_cache_size * sizeof(FC_Image*)); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
830 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
831 |
if (font->loading_string == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
832 |
font->loading_string = U8_strdup(FC_GetStringASCII()); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
833 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
834 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
835 |
if (fc_buffer == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
836 |
fc_buffer = (char*)malloc(1024); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
837 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
838 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
839 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
840 |
static Uint8 FC_GrowGlyphCache(FC_Font* font) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
841 |
if (font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
842 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
843 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
844 |
#ifdef FC_USE_SDL_GPU |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
845 |
GPU_Image* new_level = GPU_CreateImage(font->height * 12, font->height * 12, GPU_FORMAT_RGBA); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
846 |
#else |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
847 |
SDL_Texture* new_level = SDL_CreateTexture(font->renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, font->height * 12, font->height * 12); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
848 |
#endif |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
849 |
if (new_level == NULL || !FC_SetGlyphCacheLevel(font, font->glyph_cache_count, new_level)) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
850 |
FC_Log("Error: SDL_FontCache ran out of packing space and could not add another cache level.\n"); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
851 |
#ifdef FC_USE_SDL_GPU |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
852 |
GPU_FreeImage(new_level); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
853 |
#else |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
854 |
SDL_DestroyTexture(new_level); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
855 |
#endif |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
856 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
857 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
858 |
return 1; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
859 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
860 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
861 |
static Uint8 FC_UploadGlyphCache(FC_Font* font, int cache_level, SDL_Surface* data_surface) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
862 |
if (font == NULL || data_surface == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
863 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
864 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
865 |
#ifdef FC_USE_SDL_GPU |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
866 |
GPU_Image* new_level = GPU_CopyImageFromSurface(data_surface); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
867 |
if (FC_GetFilterMode(font) == FC_FILTER_LINEAR) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
868 |
GPU_SetImageFilter(new_level, GPU_FILTER_LINEAR); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
869 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
870 |
else { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
871 |
GPU_SetImageFilter(new_level, GPU_FILTER_NEAREST); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
872 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
873 |
#else |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
874 |
SDL_Texture* new_level; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
875 |
if (!fc_has_render_target_support) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
876 |
new_level = SDL_CreateTextureFromSurface(font->renderer, data_surface); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
877 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
878 |
else { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
879 |
// Must upload with render target enabled so we can put more glyphs on later |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
880 |
SDL_Renderer* renderer = font->renderer; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
881 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
882 |
// Set filter mode for new texture |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
883 |
const char* old_filter_mode = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
884 |
if (FC_GetFilterMode(font) == FC_FILTER_LINEAR) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
885 |
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1"); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
886 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
887 |
else { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
888 |
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0"); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
889 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
890 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
891 |
new_level = SDL_CreateTexture(renderer, data_surface->format->format, SDL_TEXTUREACCESS_TARGET, data_surface->w, data_surface->h); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
892 |
SDL_SetTextureBlendMode(new_level, SDL_BLENDMODE_BLEND); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
893 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
894 |
// Reset filter mode for the temp texture |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
895 |
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0"); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
896 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
897 |
{ |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
898 |
Uint8 r, g, b, a; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
899 |
SDL_Texture* temp = SDL_CreateTextureFromSurface(renderer, data_surface); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
900 |
SDL_SetTextureBlendMode(temp, SDL_BLENDMODE_NONE); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
901 |
SDL_SetRenderTarget(renderer, new_level); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
902 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
903 |
SDL_GetRenderDrawColor(renderer, &r, &g, &b, &a); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
904 |
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
905 |
SDL_RenderClear(renderer); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
906 |
SDL_SetRenderDrawColor(renderer, r, g, b, a); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
907 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
908 |
SDL_RenderCopy(renderer, temp, NULL, NULL); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
909 |
SDL_SetRenderTarget(renderer, NULL); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
910 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
911 |
SDL_DestroyTexture(temp); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
912 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
913 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
914 |
// Reset to the old filter value |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
915 |
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, old_filter_mode); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
916 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
917 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
918 |
#endif |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
919 |
if (new_level == NULL || !FC_SetGlyphCacheLevel(font, cache_level, new_level)) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
920 |
FC_Log("Error: SDL_FontCache ran out of packing space and could not add another cache level.\n"); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
921 |
#ifdef FC_USE_SDL_GPU |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
922 |
GPU_FreeImage(new_level); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
923 |
#else |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
924 |
SDL_DestroyTexture(new_level); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
925 |
#endif |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
926 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
927 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
928 |
return 1; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
929 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
930 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
931 |
static FC_GlyphData* FC_PackGlyphData(FC_Font* font, Uint32 codepoint, Uint16 width, Uint16 maxWidth, Uint16 maxHeight) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
932 |
FC_Map* glyphs = font->glyphs; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
933 |
FC_GlyphData* last_glyph = &font->last_glyph; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
934 |
Uint16 height = font->height + FC_CACHE_PADDING; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
935 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
936 |
if (last_glyph->rect.x + last_glyph->rect.w + width >= maxWidth - FC_CACHE_PADDING) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
937 |
if (last_glyph->rect.y + height + height >= maxHeight - FC_CACHE_PADDING) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
938 |
// Get ready to pack on the next cache level when it is ready |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
939 |
last_glyph->cache_level = font->glyph_cache_count; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
940 |
last_glyph->rect.x = FC_CACHE_PADDING; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
941 |
last_glyph->rect.y = FC_CACHE_PADDING; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
942 |
last_glyph->rect.w = 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
943 |
return NULL; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
944 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
945 |
else { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
946 |
// Go to next row |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
947 |
last_glyph->rect.x = FC_CACHE_PADDING; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
948 |
last_glyph->rect.y += height; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
949 |
last_glyph->rect.w = 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
950 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
951 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
952 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
953 |
// Move to next space |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
954 |
last_glyph->rect.x += last_glyph->rect.w + 1 + FC_CACHE_PADDING; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
955 |
last_glyph->rect.w = width; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
956 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
957 |
return FC_MapInsert(glyphs, codepoint, FC_MakeGlyphData(last_glyph->cache_level, last_glyph->rect.x, last_glyph->rect.y, last_glyph->rect.w, last_glyph->rect.h)); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
958 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
959 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
960 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
961 |
FC_Image* FC_GetGlyphCacheLevel(FC_Font* font, int cache_level) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
962 |
if (font == NULL || cache_level < 0 || cache_level > font->glyph_cache_count) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
963 |
return NULL; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
964 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
965 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
966 |
return font->glyph_cache[cache_level]; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
967 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
968 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
969 |
Uint8 FC_SetGlyphCacheLevel(FC_Font* font, int cache_level, FC_Image* cache_texture) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
970 |
if (font == NULL || cache_level < 0) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
971 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
972 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
973 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
974 |
// Must be sequentially added |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
975 |
if (cache_level > font->glyph_cache_count + 1) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
976 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
977 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
978 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
979 |
if (cache_level == font->glyph_cache_count) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
980 |
font->glyph_cache_count++; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
981 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
982 |
// Grow cache? |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
983 |
if (font->glyph_cache_count > font->glyph_cache_size) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
984 |
// Copy old cache to new one |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
985 |
int i; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
986 |
FC_Image** new_cache; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
987 |
new_cache = (FC_Image**)malloc(font->glyph_cache_count * sizeof(FC_Image*)); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
988 |
for (i = 0; i < font->glyph_cache_size; ++i) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
989 |
new_cache[i] = font->glyph_cache[i]; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
990 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
991 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
992 |
// Save new cache |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
993 |
free(font->glyph_cache); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
994 |
font->glyph_cache_size = font->glyph_cache_count; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
995 |
font->glyph_cache = new_cache; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
996 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
997 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
998 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
999 |
font->glyph_cache[cache_level] = cache_texture; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1000 |
return 1; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1001 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1002 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1003 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1004 |
FC_Font* FC_CreateFont(void) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1005 |
FC_Font* font; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1006 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1007 |
font = (FC_Font*)malloc(sizeof(FC_Font)); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1008 |
memset(font, 0, sizeof(FC_Font)); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1009 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1010 |
FC_Init(font); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1011 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1012 |
return font; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1013 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1014 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1015 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1016 |
// Assume this many will be enough... |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1017 |
#define FC_LOAD_MAX_SURFACES 10 |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1018 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1019 |
#ifdef FC_USE_SDL_GPU |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1020 |
Uint8 FC_LoadFontFromTTF(FC_Font* font, TTF_Font* ttf, SDL_Color color) |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1021 |
#else |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1022 |
Uint8 FC_LoadFontFromTTF(FC_Font* font, SDL_Renderer* renderer, TTF_Font* ttf, SDL_Color color) |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1023 |
#endif |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1024 |
{ |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1025 |
if (font == NULL || ttf == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1026 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1027 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1028 |
#ifndef FC_USE_SDL_GPU |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1029 |
if (renderer == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1030 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1031 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1032 |
#endif |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1033 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1034 |
FC_ClearFont(font); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1035 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1036 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1037 |
// Might as well check render target support here |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1038 |
#ifdef FC_USE_SDL_GPU |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1039 |
fc_has_render_target_support = GPU_IsFeatureEnabled(GPU_FEATURE_RENDER_TARGETS); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1040 |
#else |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1041 |
SDL_RendererInfo info; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1042 |
SDL_GetRendererInfo(renderer, &info); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1043 |
fc_has_render_target_support = (info.flags & SDL_RENDERER_TARGETTEXTURE); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1044 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1045 |
font->renderer = renderer; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1046 |
#endif |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1047 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1048 |
font->ttf_source = ttf; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1049 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1050 |
//font->line_height = TTF_FontLineSkip(ttf); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1051 |
font->height = TTF_FontHeight(ttf); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1052 |
font->ascent = TTF_FontAscent(ttf); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1053 |
font->descent = -TTF_FontDescent(ttf); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1054 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1055 |
font->baseline = font->height - font->descent; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1056 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1057 |
font->default_color = color; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1058 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1059 |
{ |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1060 |
SDL_Color white = {255, 255, 255, 255}; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1061 |
SDL_Surface* glyph_surf; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1062 |
char buff[5]; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1063 |
const char* buff_ptr = buff; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1064 |
const char* source_string; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1065 |
Uint8 packed = 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1066 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1067 |
// Copy glyphs from the surface to the font texture and store the position data |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1068 |
// Pack row by row into a square texture |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1069 |
// Try figuring out dimensions that make sense for the font size. |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1070 |
unsigned int w = font->height*12; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1071 |
unsigned int h = font->height*12; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1072 |
SDL_Surface* surfaces[FC_LOAD_MAX_SURFACES]; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1073 |
int num_surfaces = 1; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1074 |
surfaces[0] = FC_CreateSurface32(w, h); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1075 |
font->last_glyph.rect.x = FC_CACHE_PADDING; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1076 |
font->last_glyph.rect.y = FC_CACHE_PADDING; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1077 |
font->last_glyph.rect.w = 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1078 |
font->last_glyph.rect.h = font->height; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1079 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1080 |
memset(buff, 0, 5); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1081 |
source_string = font->loading_string; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1082 |
for (; *source_string != '\0'; source_string = U8_next(source_string)) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1083 |
if (!U8_charcpy(buff, source_string, 5)) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1084 |
continue; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1085 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1086 |
glyph_surf = TTF_RenderUTF8_Blended(ttf, buff, white); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1087 |
if (glyph_surf == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1088 |
continue; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1089 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1090 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1091 |
// Try packing. If it fails, create a new surface for the next cache level. |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1092 |
packed = (FC_PackGlyphData(font, FC_GetCodepointFromUTF8(&buff_ptr, 0), glyph_surf->w, surfaces[num_surfaces-1]->w, surfaces[num_surfaces-1]->h) != NULL); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1093 |
if (!packed) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1094 |
int i = num_surfaces-1; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1095 |
if (num_surfaces >= FC_LOAD_MAX_SURFACES) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1096 |
// Can't do any more! |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1097 |
FC_Log("SDL_FontCache error: Could not create enough cache surfaces to fit all of the loading string!\n"); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1098 |
SDL_FreeSurface(glyph_surf); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1099 |
break; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1100 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1101 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1102 |
// Upload the current surface to the glyph cache now so we can keep the cache level packing cursor up to date as we go. |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1103 |
FC_UploadGlyphCache(font, i, surfaces[i]); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1104 |
SDL_FreeSurface(surfaces[i]); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1105 |
#ifndef FC_USE_SDL_GPU |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1106 |
SDL_SetTextureBlendMode(font->glyph_cache[i], SDL_BLENDMODE_BLEND); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1107 |
#endif |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1108 |
// Update the glyph cursor to the new cache level. We need to do this here because the actual cache lags behind our use of the packing above. |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1109 |
font->last_glyph.cache_level = num_surfaces; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1110 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1111 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1112 |
surfaces[num_surfaces] = FC_CreateSurface32(w, h); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1113 |
num_surfaces++; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1114 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1115 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1116 |
// Try packing for the new surface, then blit onto it. |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1117 |
if (packed || FC_PackGlyphData(font, FC_GetCodepointFromUTF8(&buff_ptr, 0), glyph_surf->w, surfaces[num_surfaces-1]->w, surfaces[num_surfaces-1]->h) != NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1118 |
SDL_SetSurfaceBlendMode(glyph_surf, SDL_BLENDMODE_NONE); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1119 |
SDL_Rect srcRect = {0, 0, glyph_surf->w, glyph_surf->h}; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1120 |
SDL_Rect destrect = font->last_glyph.rect; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1121 |
SDL_BlitSurface(glyph_surf, &srcRect, surfaces[num_surfaces-1], &destrect); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1122 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1123 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1124 |
SDL_FreeSurface(glyph_surf); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1125 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1126 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1127 |
{ |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1128 |
int i = num_surfaces-1; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1129 |
FC_UploadGlyphCache(font, i, surfaces[i]); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1130 |
SDL_FreeSurface(surfaces[i]); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1131 |
#ifndef FC_USE_SDL_GPU |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1132 |
SDL_SetTextureBlendMode(font->glyph_cache[i], SDL_BLENDMODE_BLEND); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1133 |
#endif |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1134 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1135 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1136 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1137 |
return 1; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1138 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1139 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1140 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1141 |
#ifdef FC_USE_SDL_GPU |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1142 |
Uint8 FC_LoadFont(FC_Font* font, const char* filename_ttf, Uint32 pointSize, SDL_Color color, int style) |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1143 |
#else |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1144 |
Uint8 FC_LoadFont(FC_Font* font, FC_Target* renderer, const char* filename_ttf, Uint32 pointSize, SDL_Color color, int style) |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1145 |
#endif |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1146 |
{ |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1147 |
SDL_RWops* rwops; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1148 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1149 |
if (font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1150 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1151 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1152 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1153 |
rwops = SDL_RWFromFile(filename_ttf, "rb"); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1154 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1155 |
if (rwops == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1156 |
FC_Log("Unable to open file for reading: %s \n", SDL_GetError()); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1157 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1158 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1159 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1160 |
#ifdef FC_USE_SDL_GPU |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1161 |
return FC_LoadFont_RW(font, rwops, 1, pointSize, color, style); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1162 |
#else |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1163 |
return FC_LoadFont_RW(font, renderer, rwops, 1, pointSize, color, style); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1164 |
#endif |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1165 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1166 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1167 |
#ifdef FC_USE_SDL_GPU |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1168 |
Uint8 FC_LoadFont_RW(FC_Font* font, SDL_RWops* file_rwops_ttf, Uint8 own_rwops, Uint32 pointSize, SDL_Color color, int style) |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1169 |
#else |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1170 |
Uint8 FC_LoadFont_RW(FC_Font* font, FC_Target* renderer, SDL_RWops* file_rwops_ttf, Uint8 own_rwops, Uint32 pointSize, SDL_Color color, int style) |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1171 |
#endif |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1172 |
{ |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1173 |
Uint8 result; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1174 |
TTF_Font* ttf; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1175 |
Uint8 outline; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1176 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1177 |
if (font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1178 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1179 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1180 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1181 |
if (!TTF_WasInit() && TTF_Init() < 0) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1182 |
FC_Log("Unable to initialize SDL_ttf: %s \n", TTF_GetError()); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1183 |
if (own_rwops) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1184 |
SDL_RWclose(file_rwops_ttf); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1185 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1186 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1187 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1188 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1189 |
ttf = TTF_OpenFontRW(file_rwops_ttf, own_rwops, pointSize); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1190 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1191 |
if (ttf == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1192 |
FC_Log("Unable to load TrueType font: %s \n", TTF_GetError()); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1193 |
if (own_rwops) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1194 |
SDL_RWclose(file_rwops_ttf); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1195 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1196 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1197 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1198 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1199 |
outline = (style & TTF_STYLE_OUTLINE); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1200 |
if (outline) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1201 |
style &= ~TTF_STYLE_OUTLINE; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1202 |
TTF_SetFontOutline(ttf, 1); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1203 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1204 |
TTF_SetFontStyle(ttf, style); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1205 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1206 |
#ifdef FC_USE_SDL_GPU |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1207 |
result = FC_LoadFontFromTTF(font, ttf, color); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1208 |
#else |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1209 |
result = FC_LoadFontFromTTF(font, renderer, ttf, color); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1210 |
#endif |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1211 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1212 |
// Can only load new (uncached) glyphs if we can keep the SDL_RWops open. |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1213 |
font->owns_ttf_source = own_rwops; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1214 |
if (!own_rwops) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1215 |
TTF_CloseFont(font->ttf_source); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1216 |
font->ttf_source = NULL; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1217 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1218 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1219 |
return result; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1220 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1221 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
1222 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1223 |
void FC_ClearFont(FC_Font* font) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1224 |
int i; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1225 |
if (font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1226 |
return; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1227 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1228 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1229 |
// Release resources |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1230 |
if (font->owns_ttf_source) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1231 |
TTF_CloseFont(font->ttf_source); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1232 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1233 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1234 |
font->owns_ttf_source = 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1235 |
font->ttf_source = NULL; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1236 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1237 |
// Delete glyph map |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1238 |
FC_MapFree(font->glyphs); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1239 |
font->glyphs = NULL; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1240 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1241 |
// Delete glyph cache |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1242 |
for (i = 0; i < font->glyph_cache_count; ++i) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1243 |
#ifdef FC_USE_SDL_GPU |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1244 |
GPU_FreeImage(font->glyph_cache[i]); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1245 |
#else |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1246 |
SDL_DestroyTexture(font->glyph_cache[i]); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1247 |
#endif |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1248 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1249 |
free(font->glyph_cache); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1250 |
font->glyph_cache = NULL; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1251 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1252 |
// Reset font |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1253 |
FC_Init(font); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1254 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1255 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1256 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1257 |
void FC_FreeFont(FC_Font* font) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1258 |
int i; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1259 |
if (font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1260 |
return; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1261 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1262 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1263 |
// Release resources |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1264 |
if (font->owns_ttf_source) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1265 |
TTF_CloseFont(font->ttf_source); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1266 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1267 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1268 |
// Delete glyph map |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1269 |
FC_MapFree(font->glyphs); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1270 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1271 |
// Delete glyph cache |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1272 |
for (i = 0; i < font->glyph_cache_count; ++i) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1273 |
#ifdef FC_USE_SDL_GPU |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1274 |
GPU_FreeImage(font->glyph_cache[i]); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1275 |
#else |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1276 |
SDL_DestroyTexture(font->glyph_cache[i]); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1277 |
#endif |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1278 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1279 |
free(font->glyph_cache); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1280 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1281 |
free(font->loading_string); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1282 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1283 |
free(font); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1284 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1285 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1286 |
int FC_GetNumCacheLevels(FC_Font* font) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1287 |
return font->glyph_cache_count; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1288 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1289 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1290 |
Uint8 FC_AddGlyphToCache(FC_Font* font, SDL_Surface* glyph_surface) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1291 |
if (font == NULL || glyph_surface == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1292 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1293 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1294 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1295 |
SDL_SetSurfaceBlendMode(glyph_surface, SDL_BLENDMODE_NONE); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1296 |
FC_Image* dest = FC_GetGlyphCacheLevel(font, font->last_glyph.cache_level); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1297 |
if (dest == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1298 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1299 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1300 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1301 |
#ifdef FC_USE_SDL_GPU |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1302 |
{ |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1303 |
GPU_Target* target = GPU_LoadTarget(dest); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1304 |
if (target == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1305 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1306 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1307 |
GPU_Image* img = GPU_CopyImageFromSurface(glyph_surface); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1308 |
GPU_SetImageFilter(img, GPU_FILTER_NEAREST); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1309 |
GPU_SetBlendMode(img, GPU_BLEND_SET); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1310 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1311 |
SDL_Rect destrect = font->last_glyph.rect; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1312 |
GPU_Blit(img, NULL, target, destrect.x + destrect.w/2, destrect.y + destrect.h/2); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1313 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1314 |
GPU_FreeImage(img); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1315 |
GPU_FreeTarget(target); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1316 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1317 |
#else |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1318 |
{ |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1319 |
SDL_Texture* img = SDL_CreateTextureFromSurface(font->renderer, glyph_surface); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1320 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1321 |
SDL_Rect destrect = font->last_glyph.rect; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1322 |
SDL_SetRenderTarget(font->renderer, dest); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1323 |
SDL_RenderCopy(font->renderer, img, NULL, &destrect); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1324 |
SDL_SetRenderTarget(font->renderer, NULL); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1325 |
SDL_DestroyTexture(img); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1326 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1327 |
#endif |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1328 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1329 |
return 1; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1330 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1331 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1332 |
Uint8 FC_GetGlyphData(FC_Font* font, FC_GlyphData* result, Uint32 codepoint) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1333 |
FC_GlyphData* e = FC_MapFind(font->glyphs, codepoint); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1334 |
if (e == NULL || result == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1335 |
char buff[5]; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1336 |
int w, h; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1337 |
SDL_Color white = {255, 255, 255, 255}; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1338 |
SDL_Surface* surf; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1339 |
FC_Image* cache_image; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1340 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1341 |
if (font->ttf_source == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1342 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1343 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1344 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1345 |
FC_GetUTF8FromCodepoint(buff, codepoint); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1346 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1347 |
cache_image = FC_GetGlyphCacheLevel(font, font->last_glyph.cache_level); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1348 |
if (cache_image == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1349 |
FC_Log("SDL_FontCache: Failed to load cache image, so cannot add new glyphs!\n"); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1350 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1351 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1352 |
#ifdef FC_USE_SDL_GPU |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1353 |
w = cache_image->w; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1354 |
h = cache_image->h; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1355 |
#else |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1356 |
SDL_QueryTexture(cache_image, NULL, NULL, &w, &h); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1357 |
#endif |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1358 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1359 |
surf = TTF_RenderUTF8_Blended(font->ttf_source, buff, white); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1360 |
if (surf == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1361 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1362 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1363 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1364 |
e = FC_PackGlyphData(font, codepoint, surf->w, w, h); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1365 |
if (e == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1366 |
// Grow the cache |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1367 |
FC_GrowGlyphCache(font); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1368 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1369 |
// Try packing again |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1370 |
e = FC_PackGlyphData(font, codepoint, surf->w, w, h); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1371 |
if (e == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1372 |
SDL_FreeSurface(surf); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1373 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1374 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1375 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1376 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1377 |
// Render onto the cache texture |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1378 |
FC_AddGlyphToCache(font, surf); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1379 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1380 |
SDL_FreeSurface(surf); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1381 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1382 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1383 |
if (result != NULL && e != NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1384 |
*result = *e; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1385 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1386 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1387 |
return 1; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1388 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1389 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1390 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1391 |
FC_GlyphData* FC_SetGlyphData(FC_Font* font, Uint32 codepoint, FC_GlyphData glyph_data) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1392 |
return FC_MapInsert(font->glyphs, codepoint, glyph_data); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1393 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1394 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
1395 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
1396 |
// Drawing |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1397 |
static FC_Rect FC_RenderLeft(FC_Font* font, FC_Target* dest, float x, float y, FC_Scale scale, const char* text) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1398 |
const char* c = text; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1399 |
FC_Rect srcRect; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1400 |
FC_Rect dstRect; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1401 |
FC_Rect dirtyRect = FC_MakeRect(x, y, 0, 0); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1402 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1403 |
FC_GlyphData glyph; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1404 |
Uint32 codepoint; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1405 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1406 |
float destX = x; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1407 |
float destY = y; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1408 |
float destH; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1409 |
float destLineSpacing; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1410 |
float destLetterSpacing; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1411 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1412 |
if (font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1413 |
return dirtyRect; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1414 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1415 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1416 |
destH = font->height * scale.y; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1417 |
destLineSpacing = font->lineSpacing*scale.y; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1418 |
destLetterSpacing = font->letterSpacing*scale.x; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1419 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1420 |
if (c == NULL || font->glyph_cache_count == 0 || dest == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1421 |
return dirtyRect; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1422 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1423 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1424 |
int newlineX = x; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1425 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1426 |
for (; *c != '\0'; c++) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1427 |
if (*c == '\n') { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1428 |
destX = newlineX; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1429 |
destY += destH + destLineSpacing; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1430 |
continue; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1431 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1432 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1433 |
codepoint = FC_GetCodepointFromUTF8(&c, 1); // Increments 'c' to skip the extra UTF-8 bytes |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1434 |
if (!FC_GetGlyphData(font, &glyph, codepoint)) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1435 |
codepoint = ' '; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1436 |
if (!FC_GetGlyphData(font, &glyph, codepoint)) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1437 |
continue; // Skip bad characters |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1438 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1439 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1440 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1441 |
if (codepoint == ' ') { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1442 |
destX += glyph.rect.w*scale.x + destLetterSpacing; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1443 |
continue; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1444 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1445 |
/*if(destX >= dest->w) |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1446 |
continue; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1447 |
if(destY >= dest->h) |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1448 |
continue;*/ |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1449 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1450 |
#ifdef FC_USE_SDL_GPU |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1451 |
srcRect.x = glyph.rect.x; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1452 |
srcRect.y = glyph.rect.y; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1453 |
srcRect.w = glyph.rect.w; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1454 |
srcRect.h = glyph.rect.h; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1455 |
#else |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1456 |
srcRect = glyph.rect; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1457 |
#endif |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1458 |
dstRect = fc_render_callback(FC_GetGlyphCacheLevel(font, glyph.cache_level), &srcRect, dest, destX, destY, scale.x, scale.y); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1459 |
if (dirtyRect.w == 0 || dirtyRect.h == 0) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1460 |
dirtyRect = dstRect; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1461 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1462 |
else { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1463 |
dirtyRect = FC_RectUnion(dirtyRect, dstRect); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1464 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1465 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1466 |
destX += glyph.rect.w*scale.x + destLetterSpacing; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1467 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1468 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1469 |
return dirtyRect; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1470 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1471 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1472 |
static void set_color_for_all_caches(FC_Font* font, SDL_Color color) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1473 |
// TODO: How can I predict which glyph caches are to be used? |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1474 |
FC_Image* img; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1475 |
int i; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1476 |
int num_levels = FC_GetNumCacheLevels(font); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1477 |
for (i = 0; i < num_levels; ++i) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1478 |
img = FC_GetGlyphCacheLevel(font, i); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1479 |
set_color(img, color.r, color.g, color.b, FC_GET_ALPHA(color)); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1480 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1481 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1482 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1483 |
FC_Rect FC_Draw(FC_Font* font, FC_Target* dest, float x, float y, const char* formatted_text, ...) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1484 |
if (formatted_text == NULL || font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1485 |
return FC_MakeRect(x, y, 0, 0); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1486 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1487 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1488 |
FC_EXTRACT_VARARGS(fc_buffer, formatted_text); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1489 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1490 |
set_color_for_all_caches(font, font->default_color); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1491 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1492 |
return FC_RenderLeft(font, dest, x, y, FC_MakeScale(1,1), fc_buffer); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1493 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1494 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
1495 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
1496 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1497 |
typedef struct FC_StringList { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1498 |
char* value; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1499 |
struct FC_StringList* next; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1500 |
} FC_StringList; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1501 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1502 |
void FC_StringListFree(FC_StringList* node) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1503 |
// Delete the nodes in order |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1504 |
while (node != NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1505 |
FC_StringList* last = node; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1506 |
node = node->next; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1507 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1508 |
free(last->value); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1509 |
free(last); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1510 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1511 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1512 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1513 |
FC_StringList** FC_StringListPushBack(FC_StringList** node, char* value, Uint8 copy) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1514 |
// Get to the last node |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1515 |
while (node != NULL && *node != NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1516 |
node = &(*node)->next; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1517 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1518 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1519 |
*node = (FC_StringList*)malloc(sizeof(FC_StringList)); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1520 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1521 |
(*node)->value = (copy? U8_strdup(value) : value); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1522 |
(*node)->next = NULL; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1523 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1524 |
return node; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1525 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1526 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1527 |
static FC_StringList* FC_Explode(const char* text, char delimiter) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1528 |
FC_StringList* head; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1529 |
FC_StringList* new_node; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1530 |
FC_StringList** node; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1531 |
const char* start; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1532 |
const char* end; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1533 |
unsigned int size; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1534 |
if (text == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1535 |
return NULL; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1536 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1537 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1538 |
head = NULL; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1539 |
node = &head; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1540 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1541 |
// Doesn't technically support UTF-8, but it's probably fine, right? |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1542 |
size = 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1543 |
start = end = text; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1544 |
while (1) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1545 |
if (*end == delimiter || *end == '\0') { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1546 |
*node = (FC_StringList*)malloc(sizeof(FC_StringList)); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1547 |
new_node = *node; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1548 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1549 |
new_node->value = (char*)malloc(size + 1); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1550 |
memcpy(new_node->value, start, size); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1551 |
new_node->value[size] = '\0'; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1552 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1553 |
new_node->next = NULL; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1554 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1555 |
if (*end == '\0') { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1556 |
break; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1557 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1558 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1559 |
node = &((*node)->next); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1560 |
start = end+1; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1561 |
size = 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1562 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1563 |
else { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1564 |
++size; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1565 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1566 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1567 |
++end; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1568 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1569 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1570 |
return head; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1571 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1572 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1573 |
static FC_StringList* FC_ExplodeAndKeep(const char* text, char delimiter) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1574 |
FC_StringList* head; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1575 |
FC_StringList* new_node; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1576 |
FC_StringList** node; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1577 |
const char* start; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1578 |
const char* end; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1579 |
unsigned int size; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1580 |
if (text == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1581 |
return NULL; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1582 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1583 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1584 |
head = NULL; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1585 |
node = &head; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1586 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1587 |
// Doesn't technically support UTF-8, but it's probably fine, right? |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1588 |
size = 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1589 |
start = end = text; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1590 |
while (1) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1591 |
if (*end == delimiter || *end == '\0') { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1592 |
*node = (FC_StringList*)malloc(sizeof(FC_StringList)); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1593 |
new_node = *node; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1594 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1595 |
new_node->value = (char*)malloc(size + 1); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1596 |
memcpy(new_node->value, start, size); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1597 |
new_node->value[size] = '\0'; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1598 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1599 |
new_node->next = NULL; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1600 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1601 |
if (*end == '\0') { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1602 |
break; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1603 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1604 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1605 |
node = &((*node)->next); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1606 |
start = end; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1607 |
size = 1; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1608 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1609 |
else { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1610 |
++size; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1611 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1612 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1613 |
++end; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1614 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1615 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1616 |
return head; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1617 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1618 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1619 |
static void FC_RenderAlign(FC_Font* font, FC_Target* dest, float x, float y, int width, FC_Scale scale, FC_AlignEnum align, const char* text) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1620 |
switch (align) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1621 |
case FC_ALIGN_LEFT: |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1622 |
FC_RenderLeft(font, dest, x, y, scale, text); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1623 |
break; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1624 |
case FC_ALIGN_CENTER: |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1625 |
FC_RenderCenter(font, dest, x + width/2, y, scale, text); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1626 |
break; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1627 |
case FC_ALIGN_RIGHT: |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1628 |
FC_RenderRight(font, dest, x + width, y, scale, text); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1629 |
break; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1630 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1631 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1632 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1633 |
static FC_StringList* FC_GetBufferFitToColumn(FC_Font* font, int width, FC_Scale scale, Uint8 keep_newlines) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1634 |
FC_StringList* result = NULL; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1635 |
FC_StringList** current = &result; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1636 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1637 |
FC_StringList* ls, *iter; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1638 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1639 |
ls = (keep_newlines? FC_ExplodeAndKeep(fc_buffer, '\n') : FC_Explode(fc_buffer, '\n')); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1640 |
for (iter = ls; iter != NULL; iter = iter->next) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1641 |
char* line = iter->value; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1642 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1643 |
// If line is too long, then add words one at a time until we go over. |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1644 |
if (width > 0 && FC_GetWidth(font, "%s", line) > width) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1645 |
FC_StringList* words, *word_iter; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1646 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1647 |
words = FC_Explode(line, ' '); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1648 |
// Skip the first word for the iterator, so there will always be at least one word per line |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1649 |
line = new_concat(words->value, " "); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1650 |
for (word_iter = words->next; word_iter != NULL; word_iter = word_iter->next) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1651 |
char* line_plus_word = new_concat(line, word_iter->value); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1652 |
char* word_plus_space = new_concat(word_iter->value, " "); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1653 |
if (FC_GetWidth(font, line_plus_word) > width) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1654 |
current = FC_StringListPushBack(current, line, 0); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1655 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1656 |
line = word_plus_space; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1657 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1658 |
else { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1659 |
replace_concat(&line, word_plus_space); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1660 |
free(word_plus_space); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1661 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1662 |
free(line_plus_word); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1663 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1664 |
current = FC_StringListPushBack(current, line, 0); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1665 |
FC_StringListFree(words); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1666 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1667 |
else { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1668 |
current = FC_StringListPushBack(current, line, 0); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1669 |
iter->value = NULL; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1670 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1671 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1672 |
FC_StringListFree(ls); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1673 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1674 |
return result; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1675 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1676 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1677 |
static void FC_DrawColumnFromBuffer(FC_Font* font, FC_Target* dest, FC_Rect box, int* total_height, FC_Scale scale, FC_AlignEnum align) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1678 |
int y = box.y; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1679 |
FC_StringList* ls, *iter; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1680 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1681 |
ls = FC_GetBufferFitToColumn(font, box.w, scale, 0); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1682 |
for (iter = ls; iter != NULL; iter = iter->next) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1683 |
FC_RenderAlign(font, dest, box.x, y, box.w, scale, align, iter->value); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1684 |
y += FC_GetLineHeight(font); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1685 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1686 |
FC_StringListFree(ls); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1687 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1688 |
if (total_height != NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1689 |
*total_height = y - box.y; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1690 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1691 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1692 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1693 |
FC_Rect FC_DrawBox(FC_Font* font, FC_Target* dest, FC_Rect box, const char* formatted_text, ...) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1694 |
Uint8 useClip; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1695 |
if (formatted_text == NULL || font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1696 |
return FC_MakeRect(box.x, box.y, 0, 0); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1697 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1698 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1699 |
FC_EXTRACT_VARARGS(fc_buffer, formatted_text); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1700 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1701 |
useClip = has_clip(dest); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1702 |
FC_Rect oldclip, newclip; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1703 |
if (useClip) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1704 |
oldclip = get_clip(dest); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1705 |
newclip = FC_RectIntersect(oldclip, box); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1706 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1707 |
else { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1708 |
newclip = box; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1709 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1710 |
set_clip(dest, &newclip); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1711 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1712 |
set_color_for_all_caches(font, font->default_color); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1713 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1714 |
FC_DrawColumnFromBuffer(font, dest, box, NULL, FC_MakeScale(1,1), FC_ALIGN_LEFT); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1715 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1716 |
if (useClip) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1717 |
set_clip(dest, &oldclip); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1718 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1719 |
else { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1720 |
set_clip(dest, NULL); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1721 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1722 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1723 |
return box; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1724 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1725 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1726 |
FC_Rect FC_DrawBoxAlign(FC_Font* font, FC_Target* dest, FC_Rect box, FC_AlignEnum align, const char* formatted_text, ...) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1727 |
Uint8 useClip; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1728 |
if (formatted_text == NULL || font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1729 |
return FC_MakeRect(box.x, box.y, 0, 0); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1730 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1731 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1732 |
FC_EXTRACT_VARARGS(fc_buffer, formatted_text); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1733 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1734 |
useClip = has_clip(dest); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1735 |
FC_Rect oldclip, newclip; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1736 |
if (useClip) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1737 |
oldclip = get_clip(dest); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1738 |
newclip = FC_RectIntersect(oldclip, box); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1739 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1740 |
else { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1741 |
newclip = box; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1742 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1743 |
set_clip(dest, &newclip); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1744 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1745 |
set_color_for_all_caches(font, font->default_color); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1746 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1747 |
FC_DrawColumnFromBuffer(font, dest, box, NULL, FC_MakeScale(1,1), align); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1748 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1749 |
if (useClip) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1750 |
set_clip(dest, &oldclip); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1751 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1752 |
else { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1753 |
set_clip(dest, NULL); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1754 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1755 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1756 |
return box; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1757 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1758 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1759 |
FC_Rect FC_DrawBoxScale(FC_Font* font, FC_Target* dest, FC_Rect box, FC_Scale scale, const char* formatted_text, ...) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1760 |
Uint8 useClip; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1761 |
if (formatted_text == NULL || font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1762 |
return FC_MakeRect(box.x, box.y, 0, 0); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1763 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1764 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1765 |
FC_EXTRACT_VARARGS(fc_buffer, formatted_text); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1766 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1767 |
useClip = has_clip(dest); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1768 |
FC_Rect oldclip, newclip; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1769 |
if (useClip) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1770 |
oldclip = get_clip(dest); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1771 |
newclip = FC_RectIntersect(oldclip, box); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1772 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1773 |
else { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1774 |
newclip = box; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1775 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1776 |
set_clip(dest, &newclip); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1777 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1778 |
set_color_for_all_caches(font, font->default_color); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1779 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1780 |
FC_DrawColumnFromBuffer(font, dest, box, NULL, scale, FC_ALIGN_LEFT); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1781 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1782 |
if (useClip) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1783 |
set_clip(dest, &oldclip); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1784 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1785 |
else { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1786 |
set_clip(dest, NULL); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1787 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1788 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1789 |
return box; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1790 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1791 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1792 |
FC_Rect FC_DrawBoxColor(FC_Font* font, FC_Target* dest, FC_Rect box, SDL_Color color, const char* formatted_text, ...) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1793 |
Uint8 useClip; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1794 |
if (formatted_text == NULL || font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1795 |
return FC_MakeRect(box.x, box.y, 0, 0); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1796 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1797 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1798 |
FC_EXTRACT_VARARGS(fc_buffer, formatted_text); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1799 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1800 |
useClip = has_clip(dest); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1801 |
FC_Rect oldclip, newclip; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1802 |
if (useClip) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1803 |
oldclip = get_clip(dest); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1804 |
newclip = FC_RectIntersect(oldclip, box); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1805 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1806 |
else { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1807 |
newclip = box; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1808 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1809 |
set_clip(dest, &newclip); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1810 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1811 |
set_color_for_all_caches(font, color); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1812 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1813 |
FC_DrawColumnFromBuffer(font, dest, box, NULL, FC_MakeScale(1,1), FC_ALIGN_LEFT); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1814 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1815 |
if (useClip) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1816 |
set_clip(dest, &oldclip); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1817 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1818 |
else { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1819 |
set_clip(dest, NULL); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1820 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1821 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1822 |
return box; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1823 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1824 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1825 |
FC_Rect FC_DrawBoxEffect(FC_Font* font, FC_Target* dest, FC_Rect box, FC_Effect effect, const char* formatted_text, ...) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1826 |
Uint8 useClip; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1827 |
if (formatted_text == NULL || font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1828 |
return FC_MakeRect(box.x, box.y, 0, 0); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1829 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1830 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1831 |
FC_EXTRACT_VARARGS(fc_buffer, formatted_text); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1832 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1833 |
useClip = has_clip(dest); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1834 |
FC_Rect oldclip, newclip; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1835 |
if (useClip) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1836 |
oldclip = get_clip(dest); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1837 |
newclip = FC_RectIntersect(oldclip, box); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1838 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1839 |
else { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1840 |
newclip = box; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1841 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1842 |
set_clip(dest, &newclip); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1843 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1844 |
set_color_for_all_caches(font, effect.color); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1845 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1846 |
FC_DrawColumnFromBuffer(font, dest, box, NULL, effect.scale, effect.alignment); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1847 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1848 |
if (useClip) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1849 |
set_clip(dest, &oldclip); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1850 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1851 |
else { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1852 |
set_clip(dest, NULL); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1853 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1854 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1855 |
return box; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1856 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1857 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1858 |
FC_Rect FC_DrawColumn(FC_Font* font, FC_Target* dest, float x, float y, Uint16 width, const char* formatted_text, ...) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1859 |
FC_Rect box = {x, y, width, 0}; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1860 |
int total_height; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1861 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1862 |
if (formatted_text == NULL || font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1863 |
return FC_MakeRect(x, y, 0, 0); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1864 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1865 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1866 |
FC_EXTRACT_VARARGS(fc_buffer, formatted_text); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1867 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1868 |
set_color_for_all_caches(font, font->default_color); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1869 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1870 |
FC_DrawColumnFromBuffer(font, dest, box, &total_height, FC_MakeScale(1,1), FC_ALIGN_LEFT); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1871 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1872 |
return FC_MakeRect(box.x, box.y, width, total_height); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1873 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1874 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1875 |
FC_Rect FC_DrawColumnAlign(FC_Font* font, FC_Target* dest, float x, float y, Uint16 width, FC_AlignEnum align, const char* formatted_text, ...) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1876 |
FC_Rect box = {x, y, width, 0}; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1877 |
int total_height; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1878 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1879 |
if (formatted_text == NULL || font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1880 |
return FC_MakeRect(x, y, 0, 0); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1881 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1882 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1883 |
FC_EXTRACT_VARARGS(fc_buffer, formatted_text); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1884 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1885 |
set_color_for_all_caches(font, font->default_color); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1886 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1887 |
switch (align) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1888 |
case FC_ALIGN_CENTER: |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1889 |
box.x -= width/2; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1890 |
break; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1891 |
case FC_ALIGN_RIGHT: |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1892 |
box.x -= width; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1893 |
break; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1894 |
default: |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1895 |
break; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1896 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1897 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1898 |
FC_DrawColumnFromBuffer(font, dest, box, &total_height, FC_MakeScale(1,1), align); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1899 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1900 |
return FC_MakeRect(box.x, box.y, width, total_height); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1901 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1902 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1903 |
FC_Rect FC_DrawColumnScale(FC_Font* font, FC_Target* dest, float x, float y, Uint16 width, FC_Scale scale, const char* formatted_text, ...) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1904 |
FC_Rect box = {x, y, width, 0}; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1905 |
int total_height; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1906 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1907 |
if (formatted_text == NULL || font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1908 |
return FC_MakeRect(x, y, 0, 0); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1909 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1910 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1911 |
FC_EXTRACT_VARARGS(fc_buffer, formatted_text); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1912 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1913 |
set_color_for_all_caches(font, font->default_color); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1914 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1915 |
FC_DrawColumnFromBuffer(font, dest, box, &total_height, scale, FC_ALIGN_LEFT); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1916 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1917 |
return FC_MakeRect(box.x, box.y, width, total_height); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1918 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1919 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1920 |
FC_Rect FC_DrawColumnColor(FC_Font* font, FC_Target* dest, float x, float y, Uint16 width, SDL_Color color, const char* formatted_text, ...) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1921 |
FC_Rect box = {x, y, width, 0}; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1922 |
int total_height; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1923 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1924 |
if (formatted_text == NULL || font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1925 |
return FC_MakeRect(x, y, 0, 0); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1926 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1927 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1928 |
FC_EXTRACT_VARARGS(fc_buffer, formatted_text); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1929 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1930 |
set_color_for_all_caches(font, color); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1931 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1932 |
FC_DrawColumnFromBuffer(font, dest, box, &total_height, FC_MakeScale(1,1), FC_ALIGN_LEFT); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1933 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1934 |
return FC_MakeRect(box.x, box.y, width, total_height); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1935 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1936 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1937 |
FC_Rect FC_DrawColumnEffect(FC_Font* font, FC_Target* dest, float x, float y, Uint16 width, FC_Effect effect, const char* formatted_text, ...) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1938 |
FC_Rect box = {x, y, width, 0}; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1939 |
int total_height; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1940 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1941 |
if (formatted_text == NULL || font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1942 |
return FC_MakeRect(x, y, 0, 0); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1943 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1944 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1945 |
FC_EXTRACT_VARARGS(fc_buffer, formatted_text); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1946 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1947 |
set_color_for_all_caches(font, effect.color); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1948 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1949 |
switch (effect.alignment) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1950 |
case FC_ALIGN_CENTER: |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1951 |
box.x -= width/2; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1952 |
break; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1953 |
case FC_ALIGN_RIGHT: |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1954 |
box.x -= width; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1955 |
break; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1956 |
default: |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1957 |
break; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1958 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1959 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1960 |
FC_DrawColumnFromBuffer(font, dest, box, &total_height, effect.scale, effect.alignment); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1961 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1962 |
return FC_MakeRect(box.x, box.y, width, total_height); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1963 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1964 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1965 |
static FC_Rect FC_RenderCenter(FC_Font* font, FC_Target* dest, float x, float y, FC_Scale scale, const char* text) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1966 |
FC_Rect result = {x, y, 0, 0}; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1967 |
if (text == NULL || font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1968 |
return result; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1969 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1970 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1971 |
char* str = U8_strdup(text); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1972 |
char* del = str; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1973 |
char* c; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1974 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1975 |
// Go through str, when you find a \n, replace it with \0 and print it |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1976 |
// then move down, back, and continue. |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1977 |
for (c = str; *c != '\0';) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1978 |
if (*c == '\n') { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1979 |
*c = '\0'; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1980 |
result = FC_RectUnion(FC_RenderLeft(font, dest, x - scale.x*FC_GetWidth(font, "%s", str)/2.0f, y, scale, str), result); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1981 |
*c = '\n'; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1982 |
c++; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1983 |
str = c; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1984 |
y += scale.y*font->height; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1985 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1986 |
else { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1987 |
c++; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1988 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1989 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1990 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1991 |
result = FC_RectUnion(FC_RenderLeft(font, dest, x - scale.x*FC_GetWidth(font, "%s", str)/2.0f, y, scale, str), result); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1992 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1993 |
free(del); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1994 |
return result; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1995 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
1996 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1997 |
static FC_Rect FC_RenderRight(FC_Font* font, FC_Target* dest, float x, float y, FC_Scale scale, const char* text) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1998 |
FC_Rect result = {x, y, 0, 0}; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
1999 |
if (text == NULL || font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2000 |
return result; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2001 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2002 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2003 |
char* str = U8_strdup(text); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2004 |
char* del = str; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2005 |
char* c; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2006 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2007 |
for (c = str; *c != '\0';) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2008 |
if (*c == '\n') { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2009 |
*c = '\0'; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2010 |
result = FC_RectUnion(FC_RenderLeft(font, dest, x - scale.x*FC_GetWidth(font, "%s", str), y, scale, str), result); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2011 |
*c = '\n'; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2012 |
c++; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2013 |
str = c; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2014 |
y += scale.y*font->height; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2015 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2016 |
else { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2017 |
c++; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2018 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2019 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2020 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2021 |
result = FC_RectUnion(FC_RenderLeft(font, dest, x - scale.x*FC_GetWidth(font, "%s", str), y, scale, str), result); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2022 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2023 |
free(del); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2024 |
return result; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2025 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2026 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2027 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2028 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2029 |
FC_Rect FC_DrawScale(FC_Font* font, FC_Target* dest, float x, float y, FC_Scale scale, const char* formatted_text, ...) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2030 |
if (formatted_text == NULL || font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2031 |
return FC_MakeRect(x, y, 0, 0); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2032 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2033 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2034 |
FC_EXTRACT_VARARGS(fc_buffer, formatted_text); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2035 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2036 |
set_color_for_all_caches(font, font->default_color); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2037 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2038 |
return FC_RenderLeft(font, dest, x, y, scale, fc_buffer); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2039 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2040 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2041 |
FC_Rect FC_DrawAlign(FC_Font* font, FC_Target* dest, float x, float y, FC_AlignEnum align, const char* formatted_text, ...) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2042 |
if (formatted_text == NULL || font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2043 |
return FC_MakeRect(x, y, 0, 0); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2044 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2045 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2046 |
FC_EXTRACT_VARARGS(fc_buffer, formatted_text); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2047 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2048 |
set_color_for_all_caches(font, font->default_color); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2049 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2050 |
FC_Rect result; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2051 |
switch (align) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2052 |
case FC_ALIGN_LEFT: |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2053 |
result = FC_RenderLeft(font, dest, x, y, FC_MakeScale(1,1), fc_buffer); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2054 |
break; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2055 |
case FC_ALIGN_CENTER: |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2056 |
result = FC_RenderCenter(font, dest, x, y, FC_MakeScale(1,1), fc_buffer); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2057 |
break; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2058 |
case FC_ALIGN_RIGHT: |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2059 |
result = FC_RenderRight(font, dest, x, y, FC_MakeScale(1,1), fc_buffer); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2060 |
break; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2061 |
default: |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2062 |
result = FC_MakeRect(x, y, 0, 0); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2063 |
break; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2064 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2065 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2066 |
return result; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2067 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2068 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2069 |
FC_Rect FC_DrawColor(FC_Font* font, FC_Target* dest, float x, float y, SDL_Color color, const char* formatted_text, ...) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2070 |
if (formatted_text == NULL || font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2071 |
return FC_MakeRect(x, y, 0, 0); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2072 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2073 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2074 |
FC_EXTRACT_VARARGS(fc_buffer, formatted_text); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2075 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2076 |
set_color_for_all_caches(font, color); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2077 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2078 |
return FC_RenderLeft(font, dest, x, y, FC_MakeScale(1,1), fc_buffer); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2079 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2080 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2081 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2082 |
FC_Rect FC_DrawEffect(FC_Font* font, FC_Target* dest, float x, float y, FC_Effect effect, const char* formatted_text, ...) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2083 |
if (formatted_text == NULL || font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2084 |
return FC_MakeRect(x, y, 0, 0); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2085 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2086 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2087 |
FC_EXTRACT_VARARGS(fc_buffer, formatted_text); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2088 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2089 |
set_color_for_all_caches(font, effect.color); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2090 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2091 |
FC_Rect result; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2092 |
switch (effect.alignment) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2093 |
case FC_ALIGN_LEFT: |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2094 |
result = FC_RenderLeft(font, dest, x, y, effect.scale, fc_buffer); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2095 |
break; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2096 |
case FC_ALIGN_CENTER: |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2097 |
result = FC_RenderCenter(font, dest, x, y, effect.scale, fc_buffer); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2098 |
break; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2099 |
case FC_ALIGN_RIGHT: |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2100 |
result = FC_RenderRight(font, dest, x, y, effect.scale, fc_buffer); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2101 |
break; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2102 |
default: |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2103 |
result = FC_MakeRect(x, y, 0, 0); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2104 |
break; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2105 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2106 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2107 |
return result; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2108 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2109 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
2110 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
2111 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
2112 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
2113 |
// Getters |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2114 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
2115 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2116 |
FC_FilterEnum FC_GetFilterMode(FC_Font* font) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2117 |
if (font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2118 |
return FC_FILTER_NEAREST; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2119 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2120 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2121 |
return font->filter; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2122 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2123 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2124 |
Uint16 FC_GetLineHeight(FC_Font* font) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2125 |
if (font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2126 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2127 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2128 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2129 |
return font->height; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2130 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2131 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2132 |
Uint16 FC_GetHeight(FC_Font* font, const char* formatted_text, ...) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2133 |
if (formatted_text == NULL || font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2134 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2135 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2136 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2137 |
FC_EXTRACT_VARARGS(fc_buffer, formatted_text); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2138 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2139 |
Uint16 numLines = 1; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2140 |
const char* c; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2141 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2142 |
for (c = fc_buffer; *c != '\0'; c++) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2143 |
if (*c == '\n') { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2144 |
numLines++; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2145 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2146 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2147 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2148 |
// Actual height of letter region + line spacing |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2149 |
return font->height*numLines + font->lineSpacing*(numLines - 1); //height*numLines; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2150 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2151 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2152 |
Uint16 FC_GetWidth(FC_Font* font, const char* formatted_text, ...) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2153 |
if (formatted_text == NULL || font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2154 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2155 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2156 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2157 |
FC_EXTRACT_VARARGS(fc_buffer, formatted_text); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2158 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2159 |
const char* c; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2160 |
Uint16 width = 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2161 |
Uint16 bigWidth = 0; // Allows for multi-line strings |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2162 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2163 |
for (c = fc_buffer; *c != '\0'; c++) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2164 |
if (*c == '\n') { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2165 |
bigWidth = bigWidth >= width? bigWidth : width; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2166 |
width = 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2167 |
continue; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2168 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2169 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2170 |
FC_GlyphData glyph; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2171 |
Uint32 codepoint = FC_GetCodepointFromUTF8(&c, 1); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2172 |
if (FC_GetGlyphData(font, &glyph, codepoint) || FC_GetGlyphData(font, &glyph, ' ')) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2173 |
width += glyph.rect.w; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2174 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2175 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2176 |
bigWidth = bigWidth >= width? bigWidth : width; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2177 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2178 |
return bigWidth; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2179 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2180 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
2181 |
// If width == -1, use no width limit |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2182 |
FC_Rect FC_GetCharacterOffset(FC_Font* font, Uint16 position_index, int column_width, const char* formatted_text, ...) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2183 |
FC_Rect result = {0, 0, 1, FC_GetLineHeight(font)}; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2184 |
FC_StringList* ls, *iter; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2185 |
int num_lines = 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2186 |
Uint8 done = 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2187 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2188 |
if (formatted_text == NULL || column_width == 0 || position_index == 0 || font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2189 |
return result; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2190 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2191 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2192 |
FC_EXTRACT_VARARGS(fc_buffer, formatted_text); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2193 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2194 |
ls = FC_GetBufferFitToColumn(font, column_width, FC_MakeScale(1,1), 1); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2195 |
for (iter = ls; iter != NULL; iter = iter->next) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2196 |
char* line; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2197 |
int i = 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2198 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2199 |
++num_lines; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2200 |
for (line = iter->value; line != NULL && *line != '\0'; line = (char*)U8_next(line)) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2201 |
++i; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2202 |
--position_index; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2203 |
if (position_index == 0) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2204 |
// FIXME: Doesn't handle box-wrapped newlines correctly |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2205 |
line = (char*)U8_next(line); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2206 |
line[0] = '\0'; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2207 |
result.x = FC_GetWidth(font, "%s", iter->value); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2208 |
done = 1; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2209 |
break; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2210 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2211 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2212 |
if (done) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2213 |
break; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2214 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2215 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2216 |
FC_StringListFree(ls); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2217 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2218 |
if (num_lines > 0) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2219 |
result.y = (num_lines - 1) * FC_GetLineHeight(font); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2220 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2221 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2222 |
return result; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2223 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2224 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
2225 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2226 |
Uint16 FC_GetColumnHeight(FC_Font* font, Uint16 width, const char* formatted_text, ...) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2227 |
int y = 0; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2228 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2229 |
FC_StringList* ls, *iter; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2230 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2231 |
if (font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2232 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2233 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2234 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2235 |
if (formatted_text == NULL || width == 0) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2236 |
return font->height; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2237 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2238 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2239 |
FC_EXTRACT_VARARGS(fc_buffer, formatted_text); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2240 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2241 |
ls = FC_GetBufferFitToColumn(font, width, FC_MakeScale(1,1), 0); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2242 |
for (iter = ls; iter != NULL; iter = iter->next) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2243 |
y += FC_GetLineHeight(font); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2244 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2245 |
FC_StringListFree(ls); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2246 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2247 |
return y; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2248 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2249 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2250 |
static int FC_GetAscentFromCodepoint(FC_Font* font, Uint32 codepoint) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2251 |
FC_GlyphData glyph; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2252 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2253 |
if (font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2254 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2255 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2256 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2257 |
// FIXME: Store ascent so we can return it here |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2258 |
FC_GetGlyphData(font, &glyph, codepoint); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2259 |
return glyph.rect.h; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2260 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2261 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2262 |
static int FC_GetDescentFromCodepoint(FC_Font* font, Uint32 codepoint) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2263 |
FC_GlyphData glyph; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2264 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2265 |
if (font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2266 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2267 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2268 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2269 |
// FIXME: Store descent so we can return it here |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2270 |
FC_GetGlyphData(font, &glyph, codepoint); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2271 |
return glyph.rect.h; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2272 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2273 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2274 |
int FC_GetAscent(FC_Font* font, const char* formatted_text, ...) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2275 |
Uint32 codepoint; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2276 |
int max, ascent; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2277 |
const char* c; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2278 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2279 |
if (font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2280 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2281 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2282 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2283 |
if (formatted_text == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2284 |
return font->ascent; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2285 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2286 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2287 |
FC_EXTRACT_VARARGS(fc_buffer, formatted_text); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2288 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2289 |
max = 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2290 |
c = fc_buffer; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2291 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2292 |
while (*c != '\0') { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2293 |
codepoint = FC_GetCodepointFromUTF8(&c, 1); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2294 |
if (codepoint != 0) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2295 |
ascent = FC_GetAscentFromCodepoint(font, codepoint); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2296 |
if (ascent > max) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2297 |
max = ascent; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2298 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2299 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2300 |
++c; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2301 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2302 |
return max; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2303 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2304 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2305 |
int FC_GetDescent(FC_Font* font, const char* formatted_text, ...) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2306 |
Uint32 codepoint; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2307 |
int max, descent; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2308 |
const char* c; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2309 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2310 |
if (font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2311 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2312 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2313 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2314 |
if (formatted_text == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2315 |
return font->descent; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2316 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2317 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2318 |
FC_EXTRACT_VARARGS(fc_buffer, formatted_text); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2319 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2320 |
max = 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2321 |
c = fc_buffer; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2322 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2323 |
while (*c != '\0') { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2324 |
codepoint = FC_GetCodepointFromUTF8(&c, 1); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2325 |
if (codepoint != 0) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2326 |
descent = FC_GetDescentFromCodepoint(font, codepoint); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2327 |
if (descent > max) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2328 |
max = descent; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2329 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2330 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2331 |
++c; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2332 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2333 |
return max; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2334 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2335 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2336 |
int FC_GetBaseline(FC_Font* font) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2337 |
if (font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2338 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2339 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2340 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2341 |
return font->baseline; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2342 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2343 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2344 |
int FC_GetSpacing(FC_Font* font) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2345 |
if (font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2346 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2347 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2348 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2349 |
return font->letterSpacing; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2350 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2351 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2352 |
int FC_GetLineSpacing(FC_Font* font) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2353 |
if (font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2354 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2355 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2356 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2357 |
return font->lineSpacing; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2358 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2359 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2360 |
Uint16 FC_GetMaxWidth(FC_Font* font) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2361 |
if (font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2362 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2363 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2364 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2365 |
return font->maxWidth; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2366 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2367 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2368 |
SDL_Color FC_GetDefaultColor(FC_Font* font) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2369 |
if (font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2370 |
SDL_Color c = {0,0,0,255}; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2371 |
return c; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2372 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2373 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2374 |
return font->default_color; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2375 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2376 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
2377 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2378 |
Uint8 FC_InRect(float x, float y, FC_Rect input_rect) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2379 |
return (input_rect.x <= x && x <= input_rect.x + input_rect.w && input_rect.y <= y && y <= input_rect.y + input_rect.h); |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2380 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2381 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
2382 |
// TODO: Make it work with alignment |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2383 |
Uint16 FC_GetPositionFromOffset(FC_Font* font, float x, float y, int column_width, FC_AlignEnum align, const char* formatted_text, ...) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2384 |
FC_StringList* ls, *iter; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2385 |
Uint8 done = 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2386 |
int height = FC_GetLineHeight(font); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2387 |
Uint16 position = 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2388 |
int current_x = 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2389 |
int current_y = 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2390 |
FC_GlyphData glyph_data; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2391 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2392 |
if (formatted_text == NULL || column_width == 0 || font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2393 |
return 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2394 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2395 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2396 |
FC_EXTRACT_VARARGS(fc_buffer, formatted_text); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2397 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2398 |
ls = FC_GetBufferFitToColumn(font, column_width, FC_MakeScale(1,1), 1); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2399 |
for (iter = ls; iter != NULL; iter = iter->next) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2400 |
char* line; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2401 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2402 |
for (line = iter->value; line != NULL && *line != '\0'; line = (char*)U8_next(line)) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2403 |
if (FC_GetGlyphData(font, &glyph_data, FC_GetCodepointFromUTF8((const char**)&line, 0))) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2404 |
if (FC_InRect(x, y, FC_MakeRect(current_x, current_y, glyph_data.rect.w, glyph_data.rect.h))) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2405 |
done = 1; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2406 |
break; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2407 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2408 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2409 |
current_x += glyph_data.rect.w; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2410 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2411 |
position++; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2412 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2413 |
if (done) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2414 |
break; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2415 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2416 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2417 |
current_x = 0; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2418 |
current_y += height; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2419 |
if (y < current_y) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2420 |
break; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2421 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2422 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2423 |
FC_StringListFree(ls); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2424 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2425 |
return position; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2426 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2427 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
2428 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
2429 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
2430 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
2431 |
// Setters |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2432 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
2433 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2434 |
void FC_SetFilterMode(FC_Font* font, FC_FilterEnum filter) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2435 |
if (font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2436 |
return; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2437 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2438 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2439 |
if (font->filter != filter) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2440 |
font->filter = filter; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2441 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2442 |
#ifdef FC_USE_SDL_GPU |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2443 |
// Update each texture to use this filter mode |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2444 |
{ |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2445 |
int i; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2446 |
GPU_FilterEnum gpu_filter = GPU_FILTER_NEAREST; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2447 |
if (FC_GetFilterMode(font) == FC_FILTER_LINEAR) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2448 |
gpu_filter = GPU_FILTER_LINEAR; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2449 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2450 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2451 |
for (i = 0; i < font->glyph_cache_count; ++i) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2452 |
GPU_SetImageFilter(font->glyph_cache[i], gpu_filter); |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2453 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2454 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2455 |
#endif |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2456 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2457 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2458 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
2459 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2460 |
void FC_SetSpacing(FC_Font* font, int LetterSpacing) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2461 |
if (font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2462 |
return; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2463 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2464 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2465 |
font->letterSpacing = LetterSpacing; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2466 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2467 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2468 |
void FC_SetLineSpacing(FC_Font* font, int LineSpacing) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2469 |
if (font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2470 |
return; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2471 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2472 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2473 |
font->lineSpacing = LineSpacing; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2474 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2475 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2476 |
void FC_SetDefaultColor(FC_Font* font, SDL_Color color) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2477 |
if (font == NULL) { |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2478 |
return; |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2479 |
} |
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2480 |
|
| 1d2e2129 |
sago007 |
2015-12-23 15:41 |
2481 |
font->default_color = color; |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2482 |
} |
| 078900fe |
sago007 |
2015-12-05 15:31 |
2483 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
2484 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
2485 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
2486 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
2487 |
|
| 078900fe |
sago007 |
2015-12-05 15:31 |
2488 |
|
|
|
1970-01-01 00:00 |
2489 |
|