1 // stb_truetype.h - v1.26htcw (fork to enable streaming and low memory environments)
2 // stb_truetype.h - v1.26 - public domain
3 // authored from 2009-2021 by Sean Barrett / RAD Game Tools
4 //
5 // =======================================================================
6 //
7 //    NO SECURITY GUARANTEE -- DO NOT USE THIS ON UNTRUSTED FONT FILES
8 //
9 // This library does no range checking of the offsets found in the file,
10 // meaning an attacker can use it to read arbitrary memory.
11 //
12 // =======================================================================
13 //
14 //   This library processes TrueType files:
15 //        parse files
16 //        extract glyph metrics
17 //        extract glyph shapes
18 //        render glyphs to one-channel bitmaps with antialiasing (box filter)
19 //        render glyphs to one-channel SDF bitmaps (signed-distance field/function)
20 //
21 //   Todo:
22 //        non-MS cmaps
23 //        crashproof on bad data
24 //        hinting? (no longer patented)
25 //        cleartype-style AA?
26 //        optimize: use simple memory allocator for intermediates
27 //        optimize: build edge-list directly from curves
28 //        optimize: rasterize directly from curves?
29 //
30 // ADDITIONAL CONTRIBUTORS
31 //
32 //   Mikko Mononen: compound shape support, more cmap formats
33 //   Tor Andersson: kerning, subpixel rendering
34 //   Dougall Johnson: OpenType / Type 2 font handling
35 //   Daniel Ribeiro Maciel: basic GPOS-based kerning
36 //
37 //   Misc other:
38 //       Ryan Gordon
39 //       Simon Glass
40 //       github:IntellectualKitty
41 //       Imanol Celaya
42 //       Daniel Ribeiro Maciel
43 //
44 //   Bug/warning reports/fixes:
45 //       "Zer" on mollyrocket       Fabian "ryg" Giesen   github:NiLuJe
46 //       Cass Everitt               Martins Mozeiko       github:aloucks
47 //       stoiko (Haemimont Games)   Cap Petschulat        github:oyvindjam
48 //       Brian Hook                 Omar Cornut           github:vassvik
49 //       Walter van Niftrik         Ryan Griege
50 //       David Gow                  Peter LaValle
51 //       David Given                Sergey Popov
52 //       Ivan-Assen Ivanov          Giumo X. Clanjor
53 //       Anthony Pesch              Higor Euripedes
54 //       Johan Duparc               Thomas Fields
55 //       Hou Qiming                 Derek Vinyard
56 //       Rob Loach                  Cort Stratton
57 //       Kenney Phillis Jr.         Brian Costabile
58 //       Ken Voskuil (kaesve)
59 //
60 // VERSION HISTORY
61 //
62 //   1.26 (2021-08-28) fix broken rasterizer
63 //   1.25 (2021-07-11) many fixes
64 //   1.24 (2020-02-05) fix warning
65 //   1.23 (2020-02-02) query SVG data for glyphs; query whole kerning table (but only kern not GPOS)
66 //   1.22 (2019-08-11) minimize missing-glyph duplication; fix kerning if both 'GPOS' and 'kern' are defined
67 //   1.21 (2019-02-25) fix warning
68 //   1.20 (2019-02-07) PackFontRange skips missing codepoints; GetScaleFontVMetrics()
69 //   1.19 (2018-02-11) GPOS kerning, STBTT_fmod
70 //   1.18 (2018-01-29) add missing function
71 //   1.17 (2017-07-23) make more arguments const; doc fix
72 //   1.16 (2017-07-12) SDF support
73 //   1.15 (2017-03-03) make more arguments const
74 //   1.14 (2017-01-16) num-fonts-in-TTC function
75 //   1.13 (2017-01-02) support OpenType fonts, certain Apple fonts
76 //   1.12 (2016-10-25) suppress warnings about casting away const with -Wcast-qual
77 //   1.11 (2016-04-02) fix unused-variable warning
78 //   1.10 (2016-04-02) user-defined fabs(); rare memory leak; remove duplicate typedef
79 //   1.09 (2016-01-16) warning fix; avoid crash on outofmem; use allocation userdata properly
80 //   1.08 (2015-09-13) document stbtt_Rasterize(); fixes for vertical & horizontal edges
81 //   1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints;
82 //                     variant PackFontRanges to pack and render in separate phases;
83 //                     fix stbtt_GetFontOFfsetForIndex (never worked for non-0 input?);
84 //                     fixed an assert() bug in the new rasterizer
85 //                     replace assert() with STBTT_assert() in new rasterizer
86 //
87 //   Full history can be found at the end of this file.
88 //
89 // LICENSE
90 //
91 //   See end of file for license information.
92 //
93 // USAGE
94 //
95 //   Include this file in whatever places need to refer to it. In ONE C/C++
96 //   file, write:
97 //      #define STB_TRUETYPE_IMPLEMENTATION
98 //   before the #include of this file. This expands out the actual
99 //   implementation into that C/C++ file.
100 //
101 //   To make the implementation private to the file that generates the implementation,
102 //      #define STBTT_STATIC
103 //
104 //   Simple 3D API (don't ship this, but it's fine for tools and quick start)
105 //           stbtt_BakeFontBitmap()               -- bake a font to a bitmap for use as texture
106 //           stbtt_GetBakedQuad()                 -- compute quad to draw for a given char
107 //
108 //   Improved 3D API (more shippable):
109 //           #include "stb_rect_pack.h"           -- optional, but you really want it
110 //           stbtt_PackBegin()
111 //           stbtt_PackSetOversampling()          -- for improved quality on small fonts
112 //           stbtt_PackFontRanges()               -- pack and renders
113 //           stbtt_PackEnd()
114 //           stbtt_GetPackedQuad()
115 //
116 //   "Load" a font file from a memory buffer (you have to keep the buffer loaded)
117 //           stbtt_InitFont()
118 //           stbtt_GetFontOffsetForIndex()        -- indexing for TTC font collections
119 //           stbtt_GetNumberOfFonts()             -- number of fonts for TTC font collections
120 //
121 //   Render a unicode codepoint to a bitmap
122 //           stbtt_GetCodepointBitmap()           -- allocates and returns a bitmap
123 //           stbtt_MakeCodepointBitmap()          -- renders into bitmap you provide
124 //           stbtt_GetCodepointBitmapBox()        -- how big the bitmap must be
125 //
126 //   Character advance/positioning
127 //           stbtt_GetCodepointHMetrics()
128 //           stbtt_GetFontVMetrics()
129 //           stbtt_GetFontVMetricsOS2()
130 //           stbtt_GetCodepointKernAdvance()
131 //
132 //   Starting with version 1.06, the rasterizer was replaced with a new,
133 //   faster and generally-more-precise rasterizer. The new rasterizer more
134 //   accurately measures pixel coverage for anti-aliasing, except in the case
135 //   where multiple shapes overlap, in which case it overestimates the AA pixel
136 //   coverage. Thus, anti-aliasing of intersecting shapes may look wrong. If
137 //   this turns out to be a problem, you can re-enable the old rasterizer with
138 //        #define STBTT_RASTERIZER_VERSION 1
139 //   which will incur about a 15% speed hit.
140 //
141 // ADDITIONAL DOCUMENTATION
142 //
143 //   Immediately after this block comment are a series of sample programs.
144 //
145 //   After the sample programs is the "header file" section. This section
146 //   includes documentation for each API function.
147 //
148 //   Some important concepts to understand to use this library:
149 //
150 //      Codepoint
151 //         Characters are defined by unicode codepoints, e.g. 65 is
152 //         uppercase A, 231 is lowercase c with a cedilla, 0x7e30 is
153 //         the hiragana for "ma".
154 //
155 //      Glyph
156 //         A visual character shape (every codepoint is rendered as
157 //         some glyph)
158 //
159 //      Glyph index
160 //         A font-specific integer ID representing a glyph
161 //
162 //      Baseline
163 //         Glyph shapes are defined relative to a baseline, which is the
164 //         bottom of uppercase characters. Characters extend both above
165 //         and below the baseline.
166 //
167 //      Current Point
168 //         As you draw text to the screen, you keep track of a "current point"
169 //         which is the origin of each character. The current point's vertical
170 //         position is the baseline. Even "baked fonts" use this model.
171 //
172 //      Vertical Font Metrics
173 //         The vertical qualities of the font, used to vertically position
174 //         and space the characters. See docs for stbtt_GetFontVMetrics.
175 //
176 //      Font Size in Pixels or Points
177 //         The preferred interface for specifying font sizes in stb_truetype
178 //         is to specify how tall the font's vertical extent should be in pixels.
179 //         If that sounds good enough, skip the next paragraph.
180 //
181 //         Most font APIs instead use "points", which are a common typographic
182 //         measurement for describing font size, defined as 72 points per inch.
183 //         stb_truetype provides a point API for compatibility. However, true
184 //         "per inch" conventions don't make much sense on computer displays
185 //         since different monitors have different number of pixels per
186 //         inch. For example, Windows traditionally uses a convention that
187 //         there are 96 pixels per inch, thus making 'inch' measurements have
188 //         nothing to do with inches, and thus effectively defining a point to
189 //         be 1.333 pixels. Additionally, the TrueType font data provides
190 //         an explicit scale factor to scale a given font's glyphs to points,
191 //         but the author has observed that this scale factor is often wrong
192 //         for non-commercial fonts, thus making fonts scaled in points
193 //         according to the TrueType spec incoherently sized in practice.
194 //
195 // DETAILED USAGE:
196 //
197 //  Scale:
198 //    Select how high you want the font to be, in points or pixels.
199 //    Call ScaleForPixelHeight or ScaleForMappingEmToPixels to compute
200 //    a scale factor SF that will be used by all other functions.
201 //
202 //  Baseline:
203 //    You need to select a y-coordinate that is the baseline of where
204 //    your text will appear. Call GetFontBoundingBox to get the baseline-relative
205 //    bounding box for all characters. SF*-y0 will be the distance in pixels
206 //    that the worst-case character could extend above the baseline, so if
207 //    you want the top edge of characters to appear at the top of the
208 //    screen where y=0, then you would set the baseline to SF*-y0.
209 //
210 //  Current point:
211 //    Set the current point where the first character will appear. The
212 //    first character could extend left of the current point; this is font
213 //    dependent. You can either choose a current point that is the leftmost
214 //    point and hope, or add some padding, or check the bounding box or
215 //    left-side-bearing of the first character to be displayed and set
216 //    the current point based on that.
217 //
218 //  Displaying a character:
219 //    Compute the bounding box of the character. It will contain signed values
220 //    relative to <current_point, baseline>. I.e. if it returns x0,y0,x1,y1,
221 //    then the character should be displayed in the rectangle from
222 //    <current_point+SF*x0, baseline+SF*y0> to <current_point+SF*x1,baseline+SF*y1).
223 //
224 //  Advancing for the next character:
225 //    Call GlyphHMetrics, and compute 'current_point += SF * advance'.
226 //
227 //
228 // ADVANCED USAGE
229 //
230 //   Quality:
231 //
232 //    - Use the functions with Subpixel at the end to allow your characters
233 //      to have subpixel positioning. Since the font is anti-aliased, not
234 //      hinted, this is very import for quality. (This is not possible with
235 //      baked fonts.)
236 //
237 //    - Kerning is now supported, and if you're supporting subpixel rendering
238 //      then kerning is worth using to give your text a polished look.
239 //
240 //   Performance:
241 //
242 //    - Convert Unicode codepoints to glyph indexes and operate on the glyphs;
243 //      if you don't do this, stb_truetype is forced to do the conversion on
244 //      every call.
245 //
246 //    - There are a lot of memory allocations. We should modify it to take
247 //      a temp buffer and allocate from the temp buffer (without freeing),
248 //      should help performance a lot.
249 //
250 // NOTES
251 //
252 //   The system uses the raw data found in the .ttf file without changing it
253 //   and without building auxiliary data structures. This is a bit inefficient
254 //   on little-endian systems (the data is big-endian), but assuming you're
255 //   caching the bitmaps or glyph shapes this shouldn't be a big deal.
256 //
257 //   It appears to be very hard to programmatically determine what font a
258 //   given file is in a general way. I provide an API for this, but I don't
259 //   recommend it.
260 //
261 //
262 // PERFORMANCE MEASUREMENTS FOR 1.06:
263 //
264 //                      32-bit     64-bit
265 //   Previous release:  8.83 s     7.68 s
266 //   Pool allocations:  7.72 s     6.34 s
267 //   Inline sort     :  6.54 s     5.65 s
268 //   New rasterizer  :  5.63 s     5.00 s
269 
270 //////////////////////////////////////////////////////////////////////////////
271 //////////////////////////////////////////////////////////////////////////////
272 ////
273 ////  SAMPLE PROGRAMS
274 ////
275 //
276 //  Incomplete text-in-3d-api example, which draws quads properly aligned to be lossless.
277 //  See "tests/truetype_demo_win32.c" for a complete version.
278 #if 0
279 #define STB_TRUETYPE_IMPLEMENTATION  // force following include to generate implementation
280 #include "stb_truetype.h"
281 
282 unsigned char ttf_buffer[1 << 20];
283 unsigned char temp_bitmap[512 * 512];
284 
285 stbtt_bakedchar cdata[96]; // ASCII 32..126 is 95 glyphs
286 GLuint ftex;
287 
288 void my_stbtt_initfont(void)
289 {
290     fread(ttf_buffer, 1, 1 << 20, fopen("c:/windows/fonts/times.ttf", "rb"));
291     stbtt_BakeFontBitmap(ttf_buffer, 0, 32.0, temp_bitmap, 512, 512, 32, 96, cdata); // no guarantee this fits!
292     // can free ttf_buffer at this point
293     glGenTextures(1, &ftex);
294     glBindTexture(GL_TEXTURE_2D, ftex);
295     glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 512, 512, 0, GL_ALPHA, GL_UNSIGNED_BYTE, temp_bitmap);
296     // can free temp_bitmap at this point
297     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
298 }
299 
300 void my_stbtt_print(float x, float y, char * text)
301 {
302     // assume orthographic projection with units = screen pixels, origin at top left
303     glEnable(GL_BLEND);
304     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
305     glEnable(GL_TEXTURE_2D);
306     glBindTexture(GL_TEXTURE_2D, ftex);
307     glBegin(GL_QUADS);
308     while(*text) {
309         if(*text >= 32 && *text < 128) {
310             stbtt_aligned_quad q;
311             stbtt_GetBakedQuad(cdata, 512, 512, *text - 32, &x, &y, &q, 1);//1=opengl & d3d10+,0=d3d9
312             glTexCoord2f(q.s0, q.t0);
313             glVertex2f(q.x0, q.y0);
314             glTexCoord2f(q.s1, q.t0);
315             glVertex2f(q.x1, q.y0);
316             glTexCoord2f(q.s1, q.t1);
317             glVertex2f(q.x1, q.y1);
318             glTexCoord2f(q.s0, q.t1);
319             glVertex2f(q.x0, q.y1);
320         }
321         ++text;
322     }
323     glEnd();
324 }
325 #endif
326 //
327 //
328 //////////////////////////////////////////////////////////////////////////////
329 //
330 // Complete program (this compiles): get a single bitmap, print as ASCII art
331 //
332 #if 0
333 #include <stdio.h>
334 #define STB_TRUETYPE_IMPLEMENTATION  // force following include to generate implementation
335 #include "stb_truetype.h"
336 
337 char ttf_buffer[1 << 25];
338 
339 int main(int argc, char ** argv)
340 {
341     stbtt_fontinfo font;
342     unsigned char * bitmap;
343     int w, h, i, j, c = (argc > 1 ? atoi(argv[1]) : 'a'), s = (argc > 2 ? atoi(argv[2]) : 20);
344 
345     fread(ttf_buffer, 1, 1 << 25, fopen(argc > 3 ? argv[3] : "c:/windows/fonts/arialbd.ttf", "rb"));
346 
347     stbtt_InitFont(&font, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer, 0));
348     bitmap = stbtt_GetCodepointBitmap(&font, 0, stbtt_ScaleForPixelHeight(&font, s), c, &w, &h, 0, 0);
349 
350     for(j = 0; j < h; ++j) {
351         for(i = 0; i < w; ++i)
352             putchar(" .:ioVM@"[bitmap[j * w + i] >> 5]);
353         putchar('\n');
354     }
355     return 0;
356 }
357 #endif
358 //
359 // Output:
360 //
361 //     .ii.
362 //    @@@@@@.
363 //   V@Mio@@o
364 //   :i.  V@V
365 //     :oM@@M
366 //   :@@@MM@M
367 //   @@o  o@M
368 //  :@@.  M@M
369 //   @@@o@@@@
370 //   :M@@V:@@.
371 //
372 //////////////////////////////////////////////////////////////////////////////
373 //
374 // Complete program: print "Hello World!" banner, with bugs
375 //
376 #if 0
377 char buffer[24 << 20];
378 unsigned char screen[20][79];
379 
380 int main(int arg, char ** argv)
381 {
382     stbtt_fontinfo font;
383     int i, j, ascent, baseline, ch = 0;
384     float scale, xpos = 2; // leave a little padding in case the character extends left
385     char * text = "Heljo World!"; // intentionally misspelled to show 'lj' brokenness
386 
387     fread(buffer, 1, 1000000, fopen("c:/windows/fonts/arialbd.ttf", "rb"));
388     stbtt_InitFont(&font, buffer, 0);
389 
390     scale = stbtt_ScaleForPixelHeight(&font, 15);
391     stbtt_GetFontVMetrics(&font, &ascent, 0, 0);
392     baseline = (int)(ascent * scale);
393 
394     while(text[ch]) {
395         int advance, lsb, x0, y0, x1, y1;
396         float x_shift = xpos - (float)floor(xpos);
397         stbtt_GetCodepointHMetrics(&font, text[ch], &advance, &lsb);
398         stbtt_GetCodepointBitmapBoxSubpixel(&font, text[ch], scale, scale, x_shift, 0, &x0, &y0, &x1, &y1);
399         stbtt_MakeCodepointBitmapSubpixel(&font, &screen[baseline + y0][(int)xpos + x0], x1 - x0, y1 - y0, 79, scale, scale,
400                                           x_shift, 0, text[ch]);
401         // note that this stomps the old data, so where character boxes overlap (e.g. 'lj') it's wrong
402         // because this API is really for baking character bitmaps into textures. if you want to render
403         // a sequence of characters, you really need to render each bitmap to a temp buffer, then
404         // "alpha blend" that into the working buffer
405         xpos += (advance * scale);
406         if(text[ch + 1])
407             xpos += scale * stbtt_GetCodepointKernAdvance(&font, text[ch], text[ch + 1]);
408         ++ch;
409     }
410 
411     for(j = 0; j < 20; ++j) {
412         for(i = 0; i < 78; ++i)
413             putchar(" .:ioVM@"[screen[j][i] >> 5]);
414         putchar('\n');
415     }
416 
417     return 0;
418 }
419 #endif
420 
421 //////////////////////////////////////////////////////////////////////////////
422 //////////////////////////////////////////////////////////////////////////////
423 ////
424 ////   INTEGRATION WITH YOUR CODEBASE
425 ////
426 ////   The following sections allow you to supply alternate definitions
427 ////   of C library functions used by stb_truetype, e.g. if you don't
428 ////   link with the C runtime library.
429 
430 #ifdef STB_TRUETYPE_IMPLEMENTATION
431 // #define your own (u)stbtt_int8/16/32 before including to override this
432 #ifndef stbtt_uint8
433     typedef unsigned char   stbtt_uint8;
434     typedef signed   char   stbtt_int8;
435     typedef unsigned short  stbtt_uint16;
436     typedef signed   short  stbtt_int16;
437     typedef unsigned int    stbtt_uint32;
438     typedef signed   int    stbtt_int32;
439 #endif
440 
441 typedef char stbtt__check_size32[sizeof(stbtt_int32) == 4 ? 1 : -1];
442 typedef char stbtt__check_size16[sizeof(stbtt_int16) == 2 ? 1 : -1];
443 
444 // define STBTT_STDIO_STREAM to stream from a FILE object
445 // instead of from memory. Or define STBTT_STREAM_TYPE,
446 // STBTT_STREAM_READ and STBTT_STREAM_SEEK to implement
447 // another streaming source
448 #ifdef STBTT_STDIO_STREAM
449     #include <stdio.h>
450     #define STBTT_STREAM_TYPE FILE*
451     #define STBTT_STREAM_READ(s,x,y) fread(x,1,y,s);
452     #define STBTT_STREAM_SEEK(s,x)  fseek(s,x,SEEK_SET);
453 #endif
454 
455 // heap factor sizes for various counts of objects
456 // adjust for your platform. Below is suitable for
457 // modern PC class machines.
458 #ifndef STBTT_HEAP_FACTOR_SIZE_32
459     #define STBTT_HEAP_FACTOR_SIZE_32 2000
460 #endif
461 
462 #ifndef STBTT_HEAP_FACTOR_SIZE_128
463     #define STBTT_HEAP_FACTOR_SIZE_128 800
464 #endif
465 
466 #ifndef STBTT_HEAP_FACTOR_SIZE_DEFAULT
467     #define STBTT_HEAP_FACTOR_SIZE_DEFAULT 100
468 #endif
469 
470 // e.g. #define your own STBTT_ifloor/STBTT_iceil() to avoid math.h
471 #ifndef STBTT_ifloor
472     #include <math.h>
473     #define STBTT_ifloor(x)   ((int) floor(x))
474     #define STBTT_iceil(x)    ((int) ceil(x))
475 #endif
476 
477 #ifndef STBTT_sqrt
478     #include <math.h>
479     #define STBTT_sqrt(x)      (float)sqrt(x)
480     #define STBTT_pow(x,y)     pow(x,y)
481 #endif
482 
483 #ifndef STBTT_fmod
484     #include <math.h>
485     #define STBTT_fmod(x,y)    fmod(x,y)
486 #endif
487 
488 #ifndef STBTT_cos
489     #include <math.h>
490     #define STBTT_cos(x)       cos(x)
491     #define STBTT_acos(x)      acos(x)
492 #endif
493 
494 #ifndef STBTT_fabs
495     #include <math.h>
496     #define STBTT_fabs(x)      (float)fabs(x)
497 #endif
498 
499 // #define your own functions "STBTT_malloc" / "STBTT_free" to avoid malloc.h
500 #ifndef STBTT_malloc
501     #include <stdlib.h>
502     #define STBTT_malloc(x,u)  ((void)(u),malloc(x))
503     #define STBTT_free(x,u)    ((void)(u),free(x))
504 #endif
505 
506 #ifndef STBTT_assert
507     #include <assert.h>
508     #define STBTT_assert(x)    assert(x)
509 #endif
510 
511 #ifndef STBTT_strlen
512     #include <string.h>
513     #define STBTT_strlen(x)    strlen(x)
514 #endif
515 
516 #ifndef STBTT_memcpy
517     #include <string.h>
518     #define STBTT_memcpy       memcpy
519     #define STBTT_memset       memset
520 #endif
521 #endif
522 
523 ///////////////////////////////////////////////////////////////////////////////
524 ///////////////////////////////////////////////////////////////////////////////
525 ////
526 ////   INTERFACE
527 ////
528 ////
529 
530 #ifndef __STB_INCLUDE_STB_TRUETYPE_H__
531 #define __STB_INCLUDE_STB_TRUETYPE_H__
532 
533 #ifdef STBTT_STATIC
534     #define STBTT_DEF static
535 #else
536     #define STBTT_DEF extern
537 #endif
538 
539 #ifdef __cplusplus
540 extern "C" {
541 #endif
542 
543 // private structure
544 typedef struct {
545 #ifdef STBTT_STREAM_TYPE
546     STBTT_STREAM_TYPE data;
547     stbtt_uint32 offset;
548 #else
549     unsigned char * data;
550 #endif
551     int cursor;
552     int size;
553 } stbtt__buf;
554 
555 #if defined(__GNUC__) || defined(__clang__)
556 #pragma GCC diagnostic push
557 #pragma GCC diagnostic ignored "-Wunused-function"
558 #endif
559 
560 //////////////////////////////////////////////////////////////////////////////
561 //
562 // TEXTURE BAKING API
563 //
564 // If you use this API, you only have to call two functions ever.
565 //
566 
567 typedef struct {
568     unsigned short x0, y0, x1, y1; // coordinates of bbox in bitmap
569     float xoff, yoff, xadvance;
570 } stbtt_bakedchar;
571 
572 typedef struct {
573     float x0, y0, s0, t0; // top-left
574     float x1, y1, s1, t1; // bottom-right
575 } stbtt_aligned_quad;
576 
577 STBTT_DEF void stbtt_GetBakedQuad(const stbtt_bakedchar * chardata, int pw, int ph, // same data as above
578                                   int char_index,             // character to display
579                                   float * xpos, float * ypos, // pointers to current position in screen pixel space
580                                   stbtt_aligned_quad * q,     // output: quad to draw
581                                   int opengl_fillrule);       // true if opengl fill rule; false if DX9 or earlier
582 // Call GetBakedQuad with char_index = 'character - first_char', and it
583 // creates the quad you need to draw and advances the current position.
584 //
585 // The coordinate system used assumes y increases downwards.
586 //
587 // Characters will extend both above and below the current position;
588 // see discussion of "BASELINE" above.
589 //
590 // It's inefficient; you might want to c&p it and optimize it.
591 
592 //////////////////////////////////////////////////////////////////////////////
593 //
594 // NEW TEXTURE BAKING API
595 //
596 // This provides options for packing multiple fonts into one atlas, not
597 // perfectly but better than nothing.
598 
599 typedef struct {
600     unsigned short x0, y0, x1, y1; // coordinates of bbox in bitmap
601     float xoff, yoff, xadvance;
602     float xoff2, yoff2;
603 } stbtt_packedchar;
604 
605 /// @cond
606 /**
607  *  Tells Doxygen to ignore a duplicate declaration
608  */
609 typedef struct stbtt_pack_context stbtt_pack_context;
610 typedef struct stbtt_fontinfo stbtt_fontinfo;
611 /// @endcond
612 
613 #ifndef STB_RECT_PACK_VERSION
614 /// @cond
615 /**
616  *  Tells Doxygen to ignore a duplicate declaration
617  */
618 typedef struct stbrp_rect stbrp_rect;
619 /// @endcond
620 
621 #endif
622 STBTT_DEF int  stbtt_PackBegin(stbtt_pack_context * spc, unsigned char * pixels, int width, int height,
623                                int stride_in_bytes, int padding, void * alloc_context);
624 
625 // Initializes a packing context stored in the passed-in stbtt_pack_context.
626 // Future calls using this context will pack characters into the bitmap passed
627 // in here: a 1-channel bitmap that is width * height. stride_in_bytes is
628 // the distance from one row to the next (or 0 to mean they are packed tightly
629 // together). "padding" is the amount of padding to leave between each
630 // character (normally you want '1' for bitmaps you'll use as textures with
631 // bilinear filtering).
632 //
633 // Returns 0 on failure, 1 on success.
634 
635 STBTT_DEF void stbtt_PackEnd(stbtt_pack_context * spc);
636 // Cleans up the packing context and frees all memory.
637 
638 #define STBTT_POINT_SIZE(x)   (-(x))
639 
640 typedef struct {
641     float font_size;
642     int first_unicode_codepoint_in_range;  // if non-zero, then the chars are continuous, and this is the first codepoint
643     int * array_of_unicode_codepoints;      // if non-zero, then this is an array of unicode codepoints
644     int num_chars;
645     stbtt_packedchar * chardata_for_range; // output
646     unsigned char h_oversample, v_oversample; // don't set these, they're used internally
647 } stbtt_pack_range;
648 
649 STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context * spc, unsigned int h_oversample,
650                                          unsigned int v_oversample);
651 // Oversampling a font increases the quality by allowing higher-quality subpixel
652 // positioning, and is especially valuable at smaller text sizes.
653 //
654 // This function sets the amount of oversampling for all following calls to
655 // stbtt_PackFontRange(s) or stbtt_PackFontRangesGatherRects for a given
656 // pack context. The default (no oversampling) is achieved by h_oversample=1
657 // and v_oversample=1. The total number of pixels required is
658 // h_oversample*v_oversample larger than the default; for example, 2x2
659 // oversampling requires 4x the storage of 1x1. For best results, render
660 // oversampled textures with bilinear filtering. Look at the readme in
661 // stb/tests/oversample for information about oversampled fonts
662 //
663 // To use with PackFontRangesGather etc., you must set it before calls
664 // call to PackFontRangesGatherRects.
665 
666 STBTT_DEF void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context * spc, int skip);
667 // If skip != 0, this tells stb_truetype to skip any codepoints for which
668 // there is no corresponding glyph. If skip=0, which is the default, then
669 // codepoints without a glyph received the font's "missing character" glyph,
670 // typically an empty box by convention.
671 
672 STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar * chardata, int pw, int ph, // same data as above
673                                    int char_index,             // character to display
674                                    float * xpos, float * ypos, // pointers to current position in screen pixel space
675                                    stbtt_aligned_quad * q,     // output: quad to draw
676                                    int align_to_integer);
677 
678 STBTT_DEF int  stbtt_PackFontRangesGatherRects(stbtt_pack_context * spc, const stbtt_fontinfo * info,
679                                                stbtt_pack_range * ranges, int num_ranges, stbrp_rect * rects);
680 STBTT_DEF void stbtt_PackFontRangesPackRects(stbtt_pack_context * spc, stbrp_rect * rects, int num_rects);
681 STBTT_DEF int  stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context * spc, const stbtt_fontinfo * info,
682                                                    stbtt_pack_range * ranges, int num_ranges, stbrp_rect * rects);
683 // Calling these functions in sequence is roughly equivalent to calling
684 // stbtt_PackFontRanges(). If you more control over the packing of multiple
685 // fonts, or if you want to pack custom data into a font texture, take a look
686 // at the source to of stbtt_PackFontRanges() and create a custom version
687 // using these functions, e.g. call GatherRects multiple times,
688 // building up a single array of rects, then call PackRects once,
689 // then call RenderIntoRects repeatedly. This may result in a
690 // better packing than calling PackFontRanges multiple times
691 // (or it may not).
692 
693 // this is an opaque structure that you shouldn't mess with which holds
694 // all the context needed from PackBegin to PackEnd.
695 struct stbtt_pack_context {
696     void * user_allocator_context;
697     void * pack_info;
698     int   width;
699     int   height;
700     int   stride_in_bytes;
701     int   padding;
702     int   skip_missing;
703     unsigned int   h_oversample, v_oversample;
704     unsigned char * pixels;
705     void * nodes;
706 };
707 
708 //////////////////////////////////////////////////////////////////////////////
709 //
710 // FONT LOADING
711 //
712 //
713 #ifdef STBTT_STREAM_TYPE
714 STBTT_DEF int stbtt_GetNumberOfFonts(STBTT_STREAM_TYPE data);
715 #else
716 STBTT_DEF int stbtt_GetNumberOfFonts(const unsigned char * data);
717 #endif
718 // This function will determine the number of fonts in a font file.  TrueType
719 // collection (.ttc) files may contain multiple fonts, while TrueType font
720 // (.ttf) files only contain one font. The number of fonts can be used for
721 // indexing with the previous function where the index is between zero and one
722 // less than the total fonts. If an error occurs, -1 is returned.
723 #ifdef STBTT_STREAM_TYPE
724 STBTT_DEF int stbtt_GetFontOffsetForIndex(STBTT_STREAM_TYPE, int index);
725 #else
726 STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char * data, int index);
727 #endif
728 
729 // Each .ttf/.ttc file may have more than one font. Each font has a sequential
730 // index number starting from 0. Call this function to get the font offset for
731 // a given index; it returns -1 if the index is out of range. A regular .ttf
732 // file will only define one font and it always be at offset 0, so it will
733 // return '0' for index 0, and -1 for all other indices.
734 
735 // The following structure is defined publicly so you can declare one on
736 // the stack or as a global or etc, but you should treat it as opaque.
737 struct stbtt_fontinfo {
738     void * userdata;
739 #ifdef STBTT_STREAM_TYPE
740     STBTT_STREAM_TYPE data;
741 #else
742     unsigned char * data;             // pointer to .ttf file
743 #endif
744     int              fontstart;         // offset of start of font
745 
746     int numGlyphs;                     // number of glyphs, needed for range checking
747 
748     int loca, head, glyf, hhea, hmtx, kern, gpos, svg; // table locations as offset from start of .ttf
749     int index_map;                     // a cmap mapping for our chosen character encoding
750     int indexToLocFormat;              // format needed to map from glyph index to glyph
751 
752     stbtt__buf cff;                    // cff font data
753     stbtt__buf charstrings;            // the charstring index
754     stbtt__buf gsubrs;                 // global charstring subroutines index
755     stbtt__buf subrs;                  // private charstring subroutines index
756     stbtt__buf fontdicts;              // array of font dicts
757     stbtt__buf fdselect;               // map from glyph to fontdict
758 };
759 #ifdef STBTT_STREAM_TYPE
760 STBTT_DEF int stbtt_InitFont(stbtt_fontinfo * info, STBTT_STREAM_TYPE data, int offset);
761 #else
762 STBTT_DEF int stbtt_InitFont(stbtt_fontinfo * info, const unsigned char * data, int offset);
763 #endif
764 // Given an offset into the file that defines a font, this function builds
765 // the necessary cached info for the rest of the system. You must allocate
766 // the stbtt_fontinfo yourself, and stbtt_InitFont will fill it out. You don't
767 // need to do anything special to free it, because the contents are pure
768 // value data with no additional data structures. Returns 0 on failure.
769 
770 //////////////////////////////////////////////////////////////////////////////
771 //
772 // CHARACTER TO GLYPH-INDEX CONVERSIOn
773 
774 STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo * info, int unicode_codepoint);
775 // If you're going to perform multiple operations on the same character
776 // and you want a speed-up, call this function with the character you're
777 // going to process, then use glyph-based functions instead of the
778 // codepoint-based functions.
779 // Returns 0 if the character codepoint is not defined in the font.
780 
781 //////////////////////////////////////////////////////////////////////////////
782 //
783 // CHARACTER PROPERTIES
784 //
785 
786 STBTT_DEF float stbtt_ScaleForPixelHeight(const stbtt_fontinfo * info, float pixels);
787 // computes a scale factor to produce a font whose "height" is 'pixels' tall.
788 // Height is measured as the distance from the highest ascender to the lowest
789 // descender; in other words, it's equivalent to calling stbtt_GetFontVMetrics
790 // and computing:
791 //       scale = pixels / (ascent - descent)
792 // so if you prefer to measure height by the ascent only, use a similar calculation.
793 
794 STBTT_DEF float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo * info, float pixels);
795 // computes a scale factor to produce a font whose EM size is mapped to
796 // 'pixels' tall. This is probably what traditional APIs compute, but
797 // I'm not positive.
798 
799 STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo * info, int * ascent, int * descent, int * lineGap);
800 // ascent is the coordinate above the baseline the font extends; descent
801 // is the coordinate below the baseline the font extends (i.e. it is typically negative)
802 // lineGap is the spacing between one row's descent and the next row's ascent...
803 // so you should advance the vertical position by "*ascent - *descent + *lineGap"
804 //   these are expressed in unscaled coordinates, so you must multiply by
805 //   the scale factor for a given size
806 
807 STBTT_DEF int  stbtt_GetFontVMetricsOS2(const stbtt_fontinfo * info, int * typoAscent, int * typoDescent,
808                                         int * typoLineGap);
809 // analogous to GetFontVMetrics, but returns the "typographic" values from the OS/2
810 // table (specific to MS/Windows TTF files).
811 //
812 // Returns 1 on success (table present), 0 on failure.
813 
814 STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo * info, int * x0, int * y0, int * x1, int * y1);
815 // the bounding box around all possible characters
816 
817 STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo * info, int codepoint, int * advanceWidth,
818                                           int * leftSideBearing);
819 // leftSideBearing is the offset from the current horizontal position to the left edge of the character
820 // advanceWidth is the offset from the current horizontal position to the next horizontal position
821 //   these are expressed in unscaled coordinates
822 
823 STBTT_DEF int  stbtt_GetCodepointKernAdvance(const stbtt_fontinfo * info, int ch1, int ch2);
824 // an additional amount to add to the 'advance' value between ch1 and ch2
825 
826 STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo * info, int codepoint, int * x0, int * y0, int * x1, int * y1);
827 // Gets the bounding box of the visible part of the glyph, in unscaled coordinates
828 
829 STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo * info, int glyph_index, int * advanceWidth,
830                                       int * leftSideBearing);
831 STBTT_DEF int  stbtt_GetGlyphKernAdvance(const stbtt_fontinfo * info, int glyph1, int glyph2);
832 STBTT_DEF int  stbtt_GetGlyphBox(const stbtt_fontinfo * info, int glyph_index, int * x0, int * y0, int * x1, int * y1);
833 // as above, but takes one or more glyph indices for greater efficiency
834 
835 typedef struct _stbtt_kerningentry {
836     int glyph1; // use stbtt_FindGlyphIndex
837     int glyph2;
838     int advance;
839 } stbtt_kerningentry;
840 
841 STBTT_DEF int  stbtt_GetKerningTableLength(const stbtt_fontinfo * info);
842 STBTT_DEF int  stbtt_GetKerningTable(const stbtt_fontinfo * info, stbtt_kerningentry * table, int table_length);
843 // Retrieves a complete list of all of the kerning pairs provided by the font
844 // stbtt_GetKerningTable never writes more than table_length entries and returns how many entries it did write.
845 // The table will be sorted by (a.glyph1 == b.glyph1)?(a.glyph2 < b.glyph2):(a.glyph1 < b.glyph1)
846 
847 //////////////////////////////////////////////////////////////////////////////
848 //
849 // GLYPH SHAPES (you probably don't need these, but they have to go before
850 // the bitmaps for C declaration-order reasons)
851 //
852 
853 #ifndef STBTT_vmove // you can predefine these to use different values (but why?)
854 enum {
855     STBTT_vmove = 1,
856     STBTT_vline,
857     STBTT_vcurve,
858     STBTT_vcubic
859 };
860 #endif
861 
862 #ifndef stbtt_vertex // you can predefine this to use different values
863 // (we share this with other code at RAD)
864 #define stbtt_vertex_type short // can't use stbtt_int16 because that's not visible in the header file
865 typedef struct {
866     stbtt_vertex_type x, y, cx, cy, cx1, cy1;
867     unsigned char type, padding;
868 } stbtt_vertex;
869 #endif
870 
871 STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo * info, int glyph_index);
872 // returns non-zero if nothing is drawn for this glyph
873 
874 STBTT_DEF int stbtt_GetCodepointShape(const stbtt_fontinfo * info, int unicode_codepoint, stbtt_vertex ** vertices);
875 STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo * info, int glyph_index, stbtt_vertex ** vertices);
876 // returns # of vertices and fills *vertices with the pointer to them
877 //   these are expressed in "unscaled" coordinates
878 //
879 // The shape is a series of contours. Each one starts with
880 // a STBTT_moveto, then consists of a series of mixed
881 // STBTT_lineto and STBTT_curveto segments. A lineto
882 // draws a line from previous endpoint to its x,y; a curveto
883 // draws a quadratic bezier from previous endpoint to
884 // its x,y, using cx,cy as the bezier control point.
885 
886 STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo * info, stbtt_vertex * vertices);
887 // frees the data allocated above
888 
889 STBTT_DEF stbtt_uint32 stbtt_FindSVGDoc(const stbtt_fontinfo * info, int gl);
890 STBTT_DEF int stbtt_GetCodepointSVG(const stbtt_fontinfo * info, int unicode_codepoint, stbtt_uint32 * svgOfs);
891 STBTT_DEF int stbtt_GetGlyphSVG(const stbtt_fontinfo * info, int gl, stbtt_uint32 * svgOfs);
892 // fills svg with the character's SVG data.
893 // returns data size or 0 if SVG not found.
894 
895 //////////////////////////////////////////////////////////////////////////////
896 //
897 // BITMAP RENDERING
898 //
899 
900 STBTT_DEF void stbtt_FreeBitmap(unsigned char * bitmap, void * userdata);
901 // frees the bitmap allocated below
902 
903 STBTT_DEF unsigned char * stbtt_GetCodepointBitmap(const stbtt_fontinfo * info, float scale_x, float scale_y,
904                                                    int codepoint, int * width, int * height, int * xoff, int * yoff);
905 // allocates a large-enough single-channel 8bpp bitmap and renders the
906 // specified character/glyph at the specified scale into it, with
907 // antialiasing. 0 is no coverage (transparent), 255 is fully covered (opaque).
908 // *width & *height are filled out with the width & height of the bitmap,
909 // which is stored left-to-right, top-to-bottom.
910 //
911 // xoff/yoff are the offset it pixel space from the glyph origin to the top-left of the bitmap
912 
913 STBTT_DEF unsigned char * stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo * info, float scale_x, float scale_y,
914                                                            float shift_x, float shift_y, int codepoint, int * width, int * height, int * xoff, int * yoff);
915 // the same as stbtt_GetCodepoitnBitmap, but you can specify a subpixel
916 // shift for the character
917 
918 STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo * info, unsigned char * output, int out_w, int out_h,
919                                          int out_stride, float scale_x, float scale_y, int codepoint);
920 // the same as stbtt_GetCodepointBitmap, but you pass in storage for the bitmap
921 // in the form of 'output', with row spacing of 'out_stride' bytes. the bitmap
922 // is clipped to out_w/out_h bytes. Call stbtt_GetCodepointBitmapBox to get the
923 // width and height and positioning info for it first.
924 
925 STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo * info, unsigned char * output, int out_w,
926                                                  int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint);
927 // same as stbtt_MakeCodepointBitmap, but you can specify a subpixel
928 // shift for the character
929 
930 STBTT_DEF void stbtt_MakeCodepointBitmapSubpixelPrefilter(const stbtt_fontinfo * info, unsigned char * output,
931                                                           int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int oversample_x,
932                                                           int oversample_y, float * sub_x, float * sub_y, int codepoint);
933 // same as stbtt_MakeCodepointBitmapSubpixel, but prefiltering
934 // is performed (see stbtt_PackSetOversampling)
935 
936 STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo * font, int codepoint, float scale_x, float scale_y,
937                                            int * ix0, int * iy0, int * ix1, int * iy1);
938 // get the bbox of the bitmap centered around the glyph origin; so the
939 // bitmap width is ix1-ix0, height is iy1-iy0, and location to place
940 // the bitmap top left is (leftSideBearing*scale,iy0).
941 // (Note that the bitmap uses y-increases-down, but the shape uses
942 // y-increases-up, so CodepointBitmapBox and CodepointBox are inverted.)
943 
944 STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo * font, int codepoint, float scale_x,
945                                                    float scale_y, float shift_x, float shift_y, int * ix0, int * iy0, int * ix1, int * iy1);
946 // same as stbtt_GetCodepointBitmapBox, but you can specify a subpixel
947 // shift for the character
948 
949 // the following functions are equivalent to the above functions, but operate
950 // on glyph indices instead of Unicode codepoints (for efficiency)
951 STBTT_DEF unsigned char * stbtt_GetGlyphBitmap(const stbtt_fontinfo * info, float scale_x, float scale_y, int glyph,
952                                                int * width, int * height, int * xoff, int * yoff);
953 STBTT_DEF unsigned char * stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo * info, float scale_x, float scale_y,
954                                                        float shift_x, float shift_y, int glyph, int * width, int * height, int * xoff, int * yoff);
955 STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo * info, unsigned char * output, int out_w, int out_h,
956                                      int out_stride, float scale_x, float scale_y, int glyph);
957 STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo * info, unsigned char * output, int out_w, int out_h,
958                                              int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph);
959 STBTT_DEF void stbtt_MakeGlyphBitmapSubpixelPrefilter(const stbtt_fontinfo * info, unsigned char * output, int out_w,
960                                                       int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int oversample_x,
961                                                       int oversample_y, float * sub_x, float * sub_y, int glyph);
962 STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo * font, int glyph, float scale_x, float scale_y, int * ix0,
963                                        int * iy0, int * ix1, int * iy1);
964 STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo * font, int glyph, float scale_x, float scale_y,
965                                                float shift_x, float shift_y, int * ix0, int * iy0, int * ix1, int * iy1);
966 
967 // @TODO: don't expose this structure
968 typedef struct {
969     int w, h, stride;
970     unsigned char * pixels;
971 } stbtt__bitmap;
972 
973 // rasterize a shape with quadratic beziers into a bitmap
974 STBTT_DEF void stbtt_Rasterize(stbtt__bitmap * result,       // 1-channel bitmap to draw into
975                                float flatness_in_pixels,     // allowable error of curve in pixels
976                                stbtt_vertex * vertices,      // array of vertices defining shape
977                                int num_verts,                // number of vertices in above array
978                                float scale_x, float scale_y, // scale applied to input vertices
979                                float shift_x, float shift_y, // translation applied to input vertices
980                                int x_off, int y_off,         // another translation applied to input
981                                int invert,                   // if non-zero, vertically flip shape
982                                void * userdata);             // context for to STBTT_MALLOC
983 
984 //////////////////////////////////////////////////////////////////////////////
985 //
986 // Signed Distance Function (or Field) rendering
987 
988 STBTT_DEF void stbtt_FreeSDF(unsigned char * bitmap, void * userdata);
989 // frees the SDF bitmap allocated below
990 
991 STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo * info, float scale, int glyph, int padding,
992                                             unsigned char onedge_value, float pixel_dist_scale, int * width, int * height, int * xoff, int * yoff);
993 STBTT_DEF unsigned char * stbtt_GetCodepointSDF(const stbtt_fontinfo * info, float scale, int codepoint, int padding,
994                                                 unsigned char onedge_value, float pixel_dist_scale, int * width, int * height, int * xoff, int * yoff);
995 // These functions compute a discretized SDF field for a single character, suitable for storing
996 // in a single-channel texture, sampling with bilinear filtering, and testing against
997 // larger than some threshold to produce scalable fonts.
998 //        info              --  the font
999 //        scale             --  controls the size of the resulting SDF bitmap, same as it would be creating a regular bitmap
1000 //        glyph/codepoint   --  the character to generate the SDF for
1001 //        padding           --  extra "pixels" around the character which are filled with the distance to the character (not 0),
1002 //                                 which allows effects like bit outlines
1003 //        onedge_value      --  value 0-255 to test the SDF against to reconstruct the character (i.e. the isocontour of the character)
1004 //        pixel_dist_scale  --  what value the SDF should increase by when moving one SDF "pixel" away from the edge (on the 0..255 scale)
1005 //                                 if positive, > onedge_value is inside; if negative, < onedge_value is inside
1006 //        width,height      --  output height & width of the SDF bitmap (including padding)
1007 //        xoff,yoff         --  output origin of the character
1008 //        return value      --  a 2D array of bytes 0..255, width*height in size
1009 //
1010 // pixel_dist_scale & onedge_value are a scale & bias that allows you to make
1011 // optimal use of the limited 0..255 for your application, trading off precision
1012 // and special effects. SDF values outside the range 0..255 are clamped to 0..255.
1013 //
1014 // Example:
1015 //      scale = stbtt_ScaleForPixelHeight(22)
1016 //      padding = 5
1017 //      onedge_value = 180
1018 //      pixel_dist_scale = 180/5.0 = 36.0
1019 //
1020 //      This will create an SDF bitmap in which the character is about 22 pixels
1021 //      high but the whole bitmap is about 22+5+5=32 pixels high. To produce a filled
1022 //      shape, sample the SDF at each pixel and fill the pixel if the SDF value
1023 //      is greater than or equal to 180/255. (You'll actually want to antialias,
1024 //      which is beyond the scope of this example.) Additionally, you can compute
1025 //      offset outlines (e.g. to stroke the character border inside & outside,
1026 //      or only outside). For example, to fill outside the character up to 3 SDF
1027 //      pixels, you would compare against (180-36.0*3)/255 = 72/255. The above
1028 //      choice of variables maps a range from 5 pixels outside the shape to
1029 //      2 pixels inside the shape to 0..255; this is intended primarily for apply
1030 //      outside effects only (the interior range is needed to allow proper
1031 //      antialiasing of the font at *smaller* sizes)
1032 //
1033 // The function computes the SDF analytically at each SDF pixel, not by e.g.
1034 // building a higher-res bitmap and approximating it. In theory the quality
1035 // should be as high as possible for an SDF of this size & representation, but
1036 // unclear if this is true in practice (perhaps building a higher-res bitmap
1037 // and computing from that can allow drop-out prevention).
1038 //
1039 // The algorithm has not been optimized at all, so expect it to be slow
1040 // if computing lots of characters or very large sizes.
1041 
1042 //////////////////////////////////////////////////////////////////////////////
1043 //
1044 // Finding the right font...
1045 //
1046 // You should really just solve this offline, keep your own tables
1047 // of what font is what, and don't try to get it out of the .ttf file.
1048 // That's because getting it out of the .ttf file is really hard, because
1049 // the names in the file can appear in many possible encodings, in many
1050 // possible languages, and e.g. if you need a case-insensitive comparison,
1051 // the details of that depend on the encoding & language in a complex way
1052 // (actually underspecified in truetype, but also gigantic).
1053 //
1054 // But you can use the provided functions in two possible ways:
1055 //     stbtt_FindMatchingFont() will use *case-sensitive* comparisons on
1056 //             unicode-encoded names to try to find the font you want;
1057 //             you can run this before calling stbtt_InitFont()
1058 //
1059 //     stbtt_GetFontNameString() lets you get any of the various strings
1060 //             from the file yourself and do your own comparisons on them.
1061 //             You have to have called stbtt_InitFont() first.
1062 
1063 #ifdef STBTT_STREAM_TYPE
1064 STBTT_DEF int stbtt_FindMatchingFont(STBTT_STREAM_TYPE fontdata, const char * name, int flags);
1065 #else
1066 STBTT_DEF int stbtt_FindMatchingFont(const unsigned char * fontdata, const char * name, int flags);
1067 #endif
1068 // returns the offset (not index) of the font that matches, or -1 if none
1069 //   if you use STBTT_MACSTYLE_DONTCARE, use a font name like "Arial Bold".
1070 //   if you use any other flag, use a font name like "Arial"; this checks
1071 //     the 'macStyle' header field; i don't know if fonts set this consistently
1072 #define STBTT_MACSTYLE_DONTCARE     0
1073 #define STBTT_MACSTYLE_BOLD         1
1074 #define STBTT_MACSTYLE_ITALIC       2
1075 #define STBTT_MACSTYLE_UNDERSCORE   4
1076 #define STBTT_MACSTYLE_NONE         8   // <= not same as 0, this makes us check the bitfield is 0
1077 
1078 #ifdef STBTT_STREAM_TYPE
1079 STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char * s1, int len1, STBTT_STREAM_TYPE s2, stbtt_uint32 s2offs,
1080                                                  int len2);
1081 #else
1082 STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char * s1, int len1, const char * s2, stbtt_uint32 s2offs,
1083                                                  int len2);
1084 #endif
1085 // returns 1/0 whether the first string interpreted as utf8 is identical to
1086 // the second string interpreted as big-endian utf16... useful for strings from next func
1087 
1088 STBTT_DEF stbtt_uint32 stbtt_GetFontNameString(const stbtt_fontinfo * font, int * length, int platformID,
1089                                                int encodingID, int languageID, int nameID);
1090 
1091 // returns the string (which may be big-endian double byte, e.g. for unicode)
1092 // and puts the length in bytes in *length.
1093 //
1094 // some of the values for the IDs are below; for more see the truetype spec:
1095 //     http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6name.html
1096 //     http://www.microsoft.com/typography/otspec/name.htm
1097 
1098 enum { // platformID
1099     STBTT_PLATFORM_ID_UNICODE = 0,
1100     STBTT_PLATFORM_ID_MAC = 1,
1101     STBTT_PLATFORM_ID_ISO = 2,
1102     STBTT_PLATFORM_ID_MICROSOFT = 3
1103 };
1104 
1105 enum { // encodingID for STBTT_PLATFORM_ID_UNICODE
1106     STBTT_UNICODE_EID_UNICODE_1_0 = 0,
1107     STBTT_UNICODE_EID_UNICODE_1_1 = 1,
1108     STBTT_UNICODE_EID_ISO_10646 = 2,
1109     STBTT_UNICODE_EID_UNICODE_2_0_BMP = 3,
1110     STBTT_UNICODE_EID_UNICODE_2_0_FULL = 4
1111 };
1112 
1113 enum { // encodingID for STBTT_PLATFORM_ID_MICROSOFT
1114     STBTT_MS_EID_SYMBOL = 0,
1115     STBTT_MS_EID_UNICODE_BMP = 1,
1116     STBTT_MS_EID_SHIFTJIS = 2,
1117     STBTT_MS_EID_UNICODE_FULL = 10
1118 };
1119 
1120 enum { // encodingID for STBTT_PLATFORM_ID_MAC; same as Script Manager codes
1121     STBTT_MAC_EID_ROMAN = 0, STBTT_MAC_EID_ARABIC = 4,
1122     STBTT_MAC_EID_JAPANESE = 1, STBTT_MAC_EID_HEBREW = 5,
1123     STBTT_MAC_EID_CHINESE_TRAD = 2, STBTT_MAC_EID_GREEK = 6,
1124     STBTT_MAC_EID_KOREAN = 3, STBTT_MAC_EID_RUSSIAN = 7
1125 };
1126 
1127 enum { // languageID for STBTT_PLATFORM_ID_MICROSOFT; same as LCID...
1128     // problematic because there are e.g. 16 english LCIDs and 16 arabic LCIDs
1129     STBTT_MS_LANG_ENGLISH = 0x0409, STBTT_MS_LANG_ITALIAN = 0x0410,
1130     STBTT_MS_LANG_CHINESE = 0x0804, STBTT_MS_LANG_JAPANESE = 0x0411,
1131     STBTT_MS_LANG_DUTCH = 0x0413, STBTT_MS_LANG_KOREAN = 0x0412,
1132     STBTT_MS_LANG_FRENCH = 0x040c, STBTT_MS_LANG_RUSSIAN = 0x0419,
1133     STBTT_MS_LANG_GERMAN = 0x0407, STBTT_MS_LANG_SPANISH = 0x0409,
1134     STBTT_MS_LANG_HEBREW = 0x040d, STBTT_MS_LANG_SWEDISH = 0x041D
1135 };
1136 
1137 enum { // languageID for STBTT_PLATFORM_ID_MAC
1138     STBTT_MAC_LANG_ENGLISH = 0, STBTT_MAC_LANG_JAPANESE = 11,
1139     STBTT_MAC_LANG_ARABIC = 12, STBTT_MAC_LANG_KOREAN = 23,
1140     STBTT_MAC_LANG_DUTCH = 4, STBTT_MAC_LANG_RUSSIAN = 32,
1141     STBTT_MAC_LANG_FRENCH = 1, STBTT_MAC_LANG_SPANISH = 6,
1142     STBTT_MAC_LANG_GERMAN = 2, STBTT_MAC_LANG_SWEDISH = 5,
1143     STBTT_MAC_LANG_HEBREW = 10, STBTT_MAC_LANG_CHINESE_SIMPLIFIED = 33,
1144     STBTT_MAC_LANG_ITALIAN = 3, STBTT_MAC_LANG_CHINESE_TRAD = 19
1145 };
1146 
1147 #ifdef __cplusplus
1148 }
1149 #endif
1150 
1151 #endif // __STB_INCLUDE_STB_TRUETYPE_H__
1152 
1153 ///////////////////////////////////////////////////////////////////////////////
1154 ///////////////////////////////////////////////////////////////////////////////
1155 ////
1156 ////   IMPLEMENTATION
1157 ////
1158 ////
1159 
1160 #ifdef STB_TRUETYPE_IMPLEMENTATION
1161 
1162 #ifndef STBTT_MAX_OVERSAMPLE
1163     #define STBTT_MAX_OVERSAMPLE   8
1164 #endif
1165 
1166 #if STBTT_MAX_OVERSAMPLE > 255
1167     #error "STBTT_MAX_OVERSAMPLE cannot be > 255"
1168 #endif
1169 
1170 typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERSAMPLE - 1)) == 0 ? 1 : -1];
1171 
1172 #ifndef STBTT_RASTERIZER_VERSION
1173     #define STBTT_RASTERIZER_VERSION 2
1174 #endif
1175 
1176 #ifdef _MSC_VER
1177     #define STBTT__NOTUSED(v)  (void)(v)
1178 #else
1179     #define STBTT__NOTUSED(v)  (void)sizeof(v)
1180 #endif
1181 
1182 //////////////////////////////////////////////////////////////////////////
1183 //
1184 // stbtt__buf helpers to parse data from file
1185 //
1186 
stbtt__buf_get8(stbtt__buf * b)1187 static stbtt_uint8 stbtt__buf_get8(stbtt__buf * b)
1188 {
1189     if(b->cursor >= b->size)
1190         return 0;
1191 #ifdef STBTT_STREAM_TYPE
1192     long pos = (long)(b->cursor + b->offset);
1193     STBTT_STREAM_SEEK(b->data, pos);
1194     stbtt_uint8 result;
1195     STBTT_STREAM_READ(b->data, &result, 1);
1196     ++b->cursor;
1197     return result;
1198 #else
1199     return b->data[b->cursor++];
1200 #endif
1201 
1202 }
1203 
stbtt__buf_peek8(stbtt__buf * b)1204 static stbtt_uint8 stbtt__buf_peek8(stbtt__buf * b)
1205 {
1206     if(b->cursor >= b->size)
1207         return 0;
1208 #ifdef STBTT_STREAM_TYPE
1209     long pos = (long)(b->cursor + b->offset);
1210     STBTT_STREAM_SEEK(b->data, pos);
1211     stbtt_uint8 result;
1212     STBTT_STREAM_READ(b->data, &result, 1);
1213     return result;
1214 #else
1215     return b->data[b->cursor];
1216 #endif
1217 
1218 }
1219 
stbtt__buf_seek(stbtt__buf * b,int o)1220 static void stbtt__buf_seek(stbtt__buf * b, int o)
1221 {
1222     STBTT_assert(!(o > b->size || o < 0));
1223     b->cursor = (o > b->size || o < 0) ? b->size : o;
1224 }
1225 
stbtt__buf_skip(stbtt__buf * b,int o)1226 static void stbtt__buf_skip(stbtt__buf * b, int o)
1227 {
1228     stbtt__buf_seek(b, b->cursor + o);
1229 }
1230 
stbtt__buf_get(stbtt__buf * b,int n)1231 static stbtt_uint32 stbtt__buf_get(stbtt__buf * b, int n)
1232 {
1233     stbtt_uint32 v = 0;
1234     int i;
1235     STBTT_assert(n >= 1 && n <= 4);
1236     for(i = 0; i < n; i++)
1237         v = (v << 8) | stbtt__buf_get8(b);
1238     return v;
1239 }
1240 #ifdef STBTT_STREAM_TYPE
stbtt__new_buf(STBTT_STREAM_TYPE s,size_t size)1241     static stbtt__buf stbtt__new_buf(STBTT_STREAM_TYPE s, size_t size)
1242 #else
1243     static stbtt__buf stbtt__new_buf(const void * p, size_t size)
1244 #endif
1245 {
1246     stbtt__buf r;
1247     STBTT_assert(size < 0x40000000);
1248 #ifdef STBTT_STREAM_TYPE
1249     r.data = s;
1250     r.offset = 0;
1251 #else
1252     r.data = (stbtt_uint8 *)p;
1253 #endif
1254     r.size = (int)size;
1255     r.cursor = 0;
1256     return r;
1257 }
1258 
1259 #define stbtt__buf_get16(b)  stbtt__buf_get((b), 2)
1260 #define stbtt__buf_get32(b)  stbtt__buf_get((b), 4)
1261 
stbtt__buf_range(const stbtt__buf * b,int o,int s)1262 static stbtt__buf stbtt__buf_range(const stbtt__buf * b, int o, int s)
1263 {
1264     stbtt__buf r = stbtt__new_buf(NULL, 0);
1265     if(o < 0 || s < 0 || o > b->size || s > b->size - o) return r;
1266 #ifdef STBTT_STREAM_TYPE
1267     r.data = b->data;
1268     r.offset = b->offset + o;
1269 #else
1270     r.data = b->data + o;
1271 #endif
1272     r.size = s;
1273     return r;
1274 }
1275 
stbtt__cff_get_index(stbtt__buf * b)1276 static stbtt__buf stbtt__cff_get_index(stbtt__buf * b)
1277 {
1278     int count, start, offsize;
1279     start = b->cursor;
1280     count = stbtt__buf_get16(b);
1281     if(count) {
1282         offsize = stbtt__buf_get8(b);
1283         STBTT_assert(offsize >= 1 && offsize <= 4);
1284         stbtt__buf_skip(b, offsize * count);
1285         stbtt__buf_skip(b, stbtt__buf_get(b, offsize) - 1);
1286     }
1287     return stbtt__buf_range(b, start, b->cursor - start);
1288 }
1289 
stbtt__cff_int(stbtt__buf * b)1290 static stbtt_uint32 stbtt__cff_int(stbtt__buf * b)
1291 {
1292     int b0 = stbtt__buf_get8(b);
1293     if(b0 >= 32 && b0 <= 246)       return b0 - 139;
1294     else if(b0 >= 247 && b0 <= 250) return (b0 - 247) * 256 + stbtt__buf_get8(b) + 108;
1295     else if(b0 >= 251 && b0 <= 254) return -(b0 - 251) * 256 - stbtt__buf_get8(b) - 108;
1296     else if(b0 == 28)               return stbtt__buf_get16(b);
1297     else if(b0 == 29)               return stbtt__buf_get32(b);
1298     STBTT_assert(0);
1299     return 0;
1300 }
1301 
stbtt__cff_skip_operand(stbtt__buf * b)1302 static void stbtt__cff_skip_operand(stbtt__buf * b)
1303 {
1304     int v, b0 = stbtt__buf_peek8(b);
1305     STBTT_assert(b0 >= 28);
1306     if(b0 == 30) {
1307         stbtt__buf_skip(b, 1);
1308         while(b->cursor < b->size) {
1309             v = stbtt__buf_get8(b);
1310             if((v & 0xF) == 0xF || (v >> 4) == 0xF)
1311                 break;
1312         }
1313     }
1314     else {
1315         stbtt__cff_int(b);
1316     }
1317 }
1318 
stbtt__dict_get(stbtt__buf * b,int key)1319 static stbtt__buf stbtt__dict_get(stbtt__buf * b, int key)
1320 {
1321     stbtt__buf_seek(b, 0);
1322     while(b->cursor < b->size) {
1323         int start = b->cursor, end, op;
1324         while(stbtt__buf_peek8(b) >= 28)
1325             stbtt__cff_skip_operand(b);
1326         end = b->cursor;
1327         op = stbtt__buf_get8(b);
1328         if(op == 12)  op = stbtt__buf_get8(b) | 0x100;
1329         if(op == key) return stbtt__buf_range(b, start, end - start);
1330     }
1331     return stbtt__buf_range(b, 0, 0);
1332 }
1333 
stbtt__dict_get_ints(stbtt__buf * b,int key,int outcount,stbtt_uint32 * out)1334 static void stbtt__dict_get_ints(stbtt__buf * b, int key, int outcount, stbtt_uint32 * out)
1335 {
1336     int i;
1337     stbtt__buf operands = stbtt__dict_get(b, key);
1338     for(i = 0; i < outcount && operands.cursor < operands.size; i++)
1339         out[i] = stbtt__cff_int(&operands);
1340 }
1341 
stbtt__cff_index_count(stbtt__buf * b)1342 static int stbtt__cff_index_count(stbtt__buf * b)
1343 {
1344     stbtt__buf_seek(b, 0);
1345     return stbtt__buf_get16(b);
1346 }
1347 
stbtt__cff_index_get(stbtt__buf b,int i)1348 static stbtt__buf stbtt__cff_index_get(stbtt__buf b, int i)
1349 {
1350     int count, offsize, start, end;
1351     stbtt__buf_seek(&b, 0);
1352     count = stbtt__buf_get16(&b);
1353     offsize = stbtt__buf_get8(&b);
1354     STBTT_assert(i >= 0 && i < count);
1355     STBTT_assert(offsize >= 1 && offsize <= 4);
1356     stbtt__buf_skip(&b, i * offsize);
1357     start = stbtt__buf_get(&b, offsize);
1358     end = stbtt__buf_get(&b, offsize);
1359     return stbtt__buf_range(&b, 2 + (count + 1) * offsize + start, end - start);
1360 }
1361 
1362 //////////////////////////////////////////////////////////////////////////
1363 //
1364 // accessors to parse data from file
1365 //
1366 
1367 // on platforms that don't allow misaligned reads, if we want to allow
1368 // truetype fonts that aren't padded to alignment, define ALLOW_UNALIGNED_TRUETYPE
1369 
1370 #ifdef STBTT_STREAM_TYPE
ttBYTE(STBTT_STREAM_TYPE s,stbtt_uint32 offset)1371 static stbtt_uint8 ttBYTE(STBTT_STREAM_TYPE s, stbtt_uint32 offset)
1372 {
1373     STBTT_STREAM_SEEK(s, offset);
1374     stbtt_uint8 r;
1375     STBTT_STREAM_READ(s, &r, 1);
1376     return r;
1377 }
1378 #define ttCHAR(s, offset)     ((stbtt_int8)ttBYTE(s,offset))
ttUSHORT(STBTT_STREAM_TYPE s,stbtt_uint32 offset)1379 static stbtt_uint16 ttUSHORT(STBTT_STREAM_TYPE s, stbtt_uint32 offset)
1380 {
1381     STBTT_STREAM_SEEK(s, offset);
1382     stbtt_uint8 r[2];
1383     STBTT_STREAM_READ(s, &r, 2);
1384     return r[0] * 256 + r[1];
1385 }
ttSHORT(STBTT_STREAM_TYPE s,stbtt_uint32 offset)1386 static stbtt_int16 ttSHORT(STBTT_STREAM_TYPE s, stbtt_uint32 offset)
1387 {
1388     STBTT_STREAM_SEEK(s, offset);
1389     stbtt_uint8 r[2];
1390     STBTT_STREAM_READ(s, &r, 2);
1391     return r[0] * 256 + r[1];
1392 }
ttULONG(STBTT_STREAM_TYPE s,stbtt_uint32 offset)1393 static stbtt_uint32 ttULONG(STBTT_STREAM_TYPE s, stbtt_uint32 offset)
1394 {
1395     STBTT_STREAM_SEEK(s, offset);
1396     stbtt_uint8 r[4];
1397     STBTT_STREAM_READ(s, &r, 4);
1398     return (r[0] << 24) + (r[1] << 16) + (r[2] << 8) + r[3];
1399 }
ttLONG(STBTT_STREAM_TYPE s,stbtt_uint32 offset)1400 static stbtt_int32 ttLONG(STBTT_STREAM_TYPE s, stbtt_uint32 offset)
1401 {
1402     STBTT_STREAM_SEEK(s, offset);
1403     stbtt_uint8 r[4];
1404     STBTT_STREAM_READ(s, &r, 4);
1405     return (r[0] << 24) + (r[1] << 16) + (r[2] << 8) + r[3];
1406 }
1407 #else
1408 #define ttBYTE(p, offset)     (* (stbtt_uint8 *) (p+offset))
1409 #define ttCHAR(p, offset)     (* (stbtt_int8 *) (p+offset))
ttUSHORT(const stbtt_uint8 * p,stbtt_uint32 offset)1410 static stbtt_uint16 ttUSHORT(const stbtt_uint8 * p, stbtt_uint32 offset)
1411 {
1412     return p[offset + 0] * 256 + p[offset + 1];
1413 }
ttSHORT(const stbtt_uint8 * p,stbtt_uint32 offset)1414 static stbtt_int16 ttSHORT(const stbtt_uint8 * p, stbtt_uint32 offset)
1415 {
1416     return p[offset + 0] * 256 + p[offset + 1];
1417 }
ttULONG(const stbtt_uint8 * p,stbtt_uint32 offset)1418 static stbtt_uint32 ttULONG(const stbtt_uint8 * p, stbtt_uint32 offset)
1419 {
1420     return (p[offset + 0] << 24) + (p[offset + 1] << 16) + (p[offset + 2] << 8) + p[offset + 3];
1421 }
ttLONG(const stbtt_uint8 * p,stbtt_uint32 offset)1422 static stbtt_int32 ttLONG(const stbtt_uint8 * p, stbtt_uint32 offset)
1423 {
1424     return (p[offset + 0] << 24) + (p[offset + 1] << 16) + (p[offset + 2] << 8) + p[offset + 3];
1425 }
1426 #endif
1427 #define ttFixed(p, offset)    ttLONG(p, offset)
1428 
1429 #define stbtt_tag4(p,c0,c1,c2,c3) ((p)[0] == (c0) && (p)[1] == (c1) && (p)[2] == (c2) && (p)[3] == (c3))
1430 #define stbtt_tag(p,str)           stbtt_tag4(p,str[0],str[1],str[2],str[3])
1431 #ifdef STBTT_STREAM_TYPE
stbtt__isfont(STBTT_STREAM_TYPE stream,stbtt_uint32 offs)1432     static int stbtt__isfont(STBTT_STREAM_TYPE stream, stbtt_uint32 offs)
1433 #else
1434     static int stbtt__isfont(stbtt_uint8 * font, stbtt_uint32 offs)
1435 #endif
1436 {
1437 #ifdef STBTT_STREAM_TYPE
1438     stbtt_uint8 font[4];
1439     STBTT_STREAM_SEEK(stream, offs);
1440     STBTT_STREAM_READ(stream, font, 4);
1441 #else
1442     font += offs;
1443 #endif
1444     // check the version number
1445     if(stbtt_tag4(font, '1', 0, 0, 0))  return 1;  // TrueType 1
1446     if(stbtt_tag(font, "typ1"))   return 1;  // TrueType with type 1 font -- we don't support this!
1447     if(stbtt_tag(font, "OTTO"))   return 1;  // OpenType with CFF
1448     if(stbtt_tag4(font, 0, 1, 0, 0)) return 1;  // OpenType 1.0
1449     if(stbtt_tag(font, "true"))   return 1;  // Apple specification for TrueType fonts
1450     return 0;
1451 }
1452 
1453 // @OPTIMIZE: binary search
1454 #ifdef STBTT_STREAM_TYPE
stbtt__find_table(STBTT_STREAM_TYPE data,stbtt_uint32 fontstart,const char * tag)1455     static stbtt_uint32 stbtt__find_table(STBTT_STREAM_TYPE data, stbtt_uint32 fontstart, const char * tag)
1456 #else
1457     static stbtt_uint32 stbtt__find_table(stbtt_uint8 * data, stbtt_uint32 fontstart, const char * tag)
1458 #endif
1459 {
1460     stbtt_int32 num_tables = ttUSHORT(data, fontstart + 4);
1461     stbtt_uint32 tabledir = fontstart + 12;
1462     stbtt_int32 i;
1463     for(i = 0; i < num_tables; ++i) {
1464         stbtt_uint32 loc = tabledir + 16 * i;
1465 #ifdef STBTT_STREAM_TYPE
1466         stbtt_uint8 buf[4];
1467         STBTT_STREAM_SEEK(data, loc + 0);
1468         STBTT_STREAM_READ(data, buf, 4);
1469         if(stbtt_tag(buf, tag))
1470             return ttULONG(data, loc + 8);
1471 #else
1472         if(stbtt_tag(data + loc + 0, tag))
1473             return ttULONG(data, loc + 8);
1474 #endif
1475     }
1476     return 0;
1477 }
1478 #ifdef STBTT_STREAM_TYPE
stbtt_GetFontOffsetForIndex_internal(STBTT_STREAM_TYPE font_collection,int index)1479     static int stbtt_GetFontOffsetForIndex_internal(STBTT_STREAM_TYPE font_collection, int index)
1480 #else
1481     static int stbtt_GetFontOffsetForIndex_internal(unsigned char * font_collection, int index)
1482 #endif
1483 {
1484     // if it's just a font, there's only one valid index
1485     if(stbtt__isfont(font_collection, 0))
1486         return index == 0 ? 0 : -1;
1487 
1488     // check if it's a TTC
1489 #ifdef STBTT_STREAM_TYPE
1490     stbtt_uint8 buf[4];
1491     STBTT_STREAM_SEEK(font_collection, 0);
1492     STBTT_STREAM_READ(font_collection, buf, 4);
1493     if(stbtt_tag(buf, "ttcf")) {
1494 #else
1495     if(stbtt_tag(font_collection, "ttcf")) {
1496 #endif
1497         // version 1?
1498         if(ttULONG(font_collection, 4) == 0x00010000 || ttULONG(font_collection, 4) == 0x00020000) {
1499             stbtt_int32 n = ttLONG(font_collection, 8);
1500             if(index >= n)
1501                 return -1;
1502             return ttULONG(font_collection, 12 + index * 4);
1503         }
1504     }
1505     return -1;
1506 }
1507 #ifdef STBTT_STREAM_TYPE
1508     static int stbtt_GetNumberOfFonts_internal(STBTT_STREAM_TYPE font_collection)
1509 #else
1510     static int stbtt_GetNumberOfFonts_internal(unsigned char * font_collection)
1511 #endif
1512 {
1513     // if it's just a font, there's only one valid font
1514     if(stbtt__isfont(font_collection, 0))
1515         return 1;
1516 
1517     // check if it's a TTC
1518 #ifdef STBTT_STREAM_TYPE
1519     stbtt_uint8 buf[4];
1520     STBTT_STREAM_SEEK(font_collection, 0);
1521     STBTT_STREAM_READ(font_collection, buf, 4);
1522     if(stbtt_tag(buf, "ttcf")) {
1523 #else
1524     if(stbtt_tag(font_collection, "ttcf")) {
1525 #endif
1526         // version 1?
1527         if(ttULONG(font_collection, 4) == 0x00010000 || ttULONG(font_collection, 4) == 0x00020000) {
1528             return ttLONG(font_collection, 8);
1529         }
1530     }
1531     return 0;
1532 }
1533 
1534 static stbtt__buf stbtt__get_subrs(stbtt__buf cff, stbtt__buf fontdict)
1535 {
1536     stbtt_uint32 subrsoff = 0, private_loc[2] = { 0, 0 };
1537     stbtt__buf pdict;
1538     stbtt__dict_get_ints(&fontdict, 18, 2, private_loc);
1539     if(!private_loc[1] || !private_loc[0]) return stbtt__new_buf(NULL, 0);
1540     pdict = stbtt__buf_range(&cff, private_loc[1], private_loc[0]);
1541     stbtt__dict_get_ints(&pdict, 19, 1, &subrsoff);
1542     if(!subrsoff) return stbtt__new_buf(NULL, 0);
1543     stbtt__buf_seek(&cff, private_loc[1] + subrsoff);
1544     return stbtt__cff_get_index(&cff);
1545 }
1546 
1547 // since most people won't use this, find this table the first time it's needed
1548 static int stbtt__get_svg(stbtt_fontinfo * info)
1549 {
1550     stbtt_uint32 t;
1551     if(info->svg < 0) {
1552         t = stbtt__find_table(info->data, info->fontstart, "SVG ");
1553         if(t) {
1554             stbtt_uint32 offset = ttULONG(info->data, t + 2);
1555             info->svg = t + offset;
1556         }
1557         else {
1558             info->svg = 0;
1559         }
1560     }
1561     return info->svg;
1562 }
1563 #ifdef STBTT_STREAM_TYPE
1564     static int stbtt_InitFont_internal(stbtt_fontinfo * info, STBTT_STREAM_TYPE data, int fontstart)
1565 #else
1566     static int stbtt_InitFont_internal(stbtt_fontinfo * info, unsigned char * data, int fontstart)
1567 #endif
1568 {
1569     stbtt_uint32 cmap, t;
1570     stbtt_int32 i, numTables;
1571 
1572     info->data = data;
1573     info->fontstart = fontstart;
1574     info->cff = stbtt__new_buf(NULL, 0);
1575 
1576     cmap = stbtt__find_table(data, fontstart, "cmap");       // required
1577     info->loca = stbtt__find_table(data, fontstart, "loca"); // required
1578     info->head = stbtt__find_table(data, fontstart, "head"); // required
1579     info->glyf = stbtt__find_table(data, fontstart, "glyf"); // required
1580     info->hhea = stbtt__find_table(data, fontstart, "hhea"); // required
1581     info->hmtx = stbtt__find_table(data, fontstart, "hmtx"); // required
1582     info->kern = stbtt__find_table(data, fontstart, "kern"); // not required
1583     info->gpos = stbtt__find_table(data, fontstart, "GPOS"); // not required
1584 
1585     if(!cmap || !info->head || !info->hhea || !info->hmtx)
1586         return 0;
1587     if(info->glyf) {
1588         // required for truetype
1589         if(!info->loca) return 0;
1590     }
1591     else {
1592         // initialization for CFF / Type2 fonts (OTF)
1593         stbtt__buf b, topdict, topdictidx;
1594         stbtt_uint32 cstype = 2, charstrings = 0, fdarrayoff = 0, fdselectoff = 0;
1595         stbtt_uint32 cff;
1596 
1597         cff = stbtt__find_table(data, fontstart, "CFF ");
1598         if(!cff) return 0;
1599 
1600         info->fontdicts = stbtt__new_buf(NULL, 0);
1601         info->fdselect = stbtt__new_buf(NULL, 0);
1602 
1603         // @TODO this should use size from table (not 512MB)
1604 
1605 #ifdef STBTT_STREAM_TYPE
1606         info->cff = stbtt__new_buf(info->data, 512 * 1024 * 1024);
1607         info->cff.offset = cff;
1608 #else
1609         info->cff = stbtt__new_buf(info->data + cff, 512 * 1024 * 1024);
1610 #endif
1611         b = info->cff;
1612 
1613         // read the header
1614         stbtt__buf_skip(&b, 2);
1615         stbtt__buf_seek(&b, stbtt__buf_get8(&b)); // hdrsize
1616 
1617         // @TODO the name INDEX could list multiple fonts,
1618         // but we just use the first one.
1619         stbtt__cff_get_index(&b);  // name INDEX
1620         topdictidx = stbtt__cff_get_index(&b);
1621         topdict = stbtt__cff_index_get(topdictidx, 0);
1622         stbtt__cff_get_index(&b);  // string INDEX
1623         info->gsubrs = stbtt__cff_get_index(&b);
1624 
1625         stbtt__dict_get_ints(&topdict, 17, 1, &charstrings);
1626         stbtt__dict_get_ints(&topdict, 0x100 | 6, 1, &cstype);
1627         stbtt__dict_get_ints(&topdict, 0x100 | 36, 1, &fdarrayoff);
1628         stbtt__dict_get_ints(&topdict, 0x100 | 37, 1, &fdselectoff);
1629         info->subrs = stbtt__get_subrs(b, topdict);
1630 
1631         // we only support Type 2 charstrings
1632         if(cstype != 2) return 0;
1633         if(charstrings == 0) return 0;
1634 
1635         if(fdarrayoff) {
1636             // looks like a CID font
1637             if(!fdselectoff) return 0;
1638             stbtt__buf_seek(&b, fdarrayoff);
1639             info->fontdicts = stbtt__cff_get_index(&b);
1640             info->fdselect = stbtt__buf_range(&b, fdselectoff, b.size - fdselectoff);
1641         }
1642 
1643         stbtt__buf_seek(&b, charstrings);
1644         info->charstrings = stbtt__cff_get_index(&b);
1645     }
1646 
1647     t = stbtt__find_table(data, fontstart, "maxp");
1648     if(t)
1649         info->numGlyphs = ttUSHORT(data, t + 4);
1650     else
1651         info->numGlyphs = 0xffff;
1652 
1653     info->svg = -1;
1654 
1655     // find a cmap encoding table we understand *now* to avoid searching
1656     // later. (todo: could make this installable)
1657     // the same regardless of glyph.
1658     numTables = ttUSHORT(data, cmap + 2);
1659     info->index_map = 0;
1660     for(i = 0; i < numTables; ++i) {
1661         stbtt_uint32 encoding_record = cmap + 4 + 8 * i;
1662         // find an encoding we understand:
1663         switch(ttUSHORT(data, encoding_record)) {
1664             case STBTT_PLATFORM_ID_MICROSOFT:
1665                 switch(ttUSHORT(data, encoding_record + 2)) {
1666                     case STBTT_MS_EID_UNICODE_BMP:
1667                     case STBTT_MS_EID_UNICODE_FULL:
1668                         // MS/Unicode
1669                         info->index_map = cmap + ttULONG(data, encoding_record + 4);
1670                         break;
1671                 }
1672                 break;
1673             case STBTT_PLATFORM_ID_UNICODE:
1674                 // Mac/iOS has these
1675                 // all the encodingIDs are unicode, so we don't bother to check it
1676                 info->index_map = cmap + ttULONG(data, encoding_record + 4);
1677                 break;
1678         }
1679     }
1680     if(info->index_map == 0)
1681         return 0;
1682 
1683     info->indexToLocFormat = ttUSHORT(data, info->head + 50);
1684     return 1;
1685 }
1686 
1687 STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo * info, int unicode_codepoint)
1688 {
1689 #ifdef STBTT_STREAM_TYPE
1690     STBTT_STREAM_TYPE data = info->data;
1691 #else
1692     stbtt_uint8 * data = info->data;
1693 #endif
1694     stbtt_uint32 index_map = info->index_map;
1695 
1696     stbtt_uint16 format = ttUSHORT(data, index_map + 0);
1697     if(format == 0) {  // apple byte encoding
1698         stbtt_int32 bytes = ttUSHORT(data, index_map + 2);
1699         if(unicode_codepoint < bytes - 6)
1700             return ttBYTE(data, index_map + 6 + unicode_codepoint);
1701         return 0;
1702     }
1703     else if(format == 6) {
1704         stbtt_uint32 first = ttUSHORT(data, index_map + 6);
1705         stbtt_uint32 count = ttUSHORT(data, index_map + 8);
1706         if((stbtt_uint32)unicode_codepoint >= first && (stbtt_uint32)unicode_codepoint < first + count)
1707             return ttUSHORT(data, index_map + 10 + (unicode_codepoint - first) * 2);
1708         return 0;
1709     }
1710     else if(format == 2) {
1711         STBTT_assert(0); // @TODO: high-byte mapping for japanese/chinese/korean
1712         return 0;
1713     }
1714     else if(format == 4) {  // standard mapping for windows fonts: binary search collection of ranges
1715         stbtt_uint16 segcount = ttUSHORT(data, index_map + 6) >> 1;
1716         stbtt_uint16 searchRange = ttUSHORT(data, index_map + 8) >> 1;
1717         stbtt_uint16 entrySelector = ttUSHORT(data, index_map + 10);
1718         stbtt_uint16 rangeShift = ttUSHORT(data, index_map + 12) >> 1;
1719 
1720         // do a binary search of the segments
1721         stbtt_uint32 endCount = index_map + 14;
1722         stbtt_uint32 search = endCount;
1723 
1724         if(unicode_codepoint > 0xffff)
1725             return 0;
1726 
1727         // they lie from endCount .. endCount + segCount
1728         // but searchRange is the nearest power of two, so...
1729         if(unicode_codepoint >= ttUSHORT(data, search + rangeShift * 2))
1730             search += rangeShift * 2;
1731 
1732         // now decrement to bias correctly to find smallest
1733         search -= 2;
1734         while(entrySelector) {
1735             stbtt_uint16 end;
1736             searchRange >>= 1;
1737             end = ttUSHORT(data, search + searchRange * 2);
1738             if(unicode_codepoint > end)
1739                 search += searchRange * 2;
1740             --entrySelector;
1741         }
1742         search += 2;
1743 
1744         {
1745             stbtt_uint16 offset, start, last;
1746             stbtt_uint16 item = (stbtt_uint16)((search - endCount) >> 1);
1747 
1748             start = ttUSHORT(data, index_map + 14 + segcount * 2 + 2 + 2 * item);
1749             last = ttUSHORT(data, endCount + 2 * item);
1750             if(unicode_codepoint < start || unicode_codepoint > last)
1751                 return 0;
1752 
1753             offset = ttUSHORT(data, index_map + 14 + segcount * 6 + 2 + 2 * item);
1754             if(offset == 0)
1755                 return (stbtt_uint16)(unicode_codepoint + ttSHORT(data, index_map + 14 + segcount * 4 + 2 + 2 * item));
1756 
1757             return ttUSHORT(data, offset + (unicode_codepoint - start) * 2 + index_map + 14 + segcount * 6 + 2 + 2 * item);
1758         }
1759     }
1760     else if(format == 12 || format == 13) {
1761         stbtt_uint32 ngroups = ttULONG(data, index_map + 12);
1762         stbtt_int32 low, high;
1763         low = 0;
1764         high = (stbtt_int32)ngroups;
1765         // Binary search the right group.
1766         while(low < high) {
1767             stbtt_int32 mid = low + ((high - low) >> 1); // rounds down, so low <= mid < high
1768             stbtt_uint32 start_char = ttULONG(data, index_map + 16 + mid * 12);
1769             stbtt_uint32 end_char = ttULONG(data, index_map + 16 + mid * 12 + 4);
1770             if((stbtt_uint32)unicode_codepoint < start_char)
1771                 high = mid;
1772             else if((stbtt_uint32)unicode_codepoint > end_char)
1773                 low = mid + 1;
1774             else {
1775                 stbtt_uint32 start_glyph = ttULONG(data, index_map + 16 + mid * 12 + 8);
1776                 if(format == 12)
1777                     return start_glyph + unicode_codepoint - start_char;
1778                 else // format == 13
1779                     return start_glyph;
1780             }
1781         }
1782         return 0; // not found
1783     }
1784     // @TODO
1785     STBTT_assert(0);
1786     return 0;
1787 }
1788 
1789 STBTT_DEF int stbtt_GetCodepointShape(const stbtt_fontinfo * info, int unicode_codepoint, stbtt_vertex * *vertices)
1790 {
1791     return stbtt_GetGlyphShape(info, stbtt_FindGlyphIndex(info, unicode_codepoint), vertices);
1792 }
1793 
1794 static void stbtt_setvertex(stbtt_vertex * v, stbtt_uint8 type, stbtt_int32 x, stbtt_int32 y, stbtt_int32 cx,
1795                             stbtt_int32 cy)
1796 {
1797     v->type = type;
1798     v->x = (stbtt_int16)x;
1799     v->y = (stbtt_int16)y;
1800     v->cx = (stbtt_int16)cx;
1801     v->cy = (stbtt_int16)cy;
1802 }
1803 
1804 static int stbtt__GetGlyfOffset(const stbtt_fontinfo * info, int glyph_index)
1805 {
1806     int g1, g2;
1807 
1808     STBTT_assert(!info->cff.size);
1809 
1810     if(glyph_index >= info->numGlyphs) return -1;  // glyph index out of range
1811     if(info->indexToLocFormat >= 2)    return -1;  // unknown index->glyph map format
1812 
1813     if(info->indexToLocFormat == 0) {
1814         g1 = info->glyf + ttUSHORT(info->data, info->loca + glyph_index * 2) * 2;
1815         g2 = info->glyf + ttUSHORT(info->data, info->loca + glyph_index * 2 + 2) * 2;
1816     }
1817     else {
1818         g1 = info->glyf + ttULONG(info->data, info->loca + glyph_index * 4);
1819         g2 = info->glyf + ttULONG(info->data, info->loca + glyph_index * 4 + 4);
1820     }
1821 
1822     return g1 == g2 ? -1 : g1; // if length is 0, return -1
1823 }
1824 
1825 static int stbtt__GetGlyphInfoT2(const stbtt_fontinfo * info, int glyph_index, int * x0, int * y0, int * x1, int * y1);
1826 
1827 STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo * info, int glyph_index, int * x0, int * y0, int * x1, int * y1)
1828 {
1829     if(info->cff.size) {
1830         stbtt__GetGlyphInfoT2(info, glyph_index, x0, y0, x1, y1);
1831     }
1832     else {
1833         int g = stbtt__GetGlyfOffset(info, glyph_index);
1834         if(g < 0) return 0;
1835 
1836         if(x0) *x0 = ttSHORT(info->data, g + 2);
1837         if(y0) *y0 = ttSHORT(info->data, g + 4);
1838         if(x1) *x1 = ttSHORT(info->data, g + 6);
1839         if(y1) *y1 = ttSHORT(info->data, g + 8);
1840     }
1841     return 1;
1842 }
1843 
1844 STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo * info, int codepoint, int * x0, int * y0, int * x1, int * y1)
1845 {
1846     return stbtt_GetGlyphBox(info, stbtt_FindGlyphIndex(info, codepoint), x0, y0, x1, y1);
1847 }
1848 
1849 STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo * info, int glyph_index)
1850 {
1851     stbtt_int16 numberOfContours;
1852     int g;
1853     if(info->cff.size)
1854         return stbtt__GetGlyphInfoT2(info, glyph_index, NULL, NULL, NULL, NULL) == 0;
1855     g = stbtt__GetGlyfOffset(info, glyph_index);
1856     if(g < 0) return 1;
1857     numberOfContours = ttSHORT(info->data, g);
1858     return numberOfContours == 0;
1859 }
1860 
1861 static int stbtt__close_shape(stbtt_vertex * vertices, int num_vertices, int was_off, int start_off,
1862                               stbtt_int32 sx, stbtt_int32 sy, stbtt_int32 scx, stbtt_int32 scy, stbtt_int32 cx, stbtt_int32 cy)
1863 {
1864     if(start_off) {
1865         if(was_off)
1866             stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx + scx) >> 1, (cy + scy) >> 1, cx, cy);
1867         stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, sx, sy, scx, scy);
1868     }
1869     else {
1870         if(was_off)
1871             stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, sx, sy, cx, cy);
1872         else
1873             stbtt_setvertex(&vertices[num_vertices++], STBTT_vline, sx, sy, 0, 0);
1874     }
1875     return num_vertices;
1876 }
1877 
1878 static int stbtt__GetGlyphShapeTT(const stbtt_fontinfo * info, int glyph_index, stbtt_vertex * *pvertices)
1879 {
1880     stbtt_int16 numberOfContours;
1881     stbtt_uint32 endPtsOfContours;
1882 #ifdef STBTT_STREAM_TYPE
1883     STBTT_STREAM_TYPE data = info->data;
1884 #else
1885     stbtt_uint8 * data = info->data;
1886 #endif
1887     stbtt_vertex * vertices = 0;
1888     int num_vertices = 0;
1889     int g = stbtt__GetGlyfOffset(info, glyph_index);
1890 
1891     *pvertices = NULL;
1892 
1893     if(g < 0) return 0;
1894 
1895     numberOfContours = ttSHORT(data, g);
1896 
1897     if(numberOfContours > 0) {
1898         stbtt_uint8 flags = 0, flagcount;
1899         stbtt_int32 ins, i, j = 0, m, n, next_move, was_off = 0, off, start_off = 0;
1900         stbtt_int32 x, y, cx, cy, sx, sy, scx, scy;
1901         stbtt_uint32 points;
1902         endPtsOfContours = (g + 10);
1903         ins = ttUSHORT(data, g + 10 + numberOfContours * 2);
1904         points = g + 10 + numberOfContours * 2 + 2 + ins;
1905 
1906         n = 1 + ttUSHORT(data, endPtsOfContours + numberOfContours * 2 - 2);
1907 
1908         m = n + 2 * numberOfContours;  // a loose bound on how many vertices we might need
1909         vertices = (stbtt_vertex *)STBTT_malloc(m * sizeof(vertices[0]), info->userdata);
1910         if(vertices == 0)
1911             return 0;
1912 
1913         next_move = 0;
1914         flagcount = 0;
1915 
1916         // in first pass, we load uninterpreted data into the allocated array
1917         // above, shifted to the end of the array so we won't overwrite it when
1918         // we create our final data starting from the front
1919 
1920         off = m - n; // starting offset for uninterpreted data, regardless of how m ends up being calculated
1921 
1922         // first load flags
1923 
1924         for(i = 0; i < n; ++i) {
1925             if(flagcount == 0) {
1926                 flags = ttBYTE(data, points++);
1927                 if(flags & 8)
1928                     flagcount = ttBYTE(data, points++);
1929             }
1930             else
1931                 --flagcount;
1932             vertices[off + i].type = flags;
1933         }
1934 
1935         // now load x coordinates
1936         x = 0;
1937         for(i = 0; i < n; ++i) {
1938             flags = vertices[off + i].type;
1939             if(flags & 2) {
1940                 stbtt_int16 dx = ttBYTE(data, points++);
1941                 x += (flags & 16) ? dx : -dx; // ???
1942             }
1943             else {
1944                 if(!(flags & 16)) {
1945                     x = x + (stbtt_int16)(ttBYTE(data, points) * 256 + ttBYTE(data, points + 1));
1946                     points += 2;
1947                 }
1948             }
1949             vertices[off + i].x = (stbtt_int16)x;
1950         }
1951 
1952         // now load y coordinates
1953         y = 0;
1954         for(i = 0; i < n; ++i) {
1955             flags = vertices[off + i].type;
1956             if(flags & 4) {
1957                 stbtt_int16 dy = ttBYTE(data, points++);
1958                 y += (flags & 32) ? dy : -dy; // ???
1959             }
1960             else {
1961                 if(!(flags & 32)) {
1962                     y = y + (stbtt_int16)(ttBYTE(data, points) * 256 + ttBYTE(data, points + 1));
1963                     points += 2;
1964                 }
1965             }
1966             vertices[off + i].y = (stbtt_int16)y;
1967         }
1968 
1969         // now convert them to our format
1970         num_vertices = 0;
1971         sx = sy = cx = cy = scx = scy = 0;
1972         for(i = 0; i < n; ++i) {
1973             flags = vertices[off + i].type;
1974             x = (stbtt_int16)vertices[off + i].x;
1975             y = (stbtt_int16)vertices[off + i].y;
1976 
1977             if(next_move == i) {
1978                 if(i != 0)
1979                     num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx, sy, scx, scy, cx, cy);
1980 
1981                 // now start the new one
1982                 start_off = !(flags & 1);
1983                 if(start_off) {
1984                     // if we start off with an off-curve point, then when we need to find a point on the curve
1985                     // where we can start, and we need to save some state for when we wraparound.
1986                     scx = x;
1987                     scy = y;
1988                     if(!(vertices[off + i + 1].type & 1)) {
1989                         // next point is also a curve point, so interpolate an on-point curve
1990                         sx = (x + (stbtt_int32)vertices[off + i + 1].x) >> 1;
1991                         sy = (y + (stbtt_int32)vertices[off + i + 1].y) >> 1;
1992                     }
1993                     else {
1994                         // otherwise just use the next point as our start point
1995                         sx = (stbtt_int32)vertices[off + i + 1].x;
1996                         sy = (stbtt_int32)vertices[off + i + 1].y;
1997                         ++i; // we're using point i+1 as the starting point, so skip it
1998                     }
1999                 }
2000                 else {
2001                     sx = x;
2002                     sy = y;
2003                 }
2004                 stbtt_setvertex(&vertices[num_vertices++], STBTT_vmove, sx, sy, 0, 0);
2005                 was_off = 0;
2006                 next_move = 1 + ttUSHORT(data, endPtsOfContours + j * 2);
2007                 ++j;
2008             }
2009             else {
2010                 if(!(flags & 1)) {  // if it's a curve
2011                     if(was_off)  // two off-curve control points in a row means interpolate an on-curve midpoint
2012                         stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx + x) >> 1, (cy + y) >> 1, cx, cy);
2013                     cx = x;
2014                     cy = y;
2015                     was_off = 1;
2016                 }
2017                 else {
2018                     if(was_off)
2019                         stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, x, y, cx, cy);
2020                     else
2021                         stbtt_setvertex(&vertices[num_vertices++], STBTT_vline, x, y, 0, 0);
2022                     was_off = 0;
2023                 }
2024             }
2025         }
2026         num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx, sy, scx, scy, cx, cy);
2027     }
2028     else if(numberOfContours < 0) {
2029         // Compound shapes.
2030         int more = 1;
2031         stbtt_uint32 comp = g + 10;
2032         num_vertices = 0;
2033         vertices = 0;
2034         while(more) {
2035             stbtt_uint16 flags, gidx;
2036             int comp_num_verts = 0, i;
2037             stbtt_vertex * comp_verts = 0, * tmp = 0;
2038             float mtx[6] = { 1, 0, 0, 1, 0, 0 }, m, n;
2039 
2040             flags = ttSHORT(data, comp);
2041             comp += 2;
2042             gidx = ttSHORT(data, comp);
2043             comp += 2;
2044 
2045             if(flags & 2) {  // XY values
2046                 if(flags & 1) {  // shorts
2047                     mtx[4] = ttSHORT(data, comp);
2048                     comp += 2;
2049                     mtx[5] = ttSHORT(data, comp);
2050                     comp += 2;
2051                 }
2052                 else {
2053                     mtx[4] = ttCHAR(data, comp);
2054                     comp += 1;
2055                     mtx[5] = ttCHAR(data, comp);
2056                     comp += 1;
2057                 }
2058             }
2059             else {
2060                 // @TODO handle matching point
2061                 STBTT_assert(0);
2062             }
2063             if(flags & (1 << 3)) {  // WE_HAVE_A_SCALE
2064                 mtx[0] = mtx[3] = ttSHORT(data, comp) / 16384.0f;
2065                 comp += 2;
2066                 mtx[1] = mtx[2] = 0;
2067             }
2068             else if(flags & (1 << 6)) {  // WE_HAVE_AN_X_AND_YSCALE
2069                 mtx[0] = ttSHORT(data, comp) / 16384.0f;
2070                 comp += 2;
2071                 mtx[1] = mtx[2] = 0;
2072                 mtx[3] = ttSHORT(data, comp) / 16384.0f;
2073                 comp += 2;
2074             }
2075             else if(flags & (1 << 7)) {  // WE_HAVE_A_TWO_BY_TWO
2076                 mtx[0] = ttSHORT(data, comp) / 16384.0f;
2077                 comp += 2;
2078                 mtx[1] = ttSHORT(data, comp) / 16384.0f;
2079                 comp += 2;
2080                 mtx[2] = ttSHORT(data, comp) / 16384.0f;
2081                 comp += 2;
2082                 mtx[3] = ttSHORT(data, comp) / 16384.0f;
2083                 comp += 2;
2084             }
2085 
2086             // Find transformation scales.
2087             m = (float)STBTT_sqrt(mtx[0] * mtx[0] + mtx[1] * mtx[1]);
2088             n = (float)STBTT_sqrt(mtx[2] * mtx[2] + mtx[3] * mtx[3]);
2089 
2090             // Get indexed glyph.
2091             comp_num_verts = stbtt_GetGlyphShape(info, gidx, &comp_verts);
2092             if(comp_num_verts > 0) {
2093                 // Transform vertices.
2094                 for(i = 0; i < comp_num_verts; ++i) {
2095                     stbtt_vertex * v = &comp_verts[i];
2096                     stbtt_vertex_type x, y;
2097                     x = v->x;
2098                     y = v->y;
2099                     v->x = (stbtt_vertex_type)(m * (mtx[0] * x + mtx[2] * y + mtx[4]));
2100                     v->y = (stbtt_vertex_type)(n * (mtx[1] * x + mtx[3] * y + mtx[5]));
2101                     x = v->cx;
2102                     y = v->cy;
2103                     v->cx = (stbtt_vertex_type)(m * (mtx[0] * x + mtx[2] * y + mtx[4]));
2104                     v->cy = (stbtt_vertex_type)(n * (mtx[1] * x + mtx[3] * y + mtx[5]));
2105                 }
2106                 // Append vertices.
2107                 tmp = (stbtt_vertex *)STBTT_malloc((num_vertices + comp_num_verts) * sizeof(stbtt_vertex), info->userdata);
2108                 if(!tmp) {
2109                     if(vertices) STBTT_free(vertices, info->userdata);
2110                     if(comp_verts) STBTT_free(comp_verts, info->userdata);
2111                     return 0;
2112                 }
2113                 if(num_vertices > 0 && vertices) STBTT_memcpy(tmp, vertices, num_vertices * sizeof(stbtt_vertex));
2114                 STBTT_memcpy(tmp + num_vertices, comp_verts, comp_num_verts * sizeof(stbtt_vertex));
2115                 if(vertices) STBTT_free(vertices, info->userdata);
2116                 vertices = tmp;
2117                 STBTT_free(comp_verts, info->userdata);
2118                 num_vertices += comp_num_verts;
2119             }
2120             // More components ?
2121             more = flags & (1 << 5);
2122         }
2123     }
2124     else {
2125         // numberOfCounters == 0, do nothing
2126     }
2127 
2128     *pvertices = vertices;
2129     return num_vertices;
2130 }
2131 
2132 typedef struct {
2133     int bounds;
2134     int started;
2135     float first_x, first_y;
2136     float x, y;
2137     stbtt_int32 min_x, max_x, min_y, max_y;
2138 
2139     stbtt_vertex * pvertices;
2140     int num_vertices;
2141 } stbtt__csctx;
2142 
2143 #define STBTT__CSCTX_INIT(bounds) {bounds,0, 0,0, 0,0, 0,0,0,0, NULL, 0}
2144 
2145 static void stbtt__track_vertex(stbtt__csctx * c, stbtt_int32 x, stbtt_int32 y)
2146 {
2147     if(x > c->max_x || !c->started) c->max_x = x;
2148     if(y > c->max_y || !c->started) c->max_y = y;
2149     if(x < c->min_x || !c->started) c->min_x = x;
2150     if(y < c->min_y || !c->started) c->min_y = y;
2151     c->started = 1;
2152 }
2153 
2154 static void stbtt__csctx_v(stbtt__csctx * c, stbtt_uint8 type, stbtt_int32 x, stbtt_int32 y, stbtt_int32 cx,
2155                            stbtt_int32 cy, stbtt_int32 cx1, stbtt_int32 cy1)
2156 {
2157     if(c->bounds) {
2158         stbtt__track_vertex(c, x, y);
2159         if(type == STBTT_vcubic) {
2160             stbtt__track_vertex(c, cx, cy);
2161             stbtt__track_vertex(c, cx1, cy1);
2162         }
2163     }
2164     else {
2165         stbtt_setvertex(&c->pvertices[c->num_vertices], type, x, y, cx, cy);
2166         c->pvertices[c->num_vertices].cx1 = (stbtt_int16)cx1;
2167         c->pvertices[c->num_vertices].cy1 = (stbtt_int16)cy1;
2168     }
2169     c->num_vertices++;
2170 }
2171 
2172 static void stbtt__csctx_close_shape(stbtt__csctx * ctx)
2173 {
2174     if(ctx->first_x != ctx->x || ctx->first_y != ctx->y)
2175         stbtt__csctx_v(ctx, STBTT_vline, (int)ctx->first_x, (int)ctx->first_y, 0, 0, 0, 0);
2176 }
2177 
2178 static void stbtt__csctx_rmove_to(stbtt__csctx * ctx, float dx, float dy)
2179 {
2180     stbtt__csctx_close_shape(ctx);
2181     ctx->first_x = ctx->x = ctx->x + dx;
2182     ctx->first_y = ctx->y = ctx->y + dy;
2183     stbtt__csctx_v(ctx, STBTT_vmove, (int)ctx->x, (int)ctx->y, 0, 0, 0, 0);
2184 }
2185 
2186 static void stbtt__csctx_rline_to(stbtt__csctx * ctx, float dx, float dy)
2187 {
2188     ctx->x += dx;
2189     ctx->y += dy;
2190     stbtt__csctx_v(ctx, STBTT_vline, (int)ctx->x, (int)ctx->y, 0, 0, 0, 0);
2191 }
2192 
2193 static void stbtt__csctx_rccurve_to(stbtt__csctx * ctx, float dx1, float dy1, float dx2, float dy2, float dx3,
2194                                     float dy3)
2195 {
2196     float cx1 = ctx->x + dx1;
2197     float cy1 = ctx->y + dy1;
2198     float cx2 = cx1 + dx2;
2199     float cy2 = cy1 + dy2;
2200     ctx->x = cx2 + dx3;
2201     ctx->y = cy2 + dy3;
2202     stbtt__csctx_v(ctx, STBTT_vcubic, (int)ctx->x, (int)ctx->y, (int)cx1, (int)cy1, (int)cx2, (int)cy2);
2203 }
2204 
2205 static stbtt__buf stbtt__get_subr(stbtt__buf idx, int n)
2206 {
2207     int count = stbtt__cff_index_count(&idx);
2208     int bias = 107;
2209     if(count >= 33900)
2210         bias = 32768;
2211     else if(count >= 1240)
2212         bias = 1131;
2213     n += bias;
2214     if(n < 0 || n >= count)
2215         return stbtt__new_buf(NULL, 0);
2216     return stbtt__cff_index_get(idx, n);
2217 }
2218 
2219 static stbtt__buf stbtt__cid_get_glyph_subrs(const stbtt_fontinfo * info, int glyph_index)
2220 {
2221     stbtt__buf fdselect = info->fdselect;
2222     int nranges, start, end, v, fmt, fdselector = -1, i;
2223 
2224     stbtt__buf_seek(&fdselect, 0);
2225     fmt = stbtt__buf_get8(&fdselect);
2226     if(fmt == 0) {
2227         // untested
2228         stbtt__buf_skip(&fdselect, glyph_index);
2229         fdselector = stbtt__buf_get8(&fdselect);
2230     }
2231     else if(fmt == 3) {
2232         nranges = stbtt__buf_get16(&fdselect);
2233         start = stbtt__buf_get16(&fdselect);
2234         for(i = 0; i < nranges; i++) {
2235             v = stbtt__buf_get8(&fdselect);
2236             end = stbtt__buf_get16(&fdselect);
2237             if(glyph_index >= start && glyph_index < end) {
2238                 fdselector = v;
2239                 break;
2240             }
2241             start = end;
2242         }
2243     }
2244     if(fdselector == -1) stbtt__new_buf(NULL, 0);
2245     return stbtt__get_subrs(info->cff, stbtt__cff_index_get(info->fontdicts, fdselector));
2246 }
2247 
2248 static int stbtt__run_charstring(const stbtt_fontinfo * info, int glyph_index, stbtt__csctx * c)
2249 {
2250     int in_header = 1, maskbits = 0, subr_stack_height = 0, sp = 0, v, i, b0;
2251     int has_subrs = 0, clear_stack;
2252     float s[48];
2253     stbtt__buf subr_stack[10], subrs = info->subrs, b;
2254     float f;
2255 
2256 #define STBTT__CSERR(s) (0)
2257 
2258     // this currently ignores the initial width value, which isn't needed if we have hmtx
2259     b = stbtt__cff_index_get(info->charstrings, glyph_index);
2260     while(b.cursor < b.size) {
2261         i = 0;
2262         clear_stack = 1;
2263         b0 = stbtt__buf_get8(&b);
2264         switch(b0) {
2265             // @TODO implement hinting
2266             case 0x13: // hintmask
2267             case 0x14: // cntrmask
2268                 if(in_header)
2269                     maskbits += (sp / 2); // implicit "vstem"
2270                 in_header = 0;
2271                 stbtt__buf_skip(&b, (maskbits + 7) / 8);
2272                 break;
2273 
2274             case 0x01: // hstem
2275             case 0x03: // vstem
2276             case 0x12: // hstemhm
2277             case 0x17: // vstemhm
2278                 maskbits += (sp / 2);
2279                 break;
2280 
2281             case 0x15: // rmoveto
2282                 in_header = 0;
2283                 if(sp < 2) return STBTT__CSERR("rmoveto stack");
2284                 stbtt__csctx_rmove_to(c, s[sp - 2], s[sp - 1]);
2285                 break;
2286             case 0x04: // vmoveto
2287                 in_header = 0;
2288                 if(sp < 1) return STBTT__CSERR("vmoveto stack");
2289                 stbtt__csctx_rmove_to(c, 0, s[sp - 1]);
2290                 break;
2291             case 0x16: // hmoveto
2292                 in_header = 0;
2293                 if(sp < 1) return STBTT__CSERR("hmoveto stack");
2294                 stbtt__csctx_rmove_to(c, s[sp - 1], 0);
2295                 break;
2296 
2297             case 0x05: // rlineto
2298                 if(sp < 2) return STBTT__CSERR("rlineto stack");
2299                 for(; i + 1 < sp; i += 2)
2300                     stbtt__csctx_rline_to(c, s[i], s[i + 1]);
2301                 break;
2302 
2303             // hlineto/vlineto and vhcurveto/hvcurveto alternate horizontal and vertical
2304             // starting from a different place.
2305 
2306             case 0x07: // vlineto
2307                 if(sp < 1) return STBTT__CSERR("vlineto stack");
2308                 goto vlineto;
2309             case 0x06: // hlineto
2310                 if(sp < 1) return STBTT__CSERR("hlineto stack");
2311                 for(;;) {
2312                     if(i >= sp) break;
2313                     stbtt__csctx_rline_to(c, s[i], 0);
2314                     i++;
2315 vlineto:
2316                     if(i >= sp) break;
2317                     stbtt__csctx_rline_to(c, 0, s[i]);
2318                     i++;
2319                 }
2320                 break;
2321 
2322             case 0x1F: // hvcurveto
2323                 if(sp < 4) return STBTT__CSERR("hvcurveto stack");
2324                 goto hvcurveto;
2325             case 0x1E: // vhcurveto
2326                 if(sp < 4) return STBTT__CSERR("vhcurveto stack");
2327                 for(;;) {
2328                     if(i + 3 >= sp) break;
2329                     stbtt__csctx_rccurve_to(c, 0, s[i], s[i + 1], s[i + 2], s[i + 3], (sp - i == 5) ? s[i + 4] : 0.0f);
2330                     i += 4;
2331 hvcurveto:
2332                     if(i + 3 >= sp) break;
2333                     stbtt__csctx_rccurve_to(c, s[i], 0, s[i + 1], s[i + 2], (sp - i == 5) ? s[i + 4] : 0.0f, s[i + 3]);
2334                     i += 4;
2335                 }
2336                 break;
2337 
2338             case 0x08: // rrcurveto
2339                 if(sp < 6) return STBTT__CSERR("rcurveline stack");
2340                 for(; i + 5 < sp; i += 6)
2341                     stbtt__csctx_rccurve_to(c, s[i], s[i + 1], s[i + 2], s[i + 3], s[i + 4], s[i + 5]);
2342                 break;
2343 
2344             case 0x18: // rcurveline
2345                 if(sp < 8) return STBTT__CSERR("rcurveline stack");
2346                 for(; i + 5 < sp - 2; i += 6)
2347                     stbtt__csctx_rccurve_to(c, s[i], s[i + 1], s[i + 2], s[i + 3], s[i + 4], s[i + 5]);
2348                 if(i + 1 >= sp) return STBTT__CSERR("rcurveline stack");
2349                 stbtt__csctx_rline_to(c, s[i], s[i + 1]);
2350                 break;
2351 
2352             case 0x19: // rlinecurve
2353                 if(sp < 8) return STBTT__CSERR("rlinecurve stack");
2354                 for(; i + 1 < sp - 6; i += 2)
2355                     stbtt__csctx_rline_to(c, s[i], s[i + 1]);
2356                 if(i + 5 >= sp) return STBTT__CSERR("rlinecurve stack");
2357                 stbtt__csctx_rccurve_to(c, s[i], s[i + 1], s[i + 2], s[i + 3], s[i + 4], s[i + 5]);
2358                 break;
2359 
2360             case 0x1A: // vvcurveto
2361             case 0x1B: // hhcurveto
2362                 if(sp < 4) return STBTT__CSERR("(vv|hh)curveto stack");
2363                 f = 0.0;
2364                 if(sp & 1) {
2365                     f = s[i];
2366                     i++;
2367                 }
2368                 for(; i + 3 < sp; i += 4) {
2369                     if(b0 == 0x1B)
2370                         stbtt__csctx_rccurve_to(c, s[i], f, s[i + 1], s[i + 2], s[i + 3], 0.0);
2371                     else
2372                         stbtt__csctx_rccurve_to(c, f, s[i], s[i + 1], s[i + 2], 0.0, s[i + 3]);
2373                     f = 0.0;
2374                 }
2375                 break;
2376 
2377             case 0x0A: // callsubr
2378                 if(!has_subrs) {
2379                     if(info->fdselect.size)
2380                         subrs = stbtt__cid_get_glyph_subrs(info, glyph_index);
2381                     has_subrs = 1;
2382                 }
2383             // FALLTHROUGH
2384             case 0x1D: // callgsubr
2385                 if(sp < 1) return STBTT__CSERR("call(g|)subr stack");
2386                 v = (int)s[--sp];
2387                 if(subr_stack_height >= 10) return STBTT__CSERR("recursion limit");
2388                 subr_stack[subr_stack_height++] = b;
2389                 b = stbtt__get_subr(b0 == 0x0A ? subrs : info->gsubrs, v);
2390                 if(b.size == 0) return STBTT__CSERR("subr not found");
2391                 b.cursor = 0;
2392                 clear_stack = 0;
2393                 break;
2394 
2395             case 0x0B: // return
2396                 if(subr_stack_height <= 0) return STBTT__CSERR("return outside subr");
2397                 b = subr_stack[--subr_stack_height];
2398                 clear_stack = 0;
2399                 break;
2400 
2401             case 0x0E: // endchar
2402                 stbtt__csctx_close_shape(c);
2403                 return 1;
2404 
2405             case 0x0C: { // two-byte escape
2406                     float dx1, dx2, dx3, dx4, dx5, dx6, dy1, dy2, dy3, dy4, dy5, dy6;
2407                     float dx, dy;
2408                     int b1 = stbtt__buf_get8(&b);
2409                     switch(b1) {
2410                         // @TODO These "flex" implementations ignore the flex-depth and resolution,
2411                         // and always draw beziers.
2412                         case 0x22: // hflex
2413                             if(sp < 7) return STBTT__CSERR("hflex stack");
2414                             dx1 = s[0];
2415                             dx2 = s[1];
2416                             dy2 = s[2];
2417                             dx3 = s[3];
2418                             dx4 = s[4];
2419                             dx5 = s[5];
2420                             dx6 = s[6];
2421                             stbtt__csctx_rccurve_to(c, dx1, 0, dx2, dy2, dx3, 0);
2422                             stbtt__csctx_rccurve_to(c, dx4, 0, dx5, -dy2, dx6, 0);
2423                             break;
2424 
2425                         case 0x23: // flex
2426                             if(sp < 13) return STBTT__CSERR("flex stack");
2427                             dx1 = s[0];
2428                             dy1 = s[1];
2429                             dx2 = s[2];
2430                             dy2 = s[3];
2431                             dx3 = s[4];
2432                             dy3 = s[5];
2433                             dx4 = s[6];
2434                             dy4 = s[7];
2435                             dx5 = s[8];
2436                             dy5 = s[9];
2437                             dx6 = s[10];
2438                             dy6 = s[11];
2439                             //fd is s[12]
2440                             stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, dy3);
2441                             stbtt__csctx_rccurve_to(c, dx4, dy4, dx5, dy5, dx6, dy6);
2442                             break;
2443 
2444                         case 0x24: // hflex1
2445                             if(sp < 9) return STBTT__CSERR("hflex1 stack");
2446                             dx1 = s[0];
2447                             dy1 = s[1];
2448                             dx2 = s[2];
2449                             dy2 = s[3];
2450                             dx3 = s[4];
2451                             dx4 = s[5];
2452                             dx5 = s[6];
2453                             dy5 = s[7];
2454                             dx6 = s[8];
2455                             stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, 0);
2456                             stbtt__csctx_rccurve_to(c, dx4, 0, dx5, dy5, dx6, -(dy1 + dy2 + dy5));
2457                             break;
2458 
2459                         case 0x25: // flex1
2460                             if(sp < 11) return STBTT__CSERR("flex1 stack");
2461                             dx1 = s[0];
2462                             dy1 = s[1];
2463                             dx2 = s[2];
2464                             dy2 = s[3];
2465                             dx3 = s[4];
2466                             dy3 = s[5];
2467                             dx4 = s[6];
2468                             dy4 = s[7];
2469                             dx5 = s[8];
2470                             dy5 = s[9];
2471                             dx6 = dy6 = s[10];
2472                             dx = dx1 + dx2 + dx3 + dx4 + dx5;
2473                             dy = dy1 + dy2 + dy3 + dy4 + dy5;
2474                             if(STBTT_fabs(dx) > STBTT_fabs(dy))
2475                                 dy6 = -dy;
2476                             else
2477                                 dx6 = -dx;
2478                             stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, dy3);
2479                             stbtt__csctx_rccurve_to(c, dx4, dy4, dx5, dy5, dx6, dy6);
2480                             break;
2481 
2482                         default:
2483                             return STBTT__CSERR("unimplemented");
2484                     }
2485                 }
2486                 break;
2487 
2488             default:
2489                 if(b0 != 255 && b0 != 28 && b0 < 32)
2490                     return STBTT__CSERR("reserved operator");
2491 
2492                 // push immediate
2493                 if(b0 == 255) {
2494                     f = (float)(stbtt_int32)stbtt__buf_get32(&b) / 0x10000;
2495                 }
2496                 else {
2497                     stbtt__buf_skip(&b, -1);
2498                     f = (float)(stbtt_int16)stbtt__cff_int(&b);
2499                 }
2500                 if(sp >= 48) return STBTT__CSERR("push stack overflow");
2501                 s[sp++] = f;
2502                 clear_stack = 0;
2503                 break;
2504         }
2505         if(clear_stack) sp = 0;
2506     }
2507     return STBTT__CSERR("no endchar");
2508 
2509 #undef STBTT__CSERR
2510 }
2511 
2512 static int stbtt__GetGlyphShapeT2(const stbtt_fontinfo * info, int glyph_index, stbtt_vertex * *pvertices)
2513 {
2514     // runs the charstring twice, once to count and once to output (to avoid realloc)
2515     stbtt__csctx count_ctx = STBTT__CSCTX_INIT(1);
2516     stbtt__csctx output_ctx = STBTT__CSCTX_INIT(0);
2517     if(stbtt__run_charstring(info, glyph_index, &count_ctx)) {
2518         *pvertices = (stbtt_vertex *)STBTT_malloc(count_ctx.num_vertices * sizeof(stbtt_vertex), info->userdata);
2519         output_ctx.pvertices = *pvertices;
2520         if(stbtt__run_charstring(info, glyph_index, &output_ctx)) {
2521             STBTT_assert(output_ctx.num_vertices == count_ctx.num_vertices);
2522             return output_ctx.num_vertices;
2523         }
2524     }
2525     *pvertices = NULL;
2526     return 0;
2527 }
2528 
2529 static int stbtt__GetGlyphInfoT2(const stbtt_fontinfo * info, int glyph_index, int * x0, int * y0, int * x1, int * y1)
2530 {
2531     stbtt__csctx c = STBTT__CSCTX_INIT(1);
2532     int r = stbtt__run_charstring(info, glyph_index, &c);
2533     if(x0)  *x0 = r ? c.min_x : 0;
2534     if(y0)  *y0 = r ? c.min_y : 0;
2535     if(x1)  *x1 = r ? c.max_x : 0;
2536     if(y1)  *y1 = r ? c.max_y : 0;
2537     return r ? c.num_vertices : 0;
2538 }
2539 
2540 STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo * info, int glyph_index, stbtt_vertex * *pvertices)
2541 {
2542     if(!info->cff.size)
2543         return stbtt__GetGlyphShapeTT(info, glyph_index, pvertices);
2544     else
2545         return stbtt__GetGlyphShapeT2(info, glyph_index, pvertices);
2546 }
2547 
2548 STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo * info, int glyph_index, int * advanceWidth,
2549                                       int * leftSideBearing)
2550 {
2551     stbtt_uint16 numOfLongHorMetrics = ttUSHORT(info->data, info->hhea + 34);
2552     if(glyph_index < numOfLongHorMetrics) {
2553         if(advanceWidth)     *advanceWidth = ttSHORT(info->data, info->hmtx + 4 * glyph_index);
2554         if(leftSideBearing)  *leftSideBearing = ttSHORT(info->data, info->hmtx + 4 * glyph_index + 2);
2555     }
2556     else {
2557         if(advanceWidth)     *advanceWidth = ttSHORT(info->data, info->hmtx + 4 * (numOfLongHorMetrics - 1));
2558         if(leftSideBearing)  *leftSideBearing = ttSHORT(info->data,
2559                                                             info->hmtx + 4 * numOfLongHorMetrics + 2 * (glyph_index - numOfLongHorMetrics));
2560     }
2561 }
2562 
2563 STBTT_DEF int  stbtt_GetKerningTableLength(const stbtt_fontinfo * info)
2564 {
2565     // we only look at the first table. it must be 'horizontal' and format 0.
2566     if(!info->kern)
2567         return 0;
2568     if(ttUSHORT(info->data, 2 + info->kern) < 1)  // number of tables, need at least 1
2569         return 0;
2570     if(ttUSHORT(info->data, 8 + info->kern) != 1)  // horizontal flag must be set in format
2571         return 0;
2572 
2573     return ttUSHORT(info->data, 10 + info->kern);
2574 }
2575 
2576 STBTT_DEF int stbtt_GetKerningTable(const stbtt_fontinfo * info, stbtt_kerningentry * table, int table_length)
2577 {
2578     int k, length;
2579 
2580     // we only look at the first table. it must be 'horizontal' and format 0.
2581     if(!info->kern)
2582         return 0;
2583     if(ttUSHORT(info->data, 2 + info->kern) < 1)  // number of tables, need at least 1
2584         return 0;
2585     if(ttUSHORT(info->data, 8 + info->kern) != 1)  // horizontal flag must be set in format
2586         return 0;
2587 
2588     length = ttUSHORT(info->data, 10 + info->kern);
2589     if(table_length < length)
2590         length = table_length;
2591 
2592     for(k = 0; k < length; k++) {
2593         table[k].glyph1 = ttUSHORT(info->data, 18 + (k * 6) + info->kern);
2594         table[k].glyph2 = ttUSHORT(info->data, 20 + (k * 6) + info->kern);
2595         table[k].advance = ttSHORT(info->data, 22 + (k * 6) + info->kern);
2596     }
2597 
2598     return length;
2599 }
2600 
2601 static int stbtt__GetGlyphKernInfoAdvance(const stbtt_fontinfo * info, int glyph1, int glyph2)
2602 {
2603     stbtt_uint32 needle, straw;
2604     int l, r, m;
2605 
2606     // we only look at the first table. it must be 'horizontal' and format 0.
2607     if(!info->kern)
2608         return 0;
2609     if(ttUSHORT(info->data, info->kern + 2) < 1)  // number of tables, need at least 1
2610         return 0;
2611     if(ttUSHORT(info->data, info->kern + 8) != 1)  // horizontal flag must be set in format
2612         return 0;
2613 
2614     l = 0;
2615     r = ttUSHORT(info->data, info->kern + 10) - 1;
2616     needle = glyph1 << 16 | glyph2;
2617     while(l <= r) {
2618         m = (l + r) >> 1;
2619         straw = ttULONG(info->data, info->kern + 18 + (m * 6)); // note: unaligned read
2620         if(needle < straw)
2621             r = m - 1;
2622         else if(needle > straw)
2623             l = m + 1;
2624         else
2625             return ttSHORT(info->data, info->kern + 22 + (m * 6));
2626     }
2627     return 0;
2628 }
2629 #ifdef STBTT_STREAM_TYPE
2630     static stbtt_int32 stbtt__GetCoverageIndex(STBTT_STREAM_TYPE data, stbtt_uint32 coverageTable, int glyph)
2631 #else
2632     static stbtt_int32 stbtt__GetCoverageIndex(const stbtt_uint8 * data, stbtt_uint32 coverageTable, int glyph)
2633 #endif
2634 {
2635     stbtt_uint16 coverageFormat = ttUSHORT(data, coverageTable);
2636     switch(coverageFormat) {
2637         case 1: {
2638                 stbtt_uint16 glyphCount = ttUSHORT(data, coverageTable + 2);
2639 
2640                 // Binary search.
2641                 stbtt_int32 l = 0, r = glyphCount - 1, m;
2642                 int straw, needle = glyph;
2643                 while(l <= r) {
2644                     stbtt_uint32 glyphArray = coverageTable + 4;
2645                     stbtt_uint16 glyphID;
2646                     m = (l + r) >> 1;
2647                     glyphID = ttUSHORT(data, glyphArray + 2 * m);
2648                     straw = glyphID;
2649                     if(needle < straw)
2650                         r = m - 1;
2651                     else if(needle > straw)
2652                         l = m + 1;
2653                     else {
2654                         return m;
2655                     }
2656                 }
2657                 break;
2658             }
2659 
2660         case 2: {
2661                 stbtt_uint16 rangeCount = ttUSHORT(data, coverageTable + 2);
2662                 stbtt_uint32 rangeArray = coverageTable + 4;
2663 
2664                 // Binary search.
2665                 stbtt_int32 l = 0, r = rangeCount - 1, m;
2666                 int strawStart, strawEnd, needle = glyph;
2667                 while(l <= r) {
2668                     stbtt_uint32 rangeRecord;
2669                     m = (l + r) >> 1;
2670                     rangeRecord = rangeArray + 6 * m;
2671                     strawStart = ttUSHORT(data, rangeRecord);
2672                     strawEnd = ttUSHORT(data, rangeRecord + 2);
2673                     if(needle < strawStart)
2674                         r = m - 1;
2675                     else if(needle > strawEnd)
2676                         l = m + 1;
2677                     else {
2678                         stbtt_uint16 startCoverageIndex = ttUSHORT(data, rangeRecord + 4);
2679                         return startCoverageIndex + glyph - strawStart;
2680                     }
2681                 }
2682                 break;
2683             }
2684 
2685         default:
2686             return -1; // unsupported
2687     }
2688 
2689     return -1;
2690 }
2691 #ifdef STBTT_STREAM_TYPE
2692     static stbtt_int32  stbtt__GetGlyphClass(STBTT_STREAM_TYPE data, stbtt_uint32 classDefTable, int glyph)
2693 #else
2694     static stbtt_int32  stbtt__GetGlyphClass(const stbtt_uint8 * data, stbtt_uint32 classDefTable, int glyph)
2695 #endif
2696 {
2697     stbtt_uint16 classDefFormat = ttUSHORT(data, classDefTable);
2698     switch(classDefFormat) {
2699         case 1: {
2700                 stbtt_uint16 startGlyphID = ttUSHORT(data, classDefTable + 2);
2701                 stbtt_uint16 glyphCount = ttUSHORT(data, classDefTable + 4);
2702                 stbtt_uint32 classDef1ValueArray = classDefTable + 6;
2703 
2704                 if(glyph >= startGlyphID && glyph < startGlyphID + glyphCount)
2705                     return (stbtt_int32)ttUSHORT(data, classDef1ValueArray + 2 * (glyph - startGlyphID));
2706                 break;
2707             }
2708 
2709         case 2: {
2710                 stbtt_uint16 classRangeCount = ttUSHORT(data, classDefTable + 2);
2711                 stbtt_uint32 classRangeRecords = classDefTable + 4;
2712 
2713                 // Binary search.
2714                 stbtt_int32 l = 0, r = classRangeCount - 1, m;
2715                 int strawStart, strawEnd, needle = glyph;
2716                 while(l <= r) {
2717                     stbtt_uint32 classRangeRecord;
2718                     m = (l + r) >> 1;
2719                     classRangeRecord = classRangeRecords + 6 * m;
2720                     strawStart = ttUSHORT(data, classRangeRecord);
2721                     strawEnd = ttUSHORT(data, classRangeRecord + 2);
2722                     if(needle < strawStart)
2723                         r = m - 1;
2724                     else if(needle > strawEnd)
2725                         l = m + 1;
2726                     else
2727                         return (stbtt_int32)ttUSHORT(data, classRangeRecord + 4);
2728                 }
2729                 break;
2730             }
2731 
2732         default:
2733             return -1; // Unsupported definition type, return an error.
2734     }
2735 
2736     // "All glyphs not assigned to a class fall into class 0". (OpenType spec)
2737     return 0;
2738 }
2739 
2740 // Define to STBTT_assert(x) if you want to break on unimplemented formats.
2741 #define STBTT_GPOS_TODO_assert(x)
2742 
2743 static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo * info, int glyph1, int glyph2)
2744 {
2745     stbtt_uint16 lookupListOffset;
2746     stbtt_uint32 lookupList;
2747     stbtt_uint16 lookupCount;
2748 #ifdef STBTT_STREAM_TYPE
2749     STBTT_STREAM_TYPE data = info->data;
2750 #else
2751     const stbtt_uint8 * data = info->data;
2752 #endif
2753     stbtt_int32 i, sti;
2754 
2755     if(!info->gpos) return 0;
2756 
2757     if(ttUSHORT(data, 0 + info->gpos) != 1) return 0;  // Major version 1
2758     if(ttUSHORT(data, 2 + info->gpos) != 0) return 0;  // Minor version 0
2759 
2760     lookupListOffset = ttUSHORT(data, 8 + info->gpos);
2761     lookupList = lookupListOffset;
2762     lookupCount = ttUSHORT(data, lookupList);
2763 
2764     for(i = 0; i < lookupCount; ++i) {
2765         stbtt_uint16 lookupOffset = ttUSHORT(data, lookupList + 2 + 2 * i);
2766         stbtt_uint32 lookupTable = lookupList + lookupOffset;
2767 
2768         stbtt_uint16 lookupType = ttUSHORT(data, lookupTable);
2769         stbtt_uint16 subTableCount = ttUSHORT(data, lookupTable + 4);
2770         stbtt_uint32 subTableOffsets = lookupTable + 6;
2771         if(lookupType != 2)  // Pair Adjustment Positioning Subtable
2772             continue;
2773 
2774         for(sti = 0; sti < subTableCount; sti++) {
2775             stbtt_uint16 subtableOffset = ttUSHORT(data, subTableOffsets + 2 * sti);
2776             stbtt_uint32 table = lookupTable + subtableOffset;
2777             stbtt_uint16 posFormat = ttUSHORT(data, table);
2778             stbtt_uint16 coverageOffset = ttUSHORT(data, table + 2);
2779             stbtt_int32 coverageIndex = stbtt__GetCoverageIndex(data, table + coverageOffset, glyph1);
2780             if(coverageIndex == -1) continue;
2781 
2782             switch(posFormat) {
2783                 case 1: {
2784                         stbtt_int32 l, r, m;
2785                         int straw, needle;
2786                         stbtt_uint16 valueFormat1 = ttUSHORT(data, table + 4);
2787                         stbtt_uint16 valueFormat2 = ttUSHORT(data, table + 6);
2788                         if(valueFormat1 == 4 && valueFormat2 == 0) {  // Support more formats?
2789                             stbtt_int32 valueRecordPairSizeInBytes = 2;
2790                             stbtt_uint16 pairSetCount = ttUSHORT(data, table + 8);
2791                             stbtt_uint16 pairPosOffset = ttUSHORT(data, table + 10 + 2 * coverageIndex);
2792                             stbtt_uint32 pairValueTable = table + pairPosOffset;
2793                             stbtt_uint16 pairValueCount = ttUSHORT(data, pairValueTable);
2794                             stbtt_uint32 pairValueArray = pairValueTable + 2;
2795 
2796                             if(coverageIndex >= pairSetCount) return 0;
2797 
2798                             needle = glyph2;
2799                             r = pairValueCount - 1;
2800                             l = 0;
2801 
2802                             // Binary search.
2803                             while(l <= r) {
2804                                 stbtt_uint16 secondGlyph;
2805                                 stbtt_uint32 pairValue;
2806                                 m = (l + r) >> 1;
2807                                 pairValue = pairValueArray + (2 + valueRecordPairSizeInBytes) * m;
2808                                 secondGlyph = ttUSHORT(data, pairValue);
2809                                 straw = secondGlyph;
2810                                 if(needle < straw)
2811                                     r = m - 1;
2812                                 else if(needle > straw)
2813                                     l = m + 1;
2814                                 else {
2815                                     stbtt_int16 xAdvance = ttSHORT(data, pairValue + 2);
2816                                     return xAdvance;
2817                                 }
2818                             }
2819                         }
2820                         else
2821                             return 0;
2822                         break;
2823                     }
2824 
2825                 case 2: {
2826                         stbtt_uint16 valueFormat1 = ttUSHORT(data, table + 4);
2827                         stbtt_uint16 valueFormat2 = ttUSHORT(data, table + 6);
2828                         if(valueFormat1 == 4 && valueFormat2 == 0) {  // Support more formats?
2829                             stbtt_uint16 classDef1Offset = ttUSHORT(data, table + 8);
2830                             stbtt_uint16 classDef2Offset = ttUSHORT(data, table + 10);
2831                             int glyph1class = stbtt__GetGlyphClass(data, table + classDef1Offset, glyph1);
2832                             int glyph2class = stbtt__GetGlyphClass(data, table + classDef2Offset, glyph2);
2833 
2834                             stbtt_uint16 class1Count = ttUSHORT(data, table + 12);
2835                             stbtt_uint16 class2Count = ttUSHORT(data, table + 14);
2836                             stbtt_uint32 class1Records, class2Records;
2837                             stbtt_int16 xAdvance;
2838 
2839                             if(glyph1class < 0 || glyph1class >= class1Count) return 0;  // malformed
2840                             if(glyph2class < 0 || glyph2class >= class2Count) return 0;  // malformed
2841 
2842                             class1Records = table + 16;
2843                             class2Records = class1Records + 2 * (glyph1class * class2Count);
2844                             xAdvance = ttSHORT(data, class2Records + 2 * glyph2class);
2845                             return xAdvance;
2846                         }
2847                         else
2848                             return 0;
2849                         break;
2850                     }
2851 
2852                 default:
2853                     return 0; // Unsupported position format
2854             }
2855         }
2856     }
2857 
2858     return 0;
2859 }
2860 
2861 STBTT_DEF int  stbtt_GetGlyphKernAdvance(const stbtt_fontinfo * info, int g1, int g2)
2862 {
2863     int xAdvance = 0;
2864 
2865     if(info->gpos)
2866         xAdvance += stbtt__GetGlyphGPOSInfoAdvance(info, g1, g2);
2867     else if(info->kern)
2868         xAdvance += stbtt__GetGlyphKernInfoAdvance(info, g1, g2);
2869 
2870     return xAdvance;
2871 }
2872 
2873 STBTT_DEF int  stbtt_GetCodepointKernAdvance(const stbtt_fontinfo * info, int ch1, int ch2)
2874 {
2875     if(!info->kern && !info->gpos)  // if no kerning table, don't waste time looking up both codepoint->glyphs
2876         return 0;
2877     return stbtt_GetGlyphKernAdvance(info, stbtt_FindGlyphIndex(info, ch1), stbtt_FindGlyphIndex(info, ch2));
2878 }
2879 
2880 STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo * info, int codepoint, int * advanceWidth,
2881                                           int * leftSideBearing)
2882 {
2883     stbtt_GetGlyphHMetrics(info, stbtt_FindGlyphIndex(info, codepoint), advanceWidth, leftSideBearing);
2884 }
2885 
2886 STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo * info, int * ascent, int * descent, int * lineGap)
2887 {
2888     if(ascent) *ascent = ttSHORT(info->data, info->hhea + 4);
2889     if(descent) *descent = ttSHORT(info->data, info->hhea + 6);
2890     if(lineGap) *lineGap = ttSHORT(info->data, info->hhea + 8);
2891 }
2892 
2893 STBTT_DEF int  stbtt_GetFontVMetricsOS2(const stbtt_fontinfo * info, int * typoAscent, int * typoDescent,
2894                                         int * typoLineGap)
2895 {
2896     int tab = stbtt__find_table(info->data, info->fontstart, "OS/2");
2897     if(!tab)
2898         return 0;
2899     if(typoAscent) *typoAscent = ttSHORT(info->data, tab + 68);
2900     if(typoDescent) *typoDescent = ttSHORT(info->data, tab + 70);
2901     if(typoLineGap) *typoLineGap = ttSHORT(info->data, tab + 72);
2902     return 1;
2903 }
2904 
2905 STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo * info, int * x0, int * y0, int * x1, int * y1)
2906 {
2907     *x0 = ttSHORT(info->data, info->head + 36);
2908     *y0 = ttSHORT(info->data, info->head + 38);
2909     *x1 = ttSHORT(info->data, info->head + 40);
2910     *y1 = ttSHORT(info->data, info->head + 42);
2911 }
2912 
2913 STBTT_DEF float stbtt_ScaleForPixelHeight(const stbtt_fontinfo * info, float height)
2914 {
2915     int fheight = ttSHORT(info->data, info->hhea + 4) - ttSHORT(info->data, info->hhea + 6);
2916     return (float)height / fheight;
2917 }
2918 
2919 STBTT_DEF float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo * info, float pixels)
2920 {
2921     int unitsPerEm = ttUSHORT(info->data, info->head + 18);
2922     return pixels / unitsPerEm;
2923 }
2924 
2925 STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo * info, stbtt_vertex * v)
2926 {
2927     STBTT_free(v, info->userdata);
2928 }
2929 
2930 STBTT_DEF stbtt_uint32 stbtt_FindSVGDoc(const stbtt_fontinfo * info, int gl)
2931 {
2932     int i;
2933     stbtt_uint32 svg_doc_list = stbtt__get_svg((stbtt_fontinfo *)info);
2934 
2935     int numEntries = ttUSHORT(info->data, svg_doc_list);
2936     stbtt_uint32 svg_docs = svg_doc_list + 2;
2937 
2938     for(i = 0; i < numEntries; i++) {
2939         stbtt_uint32 svg_doc = svg_docs + (12 * i);
2940         if((gl >= ttUSHORT(info->data, svg_doc)) && (gl <= ttUSHORT(info->data, svg_doc + 2)))
2941             return svg_doc;
2942     }
2943     return 0;
2944 }
2945 
2946 STBTT_DEF int stbtt_GetGlyphSVG(const stbtt_fontinfo * info, int gl, stbtt_uint32 * svgOfs)
2947 {
2948     stbtt_uint32 svg_doc;
2949 
2950     if(info->svg == 0)
2951         return 0;
2952 
2953     svg_doc = stbtt_FindSVGDoc(info, gl);
2954     if(svg_doc != 0) {
2955         *svgOfs = info->svg + ttULONG(info->data, svg_doc + 4);
2956         return ttULONG(info->data, svg_doc + 8);
2957     }
2958     else {
2959         return 0;
2960     }
2961 }
2962 
2963 STBTT_DEF int stbtt_GetCodepointSVG(const stbtt_fontinfo * info, int unicode_codepoint, stbtt_uint32 * svgOfs)
2964 {
2965     return stbtt_GetGlyphSVG(info, stbtt_FindGlyphIndex(info, unicode_codepoint), svgOfs);
2966 }
2967 
2968 //////////////////////////////////////////////////////////////////////////////
2969 //
2970 // antialiasing software rasterizer
2971 //
2972 
2973 STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo * font, int glyph, float scale_x, float scale_y,
2974                                                float shift_x, float shift_y, int * ix0, int * iy0, int * ix1, int * iy1)
2975 {
2976     int x0 = 0, y0 = 0, x1, y1; // =0 suppresses compiler warning
2977     if(!stbtt_GetGlyphBox(font, glyph, &x0, &y0, &x1, &y1)) {
2978         // e.g. space character
2979         if(ix0) *ix0 = 0;
2980         if(iy0) *iy0 = 0;
2981         if(ix1) *ix1 = 0;
2982         if(iy1) *iy1 = 0;
2983     }
2984     else {
2985         // move to integral bboxes (treating pixels as little squares, what pixels get touched)?
2986         if(ix0) *ix0 = STBTT_ifloor(x0 * scale_x + shift_x);
2987         if(iy0) *iy0 = STBTT_ifloor(-y1 * scale_y + shift_y);
2988         if(ix1) *ix1 = STBTT_iceil(x1 * scale_x + shift_x);
2989         if(iy1) *iy1 = STBTT_iceil(-y0 * scale_y + shift_y);
2990     }
2991 }
2992 
2993 STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo * font, int glyph, float scale_x, float scale_y, int * ix0,
2994                                        int * iy0, int * ix1, int * iy1)
2995 {
2996     stbtt_GetGlyphBitmapBoxSubpixel(font, glyph, scale_x, scale_y, 0.0f, 0.0f, ix0, iy0, ix1, iy1);
2997 }
2998 
2999 STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo * font, int codepoint, float scale_x,
3000                                                    float scale_y, float shift_x, float shift_y, int * ix0, int * iy0, int * ix1, int * iy1)
3001 {
3002     stbtt_GetGlyphBitmapBoxSubpixel(font, stbtt_FindGlyphIndex(font, codepoint), scale_x, scale_y, shift_x, shift_y, ix0,
3003                                     iy0, ix1, iy1);
3004 }
3005 
3006 STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo * font, int codepoint, float scale_x, float scale_y,
3007                                            int * ix0, int * iy0, int * ix1, int * iy1)
3008 {
3009     stbtt_GetCodepointBitmapBoxSubpixel(font, codepoint, scale_x, scale_y, 0.0f, 0.0f, ix0, iy0, ix1, iy1);
3010 }
3011 
3012 //////////////////////////////////////////////////////////////////////////////
3013 //
3014 //  Rasterizer
3015 
3016 typedef struct stbtt__hheap_chunk {
3017     struct stbtt__hheap_chunk * next;
3018 } stbtt__hheap_chunk;
3019 
3020 typedef struct stbtt__hheap {
3021     struct stbtt__hheap_chunk * head;
3022     void * first_free;
3023     int    num_remaining_in_head_chunk;
3024 } stbtt__hheap;
3025 
3026 static void * stbtt__hheap_alloc(stbtt__hheap * hh, size_t size, void * userdata)
3027 {
3028     if(hh->first_free) {
3029         void * p = hh->first_free;
3030         hh->first_free = *(void **)p;
3031         return p;
3032     }
3033     else {
3034         if(hh->num_remaining_in_head_chunk == 0) {
3035             int count = (size < 32 ? STBTT_HEAP_FACTOR_SIZE_32 : size < 128 ? STBTT_HEAP_FACTOR_SIZE_128 :
3036                          STBTT_HEAP_FACTOR_SIZE_DEFAULT);
3037             stbtt__hheap_chunk * c = (stbtt__hheap_chunk *)STBTT_malloc(sizeof(stbtt__hheap_chunk) + size * count, userdata);
3038             if(c == NULL)
3039                 return NULL;
3040             c->next = hh->head;
3041             hh->head = c;
3042             hh->num_remaining_in_head_chunk = count;
3043         }
3044         --hh->num_remaining_in_head_chunk;
3045         return (char *)(hh->head) + sizeof(stbtt__hheap_chunk) + size * hh->num_remaining_in_head_chunk;
3046     }
3047 }
3048 
3049 static void stbtt__hheap_free(stbtt__hheap * hh, void * p)
3050 {
3051     *(void **)p = hh->first_free;
3052     hh->first_free = p;
3053 }
3054 
3055 static void stbtt__hheap_cleanup(stbtt__hheap * hh, void * userdata)
3056 {
3057     stbtt__hheap_chunk * c = hh->head;
3058     while(c) {
3059         stbtt__hheap_chunk * n = c->next;
3060         STBTT_free(c, userdata);
3061         c = n;
3062     }
3063 }
3064 
3065 typedef struct stbtt__edge {
3066     float x0, y0, x1, y1;
3067     int invert;
3068 } stbtt__edge;
3069 
3070 typedef struct stbtt__active_edge {
3071     struct stbtt__active_edge * next;
3072 #if STBTT_RASTERIZER_VERSION==1
3073     int x, dx;
3074     float ey;
3075     int direction;
3076 #elif STBTT_RASTERIZER_VERSION==2
3077     float fx, fdx, fdy;
3078     float direction;
3079     float sy;
3080     float ey;
3081 #else
3082 #error "Unrecognized value of STBTT_RASTERIZER_VERSION"
3083 #endif
3084 } stbtt__active_edge;
3085 
3086 #if STBTT_RASTERIZER_VERSION == 1
3087 #define STBTT_FIXSHIFT   10
3088 #define STBTT_FIX        (1 << STBTT_FIXSHIFT)
3089 #define STBTT_FIXMASK    (STBTT_FIX-1)
3090 
3091 static stbtt__active_edge * stbtt__new_active(stbtt__hheap * hh, stbtt__edge * e, int off_x, float start_point,
3092                                               void * userdata)
3093 {
3094     stbtt__active_edge * z = (stbtt__active_edge *)stbtt__hheap_alloc(hh, sizeof(*z), userdata);
3095     float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
3096     STBTT_assert(z != NULL);
3097     if(!z) return z;
3098 
3099     // round dx down to avoid overshooting
3100     if(dxdy < 0)
3101         z->dx = -STBTT_ifloor(STBTT_FIX * -dxdy);
3102     else
3103         z->dx = STBTT_ifloor(STBTT_FIX * dxdy);
3104 
3105     z->x = STBTT_ifloor(STBTT_FIX * e->x0 + z->dx * (start_point -
3106                                                      e->y0)); // use z->dx so when we offset later it's by the same amount
3107     z->x -= off_x * STBTT_FIX;
3108 
3109     z->ey = e->y1;
3110     z->next = 0;
3111     z->direction = e->invert ? 1 : -1;
3112     return z;
3113 }
3114 #elif STBTT_RASTERIZER_VERSION == 2
3115 static stbtt__active_edge * stbtt__new_active(stbtt__hheap * hh, stbtt__edge * e, int off_x, float start_point,
3116                                               void * userdata)
3117 {
3118     stbtt__active_edge * z = (stbtt__active_edge *)stbtt__hheap_alloc(hh, sizeof(*z), userdata);
3119     float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
3120     STBTT_assert(z != NULL);
3121     //STBTT_assert(e->y0 <= start_point);
3122     if(!z) return z;
3123     z->fdx = dxdy;
3124     z->fdy = dxdy != 0.0f ? (1.0f / dxdy) : 0.0f;
3125     z->fx = e->x0 + dxdy * (start_point - e->y0);
3126     z->fx -= off_x;
3127     z->direction = e->invert ? 1.0f : -1.0f;
3128     z->sy = e->y0;
3129     z->ey = e->y1;
3130     z->next = 0;
3131     return z;
3132 }
3133 #else
3134 #error "Unrecognized value of STBTT_RASTERIZER_VERSION"
3135 #endif
3136 
3137 #if STBTT_RASTERIZER_VERSION == 1
3138 // note: this routine clips fills that extend off the edges... ideally this
3139 // wouldn't happen, but it could happen if the truetype glyph bounding boxes
3140 // are wrong, or if the user supplies a too-small bitmap
3141 static void stbtt__fill_active_edges(unsigned char * scanline, int len, stbtt__active_edge * e, int max_weight)
3142 {
3143     // non-zero winding fill
3144     int x0 = 0, w = 0;
3145 
3146     while(e) {
3147         if(w == 0) {
3148             // if we're currently at zero, we need to record the edge start point
3149             x0 = e->x;
3150             w += e->direction;
3151         }
3152         else {
3153             int x1 = e->x;
3154             w += e->direction;
3155             // if we went to zero, we need to draw
3156             if(w == 0) {
3157                 int i = x0 >> STBTT_FIXSHIFT;
3158                 int j = x1 >> STBTT_FIXSHIFT;
3159 
3160                 if(i < len && j >= 0) {
3161                     if(i == j) {
3162                         // x0,x1 are the same pixel, so compute combined coverage
3163                         scanline[i] = scanline[i] + (stbtt_uint8)((x1 - x0) * max_weight >> STBTT_FIXSHIFT);
3164                     }
3165                     else {
3166                         if(i >= 0)  // add antialiasing for x0
3167                             scanline[i] = scanline[i] + (stbtt_uint8)(((STBTT_FIX - (x0 & STBTT_FIXMASK)) * max_weight) >> STBTT_FIXSHIFT);
3168                         else
3169                             i = -1; // clip
3170 
3171                         if(j < len)  // add antialiasing for x1
3172                             scanline[j] = scanline[j] + (stbtt_uint8)(((x1 & STBTT_FIXMASK) * max_weight) >> STBTT_FIXSHIFT);
3173                         else
3174                             j = len; // clip
3175 
3176                         for(++i; i < j; ++i)  // fill pixels between x0 and x1
3177                             scanline[i] = scanline[i] + (stbtt_uint8)max_weight;
3178                     }
3179                 }
3180             }
3181         }
3182 
3183         e = e->next;
3184     }
3185 }
3186 
3187 static void stbtt__rasterize_sorted_edges(stbtt__bitmap * result, stbtt__edge * e, int n, int vsubsample, int off_x,
3188                                           int off_y, void * userdata)
3189 {
3190     stbtt__hheap hh = { 0, 0, 0 };
3191     stbtt__active_edge * active = NULL;
3192     int y, j = 0;
3193     int max_weight = (255 / vsubsample);  // weight per vertical scanline
3194     int s; // vertical subsample index
3195     unsigned char scanline_data[512], * scanline;
3196 
3197     if(result->w > 512)
3198         scanline = (unsigned char *)STBTT_malloc(result->w, userdata);
3199     else
3200         scanline = scanline_data;
3201 
3202     y = off_y * vsubsample;
3203     e[n].y0 = (off_y + result->h) * (float)vsubsample + 1;
3204 
3205     while(j < result->h) {
3206         STBTT_memset(scanline, 0, result->w);
3207         for(s = 0; s < vsubsample; ++s) {
3208             // find center of pixel for this scanline
3209             float scan_y = y + 0.5f;
3210             stbtt__active_edge ** step = &active;
3211 
3212             // update all active edges;
3213             // remove all active edges that terminate before the center of this scanline
3214             while(*step) {
3215                 stbtt__active_edge * z = *step;
3216                 if(z->ey <= scan_y) {
3217                     *step = z->next; // delete from list
3218                     STBTT_assert(z->direction);
3219                     z->direction = 0;
3220                     stbtt__hheap_free(&hh, z);
3221                 }
3222                 else {
3223                     z->x += z->dx; // advance to position for current scanline
3224                     step = &((*step)->next); // advance through list
3225                 }
3226             }
3227 
3228             // resort the list if needed
3229             for(;;) {
3230                 int changed = 0;
3231                 step = &active;
3232                 while(*step && (*step)->next) {
3233                     if((*step)->x > (*step)->next->x) {
3234                         stbtt__active_edge * t = *step;
3235                         stbtt__active_edge * q = t->next;
3236 
3237                         t->next = q->next;
3238                         q->next = t;
3239                         *step = q;
3240                         changed = 1;
3241                     }
3242                     step = &(*step)->next;
3243                 }
3244                 if(!changed) break;
3245             }
3246 
3247             // insert all edges that start before the center of this scanline -- omit ones that also end on this scanline
3248             while(e->y0 <= scan_y) {
3249                 if(e->y1 > scan_y) {
3250                     stbtt__active_edge * z = stbtt__new_active(&hh, e, off_x, scan_y, userdata);
3251                     if(z != NULL) {
3252                         // find insertion point
3253                         if(active == NULL)
3254                             active = z;
3255                         else if(z->x < active->x) {
3256                             // insert at front
3257                             z->next = active;
3258                             active = z;
3259                         }
3260                         else {
3261                             // find thing to insert AFTER
3262                             stbtt__active_edge * p = active;
3263                             while(p->next && p->next->x < z->x)
3264                                 p = p->next;
3265                             // at this point, p->next->x is NOT < z->x
3266                             z->next = p->next;
3267                             p->next = z;
3268                         }
3269                     }
3270                 }
3271                 ++e;
3272             }
3273 
3274             // now process all active edges in XOR fashion
3275             if(active)
3276                 stbtt__fill_active_edges(scanline, result->w, active, max_weight);
3277 
3278             ++y;
3279         }
3280         STBTT_memcpy(result->pixels + j * result->stride, scanline, result->w);
3281         ++j;
3282     }
3283 
3284     stbtt__hheap_cleanup(&hh, userdata);
3285 
3286     if(scanline != scanline_data)
3287         STBTT_free(scanline, userdata);
3288 }
3289 
3290 #elif STBTT_RASTERIZER_VERSION == 2
3291 
3292 // the edge passed in here does not cross the vertical line at x or the vertical line at x+1
3293 // (i.e. it has already been clipped to those)
3294 static void stbtt__handle_clipped_edge(float * scanline, int x, stbtt__active_edge * e, float x0, float y0, float x1,
3295                                        float y1)
3296 {
3297     if(y0 == y1) return;
3298     STBTT_assert(y0 < y1);
3299     STBTT_assert(e->sy <= e->ey);
3300     if(y0 > e->ey) return;
3301     if(y1 < e->sy) return;
3302     if(y0 < e->sy) {
3303         x0 += (x1 - x0) * (e->sy - y0) / (y1 - y0);
3304         y0 = e->sy;
3305     }
3306     if(y1 > e->ey) {
3307         x1 += (x1 - x0) * (e->ey - y1) / (y1 - y0);
3308         y1 = e->ey;
3309     }
3310 
3311     if(x0 == x)
3312         STBTT_assert(x1 <= x + 1);
3313     else if(x0 == x + 1)
3314         STBTT_assert(x1 >= x);
3315     else if(x0 <= x)
3316         STBTT_assert(x1 <= x);
3317     else if(x0 >= x + 1)
3318         STBTT_assert(x1 >= x + 1);
3319     else
3320         STBTT_assert(x1 >= x && x1 <= x + 1);
3321 
3322     if(x0 <= x && x1 <= x)
3323         scanline[x] += e->direction * (y1 - y0);
3324     else if(x0 >= x + 1 && x1 >= x + 1) {
3325         /*Nothing to do*/;
3326     }
3327     else {
3328         STBTT_assert(x0 >= x && x0 <= x + 1 && x1 >= x && x1 <= x + 1);
3329         scanline[x] += e->direction * (y1 - y0) * (1 - ((x0 - x) + (x1 - x)) / 2); // coverage = 1 - average x position
3330     }
3331 }
3332 
3333 static float stbtt__sized_trapezoid_area(float height, float top_width, float bottom_width)
3334 {
3335     STBTT_assert(top_width >= 0);
3336     STBTT_assert(bottom_width >= 0);
3337     return (top_width + bottom_width) / 2.0f * height;
3338 }
3339 
3340 static float stbtt__position_trapezoid_area(float height, float tx0, float tx1, float bx0, float bx1)
3341 {
3342     return stbtt__sized_trapezoid_area(height, tx1 - tx0, bx1 - bx0);
3343 }
3344 
3345 static float stbtt__sized_triangle_area(float height, float width)
3346 {
3347     return height * width / 2;
3348 }
3349 
3350 static void stbtt__fill_active_edges_new(float * scanline, float * scanline_fill, int len, stbtt__active_edge * e,
3351                                          float y_top)
3352 {
3353     float y_bottom = y_top + 1;
3354 
3355     while(e) {
3356         // brute force every pixel
3357 
3358         // compute intersection points with top & bottom
3359         STBTT_assert(e->ey >= y_top);
3360 
3361         if(e->fdx == 0) {
3362             float x0 = e->fx;
3363             if(x0 < len) {
3364                 if(x0 >= 0) {
3365                     stbtt__handle_clipped_edge(scanline, (int)x0, e, x0, y_top, x0, y_bottom);
3366                     stbtt__handle_clipped_edge(scanline_fill - 1, (int)x0 + 1, e, x0, y_top, x0, y_bottom);
3367                 }
3368                 else {
3369                     stbtt__handle_clipped_edge(scanline_fill - 1, 0, e, x0, y_top, x0, y_bottom);
3370                 }
3371             }
3372         }
3373         else {
3374             float x0 = e->fx;
3375             float dx = e->fdx;
3376             float xb = x0 + dx;
3377             float x_top, x_bottom;
3378             float sy0, sy1;
3379             float dy = e->fdy;
3380             STBTT_assert(e->sy <= y_bottom && e->ey >= y_top);
3381 
3382             // compute endpoints of line segment clipped to this scanline (if the
3383             // line segment starts on this scanline. x0 is the intersection of the
3384             // line with y_top, but that may be off the line segment.
3385             if(e->sy > y_top) {
3386                 x_top = x0 + dx * (e->sy - y_top);
3387                 sy0 = e->sy;
3388             }
3389             else {
3390                 x_top = x0;
3391                 sy0 = y_top;
3392             }
3393             if(e->ey < y_bottom) {
3394                 x_bottom = x0 + dx * (e->ey - y_top);
3395                 sy1 = e->ey;
3396             }
3397             else {
3398                 x_bottom = xb;
3399                 sy1 = y_bottom;
3400             }
3401 
3402             if(x_top >= 0 && x_bottom >= 0 && x_top < len && x_bottom < len) {
3403                 // from here on, we don't have to range check x values
3404 
3405                 if((int)x_top == (int)x_bottom) {
3406                     float height;
3407                     // simple case, only spans one pixel
3408                     int x = (int)x_top;
3409                     height = (sy1 - sy0) * e->direction;
3410                     STBTT_assert(x >= 0 && x < len);
3411                     scanline[x] += stbtt__position_trapezoid_area(height, x_top, x + 1.0f, x_bottom, x + 1.0f);
3412                     scanline_fill[x] += height; // everything right of this pixel is filled
3413                 }
3414                 else {
3415                     int x, x1, x2;
3416                     float y_crossing, y_final, step, sign, area;
3417                     // covers 2+ pixels
3418                     if(x_top > x_bottom) {
3419                         // flip scanline vertically; signed area is the same
3420                         float t;
3421                         sy0 = y_bottom - (sy0 - y_top);
3422                         sy1 = y_bottom - (sy1 - y_top);
3423                         t = sy0, sy0 = sy1, sy1 = t;
3424                         t = x_bottom, x_bottom = x_top, x_top = t;
3425                         dx = -dx;
3426                         dy = -dy;
3427                         t = x0, x0 = xb, xb = t;
3428                     }
3429                     STBTT_assert(dy >= 0);
3430                     STBTT_assert(dx >= 0);
3431 
3432                     x1 = (int)x_top;
3433                     x2 = (int)x_bottom;
3434                     // compute intersection with y axis at x1+1
3435                     y_crossing = y_top + dy * (x1 + 1 - x0);
3436 
3437                     // compute intersection with y axis at x2
3438                     y_final = y_top + dy * (x2 - x0);
3439 
3440                     //           x1    x_top                            x2    x_bottom
3441                     //     y_top  +------|-----+------------+------------+--------|---+------------+
3442                     //            |            |            |            |            |            |
3443                     //            |            |            |            |            |            |
3444                     //       sy0  |      Txxxxx|............|............|............|............|
3445                     // y_crossing |            *xxxxx.......|............|............|............|
3446                     //            |            |     xxxxx..|............|............|............|
3447                     //            |            |     /-   xx*xxxx........|............|............|
3448                     //            |            | dy <       |    xxxxxx..|............|............|
3449                     //   y_final  |            |     \-     |          xx*xxx.........|............|
3450                     //       sy1  |            |            |            |   xxxxxB...|............|
3451                     //            |            |            |            |            |            |
3452                     //            |            |            |            |            |            |
3453                     //  y_bottom  +------------+------------+------------+------------+------------+
3454                     //
3455                     // goal is to measure the area covered by '.' in each pixel
3456 
3457                     // if x2 is right at the right edge of x1, y_crossing can blow up, github #1057
3458                     // @TODO: maybe test against sy1 rather than y_bottom?
3459                     if(y_crossing > y_bottom)
3460                         y_crossing = y_bottom;
3461 
3462                     sign = e->direction;
3463 
3464                     // area of the rectangle covered from sy0..y_crossing
3465                     area = sign * (y_crossing - sy0);
3466 
3467                     // area of the triangle (x_top,sy0), (x1+1,sy0), (x1+1,y_crossing)
3468                     scanline[x1] += stbtt__sized_triangle_area(area, x1 + 1 - x_top);
3469 
3470                     // check if final y_crossing is blown up; no test case for this
3471                     if(y_final > y_bottom) {
3472                         y_final = y_bottom;
3473                         dy = (y_final - y_crossing) / (x2 - (x1 + 1)); // if denom=0, y_final = y_crossing, so y_final <= y_bottom
3474                     }
3475 
3476                     // in second pixel, area covered by line segment found in first pixel
3477                     // is always a rectangle 1 wide * the height of that line segment; this
3478                     // is exactly what the variable 'area' stores. it also gets a contribution
3479                     // from the line segment within it. the THIRD pixel will get the first
3480                     // pixel's rectangle contribution, the second pixel's rectangle contribution,
3481                     // and its own contribution. the 'own contribution' is the same in every pixel except
3482                     // the leftmost and rightmost, a trapezoid that slides down in each pixel.
3483                     // the second pixel's contribution to the third pixel will be the
3484                     // rectangle 1 wide times the height change in the second pixel, which is dy.
3485 
3486                     step = sign * dy * 1; // dy is dy/dx, change in y for every 1 change in x,
3487                     // which multiplied by 1-pixel-width is how much pixel area changes for each step in x
3488                     // so the area advances by 'step' every time
3489 
3490                     for(x = x1 + 1; x < x2; ++x) {
3491                         scanline[x] += area + step / 2; // area of trapezoid is 1*step/2
3492                         area += step;
3493                     }
3494                     STBTT_assert(STBTT_fabs(area) <= 1.01f); // accumulated error from area += step unless we round step down
3495                     STBTT_assert(sy1 > y_final - 0.01f);
3496 
3497                     // area covered in the last pixel is the rectangle from all the pixels to the left,
3498                     // plus the trapezoid filled by the line segment in this pixel all the way to the right edge
3499                     scanline[x2] += area + sign * stbtt__position_trapezoid_area(sy1 - y_final, (float)x2, x2 + 1.0f, x_bottom, x2 + 1.0f);
3500 
3501                     // the rest of the line is filled based on the total height of the line segment in this pixel
3502                     scanline_fill[x2] += sign * (sy1 - sy0);
3503                 }
3504             }
3505             else {
3506                 // if edge goes outside of box we're drawing, we require
3507                 // clipping logic. since this does not match the intended use
3508                 // of this library, we use a different, very slow brute
3509                 // force implementation
3510                 // note though that this does happen some of the time because
3511                 // x_top and x_bottom can be extrapolated at the top & bottom of
3512                 // the shape and actually lie outside the bounding box
3513                 int x;
3514                 for(x = 0; x < len; ++x) {
3515                     // cases:
3516                     //
3517                     // there can be up to two intersections with the pixel. any intersection
3518                     // with left or right edges can be handled by splitting into two (or three)
3519                     // regions. intersections with top & bottom do not necessitate case-wise logic.
3520                     //
3521                     // the old way of doing this found the intersections with the left & right edges,
3522                     // then used some simple logic to produce up to three segments in sorted order
3523                     // from top-to-bottom. however, this had a problem: if an x edge was epsilon
3524                     // across the x border, then the corresponding y position might not be distinct
3525                     // from the other y segment, and it might ignored as an empty segment. to avoid
3526                     // that, we need to explicitly produce segments based on x positions.
3527 
3528                     // rename variables to clearly-defined pairs
3529                     float y0 = y_top;
3530                     float x1 = (float)(x);
3531                     float x2 = (float)(x + 1);
3532                     float x3 = xb;
3533                     float y3 = y_bottom;
3534 
3535                     // x = e->x + e->dx * (y-y_top)
3536                     // (y-y_top) = (x - e->x) / e->dx
3537                     // y = (x - e->x) / e->dx + y_top
3538                     float y1 = (x - x0) / dx + y_top;
3539                     float y2 = (x + 1 - x0) / dx + y_top;
3540 
3541                     if(x0 < x1 && x3 > x2) {          // three segments descending down-right
3542                         stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x1, y1);
3543                         stbtt__handle_clipped_edge(scanline, x, e, x1, y1, x2, y2);
3544                         stbtt__handle_clipped_edge(scanline, x, e, x2, y2, x3, y3);
3545                     }
3546                     else if(x3 < x1 && x0 > x2) {   // three segments descending down-left
3547                         stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x2, y2);
3548                         stbtt__handle_clipped_edge(scanline, x, e, x2, y2, x1, y1);
3549                         stbtt__handle_clipped_edge(scanline, x, e, x1, y1, x3, y3);
3550                     }
3551                     else if(x0 < x1 && x3 > x1) {   // two segments across x, down-right
3552                         stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x1, y1);
3553                         stbtt__handle_clipped_edge(scanline, x, e, x1, y1, x3, y3);
3554                     }
3555                     else if(x3 < x1 && x0 > x1) {   // two segments across x, down-left
3556                         stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x1, y1);
3557                         stbtt__handle_clipped_edge(scanline, x, e, x1, y1, x3, y3);
3558                     }
3559                     else if(x0 < x2 && x3 > x2) {   // two segments across x+1, down-right
3560                         stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x2, y2);
3561                         stbtt__handle_clipped_edge(scanline, x, e, x2, y2, x3, y3);
3562                     }
3563                     else if(x3 < x2 && x0 > x2) {   // two segments across x+1, down-left
3564                         stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x2, y2);
3565                         stbtt__handle_clipped_edge(scanline, x, e, x2, y2, x3, y3);
3566                     }
3567                     else {  // one segment
3568                         stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x3, y3);
3569                     }
3570                 }
3571             }
3572         }
3573         e = e->next;
3574     }
3575 }
3576 
3577 // directly AA rasterize edges w/o supersampling
3578 static void stbtt__rasterize_sorted_edges(stbtt__bitmap * result, stbtt__edge * e, int n, int vsubsample, int off_x,
3579                                           int off_y, void * userdata)
3580 {
3581     stbtt__hheap hh = { 0, 0, 0 };
3582     stbtt__active_edge * active = NULL;
3583     int y, j = 0, i;
3584     float scanline_data[129], * scanline, * scanline2;
3585 
3586     STBTT__NOTUSED(vsubsample);
3587 
3588     if(result->w > 64)
3589         scanline = (float *)STBTT_malloc((result->w * 2 + 1) * sizeof(float), userdata);
3590     else
3591         scanline = scanline_data;
3592 
3593     scanline2 = scanline + result->w;
3594 
3595     y = off_y;
3596     e[n].y0 = (float)(off_y + result->h) + 1;
3597 
3598     while(j < result->h) {
3599         // find center of pixel for this scanline
3600         float scan_y_top = y + 0.0f;
3601         float scan_y_bottom = y + 1.0f;
3602         stbtt__active_edge ** step = &active;
3603 
3604         STBTT_memset(scanline, 0, result->w * sizeof(scanline[0]));
3605         STBTT_memset(scanline2, 0, (result->w + 1) * sizeof(scanline[0]));
3606 
3607         // update all active edges;
3608         // remove all active edges that terminate before the top of this scanline
3609         while(*step) {
3610             stbtt__active_edge * z = *step;
3611             if(z->ey <= scan_y_top) {
3612                 *step = z->next; // delete from list
3613                 STBTT_assert(z->direction);
3614                 z->direction = 0;
3615                 stbtt__hheap_free(&hh, z);
3616             }
3617             else {
3618                 step = &((*step)->next); // advance through list
3619             }
3620         }
3621 
3622         // insert all edges that start before the bottom of this scanline
3623         while(e->y0 <= scan_y_bottom) {
3624             if(e->y0 != e->y1) {
3625                 stbtt__active_edge * z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata);
3626                 if(z != NULL) {
3627                     if(j == 0 && off_y != 0) {
3628                         if(z->ey < scan_y_top) {
3629                             // this can happen due to subpixel positioning and some kind of fp rounding error i think
3630                             z->ey = scan_y_top;
3631                         }
3632                     }
3633                     STBTT_assert(z->ey >= scan_y_top); // if we get really unlucky a tiny bit of an edge can be out of bounds
3634                     // insert at front
3635                     z->next = active;
3636                     active = z;
3637                 }
3638             }
3639             ++e;
3640         }
3641 
3642         // now process all active edges
3643         if(active)
3644             stbtt__fill_active_edges_new(scanline, scanline2 + 1, result->w, active, scan_y_top);
3645 
3646         {
3647             float sum = 0;
3648             for(i = 0; i < result->w; ++i) {
3649                 float k;
3650                 int m;
3651                 sum += scanline2[i];
3652                 k = scanline[i] + sum;
3653                 k = (float)STBTT_fabs(k) * 255 + 0.5f;
3654                 m = (int)k;
3655                 if(m > 255) m = 255;
3656                 result->pixels[j * result->stride + i] = (unsigned char)m;
3657             }
3658         }
3659         // advance all the edges
3660         step = &active;
3661         while(*step) {
3662             stbtt__active_edge * z = *step;
3663             z->fx += z->fdx; // advance to position for current scanline
3664             step = &((*step)->next); // advance through list
3665         }
3666 
3667         ++y;
3668         ++j;
3669     }
3670 
3671     stbtt__hheap_cleanup(&hh, userdata);
3672 
3673     if(scanline != scanline_data)
3674         STBTT_free(scanline, userdata);
3675 }
3676 #else
3677 #error "Unrecognized value of STBTT_RASTERIZER_VERSION"
3678 #endif
3679 
3680 #define STBTT__COMPARE(a,b)  ((a)->y0 < (b)->y0)
3681 
3682 static void stbtt__sort_edges_ins_sort(stbtt__edge * p, int n)
3683 {
3684     int i, j;
3685     for(i = 1; i < n; ++i) {
3686         stbtt__edge t = p[i], * a = &t;
3687         j = i;
3688         while(j > 0) {
3689             stbtt__edge * b = &p[j - 1];
3690             int c = STBTT__COMPARE(a, b);
3691             if(!c) break;
3692             p[j] = p[j - 1];
3693             --j;
3694         }
3695         if(i != j)
3696             p[j] = t;
3697     }
3698 }
3699 
3700 static void stbtt__sort_edges_quicksort(stbtt__edge * p, int n)
3701 {
3702     /* threshold for transitioning to insertion sort */
3703     while(n > 12) {
3704         stbtt__edge t;
3705         int c01, c12, c, m, i, j;
3706 
3707         /* compute median of three */
3708         m = n >> 1;
3709         c01 = STBTT__COMPARE(&p[0], &p[m]);
3710         c12 = STBTT__COMPARE(&p[m], &p[n - 1]);
3711         /* if 0 >= mid >= end, or 0 < mid < end, then use mid */
3712         if(c01 != c12) {
3713             /* otherwise, we'll need to swap something else to middle */
3714             int z;
3715             c = STBTT__COMPARE(&p[0], &p[n - 1]);
3716             /* 0>mid && mid<n:  0>n => n; 0<n => 0 */
3717             /* 0<mid && mid>n:  0>n => 0; 0<n => n */
3718             z = (c == c12) ? 0 : n - 1;
3719             t = p[z];
3720             p[z] = p[m];
3721             p[m] = t;
3722         }
3723         /* now p[m] is the median-of-three */
3724         /* swap it to the beginning so it won't move around */
3725         t = p[0];
3726         p[0] = p[m];
3727         p[m] = t;
3728 
3729         /* partition loop */
3730         i = 1;
3731         j = n - 1;
3732         for(;;) {
3733             /* handling of equality is crucial here */
3734             /* for sentinels & efficiency with duplicates */
3735             for(;; ++i) {
3736                 if(!STBTT__COMPARE(&p[i], &p[0])) break;
3737             }
3738             for(;; --j) {
3739                 if(!STBTT__COMPARE(&p[0], &p[j])) break;
3740             }
3741             /* make sure we haven't crossed */
3742             if(i >= j) break;
3743             t = p[i];
3744             p[i] = p[j];
3745             p[j] = t;
3746 
3747             ++i;
3748             --j;
3749         }
3750         /* recurse on smaller side, iterate on larger */
3751         if(j < (n - i)) {
3752             stbtt__sort_edges_quicksort(p, j);
3753             p = p + i;
3754             n = n - i;
3755         }
3756         else {
3757             stbtt__sort_edges_quicksort(p + i, n - i);
3758             n = j;
3759         }
3760     }
3761 }
3762 
3763 static void stbtt__sort_edges(stbtt__edge * p, int n)
3764 {
3765     stbtt__sort_edges_quicksort(p, n);
3766     stbtt__sort_edges_ins_sort(p, n);
3767 }
3768 
3769 typedef struct {
3770     float x, y;
3771 } stbtt__point;
3772 
3773 static void stbtt__rasterize(stbtt__bitmap * result, stbtt__point * pts, int * wcount, int windings, float scale_x,
3774                              float scale_y, float shift_x, float shift_y, int off_x, int off_y, int invert, void * userdata)
3775 {
3776     float y_scale_inv = invert ? -scale_y : scale_y;
3777     stbtt__edge * e;
3778     int n, i, j, k, m;
3779 #if STBTT_RASTERIZER_VERSION == 1
3780     int vsubsample = result->h < 8 ? 15 : 5;
3781 #elif STBTT_RASTERIZER_VERSION == 2
3782     int vsubsample = 1;
3783 #else
3784 #error "Unrecognized value of STBTT_RASTERIZER_VERSION"
3785 #endif
3786     // vsubsample should divide 255 evenly; otherwise we won't reach full opacity
3787 
3788     // now we have to blow out the windings into explicit edge lists
3789     n = 0;
3790     for(i = 0; i < windings; ++i)
3791         n += wcount[i];
3792 
3793     e = (stbtt__edge *)STBTT_malloc(sizeof(*e) * (n + 1), userdata); // add an extra one as a sentinel
3794     if(e == 0) return;
3795     n = 0;
3796 
3797     m = 0;
3798     for(i = 0; i < windings; ++i) {
3799         stbtt__point * p = pts + m;
3800         m += wcount[i];
3801         j = wcount[i] - 1;
3802         for(k = 0; k < wcount[i]; j = k++) {
3803             int a = k, b = j;
3804             // skip the edge if horizontal
3805             if(p[j].y == p[k].y)
3806                 continue;
3807             // add edge from j to k to the list
3808             e[n].invert = 0;
3809             if(invert ? p[j].y > p[k].y : p[j].y < p[k].y) {
3810                 e[n].invert = 1;
3811                 a = j, b = k;
3812             }
3813             e[n].x0 = p[a].x * scale_x + shift_x;
3814             e[n].y0 = (p[a].y * y_scale_inv + shift_y) * vsubsample;
3815             e[n].x1 = p[b].x * scale_x + shift_x;
3816             e[n].y1 = (p[b].y * y_scale_inv + shift_y) * vsubsample;
3817             ++n;
3818         }
3819     }
3820 
3821     // now sort the edges by their highest point (should snap to integer, and then by x)
3822     //STBTT_sort(e, n, sizeof(e[0]), stbtt__edge_compare);
3823     stbtt__sort_edges(e, n);
3824 
3825     // now, traverse the scanlines and find the intersections on each scanline, use xor winding rule
3826     stbtt__rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y, userdata);
3827 
3828     STBTT_free(e, userdata);
3829 }
3830 
3831 static void stbtt__add_point(stbtt__point * points, int n, float x, float y)
3832 {
3833     if(!points) return;  // during first pass, it's unallocated
3834     points[n].x = x;
3835     points[n].y = y;
3836 }
3837 
3838 // tessellate until threshold p is happy... @TODO warped to compensate for non-linear stretching
3839 static int stbtt__tesselate_curve(stbtt__point * points, int * num_points, float x0, float y0, float x1, float y1,
3840                                   float x2, float y2, float objspace_flatness_squared, int n)
3841 {
3842     // midpoint
3843     float mx = (x0 + 2 * x1 + x2) / 4;
3844     float my = (y0 + 2 * y1 + y2) / 4;
3845     // versus directly drawn line
3846     float dx = (x0 + x2) / 2 - mx;
3847     float dy = (y0 + y2) / 2 - my;
3848     if(n > 16)  // 65536 segments on one curve better be enough!
3849         return 1;
3850     if(dx * dx + dy * dy > objspace_flatness_squared) {  // half-pixel error allowed... need to be smaller if AA
3851         stbtt__tesselate_curve(points, num_points, x0, y0, (x0 + x1) / 2.0f, (y0 + y1) / 2.0f, mx, my,
3852                                objspace_flatness_squared, n + 1);
3853         stbtt__tesselate_curve(points, num_points, mx, my, (x1 + x2) / 2.0f, (y1 + y2) / 2.0f, x2, y2,
3854                                objspace_flatness_squared, n + 1);
3855     }
3856     else {
3857         stbtt__add_point(points, *num_points, x2, y2);
3858         *num_points = *num_points + 1;
3859     }
3860     return 1;
3861 }
3862 
3863 static void stbtt__tesselate_cubic(stbtt__point * points, int * num_points, float x0, float y0, float x1, float y1,
3864                                    float x2, float y2, float x3, float y3, float objspace_flatness_squared, int n)
3865 {
3866     // @TODO this "flatness" calculation is just made-up nonsense that seems to work well enough
3867     float dx0 = x1 - x0;
3868     float dy0 = y1 - y0;
3869     float dx1 = x2 - x1;
3870     float dy1 = y2 - y1;
3871     float dx2 = x3 - x2;
3872     float dy2 = y3 - y2;
3873     float dx = x3 - x0;
3874     float dy = y3 - y0;
3875     float longlen = (float)(STBTT_sqrt(dx0 * dx0 + dy0 * dy0) + STBTT_sqrt(dx1 * dx1 + dy1 * dy1) + STBTT_sqrt(
3876                                 dx2 * dx2 + dy2 * dy2));
3877     float shortlen = (float)STBTT_sqrt(dx * dx + dy * dy);
3878     float flatness_squared = longlen * longlen - shortlen * shortlen;
3879 
3880     if(n > 16)  // 65536 segments on one curve better be enough!
3881         return;
3882 
3883     if(flatness_squared > objspace_flatness_squared) {
3884         float x01 = (x0 + x1) / 2;
3885         float y01 = (y0 + y1) / 2;
3886         float x12 = (x1 + x2) / 2;
3887         float y12 = (y1 + y2) / 2;
3888         float x23 = (x2 + x3) / 2;
3889         float y23 = (y2 + y3) / 2;
3890 
3891         float xa = (x01 + x12) / 2;
3892         float ya = (y01 + y12) / 2;
3893         float xb = (x12 + x23) / 2;
3894         float yb = (y12 + y23) / 2;
3895 
3896         float mx = (xa + xb) / 2;
3897         float my = (ya + yb) / 2;
3898 
3899         stbtt__tesselate_cubic(points, num_points, x0, y0, x01, y01, xa, ya, mx, my, objspace_flatness_squared, n + 1);
3900         stbtt__tesselate_cubic(points, num_points, mx, my, xb, yb, x23, y23, x3, y3, objspace_flatness_squared, n + 1);
3901     }
3902     else {
3903         stbtt__add_point(points, *num_points, x3, y3);
3904         *num_points = *num_points + 1;
3905     }
3906 }
3907 
3908 // returns number of contours
3909 static stbtt__point * stbtt_FlattenCurves(stbtt_vertex * vertices, int num_verts, float objspace_flatness,
3910                                           int ** contour_lengths, int * num_contours, void * userdata)
3911 {
3912     stbtt__point * points = 0;
3913     int num_points = 0;
3914 
3915     float objspace_flatness_squared = objspace_flatness * objspace_flatness;
3916     int i, n = 0, start = 0, pass;
3917 
3918     // count how many "moves" there are to get the contour count
3919     for(i = 0; i < num_verts; ++i)
3920         if(vertices[i].type == STBTT_vmove)
3921             ++n;
3922 
3923     *num_contours = n;
3924     if(n == 0) return 0;
3925 
3926     *contour_lengths = (int *)STBTT_malloc(sizeof(**contour_lengths) * n, userdata);
3927 
3928     if(*contour_lengths == 0) {
3929         *num_contours = 0;
3930         return 0;
3931     }
3932 
3933     // make two passes through the points so we don't need to realloc
3934     for(pass = 0; pass < 2; ++pass) {
3935         float x = 0, y = 0;
3936         if(pass == 1) {
3937             points = (stbtt__point *)STBTT_malloc(num_points * sizeof(points[0]), userdata);
3938             if(points == NULL) goto error;
3939         }
3940         num_points = 0;
3941         n = -1;
3942         for(i = 0; i < num_verts; ++i) {
3943             switch(vertices[i].type) {
3944                 case STBTT_vmove:
3945                     // start the next contour
3946                     if(n >= 0)
3947                         (*contour_lengths)[n] = num_points - start;
3948                     ++n;
3949                     start = num_points;
3950 
3951                     x = vertices[i].x, y = vertices[i].y;
3952                     stbtt__add_point(points, num_points++, x, y);
3953                     break;
3954                 case STBTT_vline:
3955                     x = vertices[i].x, y = vertices[i].y;
3956                     stbtt__add_point(points, num_points++, x, y);
3957                     break;
3958                 case STBTT_vcurve:
3959                     stbtt__tesselate_curve(points, &num_points, x, y,
3960                                            vertices[i].cx, vertices[i].cy,
3961                                            vertices[i].x, vertices[i].y,
3962                                            objspace_flatness_squared, 0);
3963                     x = vertices[i].x, y = vertices[i].y;
3964                     break;
3965                 case STBTT_vcubic:
3966                     stbtt__tesselate_cubic(points, &num_points, x, y,
3967                                            vertices[i].cx, vertices[i].cy,
3968                                            vertices[i].cx1, vertices[i].cy1,
3969                                            vertices[i].x, vertices[i].y,
3970                                            objspace_flatness_squared, 0);
3971                     x = vertices[i].x, y = vertices[i].y;
3972                     break;
3973             }
3974         }
3975         (*contour_lengths)[n] = num_points - start;
3976     }
3977 
3978     return points;
3979 error:
3980     STBTT_free(points, userdata);
3981     STBTT_free(*contour_lengths, userdata);
3982     *contour_lengths = 0;
3983     *num_contours = 0;
3984     return NULL;
3985 }
3986 
3987 STBTT_DEF void stbtt_Rasterize(stbtt__bitmap * result, float flatness_in_pixels, stbtt_vertex * vertices, int num_verts,
3988                                float scale_x, float scale_y, float shift_x, float shift_y, int x_off, int y_off, int invert, void * userdata)
3989 {
3990     float scale = scale_x > scale_y ? scale_y : scale_x;
3991     int winding_count = 0;
3992     int * winding_lengths = NULL;
3993     stbtt__point * windings = stbtt_FlattenCurves(vertices, num_verts, flatness_in_pixels / scale, &winding_lengths,
3994                                                   &winding_count, userdata);
3995     if(windings) {
3996         stbtt__rasterize(result, windings, winding_lengths, winding_count, scale_x, scale_y, shift_x, shift_y, x_off, y_off,
3997                          invert, userdata);
3998         STBTT_free(winding_lengths, userdata);
3999         STBTT_free(windings, userdata);
4000     }
4001 }
4002 
4003 STBTT_DEF void stbtt_FreeBitmap(unsigned char * bitmap, void * userdata)
4004 {
4005     STBTT_free(bitmap, userdata);
4006 }
4007 
4008 STBTT_DEF unsigned char * stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo * info, float scale_x, float scale_y,
4009                                                        float shift_x, float shift_y, int glyph, int * width, int * height, int * xoff, int * yoff)
4010 {
4011     int ix0, iy0, ix1, iy1;
4012     stbtt__bitmap gbm;
4013     stbtt_vertex * vertices;
4014     int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices);
4015 
4016     if(scale_x == 0) scale_x = scale_y;
4017     if(scale_y == 0) {
4018         if(scale_x == 0) {
4019             STBTT_free(vertices, info->userdata);
4020             return NULL;
4021         }
4022         scale_y = scale_x;
4023     }
4024 
4025     stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0, &iy0, &ix1, &iy1);
4026 
4027     // now we get the size
4028     gbm.w = (ix1 - ix0);
4029     gbm.h = (iy1 - iy0);
4030     gbm.pixels = NULL; // in case we error
4031 
4032     if(width) *width = gbm.w;
4033     if(height) *height = gbm.h;
4034     if(xoff) *xoff = ix0;
4035     if(yoff) *yoff = iy0;
4036 
4037     if(gbm.w && gbm.h) {
4038         gbm.pixels = (unsigned char *)STBTT_malloc(gbm.w * gbm.h, info->userdata);
4039         if(gbm.pixels) {
4040             gbm.stride = gbm.w;
4041 
4042             stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0, iy0, 1, info->userdata);
4043         }
4044     }
4045     STBTT_free(vertices, info->userdata);
4046     return gbm.pixels;
4047 }
4048 
4049 STBTT_DEF unsigned char * stbtt_GetGlyphBitmap(const stbtt_fontinfo * info, float scale_x, float scale_y, int glyph,
4050                                                int * width, int * height, int * xoff, int * yoff)
4051 {
4052     return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y, 0.0f, 0.0f, glyph, width, height, xoff, yoff);
4053 }
4054 
4055 STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo * info, unsigned char * output, int out_w, int out_h,
4056                                              int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph)
4057 {
4058     int ix0, iy0;
4059     stbtt_vertex * vertices;
4060     int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices);
4061     stbtt__bitmap gbm;
4062 
4063     stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0, &iy0, 0, 0);
4064     gbm.pixels = output;
4065     gbm.w = out_w;
4066     gbm.h = out_h;
4067     gbm.stride = out_stride;
4068 
4069     if(gbm.w && gbm.h)
4070         stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0, iy0, 1, info->userdata);
4071 
4072     STBTT_free(vertices, info->userdata);
4073 }
4074 
4075 STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo * info, unsigned char * output, int out_w, int out_h,
4076                                      int out_stride, float scale_x, float scale_y, int glyph)
4077 {
4078     stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f, 0.0f, glyph);
4079 }
4080 
4081 STBTT_DEF unsigned char * stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo * info, float scale_x, float scale_y,
4082                                                            float shift_x, float shift_y, int codepoint, int * width, int * height, int * xoff, int * yoff)
4083 {
4084     return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y, shift_x, shift_y, stbtt_FindGlyphIndex(info, codepoint),
4085                                         width, height, xoff, yoff);
4086 }
4087 
4088 STBTT_DEF void stbtt_MakeCodepointBitmapSubpixelPrefilter(const stbtt_fontinfo * info, unsigned char * output,
4089                                                           int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int oversample_x,
4090                                                           int oversample_y, float * sub_x, float * sub_y, int codepoint)
4091 {
4092     stbtt_MakeGlyphBitmapSubpixelPrefilter(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y,
4093                                            oversample_x, oversample_y, sub_x, sub_y, stbtt_FindGlyphIndex(info, codepoint));
4094 }
4095 
4096 STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo * info, unsigned char * output, int out_w,
4097                                                  int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint)
4098 {
4099     stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y,
4100                                   stbtt_FindGlyphIndex(info, codepoint));
4101 }
4102 
4103 STBTT_DEF unsigned char * stbtt_GetCodepointBitmap(const stbtt_fontinfo * info, float scale_x, float scale_y,
4104                                                    int codepoint, int * width, int * height, int * xoff, int * yoff)
4105 {
4106     return stbtt_GetCodepointBitmapSubpixel(info, scale_x, scale_y, 0.0f, 0.0f, codepoint, width, height, xoff, yoff);
4107 }
4108 
4109 STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo * info, unsigned char * output, int out_w, int out_h,
4110                                          int out_stride, float scale_x, float scale_y, int codepoint)
4111 {
4112     stbtt_MakeCodepointBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f, 0.0f, codepoint);
4113 }
4114 
4115 //////////////////////////////////////////////////////////////////////////////
4116 //
4117 // bitmap baking
4118 //
4119 // This is SUPER-CRAPPY packing to keep source code small
4120 #ifdef STBTT_STREAM_TYPE
4121 static int stbtt_BakeFontBitmap_internal(STBTT_STREAM_TYPE data,
4122                                          int offset,  // font location (use offset=0 for plain .ttf)
4123                                          float pixel_height,                     // height of font in pixels
4124                                          unsigned char * pixels, int pw, int ph, // bitmap to be filled in
4125                                          int first_char, int num_chars,          // characters to bake
4126                                          stbtt_bakedchar * chardata)
4127 #else
4128 static int stbtt_BakeFontBitmap_internal(unsigned char * data,
4129                                          int offset, // font location (use offset=0 for plain .ttf)
4130                                          float pixel_height,                     // height of font in pixels
4131                                          unsigned char * pixels, int pw, int ph, // bitmap to be filled in
4132                                          int first_char, int num_chars,          // characters to bake
4133                                          stbtt_bakedchar * chardata)
4134 #endif
4135 {
4136     float scale;
4137     int x, y, bottom_y, i;
4138     stbtt_fontinfo f;
4139     f.userdata = NULL;
4140     if(!stbtt_InitFont(&f, data, offset))
4141         return -1;
4142     STBTT_memset(pixels, 0, pw * ph); // background of 0 around pixels
4143     x = y = 1;
4144     bottom_y = 1;
4145 
4146     scale = stbtt_ScaleForPixelHeight(&f, pixel_height);
4147 
4148     for(i = 0; i < num_chars; ++i) {
4149         int advance, lsb, x0, y0, x1, y1, gw, gh;
4150         int g = stbtt_FindGlyphIndex(&f, first_char + i);
4151         stbtt_GetGlyphHMetrics(&f, g, &advance, &lsb);
4152         stbtt_GetGlyphBitmapBox(&f, g, scale, scale, &x0, &y0, &x1, &y1);
4153         gw = x1 - x0;
4154         gh = y1 - y0;
4155         if(x + gw + 1 >= pw)
4156             y = bottom_y, x = 1; // advance to next row
4157         if(y + gh + 1 >= ph)  // check if it fits vertically AFTER potentially moving to next row
4158             return -i;
4159         STBTT_assert(x + gw < pw);
4160         STBTT_assert(y + gh < ph);
4161         stbtt_MakeGlyphBitmap(&f, pixels + x + y * pw, gw, gh, pw, scale, scale, g);
4162         chardata[i].x0 = (stbtt_int16)x;
4163         chardata[i].y0 = (stbtt_int16)y;
4164         chardata[i].x1 = (stbtt_int16)(x + gw);
4165         chardata[i].y1 = (stbtt_int16)(y + gh);
4166         chardata[i].xadvance = scale * advance;
4167         chardata[i].xoff = (float)x0;
4168         chardata[i].yoff = (float)y0;
4169         x = x + gw + 1;
4170         if(y + gh + 1 > bottom_y)
4171             bottom_y = y + gh + 1;
4172     }
4173     return bottom_y;
4174 }
4175 
4176 STBTT_DEF void stbtt_GetBakedQuad(const stbtt_bakedchar * chardata, int pw, int ph, int char_index, float * xpos,
4177                                   float * ypos, stbtt_aligned_quad * q, int opengl_fillrule)
4178 {
4179     float d3d_bias = opengl_fillrule ? 0 : -0.5f;
4180     float ipw = 1.0f / pw, iph = 1.0f / ph;
4181     const stbtt_bakedchar * b = chardata + char_index;
4182     int round_x = STBTT_ifloor((*xpos + b->xoff) + 0.5f);
4183     int round_y = STBTT_ifloor((*ypos + b->yoff) + 0.5f);
4184 
4185     q->x0 = round_x + d3d_bias;
4186     q->y0 = round_y + d3d_bias;
4187     q->x1 = round_x + b->x1 - b->x0 + d3d_bias;
4188     q->y1 = round_y + b->y1 - b->y0 + d3d_bias;
4189 
4190     q->s0 = b->x0 * ipw;
4191     q->t0 = b->y0 * iph;
4192     q->s1 = b->x1 * ipw;
4193     q->t1 = b->y1 * iph;
4194 
4195     *xpos += b->xadvance;
4196 }
4197 
4198 //////////////////////////////////////////////////////////////////////////////
4199 //
4200 // rectangle packing replacement routines if you don't have stb_rect_pack.h
4201 //
4202 
4203 #ifndef STB_RECT_PACK_VERSION
4204 
4205 typedef int stbrp_coord;
4206 
4207 ////////////////////////////////////////////////////////////////////////////////////
4208 //                                                                                //
4209 //                                                                                //
4210 // COMPILER WARNING ?!?!?                                                         //
4211 //                                                                                //
4212 //                                                                                //
4213 // if you get a compile warning due to these symbols being defined more than      //
4214 // once, move #include "stb_rect_pack.h" before #include "stb_truetype.h"         //
4215 //                                                                                //
4216 ////////////////////////////////////////////////////////////////////////////////////
4217 
4218 typedef struct {
4219     int width, height;
4220     int x, y, bottom_y;
4221 } stbrp_context;
4222 
4223 typedef struct {
4224     unsigned char x;
4225 } stbrp_node;
4226 
4227 struct stbrp_rect {
4228     stbrp_coord x, y;
4229     int id, w, h, was_packed;
4230 };
4231 
4232 static void stbrp_init_target(stbrp_context * con, int pw, int ph, stbrp_node * nodes, int num_nodes)
4233 {
4234     con->width = pw;
4235     con->height = ph;
4236     con->x = 0;
4237     con->y = 0;
4238     con->bottom_y = 0;
4239     STBTT__NOTUSED(nodes);
4240     STBTT__NOTUSED(num_nodes);
4241 }
4242 
4243 static void stbrp_pack_rects(stbrp_context * con, stbrp_rect * rects, int num_rects)
4244 {
4245     int i;
4246     for(i = 0; i < num_rects; ++i) {
4247         if(con->x + rects[i].w > con->width) {
4248             con->x = 0;
4249             con->y = con->bottom_y;
4250         }
4251         if(con->y + rects[i].h > con->height)
4252             break;
4253         rects[i].x = con->x;
4254         rects[i].y = con->y;
4255         rects[i].was_packed = 1;
4256         con->x += rects[i].w;
4257         if(con->y + rects[i].h > con->bottom_y)
4258             con->bottom_y = con->y + rects[i].h;
4259     }
4260     for(; i < num_rects; ++i)
4261         rects[i].was_packed = 0;
4262 }
4263 #endif
4264 
4265 //////////////////////////////////////////////////////////////////////////////
4266 //
4267 // bitmap baking
4268 //
4269 // This is SUPER-AWESOME (tm Ryan Gordon) packing using stb_rect_pack.h. If
4270 // stb_rect_pack.h isn't available, it uses the BakeFontBitmap strategy.
4271 
4272 STBTT_DEF int stbtt_PackBegin(stbtt_pack_context * spc, unsigned char * pixels, int pw, int ph, int stride_in_bytes,
4273                               int padding, void * alloc_context)
4274 {
4275     stbrp_context * context = (stbrp_context *)STBTT_malloc(sizeof(*context), alloc_context);
4276     int            num_nodes = pw - padding;
4277     stbrp_node * nodes = (stbrp_node *)STBTT_malloc(sizeof(*nodes) * num_nodes, alloc_context);
4278 
4279     if(context == NULL || nodes == NULL) {
4280         if(context != NULL) STBTT_free(context, alloc_context);
4281         if(nodes != NULL) STBTT_free(nodes, alloc_context);
4282         return 0;
4283     }
4284 
4285     spc->user_allocator_context = alloc_context;
4286     spc->width = pw;
4287     spc->height = ph;
4288     spc->pixels = pixels;
4289     spc->pack_info = context;
4290     spc->nodes = nodes;
4291     spc->padding = padding;
4292     spc->stride_in_bytes = stride_in_bytes != 0 ? stride_in_bytes : pw;
4293     spc->h_oversample = 1;
4294     spc->v_oversample = 1;
4295     spc->skip_missing = 0;
4296 
4297     stbrp_init_target(context, pw - padding, ph - padding, nodes, num_nodes);
4298 
4299     if(pixels)
4300         STBTT_memset(pixels, 0, pw * ph); // background of 0 around pixels
4301 
4302     return 1;
4303 }
4304 
4305 STBTT_DEF void stbtt_PackEnd(stbtt_pack_context * spc)
4306 {
4307     STBTT_free(spc->nodes, spc->user_allocator_context);
4308     STBTT_free(spc->pack_info, spc->user_allocator_context);
4309 }
4310 
4311 STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context * spc, unsigned int h_oversample, unsigned int v_oversample)
4312 {
4313     STBTT_assert(h_oversample <= STBTT_MAX_OVERSAMPLE);
4314     STBTT_assert(v_oversample <= STBTT_MAX_OVERSAMPLE);
4315     if(h_oversample <= STBTT_MAX_OVERSAMPLE)
4316         spc->h_oversample = h_oversample;
4317     if(v_oversample <= STBTT_MAX_OVERSAMPLE)
4318         spc->v_oversample = v_oversample;
4319 }
4320 
4321 STBTT_DEF void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context * spc, int skip)
4322 {
4323     spc->skip_missing = skip;
4324 }
4325 
4326 #define STBTT__OVER_MASK  (STBTT_MAX_OVERSAMPLE-1)
4327 
4328 static void stbtt__h_prefilter(unsigned char * pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width)
4329 {
4330     unsigned char buffer[STBTT_MAX_OVERSAMPLE];
4331     int safe_w = w - kernel_width;
4332     int j;
4333     STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); // suppress bogus warning from VS2013 -analyze
4334     for(j = 0; j < h; ++j) {
4335         int i;
4336         unsigned int total;
4337         STBTT_memset(buffer, 0, kernel_width);
4338 
4339         total = 0;
4340 
4341         // make kernel_width a constant in common cases so compiler can optimize out the divide
4342         switch(kernel_width) {
4343             case 2:
4344                 for(i = 0; i <= safe_w; ++i) {
4345                     total += pixels[i] - buffer[i & STBTT__OVER_MASK];
4346                     buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i];
4347                     pixels[i] = (unsigned char)(total / 2);
4348                 }
4349                 break;
4350             case 3:
4351                 for(i = 0; i <= safe_w; ++i) {
4352                     total += pixels[i] - buffer[i & STBTT__OVER_MASK];
4353                     buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i];
4354                     pixels[i] = (unsigned char)(total / 3);
4355                 }
4356                 break;
4357             case 4:
4358                 for(i = 0; i <= safe_w; ++i) {
4359                     total += pixels[i] - buffer[i & STBTT__OVER_MASK];
4360                     buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i];
4361                     pixels[i] = (unsigned char)(total / 4);
4362                 }
4363                 break;
4364             case 5:
4365                 for(i = 0; i <= safe_w; ++i) {
4366                     total += pixels[i] - buffer[i & STBTT__OVER_MASK];
4367                     buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i];
4368                     pixels[i] = (unsigned char)(total / 5);
4369                 }
4370                 break;
4371             default:
4372                 for(i = 0; i <= safe_w; ++i) {
4373                     total += pixels[i] - buffer[i & STBTT__OVER_MASK];
4374                     buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i];
4375                     pixels[i] = (unsigned char)(total / kernel_width);
4376                 }
4377                 break;
4378         }
4379 
4380         for(; i < w; ++i) {
4381             STBTT_assert(pixels[i] == 0);
4382             total -= buffer[i & STBTT__OVER_MASK];
4383             pixels[i] = (unsigned char)(total / kernel_width);
4384         }
4385 
4386         pixels += stride_in_bytes;
4387     }
4388 }
4389 
4390 static void stbtt__v_prefilter(unsigned char * pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width)
4391 {
4392     unsigned char buffer[STBTT_MAX_OVERSAMPLE];
4393     int safe_h = h - kernel_width;
4394     int j;
4395     STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); // suppress bogus warning from VS2013 -analyze
4396     for(j = 0; j < w; ++j) {
4397         int i;
4398         unsigned int total;
4399         STBTT_memset(buffer, 0, kernel_width);
4400 
4401         total = 0;
4402 
4403         // make kernel_width a constant in common cases so compiler can optimize out the divide
4404         switch(kernel_width) {
4405             case 2:
4406                 for(i = 0; i <= safe_h; ++i) {
4407                     total += pixels[i * stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
4408                     buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i * stride_in_bytes];
4409                     pixels[i * stride_in_bytes] = (unsigned char)(total / 2);
4410                 }
4411                 break;
4412             case 3:
4413                 for(i = 0; i <= safe_h; ++i) {
4414                     total += pixels[i * stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
4415                     buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i * stride_in_bytes];
4416                     pixels[i * stride_in_bytes] = (unsigned char)(total / 3);
4417                 }
4418                 break;
4419             case 4:
4420                 for(i = 0; i <= safe_h; ++i) {
4421                     total += pixels[i * stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
4422                     buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i * stride_in_bytes];
4423                     pixels[i * stride_in_bytes] = (unsigned char)(total / 4);
4424                 }
4425                 break;
4426             case 5:
4427                 for(i = 0; i <= safe_h; ++i) {
4428                     total += pixels[i * stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
4429                     buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i * stride_in_bytes];
4430                     pixels[i * stride_in_bytes] = (unsigned char)(total / 5);
4431                 }
4432                 break;
4433             default:
4434                 for(i = 0; i <= safe_h; ++i) {
4435                     total += pixels[i * stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
4436                     buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i * stride_in_bytes];
4437                     pixels[i * stride_in_bytes] = (unsigned char)(total / kernel_width);
4438                 }
4439                 break;
4440         }
4441 
4442         for(; i < h; ++i) {
4443             STBTT_assert(pixels[i * stride_in_bytes] == 0);
4444             total -= buffer[i & STBTT__OVER_MASK];
4445             pixels[i * stride_in_bytes] = (unsigned char)(total / kernel_width);
4446         }
4447 
4448         pixels += 1;
4449     }
4450 }
4451 
4452 static float stbtt__oversample_shift(int oversample)
4453 {
4454     if(!oversample)
4455         return 0.0f;
4456 
4457     // The prefilter is a box filter of width "oversample",
4458     // which shifts phase by (oversample - 1)/2 pixels in
4459     // oversampled space. We want to shift in the opposite
4460     // direction to counter this.
4461     return (float) - (oversample - 1) / (2.0f * (float)oversample);
4462 }
4463 
4464 // rects array must be big enough to accommodate all characters in the given ranges
4465 STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context * spc, const stbtt_fontinfo * info,
4466                                               stbtt_pack_range * ranges, int num_ranges, stbrp_rect * rects)
4467 {
4468     int i, j, k;
4469     int missing_glyph_added = 0;
4470 
4471     k = 0;
4472     for(i = 0; i < num_ranges; ++i) {
4473         float fh = ranges[i].font_size;
4474         float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh);
4475         ranges[i].h_oversample = (unsigned char)spc->h_oversample;
4476         ranges[i].v_oversample = (unsigned char)spc->v_oversample;
4477         for(j = 0; j < ranges[i].num_chars; ++j) {
4478             int x0, y0, x1, y1;
4479             int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j :
4480                             ranges[i].array_of_unicode_codepoints[j];
4481             int glyph = stbtt_FindGlyphIndex(info, codepoint);
4482             if(glyph == 0 && (spc->skip_missing || missing_glyph_added)) {
4483                 rects[k].w = rects[k].h = 0;
4484             }
4485             else {
4486                 stbtt_GetGlyphBitmapBoxSubpixel(info, glyph,
4487                                                 scale * spc->h_oversample,
4488                                                 scale * spc->v_oversample,
4489                                                 0, 0,
4490                                                 &x0, &y0, &x1, &y1);
4491                 rects[k].w = (stbrp_coord)(x1 - x0 + spc->padding + spc->h_oversample - 1);
4492                 rects[k].h = (stbrp_coord)(y1 - y0 + spc->padding + spc->v_oversample - 1);
4493                 if(glyph == 0)
4494                     missing_glyph_added = 1;
4495             }
4496             ++k;
4497         }
4498     }
4499 
4500     return k;
4501 }
4502 
4503 STBTT_DEF void stbtt_MakeGlyphBitmapSubpixelPrefilter(const stbtt_fontinfo * info, unsigned char * output, int out_w,
4504                                                       int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int prefilter_x, int prefilter_y,
4505                                                       float * sub_x, float * sub_y, int glyph)
4506 {
4507     stbtt_MakeGlyphBitmapSubpixel(info,
4508                                   output,
4509                                   out_w - (prefilter_x - 1),
4510                                   out_h - (prefilter_y - 1),
4511                                   out_stride,
4512                                   scale_x,
4513                                   scale_y,
4514                                   shift_x,
4515                                   shift_y,
4516                                   glyph);
4517 
4518     if(prefilter_x > 1)
4519         stbtt__h_prefilter(output, out_w, out_h, out_stride, prefilter_x);
4520 
4521     if(prefilter_y > 1)
4522         stbtt__v_prefilter(output, out_w, out_h, out_stride, prefilter_y);
4523 
4524     *sub_x = stbtt__oversample_shift(prefilter_x);
4525     *sub_y = stbtt__oversample_shift(prefilter_y);
4526 }
4527 
4528 // rects array must be big enough to accommodate all characters in the given ranges
4529 STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context * spc, const stbtt_fontinfo * info,
4530                                                   stbtt_pack_range * ranges, int num_ranges, stbrp_rect * rects)
4531 {
4532     int i, j, k, missing_glyph = -1, return_value = 1;
4533 
4534     // save current values
4535     int old_h_over = spc->h_oversample;
4536     int old_v_over = spc->v_oversample;
4537 
4538     k = 0;
4539     for(i = 0; i < num_ranges; ++i) {
4540         float fh = ranges[i].font_size;
4541         float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh);
4542         float recip_h, recip_v, sub_x, sub_y;
4543         spc->h_oversample = ranges[i].h_oversample;
4544         spc->v_oversample = ranges[i].v_oversample;
4545         recip_h = 1.0f / spc->h_oversample;
4546         recip_v = 1.0f / spc->v_oversample;
4547         sub_x = stbtt__oversample_shift(spc->h_oversample);
4548         sub_y = stbtt__oversample_shift(spc->v_oversample);
4549         for(j = 0; j < ranges[i].num_chars; ++j) {
4550             stbrp_rect * r = &rects[k];
4551             if(r->was_packed && r->w != 0 && r->h != 0) {
4552                 stbtt_packedchar * bc = &ranges[i].chardata_for_range[j];
4553                 int advance, lsb, x0, y0, x1, y1;
4554                 int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j :
4555                                 ranges[i].array_of_unicode_codepoints[j];
4556                 int glyph = stbtt_FindGlyphIndex(info, codepoint);
4557                 stbrp_coord pad = (stbrp_coord)spc->padding;
4558 
4559                 // pad on left and top
4560                 r->x += pad;
4561                 r->y += pad;
4562                 r->w -= pad;
4563                 r->h -= pad;
4564                 stbtt_GetGlyphHMetrics(info, glyph, &advance, &lsb);
4565                 stbtt_GetGlyphBitmapBox(info, glyph,
4566                                         scale * spc->h_oversample,
4567                                         scale * spc->v_oversample,
4568                                         &x0, &y0, &x1, &y1);
4569                 stbtt_MakeGlyphBitmapSubpixel(info,
4570                                               spc->pixels + r->x + r->y * spc->stride_in_bytes,
4571                                               r->w - spc->h_oversample + 1,
4572                                               r->h - spc->v_oversample + 1,
4573                                               spc->stride_in_bytes,
4574                                               scale * spc->h_oversample,
4575                                               scale * spc->v_oversample,
4576                                               0, 0,
4577                                               glyph);
4578 
4579                 if(spc->h_oversample > 1)
4580                     stbtt__h_prefilter(spc->pixels + r->x + r->y * spc->stride_in_bytes,
4581                                        r->w, r->h, spc->stride_in_bytes,
4582                                        spc->h_oversample);
4583 
4584                 if(spc->v_oversample > 1)
4585                     stbtt__v_prefilter(spc->pixels + r->x + r->y * spc->stride_in_bytes,
4586                                        r->w, r->h, spc->stride_in_bytes,
4587                                        spc->v_oversample);
4588 
4589                 bc->x0 = (stbtt_int16)r->x;
4590                 bc->y0 = (stbtt_int16)r->y;
4591                 bc->x1 = (stbtt_int16)(r->x + r->w);
4592                 bc->y1 = (stbtt_int16)(r->y + r->h);
4593                 bc->xadvance = scale * advance;
4594                 bc->xoff = (float)x0 * recip_h + sub_x;
4595                 bc->yoff = (float)y0 * recip_v + sub_y;
4596                 bc->xoff2 = (x0 + r->w) * recip_h + sub_x;
4597                 bc->yoff2 = (y0 + r->h) * recip_v + sub_y;
4598 
4599                 if(glyph == 0)
4600                     missing_glyph = j;
4601             }
4602             else if(spc->skip_missing) {
4603                 return_value = 0;
4604             }
4605             else if(r->was_packed && r->w == 0 && r->h == 0 && missing_glyph >= 0) {
4606                 ranges[i].chardata_for_range[j] = ranges[i].chardata_for_range[missing_glyph];
4607             }
4608             else {
4609                 return_value = 0; // if any fail, report failure
4610             }
4611 
4612             ++k;
4613         }
4614     }
4615 
4616     // restore original values
4617     spc->h_oversample = old_h_over;
4618     spc->v_oversample = old_v_over;
4619 
4620     return return_value;
4621 }
4622 
4623 #ifdef STBTT_STREAM_TYPE
4624 STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context * spc, STBTT_STREAM_TYPE fontdata, int font_index,
4625                                    stbtt_pack_range * ranges, int num_ranges);
4626 #else
4627 STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context * spc, const unsigned char * fontdata, int font_index,
4628                                    stbtt_pack_range * ranges, int num_ranges);
4629 #endif
4630 
4631 STBTT_DEF void stbtt_PackFontRangesPackRects(stbtt_pack_context * spc, stbrp_rect * rects, int num_rects)
4632 {
4633     stbrp_pack_rects((stbrp_context *)spc->pack_info, rects, num_rects);
4634 }
4635 #ifdef STBTT_STREAM_TYPE
4636 STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context * spc, STBTT_STREAM_TYPE fontdata, int font_index,
4637                                    stbtt_pack_range * ranges, int num_ranges)
4638 #else
4639 STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context * spc, const unsigned char * fontdata, int font_index,
4640                                    stbtt_pack_range * ranges, int num_ranges)
4641 #endif
4642 {
4643     stbtt_fontinfo info;
4644     int i, j, n, return_value = 1;
4645     //stbrp_context *context = (stbrp_context *) spc->pack_info;
4646     stbrp_rect * rects;
4647 
4648     // flag all characters as NOT packed
4649     for(i = 0; i < num_ranges; ++i)
4650         for(j = 0; j < ranges[i].num_chars; ++j)
4651             ranges[i].chardata_for_range[j].x0 =
4652                 ranges[i].chardata_for_range[j].y0 =
4653                     ranges[i].chardata_for_range[j].x1 =
4654                         ranges[i].chardata_for_range[j].y1 = 0;
4655 
4656     n = 0;
4657     for(i = 0; i < num_ranges; ++i)
4658         n += ranges[i].num_chars;
4659 
4660     rects = (stbrp_rect *)STBTT_malloc(sizeof(*rects) * n, spc->user_allocator_context);
4661     if(rects == NULL)
4662         return 0;
4663 
4664     info.userdata = spc->user_allocator_context;
4665     stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata, font_index));
4666 
4667     n = stbtt_PackFontRangesGatherRects(spc, &info, ranges, num_ranges, rects);
4668 
4669     stbtt_PackFontRangesPackRects(spc, rects, n);
4670 
4671     return_value = stbtt_PackFontRangesRenderIntoRects(spc, &info, ranges, num_ranges, rects);
4672 
4673     STBTT_free(rects, spc->user_allocator_context);
4674     return return_value;
4675 }
4676 
4677 #ifdef STBTT_STREAM_TYPE
4678 STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context * spc, STBTT_STREAM_TYPE fontdata, int font_index, float font_size,
4679                                   int first_unicode_codepoint_in_range, int num_chars_in_range, stbtt_packedchar * chardata_for_range);
4680 #else
4681 STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context * spc, const unsigned char * fontdata, int font_index,
4682                                   float font_size,
4683                                   int first_unicode_codepoint_in_range, int num_chars_in_range, stbtt_packedchar * chardata_for_range);
4684 #endif
4685 
4686 #ifdef STBTT_STREAM_TYPE
4687 STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context * spc, STBTT_STREAM_TYPE fontdata, int font_index, float font_size,
4688                                   int first_unicode_codepoint_in_range, int num_chars_in_range, stbtt_packedchar * chardata_for_range)
4689 #else
4690 STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context * spc, const unsigned char * fontdata, int font_index,
4691                                   float font_size,
4692                                   int first_unicode_codepoint_in_range, int num_chars_in_range, stbtt_packedchar * chardata_for_range)
4693 #endif
4694 {
4695     stbtt_pack_range range;
4696     range.first_unicode_codepoint_in_range = first_unicode_codepoint_in_range;
4697     range.array_of_unicode_codepoints = NULL;
4698     range.num_chars = num_chars_in_range;
4699     range.chardata_for_range = chardata_for_range;
4700     range.font_size = font_size;
4701     return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1);
4702 }
4703 
4704 #ifdef STBTT_STREAM_TYPE
4705 STBTT_DEF void stbtt_GetScaledFontVMetrics(STBTT_STREAM_TYPE fontdata, int index, float size, float * ascent,
4706                                            float * descent, float * lineGap);
4707 #else
4708 STBTT_DEF void stbtt_GetScaledFontVMetrics(const unsigned char * fontdata, int index, float size, float * ascent,
4709                                            float * descent, float * lineGap);
4710 #endif
4711 
4712 #ifdef STBTT_STREAM_TYPE
4713 STBTT_DEF void stbtt_GetScaledFontVMetrics(STBTT_STREAM_TYPE fontdata, int index, float size, float * ascent,
4714                                            float * descent, float * lineGap)
4715 #else
4716 STBTT_DEF void stbtt_GetScaledFontVMetrics(const unsigned char * fontdata, int index, float size, float * ascent,
4717                                            float * descent, float * lineGap)
4718 #endif
4719 {
4720     int i_ascent, i_descent, i_lineGap;
4721     float scale;
4722     stbtt_fontinfo info;
4723     stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata, index));
4724     scale = size > 0 ? stbtt_ScaleForPixelHeight(&info, size) : stbtt_ScaleForMappingEmToPixels(&info, -size);
4725     stbtt_GetFontVMetrics(&info, &i_ascent, &i_descent, &i_lineGap);
4726     *ascent = (float)i_ascent * scale;
4727     *descent = (float)i_descent * scale;
4728     *lineGap = (float)i_lineGap * scale;
4729 }
4730 
4731 STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar * chardata, int pw, int ph, int char_index, float * xpos,
4732                                    float * ypos, stbtt_aligned_quad * q, int align_to_integer)
4733 {
4734     float ipw = 1.0f / pw, iph = 1.0f / ph;
4735     const stbtt_packedchar * b = chardata + char_index;
4736 
4737     if(align_to_integer) {
4738         float x = (float)STBTT_ifloor((*xpos + b->xoff) + 0.5f);
4739         float y = (float)STBTT_ifloor((*ypos + b->yoff) + 0.5f);
4740         q->x0 = x;
4741         q->y0 = y;
4742         q->x1 = x + b->xoff2 - b->xoff;
4743         q->y1 = y + b->yoff2 - b->yoff;
4744     }
4745     else {
4746         q->x0 = *xpos + b->xoff;
4747         q->y0 = *ypos + b->yoff;
4748         q->x1 = *xpos + b->xoff2;
4749         q->y1 = *ypos + b->yoff2;
4750     }
4751 
4752     q->s0 = b->x0 * ipw;
4753     q->t0 = b->y0 * iph;
4754     q->s1 = b->x1 * ipw;
4755     q->t1 = b->y1 * iph;
4756 
4757     *xpos += b->xadvance;
4758 }
4759 
4760 //////////////////////////////////////////////////////////////////////////////
4761 //
4762 // sdf computation
4763 //
4764 
4765 #define STBTT_min(a,b)  ((a) < (b) ? (a) : (b))
4766 #define STBTT_max(a,b)  ((a) < (b) ? (b) : (a))
4767 
4768 static int stbtt__ray_intersect_bezier(float orig[2], float ray[2], float q0[2], float q1[2], float q2[2],
4769                                        float hits[2][2])
4770 {
4771     float q0perp = q0[1] * ray[0] - q0[0] * ray[1];
4772     float q1perp = q1[1] * ray[0] - q1[0] * ray[1];
4773     float q2perp = q2[1] * ray[0] - q2[0] * ray[1];
4774     float roperp = orig[1] * ray[0] - orig[0] * ray[1];
4775 
4776     float a = q0perp - 2 * q1perp + q2perp;
4777     float b = q1perp - q0perp;
4778     float c = q0perp - roperp;
4779 
4780     float s0 = 0., s1 = 0.;
4781     int num_s = 0;
4782 
4783     if(a != 0.0f) {
4784         float discr = b * b - a * c;
4785         if(discr > 0.0f) {
4786             float rcpna = -1 / a;
4787             float d = (float)STBTT_sqrt(discr);
4788             s0 = (b + d) * rcpna;
4789             s1 = (b - d) * rcpna;
4790             if(s0 >= 0.0f && s0 <= 1.0f)
4791                 num_s = 1;
4792             if(d > 0.0f && s1 >= 0.0f && s1 <= 1.0f) {
4793                 if(num_s == 0) s0 = s1;
4794                 ++num_s;
4795             }
4796         }
4797     }
4798     else {
4799         // 2*b*s + c = 0
4800         // s = -c / (2*b)
4801         s0 = c / (-2 * b);
4802         if(s0 >= 0.0f && s0 <= 1.0f)
4803             num_s = 1;
4804     }
4805 
4806     if(num_s == 0)
4807         return 0;
4808     else {
4809         float rcp_len2 = 1 / (ray[0] * ray[0] + ray[1] * ray[1]);
4810         float rayn_x = ray[0] * rcp_len2, rayn_y = ray[1] * rcp_len2;
4811 
4812         float q0d = q0[0] * rayn_x + q0[1] * rayn_y;
4813         float q1d = q1[0] * rayn_x + q1[1] * rayn_y;
4814         float q2d = q2[0] * rayn_x + q2[1] * rayn_y;
4815         float rod = orig[0] * rayn_x + orig[1] * rayn_y;
4816 
4817         float q10d = q1d - q0d;
4818         float q20d = q2d - q0d;
4819         float q0rd = q0d - rod;
4820 
4821         hits[0][0] = q0rd + s0 * (2.0f - 2.0f * s0) * q10d + s0 * s0 * q20d;
4822         hits[0][1] = a * s0 + b;
4823 
4824         if(num_s > 1) {
4825             hits[1][0] = q0rd + s1 * (2.0f - 2.0f * s1) * q10d + s1 * s1 * q20d;
4826             hits[1][1] = a * s1 + b;
4827             return 2;
4828         }
4829         else {
4830             return 1;
4831         }
4832     }
4833 }
4834 
4835 static int equal(float * a, float * b)
4836 {
4837     return (a[0] == b[0] && a[1] == b[1]);
4838 }
4839 
4840 static int stbtt__compute_crossings_x(float x, float y, int nverts, stbtt_vertex * verts)
4841 {
4842     int i;
4843     float orig[2], ray[2] = { 1, 0 };
4844     float y_frac;
4845     int winding = 0;
4846 
4847     // make sure y never passes through a vertex of the shape
4848     y_frac = (float)STBTT_fmod(y, 1.0f);
4849     if(y_frac < 0.01f)
4850         y += 0.01f;
4851     else if(y_frac > 0.99f)
4852         y -= 0.01f;
4853 
4854     orig[0] = x;
4855     orig[1] = y;
4856 
4857     // test a ray from (-infinity,y) to (x,y)
4858     for(i = 0; i < nverts; ++i) {
4859         if(verts[i].type == STBTT_vline) {
4860             int x0 = (int)verts[i - 1].x, y0 = (int)verts[i - 1].y;
4861             int x1 = (int)verts[i].x, y1 = (int)verts[i].y;
4862             if(y > STBTT_min(y0, y1) && y < STBTT_max(y0, y1) && x > STBTT_min(x0, x1)) {
4863                 float x_inter = (y - y0) / (y1 - y0) * (x1 - x0) + x0;
4864                 if(x_inter < x)
4865                     winding += (y0 < y1) ? 1 : -1;
4866             }
4867         }
4868         if(verts[i].type == STBTT_vcurve) {
4869             int x0 = (int)verts[i - 1].x, y0 = (int)verts[i - 1].y;
4870             int x1 = (int)verts[i].cx, y1 = (int)verts[i].cy;
4871             int x2 = (int)verts[i].x, y2 = (int)verts[i].y;
4872             int ax = STBTT_min(x0, STBTT_min(x1, x2)), ay = STBTT_min(y0, STBTT_min(y1, y2));
4873             int by = STBTT_max(y0, STBTT_max(y1, y2));
4874             if(y > ay && y < by && x > ax) {
4875                 float q0[2], q1[2], q2[2];
4876                 float hits[2][2];
4877                 q0[0] = (float)x0;
4878                 q0[1] = (float)y0;
4879                 q1[0] = (float)x1;
4880                 q1[1] = (float)y1;
4881                 q2[0] = (float)x2;
4882                 q2[1] = (float)y2;
4883                 if(equal(q0, q1) || equal(q1, q2)) {
4884                     x0 = (int)verts[i - 1].x;
4885                     y0 = (int)verts[i - 1].y;
4886                     x1 = (int)verts[i].x;
4887                     y1 = (int)verts[i].y;
4888                     if(y > STBTT_min(y0, y1) && y < STBTT_max(y0, y1) && x > STBTT_min(x0, x1)) {
4889                         float x_inter = (y - y0) / (y1 - y0) * (x1 - x0) + x0;
4890                         if(x_inter < x)
4891                             winding += (y0 < y1) ? 1 : -1;
4892                     }
4893                 }
4894                 else {
4895                     int num_hits = stbtt__ray_intersect_bezier(orig, ray, q0, q1, q2, hits);
4896                     if(num_hits >= 1)
4897                         if(hits[0][0] < 0)
4898                             winding += (hits[0][1] < 0 ? -1 : 1);
4899                     if(num_hits >= 2)
4900                         if(hits[1][0] < 0)
4901                             winding += (hits[1][1] < 0 ? -1 : 1);
4902                 }
4903             }
4904         }
4905     }
4906     return winding;
4907 }
4908 
4909 static float stbtt__cuberoot(float x)
4910 {
4911     if(x < 0)
4912         return -(float)STBTT_pow(-x, 1.0f / 3.0f);
4913     else
4914         return (float)STBTT_pow(x, 1.0f / 3.0f);
4915 }
4916 
4917 // x^3 + a*x^2 + b*x + c = 0
4918 static int stbtt__solve_cubic(float a, float b, float c, float * r)
4919 {
4920     float s = -a / 3;
4921     float p = b - a * a / 3;
4922     float q = a * (2 * a * a - 9 * b) / 27 + c;
4923     float p3 = p * p * p;
4924     float d = q * q + 4 * p3 / 27;
4925     if(d >= 0) {
4926         float z = (float)STBTT_sqrt(d);
4927         float u = (-q + z) / 2;
4928         float v = (-q - z) / 2;
4929         u = stbtt__cuberoot(u);
4930         v = stbtt__cuberoot(v);
4931         r[0] = s + u + v;
4932         return 1;
4933     }
4934     else {
4935         float u = (float)STBTT_sqrt(-p / 3);
4936         float v = (float)STBTT_acos(-STBTT_sqrt(-27 / p3) * q / 2) / 3; // p3 must be negative, since d is negative
4937         float m = (float)STBTT_cos(v);
4938         float n = (float)STBTT_cos(v - 3.141592f / 2) * 1.732050808f;
4939         r[0] = s + u * 2 * m;
4940         r[1] = s - u * (m + n);
4941         r[2] = s - u * (m - n);
4942 
4943         //STBTT_assert( STBTT_fabs(((r[0]+a)*r[0]+b)*r[0]+c) < 0.05f);  // these asserts may not be safe at all scales, though they're in bezier t parameter units so maybe?
4944         //STBTT_assert( STBTT_fabs(((r[1]+a)*r[1]+b)*r[1]+c) < 0.05f);
4945         //STBTT_assert( STBTT_fabs(((r[2]+a)*r[2]+b)*r[2]+c) < 0.05f);
4946         return 3;
4947     }
4948 }
4949 
4950 STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo * info, float scale, int glyph, int padding,
4951                                             unsigned char onedge_value, float pixel_dist_scale, int * width, int * height, int * xoff, int * yoff)
4952 {
4953     float scale_x = scale, scale_y = scale;
4954     int ix0, iy0, ix1, iy1;
4955     int w, h;
4956     unsigned char * data;
4957 
4958     if(scale == 0) return NULL;
4959 
4960     stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale, scale, 0.0f, 0.0f, &ix0, &iy0, &ix1, &iy1);
4961 
4962     // if empty, return NULL
4963     if(ix0 == ix1 || iy0 == iy1)
4964         return NULL;
4965 
4966     ix0 -= padding;
4967     iy0 -= padding;
4968     ix1 += padding;
4969     iy1 += padding;
4970 
4971     w = (ix1 - ix0);
4972     h = (iy1 - iy0);
4973 
4974     if(width) *width = w;
4975     if(height) *height = h;
4976     if(xoff) *xoff = ix0;
4977     if(yoff) *yoff = iy0;
4978 
4979     // invert for y-downwards bitmaps
4980     scale_y = -scale_y;
4981 
4982     {
4983         int x, y, i, j;
4984         float * precompute;
4985         stbtt_vertex * verts;
4986         int num_verts = stbtt_GetGlyphShape(info, glyph, &verts);
4987         data = (unsigned char *)STBTT_malloc(w * h, info->userdata);
4988         precompute = (float *)STBTT_malloc(num_verts * sizeof(float), info->userdata);
4989 
4990         for(i = 0, j = num_verts - 1; i < num_verts; j = i++) {
4991             if(verts[i].type == STBTT_vline) {
4992                 float x0 = verts[i].x * scale_x, y0 = verts[i].y * scale_y;
4993                 float x1 = verts[j].x * scale_x, y1 = verts[j].y * scale_y;
4994                 float dist = (float)STBTT_sqrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0));
4995                 precompute[i] = (dist == 0) ? 0.0f : 1.0f / dist;
4996             }
4997             else if(verts[i].type == STBTT_vcurve) {
4998                 float x2 = verts[j].x * scale_x, y2 = verts[j].y * scale_y;
4999                 float x1 = verts[i].cx * scale_x, y1 = verts[i].cy * scale_y;
5000                 float x0 = verts[i].x * scale_x, y0 = verts[i].y * scale_y;
5001                 float bx = x0 - 2 * x1 + x2, by = y0 - 2 * y1 + y2;
5002                 float len2 = bx * bx + by * by;
5003                 if(len2 != 0.0f)
5004                     precompute[i] = 1.0f / (bx * bx + by * by);
5005                 else
5006                     precompute[i] = 0.0f;
5007             }
5008             else
5009                 precompute[i] = 0.0f;
5010         }
5011 
5012         for(y = iy0; y < iy1; ++y) {
5013             for(x = ix0; x < ix1; ++x) {
5014                 float val;
5015                 float min_dist = 999999.0f;
5016                 float sx = (float)x + 0.5f;
5017                 float sy = (float)y + 0.5f;
5018                 float x_gspace = (sx / scale_x);
5019                 float y_gspace = (sy / scale_y);
5020 
5021                 int winding = stbtt__compute_crossings_x(x_gspace, y_gspace, num_verts,
5022                                                          verts); // @OPTIMIZE: this could just be a rasterization, but needs to be line vs. non-tesselated curves so a new path
5023 
5024                 for(i = 0; i < num_verts; ++i) {
5025                     float x0 = verts[i].x * scale_x, y0 = verts[i].y * scale_y;
5026 
5027                     if(verts[i].type == STBTT_vline && precompute[i] != 0.0f) {
5028                         float x1 = verts[i - 1].x * scale_x, y1 = verts[i - 1].y * scale_y;
5029 
5030                         float dist, dist2 = (x0 - sx) * (x0 - sx) + (y0 - sy) * (y0 - sy);
5031                         if(dist2 < min_dist * min_dist)
5032                             min_dist = (float)STBTT_sqrt(dist2);
5033 
5034                         // coarse culling against bbox
5035                         //if (sx > STBTT_min(x0,x1)-min_dist && sx < STBTT_max(x0,x1)+min_dist &&
5036                         //    sy > STBTT_min(y0,y1)-min_dist && sy < STBTT_max(y0,y1)+min_dist)
5037                         dist = (float)STBTT_fabs((x1 - x0) * (y0 - sy) - (y1 - y0) * (x0 - sx)) * precompute[i];
5038                         STBTT_assert(i != 0);
5039                         if(dist < min_dist) {
5040                             // check position along line
5041                             // x' = x0 + t*(x1-x0), y' = y0 + t*(y1-y0)
5042                             // minimize (x'-sx)*(x'-sx)+(y'-sy)*(y'-sy)
5043                             float dx = x1 - x0, dy = y1 - y0;
5044                             float px = x0 - sx, py = y0 - sy;
5045                             // minimize (px+t*dx)^2 + (py+t*dy)^2 = px*px + 2*px*dx*t + t^2*dx*dx + py*py + 2*py*dy*t + t^2*dy*dy
5046                             // derivative: 2*px*dx + 2*py*dy + (2*dx*dx+2*dy*dy)*t, set to 0 and solve
5047                             float t = -(px * dx + py * dy) / (dx * dx + dy * dy);
5048                             if(t >= 0.0f && t <= 1.0f)
5049                                 min_dist = dist;
5050                         }
5051                     }
5052                     else if(verts[i].type == STBTT_vcurve) {
5053                         float x2 = verts[i - 1].x * scale_x, y2 = verts[i - 1].y * scale_y;
5054                         float x1 = verts[i].cx * scale_x, y1 = verts[i].cy * scale_y;
5055                         float box_x0 = STBTT_min(STBTT_min(x0, x1), x2);
5056                         float box_y0 = STBTT_min(STBTT_min(y0, y1), y2);
5057                         float box_x1 = STBTT_max(STBTT_max(x0, x1), x2);
5058                         float box_y1 = STBTT_max(STBTT_max(y0, y1), y2);
5059                         // coarse culling against bbox to avoid computing cubic unnecessarily
5060                         if(sx > box_x0 - min_dist && sx < box_x1 + min_dist && sy > box_y0 - min_dist && sy < box_y1 + min_dist) {
5061                             int num = 0;
5062                             float ax = x1 - x0, ay = y1 - y0;
5063                             float bx = x0 - 2 * x1 + x2, by = y0 - 2 * y1 + y2;
5064                             float mx = x0 - sx, my = y0 - sy;
5065                             float res[3] = { 0.f, 0.f, 0.f };
5066                             float px, py, t, it, dist2;
5067                             float a_inv = precompute[i];
5068                             if(a_inv == 0.0f) {  // if a_inv is 0, it's 2nd degree so use quadratic formula
5069                                 float a = 3 * (ax * bx + ay * by);
5070                                 float b = 2 * (ax * ax + ay * ay) + (mx * bx + my * by);
5071                                 float c = mx * ax + my * ay;
5072                                 if(a == 0.0f) {  // if a is 0, it's linear
5073                                     if(b != 0.0f) {
5074                                         res[num++] = -c / b;
5075                                     }
5076                                 }
5077                                 else {
5078                                     float discriminant = b * b - 4 * a * c;
5079                                     if(discriminant < 0)
5080                                         num = 0;
5081                                     else {
5082                                         float root = (float)STBTT_sqrt(discriminant);
5083                                         res[0] = (-b - root) / (2 * a);
5084                                         res[1] = (-b + root) / (2 * a);
5085                                         num = 2; // don't bother distinguishing 1-solution case, as code below will still work
5086                                     }
5087                                 }
5088                             }
5089                             else {
5090                                 float b = 3 * (ax * bx + ay * by) * a_inv; // could precompute this as it doesn't depend on sample point
5091                                 float c = (2 * (ax * ax + ay * ay) + (mx * bx + my * by)) * a_inv;
5092                                 float d = (mx * ax + my * ay) * a_inv;
5093                                 num = stbtt__solve_cubic(b, c, d, res);
5094                             }
5095                             dist2 = (x0 - sx) * (x0 - sx) + (y0 - sy) * (y0 - sy);
5096                             if(dist2 < min_dist * min_dist)
5097                                 min_dist = (float)STBTT_sqrt(dist2);
5098 
5099                             if(num >= 1 && res[0] >= 0.0f && res[0] <= 1.0f) {
5100                                 t = res[0], it = 1.0f - t;
5101                                 px = it * it * x0 + 2 * t * it * x1 + t * t * x2;
5102                                 py = it * it * y0 + 2 * t * it * y1 + t * t * y2;
5103                                 dist2 = (px - sx) * (px - sx) + (py - sy) * (py - sy);
5104                                 if(dist2 < min_dist * min_dist)
5105                                     min_dist = (float)STBTT_sqrt(dist2);
5106                             }
5107                             if(num >= 2 && res[1] >= 0.0f && res[1] <= 1.0f) {
5108                                 t = res[1], it = 1.0f - t;
5109                                 px = it * it * x0 + 2 * t * it * x1 + t * t * x2;
5110                                 py = it * it * y0 + 2 * t * it * y1 + t * t * y2;
5111                                 dist2 = (px - sx) * (px - sx) + (py - sy) * (py - sy);
5112                                 if(dist2 < min_dist * min_dist)
5113                                     min_dist = (float)STBTT_sqrt(dist2);
5114                             }
5115                             if(num >= 3 && res[2] >= 0.0f && res[2] <= 1.0f) {
5116                                 t = res[2], it = 1.0f - t;
5117                                 px = it * it * x0 + 2 * t * it * x1 + t * t * x2;
5118                                 py = it * it * y0 + 2 * t * it * y1 + t * t * y2;
5119                                 dist2 = (px - sx) * (px - sx) + (py - sy) * (py - sy);
5120                                 if(dist2 < min_dist * min_dist)
5121                                     min_dist = (float)STBTT_sqrt(dist2);
5122                             }
5123                         }
5124                     }
5125                 }
5126                 if(winding == 0)
5127                     min_dist = -min_dist;  // if outside the shape, value is negative
5128                 val = onedge_value + pixel_dist_scale * min_dist;
5129                 if(val < 0)
5130                     val = 0;
5131                 else if(val > 255)
5132                     val = 255;
5133                 data[(y - iy0) * w + (x - ix0)] = (unsigned char)val;
5134             }
5135         }
5136         STBTT_free(precompute, info->userdata);
5137         STBTT_free(verts, info->userdata);
5138     }
5139     return data;
5140 }
5141 
5142 STBTT_DEF unsigned char * stbtt_GetCodepointSDF(const stbtt_fontinfo * info, float scale, int codepoint, int padding,
5143                                                 unsigned char onedge_value, float pixel_dist_scale, int * width, int * height, int * xoff, int * yoff)
5144 {
5145     return stbtt_GetGlyphSDF(info, scale, stbtt_FindGlyphIndex(info, codepoint), padding, onedge_value, pixel_dist_scale,
5146                              width, height, xoff, yoff);
5147 }
5148 
5149 STBTT_DEF void stbtt_FreeSDF(unsigned char * bitmap, void * userdata)
5150 {
5151     STBTT_free(bitmap, userdata);
5152 }
5153 
5154 //////////////////////////////////////////////////////////////////////////////
5155 //
5156 // font name matching -- recommended not to use this
5157 //
5158 
5159 // check if a utf8 string contains a prefix which is the utf16 string; if so return length of matching utf8 string
5160 #ifdef STBTT_STREAM_TYPE
5161 static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(stbtt_uint8 * s1, stbtt_int32 len1, STBTT_STREAM_TYPE s2,
5162                                                               stbtt_uint32 s2offs, stbtt_int32 len2)
5163 #else
5164 static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(stbtt_uint8 * s1, stbtt_int32 len1, stbtt_uint8 * s2,
5165                                                               stbtt_uint32 s2offs, stbtt_int32 len2)
5166 #endif
5167 {
5168     stbtt_int32 i = 0;
5169 
5170     // convert utf16 to utf8 and compare the results while converting
5171     while(len2) {
5172         stbtt_uint16 ch = ttUSHORT(s2, s2offs);
5173         if(ch < 0x80) {
5174             if(i >= len1) return -1;
5175             if(s1[i++] != ch) return -1;
5176         }
5177         else if(ch < 0x800) {
5178             if(i + 1 >= len1) return -1;
5179             if(s1[i++] != 0xc0 + (ch >> 6)) return -1;
5180             if(s1[i++] != 0x80 + (ch & 0x3f)) return -1;
5181         }
5182         else if(ch >= 0xd800 && ch < 0xdc00) {
5183             stbtt_uint32 c;
5184             stbtt_uint16 ch2 = ttUSHORT(s2, s2offs + 2);
5185             if(i + 3 >= len1) return -1;
5186             c = ((ch - 0xd800) << 10) + (ch2 - 0xdc00) + 0x10000;
5187             if(s1[i++] != 0xf0 + (c >> 18)) return -1;
5188             if(s1[i++] != 0x80 + ((c >> 12) & 0x3f)) return -1;
5189             if(s1[i++] != 0x80 + ((c >> 6) & 0x3f)) return -1;
5190             if(s1[i++] != 0x80 + ((c) & 0x3f)) return -1;
5191             s2offs += 2; // plus another 2 below
5192             len2 -= 2;
5193         }
5194         else if(ch >= 0xdc00 && ch < 0xe000) {
5195             return -1;
5196         }
5197         else {
5198             if(i + 2 >= len1) return -1;
5199             if(s1[i++] != 0xe0 + (ch >> 12)) return -1;
5200             if(s1[i++] != 0x80 + ((ch >> 6) & 0x3f)) return -1;
5201             if(s1[i++] != 0x80 + ((ch) & 0x3f)) return -1;
5202         }
5203         s2offs += 2;
5204         len2 -= 2;
5205     }
5206     return i;
5207 }
5208 #ifdef STBTT_STREAM_TYPE
5209 static int stbtt_CompareUTF8toUTF16_bigendian_internal(char * s1, int len1, STBTT_STREAM_TYPE s2, stbtt_uint32 s2offs,
5210                                                        int len2)
5211 {
5212     return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((stbtt_uint8 *)s1, len1, s2, s2offs, len2);
5213 }
5214 #else
5215 static int stbtt_CompareUTF8toUTF16_bigendian_internal(char * s1, int len1, char * s2, stbtt_uint32 s2offs, int len2)
5216 {
5217     return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((stbtt_uint8 *)s1, len1, (stbtt_uint8 *)s2, s2offs, len2);
5218 }
5219 #endif
5220 // returns results in whatever encoding you request... but note that 2-byte encodings
5221 // will be BIG-ENDIAN... use stbtt_CompareUTF8toUTF16_bigendian() to compare
5222 STBTT_DEF stbtt_uint32 stbtt_GetFontNameString(const stbtt_fontinfo * font, int * length, int platformID,
5223                                                int encodingID, int languageID, int nameID)
5224 {
5225     stbtt_int32 i, count, stringOffset;
5226     stbtt_uint32 offset = font->fontstart;
5227     stbtt_uint32 nm = stbtt__find_table(font->data, offset, "name");
5228     if(!nm) return 0;
5229 
5230     count = ttUSHORT(font->data, nm + 2);
5231     stringOffset = nm + ttUSHORT(font->data, nm + 4);
5232     for(i = 0; i < count; ++i) {
5233         stbtt_uint32 loc = nm + 6 + 12 * i;
5234         if(platformID == ttUSHORT(font->data, loc + 0) && encodingID == ttUSHORT(font->data, loc + 2)
5235            && languageID == ttUSHORT(font->data, loc + 4) && nameID == ttUSHORT(font->data, loc + 6)) {
5236             *length = ttUSHORT(font->data, loc + 8);
5237             return stringOffset + ttUSHORT(font->data, loc + 10);
5238         }
5239     }
5240     return 0;
5241 }
5242 #ifdef STBTT_STREAM_TYPE
5243 static int stbtt__matchpair(STBTT_STREAM_TYPE fc, stbtt_uint32 nm, stbtt_uint8 * name, stbtt_int32 nlen,
5244                             stbtt_int32 target_id, stbtt_int32 next_id)
5245 #else
5246 static int stbtt__matchpair(stbtt_uint8 * fc, stbtt_uint32 nm, stbtt_uint8 * name, stbtt_int32 nlen,
5247                             stbtt_int32 target_id, stbtt_int32 next_id)
5248 #endif
5249 {
5250     stbtt_int32 i;
5251     stbtt_int32 count = ttUSHORT(fc, nm + 2);
5252     stbtt_int32 stringOffset = nm + ttUSHORT(fc, nm + 4);
5253 
5254     for(i = 0; i < count; ++i) {
5255         stbtt_uint32 loc = nm + 6 + 12 * i;
5256         stbtt_int32 id = ttUSHORT(fc, loc + 6);
5257         if(id == target_id) {
5258             // find the encoding
5259             stbtt_int32 platform = ttUSHORT(fc, loc + 0), encoding = ttUSHORT(fc, loc + 2), language = ttUSHORT(fc, loc + 4);
5260 
5261             // is this a Unicode encoding?
5262             if(platform == 0 || (platform == 3 && encoding == 1) || (platform == 3 && encoding == 10)) {
5263                 stbtt_int32 slen = ttUSHORT(fc, loc + 8);
5264                 stbtt_int32 off = ttUSHORT(fc, loc + 10);
5265 
5266                 // check if there's a prefix match
5267                 stbtt_int32 matchlen = stbtt__CompareUTF8toUTF16_bigendian_prefix(name, nlen, fc, stringOffset + off, slen);
5268                 if(matchlen >= 0) {
5269                     // check for target_id+1 immediately following, with same encoding & language
5270                     if(i + 1 < count && ttUSHORT(fc, loc + 12 + 6) == next_id && ttUSHORT(fc, loc + 12) == platform &&
5271                        ttUSHORT(fc, loc + 12 + 2) == encoding && ttUSHORT(fc, loc + 12 + 4) == language) {
5272                         slen = ttUSHORT(fc, loc + 12 + 8);
5273                         off = ttUSHORT(fc, loc + 12 + 10);
5274                         if(slen == 0) {
5275                             if(matchlen == nlen)
5276                                 return 1;
5277                         }
5278                         else if(matchlen < nlen && name[matchlen] == ' ') {
5279                             ++matchlen;
5280 #ifdef STBTT_STREAM_TYPE
5281                             if(stbtt_CompareUTF8toUTF16_bigendian_internal((char *)(name + matchlen), nlen - matchlen, fc, stringOffset + off,
5282                                                                            slen))
5283 #else
5284                             if(stbtt_CompareUTF8toUTF16_bigendian_internal((char *)(name + matchlen), nlen - matchlen, (char *)fc,
5285                                                                            stringOffset + off, slen))
5286 #endif
5287                                 return 1;
5288                         }
5289                     }
5290                     else {
5291                         // if nothing immediately following
5292                         if(matchlen == nlen)
5293                             return 1;
5294                     }
5295                 }
5296             }
5297 
5298             // @TODO handle other encodings
5299         }
5300     }
5301     return 0;
5302 }
5303 #ifdef STBTT_STREAM_TYPE
5304     static int stbtt__matches(STBTT_STREAM_TYPE fc, stbtt_uint32 offset, stbtt_uint8 * name, stbtt_int32 flags)
5305 #else
5306     static int stbtt__matches(stbtt_uint8 * fc, stbtt_uint32 offset, stbtt_uint8 * name, stbtt_int32 flags)
5307 #endif
5308 
5309 {
5310     stbtt_int32 nlen = (stbtt_int32)STBTT_strlen((char *)name);
5311     stbtt_uint32 nm, hd;
5312     if(!stbtt__isfont(fc, offset)) return 0;
5313 
5314     // check italics/bold/underline flags in macStyle...
5315     if(flags) {
5316         hd = stbtt__find_table(fc, offset, "head");
5317         if((ttUSHORT(fc, hd + 44) & 7) != (flags & 7)) return 0;
5318     }
5319 
5320     nm = stbtt__find_table(fc, offset, "name");
5321     if(!nm) return 0;
5322 
5323     if(flags) {
5324         if(name == NULL) return 1;
5325         // if we checked the macStyle flags, then just check the family and ignore the subfamily
5326         if(stbtt__matchpair(fc, nm, name, nlen, 16, -1))  return 1;
5327         if(stbtt__matchpair(fc, nm, name, nlen, 1, -1))  return 1;
5328         if(stbtt__matchpair(fc, nm, name, nlen, 3, -1))  return 1;
5329     }
5330     else {
5331         if(name == NULL) return 1;
5332         if(stbtt__matchpair(fc, nm, name, nlen, 16, 17))  return 1;
5333         if(stbtt__matchpair(fc, nm, name, nlen, 1, 2))  return 1;
5334         if(stbtt__matchpair(fc, nm, name, nlen, 3, -1))  return 1;
5335     }
5336 
5337     return 0;
5338 }
5339 #ifdef STBTT_STREAM_TYPE
5340     static int stbtt_FindMatchingFont_internal(STBTT_STREAM_TYPE font_collection, char * name_utf8, stbtt_int32 flags)
5341 #else
5342     static int stbtt_FindMatchingFont_internal(unsigned char * font_collection, char * name_utf8, stbtt_int32 flags)
5343 #endif
5344 {
5345     stbtt_int32 i;
5346     for(i = 0;; ++i) {
5347         stbtt_int32 off = stbtt_GetFontOffsetForIndex(font_collection, i);
5348         if(off < 0) return off;
5349 #ifdef STBTT_STREAM_TYPE
5350         if(stbtt__matches(font_collection, off, (stbtt_uint8 *)name_utf8, flags))
5351 #else
5352         if(stbtt__matches((stbtt_uint8 *)font_collection, off, (stbtt_uint8 *)name_utf8, flags))
5353 #endif
5354             return off;
5355     }
5356 }
5357 
5358 #if defined(__GNUC__) || defined(__clang__)
5359     #pragma GCC diagnostic push
5360     #pragma GCC diagnostic ignored "-Wcast-qual"
5361 #endif
5362 
5363 #ifdef STBTT_STREAM_TYPE
5364 STBTT_DEF int stbtt_BakeFontBitmap(STBTT_STREAM_TYPE data, int offset,
5365                                    float pixel_height, unsigned char * pixels, int pw, int ph,
5366                                    int first_char, int num_chars, stbtt_bakedchar * chardata);
5367 #else
5368 STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char * data, int offset,
5369                                    float pixel_height, unsigned char * pixels, int pw, int ph,
5370                                    int first_char, int num_chars, stbtt_bakedchar * chardata);
5371 #endif
5372 
5373 #ifdef STBTT_STREAM_TYPE
5374 STBTT_DEF int stbtt_BakeFontBitmap(STBTT_STREAM_TYPE data, int offset,
5375                                    float pixel_height, unsigned char * pixels, int pw, int ph,
5376                                    int first_char, int num_chars, stbtt_bakedchar * chardata)
5377 #else
5378 STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char * data, int offset,
5379                                    float pixel_height, unsigned char * pixels, int pw, int ph,
5380                                    int first_char, int num_chars, stbtt_bakedchar * chardata)
5381 #endif
5382 {
5383 #ifdef STBTT_STREAM_TYPE
5384     return stbtt_BakeFontBitmap_internal(data, offset, pixel_height, pixels, pw, ph, first_char, num_chars, chardata);
5385 #else
5386     return stbtt_BakeFontBitmap_internal((unsigned char *)data, offset, pixel_height, pixels, pw, ph, first_char, num_chars,
5387                                          chardata);
5388 #endif
5389 }
5390 #ifdef STBTT_STREAM_TYPE
5391 STBTT_DEF int stbtt_GetFontOffsetForIndex(STBTT_STREAM_TYPE data, int index)
5392 {
5393     return stbtt_GetFontOffsetForIndex_internal(data, index);
5394 }
5395 #else
5396 STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char * data, int index)
5397 {
5398     return stbtt_GetFontOffsetForIndex_internal((unsigned char *)data, index);
5399 }
5400 #endif
5401 #ifdef STBTT_STREAM_TYPE
5402 STBTT_DEF int stbtt_GetNumberOfFonts(STBTT_STREAM_TYPE data)
5403 {
5404     return stbtt_GetNumberOfFonts_internal(data);
5405 }
5406 #else
5407 STBTT_DEF int stbtt_GetNumberOfFonts(const unsigned char * data)
5408 {
5409     return stbtt_GetNumberOfFonts_internal((unsigned char *)data);
5410 }
5411 #endif
5412 #ifdef STBTT_STREAM_TYPE
5413 STBTT_DEF int stbtt_InitFont(stbtt_fontinfo * info, STBTT_STREAM_TYPE data, int offset)
5414 {
5415     return stbtt_InitFont_internal(info, data, offset);
5416 }
5417 #else
5418 STBTT_DEF int stbtt_InitFont(stbtt_fontinfo * info, const unsigned char * data, int offset)
5419 {
5420     return stbtt_InitFont_internal(info, (unsigned char *)data, offset);
5421 }
5422 #endif
5423 #ifdef STBTT_STREAM_TYPE
5424 STBTT_DEF int stbtt_FindMatchingFont(STBTT_STREAM_TYPE fontdata, const char * name, int flags)
5425 {
5426     return stbtt_FindMatchingFont_internal(fontdata, (char *)name, flags);
5427 }
5428 #else
5429 STBTT_DEF int stbtt_FindMatchingFont(const unsigned char * fontdata, const char * name, int flags)
5430 {
5431     return stbtt_FindMatchingFont_internal((unsigned char *)fontdata, (char *)name, flags);
5432 }
5433 #endif
5434 #ifdef STBTT_STREAM_TYPE
5435 STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char * s1, int len1, STBTT_STREAM_TYPE s2, stbtt_uint32 s2offs,
5436                                                  int len2)
5437 {
5438     return stbtt_CompareUTF8toUTF16_bigendian_internal((char *)s1, len1, s2, s2offs, len2);
5439 }
5440 #else
5441 STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char * s1, int len1, const char * s2, stbtt_uint32 s2offs,
5442                                                  int len2)
5443 {
5444     return stbtt_CompareUTF8toUTF16_bigendian_internal((char *)s1, len1, (char *)s2, s2offs, len2);
5445 }
5446 #endif
5447 
5448 #if defined(__GNUC__) || defined(__clang__)
5449     #pragma GCC diagnostic pop
5450     #pragma GCC diagnostic pop
5451 #endif
5452 
5453 #endif // STB_TRUETYPE_IMPLEMENTATION
5454 
5455 // FULL VERSION HISTORY
5456 //
5457 //   1.25 (2021-07-11) many fixes
5458 //   1.24 (2020-02-05) fix warning
5459 //   1.23 (2020-02-02) query SVG data for glyphs; query whole kerning table (but only kern not GPOS)
5460 //   1.22 (2019-08-11) minimize missing-glyph duplication; fix kerning if both 'GPOS' and 'kern' are defined
5461 //   1.21 (2019-02-25) fix warning
5462 //   1.20 (2019-02-07) PackFontRange skips missing codepoints; GetScaleFontVMetrics()
5463 //   1.19 (2018-02-11) OpenType GPOS kerning (horizontal only), STBTT_fmod
5464 //   1.18 (2018-01-29) add missing function
5465 //   1.17 (2017-07-23) make more arguments const; doc fix
5466 //   1.16 (2017-07-12) SDF support
5467 //   1.15 (2017-03-03) make more arguments const
5468 //   1.14 (2017-01-16) num-fonts-in-TTC function
5469 //   1.13 (2017-01-02) support OpenType fonts, certain Apple fonts
5470 //   1.12 (2016-10-25) suppress warnings about casting away const with -Wcast-qual
5471 //   1.11 (2016-04-02) fix unused-variable warning
5472 //   1.10 (2016-04-02) allow user-defined fabs() replacement
5473 //                     fix memory leak if fontsize=0.0
5474 //                     fix warning from duplicate typedef
5475 //   1.09 (2016-01-16) warning fix; avoid crash on outofmem; use alloc userdata for PackFontRanges
5476 //   1.08 (2015-09-13) document stbtt_Rasterize(); fixes for vertical & horizontal edges
5477 //   1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints;
5478 //                     allow PackFontRanges to pack and render in separate phases;
5479 //                     fix stbtt_GetFontOFfsetForIndex (never worked for non-0 input?);
5480 //                     fixed an assert() bug in the new rasterizer
5481 //                     replace assert() with STBTT_assert() in new rasterizer
5482 //   1.06 (2015-07-14) performance improvements (~35% faster on x86 and x64 on test machine)
5483 //                     also more precise AA rasterizer, except if shapes overlap
5484 //                     remove need for STBTT_sort
5485 //   1.05 (2015-04-15) fix misplaced definitions for STBTT_STATIC
5486 //   1.04 (2015-04-15) typo in example
5487 //   1.03 (2015-04-12) STBTT_STATIC, fix memory leak in new packing, various fixes
5488 //   1.02 (2014-12-10) fix various warnings & compile issues w/ stb_rect_pack, C++
5489 //   1.01 (2014-12-08) fix subpixel position when oversampling to exactly match
5490 //                        non-oversampled; STBTT_POINT_SIZE for packed case only
5491 //   1.00 (2014-12-06) add new PackBegin etc. API, w/ support for oversampling
5492 //   0.99 (2014-09-18) fix multiple bugs with subpixel rendering (ryg)
5493 //   0.9  (2014-08-07) support certain mac/iOS fonts without an MS platformID
5494 //   0.8b (2014-07-07) fix a warning
5495 //   0.8  (2014-05-25) fix a few more warnings
5496 //   0.7  (2013-09-25) bugfix: subpixel glyph bug fixed in 0.5 had come back
5497 //   0.6c (2012-07-24) improve documentation
5498 //   0.6b (2012-07-20) fix a few more warnings
5499 //   0.6  (2012-07-17) fix warnings; added stbtt_ScaleForMappingEmToPixels,
5500 //                        stbtt_GetFontBoundingBox, stbtt_IsGlyphEmpty
5501 //   0.5  (2011-12-09) bugfixes:
5502 //                        subpixel glyph renderer computed wrong bounding box
5503 //                        first vertex of shape can be off-curve (FreeSans)
5504 //   0.4b (2011-12-03) fixed an error in the font baking example
5505 //   0.4  (2011-12-01) kerning, subpixel rendering (tor)
5506 //                    bugfixes for:
5507 //                        codepoint-to-glyph conversion using table fmt=12
5508 //                        codepoint-to-glyph conversion using table fmt=4
5509 //                        stbtt_GetBakedQuad with non-square texture (Zer)
5510 //                    updated Hello World! sample to use kerning and subpixel
5511 //                    fixed some warnings
5512 //   0.3  (2009-06-24) cmap fmt=12, compound shapes (MM)
5513 //                    userdata, malloc-from-userdata, non-zero fill (stb)
5514 //   0.2  (2009-03-11) Fix unsigned/signed char warnings
5515 //   0.1  (2009-03-09) First public release
5516 //
5517 
5518 /*
5519 ------------------------------------------------------------------------------
5520 This software is available under 2 licenses -- choose whichever you prefer.
5521 ------------------------------------------------------------------------------
5522 ALTERNATIVE A - MIT License
5523 Copyright (c) 2017 Sean Barrett
5524 Permission is hereby granted, free of charge, to any person obtaining a copy of
5525 this software and associated documentation files (the "Software"), to deal in
5526 the Software without restriction, including without limitation the rights to
5527 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
5528 of the Software, and to permit persons to whom the Software is furnished to do
5529 so, subject to the following conditions:
5530 The above copyright notice and this permission notice shall be included in all
5531 copies or substantial portions of the Software.
5532 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
5533 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
5534 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
5535 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
5536 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
5537 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
5538 SOFTWARE.
5539 ------------------------------------------------------------------------------
5540 ALTERNATIVE B - Public Domain (www.unlicense.org)
5541 This is free and unencumbered software released into the public domain.
5542 Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
5543 software, either in source code form or as a compiled binary, for any purpose,
5544 commercial or non-commercial, and by any means.
5545 In jurisdictions that recognize copyright laws, the author or authors of this
5546 software dedicate any and all copyright interest in the software to the public
5547 domain. We make this dedication for the benefit of the public at large and to
5548 the detriment of our heirs and successors. We intend this dedication to be an
5549 overt act of relinquishment in perpetuity of all present and future rights to
5550 this software under copyright law.
5551 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
5552 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
5553 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
5554 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
5555 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
5556 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
5557 ------------------------------------------------------------------------------
5558 */
5559