waveshare_epaper

Waveshare e-paper display shenanigans
git clone git://bsandro.tech/waveshare_epaper
Log | Files | Refs | README

stb_truetype.h (199033B)


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