duckstation

duckstation, but archived from the revision just before upstream changed it to a proprietary software project, this version is the libre one
git clone https://git.neptards.moe/u3shit/duckstation.git
Log | Files | Refs | README | LICENSE

imstb_truetype.h (199485B)


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