Subversion Repository Public Repository

Divide-Framework

This repository has no backups
This repository's network speed is throttled to 100KB/sec

Diff Revisions 336 vs 337 for /trunk/Source Code/Platform/Video/OpenGL/Text/Headers/fontstash.h

Diff revisions: vs.
  @@ -22,46 +22,46 @@
22 22 #define FONS_INVALID -1
23 23
24 24 enum FONSflags {
25 - FONS_ZERO_TOPLEFT = 1,
26 - FONS_ZERO_BOTTOMLEFT = 2,
25 + FONS_ZERO_TOPLEFT = 1,
26 + FONS_ZERO_BOTTOMLEFT = 2,
27 27 };
28 28
29 29 enum FONSalign {
30 - // Horizontal align
31 - FONS_ALIGN_LEFT = 1<<0, // Default
32 - FONS_ALIGN_CENTER = 1<<1,
33 - FONS_ALIGN_RIGHT = 1<<2,
34 - // Vertical align
35 - FONS_ALIGN_TOP = 1<<3,
36 - FONS_ALIGN_MIDDLE = 1<<4,
37 - FONS_ALIGN_BOTTOM = 1<<5,
38 - FONS_ALIGN_BASELINE = 1<<6, // Default
30 + // Horizontal align
31 + FONS_ALIGN_LEFT = 1<<0, // Default
32 + FONS_ALIGN_CENTER = 1<<1,
33 + FONS_ALIGN_RIGHT = 1<<2,
34 + // Vertical align
35 + FONS_ALIGN_TOP = 1<<3,
36 + FONS_ALIGN_MIDDLE = 1<<4,
37 + FONS_ALIGN_BOTTOM = 1<<5,
38 + FONS_ALIGN_BASELINE = 1<<6, // Default
39 39 };
40 40
41 41 struct FONSparams {
42 - int width, height;
43 - unsigned char flags;
44 - void* userPtr;
45 - int (*renderCreate)(void* uptr, int width, int height);
46 - void (*renderUpdate)(void* uptr, int* rect, const unsigned char* data);
47 - void (*renderDraw)(void* uptr, const float* verts, const float* tcoords, const unsigned char* colors, int nverts);
48 - void (*renderDelete)(void* uptr);
42 + int width, height;
43 + unsigned char flags;
44 + void* userPtr;
45 + int (*renderCreate)(void* uptr, int width, int height);
46 + void (*renderUpdate)(void* uptr, int* rect, const unsigned char* data);
47 + void (*renderDraw)(void* uptr, const float* verts, const float* tcoords, const unsigned char* colors, int nverts);
48 + void (*renderDelete)(void* uptr);
49 49 };
50 50
51 51 struct FONSquad
52 52 {
53 - float x0,y0,s0,t0;
54 - float x1,y1,s1,t1;
53 + float x0,y0,s0,t0;
54 + float x1,y1,s1,t1;
55 55 };
56 56
57 57 struct FONStextIter {
58 - float x, y, scale, spacing;
59 - short isize, iblur;
60 - struct FONSfont* font;
61 - struct FONSglyph* prevGlyph;
62 - const char* str;
63 - const char* end;
64 - unsigned int utf8state;
58 + float x, y, scale, spacing;
59 + short isize, iblur;
60 + struct FONSfont* font;
61 + struct FONSglyph* prevGlyph;
62 + const char* str;
63 + const char* end;
64 + unsigned int utf8state;
65 65 };
66 66
67 67 // Contructor and destructor.
  @@ -117,82 +117,82 @@
