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