medfall

A super great game engine
Log | Files | Refs

stb_truetype.h (191325B)


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