117 117 #include "stb_truetype.h"
118 118
119 119 #ifndef FONS_SCRATCH_BUF_SIZE
120 - # define FONS_SCRATCH_BUF_SIZE 16000
120 + # define FONS_SCRATCH_BUF_SIZE 16000
121 121 #endif
122 122 #ifndef FONS_HASH_LUT_SIZE
123 - # define FONS_HASH_LUT_SIZE 256
123 + # define FONS_HASH_LUT_SIZE 256
124 124 #endif
125 125 #ifndef FONS_INIT_FONTS
126 - # define FONS_INIT_FONTS 4
126 + # define FONS_INIT_FONTS 4
127 127 #endif
128 128 #ifndef FONS_INIT_GLYPHS
129 - # define FONS_INIT_GLYPHS 256
129 + # define FONS_INIT_GLYPHS 256
130 130 #endif
131 131 #ifndef FONS_INIT_ATLAS_NODES
132 - # define FONS_INIT_ATLAS_NODES 256
132 + # define FONS_INIT_ATLAS_NODES 256
133 133 #endif
134 134 #ifndef FONS_VERTEX_COUNT
135 - # define FONS_VERTEX_COUNT 1024
135 + # define FONS_VERTEX_COUNT 1024
136 136 #endif
137 137 #ifndef FONS_MAX_STATES
138 - # define FONS_MAX_STATES 20
138 + # define FONS_MAX_STATES 20
139 139 #endif
140 140
141 141 static unsigned int fons__hashint(unsigned int a)
142 142 {
143 - a += ~(a<<15);
144 - a ^= (a>>10);
145 - a += (a<<3);
146 - a ^= (a>>6);
147 - a += ~(a<<11);
148 - a ^= (a>>16);
149 - return a;
143 + a += ~(a<<15);
144 + a ^= (a>>10);
145 + a += (a<<3);
146 + a ^= (a>>6);
147 + a += ~(a<<11);
148 + a ^= (a>>16);
149 + return a;
150 150 }
151 151
152 152 static int fons__mini(int a, int b)
153 153 {
154 - return a < b ? a : b;
154 + return a < b ? a : b;
155 155 }
156 156
157 157 static int fons__maxi(int a, int b)
158 158 {
159 - return a > b ? a : b;
159 + return a > b ? a : b;
160 160 }
161 161
162 162 struct FONSglyph
163 163 {
164 - unsigned int codepoint;
165 - int index;
166 - int next;
167 - short size, blur;
168 - short x0,y0,x1,y1;
169 - short xadv,xoff,yoff;
164 + unsigned int codepoint;
165 + int index;
166 + int next;
167 + short size, blur;
168 + short x0,y0,x1,y1;
169 + short xadv,xoff,yoff;
170 170 };
171 171
172 172 struct FONSfont
173 173 {
174 - stbtt_fontinfo font;
175 - char name[64];
176 - unsigned char* data;
177 - int dataSize;
178 - unsigned char freeData;
179 - float ascender;
180 - float descender;
181 - float lineh;
182 - struct FONSglyph* glyphs;
183 - int cglyphs;
184 - int nglyphs;
185 - int lut[FONS_HASH_LUT_SIZE];
174 + stbtt_fontinfo font;
175 + char name[64];
176 + unsigned char* data;
177 + int dataSize;
178 + unsigned char freeData;
179 + float ascender;
180 + float descender;
181 + float lineh;
182 + struct FONSglyph* glyphs;
183 + int cglyphs;
184 + int nglyphs;
185 + int lut[FONS_HASH_LUT_SIZE];
186 186 };
187 187
188 188 struct FONSstate
189 189 {
190 - int font;
191 - int align;
192 - float size;
193 - unsigned char color[4];
194 - float blur;
195 - float spacing;
190 + int font;
191 + int align;
192 + float size;
193 + unsigned char color[4];
194 + float blur;
195 + float spacing;
196 196 };
197 197
198 198 struct FONSatlasNode {
  @@ -201,47 +201,47 @@
201 201
202 202 struct FONSatlas
203 203 {
204 - int width, height;
205 - struct FONSatlasNode* nodes;
206 - int nnodes;
207 - int cnodes;
204 + int width, height;
205 + struct FONSatlasNode* nodes;
206 + int nnodes;
207 + int cnodes;
208 208 };
209 209
210 210 struct FONScontext
211 211 {
212 - struct FONSparams params;
213 - float itw,ith;
214 - unsigned char* texData;
215 - int dirtyRect[4];
216 - struct FONSfont** fonts;
217 - struct FONSatlas* atlas;
218 - int cfonts;
219 - int nfonts;
220 - float verts[FONS_VERTEX_COUNT*2];
221 - float tcoords[FONS_VERTEX_COUNT*2];
222 - unsigned char colors[FONS_VERTEX_COUNT*4];
223 - int nverts;
224 - unsigned char scratch[FONS_SCRATCH_BUF_SIZE];
225 - int nscratch;
226 - struct FONSstate states[FONS_MAX_STATES];
227 - int nstates;
212 + struct FONSparams params;
213 + float itw,ith;
214 + unsigned char* texData;
215 + int dirtyRect[4];
216 + struct FONSfont** fonts;
217 + struct FONSatlas* atlas;
218 + int cfonts;
219 + int nfonts;
220 + float verts[FONS_VERTEX_COUNT*2];
221 + float tcoords[FONS_VERTEX_COUNT*2];
222 + unsigned char colors[FONS_VERTEX_COUNT*4];
223 + int nverts;
224 + unsigned char scratch[FONS_SCRATCH_BUF_SIZE];
225 + int nscratch;
226 + struct FONSstate states[FONS_MAX_STATES];
227 + int nstates;
228 228 };
229 229
230 230 static void* fons__tmpalloc(size_t size, void* up)
231 231 {
232 - unsigned char* ptr;
232 + unsigned char* ptr;
233 233
234 - struct FONScontext* stash = (struct FONScontext*)up;
235 - if (stash->nscratch+(int)size > FONS_SCRATCH_BUF_SIZE)
236 - return nullptr;
237 - ptr = stash->scratch + stash->nscratch;
238 - stash->nscratch += (int)size;
239 - return ptr;
234 + struct FONScontext* stash = (struct FONScontext*)up;
235 + if (stash->nscratch+(int)size > FONS_SCRATCH_BUF_SIZE)
236 + return nullptr;
237 + ptr = stash->scratch + stash->nscratch;
238 + stash->nscratch += (int)size;
239 + return ptr;
240 240 }
241 241
242 242 static void fons__tmpfree(void* ptr, void* up)
243 243 {
244 - // empty
244 + // empty
245 245 }
246 246
247 247 // Copyright (c) 2008-2010 Bjoern Hoehrmann <bjoern@hoehrmann.de>
  @@ -252,258 +252,258 @@
252 252
253 253 static unsigned int fons__decutf8(unsigned int* state, unsigned int* codep, unsigned int byte)
254 254 {
255 - static const unsigned char utf8d[] = {
256 - // The first part of the table maps bytes to character classes that
257 - // to reduce the size of the transition table and create bitmasks.
258 - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
259 - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
260 - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
261 - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
262 - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
263 - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
264 - 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
265 - 10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8,
266 -
267 - // The second part is a transition table that maps a combination
268 - // of a state of the automaton and a character class to a state.
269 - 0,12,24,36,60,96,84,12,12,12,48,72, 12,12,12,12,12,12,12,12,12,12,12,12,
270 - 12, 0,12,12,12,12,12, 0,12, 0,12,12, 12,24,12,12,12,12,12,24,12,24,12,12,
271 - 12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24,12,12,
272 - 12,12,12,12,12,12,12,36,12,36,12,12, 12,36,12,12,12,12,12,36,12,36,12,12,
273 - 12,36,12,12,12,12,12,12,12,12,12,12,
255 + static const unsigned char utf8d[] = {
256 + // The first part of the table maps bytes to character classes that
257 + // to reduce the size of the transition table and create bitmasks.
258 + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
259 + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
260 + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
261 + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
262 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
263 + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
264 + 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
265 + 10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8,
266 +
267 + // The second part is a transition table that maps a combination
268 + // of a state of the automaton and a character class to a state.
269 + 0,12,24,36,60,96,84,12,12,12,48,72, 12,12,12,12,12,12,12,12,12,12,12,12,
270 + 12, 0,12,12,12,12,12, 0,12, 0,12,12, 12,24,12,12,12,12,12,24,12,24,12,12,
271 + 12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24,12,12,
272 + 12,12,12,12,12,12,12,36,12,36,12,12, 12,36,12,12,12,12,12,36,12,36,12,12,
273 + 12,36,12,12,12,12,12,12,12,12,12,12,
274 274 };
275 275
276 - unsigned int type = utf8d[byte];
276 + unsigned int type = utf8d[byte];
277 277
278 278 *codep = (*state != FONS_UTF8_ACCEPT) ?
279 - (byte & 0x3fu) | (*codep << 6) :
280 - (0xff >> type) & (byte);
279 + (byte & 0x3fu) | (*codep << 6) :
280 + (0xff >> type) & (byte);
281 281
282 - *state = utf8d[256 + *state + type];
283 - return *state;
282 + *state = utf8d[256 + *state + type];
283 + return *state;
284 284 }
285 285
286 286 // Atlas based on Skyline Pin Packer by Jukka Jylänki
287 287
288 288 static void fons__deleteAtlas(struct FONSatlas* atlas)
289 289 {
290 - if (atlas == nullptr) return;
291 - if (atlas->nodes != nullptr) free(atlas->nodes);
292 - free(atlas);
290 + if (atlas == nullptr) return;
291 + if (atlas->nodes != nullptr) free(atlas->nodes);
292 + free(atlas);
293 293 }
294 294
295 295 static struct FONSatlas* fons__allocAtlas(int w, int h, int nnodes)
296 296 {
297 - struct FONSatlas* atlas = nullptr;
297 + struct FONSatlas* atlas = nullptr;
298 298
299 - // Allocate memory for the font stash.
300 - atlas = (struct FONSatlas*)malloc(sizeof(struct FONSatlas));
301 - if (atlas == nullptr) goto error;
302 - memset(atlas, 0, sizeof(struct FONSatlas));
303 -
304 - atlas->width = w;
305 - atlas->height = h;
306 -
307 - // Allocate space for skyline nodes
308 - atlas->nodes = (struct FONSatlasNode*)malloc(sizeof(struct FONSatlasNode) * nnodes);
309 - if (atlas->nodes == nullptr) goto error;
310 - memset(atlas->nodes, 0, sizeof(struct FONSatlasNode) * nnodes);
311 - atlas->nnodes = 0;
312 - atlas->cnodes = nnodes;
313 -
314 - // Init root node.
315 - atlas->nodes[0].x = 0;
316 - atlas->nodes[0].y = 0;
317 - atlas->nodes[0].width = w;
318 - atlas->nnodes++;
299 + // Allocate memory for the font stash.
300 + atlas = (struct FONSatlas*)malloc(sizeof(struct FONSatlas));
301 + if (atlas == nullptr) goto error;
302 + memset(atlas, 0, sizeof(struct FONSatlas));
303 +
304 + atlas->width = w;
305 + atlas->height = h;
306 +
307 + // Allocate space for skyline nodes
308 + atlas->nodes = (struct FONSatlasNode*)malloc(sizeof(struct FONSatlasNode) * nnodes);
309 + if (atlas->nodes == nullptr) goto error;
310 + memset(atlas->nodes, 0, sizeof(struct FONSatlasNode) * nnodes);
311 + atlas->nnodes = 0;
312 + atlas->cnodes = nnodes;
313 +
314 + // Init root node.
315 + atlas->nodes[0].x = 0;
316 + atlas->nodes[0].y = 0;
317 + atlas->nodes[0].width = w;
318 + atlas->nnodes++;
319 319
320 - return atlas;
320 + return atlas;
321 321
322 322 error:
323 - if (atlas) fons__deleteAtlas(atlas);
324 - return nullptr;
323 + if (atlas) fons__deleteAtlas(atlas);
324 + return nullptr;
325 325 }
326 326
327 327 static int fons__atlasInsertNode(struct FONSatlas* atlas, int idx, int x, int y, int w)
328 328 {
329 - int i;
330 - // Insert node
331 - if (atlas->nnodes+1 > atlas->cnodes) {
332 - atlas->cnodes = atlas->cnodes == 0 ? 8 : atlas->cnodes * 2;
333 - atlas->nodes = (struct FONSatlasNode*)realloc(atlas->nodes, sizeof(struct FONSatlasNode) * atlas->cnodes);
334 - if (atlas->nodes == nullptr)
335 - return 0;
336 - }
337 - for (i = atlas->nnodes; i > idx; i--)
338 - atlas->nodes[i] = atlas->nodes[i-1];
339 - atlas->nodes[idx].x = x;
340 - atlas->nodes[idx].y = y;
341 - atlas->nodes[idx].width = w;
342 - atlas->nnodes++;
329 + int i;
330 + // Insert node
331 + if (atlas->nnodes+1 > atlas->cnodes) {
332 + atlas->cnodes = atlas->cnodes == 0 ? 8 : atlas->cnodes * 2;
333 + atlas->nodes = (struct FONSatlasNode*)realloc(atlas->nodes, sizeof(struct FONSatlasNode) * atlas->cnodes);
334 + if (atlas->nodes == nullptr)
335 + return 0;
336 + }
337 + for (i = atlas->nnodes; i > idx; i--)
338 + atlas->nodes[i] = atlas->nodes[i-1];
339 + atlas->nodes[idx].x = x;
340 + atlas->nodes[idx].y = y;
341 + atlas->nodes[idx].width = w;
342 + atlas->nnodes++;
343 343
344 - return 1;
344 + return 1;
345 345 }
346 346
347 347 static void fons__atlasRemoveNode(struct FONSatlas* atlas, int idx)
348 348 {
349 - int i;
350 - if (atlas->nnodes == 0) return;
351 - for (i = idx; i < atlas->nnodes-1; i++)
352 - atlas->nodes[i] = atlas->nodes[i+1];
353 - atlas->nnodes--;
349 + int i;
350 + if (atlas->nnodes == 0) return;
351 + for (i = idx; i < atlas->nnodes-1; i++)
352 + atlas->nodes[i] = atlas->nodes[i+1];
353 + atlas->nnodes--;
354 354 }
355 355
356 356 static int fons__atlasAddSkylineLevel(struct FONSatlas* atlas, int idx, int x, int y, int w, int h)
357 357 {
358 - int i;
358 + int i;
359 359
360 - // Insert new node
361 - if (fons__atlasInsertNode(atlas, idx, x, y+h, w) == 0)
362 - return 0;
363 -
364 - // Delete skyline segments that fall under the shaodw of the new segment.
365 - for (i = idx+1; i < atlas->nnodes; i++) {
366 - if (atlas->nodes[i].x < atlas->nodes[i-1].x + atlas->nodes[i-1].width) {
367 - int shrink = atlas->nodes[i-1].x + atlas->nodes[i-1].width - atlas->nodes[i].x;
368 - atlas->nodes[i].x += shrink;
369 - atlas->nodes[i].width -= shrink;
370 - if (atlas->nodes[i].width <= 0) {
371 - fons__atlasRemoveNode(atlas, i);
372 - i--;
373 - } else {
374 - break;
375 - }
376 - } else {
377 - break;
378 - }
379 - }
380 -
381 - // Merge same height skyline segments that are next to each other.
382 - for (i = 0; i < atlas->nnodes-1; i++) {
383 - if (atlas->nodes[i].y == atlas->nodes[i+1].y) {
384 - atlas->nodes[i].width += atlas->nodes[i+1].width;
385 - fons__atlasRemoveNode(atlas, i+1);
386 - i--;
387 - }
388 - }
360 + // Insert new node
361 + if (fons__atlasInsertNode(atlas, idx, x, y+h, w) == 0)
362 + return 0;
363 +
364 + // Delete skyline segments that fall under the shaodw of the new segment.
365 + for (i = idx+1; i < atlas->nnodes; i++) {
366 + if (atlas->nodes[i].x < atlas->nodes[i-1].x + atlas->nodes[i-1].width) {
367 + int shrink = atlas->nodes[i-1].x + atlas->nodes[i-1].width - atlas->nodes[i].x;
368 + atlas->nodes[i].x += shrink;
369 + atlas->nodes[i].width -= shrink;
370 + if (atlas->nodes[i].width <= 0) {
371 + fons__atlasRemoveNode(atlas, i);
372 + i--;
373 + } else {
374 + break;
375 + }
376 + } else {
377 + break;
378 + }
379 + }
380 +
381 + // Merge same height skyline segments that are next to each other.
382 + for (i = 0; i < atlas->nnodes-1; i++) {
383 + if (atlas->nodes[i].y == atlas->nodes[i+1].y) {
384 + atlas->nodes[i].width += atlas->nodes[i+1].width;
385 + fons__atlasRemoveNode(atlas, i+1);
386 + i--;
387 + }
388 + }
389 389
390 - return 1;
390 + return 1;
391 391 }
392 392
393 393 static int fons__atlasRectFits(struct FONSatlas* atlas, int i, int w, int h)
394 394 {
395 - // Checks if there is enough space at the location of skyline span 'i',
396 - // and return the max height of all skyline spans under that at that location,
397 - // (think tetris block being dropped at that position). Or -1 if no space found.
398 - int x = atlas->nodes[i].x;
399 - int y = atlas->nodes[i].y;
400 - if (x + w > atlas->width)
401 - return -1;
402 - int spaceLeft = w;
403 - while (spaceLeft > 0) {
404 - if (i == atlas->nnodes) return -1;
405 - y = fons__maxi(y, atlas->nodes[i].y);
406 - if (y + h > atlas->height) return -1;
407 - spaceLeft -= atlas->nodes[i].width;
408 - ++i;
409 - }
410 - return y;
395 + // Checks if there is enough space at the location of skyline span 'i',
396 + // and return the max height of all skyline spans under that at that location,
397 + // (think tetris block being dropped at that position). Or -1 if no space found.
398 + int x = atlas->nodes[i].x;
399 + int y = atlas->nodes[i].y;
400 + if (x + w > atlas->width)
401 + return -1;
402 + int spaceLeft = w;
403 + while (spaceLeft > 0) {
404 + if (i == atlas->nnodes) return -1;
405 + y = fons__maxi(y, atlas->nodes[i].y);
406 + if (y + h > atlas->height) return -1;
407 + spaceLeft -= atlas->nodes[i].width;
408 + ++i;
409 + }
410 + return y;
411 411 }
412 412
413 413 static int fons__atlasAddRect(struct FONSatlas* atlas, int rw, int rh, int* rx, int* ry)
414 414 {
415 - int besth = atlas->height, bestw = atlas->width, besti = -1;
416 - int bestx = 0, besty = 0, i = 0;
415 + int besth = atlas->height, bestw = atlas->width, besti = -1;
416 + int bestx = 0, besty = 0, i = 0;
417 417
418 - // Bottom left fit heuristic.
419 - for (i = 0; i < atlas->nnodes; i++) {
420 - int y = fons__atlasRectFits(atlas, i, rw, rh);
421 - if (y != -1) {
422 - if (y + rh < besth || (y + rh == besth && atlas->nodes[i].width < bestw)) {
423 - besti = i;
424 - bestw = atlas->nodes[i].width;
425 - besth = y + rh;
426 - bestx = atlas->nodes[i].x;
427 - besty = y;
428 - }
429 - }
430 - }
431 -
432 - if (besti == -1)
433 - return 0;
434 -
435 - // Perform the actual packing.
436 - if (fons__atlasAddSkylineLevel(atlas, besti, bestx, besty, rw, rh) == 0)
437 - return 0;
418 + // Bottom left fit heuristic.
419 + for (i = 0; i < atlas->nnodes; i++) {
420 + int y = fons__atlasRectFits(atlas, i, rw, rh);
421 + if (y != -1) {
422 + if (y + rh < besth || (y + rh == besth && atlas->nodes[i].width < bestw)) {
423 + besti = i;
424 + bestw = atlas->nodes[i].width;
425 + besth = y + rh;
426 + bestx = atlas->nodes[i].x;
427 + besty = y;
428 + }
429 + }
430 + }
431 +
432 + if (besti == -1)
433 + return 0;
434 +
435 + // Perform the actual packing.
436 + if (fons__atlasAddSkylineLevel(atlas, besti, bestx, besty, rw, rh) == 0)
437 + return 0;
438 438
439 - *rx = bestx;
440 - *ry = besty;
439 + *rx = bestx;
440 + *ry = besty;
441 441
442 - return 1;
442 + return 1;
443 443 }
444 444
445 445
446 446 struct FONScontext* fonsCreateInternal(struct FONSparams* params)
447 447 {
448 - struct FONScontext* stash = nullptr;
448 + struct FONScontext* stash = nullptr;
449 449
450 - // Allocate memory for the font stash.
451 - stash = (struct FONScontext*)malloc(sizeof(struct FONScontext));
452 - if (stash == nullptr) goto error;
453 - memset(stash, 0, sizeof(struct FONScontext));
454 -
455 - stash->params = *params;
456 -
457 - if (stash->params.renderCreate != nullptr) {
458 - if (stash->params.renderCreate(stash->params.userPtr, stash->params.width, stash->params.height) == 0)
459 - goto error;
460 - }
461 -
462 - stash->atlas = fons__allocAtlas(stash->params.width, stash->params.height, FONS_INIT_ATLAS_NODES);
463 - if (stash->atlas == nullptr) goto error;
464 -
465 - // Allocate space for fonts.
466 - stash->fonts = (struct FONSfont**)malloc(sizeof(struct FONSfont*) * FONS_INIT_FONTS);
467 - if (stash->fonts == nullptr) goto error;
468 - memset(stash->fonts, 0, sizeof(struct FONSfont*) * FONS_INIT_FONTS);
469 - stash->cfonts = FONS_INIT_FONTS;
470 - stash->nfonts = 0;
471 -
472 - // Create texture for the cache.
473 - stash->itw = 1.0f/stash->params.width;
474 - stash->ith = 1.0f/stash->params.height;
475 - stash->texData = (unsigned char*)malloc(stash->params.width * stash->params.height);
476 - if (stash->texData == nullptr) goto error;
477 - memset(stash->texData, 0, stash->params.width * stash->params.height);
478 -
479 - stash->dirtyRect[0] = stash->params.width;
480 - stash->dirtyRect[1] = stash->params.height;
481 - stash->dirtyRect[2] = 0;
482 - stash->dirtyRect[3] = 0;
450 + // Allocate memory for the font stash.
451 + stash = (struct FONScontext*)malloc(sizeof(struct FONScontext));
452 + if (stash == nullptr) goto error;
453 + memset(stash, 0, sizeof(struct FONScontext));
454 +
455 + stash->params = *params;
456 +
457 + if (stash->params.renderCreate != nullptr) {
458 + if (stash->params.renderCreate(stash->params.userPtr, stash->params.width, stash->params.height) == 0)
459 + goto error;
460 + }
461 +
462 + stash->atlas = fons__allocAtlas(stash->params.width, stash->params.height, FONS_INIT_ATLAS_NODES);
463 + if (stash->atlas == nullptr) goto error;
464 +
465 + // Allocate space for fonts.
466 + stash->fonts = (struct FONSfont**)malloc(sizeof(struct FONSfont*) * FONS_INIT_FONTS);
467 + if (stash->fonts == nullptr) goto error;
468 + memset(stash->fonts, 0, sizeof(struct FONSfont*) * FONS_INIT_FONTS);
469 + stash->cfonts = FONS_INIT_FONTS;
470 + stash->nfonts = 0;
471 +
472 + // Create texture for the cache.
473 + stash->itw = 1.0f/stash->params.width;
474 + stash->ith = 1.0f/stash->params.height;
475 + stash->texData = (unsigned char*)malloc(stash->params.width * stash->params.height);
476 + if (stash->texData == nullptr) goto error;
477 + memset(stash->texData, 0, stash->params.width * stash->params.height);
478 +
479 + stash->dirtyRect[0] = stash->params.width;
480 + stash->dirtyRect[1] = stash->params.height;
481 + stash->dirtyRect[2] = 0;
482 + stash->dirtyRect[3] = 0;
483 483
484 - fonsPushState(stash);
485 - fonsClearState(stash);
484 + fonsPushState(stash);
485 + fonsClearState(stash);
486 486
487 - return stash;
487 + return stash;
488 488
489 489 error:
490 - fonsDeleteInternal(stash);
491 - return nullptr;
490 + fonsDeleteInternal(stash);
491 + return nullptr;
492 492 }
493 493
494 494 static struct FONSstate* fons__getState(struct FONScontext* stash)
495 495 {
496 - return &stash->states[stash->nstates-1];
496 + return &stash->states[stash->nstates-1];
497 497 }
498 498
499 499 void fonsSetSize(struct FONScontext* stash, float size)
500 500 {
501 - fons__getState(stash)->size = size;
501 + fons__getState(stash)->size = size;
502 502 }
503 503
504 504 void fonsSetColor(struct FONScontext* stash, unsigned char colorR, unsigned char colorG, unsigned char colorB, unsigned char colorA)
505 505 {
506 - fons__getState(stash)->color[0] = colorR;
506 + fons__getState(stash)->color[0] = colorR;
507 507 fons__getState(stash)->color[1] = colorG;
508 508 fons__getState(stash)->color[2] = colorB;
509 509 fons__getState(stash)->color[3] = colorA;
  @@ -511,179 +511,179 @@
511 511
512 512 void fonsSetSpacing(struct FONScontext* stash, float spacing)
513 513 {
514 - fons__getState(stash)->spacing = spacing;
514 + fons__getState(stash)->spacing = spacing;
515 515 }
516 516
517 517 void fonsSetBlur(struct FONScontext* stash, float blur)
518 518 {
519 - fons__getState(stash)->blur = blur;
519 + fons__getState(stash)->blur = blur;
520 520 }
521 521
522 522 void fonsSetAlign(struct FONScontext* stash, int align)
523 523 {
524 - fons__getState(stash)->align = align;
524 + fons__getState(stash)->align = align;
525 525 }
526 526
527 527 void fonsSetFont(struct FONScontext* stash, int font)
528 528 {
529 - fons__getState(stash)->font = font;
529 + fons__getState(stash)->font = font;
530 530 }
531 531
532 532 void fonsPushState(struct FONScontext* stash)
533 533 {
534 - if (stash->nstates >= FONS_MAX_STATES)
535 - return;
536 - if (stash->nstates > 0)
537 - memcpy(&stash->states[stash->nstates], &stash->states[stash->nstates-1], sizeof(struct FONSstate));
538 - stash->nstates++;
534 + if (stash->nstates >= FONS_MAX_STATES)
535 + return;
536 + if (stash->nstates > 0)
537 + memcpy(&stash->states[stash->nstates], &stash->states[stash->nstates-1], sizeof(struct FONSstate));
538 + stash->nstates++;
539 539 }
540 540
541 541 void fonsPopState(struct FONScontext* stash)
542 542 {
543 - if (stash->nstates <= 1)
544 - return;
545 - stash->nstates--;
543 + if (stash->nstates <= 1)
544 + return;
545 + stash->nstates--;
546 546 }
547 547
548 548 void fonsClearState(struct FONScontext* stash)
549 549 {
550 - struct FONSstate* state = fons__getState(stash);
551 - state->size = 12.0f;
552 - state->color[0] = 255;
550 + struct FONSstate* state = fons__getState(stash);
551 + state->size = 12.0f;
552 + state->color[0] = 255;
553 553 state->color[1] = 255;
554 554 state->color[2] = 255;
555 555 state->color[3] = 255;
556 - state->font = 0;
557 - state->blur = 0;
558 - state->spacing = 0;
559 - state->align = FONS_ALIGN_LEFT | FONS_ALIGN_BASELINE;
556 + state->font = 0;
557 + state->blur = 0;
558 + state->spacing = 0;
559 + state->align = FONS_ALIGN_LEFT | FONS_ALIGN_BASELINE;
560 560 }
561 561
562 562 static void fons__freeFont(struct FONSfont* font)
563 563 {
564 - if (font == nullptr) return;
565 - if (font->glyphs) free(font->glyphs);
566 - if (font->freeData && font->data) free(font->data);
567 - free(font);
564 + if (font == nullptr) return;
565 + if (font->glyphs) free(font->glyphs);
566 + if (font->freeData && font->data) free(font->data);
567 + free(font);
568 568 }
569 569
570 570 static int fons__allocFont(struct FONScontext* stash)
571 571 {
572 - struct FONSfont* font = nullptr;
573 - if (stash->nfonts+1 > stash->cfonts) {
574 - stash->cfonts = stash->cfonts == 0 ? 8 : stash->cfonts * 2;
575 - stash->fonts = (struct FONSfont**)realloc(stash->fonts, sizeof(struct FONSfont*) * stash->cfonts);
576 - if (stash->fonts == nullptr)
577 - return -1;
578 - }
579 - font = (struct FONSfont*)malloc(sizeof(struct FONSfont));
580 - if (font == nullptr) goto error;
581 - memset(font, 0, sizeof(struct FONSfont));
582 -
583 - font->glyphs = (struct FONSglyph*)malloc(sizeof(struct FONSglyph) * FONS_INIT_GLYPHS);
584 - if (font->glyphs == nullptr) goto error;
585 - font->cglyphs = FONS_INIT_GLYPHS;
586 - font->nglyphs = 0;
587 -
588 - stash->fonts[stash->nfonts++] = font;
589 - return stash->nfonts-1;
572 + struct FONSfont* font = nullptr;
573 + if (stash->nfonts+1 > stash->cfonts) {
574 + stash->cfonts = stash->cfonts == 0 ? 8 : stash->cfonts * 2;
575 + stash->fonts = (struct FONSfont**)realloc(stash->fonts, sizeof(struct FONSfont*) * stash->cfonts);
576 + if (stash->fonts == nullptr)
577 + return -1;
578 + }
579 + font = (struct FONSfont*)malloc(sizeof(struct FONSfont));
580 + if (font == nullptr) goto error;
581 + memset(font, 0, sizeof(struct FONSfont));
582 +
583 + font->glyphs = (struct FONSglyph*)malloc(sizeof(struct FONSglyph) * FONS_INIT_GLYPHS);
584 + if (font->glyphs == nullptr) goto error;
585 + font->cglyphs = FONS_INIT_GLYPHS;
586 + font->nglyphs = 0;
587 +
588 + stash->fonts[stash->nfonts++] = font;
589 + return stash->nfonts-1;
590 590
591 591 error:
592 - fons__freeFont(font);
592 + fons__freeFont(font);
593 593
594 - return FONS_INVALID;
594 + return FONS_INVALID;
595 595 }
596 596
597 597 int fonsAddFont(struct FONScontext* stash, const char* name, const char* path)
598 598 {
599 - FILE* fp = 0;
600 - int dataSize = 0;
601 - unsigned char* data = nullptr;
602 -
603 - // Read in the font data.
604 - fp = fopen(path, "rb");
605 - if (!fp) goto error;
606 - fseek(fp,0,SEEK_END);
607 - dataSize = (int)ftell(fp);
608 - fseek(fp,0,SEEK_SET);
609 - data = (unsigned char*)malloc(dataSize);
610 - if (data == nullptr) goto error;
611 - fread(data, 1, dataSize, fp);
612 - fclose(fp);
613 - fp = 0;
599 + FILE* fp = 0;
600 + int dataSize = 0;
601 + unsigned char* data = nullptr;
602 +
603 + // Read in the font data.
604 + fp = fopen(path, "rb");
605 + if (!fp) goto error;
606 + fseek(fp,0,SEEK_END);
607 + dataSize = (int)ftell(fp);
608 + fseek(fp,0,SEEK_SET);
609 + data = (unsigned char*)malloc(dataSize);
610 + if (data == nullptr) goto error;
611 + fread(data, 1, dataSize, fp);
612 + fclose(fp);
613 + fp = 0;
614 614
615 - return fonsAddFontMem(stash, name, data, dataSize, 1);
615 + return fonsAddFontMem(stash, name, data, dataSize, 1);
616 616
617 617 error:
618 - if (data) free(data);
619 - if (fp) fclose(fp);
620 - return 0;
618 + if (data) free(data);
619 + if (fp) fclose(fp);
620 + return 0;
621 621 }
622 622
623 623 int fonsAddFontMem(struct FONScontext* stash, const char* name, unsigned char* data, int dataSize, int freeData)
624 624 {
625 - int i, ascent, descent, fh, lineGap;
626 - struct FONSfont* font;
625 + int i, ascent, descent, fh, lineGap;
626 + struct FONSfont* font;
627 627
628 - int idx = fons__allocFont(stash);
629 - if (idx == FONS_INVALID)
630 - return FONS_INVALID;
631 -
632 - font = stash->fonts[idx];
633 -
634 - strncpy(font->name, name, sizeof(font->name));
635 - font->name[sizeof(font->name)-1] = '\0';
636 -
637 - // Init hash lookup.
638 - for (i = 0; i < FONS_HASH_LUT_SIZE; ++i)
639 - font->lut[i] = -1;
640 -
641 - // Read in the font data.
642 - font->dataSize = dataSize;
643 - font->data = data;
644 - font->freeData = freeData;
645 -
646 - // Init stb_truetype
647 - stash->nscratch = 0;
648 - font->font.userdata = stash;
649 - if (!stbtt_InitFont(&font->font, font->data, 0)) goto error;
650 -
651 - // Store normalized line height. The real line height is got
652 - // by multiplying the lineh by font size.
653 - stbtt_GetFontVMetrics(&font->font, &ascent, &descent, &lineGap);
654 - fh = ascent - descent;
655 - font->ascender = (float)ascent / (float)fh;
656 - font->descender = (float)descent / (float)fh;
657 - font->lineh = (float)(fh + lineGap) / (float)fh;
628 + int idx = fons__allocFont(stash);
629 + if (idx == FONS_INVALID)
630 + return FONS_INVALID;
631 +
632 + font = stash->fonts[idx];
633 +
634 + strncpy(font->name, name, sizeof(font->name));
635 + font->name[sizeof(font->name)-1] = '\0';
636 +
637 + // Init hash lookup.
638 + for (i = 0; i < FONS_HASH_LUT_SIZE; ++i)
639 + font->lut[i] = -1;
640 +
641 + // Read in the font data.
642 + font->dataSize = dataSize;
643 + font->data = data;
644 + font->freeData = freeData;
645 +
646 + // Init stb_truetype
647 + stash->nscratch = 0;
648 + font->font.userdata = stash;
649 + if (!stbtt_InitFont(&font->font, font->data, 0)) goto error;
650 +
651 + // Store normalized line height. The real line height is got
652 + // by multiplying the lineh by font size.
653 + stbtt_GetFontVMetrics(&font->font, &ascent, &descent, &lineGap);
654 + fh = ascent - descent;
655 + font->ascender = (float)ascent / (float)fh;
656 + font->descender = (float)descent / (float)fh;
657 + font->lineh = (float)(fh + lineGap) / (float)fh;
658 658
659 - return idx;
659 + return idx;
660 660
661 661 error:
662 - fons__freeFont(font);
663 - stash->nfonts--;
664 - return FONS_INVALID;
662 + fons__freeFont(font);
663 + stash->nfonts--;
664 + return FONS_INVALID;
665 665 }
666 666
667 667 int fonsGetFontByName(struct FONScontext* s, const char* name)
668 668 {
669 - int i;
670 - for (i = 0; i < s->nfonts; i++) {
671 - if (strcmp(s->fonts[i]->name, name) == 0)
672 - return i;
673 - }
674 - return FONS_INVALID;
669 + int i;
670 + for (i = 0; i < s->nfonts; i++) {
671 + if (strcmp(s->fonts[i]->name, name) == 0)
672 + return i;
673 + }
674 + return FONS_INVALID;
675 675 }
676 676
677 677
678 678 static struct FONSglyph* fons__allocGlyph(struct FONSfont* font)
679 679 {
680 - if (font->nglyphs+1 > font->cglyphs) {
681 - font->cglyphs = font->cglyphs == 0 ? 8 : font->cglyphs * 2;
682 - font->glyphs = (struct FONSglyph*)realloc(font->glyphs, sizeof(struct FONSglyph) * font->cglyphs);
683 - if (font->glyphs == nullptr) return nullptr;
684 - }
685 - font->nglyphs++;
686 - return &font->glyphs[font->nglyphs-1];
680 + if (font->nglyphs+1 > font->cglyphs) {
681 + font->cglyphs = font->cglyphs == 0 ? 8 : font->cglyphs * 2;
682 + font->glyphs = (struct FONSglyph*)realloc(font->glyphs, sizeof(struct FONSglyph) * font->cglyphs);
683 + if (font->glyphs == nullptr) return nullptr;
684 + }
685 + font->nglyphs++;
686 + return &font->glyphs[font->nglyphs-1];
687 687 }
688 688
689 689
  @@ -694,553 +694,553 @@
694 694
695 695 static void fons__blurCols(unsigned char* dst, int w, int h, int dstStride, int alpha)
696 696 {
697 - int x, y;
698 - for (y = 0; y < h; y++) {
699 - int z = 0; // force zero border
700 - for (x = 1; x < w; x++) {
701 - z += (alpha * (((int)(dst[x]) << ZPREC) - z)) >> APREC;
702 - dst[x] = (unsigned char)(z >> ZPREC);
703 - }
704 - dst[w-1] = 0; // force zero border
705 - z = 0;
706 - for (x = w-2; x >= 0; x--) {
707 - z += (alpha * (((int)(dst[x]) << ZPREC) - z)) >> APREC;
708 - dst[x] = (unsigned char)(z >> ZPREC);
709 - }
710 - dst[0] = 0; // force zero border
711 - dst += dstStride;
712 - }
697 + int x, y;
698 + for (y = 0; y < h; y++) {
699 + int z = 0; // force zero border
700 + for (x = 1; x < w; x++) {
701 + z += (alpha * (((int)(dst[x]) << ZPREC) - z)) >> APREC;
702 + dst[x] = (unsigned char)(z >> ZPREC);
703 + }
704 + dst[w-1] = 0; // force zero border
705 + z = 0;
706 + for (x = w-2; x >= 0; x--) {
707 + z += (alpha * (((int)(dst[x]) << ZPREC) - z)) >> APREC;
708 + dst[x] = (unsigned char)(z >> ZPREC);
709 + }
710 + dst[0] = 0; // force zero border
711 + dst += dstStride;
712 + }
713 713 }
714 714
715 715 static void fons__blurRows(unsigned char* dst, int w, int h, int dstStride, int alpha)
716 716 {
717 - int x, y;
718 - for (x = 0; x < w; x++) {
719 - int z = 0; // force zero border
720 - for (y = dstStride; y < h*dstStride; y += dstStride) {
721 - z += (alpha * (((int)(dst[y]) << ZPREC) - z)) >> APREC;
722 - dst[y] = (unsigned char)(z >> ZPREC);
723 - }
724 - dst[(h-1)*dstStride] = 0; // force zero border
725 - z = 0;
726 - for (y = (h-2)*dstStride; y >= 0; y -= dstStride) {
727 - z += (alpha * (((int)(dst[y]) << ZPREC) - z)) >> APREC;
728 - dst[y] = (unsigned char)(z >> ZPREC);
729 - }
730 - dst[0] = 0; // force zero border
731 - dst++;
732 - }
717 + int x, y;
718 + for (x = 0; x < w; x++) {
719 + int z = 0; // force zero border
720 + for (y = dstStride; y < h*dstStride; y += dstStride) {
721 + z += (alpha * (((int)(dst[y]) << ZPREC) - z)) >> APREC;
722 + dst[y] = (unsigned char)(z >> ZPREC);
723 + }
724 + dst[(h-1)*dstStride] = 0; // force zero border
725 + z = 0;
726 + for (y = (h-2)*dstStride; y >= 0; y -= dstStride) {
727 + z += (alpha * (((int)(dst[y]) << ZPREC) - z)) >> APREC;
728 + dst[y] = (unsigned char)(z >> ZPREC);
729 + }
730 + dst[0] = 0; // force zero border
731 + dst++;
732 + }
733 733 }
734 734
735 735
736 736 static void fons__blur(struct FONScontext* stash, unsigned char* dst, int w, int h, int dstStride, int blur)
737 737 {
738 - int alpha;
739 - float sigma;
738 + int alpha;
739 + float sigma;
740 740
741 - if (blur < 1)
742 - return;
743 - // Calculate the alpha such that 90% of the kernel is within the radius. (Kernel extends to infinity)
744 - sigma = (float)blur * 0.57735f; // 1 / sqrt(3)
745 - alpha = (int)((1<<APREC) * (1.0f - expf(-2.3f / (sigma+1.0f))));
746 - fons__blurRows(dst, w, h, dstStride, alpha);
747 - fons__blurCols(dst, w, h, dstStride, alpha);
748 - fons__blurRows(dst, w, h, dstStride, alpha);
749 - fons__blurCols(dst, w, h, dstStride, alpha);
750 - // fons__blurrows(dst, w, h, dstStride, alpha);
751 - // fons__blurcols(dst, w, h, dstStride, alpha);
741 + if (blur < 1)
742 + return;
743 + // Calculate the alpha such that 90% of the kernel is within the radius. (Kernel extends to infinity)
744 + sigma = (float)blur * 0.57735f; // 1 / sqrt(3)
745 + alpha = (int)((1<<APREC) * (1.0f - expf(-2.3f / (sigma+1.0f))));
746 + fons__blurRows(dst, w, h, dstStride, alpha);
747 + fons__blurCols(dst, w, h, dstStride, alpha);
748 + fons__blurRows(dst, w, h, dstStride, alpha);
749 + fons__blurCols(dst, w, h, dstStride, alpha);
750 + // fons__blurrows(dst, w, h, dstStride, alpha);
751 + // fons__blurcols(dst, w, h, dstStride, alpha);
752 752 }
753 753
754 754 static struct FONSglyph* fons__getGlyph(struct FONScontext* stash, struct FONSfont* font, unsigned int codepoint,
755 - short isize, short iblur)
755 + short isize, short iblur)
756 756 {
757 - int i, g, advance, lsb, x0, y0, x1, y1, gw, gh, gx, gy, x, y;
758 - float scale;
759 - struct FONSglyph* glyph = nullptr;
760 - unsigned int h;
761 - float size = isize/10.0f;
762 - int pad;
763 - unsigned char* bdst;
764 - unsigned char* dst;
765 -
766 - if (isize < 2) return nullptr;
767 - if (iblur > 20) iblur = 20;
768 - pad = iblur+2;
769 -
770 - // Reset allocator.
771 - stash->nscratch = 0;
772 -
773 - // Find code point and size.
774 - h = fons__hashint(codepoint) & (FONS_HASH_LUT_SIZE-1);
775 - i = font->lut[h];
776 - while (i != -1) {
777 - if (font->glyphs[i].codepoint == codepoint && font->glyphs[i].size == isize && font->glyphs[i].blur == iblur)
778 - return &font->glyphs[i];
779 - i = font->glyphs[i].next;
780 - }
781 -
782 - // Could not find glyph, create it.
783 - scale = stbtt_ScaleForPixelHeight(&font->font, size);
784 - g = stbtt_FindGlyphIndex(&font->font, codepoint);
785 - stbtt_GetGlyphHMetrics(&font->font, g, &advance, &lsb);
786 - stbtt_GetGlyphBitmapBox(&font->font, g, scale,scale, &x0,&y0,&x1,&y1);
787 - gw = x1-x0 + pad*2;
788 - gh = y1-y0 + pad*2;
789 -
790 - // Find free spot for the rect in the atlas
791 - if (fons__atlasAddRect(stash->atlas, gw, gh, &gx, &gy) == 0)
792 - return nullptr;
793 -
794 - // Init glyph.
795 - glyph = fons__allocGlyph(font);
796 - glyph->codepoint = codepoint;
797 - glyph->size = isize;
798 - glyph->blur = iblur;
799 - glyph->index = g;
800 - glyph->x0 = gx;
801 - glyph->y0 = gy;
802 - glyph->x1 = glyph->x0+gw;
803 - glyph->y1 = glyph->y0+gh;
804 - glyph->xadv = (short)(scale * advance * 10.0f);
805 - glyph->xoff = x0 - pad;
806 - glyph->yoff = y0 - pad;
807 - glyph->next = 0;
808 -
809 - // Insert char to hash lookup.
810 - glyph->next = font->lut[h];
811 - font->lut[h] = font->nglyphs-1;
812 -
813 - // Rasterize
814 - dst = &stash->texData[(glyph->x0+pad) + (glyph->y0+pad) * stash->params.width];
815 - stbtt_MakeGlyphBitmap(&font->font, dst, gw-pad*2,gh-pad*2, stash->params.width, scale,scale, g);
816 -
817 - // Make sure there is one pixel empty border.
818 - dst = &stash->texData[glyph->x0 + glyph->y0 * stash->params.width];
819 - for (y = 0; y < gh; y++) {
820 - dst[y*stash->params.width] = 0;
821 - dst[gw-1 + y*stash->params.width] = 0;
822 - }
823 - for (x = 0; x < gw; x++) {
824 - dst[x] = 0;
825 - dst[x + (gh-1)*stash->params.width] = 0;
826 - }
827 -
828 - /*
829 - // Debug code to color the glyph background
830 - int x,y;
831 - unsigned char* fdst = &stash->texData[glyph->x0 + glyph->y0 * stash->params.width];
832 - for (y = 0; y < gh; y++) {
833 - for (x = 0; x < gw; x++) {
834 - int a = (int)fdst[x+y*stash->params.width] + 20;
835 - if (a > 255) a = 255;
836 - fdst[x+y*stash->params.width] = a;
837 - }
838 - }
839 - */
840 -
841 - // Blur
842 - if (iblur > 0) {
843 - stash->nscratch = 0;
844 - bdst = &stash->texData[glyph->x0 + glyph->y0 * stash->params.width];
845 - fons__blur(stash, bdst, gw,gh, stash->params.width, iblur);
846 - }
847 -
848 - stash->dirtyRect[0] = fons__mini(stash->dirtyRect[0], glyph->x0);
849 - stash->dirtyRect[1] = fons__mini(stash->dirtyRect[1], glyph->y0);
850 - stash->dirtyRect[2] = fons__maxi(stash->dirtyRect[2], glyph->x1);
851 - stash->dirtyRect[3] = fons__maxi(stash->dirtyRect[3], glyph->y1);
757 + int i, g, advance, lsb, x0, y0, x1, y1, gw, gh, gx, gy, x, y;
758 + float scale;
759 + struct FONSglyph* glyph = nullptr;
760 + unsigned int h;
761 + float size = isize/10.0f;
762 + int pad;
763 + unsigned char* bdst;
764 + unsigned char* dst;
765 +
766 + if (isize < 2) return nullptr;
767 + if (iblur > 20) iblur = 20;
768 + pad = iblur+2;
769 +
770 + // Reset allocator.
771 + stash->nscratch = 0;
772 +
773 + // Find code point and size.
774 + h = fons__hashint(codepoint) & (FONS_HASH_LUT_SIZE-1);
775 + i = font->lut[h];
776 + while (i != -1) {
777 + if (font->glyphs[i].codepoint == codepoint && font->glyphs[i].size == isize && font->glyphs[i].blur == iblur)
778 + return &font->glyphs[i];
779 + i = font->glyphs[i].next;
780 + }
781 +
782 + // Could not find glyph, create it.
783 + scale = stbtt_ScaleForPixelHeight(&font->font, size);
784 + g = stbtt_FindGlyphIndex(&font->font, codepoint);
785 + stbtt_GetGlyphHMetrics(&font->font, g, &advance, &lsb);
786 + stbtt_GetGlyphBitmapBox(&font->font, g, scale,scale, &x0,&y0,&x1,&y1);
787 + gw = x1-x0 + pad*2;
788 + gh = y1-y0 + pad*2;
789 +
790 + // Find free spot for the rect in the atlas
791 + if (fons__atlasAddRect(stash->atlas, gw, gh, &gx, &gy) == 0)
792 + return nullptr;
793 +
794 + // Init glyph.
795 + glyph = fons__allocGlyph(font);
796 + glyph->codepoint = codepoint;
797 + glyph->size = isize;
798 + glyph->blur = iblur;
799 + glyph->index = g;
800 + glyph->x0 = gx;
801 + glyph->y0 = gy;
802 + glyph->x1 = glyph->x0+gw;
803 + glyph->y1 = glyph->y0+gh;
804 + glyph->xadv = (short)(scale * advance * 10.0f);
805 + glyph->xoff = x0 - pad;
806 + glyph->yoff = y0 - pad;
807 + glyph->next = 0;
808 +
809 + // Insert char to hash lookup.
810 + glyph->next = font->lut[h];
811 + font->lut[h] = font->nglyphs-1;
812 +
813 + // Rasterize
814 + dst = &stash->texData[(glyph->x0+pad) + (glyph->y0+pad) * stash->params.width];
815 + stbtt_MakeGlyphBitmap(&font->font, dst, gw-pad*2,gh-pad*2, stash->params.width, scale,scale, g);
816 +
817 + // Make sure there is one pixel empty border.
818 + dst = &stash->texData[glyph->x0 + glyph->y0 * stash->params.width];
819 + for (y = 0; y < gh; y++) {
820 + dst[y*stash->params.width] = 0;
821 + dst[gw-1 + y*stash->params.width] = 0;
822 + }
823 + for (x = 0; x < gw; x++) {
824 + dst[x] = 0;
825 + dst[x + (gh-1)*stash->params.width] = 0;
826 + }
827 +
828 + /*
829 + // Debug code to color the glyph background
830 + int x,y;
831 + unsigned char* fdst = &stash->texData[glyph->x0 + glyph->y0 * stash->params.width];
832 + for (y = 0; y < gh; y++) {
833 + for (x = 0; x < gw; x++) {
834 + int a = (int)fdst[x+y*stash->params.width] + 20;
835 + if (a > 255) a = 255;
836 + fdst[x+y*stash->params.width] = a;
837 + }
838 + }
839 + */
840 +
841 + // Blur
842 + if (iblur > 0) {
843 + stash->nscratch = 0;
844 + bdst = &stash->texData[glyph->x0 + glyph->y0 * stash->params.width];
845 + fons__blur(stash, bdst, gw,gh, stash->params.width, iblur);
846 + }
847 +
848 + stash->dirtyRect[0] = fons__mini(stash->dirtyRect[0], glyph->x0);
849 + stash->dirtyRect[1] = fons__mini(stash->dirtyRect[1], glyph->y0);
850 + stash->dirtyRect[2] = fons__maxi(stash->dirtyRect[2], glyph->x1);
851 + stash->dirtyRect[3] = fons__maxi(stash->dirtyRect[3], glyph->y1);
852 852
853 - return glyph;
853 + return glyph;
854 854 }
855 855
856 856 static void fons__getQuad(struct FONScontext* stash, struct FONSfont* font,
857 - struct FONSglyph* prevGlyph, struct FONSglyph* glyph,
858 - float scale, float spacing, float* x, float* y, struct FONSquad* q)
857 + struct FONSglyph* prevGlyph, struct FONSglyph* glyph,
858 + float scale, float spacing, float* x, float* y, struct FONSquad* q)
859 859 {
860 - int rx,ry,xoff,yoff,x0,y0,x1,y1;
860 + int rx,ry,xoff,yoff,x0,y0,x1,y1;
861 861
862 - if (prevGlyph) {
863 - float adv = stbtt_GetGlyphKernAdvance(&font->font, prevGlyph->index, glyph->index) * scale;
864 - *x += adv;
865 - }
866 -
867 - // Each glyph has 2px border to allow good interpolation,
868 - // one pixel to prevent leaking, and one to allow good interpolation for rendering.
869 - // Inset the texture region by one pixel for corret interpolation.
870 - xoff = glyph->xoff+1;
871 - yoff = glyph->yoff+1;
872 - x0 = glyph->x0+1;
873 - y0 = glyph->y0+1;
874 - x1 = glyph->x1-1;
875 - y1 = glyph->y1-1;
876 -
877 - if (stash->params.flags & FONS_ZERO_TOPLEFT) {
878 - rx = (int)(*x + xoff);
879 - ry = (int)(*y + yoff);
880 -
881 - q->x0 = rx;
882 - q->y0 = ry;
883 - q->x1 = rx + x1 - x0;
884 - q->y1 = ry + y1 - y0;
885 -
886 - q->s0 = x0 * stash->itw;
887 - q->t0 = y0 * stash->ith;
888 - q->s1 = x1 * stash->itw;
889 - q->t1 = y1 * stash->ith;
890 - } else {
891 - rx = (int)(*x + xoff);
892 - ry = (int)(*y - yoff);
893 -
894 - q->x0 = rx;
895 - q->y0 = ry;
896 - q->x1 = rx + x1 - x0;
897 - q->y1 = ry - y1 + y0;
898 -
899 - q->s0 = x0 * stash->itw;
900 - q->t0 = y0 * stash->ith;
901 - q->s1 = x1 * stash->itw;
902 - q->t1 = y1 * stash->ith;
903 - }
862 + if (prevGlyph) {
863 + float adv = stbtt_GetGlyphKernAdvance(&font->font, prevGlyph->index, glyph->index) * scale;
864 + *x += adv;
865 + }
866 +
867 + // Each glyph has 2px border to allow good interpolation,
868 + // one pixel to prevent leaking, and one to allow good interpolation for rendering.
869 + // Inset the texture region by one pixel for corret interpolation.
870 + xoff = glyph->xoff+1;
871 + yoff = glyph->yoff+1;
872 + x0 = glyph->x0+1;
873 + y0 = glyph->y0+1;
874 + x1 = glyph->x1-1;
875 + y1 = glyph->y1-1;
876 +
877 + if (stash->params.flags & FONS_ZERO_TOPLEFT) {
878 + rx = (int)(*x + xoff);
879 + ry = (int)(*y + yoff);
880 +
881 + q->x0 = rx;
882 + q->y0 = ry;
883 + q->x1 = rx + x1 - x0;
884 + q->y1 = ry + y1 - y0;
885 +
886 + q->s0 = x0 * stash->itw;
887 + q->t0 = y0 * stash->ith;
888 + q->s1 = x1 * stash->itw;
889 + q->t1 = y1 * stash->ith;
890 + } else {
891 + rx = (int)(*x + xoff);
892 + ry = (int)(*y - yoff);
893 +
894 + q->x0 = rx;
895 + q->y0 = ry;
896 + q->x1 = rx + x1 - x0;
897 + q->y1 = ry - y1 + y0;
898 +
899 + q->s0 = x0 * stash->itw;
900 + q->t0 = y0 * stash->ith;
901 + q->s1 = x1 * stash->itw;
902 + q->t1 = y1 * stash->ith;
903 + }
904 904
905 - *x += (int)(glyph->xadv / 10.0f + spacing + 0.5f);
905 + *x += (int)(glyph->xadv / 10.0f + spacing + 0.5f);
906 906 }
907 907
908 908 static void fons__flush(struct FONScontext* stash)
909 909 {
910 - // Flush texture
911 - if (stash->dirtyRect[0] < stash->dirtyRect[2] && stash->dirtyRect[1] < stash->dirtyRect[3]) {
912 - if (stash->params.renderUpdate != nullptr)
913 - stash->params.renderUpdate(stash->params.userPtr, stash->dirtyRect, stash->texData);
914 - // Reset dirty rect
915 - stash->dirtyRect[0] = stash->params.width;
916 - stash->dirtyRect[1] = stash->params.height;
917 - stash->dirtyRect[2] = 0;
918 - stash->dirtyRect[3] = 0;
919 - }
920 -
921 - // Flush triangles
922 - if (stash->nverts > 0) {
923 - if (stash->params.renderDraw != nullptr)
924 - stash->params.renderDraw(stash->params.userPtr, stash->verts, stash->tcoords, stash->colors, stash->nverts);
925 - stash->nverts = 0;
926 - }
910 + // Flush texture
911 + if (stash->dirtyRect[0] < stash->dirtyRect[2] && stash->dirtyRect[1] < stash->dirtyRect[3]) {
912 + if (stash->params.renderUpdate != nullptr)
913 + stash->params.renderUpdate(stash->params.userPtr, stash->dirtyRect, stash->texData);
914 + // Reset dirty rect
915 + stash->dirtyRect[0] = stash->params.width;
916 + stash->dirtyRect[1] = stash->params.height;
917 + stash->dirtyRect[2] = 0;
918 + stash->dirtyRect[3] = 0;
919 + }
920 +
921 + // Flush triangles
922 + if (stash->nverts > 0) {
923 + if (stash->params.renderDraw != nullptr)
924 + stash->params.renderDraw(stash->params.userPtr, stash->verts, stash->tcoords, stash->colors, stash->nverts);
925 + stash->nverts = 0;
926 + }
927 927 }
928 928
929 929 static __inline void fons__vertex(struct FONScontext* stash, float x, float y, float s, float t, unsigned char cR, unsigned char cG, unsigned char cB, unsigned char cA)
930 930 {
931 - stash->verts[stash->nverts*2+0] = x;
932 - stash->verts[stash->nverts*2+1] = y;
933 - stash->tcoords[stash->nverts*2+0] = s;
934 - stash->tcoords[stash->nverts*2+1] = t;
935 - stash->colors[stash->nverts*4+0] = cR;
931 + stash->verts[stash->nverts*2+0] = x;
932 + stash->verts[stash->nverts*2+1] = y;
933 + stash->tcoords[stash->nverts*2+0] = s;
934 + stash->tcoords[stash->nverts*2+1] = t;
935 + stash->colors[stash->nverts*4+0] = cR;
936 936 stash->colors[stash->nverts*4+1] = cG;
937 937 stash->colors[stash->nverts*4+2] = cB;
938 938 stash->colors[stash->nverts*4+3] = cA;
939 - stash->nverts++;
939 + stash->nverts++;
940 940 }
941 941
942 942 static float fons__getVertAlign(struct FONScontext* stash, struct FONSfont* font, int align, short isize)
943 943 {
944 - if (stash->params.flags & FONS_ZERO_TOPLEFT) {
945 - if (align & FONS_ALIGN_TOP) {
946 - return font->ascender * (float)isize/10.0f;
947 - } else if (align & FONS_ALIGN_MIDDLE) {
948 - return (font->ascender + font->descender) / 2.0f * (float)isize/10.0f;
949 - } else if (align & FONS_ALIGN_BASELINE) {
950 - return 0.0f;
951 - } else if (align & FONS_ALIGN_BOTTOM) {
952 - return font->descender * (float)isize/10.0f;
953 - }
954 - } else {
955 - if (align & FONS_ALIGN_TOP) {
956 - return -font->ascender * (float)isize/10.0f;
957 - } else if (align & FONS_ALIGN_MIDDLE) {
958 - return -(font->ascender + font->descender) / 2.0f * (float)isize/10.0f;
959 - } else if (align & FONS_ALIGN_BASELINE) {
960 - return 0.0f;
961 - } else if (align & FONS_ALIGN_BOTTOM) {
962 - return -font->descender * (float)isize/10.0f;
963 - }
964 - }
965 - return 0.0;
944 + if (stash->params.flags & FONS_ZERO_TOPLEFT) {
945 + if (align & FONS_ALIGN_TOP) {
946 + return font->ascender * (float)isize/10.0f;
947 + } else if (align & FONS_ALIGN_MIDDLE) {
948 + return (font->ascender + font->descender) / 2.0f * (float)isize/10.0f;
949 + } else if (align & FONS_ALIGN_BASELINE) {
950 + return 0.0f;
951 + } else if (align & FONS_ALIGN_BOTTOM) {
952 + return font->descender * (float)isize/10.0f;
953 + }
954 + } else {
955 + if (align & FONS_ALIGN_TOP) {
956 + return -font->ascender * (float)isize/10.0f;
957 + } else if (align & FONS_ALIGN_MIDDLE) {
958 + return -(font->ascender + font->descender) / 2.0f * (float)isize/10.0f;
959 + } else if (align & FONS_ALIGN_BASELINE) {
960 + return 0.0f;
961 + } else if (align & FONS_ALIGN_BOTTOM) {
962 + return -font->descender * (float)isize/10.0f;
963 + }
964 + }
965 + return 0.0;
966 966 }
967 967
968 968 float fonsDrawText(struct FONScontext* stash,
969 - float x, float y,
970 - const char* str, const char* end)
969 + float x, float y,
970 + const char* str, const char* end)
971 971 {
972 - struct FONSstate* state = fons__getState(stash);
973 - unsigned int codepoint;
974 - unsigned int utf8state = 0;
975 - struct FONSglyph* glyph = nullptr;
976 - struct FONSglyph* prevGlyph = nullptr;
977 - struct FONSquad q;
978 - short isize = (short)(state->size*10.0f);
979 - short iblur = (short)state->blur;
980 - float scale;
981 - struct FONSfont* font;
982 - float width;
983 -
984 - if (stash == nullptr) return x;
985 - if (state->font < 0 || state->font >= stash->nfonts) return x;
986 - font = stash->fonts[state->font];
987 - if (!font->data) return x;
988 -
989 - scale = stbtt_ScaleForPixelHeight(&font->font, (float)isize/10.0f);
990 -
991 - // Align horizontally
992 - if (state->align & FONS_ALIGN_LEFT) {
993 - // empty
994 - } else if (state->align & FONS_ALIGN_RIGHT) {
995 - width = fonsTextBounds(stash, str, end, nullptr);
996 - x -= width;
997 - } else if (state->align & FONS_ALIGN_CENTER) {
998 - width = fonsTextBounds(stash, str, end, nullptr);
999 - x -= width * 0.5f;
1000 - }
1001 - // Align vertically.
1002 - y += fons__getVertAlign(stash, font, state->align, isize);
1003 -
1004 - if (end == nullptr)
1005 - end = str + strlen(str);
1006 -
1007 - for (; *str; ++str) {
1008 - if (fons__decutf8(&utf8state, &codepoint, *(const unsigned char*)str))
1009 - continue;
1010 - glyph = fons__getGlyph(stash, font, codepoint, isize, iblur);
1011 - if (glyph) {
1012 - fons__getQuad(stash, font, prevGlyph, glyph, scale, state->spacing, &x, &y, &q);
1013 -
1014 - if (stash->nverts+6 > FONS_VERTEX_COUNT)
1015 - fons__flush(stash);
1016 -
1017 - fons__vertex(stash, q.x0, q.y0, q.s0, q.t0, state->color[0],state->color[1],state->color[2],state->color[3]);
1018 - fons__vertex(stash, q.x1, q.y1, q.s1, q.t1, state->color[0],state->color[1],state->color[2],state->color[3]);
1019 - fons__vertex(stash, q.x1, q.y0, q.s1, q.t0, state->color[0],state->color[1],state->color[2],state->color[3]);
1020 -
1021 - fons__vertex(stash, q.x0, q.y0, q.s0, q.t0, state->color[0],state->color[1],state->color[2],state->color[3]);
1022 - fons__vertex(stash, q.x0, q.y1, q.s0, q.t1, state->color[0],state->color[1],state->color[2],state->color[3]);
1023 - fons__vertex(stash, q.x1, q.y1, q.s1, q.t1, state->color[0],state->color[1],state->color[2],state->color[3]);
1024 - }
1025 - prevGlyph = glyph;
1026 - }
1027 - fons__flush(stash);
972 + struct FONSstate* state = fons__getState(stash);
973 + unsigned int codepoint;
974 + unsigned int utf8state = 0;
975 + struct FONSglyph* glyph = nullptr;
976 + struct FONSglyph* prevGlyph = nullptr;
977 + struct FONSquad q;
978 + short isize = (short)(state->size*10.0f);
979 + short iblur = (short)state->blur;
980 + float scale;
981 + struct FONSfont* font;
982 + float width;
983 +
984 + if (stash == nullptr) return x;
985 + if (state->font < 0 || state->font >= stash->nfonts) return x;
986 + font = stash->fonts[state->font];
987 + if (!font->data) return x;
988 +
989 + scale = stbtt_ScaleForPixelHeight(&font->font, (float)isize/10.0f);
990 +
991 + // Align horizontally
992 + if (state->align & FONS_ALIGN_LEFT) {
993 + // empty
994 + } else if (state->align & FONS_ALIGN_RIGHT) {
995 + width = fonsTextBounds(stash, str, end, nullptr);
996 + x -= width;
997 + } else if (state->align & FONS_ALIGN_CENTER) {
998 + width = fonsTextBounds(stash, str, end, nullptr);
999 + x -= width * 0.5f;
1000 + }
1001 + // Align vertically.
1002 + y += fons__getVertAlign(stash, font, state->align, isize);
1003 +
1004 + if (end == nullptr)
1005 + end = str + strlen(str);
1006 +
1007 + for (; *str; ++str) {
1008 + if (fons__decutf8(&utf8state, &codepoint, *(const unsigned char*)str))
1009 + continue;
1010 + glyph = fons__getGlyph(stash, font, codepoint, isize, iblur);
1011 + if (glyph) {
1012 + fons__getQuad(stash, font, prevGlyph, glyph, scale, state->spacing, &x, &y, &q);
1013 +
1014 + if (stash->nverts+6 > FONS_VERTEX_COUNT)
1015 + fons__flush(stash);
1016 +
1017 + fons__vertex(stash, q.x0, q.y0, q.s0, q.t0, state->color[0],state->color[1],state->color[2],state->color[3]);
1018 + fons__vertex(stash, q.x1, q.y1, q.s1, q.t1, state->color[0],state->color[1],state->color[2],state->color[3]);
1019 + fons__vertex(stash, q.x1, q.y0, q.s1, q.t0, state->color[0],state->color[1],state->color[2],state->color[3]);
1020 +
1021 + fons__vertex(stash, q.x0, q.y0, q.s0, q.t0, state->color[0],state->color[1],state->color[2],state->color[3]);
1022 + fons__vertex(stash, q.x0, q.y1, q.s0, q.t1, state->color[0],state->color[1],state->color[2],state->color[3]);
1023 + fons__vertex(stash, q.x1, q.y1, q.s1, q.t1, state->color[0],state->color[1],state->color[2],state->color[3]);
1024 + }
1025 + prevGlyph = glyph;
1026 + }
1027 + fons__flush(stash);
1028 1028
1029 - return x;
1029 + return x;
1030 1030 }
1031 1031
1032 1032 int fonsTextIterInit(struct FONScontext* stash, struct FONStextIter* iter,
1033 - float x, float y, const char* str, const char* end)
1033 + float x, float y, const char* str, const char* end)
1034 1034 {
1035 - struct FONSstate* state = fons__getState(stash);
1036 - float width;
1035 + struct FONSstate* state = fons__getState(stash);
1036 + float width;
1037 1037
1038 - memset(iter, 0, sizeof(*iter));
1038 + memset(iter, 0, sizeof(*iter));
1039 1039
1040 - if (stash == nullptr) return 0;
1041 - if (state->font < 0 || state->font >= stash->nfonts) return 0;
1042 - iter->font = stash->fonts[state->font];
1043 - if (!iter->font->data) return 0;
1044 -
1045 - iter->isize = (short)(state->size*10.0f);
1046 - iter->iblur = (short)state->blur;
1047 - iter->scale = stbtt_ScaleForPixelHeight(&iter->font->font, (float)iter->isize/10.0f);
1048 -
1049 - // Align horizontally
1050 - if (state->align & FONS_ALIGN_LEFT) {
1051 - // empty
1052 - } else if (state->align & FONS_ALIGN_RIGHT) {
1053 - width = fonsTextBounds(stash, str, end, nullptr);
1054 - x -= width;
1055 - } else if (state->align & FONS_ALIGN_CENTER) {
1056 - width = fonsTextBounds(stash, str, end, nullptr);
1057 - x -= width * 0.5f;
1058 - }
1059 - // Align vertically.
1060 - y += fons__getVertAlign(stash, iter->font, state->align, iter->isize);
1061 -
1062 - if (end == nullptr)
1063 - end = str + strlen(str);
1064 -
1065 - iter->x = x;
1066 - iter->y = y;
1067 - iter->spacing = state->spacing;
1068 - iter->str = str;
1069 - iter->end = end;
1040 + if (stash == nullptr) return 0;
1041 + if (state->font < 0 || state->font >= stash->nfonts) return 0;
1042 + iter->font = stash->fonts[state->font];
1043 + if (!iter->font->data) return 0;
1044 +
1045 + iter->isize = (short)(state->size*10.0f);
1046 + iter->iblur = (short)state->blur;
1047 + iter->scale = stbtt_ScaleForPixelHeight(&iter->font->font, (float)iter->isize/10.0f);
1048 +
1049 + // Align horizontally
1050 + if (state->align & FONS_ALIGN_LEFT) {
1051 + // empty
1052 + } else if (state->align & FONS_ALIGN_RIGHT) {
1053 + width = fonsTextBounds(stash, str, end, nullptr);
1054 + x -= width;
1055 + } else if (state->align & FONS_ALIGN_CENTER) {
1056 + width = fonsTextBounds(stash, str, end, nullptr);
1057 + x -= width * 0.5f;
1058 + }
1059 + // Align vertically.
1060 + y += fons__getVertAlign(stash, iter->font, state->align, iter->isize);
1061 +
1062 + if (end == nullptr)
1063 + end = str + strlen(str);
1064 +
1065 + iter->x = x;
1066 + iter->y = y;
1067 + iter->spacing = state->spacing;
1068 + iter->str = str;
1069 + iter->end = end;
1070 1070
1071 - return 1;
1071 + return 1;
1072 1072 }
1073 1073
1074 1074 int fonsTextIterNext(struct FONScontext* stash, struct FONStextIter* iter, struct FONSquad* quad)
1075 1075 {
1076 - struct FONSglyph* glyph = nullptr;
1077 - unsigned int codepoint = 0;
1078 - const char* str = iter->str;
1079 -
1080 - if (*str == '\0')
1081 - return 0;
1082 -
1083 - for (; str != iter->end; str++) {
1084 - if (fons__decutf8(&iter->utf8state, &codepoint, *(const unsigned char*)str))
1085 - continue;
1086 - str++;
1087 - // Get glyph and quad
1088 - glyph = fons__getGlyph(stash, iter->font, codepoint, iter->isize, iter->iblur);
1089 - if (glyph != nullptr)
1090 - fons__getQuad(stash, iter->font, iter->prevGlyph, glyph, iter->scale, iter->spacing, &iter->x, &iter->y, quad);
1091 - iter->prevGlyph = glyph;
1092 - break;
1093 - }
1094 - iter->str = str;
1076 + struct FONSglyph* glyph = nullptr;
1077 + unsigned int codepoint = 0;
1078 + const char* str = iter->str;
1079 +
1080 + if (*str == '\0')
1081 + return 0;
1082 +
1083 + for (; str != iter->end; str++) {
1084 + if (fons__decutf8(&iter->utf8state, &codepoint, *(const unsigned char*)str))
1085 + continue;
1086 + str++;
1087 + // Get glyph and quad
1088 + glyph = fons__getGlyph(stash, iter->font, codepoint, iter->isize, iter->iblur);
1089 + if (glyph != nullptr)
1090 + fons__getQuad(stash, iter->font, iter->prevGlyph, glyph, iter->scale, iter->spacing, &iter->x, &iter->y, quad);
1091 + iter->prevGlyph = glyph;
1092 + break;
1093 + }
1094 + iter->str = str;
1095 1095
1096 - return 1;
1096 + return 1;
1097 1097 }
1098 1098
1099 1099 void fonsDrawDebug(struct FONScontext* stash, float x, float y)
1100 1100 {
1101 - int w = stash->params.width;
1102 - int h = stash->params.height;
1103 - if (stash->nverts+6 > FONS_VERTEX_COUNT)
1104 - fons__flush(stash);
1105 -
1106 - fons__vertex(stash, x+0, y+0, 0, 0, 255,255,255,255);
1107 - fons__vertex(stash, x+w, y+h, 1, 1, 255,255,255,255);
1108 - fons__vertex(stash, x+w, y+0, 1, 0, 255,255,255,255);
1109 -
1110 - fons__vertex(stash, x+0, y+0, 0, 0, 255,255,255,255);
1111 - fons__vertex(stash, x+0, y+h, 0, 1, 255,255,255,255);
1112 - fons__vertex(stash, x+w, y+h, 1, 1, 255,255,255,255);
1101 + int w = stash->params.width;
1102 + int h = stash->params.height;
1103 + if (stash->nverts+6 > FONS_VERTEX_COUNT)
1104 + fons__flush(stash);
1105 +
1106 + fons__vertex(stash, x+0, y+0, 0, 0, 255,255,255,255);
1107 + fons__vertex(stash, x+w, y+h, 1, 1, 255,255,255,255);
1108 + fons__vertex(stash, x+w, y+0, 1, 0, 255,255,255,255);
1109 +
1110 + fons__vertex(stash, x+0, y+0, 0, 0, 255,255,255,255);
1111 + fons__vertex(stash, x+0, y+h, 0, 1, 255,255,255,255);
1112 + fons__vertex(stash, x+w, y+h, 1, 1, 255,255,255,255);
1113 1113 }
1114 1114
1115 1115 float fonsTextBounds(struct FONScontext* stash,
1116 - const char* str, const char* end,
1117 - float* bounds)
1116 + const char* str, const char* end,
1117 + float* bounds)
1118 1118 {
1119 - struct FONSstate* state = fons__getState(stash);
1120 - unsigned int codepoint;
1121 - unsigned int utf8state = 0;
1122 - struct FONSquad q;
1123 - struct FONSglyph* glyph = nullptr;
1124 - struct FONSglyph* prevGlyph = nullptr;
1125 - short isize = (short)(state->size*10.0f);
1126 - short iblur = (short)state->blur;
1127 - float scale;
1128 - struct FONSfont* font;
1129 - float x = 0, y = 0, minx, miny, maxx, maxy;
1130 -
1131 - if (stash == nullptr) return 0;
1132 - if (state->font < 0 || state->font >= stash->nfonts) return 0;
1133 - font = stash->fonts[state->font];
1134 - if (!font->data) return 0;
1135 -
1136 - scale = stbtt_ScaleForPixelHeight(&font->font, (float)isize/10.0f);
1137 -
1138 - // Align vertically.
1139 - y += fons__getVertAlign(stash, font, state->align, isize);
1140 -
1141 - minx = maxx = x;
1142 - miny = maxy = y;
1143 -
1144 - if (end == nullptr)
1145 - end = str + strlen(str);
1146 -
1147 - for (; *str; ++str) {
1148 - if (fons__decutf8(&utf8state, &codepoint, *(const unsigned char*)str))
1149 - continue;
1150 - glyph = fons__getGlyph(stash, font, codepoint, isize, iblur);
1151 - if (glyph) {
1152 - fons__getQuad(stash, font, prevGlyph, glyph, state->spacing, scale, &x, &y, &q);
1153 - if (q.x0 < minx) minx = q.x0;
1154 - if (q.x1 > maxx) maxx = q.x1;
1155 - if (q.y1 < miny) miny = q.y1;
1156 - if (q.y0 > maxy) maxy = q.y0;
1157 - }
1158 - prevGlyph = glyph;
1159 - }
1160 -
1161 - // Align horizontally
1162 - if (state->align & FONS_ALIGN_LEFT) {
1163 - // empty
1164 - } else if (state->align & FONS_ALIGN_RIGHT) {
1165 - minx -= x;
1166 - maxx -= x;
1167 - } else if (state->align & FONS_ALIGN_CENTER) {
1168 - minx -= x * 0.5f;
1169 - maxx -= x * 0.5f;
1170 - }
1171 -
1172 - if (bounds) {
1173 - bounds[0] = minx;
1174 - bounds[1] = miny;
1175 - bounds[2] = maxx;
1176 - bounds[3] = maxy;
1177 - }
1119 + struct FONSstate* state = fons__getState(stash);
1120 + unsigned int codepoint;
1121 + unsigned int utf8state = 0;
1122 + struct FONSquad q;
1123 + struct FONSglyph* glyph = nullptr;
1124 + struct FONSglyph* prevGlyph = nullptr;
1125 + short isize = (short)(state->size*10.0f);
1126 + short iblur = (short)state->blur;
1127 + float scale;
1128 + struct FONSfont* font;
1129 + float x = 0, y = 0, minx, miny, maxx, maxy;
1130 +
1131 + if (stash == nullptr) return 0;
1132 + if (state->font < 0 || state->font >= stash->nfonts) return 0;
1133 + font = stash->fonts[state->font];
1134 + if (!font->data) return 0;
1135 +
1136 + scale = stbtt_ScaleForPixelHeight(&font->font, (float)isize/10.0f);
1137 +
1138 + // Align vertically.
1139 + y += fons__getVertAlign(stash, font, state->align, isize);
1140 +
1141 + minx = maxx = x;
1142 + miny = maxy = y;
1143 +
1144 + if (end == nullptr)
1145 + end = str + strlen(str);
1146 +
1147 + for (; *str; ++str) {
1148 + if (fons__decutf8(&utf8state, &codepoint, *(const unsigned char*)str))
1149 + continue;
1150 + glyph = fons__getGlyph(stash, font, codepoint, isize, iblur);
1151 + if (glyph) {
1152 + fons__getQuad(stash, font, prevGlyph, glyph, state->spacing, scale, &x, &y, &q);
1153 + if (q.x0 < minx) minx = q.x0;
1154 + if (q.x1 > maxx) maxx = q.x1;
1155 + if (q.y1 < miny) miny = q.y1;
1156 + if (q.y0 > maxy) maxy = q.y0;
1157 + }
1158 + prevGlyph = glyph;
1159 + }
1160 +
1161 + // Align horizontally
1162 + if (state->align & FONS_ALIGN_LEFT) {
1163 + // empty
1164 + } else if (state->align & FONS_ALIGN_RIGHT) {
1165 + minx -= x;
1166 + maxx -= x;
1167 + } else if (state->align & FONS_ALIGN_CENTER) {
1168 + minx -= x * 0.5f;
1169 + maxx -= x * 0.5f;
1170 + }
1171 +
1172 + if (bounds) {
1173 + bounds[0] = minx;
1174 + bounds[1] = miny;
1175 + bounds[2] = maxx;
1176 + bounds[3] = maxy;
1177 + }
1178 1178
1179 - return x;
1179 + return x;
1180 1180 }
1181 1181
1182 1182 void fonsVertMetrics(struct FONScontext* stash,
1183 - float* ascender, float* descender, float* lineh)
1183 + float* ascender, float* descender, float* lineh)
1184 1184 {
1185 - struct FONSfont* font;
1186 - struct FONSstate* state = fons__getState(stash);
1187 - short isize;
1188 -
1189 - if (stash == nullptr) return;
1190 - if (state->font < 0 || state->font >= stash->nfonts) return;
1191 - font = stash->fonts[state->font];
1192 - isize = (short)(state->size*10.0f);
1193 - if (!font->data) return;
1194 -
1195 - if (ascender)
1196 - *ascender = font->ascender*isize/10.0f;
1197 - if (descender)
1198 - *descender = font->descender*isize/10.0f;
1199 - if (lineh)
1200 - *lineh = font->lineh*isize/10.0f;
1185 + struct FONSfont* font;
1186 + struct FONSstate* state = fons__getState(stash);
1187 + short isize;
1188 +
1189 + if (stash == nullptr) return;
1190 + if (state->font < 0 || state->font >= stash->nfonts) return;
1191 + font = stash->fonts[state->font];
1192 + isize = (short)(state->size*10.0f);
1193 + if (!font->data) return;
1194 +
1195 + if (ascender)
1196 + *ascender = font->ascender*isize/10.0f;
1197 + if (descender)
1198 + *descender = font->descender*isize/10.0f;
1199 + if (lineh)
1200 + *lineh = font->lineh*isize/10.0f;
1201 1201 }
1202 1202
1203 1203 const unsigned char* fonsGetTextureData(struct FONScontext* stash, int* width, int* height)
1204 1204 {
1205 - if (width != nullptr)
1206 - *width = stash->params.width;
1207 - if (height != nullptr)
1208 - *height = stash->params.height;
1209 - return stash->texData;
1205 + if (width != nullptr)
1206 + *width = stash->params.width;
1207 + if (height != nullptr)
1208 + *height = stash->params.height;
1209 + return stash->texData;
1210 1210 }
1211 1211
1212 1212 int fonsValidateTexture(struct FONScontext* stash, int* dirty)
1213 1213 {
1214 - if (stash->dirtyRect[0] < stash->dirtyRect[2] && stash->dirtyRect[1] < stash->dirtyRect[3]) {
1215 - dirty[0] = stash->dirtyRect[0];
1216 - dirty[1] = stash->dirtyRect[1];
1217 - dirty[2] = stash->dirtyRect[2];
1218 - dirty[3] = stash->dirtyRect[3];
1219 - // Reset dirty rect
1220 - stash->dirtyRect[0] = stash->params.width;
1221 - stash->dirtyRect[1] = stash->params.height;
1222 - stash->dirtyRect[2] = 0;
1223 - stash->dirtyRect[3] = 0;
1224 - return 1;
1225 - }
1226 - return 0;
1214 + if (stash->dirtyRect[0] < stash->dirtyRect[2] && stash->dirtyRect[1] < stash->dirtyRect[3]) {
1215 + dirty[0] = stash->dirtyRect[0];
1216 + dirty[1] = stash->dirtyRect[1];
1217 + dirty[2] = stash->dirtyRect[2];
1218 + dirty[3] = stash->dirtyRect[3];
1219 + // Reset dirty rect
1220 + stash->dirtyRect[0] = stash->params.width;
1221 + stash->dirtyRect[1] = stash->params.height;
1222 + stash->dirtyRect[2] = 0;
1223 + stash->dirtyRect[3] = 0;
1224 + return 1;
1225 + }
1226 + return 0;
1227 1227 }
1228 1228
1229 1229 void fonsDeleteInternal(struct FONScontext* stash)
1230 1230 {
1231 - int i;
1232 - if (stash == nullptr) return;
1231 + int i;
1232 + if (stash == nullptr) return;
1233 1233
1234 - if (stash->params.renderDelete)
1235 - stash->params.renderDelete(stash->params.userPtr);
1234 + if (stash->params.renderDelete)
1235 + stash->params.renderDelete(stash->params.userPtr);
1236 1236
1237 - for (i = 0; i < stash->nfonts; ++i)
1238 - fons__freeFont(stash->fonts[i]);
1237 + for (i = 0; i < stash->nfonts; ++i)
1238 + fons__freeFont(stash->fonts[i]);
1239 1239
1240 - if (stash->atlas) fons__deleteAtlas(stash->atlas);
1241 - if (stash->fonts) free(stash->fonts);
1242 - if (stash->texData) free(stash->texData);
1243 - free(stash);
1240 + if (stash->atlas) fons__deleteAtlas(stash->atlas);
1241 + if (stash->fonts) free(stash->fonts);
1242 + if (stash->texData) free(stash->texData);
1243 + free(stash);
1244 1244 }
1245 1245
1246 1246 #endif