DPF

DISTRHO Plugin Framework
Log | Files | Refs | Submodules | README | LICENSE

stb_truetype.h (195646B)


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