imgui

FORK: Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies
git clone https://git.neptards.moe/neptards/imgui.git
Log | Files | Refs

imstb_truetype.h (192489B)


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