Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-09 07:49:52

0001 // stb_truetype.h - v1.26 - public domain
0002 // authored from 2009-2021 by Sean Barrett / RAD Game Tools
0003 //
0004 // =======================================================================
0005 //
0006 //    NO SECURITY GUARANTEE -- DO NOT USE THIS ON UNTRUSTED FONT FILES
0007 //
0008 // This library does no range checking of the offsets found in the file,
0009 // meaning an attacker can use it to read arbitrary memory.
0010 //
0011 // =======================================================================
0012 //
0013 //   This library processes TrueType files:
0014 //        parse files
0015 //        extract glyph metrics
0016 //        extract glyph shapes
0017 //        render glyphs to one-channel bitmaps with antialiasing (box filter)
0018 //        render glyphs to one-channel SDF bitmaps (signed-distance field/function)
0019 //
0020 //   Todo:
0021 //        non-MS cmaps
0022 //        crashproof on bad data
0023 //        hinting? (no longer patented)
0024 //        cleartype-style AA?
0025 //        optimize: use simple memory allocator for intermediates
0026 //        optimize: build edge-list directly from curves
0027 //        optimize: rasterize directly from curves?
0028 //
0029 // ADDITIONAL CONTRIBUTORS
0030 //
0031 //   Mikko Mononen: compound shape support, more cmap formats
0032 //   Tor Andersson: kerning, subpixel rendering
0033 //   Dougall Johnson: OpenType / Type 2 font handling
0034 //   Daniel Ribeiro Maciel: basic GPOS-based kerning
0035 //
0036 //   Misc other:
0037 //       Ryan Gordon
0038 //       Simon Glass
0039 //       github:IntellectualKitty
0040 //       Imanol Celaya
0041 //       Daniel Ribeiro Maciel
0042 //
0043 //   Bug/warning reports/fixes:
0044 //       "Zer" on mollyrocket       Fabian "ryg" Giesen   github:NiLuJe
0045 //       Cass Everitt               Martins Mozeiko       github:aloucks
0046 //       stoiko (Haemimont Games)   Cap Petschulat        github:oyvindjam
0047 //       Brian Hook                 Omar Cornut           github:vassvik
0048 //       Walter van Niftrik         Ryan Griege
0049 //       David Gow                  Peter LaValle
0050 //       David Given                Sergey Popov
0051 //       Ivan-Assen Ivanov          Giumo X. Clanjor
0052 //       Anthony Pesch              Higor Euripedes
0053 //       Johan Duparc               Thomas Fields
0054 //       Hou Qiming                 Derek Vinyard
0055 //       Rob Loach                  Cort Stratton
0056 //       Kenney Phillis Jr.         Brian Costabile
0057 //       Ken Voskuil (kaesve)       Yakov Galka
0058 //
0059 // VERSION HISTORY
0060 //
0061 //   1.26 (2021-08-28) fix broken rasterizer
0062 //   1.25 (2021-07-11) many fixes
0063 //   1.24 (2020-02-05) fix warning
0064 //   1.23 (2020-02-02) query SVG data for glyphs; query whole kerning table (but only kern not GPOS)
0065 //   1.22 (2019-08-11) minimize missing-glyph duplication; fix kerning if both 'GPOS' and 'kern' are defined
0066 //   1.21 (2019-02-25) fix warning
0067 //   1.20 (2019-02-07) PackFontRange skips missing codepoints; GetScaleFontVMetrics()
0068 //   1.19 (2018-02-11) GPOS kerning, STBTT_fmod
0069 //   1.18 (2018-01-29) add missing function
0070 //   1.17 (2017-07-23) make more arguments const; doc fix
0071 //   1.16 (2017-07-12) SDF support
0072 //   1.15 (2017-03-03) make more arguments const
0073 //   1.14 (2017-01-16) num-fonts-in-TTC function
0074 //   1.13 (2017-01-02) support OpenType fonts, certain Apple fonts
0075 //   1.12 (2016-10-25) suppress warnings about casting away const with -Wcast-qual
0076 //   1.11 (2016-04-02) fix unused-variable warning
0077 //   1.10 (2016-04-02) user-defined fabs(); rare memory leak; remove duplicate typedef
0078 //   1.09 (2016-01-16) warning fix; avoid crash on outofmem; use allocation userdata properly
0079 //   1.08 (2015-09-13) document stbtt_Rasterize(); fixes for vertical & horizontal edges
0080 //   1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints;
0081 //                     variant PackFontRanges to pack and render in separate phases;
0082 //                     fix stbtt_GetFontOFfsetForIndex (never worked for non-0 input?);
0083 //                     fixed an assert() bug in the new rasterizer
0084 //                     replace assert() with STBTT_assert() in new rasterizer
0085 //
0086 //   Full history can be found at the end of this file.
0087 //
0088 // LICENSE
0089 //
0090 //   See end of file for license information.
0091 //
0092 // USAGE
0093 //
0094 //   Include this file in whatever places need to refer to it. In ONE C/C++
0095 //   file, write:
0096 //      #define STB_TRUETYPE_IMPLEMENTATION
0097 //   before the #include of this file. This expands out the actual
0098 //   implementation into that C/C++ file.
0099 //
0100 //   To make the implementation private to the file that generates the implementation,
0101 //      #define STBTT_STATIC
0102 //
0103 //   Simple 3D API (don't ship this, but it's fine for tools and quick start)
0104 //           stbtt_BakeFontBitmap()               -- bake a font to a bitmap for use as texture
0105 //           stbtt_GetBakedQuad()                 -- compute quad to draw for a given char
0106 //
0107 //   Improved 3D API (more shippable):
0108 //           #include "stb_rect_pack.h"           -- optional, but you really want it
0109 //           stbtt_PackBegin()
0110 //           stbtt_PackSetOversampling()          -- for improved quality on small fonts
0111 //           stbtt_PackFontRanges()               -- pack and renders
0112 //           stbtt_PackEnd()
0113 //           stbtt_GetPackedQuad()
0114 //
0115 //   "Load" a font file from a memory buffer (you have to keep the buffer loaded)
0116 //           stbtt_InitFont()
0117 //           stbtt_GetFontOffsetForIndex()        -- indexing for TTC font collections
0118 //           stbtt_GetNumberOfFonts()             -- number of fonts for TTC font collections
0119 //
0120 //   Render a unicode codepoint to a bitmap
0121 //           stbtt_GetCodepointBitmap()           -- allocates and returns a bitmap
0122 //           stbtt_MakeCodepointBitmap()          -- renders into bitmap you provide
0123 //           stbtt_GetCodepointBitmapBox()        -- how big the bitmap must be
0124 //
0125 //   Character advance/positioning
0126 //           stbtt_GetCodepointHMetrics()
0127 //           stbtt_GetFontVMetrics()
0128 //           stbtt_GetFontVMetricsOS2()
0129 //           stbtt_GetCodepointKernAdvance()
0130 //
0131 //   Starting with version 1.06, the rasterizer was replaced with a new,
0132 //   faster and generally-more-precise rasterizer. The new rasterizer more
0133 //   accurately measures pixel coverage for anti-aliasing, except in the case
0134 //   where multiple shapes overlap, in which case it overestimates the AA pixel
0135 //   coverage. Thus, anti-aliasing of intersecting shapes may look wrong. If
0136 //   this turns out to be a problem, you can re-enable the old rasterizer with
0137 //        #define STBTT_RASTERIZER_VERSION 1
0138 //   which will incur about a 15% speed hit.
0139 //
0140 // ADDITIONAL DOCUMENTATION
0141 //
0142 //   Immediately after this block comment are a series of sample programs.
0143 //
0144 //   After the sample programs is the "header file" section. This section
0145 //   includes documentation for each API function.
0146 //
0147 //   Some important concepts to understand to use this library:
0148 //
0149 //      Codepoint
0150 //         Characters are defined by unicode codepoints, e.g. 65 is
0151 //         uppercase A, 231 is lowercase c with a cedilla, 0x7e30 is
0152 //         the hiragana for "ma".
0153 //
0154 //      Glyph
0155 //         A visual character shape (every codepoint is rendered as
0156 //         some glyph)
0157 //
0158 //      Glyph index
0159 //         A font-specific integer ID representing a glyph
0160 //
0161 //      Baseline
0162 //         Glyph shapes are defined relative to a baseline, which is the
0163 //         bottom of uppercase characters. Characters extend both above
0164 //         and below the baseline.
0165 //
0166 //      Current Point
0167 //         As you draw text to the screen, you keep track of a "current point"
0168 //         which is the origin of each character. The current point's vertical
0169 //         position is the baseline. Even "baked fonts" use this model.
0170 //
0171 //      Vertical Font Metrics
0172 //         The vertical qualities of the font, used to vertically position
0173 //         and space the characters. See docs for stbtt_GetFontVMetrics.
0174 //
0175 //      Font Size in Pixels or Points
0176 //         The preferred interface for specifying font sizes in stb_truetype
0177 //         is to specify how tall the font's vertical extent should be in pixels.
0178 //         If that sounds good enough, skip the next paragraph.
0179 //
0180 //         Most font APIs instead use "points", which are a common typographic
0181 //         measurement for describing font size, defined as 72 points per inch.
0182 //         stb_truetype provides a point API for compatibility. However, true
0183 //         "per inch" conventions don't make much sense on computer displays
0184 //         since different monitors have different number of pixels per
0185 //         inch. For example, Windows traditionally uses a convention that
0186 //         there are 96 pixels per inch, thus making 'inch' measurements have
0187 //         nothing to do with inches, and thus effectively defining a point to
0188 //         be 1.333 pixels. Additionally, the TrueType font data provides
0189 //         an explicit scale factor to scale a given font's glyphs to points,
0190 //         but the author has observed that this scale factor is often wrong
0191 //         for non-commercial fonts, thus making fonts scaled in points
0192 //         according to the TrueType spec incoherently sized in practice.
0193 //
0194 // DETAILED USAGE:
0195 //
0196 //  Scale:
0197 //    Select how high you want the font to be, in points or pixels.
0198 //    Call ScaleForPixelHeight or ScaleForMappingEmToPixels to compute
0199 //    a scale factor SF that will be used by all other functions.
0200 //
0201 //  Baseline:
0202 //    You need to select a y-coordinate that is the baseline of where
0203 //    your text will appear. Call GetFontBoundingBox to get the baseline-relative
0204 //    bounding box for all characters. SF*-y0 will be the distance in pixels
0205 //    that the worst-case character could extend above the baseline, so if
0206 //    you want the top edge of characters to appear at the top of the
0207 //    screen where y=0, then you would set the baseline to SF*-y0.
0208 //
0209 //  Current point:
0210 //    Set the current point where the first character will appear. The
0211 //    first character could extend left of the current point; this is font
0212 //    dependent. You can either choose a current point that is the leftmost
0213 //    point and hope, or add some padding, or check the bounding box or
0214 //    left-side-bearing of the first character to be displayed and set
0215 //    the current point based on that.
0216 //
0217 //  Displaying a character:
0218 //    Compute the bounding box of the character. It will contain signed values
0219 //    relative to <current_point, baseline>. I.e. if it returns x0,y0,x1,y1,
0220 //    then the character should be displayed in the rectangle from
0221 //    <current_point+SF*x0, baseline+SF*y0> to <current_point+SF*x1,baseline+SF*y1).
0222 //
0223 //  Advancing for the next character:
0224 //    Call GlyphHMetrics, and compute 'current_point += SF * advance'.
0225 //
0226 //
0227 // ADVANCED USAGE
0228 //
0229 //   Quality:
0230 //
0231 //    - Use the functions with Subpixel at the end to allow your characters
0232 //      to have subpixel positioning. Since the font is anti-aliased, not
0233 //      hinted, this is very import for quality. (This is not possible with
0234 //      baked fonts.)
0235 //
0236 //    - Kerning is now supported, and if you're supporting subpixel rendering
0237 //      then kerning is worth using to give your text a polished look.
0238 //
0239 //   Performance:
0240 //
0241 //    - Convert Unicode codepoints to glyph indexes and operate on the glyphs;
0242 //      if you don't do this, stb_truetype is forced to do the conversion on
0243 //      every call.
0244 //
0245 //    - There are a lot of memory allocations. We should modify it to take
0246 //      a temp buffer and allocate from the temp buffer (without freeing),
0247 //      should help performance a lot.
0248 //
0249 // NOTES
0250 //
0251 //   The system uses the raw data found in the .ttf file without changing it
0252 //   and without building auxiliary data structures. This is a bit inefficient
0253 //   on little-endian systems (the data is big-endian), but assuming you're
0254 //   caching the bitmaps or glyph shapes this shouldn't be a big deal.
0255 //
0256 //   It appears to be very hard to programmatically determine what font a
0257 //   given file is in a general way. I provide an API for this, but I don't
0258 //   recommend it.
0259 //
0260 //
0261 // PERFORMANCE MEASUREMENTS FOR 1.06:
0262 //
0263 //                      32-bit     64-bit
0264 //   Previous release:  8.83 s     7.68 s
0265 //   Pool allocations:  7.72 s     6.34 s
0266 //   Inline sort     :  6.54 s     5.65 s
0267 //   New rasterizer  :  5.63 s     5.00 s
0268 
0269 //////////////////////////////////////////////////////////////////////////////
0270 //////////////////////////////////////////////////////////////////////////////
0271 ////
0272 ////  SAMPLE PROGRAMS
0273 ////
0274 //
0275 //  Incomplete text-in-3d-api example, which draws quads properly aligned to be lossless.
0276 //  See "tests/truetype_demo_win32.c" for a complete version.
0277 #if 0
0278 #define STB_TRUETYPE_IMPLEMENTATION  // force following include to generate implementation
0279 #include "stb_truetype.h"
0280 
0281 unsigned char ttf_buffer[1<<20];
0282 unsigned char temp_bitmap[512*512];
0283 
0284 stbtt_bakedchar cdata[96]; // ASCII 32..126 is 95 glyphs
0285 GLuint ftex;
0286 
0287 void my_stbtt_initfont(void)
0288 {
0289    fread(ttf_buffer, 1, 1<<20, fopen("c:/windows/fonts/times.ttf", "rb"));
0290    stbtt_BakeFontBitmap(ttf_buffer,0, 32.0, temp_bitmap,512,512, 32,96, cdata); // no guarantee this fits!
0291    // can free ttf_buffer at this point
0292    glGenTextures(1, &ftex);
0293    glBindTexture(GL_TEXTURE_2D, ftex);
0294    glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 512,512, 0, GL_ALPHA, GL_UNSIGNED_BYTE, temp_bitmap);
0295    // can free temp_bitmap at this point
0296    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
0297 }
0298 
0299 void my_stbtt_print(float x, float y, char *text)
0300 {
0301    // assume orthographic projection with units = screen pixels, origin at top left
0302    glEnable(GL_BLEND);
0303    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
0304    glEnable(GL_TEXTURE_2D);
0305    glBindTexture(GL_TEXTURE_2D, ftex);
0306    glBegin(GL_QUADS);
0307    while (*text) {
0308       if (*text >= 32 && *text < 128) {
0309          stbtt_aligned_quad q;
0310          stbtt_GetBakedQuad(cdata, 512,512, *text-32, &x,&y,&q,1);//1=opengl & d3d10+,0=d3d9
0311          glTexCoord2f(q.s0,q.t0); glVertex2f(q.x0,q.y0);
0312          glTexCoord2f(q.s1,q.t0); glVertex2f(q.x1,q.y0);
0313          glTexCoord2f(q.s1,q.t1); glVertex2f(q.x1,q.y1);
0314          glTexCoord2f(q.s0,q.t1); glVertex2f(q.x0,q.y1);
0315       }
0316       ++text;
0317    }
0318    glEnd();
0319 }
0320 #endif
0321 //
0322 //
0323 //////////////////////////////////////////////////////////////////////////////
0324 //
0325 // Complete program (this compiles): get a single bitmap, print as ASCII art
0326 //
0327 #if 0
0328 #include <stdio.h>
0329 #define STB_TRUETYPE_IMPLEMENTATION  // force following include to generate implementation
0330 #include "stb_truetype.h"
0331 
0332 char ttf_buffer[1<<25];
0333 
0334 int main(int argc, char **argv)
0335 {
0336    stbtt_fontinfo font;
0337    unsigned char *bitmap;
0338    int w,h,i,j,c = (argc > 1 ? atoi(argv[1]) : 'a'), s = (argc > 2 ? atoi(argv[2]) : 20);
0339 
0340    fread(ttf_buffer, 1, 1<<25, fopen(argc > 3 ? argv[3] : "c:/windows/fonts/arialbd.ttf", "rb"));
0341 
0342    stbtt_InitFont(&font, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer,0));
0343    bitmap = stbtt_GetCodepointBitmap(&font, 0,stbtt_ScaleForPixelHeight(&font, s), c, &w, &h, 0,0);
0344 
0345    for (j=0; j < h; ++j) {
0346       for (i=0; i < w; ++i)
0347          putchar(" .:ioVM@"[bitmap[j*w+i]>>5]);
0348       putchar('\n');
0349    }
0350    return 0;
0351 }
0352 #endif
0353 //
0354 // Output:
0355 //
0356 //     .ii.
0357 //    @@@@@@.
0358 //   V@Mio@@o
0359 //   :i.  V@V
0360 //     :oM@@M
0361 //   :@@@MM@M
0362 //   @@o  o@M
0363 //  :@@.  M@M
0364 //   @@@o@@@@
0365 //   :M@@V:@@.
0366 //
0367 //////////////////////////////////////////////////////////////////////////////
0368 //
0369 // Complete program: print "Hello World!" banner, with bugs
0370 //
0371 #if 0
0372 char buffer[24<<20];
0373 unsigned char screen[20][79];
0374 
0375 int main(int arg, char **argv)
0376 {
0377    stbtt_fontinfo font;
0378    int i,j,ascent,baseline,ch=0;
0379    float scale, xpos=2; // leave a little padding in case the character extends left
0380    char *text = "Heljo World!"; // intentionally misspelled to show 'lj' brokenness
0381 
0382    fread(buffer, 1, 1000000, fopen("c:/windows/fonts/arialbd.ttf", "rb"));
0383    stbtt_InitFont(&font, buffer, 0);
0384 
0385    scale = stbtt_ScaleForPixelHeight(&font, 15);
0386    stbtt_GetFontVMetrics(&font, &ascent,0,0);
0387    baseline = (int) (ascent*scale);
0388 
0389    while (text[ch]) {
0390       int advance,lsb,x0,y0,x1,y1;
0391       float x_shift = xpos - (float) floor(xpos);
0392       stbtt_GetCodepointHMetrics(&font, text[ch], &advance, &lsb);
0393       stbtt_GetCodepointBitmapBoxSubpixel(&font, text[ch], scale,scale,x_shift,0, &x0,&y0,&x1,&y1);
0394       stbtt_MakeCodepointBitmapSubpixel(&font, &screen[baseline + y0][(int) xpos + x0], x1-x0,y1-y0, 79, scale,scale,x_shift,0, text[ch]);
0395       // note that this stomps the old data, so where character boxes overlap (e.g. 'lj') it's wrong
0396       // because this API is really for baking character bitmaps into textures. if you want to render
0397       // a sequence of characters, you really need to render each bitmap to a temp buffer, then
0398       // "alpha blend" that into the working buffer
0399       xpos += (advance * scale);
0400       if (text[ch+1])
0401          xpos += scale*stbtt_GetCodepointKernAdvance(&font, text[ch],text[ch+1]);
0402       ++ch;
0403    }
0404 
0405    for (j=0; j < 20; ++j) {
0406       for (i=0; i < 78; ++i)
0407          putchar(" .:ioVM@"[screen[j][i]>>5]);
0408       putchar('\n');
0409    }
0410 
0411    return 0;
0412 }
0413 #endif
0414 
0415 
0416 //////////////////////////////////////////////////////////////////////////////
0417 //////////////////////////////////////////////////////////////////////////////
0418 ////
0419 ////   INTEGRATION WITH YOUR CODEBASE
0420 ////
0421 ////   The following sections allow you to supply alternate definitions
0422 ////   of C library functions used by stb_truetype, e.g. if you don't
0423 ////   link with the C runtime library.
0424 
0425 #ifdef STB_TRUETYPE_IMPLEMENTATION
0426    // #define your own (u)stbtt_int8/16/32 before including to override this
0427    #ifndef stbtt_uint8
0428    typedef unsigned char   stbtt_uint8;
0429    typedef signed   char   stbtt_int8;
0430    typedef unsigned short  stbtt_uint16;
0431    typedef signed   short  stbtt_int16;
0432    typedef unsigned int    stbtt_uint32;
0433    typedef signed   int    stbtt_int32;
0434    #endif
0435 
0436    typedef char stbtt__check_size32[sizeof(stbtt_int32)==4 ? 1 : -1];
0437    typedef char stbtt__check_size16[sizeof(stbtt_int16)==2 ? 1 : -1];
0438 
0439    // e.g. #define your own STBTT_ifloor/STBTT_iceil() to avoid math.h
0440    #ifndef STBTT_ifloor
0441    #include <math.h>
0442    #define STBTT_ifloor(x)   ((int) floor(x))
0443    #define STBTT_iceil(x)    ((int) ceil(x))
0444    #endif
0445 
0446    #ifndef STBTT_sqrt
0447    #include <math.h>
0448    #define STBTT_sqrt(x)      sqrt(x)
0449    #define STBTT_pow(x,y)     pow(x,y)
0450    #endif
0451 
0452    #ifndef STBTT_fmod
0453    #include <math.h>
0454    #define STBTT_fmod(x,y)    fmod(x,y)
0455    #endif
0456 
0457    #ifndef STBTT_cos
0458    #include <math.h>
0459    #define STBTT_cos(x)       cos(x)
0460    #define STBTT_acos(x)      acos(x)
0461    #endif
0462 
0463    #ifndef STBTT_fabs
0464    #include <math.h>
0465    #define STBTT_fabs(x)      fabs(x)
0466    #endif
0467 
0468    // #define your own functions "STBTT_malloc" / "STBTT_free" to avoid malloc.h
0469    #ifndef STBTT_malloc
0470    #include <stdlib.h>
0471    #define STBTT_malloc(x,u)  ((void)(u),malloc(x))
0472    #define STBTT_free(x,u)    ((void)(u),free(x))
0473    #endif
0474 
0475    #ifndef STBTT_assert
0476    #include <assert.h>
0477    #define STBTT_assert(x)    assert(x)
0478    #endif
0479 
0480    #ifndef STBTT_strlen
0481    #include <string.h>
0482    #define STBTT_strlen(x)    strlen(x)
0483    #endif
0484 
0485    #ifndef STBTT_memcpy
0486    #include <string.h>
0487    #define STBTT_memcpy       memcpy
0488    #define STBTT_memset       memset
0489    #endif
0490 #endif
0491 
0492 ///////////////////////////////////////////////////////////////////////////////
0493 ///////////////////////////////////////////////////////////////////////////////
0494 ////
0495 ////   INTERFACE
0496 ////
0497 ////
0498 
0499 #ifndef __STB_INCLUDE_STB_TRUETYPE_H__
0500 #define __STB_INCLUDE_STB_TRUETYPE_H__
0501 
0502 #ifdef STBTT_STATIC
0503 #define STBTT_DEF static
0504 #else
0505 #define STBTT_DEF extern
0506 #endif
0507 
0508 #ifdef __cplusplus
0509 extern "C" {
0510 #endif
0511 
0512 // private structure
0513 typedef struct
0514 {
0515    unsigned char *data;
0516    int cursor;
0517    int size;
0518 } stbtt__buf;
0519 
0520 //////////////////////////////////////////////////////////////////////////////
0521 //
0522 // TEXTURE BAKING API
0523 //
0524 // If you use this API, you only have to call two functions ever.
0525 //
0526 
0527 typedef struct
0528 {
0529    unsigned short x0,y0,x1,y1; // coordinates of bbox in bitmap
0530    float xoff,yoff,xadvance;
0531 } stbtt_bakedchar;
0532 
0533 STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset,  // font location (use offset=0 for plain .ttf)
0534                                 float pixel_height,                     // height of font in pixels
0535                                 unsigned char *pixels, int pw, int ph,  // bitmap to be filled in
0536                                 int first_char, int num_chars,          // characters to bake
0537                                 stbtt_bakedchar *chardata);             // you allocate this, it's num_chars long
0538 // if return is positive, the first unused row of the bitmap
0539 // if return is negative, returns the negative of the number of characters that fit
0540 // if return is 0, no characters fit and no rows were used
0541 // This uses a very crappy packing.
0542 
0543 typedef struct
0544 {
0545    float x0,y0,s0,t0; // top-left
0546    float x1,y1,s1,t1; // bottom-right
0547 } stbtt_aligned_quad;
0548 
0549 STBTT_DEF void stbtt_GetBakedQuad(const stbtt_bakedchar *chardata, int pw, int ph,  // same data as above
0550                                int char_index,             // character to display
0551                                float *xpos, float *ypos,   // pointers to current position in screen pixel space
0552                                stbtt_aligned_quad *q,      // output: quad to draw
0553                                int opengl_fillrule);       // true if opengl fill rule; false if DX9 or earlier
0554 // Call GetBakedQuad with char_index = 'character - first_char', and it
0555 // creates the quad you need to draw and advances the current position.
0556 //
0557 // The coordinate system used assumes y increases downwards.
0558 //
0559 // Characters will extend both above and below the current position;
0560 // see discussion of "BASELINE" above.
0561 //
0562 // It's inefficient; you might want to c&p it and optimize it.
0563 
0564 STBTT_DEF void stbtt_GetScaledFontVMetrics(const unsigned char *fontdata, int index, float size, float *ascent, float *descent, float *lineGap);
0565 // Query the font vertical metrics without having to create a font first.
0566 
0567 
0568 //////////////////////////////////////////////////////////////////////////////
0569 //
0570 // NEW TEXTURE BAKING API
0571 //
0572 // This provides options for packing multiple fonts into one atlas, not
0573 // perfectly but better than nothing.
0574 
0575 typedef struct
0576 {
0577    unsigned short x0,y0,x1,y1; // coordinates of bbox in bitmap
0578    float xoff,yoff,xadvance;
0579    float xoff2,yoff2;
0580 } stbtt_packedchar;
0581 
0582 typedef struct stbtt_pack_context stbtt_pack_context;
0583 typedef struct stbtt_fontinfo stbtt_fontinfo;
0584 #ifndef STB_RECT_PACK_VERSION
0585 typedef struct stbrp_rect stbrp_rect;
0586 #endif
0587 
0588 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);
0589 // Initializes a packing context stored in the passed-in stbtt_pack_context.
0590 // Future calls using this context will pack characters into the bitmap passed
0591 // in here: a 1-channel bitmap that is width * height. stride_in_bytes is
0592 // the distance from one row to the next (or 0 to mean they are packed tightly
0593 // together). "padding" is the amount of padding to leave between each
0594 // character (normally you want '1' for bitmaps you'll use as textures with
0595 // bilinear filtering).
0596 //
0597 // Returns 0 on failure, 1 on success.
0598 
0599 STBTT_DEF void stbtt_PackEnd  (stbtt_pack_context *spc);
0600 // Cleans up the packing context and frees all memory.
0601 
0602 #define STBTT_POINT_SIZE(x)   (-(x))
0603 
0604 STBTT_DEF int  stbtt_PackFontRange(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, float font_size,
0605                                 int first_unicode_char_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range);
0606 // Creates character bitmaps from the font_index'th font found in fontdata (use
0607 // font_index=0 if you don't know what that is). It creates num_chars_in_range
0608 // bitmaps for characters with unicode values starting at first_unicode_char_in_range
0609 // and increasing. Data for how to render them is stored in chardata_for_range;
0610 // pass these to stbtt_GetPackedQuad to get back renderable quads.
0611 //
0612 // font_size is the full height of the character from ascender to descender,
0613 // as computed by stbtt_ScaleForPixelHeight. To use a point size as computed
0614 // by stbtt_ScaleForMappingEmToPixels, wrap the point size in STBTT_POINT_SIZE()
0615 // and pass that result as 'font_size':
0616 //       ...,                  20 , ... // font max minus min y is 20 pixels tall
0617 //       ..., STBTT_POINT_SIZE(20), ... // 'M' is 20 pixels tall
0618 
0619 typedef struct
0620 {
0621    float font_size;
0622    int first_unicode_codepoint_in_range;  // if non-zero, then the chars are continuous, and this is the first codepoint
0623    int *array_of_unicode_codepoints;       // if non-zero, then this is an array of unicode codepoints
0624    int num_chars;
0625    stbtt_packedchar *chardata_for_range; // output
0626    unsigned char h_oversample, v_oversample; // don't set these, they're used internally
0627 } stbtt_pack_range;
0628 
0629 STBTT_DEF int  stbtt_PackFontRanges(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges);
0630 // Creates character bitmaps from multiple ranges of characters stored in
0631 // ranges. This will usually create a better-packed bitmap than multiple
0632 // calls to stbtt_PackFontRange. Note that you can call this multiple
0633 // times within a single PackBegin/PackEnd.
0634 
0635 STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample);
0636 // Oversampling a font increases the quality by allowing higher-quality subpixel
0637 // positioning, and is especially valuable at smaller text sizes.
0638 //
0639 // This function sets the amount of oversampling for all following calls to
0640 // stbtt_PackFontRange(s) or stbtt_PackFontRangesGatherRects for a given
0641 // pack context. The default (no oversampling) is achieved by h_oversample=1
0642 // and v_oversample=1. The total number of pixels required is
0643 // h_oversample*v_oversample larger than the default; for example, 2x2
0644 // oversampling requires 4x the storage of 1x1. For best results, render
0645 // oversampled textures with bilinear filtering. Look at the readme in
0646 // stb/tests/oversample for information about oversampled fonts
0647 //
0648 // To use with PackFontRangesGather etc., you must set it before calls
0649 // call to PackFontRangesGatherRects.
0650 
0651 STBTT_DEF void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context *spc, int skip);
0652 // If skip != 0, this tells stb_truetype to skip any codepoints for which
0653 // there is no corresponding glyph. If skip=0, which is the default, then
0654 // codepoints without a glyph recived the font's "missing character" glyph,
0655 // typically an empty box by convention.
0656 
0657 STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph,  // same data as above
0658                                int char_index,             // character to display
0659                                float *xpos, float *ypos,   // pointers to current position in screen pixel space
0660                                stbtt_aligned_quad *q,      // output: quad to draw
0661                                int align_to_integer);
0662 
0663 STBTT_DEF int  stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects);
0664 STBTT_DEF void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect *rects, int num_rects);
0665 STBTT_DEF int  stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects);
0666 // Calling these functions in sequence is roughly equivalent to calling
0667 // stbtt_PackFontRanges(). If you more control over the packing of multiple
0668 // fonts, or if you want to pack custom data into a font texture, take a look
0669 // at the source to of stbtt_PackFontRanges() and create a custom version
0670 // using these functions, e.g. call GatherRects multiple times,
0671 // building up a single array of rects, then call PackRects once,
0672 // then call RenderIntoRects repeatedly. This may result in a
0673 // better packing than calling PackFontRanges multiple times
0674 // (or it may not).
0675 
0676 // this is an opaque structure that you shouldn't mess with which holds
0677 // all the context needed from PackBegin to PackEnd.
0678 struct stbtt_pack_context {
0679    void *user_allocator_context;
0680    void *pack_info;
0681    int   width;
0682    int   height;
0683    int   stride_in_bytes;
0684    int   padding;
0685    int   skip_missing;
0686    unsigned int   h_oversample, v_oversample;
0687    unsigned char *pixels;
0688    void  *nodes;
0689 };
0690 
0691 //////////////////////////////////////////////////////////////////////////////
0692 //
0693 // FONT LOADING
0694 //
0695 //
0696 
0697 STBTT_DEF int stbtt_GetNumberOfFonts(const unsigned char *data);
0698 // This function will determine the number of fonts in a font file.  TrueType
0699 // collection (.ttc) files may contain multiple fonts, while TrueType font
0700 // (.ttf) files only contain one font. The number of fonts can be used for
0701 // indexing with the previous function where the index is between zero and one
0702 // less than the total fonts. If an error occurs, -1 is returned.
0703 
0704 STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index);
0705 // Each .ttf/.ttc file may have more than one font. Each font has a sequential
0706 // index number starting from 0. Call this function to get the font offset for
0707 // a given index; it returns -1 if the index is out of range. A regular .ttf
0708 // file will only define one font and it always be at offset 0, so it will
0709 // return '0' for index 0, and -1 for all other indices.
0710 
0711 // The following structure is defined publicly so you can declare one on
0712 // the stack or as a global or etc, but you should treat it as opaque.
0713 struct stbtt_fontinfo
0714 {
0715    void           * userdata;
0716    unsigned char  * data;              // pointer to .ttf file
0717    int              fontstart;         // offset of start of font
0718 
0719    int numGlyphs;                     // number of glyphs, needed for range checking
0720 
0721    int loca,head,glyf,hhea,hmtx,kern,gpos,svg; // table locations as offset from start of .ttf
0722    int index_map;                     // a cmap mapping for our chosen character encoding
0723    int indexToLocFormat;              // format needed to map from glyph index to glyph
0724 
0725    stbtt__buf cff;                    // cff font data
0726    stbtt__buf charstrings;            // the charstring index
0727    stbtt__buf gsubrs;                 // global charstring subroutines index
0728    stbtt__buf subrs;                  // private charstring subroutines index
0729    stbtt__buf fontdicts;              // array of font dicts
0730    stbtt__buf fdselect;               // map from glyph to fontdict
0731 };
0732 
0733 STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset);
0734 // Given an offset into the file that defines a font, this function builds
0735 // the necessary cached info for the rest of the system. You must allocate
0736 // the stbtt_fontinfo yourself, and stbtt_InitFont will fill it out. You don't
0737 // need to do anything special to free it, because the contents are pure
0738 // value data with no additional data structures. Returns 0 on failure.
0739 
0740 
0741 //////////////////////////////////////////////////////////////////////////////
0742 //
0743 // CHARACTER TO GLYPH-INDEX CONVERSIOn
0744 
0745 STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint);
0746 // If you're going to perform multiple operations on the same character
0747 // and you want a speed-up, call this function with the character you're
0748 // going to process, then use glyph-based functions instead of the
0749 // codepoint-based functions.
0750 // Returns 0 if the character codepoint is not defined in the font.
0751 
0752 
0753 //////////////////////////////////////////////////////////////////////////////
0754 //
0755 // CHARACTER PROPERTIES
0756 //
0757 
0758 STBTT_DEF float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float pixels);
0759 // computes a scale factor to produce a font whose "height" is 'pixels' tall.
0760 // Height is measured as the distance from the highest ascender to the lowest
0761 // descender; in other words, it's equivalent to calling stbtt_GetFontVMetrics
0762 // and computing:
0763 //       scale = pixels / (ascent - descent)
0764 // so if you prefer to measure height by the ascent only, use a similar calculation.
0765 
0766 STBTT_DEF float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels);
0767 // computes a scale factor to produce a font whose EM size is mapped to
0768 // 'pixels' tall. This is probably what traditional APIs compute, but
0769 // I'm not positive.
0770 
0771 STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap);
0772 // ascent is the coordinate above the baseline the font extends; descent
0773 // is the coordinate below the baseline the font extends (i.e. it is typically negative)
0774 // lineGap is the spacing between one row's descent and the next row's ascent...
0775 // so you should advance the vertical position by "*ascent - *descent + *lineGap"
0776 //   these are expressed in unscaled coordinates, so you must multiply by
0777 //   the scale factor for a given size
0778 
0779 STBTT_DEF int  stbtt_GetFontVMetricsOS2(const stbtt_fontinfo *info, int *typoAscent, int *typoDescent, int *typoLineGap);
0780 // analogous to GetFontVMetrics, but returns the "typographic" values from the OS/2
0781 // table (specific to MS/Windows TTF files).
0782 //
0783 // Returns 1 on success (table present), 0 on failure.
0784 
0785 STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1);
0786 // the bounding box around all possible characters
0787 
0788 STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing);
0789 // leftSideBearing is the offset from the current horizontal position to the left edge of the character
0790 // advanceWidth is the offset from the current horizontal position to the next horizontal position
0791 //   these are expressed in unscaled coordinates
0792 
0793 STBTT_DEF int  stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2);
0794 // an additional amount to add to the 'advance' value between ch1 and ch2
0795 
0796 STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1);
0797 // Gets the bounding box of the visible part of the glyph, in unscaled coordinates
0798 
0799 STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing);
0800 STBTT_DEF int  stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2);
0801 STBTT_DEF int  stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1);
0802 // as above, but takes one or more glyph indices for greater efficiency
0803 
0804 typedef struct stbtt_kerningentry
0805 {
0806    int glyph1; // use stbtt_FindGlyphIndex
0807    int glyph2;
0808    int advance;
0809 } stbtt_kerningentry;
0810 
0811 STBTT_DEF int  stbtt_GetKerningTableLength(const stbtt_fontinfo *info);
0812 STBTT_DEF int  stbtt_GetKerningTable(const stbtt_fontinfo *info, stbtt_kerningentry* table, int table_length);
0813 // Retrieves a complete list of all of the kerning pairs provided by the font
0814 // stbtt_GetKerningTable never writes more than table_length entries and returns how many entries it did write.
0815 // The table will be sorted by (a.glyph1 == b.glyph1)?(a.glyph2 < b.glyph2):(a.glyph1 < b.glyph1)
0816 
0817 //////////////////////////////////////////////////////////////////////////////
0818 //
0819 // GLYPH SHAPES (you probably don't need these, but they have to go before
0820 // the bitmaps for C declaration-order reasons)
0821 //
0822 
0823 #ifndef STBTT_vmove // you can predefine these to use different values (but why?)
0824    enum {
0825       STBTT_vmove=1,
0826       STBTT_vline,
0827       STBTT_vcurve,
0828       STBTT_vcubic
0829    };
0830 #endif
0831 
0832 #ifndef stbtt_vertex // you can predefine this to use different values
0833                    // (we share this with other code at RAD)
0834    #define stbtt_vertex_type short // can't use stbtt_int16 because that's not visible in the header file
0835    typedef struct
0836    {
0837       stbtt_vertex_type x,y,cx,cy,cx1,cy1;
0838       unsigned char type,padding;
0839    } stbtt_vertex;
0840 #endif
0841 
0842 STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index);
0843 // returns non-zero if nothing is drawn for this glyph
0844 
0845 STBTT_DEF int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices);
0846 STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **vertices);
0847 // returns # of vertices and fills *vertices with the pointer to them
0848 //   these are expressed in "unscaled" coordinates
0849 //
0850 // The shape is a series of contours. Each one starts with
0851 // a STBTT_moveto, then consists of a series of mixed
0852 // STBTT_lineto and STBTT_curveto segments. A lineto
0853 // draws a line from previous endpoint to its x,y; a curveto
0854 // draws a quadratic bezier from previous endpoint to
0855 // its x,y, using cx,cy as the bezier control point.
0856 
0857 STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices);
0858 // frees the data allocated above
0859 
0860 STBTT_DEF unsigned char *stbtt_FindSVGDoc(const stbtt_fontinfo *info, int gl);
0861 STBTT_DEF int stbtt_GetCodepointSVG(const stbtt_fontinfo *info, int unicode_codepoint, const char **svg);
0862 STBTT_DEF int stbtt_GetGlyphSVG(const stbtt_fontinfo *info, int gl, const char **svg);
0863 // fills svg with the character's SVG data.
0864 // returns data size or 0 if SVG not found.
0865 
0866 //////////////////////////////////////////////////////////////////////////////
0867 //
0868 // BITMAP RENDERING
0869 //
0870 
0871 STBTT_DEF void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata);
0872 // frees the bitmap allocated below
0873 
0874 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);
0875 // allocates a large-enough single-channel 8bpp bitmap and renders the
0876 // specified character/glyph at the specified scale into it, with
0877 // antialiasing. 0 is no coverage (transparent), 255 is fully covered (opaque).
0878 // *width & *height are filled out with the width & height of the bitmap,
0879 // which is stored left-to-right, top-to-bottom.
0880 //
0881 // xoff/yoff are the offset it pixel space from the glyph origin to the top-left of the bitmap
0882 
0883 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);
0884 // the same as stbtt_GetCodepoitnBitmap, but you can specify a subpixel
0885 // shift for the character
0886 
0887 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);
0888 // the same as stbtt_GetCodepointBitmap, but you pass in storage for the bitmap
0889 // in the form of 'output', with row spacing of 'out_stride' bytes. the bitmap
0890 // is clipped to out_w/out_h bytes. Call stbtt_GetCodepointBitmapBox to get the
0891 // width and height and positioning info for it first.
0892 
0893 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);
0894 // same as stbtt_MakeCodepointBitmap, but you can specify a subpixel
0895 // shift for the character
0896 
0897 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);
0898 // same as stbtt_MakeCodepointBitmapSubpixel, but prefiltering
0899 // is performed (see stbtt_PackSetOversampling)
0900 
0901 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);
0902 // get the bbox of the bitmap centered around the glyph origin; so the
0903 // bitmap width is ix1-ix0, height is iy1-iy0, and location to place
0904 // the bitmap top left is (leftSideBearing*scale,iy0).
0905 // (Note that the bitmap uses y-increases-down, but the shape uses
0906 // y-increases-up, so CodepointBitmapBox and CodepointBox are inverted.)
0907 
0908 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);
0909 // same as stbtt_GetCodepointBitmapBox, but you can specify a subpixel
0910 // shift for the character
0911 
0912 // the following functions are equivalent to the above functions, but operate
0913 // on glyph indices instead of Unicode codepoints (for efficiency)
0914 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);
0915 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);
0916 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);
0917 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);
0918 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);
0919 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);
0920 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);
0921 
0922 
0923 // @TODO: don't expose this structure
0924 typedef struct
0925 {
0926    int w,h,stride;
0927    unsigned char *pixels;
0928 } stbtt__bitmap;
0929 
0930 // rasterize a shape with quadratic beziers into a bitmap
0931 STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result,        // 1-channel bitmap to draw into
0932                                float flatness_in_pixels,     // allowable error of curve in pixels
0933                                stbtt_vertex *vertices,       // array of vertices defining shape
0934                                int num_verts,                // number of vertices in above array
0935                                float scale_x, float scale_y, // scale applied to input vertices
0936                                float shift_x, float shift_y, // translation applied to input vertices
0937                                int x_off, int y_off,         // another translation applied to input
0938                                int invert,                   // if non-zero, vertically flip shape
0939                                void *userdata);              // context for to STBTT_MALLOC
0940 
0941 //////////////////////////////////////////////////////////////////////////////
0942 //
0943 // Signed Distance Function (or Field) rendering
0944 
0945 STBTT_DEF void stbtt_FreeSDF(unsigned char *bitmap, void *userdata);
0946 // frees the SDF bitmap allocated below
0947 
0948 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);
0949 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);
0950 // These functions compute a discretized SDF field for a single character, suitable for storing
0951 // in a single-channel texture, sampling with bilinear filtering, and testing against
0952 // larger than some threshold to produce scalable fonts.
0953 //        info              --  the font
0954 //        scale             --  controls the size of the resulting SDF bitmap, same as it would be creating a regular bitmap
0955 //        glyph/codepoint   --  the character to generate the SDF for
0956 //        padding           --  extra "pixels" around the character which are filled with the distance to the character (not 0),
0957 //                                 which allows effects like bit outlines
0958 //        onedge_value      --  value 0-255 to test the SDF against to reconstruct the character (i.e. the isocontour of the character)
0959 //        pixel_dist_scale  --  what value the SDF should increase by when moving one SDF "pixel" away from the edge (on the 0..255 scale)
0960 //                                 if positive, > onedge_value is inside; if negative, < onedge_value is inside
0961 //        width,height      --  output height & width of the SDF bitmap (including padding)
0962 //        xoff,yoff         --  output origin of the character
0963 //        return value      --  a 2D array of bytes 0..255, width*height in size
0964 //
0965 // pixel_dist_scale & onedge_value are a scale & bias that allows you to make
0966 // optimal use of the limited 0..255 for your application, trading off precision
0967 // and special effects. SDF values outside the range 0..255 are clamped to 0..255.
0968 //
0969 // Example:
0970 //      scale = stbtt_ScaleForPixelHeight(22)
0971 //      padding = 5
0972 //      onedge_value = 180
0973 //      pixel_dist_scale = 180/5.0 = 36.0
0974 //
0975 //      This will create an SDF bitmap in which the character is about 22 pixels
0976 //      high but the whole bitmap is about 22+5+5=32 pixels high. To produce a filled
0977 //      shape, sample the SDF at each pixel and fill the pixel if the SDF value
0978 //      is greater than or equal to 180/255. (You'll actually want to antialias,
0979 //      which is beyond the scope of this example.) Additionally, you can compute
0980 //      offset outlines (e.g. to stroke the character border inside & outside,
0981 //      or only outside). For example, to fill outside the character up to 3 SDF
0982 //      pixels, you would compare against (180-36.0*3)/255 = 72/255. The above
0983 //      choice of variables maps a range from 5 pixels outside the shape to
0984 //      2 pixels inside the shape to 0..255; this is intended primarily for apply
0985 //      outside effects only (the interior range is needed to allow proper
0986 //      antialiasing of the font at *smaller* sizes)
0987 //
0988 // The function computes the SDF analytically at each SDF pixel, not by e.g.
0989 // building a higher-res bitmap and approximating it. In theory the quality
0990 // should be as high as possible for an SDF of this size & representation, but
0991 // unclear if this is true in practice (perhaps building a higher-res bitmap
0992 // and computing from that can allow drop-out prevention).
0993 //
0994 // The algorithm has not been optimized at all, so expect it to be slow
0995 // if computing lots of characters or very large sizes.
0996 
0997 
0998 
0999 //////////////////////////////////////////////////////////////////////////////
1000 //
1001 // Finding the right font...
1002 //
1003 // You should really just solve this offline, keep your own tables
1004 // of what font is what, and don't try to get it out of the .ttf file.
1005 // That's because getting it out of the .ttf file is really hard, because
1006 // the names in the file can appear in many possible encodings, in many
1007 // possible languages, and e.g. if you need a case-insensitive comparison,
1008 // the details of that depend on the encoding & language in a complex way
1009 // (actually underspecified in truetype, but also gigantic).
1010 //
1011 // But you can use the provided functions in two possible ways:
1012 //     stbtt_FindMatchingFont() will use *case-sensitive* comparisons on
1013 //             unicode-encoded names to try to find the font you want;
1014 //             you can run this before calling stbtt_InitFont()
1015 //
1016 //     stbtt_GetFontNameString() lets you get any of the various strings
1017 //             from the file yourself and do your own comparisons on them.
1018 //             You have to have called stbtt_InitFont() first.
1019 
1020 
1021 STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *fontdata, const char *name, int flags);
1022 // returns the offset (not index) of the font that matches, or -1 if none
1023 //   if you use STBTT_MACSTYLE_DONTCARE, use a font name like "Arial Bold".
1024 //   if you use any other flag, use a font name like "Arial"; this checks
1025 //     the 'macStyle' header field; i don't know if fonts set this consistently
1026 #define STBTT_MACSTYLE_DONTCARE     0
1027 #define STBTT_MACSTYLE_BOLD         1
1028 #define STBTT_MACSTYLE_ITALIC       2
1029 #define STBTT_MACSTYLE_UNDERSCORE   4
1030 #define STBTT_MACSTYLE_NONE         8   // <= not same as 0, this makes us check the bitfield is 0
1031 
1032 STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2);
1033 // returns 1/0 whether the first string interpreted as utf8 is identical to
1034 // the second string interpreted as big-endian utf16... useful for strings from next func
1035 
1036 STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID);
1037 // returns the string (which may be big-endian double byte, e.g. for unicode)
1038 // and puts the length in bytes in *length.
1039 //
1040 // some of the values for the IDs are below; for more see the truetype spec:
1041 //     http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6name.html
1042 //     http://www.microsoft.com/typography/otspec/name.htm
1043 
1044 enum { // platformID
1045    STBTT_PLATFORM_ID_UNICODE   =0,
1046    STBTT_PLATFORM_ID_MAC       =1,
1047    STBTT_PLATFORM_ID_ISO       =2,
1048    STBTT_PLATFORM_ID_MICROSOFT =3
1049 };
1050 
1051 enum { // encodingID for STBTT_PLATFORM_ID_UNICODE
1052    STBTT_UNICODE_EID_UNICODE_1_0    =0,
1053    STBTT_UNICODE_EID_UNICODE_1_1    =1,
1054    STBTT_UNICODE_EID_ISO_10646      =2,
1055    STBTT_UNICODE_EID_UNICODE_2_0_BMP=3,
1056    STBTT_UNICODE_EID_UNICODE_2_0_FULL=4
1057 };
1058 
1059 enum { // encodingID for STBTT_PLATFORM_ID_MICROSOFT
1060    STBTT_MS_EID_SYMBOL        =0,
1061    STBTT_MS_EID_UNICODE_BMP   =1,
1062    STBTT_MS_EID_SHIFTJIS      =2,
1063    STBTT_MS_EID_UNICODE_FULL  =10
1064 };
1065 
1066 enum { // encodingID for STBTT_PLATFORM_ID_MAC; same as Script Manager codes
1067    STBTT_MAC_EID_ROMAN        =0,   STBTT_MAC_EID_ARABIC       =4,
1068    STBTT_MAC_EID_JAPANESE     =1,   STBTT_MAC_EID_HEBREW       =5,
1069    STBTT_MAC_EID_CHINESE_TRAD =2,   STBTT_MAC_EID_GREEK        =6,
1070    STBTT_MAC_EID_KOREAN       =3,   STBTT_MAC_EID_RUSSIAN      =7
1071 };
1072 
1073 enum { // languageID for STBTT_PLATFORM_ID_MICROSOFT; same as LCID...
1074        // problematic because there are e.g. 16 english LCIDs and 16 arabic LCIDs
1075    STBTT_MS_LANG_ENGLISH     =0x0409,   STBTT_MS_LANG_ITALIAN     =0x0410,
1076    STBTT_MS_LANG_CHINESE     =0x0804,   STBTT_MS_LANG_JAPANESE    =0x0411,
1077    STBTT_MS_LANG_DUTCH       =0x0413,   STBTT_MS_LANG_KOREAN      =0x0412,
1078    STBTT_MS_LANG_FRENCH      =0x040c,   STBTT_MS_LANG_RUSSIAN     =0x0419,
1079    STBTT_MS_LANG_GERMAN      =0x0407,   STBTT_MS_LANG_SPANISH     =0x0409,
1080    STBTT_MS_LANG_HEBREW      =0x040d,   STBTT_MS_LANG_SWEDISH     =0x041D
1081 };
1082 
1083 enum { // languageID for STBTT_PLATFORM_ID_MAC
1084    STBTT_MAC_LANG_ENGLISH      =0 ,   STBTT_MAC_LANG_JAPANESE     =11,
1085    STBTT_MAC_LANG_ARABIC       =12,   STBTT_MAC_LANG_KOREAN       =23,
1086    STBTT_MAC_LANG_DUTCH        =4 ,   STBTT_MAC_LANG_RUSSIAN      =32,
1087    STBTT_MAC_LANG_FRENCH       =1 ,   STBTT_MAC_LANG_SPANISH      =6 ,
1088    STBTT_MAC_LANG_GERMAN       =2 ,   STBTT_MAC_LANG_SWEDISH      =5 ,
1089    STBTT_MAC_LANG_HEBREW       =10,   STBTT_MAC_LANG_CHINESE_SIMPLIFIED =33,
1090    STBTT_MAC_LANG_ITALIAN      =3 ,   STBTT_MAC_LANG_CHINESE_TRAD =19
1091 };
1092 
1093 #ifdef __cplusplus
1094 }
1095 #endif
1096 
1097 #endif // __STB_INCLUDE_STB_TRUETYPE_H__
1098 
1099 ///////////////////////////////////////////////////////////////////////////////
1100 ///////////////////////////////////////////////////////////////////////////////
1101 ////
1102 ////   IMPLEMENTATION
1103 ////
1104 ////
1105 
1106 #ifdef STB_TRUETYPE_IMPLEMENTATION
1107 
1108 #ifndef STBTT_MAX_OVERSAMPLE
1109 #define STBTT_MAX_OVERSAMPLE   8
1110 #endif
1111 
1112 #if STBTT_MAX_OVERSAMPLE > 255
1113 #error "STBTT_MAX_OVERSAMPLE cannot be > 255"
1114 #endif
1115 
1116 typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERSAMPLE-1)) == 0 ? 1 : -1];
1117 
1118 #ifndef STBTT_RASTERIZER_VERSION
1119 #define STBTT_RASTERIZER_VERSION 2
1120 #endif
1121 
1122 #ifdef _MSC_VER
1123 #define STBTT__NOTUSED(v)  (void)(v)
1124 #else
1125 #define STBTT__NOTUSED(v)  (void)sizeof(v)
1126 #endif
1127 
1128 //////////////////////////////////////////////////////////////////////////
1129 //
1130 // stbtt__buf helpers to parse data from file
1131 //
1132 
1133 static stbtt_uint8 stbtt__buf_get8(stbtt__buf *b)
1134 {
1135    if (b->cursor >= b->size)
1136       return 0;
1137    return b->data[b->cursor++];
1138 }
1139 
1140 static stbtt_uint8 stbtt__buf_peek8(stbtt__buf *b)
1141 {
1142    if (b->cursor >= b->size)
1143       return 0;
1144    return b->data[b->cursor];
1145 }
1146 
1147 static void stbtt__buf_seek(stbtt__buf *b, int o)
1148 {
1149    STBTT_assert(!(o > b->size || o < 0));
1150    b->cursor = (o > b->size || o < 0) ? b->size : o;
1151 }
1152 
1153 static void stbtt__buf_skip(stbtt__buf *b, int o)
1154 {
1155    stbtt__buf_seek(b, b->cursor + o);
1156 }
1157 
1158 static stbtt_uint32 stbtt__buf_get(stbtt__buf *b, int n)
1159 {
1160    stbtt_uint32 v = 0;
1161    int i;
1162    STBTT_assert(n >= 1 && n <= 4);
1163    for (i = 0; i < n; i++)
1164       v = (v << 8) | stbtt__buf_get8(b);
1165    return v;
1166 }
1167 
1168 static stbtt__buf stbtt__new_buf(const void *p, size_t size)
1169 {
1170    stbtt__buf r;
1171    STBTT_assert(size < 0x40000000);
1172    r.data = (stbtt_uint8*) p;
1173    r.size = (int) size;
1174    r.cursor = 0;
1175    return r;
1176 }
1177 
1178 #define stbtt__buf_get16(b)  stbtt__buf_get((b), 2)
1179 #define stbtt__buf_get32(b)  stbtt__buf_get((b), 4)
1180 
1181 static stbtt__buf stbtt__buf_range(const stbtt__buf *b, int o, int s)
1182 {
1183    stbtt__buf r = stbtt__new_buf(NULL, 0);
1184    if (o < 0 || s < 0 || o > b->size || s > b->size - o) return r;
1185    r.data = b->data + o;
1186    r.size = s;
1187    return r;
1188 }
1189 
1190 static stbtt__buf stbtt__cff_get_index(stbtt__buf *b)
1191 {
1192    int count, start, offsize;
1193    start = b->cursor;
1194    count = stbtt__buf_get16(b);
1195    if (count) {
1196       offsize = stbtt__buf_get8(b);
1197       STBTT_assert(offsize >= 1 && offsize <= 4);
1198       stbtt__buf_skip(b, offsize * count);
1199       stbtt__buf_skip(b, stbtt__buf_get(b, offsize) - 1);
1200    }
1201    return stbtt__buf_range(b, start, b->cursor - start);
1202 }
1203 
1204 static stbtt_uint32 stbtt__cff_int(stbtt__buf *b)
1205 {
1206    int b0 = stbtt__buf_get8(b);
1207    if (b0 >= 32 && b0 <= 246)       return b0 - 139;
1208    else if (b0 >= 247 && b0 <= 250) return (b0 - 247)*256 + stbtt__buf_get8(b) + 108;
1209    else if (b0 >= 251 && b0 <= 254) return -(b0 - 251)*256 - stbtt__buf_get8(b) - 108;
1210    else if (b0 == 28)               return stbtt__buf_get16(b);
1211    else if (b0 == 29)               return stbtt__buf_get32(b);
1212    STBTT_assert(0);
1213    return 0;
1214 }
1215 
1216 static void stbtt__cff_skip_operand(stbtt__buf *b) {
1217    int v, b0 = stbtt__buf_peek8(b);
1218    STBTT_assert(b0 >= 28);
1219    if (b0 == 30) {
1220       stbtt__buf_skip(b, 1);
1221       while (b->cursor < b->size) {
1222          v = stbtt__buf_get8(b);
1223          if ((v & 0xF) == 0xF || (v >> 4) == 0xF)
1224             break;
1225       }
1226    } else {
1227       stbtt__cff_int(b);
1228    }
1229 }
1230 
1231 static stbtt__buf stbtt__dict_get(stbtt__buf *b, int key)
1232 {
1233    stbtt__buf_seek(b, 0);
1234    while (b->cursor < b->size) {
1235       int start = b->cursor, end, op;
1236       while (stbtt__buf_peek8(b) >= 28)
1237          stbtt__cff_skip_operand(b);
1238       end = b->cursor;
1239       op = stbtt__buf_get8(b);
1240       if (op == 12)  op = stbtt__buf_get8(b) | 0x100;
1241       if (op == key) return stbtt__buf_range(b, start, end-start);
1242    }
1243    return stbtt__buf_range(b, 0, 0);
1244 }
1245 
1246 static void stbtt__dict_get_ints(stbtt__buf *b, int key, int outcount, stbtt_uint32 *out)
1247 {
1248    int i;
1249    stbtt__buf operands = stbtt__dict_get(b, key);
1250    for (i = 0; i < outcount && operands.cursor < operands.size; i++)
1251       out[i] = stbtt__cff_int(&operands);
1252 }
1253 
1254 static int stbtt__cff_index_count(stbtt__buf *b)
1255 {
1256    stbtt__buf_seek(b, 0);
1257    return stbtt__buf_get16(b);
1258 }
1259 
1260 static stbtt__buf stbtt__cff_index_get(stbtt__buf b, int i)
1261 {
1262    int count, offsize, start, end;
1263    stbtt__buf_seek(&b, 0);
1264    count = stbtt__buf_get16(&b);
1265    offsize = stbtt__buf_get8(&b);
1266    STBTT_assert(i >= 0 && i < count);
1267    STBTT_assert(offsize >= 1 && offsize <= 4);
1268    stbtt__buf_skip(&b, i*offsize);
1269    start = stbtt__buf_get(&b, offsize);
1270    end = stbtt__buf_get(&b, offsize);
1271    return stbtt__buf_range(&b, 2+(count+1)*offsize+start, end - start);
1272 }
1273 
1274 //////////////////////////////////////////////////////////////////////////
1275 //
1276 // accessors to parse data from file
1277 //
1278 
1279 // on platforms that don't allow misaligned reads, if we want to allow
1280 // truetype fonts that aren't padded to alignment, define ALLOW_UNALIGNED_TRUETYPE
1281 
1282 #define ttBYTE(p)     (* (stbtt_uint8 *) (p))
1283 #define ttCHAR(p)     (* (stbtt_int8 *) (p))
1284 #define ttFixed(p)    ttLONG(p)
1285 
1286 static stbtt_uint16 ttUSHORT(stbtt_uint8 *p) { return p[0]*256 + p[1]; }
1287 static stbtt_int16 ttSHORT(stbtt_uint8 *p)   { return p[0]*256 + p[1]; }
1288 static stbtt_uint32 ttULONG(stbtt_uint8 *p)  { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; }
1289 static stbtt_int32 ttLONG(stbtt_uint8 *p)    { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; }
1290 
1291 #define stbtt_tag4(p,c0,c1,c2,c3) ((p)[0] == (c0) && (p)[1] == (c1) && (p)[2] == (c2) && (p)[3] == (c3))
1292 #define stbtt_tag(p,str)           stbtt_tag4(p,str[0],str[1],str[2],str[3])
1293 
1294 static int stbtt__isfont(stbtt_uint8 *font)
1295 {
1296    // check the version number
1297    if (stbtt_tag4(font, '1',0,0,0))  return 1; // TrueType 1
1298    if (stbtt_tag(font, "typ1"))   return 1; // TrueType with type 1 font -- we don't support this!
1299    if (stbtt_tag(font, "OTTO"))   return 1; // OpenType with CFF
1300    if (stbtt_tag4(font, 0,1,0,0)) return 1; // OpenType 1.0
1301    if (stbtt_tag(font, "true"))   return 1; // Apple specification for TrueType fonts
1302    return 0;
1303 }
1304 
1305 // @OPTIMIZE: binary search
1306 static stbtt_uint32 stbtt__find_table(stbtt_uint8 *data, stbtt_uint32 fontstart, const char *tag)
1307 {
1308    stbtt_int32 num_tables = ttUSHORT(data+fontstart+4);
1309    stbtt_uint32 tabledir = fontstart + 12;
1310    stbtt_int32 i;
1311    for (i=0; i < num_tables; ++i) {
1312       stbtt_uint32 loc = tabledir + 16*i;
1313       if (stbtt_tag(data+loc+0, tag))
1314          return ttULONG(data+loc+8);
1315    }
1316    return 0;
1317 }
1318 
1319 static int stbtt_GetFontOffsetForIndex_internal(unsigned char *font_collection, int index)
1320 {
1321    // if it's just a font, there's only one valid index
1322    if (stbtt__isfont(font_collection))
1323       return index == 0 ? 0 : -1;
1324 
1325    // check if it's a TTC
1326    if (stbtt_tag(font_collection, "ttcf")) {
1327       // version 1?
1328       if (ttULONG(font_collection+4) == 0x00010000 || ttULONG(font_collection+4) == 0x00020000) {
1329          stbtt_int32 n = ttLONG(font_collection+8);
1330          if (index >= n)
1331             return -1;
1332          return ttULONG(font_collection+12+index*4);
1333       }
1334    }
1335    return -1;
1336 }
1337 
1338 static int stbtt_GetNumberOfFonts_internal(unsigned char *font_collection)
1339 {
1340    // if it's just a font, there's only one valid font
1341    if (stbtt__isfont(font_collection))
1342       return 1;
1343 
1344    // check if it's a TTC
1345    if (stbtt_tag(font_collection, "ttcf")) {
1346       // version 1?
1347       if (ttULONG(font_collection+4) == 0x00010000 || ttULONG(font_collection+4) == 0x00020000) {
1348          return ttLONG(font_collection+8);
1349       }
1350    }
1351    return 0;
1352 }
1353 
1354 static stbtt__buf stbtt__get_subrs(stbtt__buf cff, stbtt__buf fontdict)
1355 {
1356    stbtt_uint32 subrsoff = 0, private_loc[2] = { 0, 0 };
1357    stbtt__buf pdict;
1358    stbtt__dict_get_ints(&fontdict, 18, 2, private_loc);
1359    if (!private_loc[1] || !private_loc[0]) return stbtt__new_buf(NULL, 0);
1360    pdict = stbtt__buf_range(&cff, private_loc[1], private_loc[0]);
1361    stbtt__dict_get_ints(&pdict, 19, 1, &subrsoff);
1362    if (!subrsoff) return stbtt__new_buf(NULL, 0);
1363    stbtt__buf_seek(&cff, private_loc[1]+subrsoff);
1364    return stbtt__cff_get_index(&cff);
1365 }
1366 
1367 // since most people won't use this, find this table the first time it's needed
1368 static int stbtt__get_svg(stbtt_fontinfo *info)
1369 {
1370    stbtt_uint32 t;
1371    if (info->svg < 0) {
1372       t = stbtt__find_table(info->data, info->fontstart, "SVG ");
1373       if (t) {
1374          stbtt_uint32 offset = ttULONG(info->data + t + 2);
1375          info->svg = t + offset;
1376       } else {
1377          info->svg = 0;
1378       }
1379    }
1380    return info->svg;
1381 }
1382 
1383 static int stbtt_InitFont_internal(stbtt_fontinfo *info, unsigned char *data, int fontstart)
1384 {
1385    stbtt_uint32 cmap, t;
1386    stbtt_int32 i,numTables;
1387 
1388    info->data = data;
1389    info->fontstart = fontstart;
1390    info->cff = stbtt__new_buf(NULL, 0);
1391 
1392    cmap = stbtt__find_table(data, fontstart, "cmap");       // required
1393    info->loca = stbtt__find_table(data, fontstart, "loca"); // required
1394    info->head = stbtt__find_table(data, fontstart, "head"); // required
1395    info->glyf = stbtt__find_table(data, fontstart, "glyf"); // required
1396    info->hhea = stbtt__find_table(data, fontstart, "hhea"); // required
1397    info->hmtx = stbtt__find_table(data, fontstart, "hmtx"); // required
1398    info->kern = stbtt__find_table(data, fontstart, "kern"); // not required
1399    info->gpos = stbtt__find_table(data, fontstart, "GPOS"); // not required
1400 
1401    if (!cmap || !info->head || !info->hhea || !info->hmtx)
1402       return 0;
1403    if (info->glyf) {
1404       // required for truetype
1405       if (!info->loca) return 0;
1406    } else {
1407       // initialization for CFF / Type2 fonts (OTF)
1408       stbtt__buf b, topdict, topdictidx;
1409       stbtt_uint32 cstype = 2, charstrings = 0, fdarrayoff = 0, fdselectoff = 0;
1410       stbtt_uint32 cff;
1411 
1412       cff = stbtt__find_table(data, fontstart, "CFF ");
1413       if (!cff) return 0;
1414 
1415       info->fontdicts = stbtt__new_buf(NULL, 0);
1416       info->fdselect = stbtt__new_buf(NULL, 0);
1417 
1418       // @TODO this should use size from table (not 512MB)
1419       info->cff = stbtt__new_buf(data+cff, 512*1024*1024);
1420       b = info->cff;
1421 
1422       // read the header
1423       stbtt__buf_skip(&b, 2);
1424       stbtt__buf_seek(&b, stbtt__buf_get8(&b)); // hdrsize
1425 
1426       // @TODO the name INDEX could list multiple fonts,
1427       // but we just use the first one.
1428       stbtt__cff_get_index(&b);  // name INDEX
1429       topdictidx = stbtt__cff_get_index(&b);
1430       topdict = stbtt__cff_index_get(topdictidx, 0);
1431       stbtt__cff_get_index(&b);  // string INDEX
1432       info->gsubrs = stbtt__cff_get_index(&b);
1433 
1434       stbtt__dict_get_ints(&topdict, 17, 1, &charstrings);
1435       stbtt__dict_get_ints(&topdict, 0x100 | 6, 1, &cstype);
1436       stbtt__dict_get_ints(&topdict, 0x100 | 36, 1, &fdarrayoff);
1437       stbtt__dict_get_ints(&topdict, 0x100 | 37, 1, &fdselectoff);
1438       info->subrs = stbtt__get_subrs(b, topdict);
1439 
1440       // we only support Type 2 charstrings
1441       if (cstype != 2) return 0;
1442       if (charstrings == 0) return 0;
1443 
1444       if (fdarrayoff) {
1445          // looks like a CID font
1446          if (!fdselectoff) return 0;
1447          stbtt__buf_seek(&b, fdarrayoff);
1448          info->fontdicts = stbtt__cff_get_index(&b);
1449          info->fdselect = stbtt__buf_range(&b, fdselectoff, b.size-fdselectoff);
1450       }
1451 
1452       stbtt__buf_seek(&b, charstrings);
1453       info->charstrings = stbtt__cff_get_index(&b);
1454    }
1455 
1456    t = stbtt__find_table(data, fontstart, "maxp");
1457    if (t)
1458       info->numGlyphs = ttUSHORT(data+t+4);
1459    else
1460       info->numGlyphs = 0xffff;
1461 
1462    info->svg = -1;
1463 
1464    // find a cmap encoding table we understand *now* to avoid searching
1465    // later. (todo: could make this installable)
1466    // the same regardless of glyph.
1467    numTables = ttUSHORT(data + cmap + 2);
1468    info->index_map = 0;
1469    for (i=0; i < numTables; ++i) {
1470       stbtt_uint32 encoding_record = cmap + 4 + 8 * i;
1471       // find an encoding we understand:
1472       switch(ttUSHORT(data+encoding_record)) {
1473          case STBTT_PLATFORM_ID_MICROSOFT:
1474             switch (ttUSHORT(data+encoding_record+2)) {
1475                case STBTT_MS_EID_UNICODE_BMP:
1476                case STBTT_MS_EID_UNICODE_FULL:
1477                   // MS/Unicode
1478                   info->index_map = cmap + ttULONG(data+encoding_record+4);
1479                   break;
1480             }
1481             break;
1482         case STBTT_PLATFORM_ID_UNICODE:
1483             // Mac/iOS has these
1484             // all the encodingIDs are unicode, so we don't bother to check it
1485             info->index_map = cmap + ttULONG(data+encoding_record+4);
1486             break;
1487       }
1488    }
1489    if (info->index_map == 0)
1490       return 0;
1491 
1492    info->indexToLocFormat = ttUSHORT(data+info->head + 50);
1493    return 1;
1494 }
1495 
1496 STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint)
1497 {
1498    stbtt_uint8 *data = info->data;
1499    stbtt_uint32 index_map = info->index_map;
1500 
1501    stbtt_uint16 format = ttUSHORT(data + index_map + 0);
1502    if (format == 0) { // apple byte encoding
1503       stbtt_int32 bytes = ttUSHORT(data + index_map + 2);
1504       if (unicode_codepoint < bytes-6)
1505          return ttBYTE(data + index_map + 6 + unicode_codepoint);
1506       return 0;
1507    } else if (format == 6) {
1508       stbtt_uint32 first = ttUSHORT(data + index_map + 6);
1509       stbtt_uint32 count = ttUSHORT(data + index_map + 8);
1510       if ((stbtt_uint32) unicode_codepoint >= first && (stbtt_uint32) unicode_codepoint < first+count)
1511          return ttUSHORT(data + index_map + 10 + (unicode_codepoint - first)*2);
1512       return 0;
1513    } else if (format == 2) {
1514       STBTT_assert(0); // @TODO: high-byte mapping for japanese/chinese/korean
1515       return 0;
1516    } else if (format == 4) { // standard mapping for windows fonts: binary search collection of ranges
1517       stbtt_uint16 segcount = ttUSHORT(data+index_map+6) >> 1;
1518       stbtt_uint16 searchRange = ttUSHORT(data+index_map+8) >> 1;
1519       stbtt_uint16 entrySelector = ttUSHORT(data+index_map+10);
1520       stbtt_uint16 rangeShift = ttUSHORT(data+index_map+12) >> 1;
1521 
1522       // do a binary search of the segments
1523       stbtt_uint32 endCount = index_map + 14;
1524       stbtt_uint32 search = endCount;
1525 
1526       if (unicode_codepoint > 0xffff)
1527          return 0;
1528 
1529       // they lie from endCount .. endCount + segCount
1530       // but searchRange is the nearest power of two, so...
1531       if (unicode_codepoint >= ttUSHORT(data + search + rangeShift*2))
1532          search += rangeShift*2;
1533 
1534       // now decrement to bias correctly to find smallest
1535       search -= 2;
1536       while (entrySelector) {
1537          stbtt_uint16 end;
1538          searchRange >>= 1;
1539          end = ttUSHORT(data + search + searchRange*2);
1540          if (unicode_codepoint > end)
1541             search += searchRange*2;
1542          --entrySelector;
1543       }
1544       search += 2;
1545 
1546       {
1547          stbtt_uint16 offset, start, last;
1548          stbtt_uint16 item = (stbtt_uint16) ((search - endCount) >> 1);
1549 
1550          start = ttUSHORT(data + index_map + 14 + segcount*2 + 2 + 2*item);
1551          last = ttUSHORT(data + endCount + 2*item);
1552          if (unicode_codepoint < start || unicode_codepoint > last)
1553             return 0;
1554 
1555          offset = ttUSHORT(data + index_map + 14 + segcount*6 + 2 + 2*item);
1556          if (offset == 0)
1557             return (stbtt_uint16) (unicode_codepoint + ttSHORT(data + index_map + 14 + segcount*4 + 2 + 2*item));
1558 
1559          return ttUSHORT(data + offset + (unicode_codepoint-start)*2 + index_map + 14 + segcount*6 + 2 + 2*item);
1560       }
1561    } else if (format == 12 || format == 13) {
1562       stbtt_uint32 ngroups = ttULONG(data+index_map+12);
1563       stbtt_int32 low,high;
1564       low = 0; high = (stbtt_int32)ngroups;
1565       // Binary search the right group.
1566       while (low < high) {
1567          stbtt_int32 mid = low + ((high-low) >> 1); // rounds down, so low <= mid < high
1568          stbtt_uint32 start_char = ttULONG(data+index_map+16+mid*12);
1569          stbtt_uint32 end_char = ttULONG(data+index_map+16+mid*12+4);
1570          if ((stbtt_uint32) unicode_codepoint < start_char)
1571             high = mid;
1572          else if ((stbtt_uint32) unicode_codepoint > end_char)
1573             low = mid+1;
1574          else {
1575             stbtt_uint32 start_glyph = ttULONG(data+index_map+16+mid*12+8);
1576             if (format == 12)
1577                return start_glyph + unicode_codepoint-start_char;
1578             else // format == 13
1579                return start_glyph;
1580          }
1581       }
1582       return 0; // not found
1583    }
1584    // @TODO
1585    STBTT_assert(0);
1586    return 0;
1587 }
1588 
1589 STBTT_DEF int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices)
1590 {
1591    return stbtt_GetGlyphShape(info, stbtt_FindGlyphIndex(info, unicode_codepoint), vertices);
1592 }
1593 
1594 static void stbtt_setvertex(stbtt_vertex *v, stbtt_uint8 type, stbtt_int32 x, stbtt_int32 y, stbtt_int32 cx, stbtt_int32 cy)
1595 {
1596    v->type = type;
1597    v->x = (stbtt_int16) x;
1598    v->y = (stbtt_int16) y;
1599    v->cx = (stbtt_int16) cx;
1600    v->cy = (stbtt_int16) cy;
1601 }
1602 
1603 static int stbtt__GetGlyfOffset(const stbtt_fontinfo *info, int glyph_index)
1604 {
1605    int g1,g2;
1606 
1607    STBTT_assert(!info->cff.size);
1608 
1609    if (glyph_index >= info->numGlyphs) return -1; // glyph index out of range
1610    if (info->indexToLocFormat >= 2)    return -1; // unknown index->glyph map format
1611 
1612    if (info->indexToLocFormat == 0) {
1613       g1 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2) * 2;
1614       g2 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2 + 2) * 2;
1615    } else {
1616       g1 = info->glyf + ttULONG (info->data + info->loca + glyph_index * 4);
1617       g2 = info->glyf + ttULONG (info->data + info->loca + glyph_index * 4 + 4);
1618    }
1619 
1620    return g1==g2 ? -1 : g1; // if length is 0, return -1
1621 }
1622 
1623 static int stbtt__GetGlyphInfoT2(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1);
1624 
1625 STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1)
1626 {
1627    if (info->cff.size) {
1628       stbtt__GetGlyphInfoT2(info, glyph_index, x0, y0, x1, y1);
1629    } else {
1630       int g = stbtt__GetGlyfOffset(info, glyph_index);
1631       if (g < 0) return 0;
1632 
1633       if (x0) *x0 = ttSHORT(info->data + g + 2);
1634       if (y0) *y0 = ttSHORT(info->data + g + 4);
1635       if (x1) *x1 = ttSHORT(info->data + g + 6);
1636       if (y1) *y1 = ttSHORT(info->data + g + 8);
1637    }
1638    return 1;
1639 }
1640 
1641 STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1)
1642 {
1643    return stbtt_GetGlyphBox(info, stbtt_FindGlyphIndex(info,codepoint), x0,y0,x1,y1);
1644 }
1645 
1646 STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index)
1647 {
1648    stbtt_int16 numberOfContours;
1649    int g;
1650    if (info->cff.size)
1651       return stbtt__GetGlyphInfoT2(info, glyph_index, NULL, NULL, NULL, NULL) == 0;
1652    g = stbtt__GetGlyfOffset(info, glyph_index);
1653    if (g < 0) return 1;
1654    numberOfContours = ttSHORT(info->data + g);
1655    return numberOfContours == 0;
1656 }
1657 
1658 static int stbtt__close_shape(stbtt_vertex *vertices, int num_vertices, int was_off, int start_off,
1659     stbtt_int32 sx, stbtt_int32 sy, stbtt_int32 scx, stbtt_int32 scy, stbtt_int32 cx, stbtt_int32 cy)
1660 {
1661    if (start_off) {
1662       if (was_off)
1663          stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx+scx)>>1, (cy+scy)>>1, cx,cy);
1664       stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, sx,sy,scx,scy);
1665    } else {
1666       if (was_off)
1667          stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve,sx,sy,cx,cy);
1668       else
1669          stbtt_setvertex(&vertices[num_vertices++], STBTT_vline,sx,sy,0,0);
1670    }
1671    return num_vertices;
1672 }
1673 
1674 static int stbtt__GetGlyphShapeTT(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices)
1675 {
1676    stbtt_int16 numberOfContours;
1677    stbtt_uint8 *endPtsOfContours;
1678    stbtt_uint8 *data = info->data;
1679    stbtt_vertex *vertices=0;
1680    int num_vertices=0;
1681    int g = stbtt__GetGlyfOffset(info, glyph_index);
1682 
1683    *pvertices = NULL;
1684 
1685    if (g < 0) return 0;
1686 
1687    numberOfContours = ttSHORT(data + g);
1688 
1689    if (numberOfContours > 0) {
1690       stbtt_uint8 flags=0,flagcount;
1691       stbtt_int32 ins, i,j=0,m,n, next_move, was_off=0, off, start_off=0;
1692       stbtt_int32 x,y,cx,cy,sx,sy, scx,scy;
1693       stbtt_uint8 *points;
1694       endPtsOfContours = (data + g + 10);
1695       ins = ttUSHORT(data + g + 10 + numberOfContours * 2);
1696       points = data + g + 10 + numberOfContours * 2 + 2 + ins;
1697 
1698       n = 1+ttUSHORT(endPtsOfContours + numberOfContours*2-2);
1699 
1700       m = n + 2*numberOfContours;  // a loose bound on how many vertices we might need
1701       vertices = (stbtt_vertex *) STBTT_malloc(m * sizeof(vertices[0]), info->userdata);
1702       if (vertices == 0)
1703          return 0;
1704 
1705       next_move = 0;
1706       flagcount=0;
1707 
1708       // in first pass, we load uninterpreted data into the allocated array
1709       // above, shifted to the end of the array so we won't overwrite it when
1710       // we create our final data starting from the front
1711 
1712       off = m - n; // starting offset for uninterpreted data, regardless of how m ends up being calculated
1713 
1714       // first load flags
1715 
1716       for (i=0; i < n; ++i) {
1717          if (flagcount == 0) {
1718             flags = *points++;
1719             if (flags & 8)
1720                flagcount = *points++;
1721          } else
1722             --flagcount;
1723          vertices[off+i].type = flags;
1724       }
1725 
1726       // now load x coordinates
1727       x=0;
1728       for (i=0; i < n; ++i) {
1729          flags = vertices[off+i].type;
1730          if (flags & 2) {
1731             stbtt_int16 dx = *points++;
1732             x += (flags & 16) ? dx : -dx; // ???
1733          } else {
1734             if (!(flags & 16)) {
1735                x = x + (stbtt_int16) (points[0]*256 + points[1]);
1736                points += 2;
1737             }
1738          }
1739          vertices[off+i].x = (stbtt_int16) x;
1740       }
1741 
1742       // now load y coordinates
1743       y=0;
1744       for (i=0; i < n; ++i) {
1745          flags = vertices[off+i].type;
1746          if (flags & 4) {
1747             stbtt_int16 dy = *points++;
1748             y += (flags & 32) ? dy : -dy; // ???
1749          } else {
1750             if (!(flags & 32)) {
1751                y = y + (stbtt_int16) (points[0]*256 + points[1]);
1752                points += 2;
1753             }
1754          }
1755          vertices[off+i].y = (stbtt_int16) y;
1756       }
1757 
1758       // now convert them to our format
1759       num_vertices=0;
1760       sx = sy = cx = cy = scx = scy = 0;
1761       for (i=0; i < n; ++i) {
1762          flags = vertices[off+i].type;
1763          x     = (stbtt_int16) vertices[off+i].x;
1764          y     = (stbtt_int16) vertices[off+i].y;
1765 
1766          if (next_move == i) {
1767             if (i != 0)
1768                num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
1769 
1770             // now start the new one
1771             start_off = !(flags & 1);
1772             if (start_off) {
1773                // if we start off with an off-curve point, then when we need to find a point on the curve
1774                // where we can start, and we need to save some state for when we wraparound.
1775                scx = x;
1776                scy = y;
1777                if (!(vertices[off+i+1].type & 1)) {
1778                   // next point is also a curve point, so interpolate an on-point curve
1779                   sx = (x + (stbtt_int32) vertices[off+i+1].x) >> 1;
1780                   sy = (y + (stbtt_int32) vertices[off+i+1].y) >> 1;
1781                } else {
1782                   // otherwise just use the next point as our start point
1783                   sx = (stbtt_int32) vertices[off+i+1].x;
1784                   sy = (stbtt_int32) vertices[off+i+1].y;
1785                   ++i; // we're using point i+1 as the starting point, so skip it
1786                }
1787             } else {
1788                sx = x;
1789                sy = y;
1790             }
1791             stbtt_setvertex(&vertices[num_vertices++], STBTT_vmove,sx,sy,0,0);
1792             was_off = 0;
1793             next_move = 1 + ttUSHORT(endPtsOfContours+j*2);
1794             ++j;
1795          } else {
1796             if (!(flags & 1)) { // if it's a curve
1797                if (was_off) // two off-curve control points in a row means interpolate an on-curve midpoint
1798                   stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx+x)>>1, (cy+y)>>1, cx, cy);
1799                cx = x;
1800                cy = y;
1801                was_off = 1;
1802             } else {
1803                if (was_off)
1804                   stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, x,y, cx, cy);
1805                else
1806                   stbtt_setvertex(&vertices[num_vertices++], STBTT_vline, x,y,0,0);
1807                was_off = 0;
1808             }
1809          }
1810       }
1811       num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
1812    } else if (numberOfContours < 0) {
1813       // Compound shapes.
1814       int more = 1;
1815       stbtt_uint8 *comp = data + g + 10;
1816       num_vertices = 0;
1817       vertices = 0;
1818       while (more) {
1819          stbtt_uint16 flags, gidx;
1820          int comp_num_verts = 0, i;
1821          stbtt_vertex *comp_verts = 0, *tmp = 0;
1822          float mtx[6] = {1,0,0,1,0,0}, m, n;
1823 
1824          flags = ttSHORT(comp); comp+=2;
1825          gidx = ttSHORT(comp); comp+=2;
1826 
1827          if (flags & 2) { // XY values
1828             if (flags & 1) { // shorts
1829                mtx[4] = ttSHORT(comp); comp+=2;
1830                mtx[5] = ttSHORT(comp); comp+=2;
1831             } else {
1832                mtx[4] = ttCHAR(comp); comp+=1;
1833                mtx[5] = ttCHAR(comp); comp+=1;
1834             }
1835          }
1836          else {
1837             // @TODO handle matching point
1838             STBTT_assert(0);
1839          }
1840          if (flags & (1<<3)) { // WE_HAVE_A_SCALE
1841             mtx[0] = mtx[3] = ttSHORT(comp)/16384.0f; comp+=2;
1842             mtx[1] = mtx[2] = 0;
1843          } else if (flags & (1<<6)) { // WE_HAVE_AN_X_AND_YSCALE
1844             mtx[0] = ttSHORT(comp)/16384.0f; comp+=2;
1845             mtx[1] = mtx[2] = 0;
1846             mtx[3] = ttSHORT(comp)/16384.0f; comp+=2;
1847          } else if (flags & (1<<7)) { // WE_HAVE_A_TWO_BY_TWO
1848             mtx[0] = ttSHORT(comp)/16384.0f; comp+=2;
1849             mtx[1] = ttSHORT(comp)/16384.0f; comp+=2;
1850             mtx[2] = ttSHORT(comp)/16384.0f; comp+=2;
1851             mtx[3] = ttSHORT(comp)/16384.0f; comp+=2;
1852          }
1853 
1854          // Find transformation scales.
1855          m = (float) STBTT_sqrt(mtx[0]*mtx[0] + mtx[1]*mtx[1]);
1856          n = (float) STBTT_sqrt(mtx[2]*mtx[2] + mtx[3]*mtx[3]);
1857 
1858          // Get indexed glyph.
1859          comp_num_verts = stbtt_GetGlyphShape(info, gidx, &comp_verts);
1860          if (comp_num_verts > 0) {
1861             // Transform vertices.
1862             for (i = 0; i < comp_num_verts; ++i) {
1863                stbtt_vertex* v = &comp_verts[i];
1864                stbtt_vertex_type x,y;
1865                x=v->x; y=v->y;
1866                v->x = (stbtt_vertex_type)(m * (mtx[0]*x + mtx[2]*y + mtx[4]));
1867                v->y = (stbtt_vertex_type)(n * (mtx[1]*x + mtx[3]*y + mtx[5]));
1868                x=v->cx; y=v->cy;
1869                v->cx = (stbtt_vertex_type)(m * (mtx[0]*x + mtx[2]*y + mtx[4]));
1870                v->cy = (stbtt_vertex_type)(n * (mtx[1]*x + mtx[3]*y + mtx[5]));
1871             }
1872             // Append vertices.
1873             tmp = (stbtt_vertex*)STBTT_malloc((num_vertices+comp_num_verts)*sizeof(stbtt_vertex), info->userdata);
1874             if (!tmp) {
1875                if (vertices) STBTT_free(vertices, info->userdata);
1876                if (comp_verts) STBTT_free(comp_verts, info->userdata);
1877                return 0;
1878             }
1879             if (num_vertices > 0 && vertices) STBTT_memcpy(tmp, vertices, num_vertices*sizeof(stbtt_vertex));
1880             STBTT_memcpy(tmp+num_vertices, comp_verts, comp_num_verts*sizeof(stbtt_vertex));
1881             if (vertices) STBTT_free(vertices, info->userdata);
1882             vertices = tmp;
1883             STBTT_free(comp_verts, info->userdata);
1884             num_vertices += comp_num_verts;
1885          }
1886          // More components ?
1887          more = flags & (1<<5);
1888       }
1889    } else {
1890       // numberOfCounters == 0, do nothing
1891    }
1892 
1893    *pvertices = vertices;
1894    return num_vertices;
1895 }
1896 
1897 typedef struct
1898 {
1899    int bounds;
1900    int started;
1901    float first_x, first_y;
1902    float x, y;
1903    stbtt_int32 min_x, max_x, min_y, max_y;
1904 
1905    stbtt_vertex *pvertices;
1906    int num_vertices;
1907 } stbtt__csctx;
1908 
1909 #define STBTT__CSCTX_INIT(bounds) {bounds,0, 0,0, 0,0, 0,0,0,0, NULL, 0}
1910 
1911 static void stbtt__track_vertex(stbtt__csctx *c, stbtt_int32 x, stbtt_int32 y)
1912 {
1913    if (x > c->max_x || !c->started) c->max_x = x;
1914    if (y > c->max_y || !c->started) c->max_y = y;
1915    if (x < c->min_x || !c->started) c->min_x = x;
1916    if (y < c->min_y || !c->started) c->min_y = y;
1917    c->started = 1;
1918 }
1919 
1920 static void stbtt__csctx_v(stbtt__csctx *c, stbtt_uint8 type, stbtt_int32 x, stbtt_int32 y, stbtt_int32 cx, stbtt_int32 cy, stbtt_int32 cx1, stbtt_int32 cy1)
1921 {
1922    if (c->bounds) {
1923       stbtt__track_vertex(c, x, y);
1924       if (type == STBTT_vcubic) {
1925          stbtt__track_vertex(c, cx, cy);
1926          stbtt__track_vertex(c, cx1, cy1);
1927       }
1928    } else {
1929       stbtt_setvertex(&c->pvertices[c->num_vertices], type, x, y, cx, cy);
1930       c->pvertices[c->num_vertices].cx1 = (stbtt_int16) cx1;
1931       c->pvertices[c->num_vertices].cy1 = (stbtt_int16) cy1;
1932    }
1933    c->num_vertices++;
1934 }
1935 
1936 static void stbtt__csctx_close_shape(stbtt__csctx *ctx)
1937 {
1938    if (ctx->first_x != ctx->x || ctx->first_y != ctx->y)
1939       stbtt__csctx_v(ctx, STBTT_vline, (int)ctx->first_x, (int)ctx->first_y, 0, 0, 0, 0);
1940 }
1941 
1942 static void stbtt__csctx_rmove_to(stbtt__csctx *ctx, float dx, float dy)
1943 {
1944    stbtt__csctx_close_shape(ctx);
1945    ctx->first_x = ctx->x = ctx->x + dx;
1946    ctx->first_y = ctx->y = ctx->y + dy;
1947    stbtt__csctx_v(ctx, STBTT_vmove, (int)ctx->x, (int)ctx->y, 0, 0, 0, 0);
1948 }
1949 
1950 static void stbtt__csctx_rline_to(stbtt__csctx *ctx, float dx, float dy)
1951 {
1952    ctx->x += dx;
1953    ctx->y += dy;
1954    stbtt__csctx_v(ctx, STBTT_vline, (int)ctx->x, (int)ctx->y, 0, 0, 0, 0);
1955 }
1956 
1957 static void stbtt__csctx_rccurve_to(stbtt__csctx *ctx, float dx1, float dy1, float dx2, float dy2, float dx3, float dy3)
1958 {
1959    float cx1 = ctx->x + dx1;
1960    float cy1 = ctx->y + dy1;
1961    float cx2 = cx1 + dx2;
1962    float cy2 = cy1 + dy2;
1963    ctx->x = cx2 + dx3;
1964    ctx->y = cy2 + dy3;
1965    stbtt__csctx_v(ctx, STBTT_vcubic, (int)ctx->x, (int)ctx->y, (int)cx1, (int)cy1, (int)cx2, (int)cy2);
1966 }
1967 
1968 static stbtt__buf stbtt__get_subr(stbtt__buf idx, int n)
1969 {
1970    int count = stbtt__cff_index_count(&idx);
1971    int bias = 107;
1972    if (count >= 33900)
1973       bias = 32768;
1974    else if (count >= 1240)
1975       bias = 1131;
1976    n += bias;
1977    if (n < 0 || n >= count)
1978       return stbtt__new_buf(NULL, 0);
1979    return stbtt__cff_index_get(idx, n);
1980 }
1981 
1982 static stbtt__buf stbtt__cid_get_glyph_subrs(const stbtt_fontinfo *info, int glyph_index)
1983 {
1984    stbtt__buf fdselect = info->fdselect;
1985    int nranges, start, end, v, fmt, fdselector = -1, i;
1986 
1987    stbtt__buf_seek(&fdselect, 0);
1988    fmt = stbtt__buf_get8(&fdselect);
1989    if (fmt == 0) {
1990       // untested
1991       stbtt__buf_skip(&fdselect, glyph_index);
1992       fdselector = stbtt__buf_get8(&fdselect);
1993    } else if (fmt == 3) {
1994       nranges = stbtt__buf_get16(&fdselect);
1995       start = stbtt__buf_get16(&fdselect);
1996       for (i = 0; i < nranges; i++) {
1997          v = stbtt__buf_get8(&fdselect);
1998          end = stbtt__buf_get16(&fdselect);
1999          if (glyph_index >= start && glyph_index < end) {
2000             fdselector = v;
2001             break;
2002          }
2003          start = end;
2004       }
2005    }
2006    if (fdselector == -1) stbtt__new_buf(NULL, 0);
2007    return stbtt__get_subrs(info->cff, stbtt__cff_index_get(info->fontdicts, fdselector));
2008 }
2009 
2010 static int stbtt__run_charstring(const stbtt_fontinfo *info, int glyph_index, stbtt__csctx *c)
2011 {
2012    int in_header = 1, maskbits = 0, subr_stack_height = 0, sp = 0, v, i, b0;
2013    int has_subrs = 0, clear_stack;
2014    float s[48];
2015    stbtt__buf subr_stack[10], subrs = info->subrs, b;
2016    float f;
2017 
2018 #define STBTT__CSERR(s) (0)
2019 
2020    // this currently ignores the initial width value, which isn't needed if we have hmtx
2021    b = stbtt__cff_index_get(info->charstrings, glyph_index);
2022    while (b.cursor < b.size) {
2023       i = 0;
2024       clear_stack = 1;
2025       b0 = stbtt__buf_get8(&b);
2026       switch (b0) {
2027       // @TODO implement hinting
2028       case 0x13: // hintmask
2029       case 0x14: // cntrmask
2030          if (in_header)
2031             maskbits += (sp / 2); // implicit "vstem"
2032          in_header = 0;
2033          stbtt__buf_skip(&b, (maskbits + 7) / 8);
2034          break;
2035 
2036       case 0x01: // hstem
2037       case 0x03: // vstem
2038       case 0x12: // hstemhm
2039       case 0x17: // vstemhm
2040          maskbits += (sp / 2);
2041          break;
2042 
2043       case 0x15: // rmoveto
2044          in_header = 0;
2045          if (sp < 2) return STBTT__CSERR("rmoveto stack");
2046          stbtt__csctx_rmove_to(c, s[sp-2], s[sp-1]);
2047          break;
2048       case 0x04: // vmoveto
2049          in_header = 0;
2050          if (sp < 1) return STBTT__CSERR("vmoveto stack");
2051          stbtt__csctx_rmove_to(c, 0, s[sp-1]);
2052          break;
2053       case 0x16: // hmoveto
2054          in_header = 0;
2055          if (sp < 1) return STBTT__CSERR("hmoveto stack");
2056          stbtt__csctx_rmove_to(c, s[sp-1], 0);
2057          break;
2058 
2059       case 0x05: // rlineto
2060          if (sp < 2) return STBTT__CSERR("rlineto stack");
2061          for (; i + 1 < sp; i += 2)
2062             stbtt__csctx_rline_to(c, s[i], s[i+1]);
2063          break;
2064 
2065       // hlineto/vlineto and vhcurveto/hvcurveto alternate horizontal and vertical
2066       // starting from a different place.
2067 
2068       case 0x07: // vlineto
2069          if (sp < 1) return STBTT__CSERR("vlineto stack");
2070          goto vlineto;
2071       case 0x06: // hlineto
2072          if (sp < 1) return STBTT__CSERR("hlineto stack");
2073          for (;;) {
2074             if (i >= sp) break;
2075             stbtt__csctx_rline_to(c, s[i], 0);
2076             i++;
2077       vlineto:
2078             if (i >= sp) break;
2079             stbtt__csctx_rline_to(c, 0, s[i]);
2080             i++;
2081          }
2082          break;
2083 
2084       case 0x1F: // hvcurveto
2085          if (sp < 4) return STBTT__CSERR("hvcurveto stack");
2086          goto hvcurveto;
2087       case 0x1E: // vhcurveto
2088          if (sp < 4) return STBTT__CSERR("vhcurveto stack");
2089          for (;;) {
2090             if (i + 3 >= sp) break;
2091             stbtt__csctx_rccurve_to(c, 0, s[i], s[i+1], s[i+2], s[i+3], (sp - i == 5) ? s[i + 4] : 0.0f);
2092             i += 4;
2093       hvcurveto:
2094             if (i + 3 >= sp) break;
2095             stbtt__csctx_rccurve_to(c, s[i], 0, s[i+1], s[i+2], (sp - i == 5) ? s[i+4] : 0.0f, s[i+3]);
2096             i += 4;
2097          }
2098          break;
2099 
2100       case 0x08: // rrcurveto
2101          if (sp < 6) return STBTT__CSERR("rcurveline stack");
2102          for (; i + 5 < sp; i += 6)
2103             stbtt__csctx_rccurve_to(c, s[i], s[i+1], s[i+2], s[i+3], s[i+4], s[i+5]);
2104          break;
2105 
2106       case 0x18: // rcurveline
2107          if (sp < 8) return STBTT__CSERR("rcurveline stack");
2108          for (; i + 5 < sp - 2; i += 6)
2109             stbtt__csctx_rccurve_to(c, s[i], s[i+1], s[i+2], s[i+3], s[i+4], s[i+5]);
2110          if (i + 1 >= sp) return STBTT__CSERR("rcurveline stack");
2111          stbtt__csctx_rline_to(c, s[i], s[i+1]);
2112          break;
2113 
2114       case 0x19: // rlinecurve
2115          if (sp < 8) return STBTT__CSERR("rlinecurve stack");
2116          for (; i + 1 < sp - 6; i += 2)
2117             stbtt__csctx_rline_to(c, s[i], s[i+1]);
2118          if (i + 5 >= sp) return STBTT__CSERR("rlinecurve stack");
2119          stbtt__csctx_rccurve_to(c, s[i], s[i+1], s[i+2], s[i+3], s[i+4], s[i+5]);
2120          break;
2121 
2122       case 0x1A: // vvcurveto
2123       case 0x1B: // hhcurveto
2124          if (sp < 4) return STBTT__CSERR("(vv|hh)curveto stack");
2125          f = 0.0;
2126          if (sp & 1) { f = s[i]; i++; }
2127          for (; i + 3 < sp; i += 4) {
2128             if (b0 == 0x1B)
2129                stbtt__csctx_rccurve_to(c, s[i], f, s[i+1], s[i+2], s[i+3], 0.0);
2130             else
2131                stbtt__csctx_rccurve_to(c, f, s[i], s[i+1], s[i+2], 0.0, s[i+3]);
2132             f = 0.0;
2133          }
2134          break;
2135 
2136       case 0x0A: // callsubr
2137          if (!has_subrs) {
2138             if (info->fdselect.size)
2139                subrs = stbtt__cid_get_glyph_subrs(info, glyph_index);
2140             has_subrs = 1;
2141          }
2142          // FALLTHROUGH
2143       case 0x1D: // callgsubr
2144          if (sp < 1) return STBTT__CSERR("call(g|)subr stack");
2145          v = (int) s[--sp];
2146          if (subr_stack_height >= 10) return STBTT__CSERR("recursion limit");
2147          subr_stack[subr_stack_height++] = b;
2148          b = stbtt__get_subr(b0 == 0x0A ? subrs : info->gsubrs, v);
2149          if (b.size == 0) return STBTT__CSERR("subr not found");
2150          b.cursor = 0;
2151          clear_stack = 0;
2152          break;
2153 
2154       case 0x0B: // return
2155          if (subr_stack_height <= 0) return STBTT__CSERR("return outside subr");
2156          b = subr_stack[--subr_stack_height];
2157          clear_stack = 0;
2158          break;
2159 
2160       case 0x0E: // endchar
2161          stbtt__csctx_close_shape(c);
2162          return 1;
2163 
2164       case 0x0C: { // two-byte escape
2165          float dx1, dx2, dx3, dx4, dx5, dx6, dy1, dy2, dy3, dy4, dy5, dy6;
2166          float dx, dy;
2167          int b1 = stbtt__buf_get8(&b);
2168          switch (b1) {
2169          // @TODO These "flex" implementations ignore the flex-depth and resolution,
2170          // and always draw beziers.
2171          case 0x22: // hflex
2172             if (sp < 7) return STBTT__CSERR("hflex stack");
2173             dx1 = s[0];
2174             dx2 = s[1];
2175             dy2 = s[2];
2176             dx3 = s[3];
2177             dx4 = s[4];
2178             dx5 = s[5];
2179             dx6 = s[6];
2180             stbtt__csctx_rccurve_to(c, dx1, 0, dx2, dy2, dx3, 0);
2181             stbtt__csctx_rccurve_to(c, dx4, 0, dx5, -dy2, dx6, 0);
2182             break;
2183 
2184          case 0x23: // flex
2185             if (sp < 13) return STBTT__CSERR("flex stack");
2186             dx1 = s[0];
2187             dy1 = s[1];
2188             dx2 = s[2];
2189             dy2 = s[3];
2190             dx3 = s[4];
2191             dy3 = s[5];
2192             dx4 = s[6];
2193             dy4 = s[7];
2194             dx5 = s[8];
2195             dy5 = s[9];
2196             dx6 = s[10];
2197             dy6 = s[11];
2198             //fd is s[12]
2199             stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, dy3);
2200             stbtt__csctx_rccurve_to(c, dx4, dy4, dx5, dy5, dx6, dy6);
2201             break;
2202 
2203          case 0x24: // hflex1
2204             if (sp < 9) return STBTT__CSERR("hflex1 stack");
2205             dx1 = s[0];
2206             dy1 = s[1];
2207             dx2 = s[2];
2208             dy2 = s[3];
2209             dx3 = s[4];
2210             dx4 = s[5];
2211             dx5 = s[6];
2212             dy5 = s[7];
2213             dx6 = s[8];
2214             stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, 0);
2215             stbtt__csctx_rccurve_to(c, dx4, 0, dx5, dy5, dx6, -(dy1+dy2+dy5));
2216             break;
2217 
2218          case 0x25: // flex1
2219             if (sp < 11) return STBTT__CSERR("flex1 stack");
2220             dx1 = s[0];
2221             dy1 = s[1];
2222             dx2 = s[2];
2223             dy2 = s[3];
2224             dx3 = s[4];
2225             dy3 = s[5];
2226             dx4 = s[6];
2227             dy4 = s[7];
2228             dx5 = s[8];
2229             dy5 = s[9];
2230             dx6 = dy6 = s[10];
2231             dx = dx1+dx2+dx3+dx4+dx5;
2232             dy = dy1+dy2+dy3+dy4+dy5;
2233             if (STBTT_fabs(dx) > STBTT_fabs(dy))
2234                dy6 = -dy;
2235             else
2236                dx6 = -dx;
2237             stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, dy3);
2238             stbtt__csctx_rccurve_to(c, dx4, dy4, dx5, dy5, dx6, dy6);
2239             break;
2240 
2241          default:
2242             return STBTT__CSERR("unimplemented");
2243          }
2244       } break;
2245 
2246       default:
2247          if (b0 != 255 && b0 != 28 && b0 < 32)
2248             return STBTT__CSERR("reserved operator");
2249 
2250          // push immediate
2251          if (b0 == 255) {
2252             f = (float)(stbtt_int32)stbtt__buf_get32(&b) / 0x10000;
2253          } else {
2254             stbtt__buf_skip(&b, -1);
2255             f = (float)(stbtt_int16)stbtt__cff_int(&b);
2256          }
2257          if (sp >= 48) return STBTT__CSERR("push stack overflow");
2258          s[sp++] = f;
2259          clear_stack = 0;
2260          break;
2261       }
2262       if (clear_stack) sp = 0;
2263    }
2264    return STBTT__CSERR("no endchar");
2265 
2266 #undef STBTT__CSERR
2267 }
2268 
2269 static int stbtt__GetGlyphShapeT2(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices)
2270 {
2271    // runs the charstring twice, once to count and once to output (to avoid realloc)
2272    stbtt__csctx count_ctx = STBTT__CSCTX_INIT(1);
2273    stbtt__csctx output_ctx = STBTT__CSCTX_INIT(0);
2274    if (stbtt__run_charstring(info, glyph_index, &count_ctx)) {
2275       *pvertices = (stbtt_vertex*)STBTT_malloc(count_ctx.num_vertices*sizeof(stbtt_vertex), info->userdata);
2276       output_ctx.pvertices = *pvertices;
2277       if (stbtt__run_charstring(info, glyph_index, &output_ctx)) {
2278          STBTT_assert(output_ctx.num_vertices == count_ctx.num_vertices);
2279          return output_ctx.num_vertices;
2280       }
2281    }
2282    *pvertices = NULL;
2283    return 0;
2284 }
2285 
2286 static int stbtt__GetGlyphInfoT2(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1)
2287 {
2288    stbtt__csctx c = STBTT__CSCTX_INIT(1);
2289    int r = stbtt__run_charstring(info, glyph_index, &c);
2290    if (x0)  *x0 = r ? c.min_x : 0;
2291    if (y0)  *y0 = r ? c.min_y : 0;
2292    if (x1)  *x1 = r ? c.max_x : 0;
2293    if (y1)  *y1 = r ? c.max_y : 0;
2294    return r ? c.num_vertices : 0;
2295 }
2296 
2297 STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices)
2298 {
2299    if (!info->cff.size)
2300       return stbtt__GetGlyphShapeTT(info, glyph_index, pvertices);
2301    else
2302       return stbtt__GetGlyphShapeT2(info, glyph_index, pvertices);
2303 }
2304 
2305 STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing)
2306 {
2307    stbtt_uint16 numOfLongHorMetrics = ttUSHORT(info->data+info->hhea + 34);
2308    if (glyph_index < numOfLongHorMetrics) {
2309       if (advanceWidth)     *advanceWidth    = ttSHORT(info->data + info->hmtx + 4*glyph_index);
2310       if (leftSideBearing)  *leftSideBearing = ttSHORT(info->data + info->hmtx + 4*glyph_index + 2);
2311    } else {
2312       if (advanceWidth)     *advanceWidth    = ttSHORT(info->data + info->hmtx + 4*(numOfLongHorMetrics-1));
2313       if (leftSideBearing)  *leftSideBearing = ttSHORT(info->data + info->hmtx + 4*numOfLongHorMetrics + 2*(glyph_index - numOfLongHorMetrics));
2314    }
2315 }
2316 
2317 STBTT_DEF int  stbtt_GetKerningTableLength(const stbtt_fontinfo *info)
2318 {
2319    stbtt_uint8 *data = info->data + info->kern;
2320 
2321    // we only look at the first table. it must be 'horizontal' and format 0.
2322    if (!info->kern)
2323       return 0;
2324    if (ttUSHORT(data+2) < 1) // number of tables, need at least 1
2325       return 0;
2326    if (ttUSHORT(data+8) != 1) // horizontal flag must be set in format
2327       return 0;
2328 
2329    return ttUSHORT(data+10);
2330 }
2331 
2332 STBTT_DEF int stbtt_GetKerningTable(const stbtt_fontinfo *info, stbtt_kerningentry* table, int table_length)
2333 {
2334    stbtt_uint8 *data = info->data + info->kern;
2335    int k, length;
2336 
2337    // we only look at the first table. it must be 'horizontal' and format 0.
2338    if (!info->kern)
2339       return 0;
2340    if (ttUSHORT(data+2) < 1) // number of tables, need at least 1
2341       return 0;
2342    if (ttUSHORT(data+8) != 1) // horizontal flag must be set in format
2343       return 0;
2344 
2345    length = ttUSHORT(data+10);
2346    if (table_length < length)
2347       length = table_length;
2348 
2349    for (k = 0; k < length; k++)
2350    {
2351       table[k].glyph1 = ttUSHORT(data+18+(k*6));
2352       table[k].glyph2 = ttUSHORT(data+20+(k*6));
2353       table[k].advance = ttSHORT(data+22+(k*6));
2354    }
2355 
2356    return length;
2357 }
2358 
2359 static int stbtt__GetGlyphKernInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2)
2360 {
2361    stbtt_uint8 *data = info->data + info->kern;
2362    stbtt_uint32 needle, straw;
2363    int l, r, m;
2364 
2365    // we only look at the first table. it must be 'horizontal' and format 0.
2366    if (!info->kern)
2367       return 0;
2368    if (ttUSHORT(data+2) < 1) // number of tables, need at least 1
2369       return 0;
2370    if (ttUSHORT(data+8) != 1) // horizontal flag must be set in format
2371       return 0;
2372 
2373    l = 0;
2374    r = ttUSHORT(data+10) - 1;
2375    needle = glyph1 << 16 | glyph2;
2376    while (l <= r) {
2377       m = (l + r) >> 1;
2378       straw = ttULONG(data+18+(m*6)); // note: unaligned read
2379       if (needle < straw)
2380          r = m - 1;
2381       else if (needle > straw)
2382          l = m + 1;
2383       else
2384          return ttSHORT(data+22+(m*6));
2385    }
2386    return 0;
2387 }
2388 
2389 static stbtt_int32 stbtt__GetCoverageIndex(stbtt_uint8 *coverageTable, int glyph)
2390 {
2391    stbtt_uint16 coverageFormat = ttUSHORT(coverageTable);
2392    switch (coverageFormat) {
2393       case 1: {
2394          stbtt_uint16 glyphCount = ttUSHORT(coverageTable + 2);
2395 
2396          // Binary search.
2397          stbtt_int32 l=0, r=glyphCount-1, m;
2398          int straw, needle=glyph;
2399          while (l <= r) {
2400             stbtt_uint8 *glyphArray = coverageTable + 4;
2401             stbtt_uint16 glyphID;
2402             m = (l + r) >> 1;
2403             glyphID = ttUSHORT(glyphArray + 2 * m);
2404             straw = glyphID;
2405             if (needle < straw)
2406                r = m - 1;
2407             else if (needle > straw)
2408                l = m + 1;
2409             else {
2410                return m;
2411             }
2412          }
2413          break;
2414       }
2415 
2416       case 2: {
2417          stbtt_uint16 rangeCount = ttUSHORT(coverageTable + 2);
2418          stbtt_uint8 *rangeArray = coverageTable + 4;
2419 
2420          // Binary search.
2421          stbtt_int32 l=0, r=rangeCount-1, m;
2422          int strawStart, strawEnd, needle=glyph;
2423          while (l <= r) {
2424             stbtt_uint8 *rangeRecord;
2425             m = (l + r) >> 1;
2426             rangeRecord = rangeArray + 6 * m;
2427             strawStart = ttUSHORT(rangeRecord);
2428             strawEnd = ttUSHORT(rangeRecord + 2);
2429             if (needle < strawStart)
2430                r = m - 1;
2431             else if (needle > strawEnd)
2432                l = m + 1;
2433             else {
2434                stbtt_uint16 startCoverageIndex = ttUSHORT(rangeRecord + 4);
2435                return startCoverageIndex + glyph - strawStart;
2436             }
2437          }
2438          break;
2439       }
2440 
2441       default: return -1; // unsupported
2442    }
2443 
2444    return -1;
2445 }
2446 
2447 static stbtt_int32  stbtt__GetGlyphClass(stbtt_uint8 *classDefTable, int glyph)
2448 {
2449    stbtt_uint16 classDefFormat = ttUSHORT(classDefTable);
2450    switch (classDefFormat)
2451    {
2452       case 1: {
2453          stbtt_uint16 startGlyphID = ttUSHORT(classDefTable + 2);
2454          stbtt_uint16 glyphCount = ttUSHORT(classDefTable + 4);
2455          stbtt_uint8 *classDef1ValueArray = classDefTable + 6;
2456 
2457          if (glyph >= startGlyphID && glyph < startGlyphID + glyphCount)
2458             return (stbtt_int32)ttUSHORT(classDef1ValueArray + 2 * (glyph - startGlyphID));
2459          break;
2460       }
2461 
2462       case 2: {
2463          stbtt_uint16 classRangeCount = ttUSHORT(classDefTable + 2);
2464          stbtt_uint8 *classRangeRecords = classDefTable + 4;
2465 
2466          // Binary search.
2467          stbtt_int32 l=0, r=classRangeCount-1, m;
2468          int strawStart, strawEnd, needle=glyph;
2469          while (l <= r) {
2470             stbtt_uint8 *classRangeRecord;
2471             m = (l + r) >> 1;
2472             classRangeRecord = classRangeRecords + 6 * m;
2473             strawStart = ttUSHORT(classRangeRecord);
2474             strawEnd = ttUSHORT(classRangeRecord + 2);
2475             if (needle < strawStart)
2476                r = m - 1;
2477             else if (needle > strawEnd)
2478                l = m + 1;
2479             else
2480                return (stbtt_int32)ttUSHORT(classRangeRecord + 4);
2481          }
2482          break;
2483       }
2484 
2485       default:
2486          return -1; // Unsupported definition type, return an error.
2487    }
2488 
2489    // "All glyphs not assigned to a class fall into class 0". (OpenType spec)
2490    return 0;
2491 }
2492 
2493 // Define to STBTT_assert(x) if you want to break on unimplemented formats.
2494 #define STBTT_GPOS_TODO_assert(x)
2495 
2496 static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2)
2497 {
2498    stbtt_uint16 lookupListOffset;
2499    stbtt_uint8 *lookupList;
2500    stbtt_uint16 lookupCount;
2501    stbtt_uint8 *data;
2502    stbtt_int32 i, sti;
2503 
2504    if (!info->gpos) return 0;
2505 
2506    data = info->data + info->gpos;
2507 
2508    if (ttUSHORT(data+0) != 1) return 0; // Major version 1
2509    if (ttUSHORT(data+2) != 0) return 0; // Minor version 0
2510 
2511    lookupListOffset = ttUSHORT(data+8);
2512    lookupList = data + lookupListOffset;
2513    lookupCount = ttUSHORT(lookupList);
2514 
2515    for (i=0; i<lookupCount; ++i) {
2516       stbtt_uint16 lookupOffset = ttUSHORT(lookupList + 2 + 2 * i);
2517       stbtt_uint8 *lookupTable = lookupList + lookupOffset;
2518 
2519       stbtt_uint16 lookupType = ttUSHORT(lookupTable);
2520       stbtt_uint16 subTableCount = ttUSHORT(lookupTable + 4);
2521       stbtt_uint8 *subTableOffsets = lookupTable + 6;
2522       if (lookupType != 2) // Pair Adjustment Positioning Subtable
2523          continue;
2524 
2525       for (sti=0; sti<subTableCount; sti++) {
2526          stbtt_uint16 subtableOffset = ttUSHORT(subTableOffsets + 2 * sti);
2527          stbtt_uint8 *table = lookupTable + subtableOffset;
2528          stbtt_uint16 posFormat = ttUSHORT(table);
2529          stbtt_uint16 coverageOffset = ttUSHORT(table + 2);
2530          stbtt_int32 coverageIndex = stbtt__GetCoverageIndex(table + coverageOffset, glyph1);
2531          if (coverageIndex == -1) continue;
2532 
2533          switch (posFormat) {
2534             case 1: {
2535                stbtt_int32 l, r, m;
2536                int straw, needle;
2537                stbtt_uint16 valueFormat1 = ttUSHORT(table + 4);
2538                stbtt_uint16 valueFormat2 = ttUSHORT(table + 6);
2539                if (valueFormat1 == 4 && valueFormat2 == 0) { // Support more formats?
2540                   stbtt_int32 valueRecordPairSizeInBytes = 2;
2541                   stbtt_uint16 pairSetCount = ttUSHORT(table + 8);
2542                   stbtt_uint16 pairPosOffset = ttUSHORT(table + 10 + 2 * coverageIndex);
2543                   stbtt_uint8 *pairValueTable = table + pairPosOffset;
2544                   stbtt_uint16 pairValueCount = ttUSHORT(pairValueTable);
2545                   stbtt_uint8 *pairValueArray = pairValueTable + 2;
2546 
2547                   if (coverageIndex >= pairSetCount) return 0;
2548 
2549                   needle=glyph2;
2550                   r=pairValueCount-1;
2551                   l=0;
2552 
2553                   // Binary search.
2554                   while (l <= r) {
2555                      stbtt_uint16 secondGlyph;
2556                      stbtt_uint8 *pairValue;
2557                      m = (l + r) >> 1;
2558                      pairValue = pairValueArray + (2 + valueRecordPairSizeInBytes) * m;
2559                      secondGlyph = ttUSHORT(pairValue);
2560                      straw = secondGlyph;
2561                      if (needle < straw)
2562                         r = m - 1;
2563                      else if (needle > straw)
2564                         l = m + 1;
2565                      else {
2566                         stbtt_int16 xAdvance = ttSHORT(pairValue + 2);
2567                         return xAdvance;
2568                      }
2569                   }
2570                } else
2571                   return 0;
2572                break;
2573             }
2574 
2575             case 2: {
2576                stbtt_uint16 valueFormat1 = ttUSHORT(table + 4);
2577                stbtt_uint16 valueFormat2 = ttUSHORT(table + 6);
2578                if (valueFormat1 == 4 && valueFormat2 == 0) { // Support more formats?
2579                   stbtt_uint16 classDef1Offset = ttUSHORT(table + 8);
2580                   stbtt_uint16 classDef2Offset = ttUSHORT(table + 10);
2581                   int glyph1class = stbtt__GetGlyphClass(table + classDef1Offset, glyph1);
2582                   int glyph2class = stbtt__GetGlyphClass(table + classDef2Offset, glyph2);
2583 
2584                   stbtt_uint16 class1Count = ttUSHORT(table + 12);
2585                   stbtt_uint16 class2Count = ttUSHORT(table + 14);
2586                   stbtt_uint8 *class1Records, *class2Records;
2587                   stbtt_int16 xAdvance;
2588 
2589                   if (glyph1class < 0 || glyph1class >= class1Count) return 0; // malformed
2590                   if (glyph2class < 0 || glyph2class >= class2Count) return 0; // malformed
2591 
2592                   class1Records = table + 16;
2593                   class2Records = class1Records + 2 * (glyph1class * class2Count);
2594                   xAdvance = ttSHORT(class2Records + 2 * glyph2class);
2595                   return xAdvance;
2596                } else
2597                   return 0;
2598                break;
2599             }
2600 
2601             default:
2602                return 0; // Unsupported position format
2603          }
2604       }
2605    }
2606 
2607    return 0;
2608 }
2609 
2610 STBTT_DEF int  stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int g1, int g2)
2611 {
2612    int xAdvance = 0;
2613 
2614    if (info->gpos)
2615       xAdvance += stbtt__GetGlyphGPOSInfoAdvance(info, g1, g2);
2616    else if (info->kern)
2617       xAdvance += stbtt__GetGlyphKernInfoAdvance(info, g1, g2);
2618 
2619    return xAdvance;
2620 }
2621 
2622 STBTT_DEF int  stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2)
2623 {
2624    if (!info->kern && !info->gpos) // if no kerning table, don't waste time looking up both codepoint->glyphs
2625       return 0;
2626    return stbtt_GetGlyphKernAdvance(info, stbtt_FindGlyphIndex(info,ch1), stbtt_FindGlyphIndex(info,ch2));
2627 }
2628 
2629 STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing)
2630 {
2631    stbtt_GetGlyphHMetrics(info, stbtt_FindGlyphIndex(info,codepoint), advanceWidth, leftSideBearing);
2632 }
2633 
2634 STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap)
2635 {
2636    if (ascent ) *ascent  = ttSHORT(info->data+info->hhea + 4);
2637    if (descent) *descent = ttSHORT(info->data+info->hhea + 6);
2638    if (lineGap) *lineGap = ttSHORT(info->data+info->hhea + 8);
2639 }
2640 
2641 STBTT_DEF int  stbtt_GetFontVMetricsOS2(const stbtt_fontinfo *info, int *typoAscent, int *typoDescent, int *typoLineGap)
2642 {
2643    int tab = stbtt__find_table(info->data, info->fontstart, "OS/2");
2644    if (!tab)
2645       return 0;
2646    if (typoAscent ) *typoAscent  = ttSHORT(info->data+tab + 68);
2647    if (typoDescent) *typoDescent = ttSHORT(info->data+tab + 70);
2648    if (typoLineGap) *typoLineGap = ttSHORT(info->data+tab + 72);
2649    return 1;
2650 }
2651 
2652 STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1)
2653 {
2654    *x0 = ttSHORT(info->data + info->head + 36);
2655    *y0 = ttSHORT(info->data + info->head + 38);
2656    *x1 = ttSHORT(info->data + info->head + 40);
2657    *y1 = ttSHORT(info->data + info->head + 42);
2658 }
2659 
2660 STBTT_DEF float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float height)
2661 {
2662    int fheight = ttSHORT(info->data + info->hhea + 4) - ttSHORT(info->data + info->hhea + 6);
2663    return (float) height / fheight;
2664 }
2665 
2666 STBTT_DEF float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels)
2667 {
2668    int unitsPerEm = ttUSHORT(info->data + info->head + 18);
2669    return pixels / unitsPerEm;
2670 }
2671 
2672 STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *v)
2673 {
2674    STBTT_free(v, info->userdata);
2675 }
2676 
2677 STBTT_DEF stbtt_uint8 *stbtt_FindSVGDoc(const stbtt_fontinfo *info, int gl)
2678 {
2679    int i;
2680    stbtt_uint8 *data = info->data;
2681    stbtt_uint8 *svg_doc_list = data + stbtt__get_svg((stbtt_fontinfo *) info);
2682 
2683    int numEntries = ttUSHORT(svg_doc_list);
2684    stbtt_uint8 *svg_docs = svg_doc_list + 2;
2685 
2686    for(i=0; i<numEntries; i++) {
2687       stbtt_uint8 *svg_doc = svg_docs + (12 * i);
2688       if ((gl >= ttUSHORT(svg_doc)) && (gl <= ttUSHORT(svg_doc + 2)))
2689          return svg_doc;
2690    }
2691    return 0;
2692 }
2693 
2694 STBTT_DEF int stbtt_GetGlyphSVG(const stbtt_fontinfo *info, int gl, const char **svg)
2695 {
2696    stbtt_uint8 *data = info->data;
2697    stbtt_uint8 *svg_doc;
2698 
2699    if (info->svg == 0)
2700       return 0;
2701 
2702    svg_doc = stbtt_FindSVGDoc(info, gl);
2703    if (svg_doc != NULL) {
2704       *svg = (char *) data + info->svg + ttULONG(svg_doc + 4);
2705       return ttULONG(svg_doc + 8);
2706    } else {
2707       return 0;
2708    }
2709 }
2710 
2711 STBTT_DEF int stbtt_GetCodepointSVG(const stbtt_fontinfo *info, int unicode_codepoint, const char **svg)
2712 {
2713    return stbtt_GetGlyphSVG(info, stbtt_FindGlyphIndex(info, unicode_codepoint), svg);
2714 }
2715 
2716 //////////////////////////////////////////////////////////////////////////////
2717 //
2718 // antialiasing software rasterizer
2719 //
2720 
2721 STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1)
2722 {
2723    int x0=0,y0=0,x1,y1; // =0 suppresses compiler warning
2724    if (!stbtt_GetGlyphBox(font, glyph, &x0,&y0,&x1,&y1)) {
2725       // e.g. space character
2726       if (ix0) *ix0 = 0;
2727       if (iy0) *iy0 = 0;
2728       if (ix1) *ix1 = 0;
2729       if (iy1) *iy1 = 0;
2730    } else {
2731       // move to integral bboxes (treating pixels as little squares, what pixels get touched)?
2732       if (ix0) *ix0 = STBTT_ifloor( x0 * scale_x + shift_x);
2733       if (iy0) *iy0 = STBTT_ifloor(-y1 * scale_y + shift_y);
2734       if (ix1) *ix1 = STBTT_iceil ( x1 * scale_x + shift_x);
2735       if (iy1) *iy1 = STBTT_iceil (-y0 * scale_y + shift_y);
2736    }
2737 }
2738 
2739 STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1)
2740 {
2741    stbtt_GetGlyphBitmapBoxSubpixel(font, glyph, scale_x, scale_y,0.0f,0.0f, ix0, iy0, ix1, iy1);
2742 }
2743 
2744 STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1)
2745 {
2746    stbtt_GetGlyphBitmapBoxSubpixel(font, stbtt_FindGlyphIndex(font,codepoint), scale_x, scale_y,shift_x,shift_y, ix0,iy0,ix1,iy1);
2747 }
2748 
2749 STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1)
2750 {
2751    stbtt_GetCodepointBitmapBoxSubpixel(font, codepoint, scale_x, scale_y,0.0f,0.0f, ix0,iy0,ix1,iy1);
2752 }
2753 
2754 //////////////////////////////////////////////////////////////////////////////
2755 //
2756 //  Rasterizer
2757 
2758 typedef struct stbtt__hheap_chunk
2759 {
2760    struct stbtt__hheap_chunk *next;
2761 } stbtt__hheap_chunk;
2762 
2763 typedef struct stbtt__hheap
2764 {
2765    struct stbtt__hheap_chunk *head;
2766    void   *first_free;
2767    int    num_remaining_in_head_chunk;
2768 } stbtt__hheap;
2769 
2770 static void *stbtt__hheap_alloc(stbtt__hheap *hh, size_t size, void *userdata)
2771 {
2772    if (hh->first_free) {
2773       void *p = hh->first_free;
2774       hh->first_free = * (void **) p;
2775       return p;
2776    } else {
2777       if (hh->num_remaining_in_head_chunk == 0) {
2778          int count = (size < 32 ? 2000 : size < 128 ? 800 : 100);
2779          stbtt__hheap_chunk *c = (stbtt__hheap_chunk *) STBTT_malloc(sizeof(stbtt__hheap_chunk) + size * count, userdata);
2780          if (c == NULL)
2781             return NULL;
2782          c->next = hh->head;
2783          hh->head = c;
2784          hh->num_remaining_in_head_chunk = count;
2785       }
2786       --hh->num_remaining_in_head_chunk;
2787       return (char *) (hh->head) + sizeof(stbtt__hheap_chunk) + size * hh->num_remaining_in_head_chunk;
2788    }
2789 }
2790 
2791 static void stbtt__hheap_free(stbtt__hheap *hh, void *p)
2792 {
2793    *(void **) p = hh->first_free;
2794    hh->first_free = p;
2795 }
2796 
2797 static void stbtt__hheap_cleanup(stbtt__hheap *hh, void *userdata)
2798 {
2799    stbtt__hheap_chunk *c = hh->head;
2800    while (c) {
2801       stbtt__hheap_chunk *n = c->next;
2802       STBTT_free(c, userdata);
2803       c = n;
2804    }
2805 }
2806 
2807 typedef struct stbtt__edge {
2808    float x0,y0, x1,y1;
2809    int invert;
2810 } stbtt__edge;
2811 
2812 
2813 typedef struct stbtt__active_edge
2814 {
2815    struct stbtt__active_edge *next;
2816    #if STBTT_RASTERIZER_VERSION==1
2817    int x,dx;
2818    float ey;
2819    int direction;
2820    #elif STBTT_RASTERIZER_VERSION==2
2821    float fx,fdx,fdy;
2822    float direction;
2823    float sy;
2824    float ey;
2825    #else
2826    #error "Unrecognized value of STBTT_RASTERIZER_VERSION"
2827    #endif
2828 } stbtt__active_edge;
2829 
2830 #if STBTT_RASTERIZER_VERSION == 1
2831 #define STBTT_FIXSHIFT   10
2832 #define STBTT_FIX        (1 << STBTT_FIXSHIFT)
2833 #define STBTT_FIXMASK    (STBTT_FIX-1)
2834 
2835 static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, int off_x, float start_point, void *userdata)
2836 {
2837    stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh, sizeof(*z), userdata);
2838    float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
2839    STBTT_assert(z != NULL);
2840    if (!z) return z;
2841 
2842    // round dx down to avoid overshooting
2843    if (dxdy < 0)
2844       z->dx = -STBTT_ifloor(STBTT_FIX * -dxdy);
2845    else
2846       z->dx = STBTT_ifloor(STBTT_FIX * dxdy);
2847 
2848    z->x = STBTT_ifloor(STBTT_FIX * e->x0 + z->dx * (start_point - e->y0)); // use z->dx so when we offset later it's by the same amount
2849    z->x -= off_x * STBTT_FIX;
2850 
2851    z->ey = e->y1;
2852    z->next = 0;
2853    z->direction = e->invert ? 1 : -1;
2854    return z;
2855 }
2856 #elif STBTT_RASTERIZER_VERSION == 2
2857 static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, int off_x, float start_point, void *userdata)
2858 {
2859    stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh, sizeof(*z), userdata);
2860    float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
2861    STBTT_assert(z != NULL);
2862    //STBTT_assert(e->y0 <= start_point);
2863    if (!z) return z;
2864    z->fdx = dxdy;
2865    z->fdy = dxdy != 0.0f ? (1.0f/dxdy) : 0.0f;
2866    z->fx = e->x0 + dxdy * (start_point - e->y0);
2867    z->fx -= off_x;
2868    z->direction = e->invert ? 1.0f : -1.0f;
2869    z->sy = e->y0;
2870    z->ey = e->y1;
2871    z->next = 0;
2872    return z;
2873 }
2874 #else
2875 #error "Unrecognized value of STBTT_RASTERIZER_VERSION"
2876 #endif
2877 
2878 #if STBTT_RASTERIZER_VERSION == 1
2879 // note: this routine clips fills that extend off the edges... ideally this
2880 // wouldn't happen, but it could happen if the truetype glyph bounding boxes
2881 // are wrong, or if the user supplies a too-small bitmap
2882 static void stbtt__fill_active_edges(unsigned char *scanline, int len, stbtt__active_edge *e, int max_weight)
2883 {
2884    // non-zero winding fill
2885    int x0=0, w=0;
2886 
2887    while (e) {
2888       if (w == 0) {
2889          // if we're currently at zero, we need to record the edge start point
2890          x0 = e->x; w += e->direction;
2891       } else {
2892          int x1 = e->x; w += e->direction;
2893          // if we went to zero, we need to draw
2894          if (w == 0) {
2895             int i = x0 >> STBTT_FIXSHIFT;
2896             int j = x1 >> STBTT_FIXSHIFT;
2897 
2898             if (i < len && j >= 0) {
2899                if (i == j) {
2900                   // x0,x1 are the same pixel, so compute combined coverage
2901                   scanline[i] = scanline[i] + (stbtt_uint8) ((x1 - x0) * max_weight >> STBTT_FIXSHIFT);
2902                } else {
2903                   if (i >= 0) // add antialiasing for x0
2904                      scanline[i] = scanline[i] + (stbtt_uint8) (((STBTT_FIX - (x0 & STBTT_FIXMASK)) * max_weight) >> STBTT_FIXSHIFT);
2905                   else
2906                      i = -1; // clip
2907 
2908                   if (j < len) // add antialiasing for x1
2909                      scanline[j] = scanline[j] + (stbtt_uint8) (((x1 & STBTT_FIXMASK) * max_weight) >> STBTT_FIXSHIFT);
2910                   else
2911                      j = len; // clip
2912 
2913                   for (++i; i < j; ++i) // fill pixels between x0 and x1
2914                      scanline[i] = scanline[i] + (stbtt_uint8) max_weight;
2915                }
2916             }
2917          }
2918       }
2919 
2920       e = e->next;
2921    }
2922 }
2923 
2924 static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata)
2925 {
2926    stbtt__hheap hh = { 0, 0, 0 };
2927    stbtt__active_edge *active = NULL;
2928    int y,j=0;
2929    int max_weight = (255 / vsubsample);  // weight per vertical scanline
2930    int s; // vertical subsample index
2931    unsigned char scanline_data[512], *scanline;
2932 
2933    if (result->w > 512)
2934       scanline = (unsigned char *) STBTT_malloc(result->w, userdata);
2935    else
2936       scanline = scanline_data;
2937 
2938    y = off_y * vsubsample;
2939    e[n].y0 = (off_y + result->h) * (float) vsubsample + 1;
2940 
2941    while (j < result->h) {
2942       STBTT_memset(scanline, 0, result->w);
2943       for (s=0; s < vsubsample; ++s) {
2944          // find center of pixel for this scanline
2945          float scan_y = y + 0.5f;
2946          stbtt__active_edge **step = &active;
2947 
2948          // update all active edges;
2949          // remove all active edges that terminate before the center of this scanline
2950          while (*step) {
2951             stbtt__active_edge * z = *step;
2952             if (z->ey <= scan_y) {
2953                *step = z->next; // delete from list
2954                STBTT_assert(z->direction);
2955                z->direction = 0;
2956                stbtt__hheap_free(&hh, z);
2957             } else {
2958                z->x += z->dx; // advance to position for current scanline
2959                step = &((*step)->next); // advance through list
2960             }
2961          }
2962 
2963          // resort the list if needed
2964          for(;;) {
2965             int changed=0;
2966             step = &active;
2967             while (*step && (*step)->next) {
2968                if ((*step)->x > (*step)->next->x) {
2969                   stbtt__active_edge *t = *step;
2970                   stbtt__active_edge *q = t->next;
2971 
2972                   t->next = q->next;
2973                   q->next = t;
2974                   *step = q;
2975                   changed = 1;
2976                }
2977                step = &(*step)->next;
2978             }
2979             if (!changed) break;
2980          }
2981 
2982          // insert all edges that start before the center of this scanline -- omit ones that also end on this scanline
2983          while (e->y0 <= scan_y) {
2984             if (e->y1 > scan_y) {
2985                stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y, userdata);
2986                if (z != NULL) {
2987                   // find insertion point
2988                   if (active == NULL)
2989                      active = z;
2990                   else if (z->x < active->x) {
2991                      // insert at front
2992                      z->next = active;
2993                      active = z;
2994                   } else {
2995                      // find thing to insert AFTER
2996                      stbtt__active_edge *p = active;
2997                      while (p->next && p->next->x < z->x)
2998                         p = p->next;
2999                      // at this point, p->next->x is NOT < z->x
3000                      z->next = p->next;
3001                      p->next = z;
3002                   }
3003                }
3004             }
3005             ++e;
3006          }
3007 
3008          // now process all active edges in XOR fashion
3009          if (active)
3010             stbtt__fill_active_edges(scanline, result->w, active, max_weight);
3011 
3012          ++y;
3013       }
3014       STBTT_memcpy(result->pixels + j * result->stride, scanline, result->w);
3015       ++j;
3016    }
3017 
3018    stbtt__hheap_cleanup(&hh, userdata);
3019 
3020    if (scanline != scanline_data)
3021       STBTT_free(scanline, userdata);
3022 }
3023 
3024 #elif STBTT_RASTERIZER_VERSION == 2
3025 
3026 // the edge passed in here does not cross the vertical line at x or the vertical line at x+1
3027 // (i.e. it has already been clipped to those)
3028 static void stbtt__handle_clipped_edge(float *scanline, int x, stbtt__active_edge *e, float x0, float y0, float x1, float y1)
3029 {
3030    if (y0 == y1) return;
3031    STBTT_assert(y0 < y1);
3032    STBTT_assert(e->sy <= e->ey);
3033    if (y0 > e->ey) return;
3034    if (y1 < e->sy) return;
3035    if (y0 < e->sy) {
3036       x0 += (x1-x0) * (e->sy - y0) / (y1-y0);
3037       y0 = e->sy;
3038    }
3039    if (y1 > e->ey) {
3040       x1 += (x1-x0) * (e->ey - y1) / (y1-y0);
3041       y1 = e->ey;
3042    }
3043 
3044    if (x0 == x)
3045       STBTT_assert(x1 <= x+1);
3046    else if (x0 == x+1)
3047       STBTT_assert(x1 >= x);
3048    else if (x0 <= x)
3049       STBTT_assert(x1 <= x);
3050    else if (x0 >= x+1)
3051       STBTT_assert(x1 >= x+1);
3052    else
3053       STBTT_assert(x1 >= x && x1 <= x+1);
3054 
3055    if (x0 <= x && x1 <= x)
3056       scanline[x] += e->direction * (y1-y0);
3057    else if (x0 >= x+1 && x1 >= x+1)
3058       ;
3059    else {
3060       STBTT_assert(x0 >= x && x0 <= x+1 && x1 >= x && x1 <= x+1);
3061       scanline[x] += e->direction * (y1-y0) * (1-((x0-x)+(x1-x))/2); // coverage = 1 - average x position
3062    }
3063 }
3064 
3065 static float stbtt__sized_trapezoid_area(float height, float top_width, float bottom_width)
3066 {
3067    STBTT_assert(top_width >= 0);
3068    STBTT_assert(bottom_width >= 0);
3069    return (top_width + bottom_width) / 2.0f * height;
3070 }
3071 
3072 static float stbtt__position_trapezoid_area(float height, float tx0, float tx1, float bx0, float bx1)
3073 {
3074    return stbtt__sized_trapezoid_area(height, tx1 - tx0, bx1 - bx0);
3075 }
3076 
3077 static float stbtt__sized_triangle_area(float height, float width)
3078 {
3079    return height * width / 2;
3080 }
3081 
3082 static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill, int len, stbtt__active_edge *e, float y_top)
3083 {
3084    float y_bottom = y_top+1;
3085 
3086    while (e) {
3087       // brute force every pixel
3088 
3089       // compute intersection points with top & bottom
3090       STBTT_assert(e->ey >= y_top);
3091 
3092       if (e->fdx == 0) {
3093          float x0 = e->fx;
3094          if (x0 < len) {
3095             if (x0 >= 0) {
3096                stbtt__handle_clipped_edge(scanline,(int) x0,e, x0,y_top, x0,y_bottom);
3097                stbtt__handle_clipped_edge(scanline_fill-1,(int) x0+1,e, x0,y_top, x0,y_bottom);
3098             } else {
3099                stbtt__handle_clipped_edge(scanline_fill-1,0,e, x0,y_top, x0,y_bottom);
3100             }
3101          }
3102       } else {
3103          float x0 = e->fx;
3104          float dx = e->fdx;
3105          float xb = x0 + dx;
3106          float x_top, x_bottom;
3107          float sy0,sy1;
3108          float dy = e->fdy;
3109          STBTT_assert(e->sy <= y_bottom && e->ey >= y_top);
3110 
3111          // compute endpoints of line segment clipped to this scanline (if the
3112          // line segment starts on this scanline. x0 is the intersection of the
3113          // line with y_top, but that may be off the line segment.
3114          if (e->sy > y_top) {
3115             x_top = x0 + dx * (e->sy - y_top);
3116             sy0 = e->sy;
3117          } else {
3118             x_top = x0;
3119             sy0 = y_top;
3120          }
3121          if (e->ey < y_bottom) {
3122             x_bottom = x0 + dx * (e->ey - y_top);
3123             sy1 = e->ey;
3124          } else {
3125             x_bottom = xb;
3126             sy1 = y_bottom;
3127          }
3128 
3129          if (x_top >= 0 && x_bottom >= 0 && x_top < len && x_bottom < len) {
3130             // from here on, we don't have to range check x values
3131 
3132             if ((int) x_top == (int) x_bottom) {
3133                float height;
3134                // simple case, only spans one pixel
3135                int x = (int) x_top;
3136                height = (sy1 - sy0) * e->direction;
3137                STBTT_assert(x >= 0 && x < len);
3138                scanline[x]      += stbtt__position_trapezoid_area(height, x_top, x+1.0f, x_bottom, x+1.0f);
3139                scanline_fill[x] += height; // everything right of this pixel is filled
3140             } else {
3141                int x,x1,x2;
3142                float y_crossing, y_final, step, sign, area;
3143                // covers 2+ pixels
3144                if (x_top > x_bottom) {
3145                   // flip scanline vertically; signed area is the same
3146                   float t;
3147                   sy0 = y_bottom - (sy0 - y_top);
3148                   sy1 = y_bottom - (sy1 - y_top);
3149                   t = sy0, sy0 = sy1, sy1 = t;
3150                   t = x_bottom, x_bottom = x_top, x_top = t;
3151                   dx = -dx;
3152                   dy = -dy;
3153                   t = x0, x0 = xb, xb = t;
3154                }
3155                STBTT_assert(dy >= 0);
3156                STBTT_assert(dx >= 0);
3157 
3158                x1 = (int) x_top;
3159                x2 = (int) x_bottom;
3160                // compute intersection with y axis at x1+1
3161                y_crossing = y_top + dy * (x1+1 - x0);
3162 
3163                // compute intersection with y axis at x2
3164                y_final = y_top + dy * (x2 - x0);
3165 
3166                //           x1    x_top                            x2    x_bottom
3167                //     y_top  +------|-----+------------+------------+--------|---+------------+
3168                //            |            |            |            |            |            |
3169                //            |            |            |            |            |            |
3170                //       sy0  |      Txxxxx|............|............|............|............|
3171                // y_crossing |            *xxxxx.......|............|............|............|
3172                //            |            |     xxxxx..|............|............|............|
3173                //            |            |     /-   xx*xxxx........|............|............|
3174                //            |            | dy <       |    xxxxxx..|............|............|
3175                //   y_final  |            |     \-     |          xx*xxx.........|............|
3176                //       sy1  |            |            |            |   xxxxxB...|............|
3177                //            |            |            |            |            |            |
3178                //            |            |            |            |            |            |
3179                //  y_bottom  +------------+------------+------------+------------+------------+
3180                //
3181                // goal is to measure the area covered by '.' in each pixel
3182 
3183                // if x2 is right at the right edge of x1, y_crossing can blow up, github #1057
3184                // @TODO: maybe test against sy1 rather than y_bottom?
3185                if (y_crossing > y_bottom)
3186                   y_crossing = y_bottom;
3187 
3188                sign = e->direction;
3189 
3190                // area of the rectangle covered from sy0..y_crossing
3191                area = sign * (y_crossing-sy0);
3192 
3193                // area of the triangle (x_top,sy0), (x1+1,sy0), (x1+1,y_crossing)
3194                scanline[x1] += stbtt__sized_triangle_area(area, x1+1 - x_top);
3195 
3196                // check if final y_crossing is blown up; no test case for this
3197                if (y_final > y_bottom) {
3198                   y_final = y_bottom;
3199                   dy = (y_final - y_crossing ) / (x2 - (x1+1)); // if denom=0, y_final = y_crossing, so y_final <= y_bottom
3200                }
3201 
3202                // in second pixel, area covered by line segment found in first pixel
3203                // is always a rectangle 1 wide * the height of that line segment; this
3204                // is exactly what the variable 'area' stores. it also gets a contribution
3205                // from the line segment within it. the THIRD pixel will get the first
3206                // pixel's rectangle contribution, the second pixel's rectangle contribution,
3207                // and its own contribution. the 'own contribution' is the same in every pixel except
3208                // the leftmost and rightmost, a trapezoid that slides down in each pixel.
3209                // the second pixel's contribution to the third pixel will be the
3210                // rectangle 1 wide times the height change in the second pixel, which is dy.
3211 
3212                step = sign * dy * 1; // dy is dy/dx, change in y for every 1 change in x,
3213                // which multiplied by 1-pixel-width is how much pixel area changes for each step in x
3214                // so the area advances by 'step' every time
3215 
3216                for (x = x1+1; x < x2; ++x) {
3217                   scanline[x] += area + step/2; // area of trapezoid is 1*step/2
3218                   area += step;
3219                }
3220                STBTT_assert(STBTT_fabs(area) <= 1.01f); // accumulated error from area += step unless we round step down
3221                STBTT_assert(sy1 > y_final-0.01f);
3222 
3223                // area covered in the last pixel is the rectangle from all the pixels to the left,
3224                // plus the trapezoid filled by the line segment in this pixel all the way to the right edge
3225                scanline[x2] += area + sign * stbtt__position_trapezoid_area(sy1-y_final, (float) x2, x2+1.0f, x_bottom, x2+1.0f);
3226 
3227                // the rest of the line is filled based on the total height of the line segment in this pixel
3228                scanline_fill[x2] += sign * (sy1-sy0);
3229             }
3230          } else {
3231             // if edge goes outside of box we're drawing, we require
3232             // clipping logic. since this does not match the intended use
3233             // of this library, we use a different, very slow brute
3234             // force implementation
3235             // note though that this does happen some of the time because
3236             // x_top and x_bottom can be extrapolated at the top & bottom of
3237             // the shape and actually lie outside the bounding box
3238             int x;
3239             for (x=0; x < len; ++x) {
3240                // cases:
3241                //
3242                // there can be up to two intersections with the pixel. any intersection
3243                // with left or right edges can be handled by splitting into two (or three)
3244                // regions. intersections with top & bottom do not necessitate case-wise logic.
3245                //
3246                // the old way of doing this found the intersections with the left & right edges,
3247                // then used some simple logic to produce up to three segments in sorted order
3248                // from top-to-bottom. however, this had a problem: if an x edge was epsilon
3249                // across the x border, then the corresponding y position might not be distinct
3250                // from the other y segment, and it might ignored as an empty segment. to avoid
3251                // that, we need to explicitly produce segments based on x positions.
3252 
3253                // rename variables to clearly-defined pairs
3254                float y0 = y_top;
3255                float x1 = (float) (x);
3256                float x2 = (float) (x+1);
3257                float x3 = xb;
3258                float y3 = y_bottom;
3259 
3260                // x = e->x + e->dx * (y-y_top)
3261                // (y-y_top) = (x - e->x) / e->dx
3262                // y = (x - e->x) / e->dx + y_top
3263                float y1 = (x - x0) / dx + y_top;
3264                float y2 = (x+1 - x0) / dx + y_top;
3265 
3266                if (x0 < x1 && x3 > x2) {         // three segments descending down-right
3267                   stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1);
3268                   stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x2,y2);
3269                   stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3);
3270                } else if (x3 < x1 && x0 > x2) {  // three segments descending down-left
3271                   stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2);
3272                   stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x1,y1);
3273                   stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3);
3274                } else if (x0 < x1 && x3 > x1) {  // two segments across x, down-right
3275                   stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1);
3276                   stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3);
3277                } else if (x3 < x1 && x0 > x1) {  // two segments across x, down-left
3278                   stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1);
3279                   stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3);
3280                } else if (x0 < x2 && x3 > x2) {  // two segments across x+1, down-right
3281                   stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2);
3282                   stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3);
3283                } else if (x3 < x2 && x0 > x2) {  // two segments across x+1, down-left
3284                   stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2);
3285                   stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3);
3286                } else {  // one segment
3287                   stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x3,y3);
3288                }
3289             }
3290          }
3291       }
3292       e = e->next;
3293    }
3294 }
3295 
3296 // directly AA rasterize edges w/o supersampling
3297 static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata)
3298 {
3299    stbtt__hheap hh = { 0, 0, 0 };
3300    stbtt__active_edge *active = NULL;
3301    int y,j=0, i;
3302    float scanline_data[129], *scanline, *scanline2;
3303 
3304    STBTT__NOTUSED(vsubsample);
3305 
3306    if (result->w > 64)
3307       scanline = (float *) STBTT_malloc((result->w*2+1) * sizeof(float), userdata);
3308    else
3309       scanline = scanline_data;
3310 
3311    scanline2 = scanline + result->w;
3312 
3313    y = off_y;
3314    e[n].y0 = (float) (off_y + result->h) + 1;
3315 
3316    while (j < result->h) {
3317       // find center of pixel for this scanline
3318       float scan_y_top    = y + 0.0f;
3319       float scan_y_bottom = y + 1.0f;
3320       stbtt__active_edge **step = &active;
3321 
3322       STBTT_memset(scanline , 0, result->w*sizeof(scanline[0]));
3323       STBTT_memset(scanline2, 0, (result->w+1)*sizeof(scanline[0]));
3324 
3325       // update all active edges;
3326       // remove all active edges that terminate before the top of this scanline
3327       while (*step) {
3328          stbtt__active_edge * z = *step;
3329          if (z->ey <= scan_y_top) {
3330             *step = z->next; // delete from list
3331             STBTT_assert(z->direction);
3332             z->direction = 0;
3333             stbtt__hheap_free(&hh, z);
3334          } else {
3335             step = &((*step)->next); // advance through list
3336          }
3337       }
3338 
3339       // insert all edges that start before the bottom of this scanline
3340       while (e->y0 <= scan_y_bottom) {
3341          if (e->y0 != e->y1) {
3342             stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata);
3343             if (z != NULL) {
3344                if (j == 0 && off_y != 0) {
3345                   if (z->ey < scan_y_top) {
3346                      // this can happen due to subpixel positioning and some kind of fp rounding error i think
3347                      z->ey = scan_y_top;
3348                   }
3349                }
3350                STBTT_assert(z->ey >= scan_y_top); // if we get really unlucky a tiny bit of an edge can be out of bounds
3351                // insert at front
3352                z->next = active;
3353                active = z;
3354             }
3355          }
3356          ++e;
3357       }
3358 
3359       // now process all active edges
3360       if (active)
3361          stbtt__fill_active_edges_new(scanline, scanline2+1, result->w, active, scan_y_top);
3362 
3363       {
3364          float sum = 0;
3365          for (i=0; i < result->w; ++i) {
3366             float k;
3367             int m;
3368             sum += scanline2[i];
3369             k = scanline[i] + sum;
3370             k = (float) STBTT_fabs(k)*255 + 0.5f;
3371             m = (int) k;
3372             if (m > 255) m = 255;
3373             result->pixels[j*result->stride + i] = (unsigned char) m;
3374          }
3375       }
3376       // advance all the edges
3377       step = &active;
3378       while (*step) {
3379          stbtt__active_edge *z = *step;
3380          z->fx += z->fdx; // advance to position for current scanline
3381          step = &((*step)->next); // advance through list
3382       }
3383 
3384       ++y;
3385       ++j;
3386    }
3387 
3388    stbtt__hheap_cleanup(&hh, userdata);
3389 
3390    if (scanline != scanline_data)
3391       STBTT_free(scanline, userdata);
3392 }
3393 #else
3394 #error "Unrecognized value of STBTT_RASTERIZER_VERSION"
3395 #endif
3396 
3397 #define STBTT__COMPARE(a,b)  ((a)->y0 < (b)->y0)
3398 
3399 static void stbtt__sort_edges_ins_sort(stbtt__edge *p, int n)
3400 {
3401    int i,j;
3402    for (i=1; i < n; ++i) {
3403       stbtt__edge t = p[i], *a = &t;
3404       j = i;
3405       while (j > 0) {
3406          stbtt__edge *b = &p[j-1];
3407          int c = STBTT__COMPARE(a,b);
3408          if (!c) break;
3409          p[j] = p[j-1];
3410          --j;
3411       }
3412       if (i != j)
3413          p[j] = t;
3414    }
3415 }
3416 
3417 static void stbtt__sort_edges_quicksort(stbtt__edge *p, int n)
3418 {
3419    /* threshold for transitioning to insertion sort */
3420    while (n > 12) {
3421       stbtt__edge t;
3422       int c01,c12,c,m,i,j;
3423 
3424       /* compute median of three */
3425       m = n >> 1;
3426       c01 = STBTT__COMPARE(&p[0],&p[m]);
3427       c12 = STBTT__COMPARE(&p[m],&p[n-1]);
3428       /* if 0 >= mid >= end, or 0 < mid < end, then use mid */
3429       if (c01 != c12) {
3430          /* otherwise, we'll need to swap something else to middle */
3431          int z;
3432          c = STBTT__COMPARE(&p[0],&p[n-1]);
3433          /* 0>mid && mid<n:  0>n => n; 0<n => 0 */
3434          /* 0<mid && mid>n:  0>n => 0; 0<n => n */
3435          z = (c == c12) ? 0 : n-1;
3436          t = p[z];
3437          p[z] = p[m];
3438          p[m] = t;
3439       }
3440       /* now p[m] is the median-of-three */
3441       /* swap it to the beginning so it won't move around */
3442       t = p[0];
3443       p[0] = p[m];
3444       p[m] = t;
3445 
3446       /* partition loop */
3447       i=1;
3448       j=n-1;
3449       for(;;) {
3450          /* handling of equality is crucial here */
3451          /* for sentinels & efficiency with duplicates */
3452          for (;;++i) {
3453             if (!STBTT__COMPARE(&p[i], &p[0])) break;
3454          }
3455          for (;;--j) {
3456             if (!STBTT__COMPARE(&p[0], &p[j])) break;
3457          }
3458          /* make sure we haven't crossed */
3459          if (i >= j) break;
3460          t = p[i];
3461          p[i] = p[j];
3462          p[j] = t;
3463 
3464          ++i;
3465          --j;
3466       }
3467       /* recurse on smaller side, iterate on larger */
3468       if (j < (n-i)) {
3469          stbtt__sort_edges_quicksort(p,j);
3470          p = p+i;
3471          n = n-i;
3472       } else {
3473          stbtt__sort_edges_quicksort(p+i, n-i);
3474          n = j;
3475       }
3476    }
3477 }
3478 
3479 static void stbtt__sort_edges(stbtt__edge *p, int n)
3480 {
3481    stbtt__sort_edges_quicksort(p, n);
3482    stbtt__sort_edges_ins_sort(p, n);
3483 }
3484 
3485 typedef struct
3486 {
3487    float x,y;
3488 } stbtt__point;
3489 
3490 static void stbtt__rasterize(stbtt__bitmap *result, stbtt__point *pts, int *wcount, int windings, float scale_x, float scale_y, float shift_x, float shift_y, int off_x, int off_y, int invert, void *userdata)
3491 {
3492    float y_scale_inv = invert ? -scale_y : scale_y;
3493    stbtt__edge *e;
3494    int n,i,j,k,m;
3495 #if STBTT_RASTERIZER_VERSION == 1
3496    int vsubsample = result->h < 8 ? 15 : 5;
3497 #elif STBTT_RASTERIZER_VERSION == 2
3498    int vsubsample = 1;
3499 #else
3500    #error "Unrecognized value of STBTT_RASTERIZER_VERSION"
3501 #endif
3502    // vsubsample should divide 255 evenly; otherwise we won't reach full opacity
3503 
3504    // now we have to blow out the windings into explicit edge lists
3505    n = 0;
3506    for (i=0; i < windings; ++i)
3507       n += wcount[i];
3508 
3509    e = (stbtt__edge *) STBTT_malloc(sizeof(*e) * (n+1), userdata); // add an extra one as a sentinel
3510    if (e == 0) return;
3511    n = 0;
3512 
3513    m=0;
3514    for (i=0; i < windings; ++i) {
3515       stbtt__point *p = pts + m;
3516       m += wcount[i];
3517       j = wcount[i]-1;
3518       for (k=0; k < wcount[i]; j=k++) {
3519          int a=k,b=j;
3520          // skip the edge if horizontal
3521          if (p[j].y == p[k].y)
3522             continue;
3523          // add edge from j to k to the list
3524          e[n].invert = 0;
3525          if (invert ? p[j].y > p[k].y : p[j].y < p[k].y) {
3526             e[n].invert = 1;
3527             a=j,b=k;
3528          }
3529          e[n].x0 = p[a].x * scale_x + shift_x;
3530          e[n].y0 = (p[a].y * y_scale_inv + shift_y) * vsubsample;
3531          e[n].x1 = p[b].x * scale_x + shift_x;
3532          e[n].y1 = (p[b].y * y_scale_inv + shift_y) * vsubsample;
3533          ++n;
3534       }
3535    }
3536 
3537    // now sort the edges by their highest point (should snap to integer, and then by x)
3538    //STBTT_sort(e, n, sizeof(e[0]), stbtt__edge_compare);
3539    stbtt__sort_edges(e, n);
3540 
3541    // now, traverse the scanlines and find the intersections on each scanline, use xor winding rule
3542    stbtt__rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y, userdata);
3543 
3544    STBTT_free(e, userdata);
3545 }
3546 
3547 static void stbtt__add_point(stbtt__point *points, int n, float x, float y)
3548 {
3549    if (!points) return; // during first pass, it's unallocated
3550    points[n].x = x;
3551    points[n].y = y;
3552 }
3553 
3554 // tessellate until threshold p is happy... @TODO warped to compensate for non-linear stretching
3555 static int stbtt__tesselate_curve(stbtt__point *points, int *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float objspace_flatness_squared, int n)
3556 {
3557    // midpoint
3558    float mx = (x0 + 2*x1 + x2)/4;
3559    float my = (y0 + 2*y1 + y2)/4;
3560    // versus directly drawn line
3561    float dx = (x0+x2)/2 - mx;
3562    float dy = (y0+y2)/2 - my;
3563    if (n > 16) // 65536 segments on one curve better be enough!
3564       return 1;
3565    if (dx*dx+dy*dy > objspace_flatness_squared) { // half-pixel error allowed... need to be smaller if AA
3566       stbtt__tesselate_curve(points, num_points, x0,y0, (x0+x1)/2.0f,(y0+y1)/2.0f, mx,my, objspace_flatness_squared,n+1);
3567       stbtt__tesselate_curve(points, num_points, mx,my, (x1+x2)/2.0f,(y1+y2)/2.0f, x2,y2, objspace_flatness_squared,n+1);
3568    } else {
3569       stbtt__add_point(points, *num_points,x2,y2);
3570       *num_points = *num_points+1;
3571    }
3572    return 1;
3573 }
3574 
3575 static void stbtt__tesselate_cubic(stbtt__point *points, int *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3, float objspace_flatness_squared, int n)
3576 {
3577    // @TODO this "flatness" calculation is just made-up nonsense that seems to work well enough
3578    float dx0 = x1-x0;
3579    float dy0 = y1-y0;
3580    float dx1 = x2-x1;
3581    float dy1 = y2-y1;
3582    float dx2 = x3-x2;
3583    float dy2 = y3-y2;
3584    float dx = x3-x0;
3585    float dy = y3-y0;
3586    float longlen = (float) (STBTT_sqrt(dx0*dx0+dy0*dy0)+STBTT_sqrt(dx1*dx1+dy1*dy1)+STBTT_sqrt(dx2*dx2+dy2*dy2));
3587    float shortlen = (float) STBTT_sqrt(dx*dx+dy*dy);
3588    float flatness_squared = longlen*longlen-shortlen*shortlen;
3589 
3590    if (n > 16) // 65536 segments on one curve better be enough!
3591       return;
3592 
3593    if (flatness_squared > objspace_flatness_squared) {
3594       float x01 = (x0+x1)/2;
3595       float y01 = (y0+y1)/2;
3596       float x12 = (x1+x2)/2;
3597       float y12 = (y1+y2)/2;
3598       float x23 = (x2+x3)/2;
3599       float y23 = (y2+y3)/2;
3600 
3601       float xa = (x01+x12)/2;
3602       float ya = (y01+y12)/2;
3603       float xb = (x12+x23)/2;
3604       float yb = (y12+y23)/2;
3605 
3606       float mx = (xa+xb)/2;
3607       float my = (ya+yb)/2;
3608 
3609       stbtt__tesselate_cubic(points, num_points, x0,y0, x01,y01, xa,ya, mx,my, objspace_flatness_squared,n+1);
3610       stbtt__tesselate_cubic(points, num_points, mx,my, xb,yb, x23,y23, x3,y3, objspace_flatness_squared,n+1);
3611    } else {
3612       stbtt__add_point(points, *num_points,x3,y3);
3613       *num_points = *num_points+1;
3614    }
3615 }
3616 
3617 // returns number of contours
3618 static stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts, float objspace_flatness, int **contour_lengths, int *num_contours, void *userdata)
3619 {
3620    stbtt__point *points=0;
3621    int num_points=0;
3622 
3623    float objspace_flatness_squared = objspace_flatness * objspace_flatness;
3624    int i,n=0,start=0, pass;
3625 
3626    // count how many "moves" there are to get the contour count
3627    for (i=0; i < num_verts; ++i)
3628       if (vertices[i].type == STBTT_vmove)
3629          ++n;
3630 
3631    *num_contours = n;
3632    if (n == 0) return 0;
3633 
3634    *contour_lengths = (int *) STBTT_malloc(sizeof(**contour_lengths) * n, userdata);
3635 
3636    if (*contour_lengths == 0) {
3637       *num_contours = 0;
3638       return 0;
3639    }
3640 
3641    // make two passes through the points so we don't need to realloc
3642    for (pass=0; pass < 2; ++pass) {
3643       float x=0,y=0;
3644       if (pass == 1) {
3645          points = (stbtt__point *) STBTT_malloc(num_points * sizeof(points[0]), userdata);
3646          if (points == NULL) goto error;
3647       }
3648       num_points = 0;
3649       n= -1;
3650       for (i=0; i < num_verts; ++i) {
3651          switch (vertices[i].type) {
3652             case STBTT_vmove:
3653                // start the next contour
3654                if (n >= 0)
3655                   (*contour_lengths)[n] = num_points - start;
3656                ++n;
3657                start = num_points;
3658 
3659                x = vertices[i].x, y = vertices[i].y;
3660                stbtt__add_point(points, num_points++, x,y);
3661                break;
3662             case STBTT_vline:
3663                x = vertices[i].x, y = vertices[i].y;
3664                stbtt__add_point(points, num_points++, x, y);
3665                break;
3666             case STBTT_vcurve:
3667                stbtt__tesselate_curve(points, &num_points, x,y,
3668                                         vertices[i].cx, vertices[i].cy,
3669                                         vertices[i].x,  vertices[i].y,
3670                                         objspace_flatness_squared, 0);
3671                x = vertices[i].x, y = vertices[i].y;
3672                break;
3673             case STBTT_vcubic:
3674                stbtt__tesselate_cubic(points, &num_points, x,y,
3675                                         vertices[i].cx, vertices[i].cy,
3676                                         vertices[i].cx1, vertices[i].cy1,
3677                                         vertices[i].x,  vertices[i].y,
3678                                         objspace_flatness_squared, 0);
3679                x = vertices[i].x, y = vertices[i].y;
3680                break;
3681          }
3682       }
3683       (*contour_lengths)[n] = num_points - start;
3684    }
3685 
3686    return points;
3687 error:
3688    STBTT_free(points, userdata);
3689    STBTT_free(*contour_lengths, userdata);
3690    *contour_lengths = 0;
3691    *num_contours = 0;
3692    return NULL;
3693 }
3694 
3695 STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, float shift_x, float shift_y, int x_off, int y_off, int invert, void *userdata)
3696 {
3697    float scale            = scale_x > scale_y ? scale_y : scale_x;
3698    int winding_count      = 0;
3699    int *winding_lengths   = NULL;
3700    stbtt__point *windings = stbtt_FlattenCurves(vertices, num_verts, flatness_in_pixels / scale, &winding_lengths, &winding_count, userdata);
3701    if (windings) {
3702       stbtt__rasterize(result, windings, winding_lengths, winding_count, scale_x, scale_y, shift_x, shift_y, x_off, y_off, invert, userdata);
3703       STBTT_free(winding_lengths, userdata);
3704       STBTT_free(windings, userdata);
3705    }
3706 }
3707 
3708 STBTT_DEF void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata)
3709 {
3710    STBTT_free(bitmap, userdata);
3711 }
3712 
3713 STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff)
3714 {
3715    int ix0,iy0,ix1,iy1;
3716    stbtt__bitmap gbm;
3717    stbtt_vertex *vertices;
3718    int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices);
3719 
3720    if (scale_x == 0) scale_x = scale_y;
3721    if (scale_y == 0) {
3722       if (scale_x == 0) {
3723          STBTT_free(vertices, info->userdata);
3724          return NULL;
3725       }
3726       scale_y = scale_x;
3727    }
3728 
3729    stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,&ix1,&iy1);
3730 
3731    // now we get the size
3732    gbm.w = (ix1 - ix0);
3733    gbm.h = (iy1 - iy0);
3734    gbm.pixels = NULL; // in case we error
3735 
3736    if (width ) *width  = gbm.w;
3737    if (height) *height = gbm.h;
3738    if (xoff  ) *xoff   = ix0;
3739    if (yoff  ) *yoff   = iy0;
3740 
3741    if (gbm.w && gbm.h) {
3742       gbm.pixels = (unsigned char *) STBTT_malloc(gbm.w * gbm.h, info->userdata);
3743       if (gbm.pixels) {
3744          gbm.stride = gbm.w;
3745 
3746          stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0, iy0, 1, info->userdata);
3747       }
3748    }
3749    STBTT_free(vertices, info->userdata);
3750    return gbm.pixels;
3751 }
3752 
3753 STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff)
3754 {
3755    return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y, 0.0f, 0.0f, glyph, width, height, xoff, yoff);
3756 }
3757 
3758 STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph)
3759 {
3760    int ix0,iy0;
3761    stbtt_vertex *vertices;
3762    int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices);
3763    stbtt__bitmap gbm;
3764 
3765    stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,0,0);
3766    gbm.pixels = output;
3767    gbm.w = out_w;
3768    gbm.h = out_h;
3769    gbm.stride = out_stride;
3770 
3771    if (gbm.w && gbm.h)
3772       stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0,iy0, 1, info->userdata);
3773 
3774    STBTT_free(vertices, info->userdata);
3775 }
3776 
3777 STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph)
3778 {
3779    stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f,0.0f, glyph);
3780 }
3781 
3782 STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int *width, int *height, int *xoff, int *yoff)
3783 {
3784    return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y,shift_x,shift_y, stbtt_FindGlyphIndex(info,codepoint), width,height,xoff,yoff);
3785 }
3786 
3787 STBTT_DEF void stbtt_MakeCodepointBitmapSubpixelPrefilter(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int oversample_x, int oversample_y, float *sub_x, float *sub_y, int codepoint)
3788 {
3789    stbtt_MakeGlyphBitmapSubpixelPrefilter(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y, oversample_x, oversample_y, sub_x, sub_y, stbtt_FindGlyphIndex(info,codepoint));
3790 }
3791 
3792 STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint)
3793 {
3794    stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y, stbtt_FindGlyphIndex(info,codepoint));
3795 }
3796 
3797 STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff)
3798 {
3799    return stbtt_GetCodepointBitmapSubpixel(info, scale_x, scale_y, 0.0f,0.0f, codepoint, width,height,xoff,yoff);
3800 }
3801 
3802 STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint)
3803 {
3804    stbtt_MakeCodepointBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f,0.0f, codepoint);
3805 }
3806 
3807 //////////////////////////////////////////////////////////////////////////////
3808 //
3809 // bitmap baking
3810 //
3811 // This is SUPER-CRAPPY packing to keep source code small
3812 
3813 static int stbtt_BakeFontBitmap_internal(unsigned char *data, int offset,  // font location (use offset=0 for plain .ttf)
3814                                 float pixel_height,                     // height of font in pixels
3815                                 unsigned char *pixels, int pw, int ph,  // bitmap to be filled in
3816                                 int first_char, int num_chars,          // characters to bake
3817                                 stbtt_bakedchar *chardata)
3818 {
3819    float scale;
3820    int x,y,bottom_y, i;
3821    stbtt_fontinfo f;
3822    f.userdata = NULL;
3823    if (!stbtt_InitFont(&f, data, offset))
3824       return -1;
3825    STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels
3826    x=y=1;
3827    bottom_y = 1;
3828 
3829    scale = stbtt_ScaleForPixelHeight(&f, pixel_height);
3830 
3831    for (i=0; i < num_chars; ++i) {
3832       int advance, lsb, x0,y0,x1,y1,gw,gh;
3833       int g = stbtt_FindGlyphIndex(&f, first_char + i);
3834       stbtt_GetGlyphHMetrics(&f, g, &advance, &lsb);
3835       stbtt_GetGlyphBitmapBox(&f, g, scale,scale, &x0,&y0,&x1,&y1);
3836       gw = x1-x0;
3837       gh = y1-y0;
3838       if (x + gw + 1 >= pw)
3839          y = bottom_y, x = 1; // advance to next row
3840       if (y + gh + 1 >= ph) // check if it fits vertically AFTER potentially moving to next row
3841          return -i;
3842       STBTT_assert(x+gw < pw);
3843       STBTT_assert(y+gh < ph);
3844       stbtt_MakeGlyphBitmap(&f, pixels+x+y*pw, gw,gh,pw, scale,scale, g);
3845       chardata[i].x0 = (stbtt_int16) x;
3846       chardata[i].y0 = (stbtt_int16) y;
3847       chardata[i].x1 = (stbtt_int16) (x + gw);
3848       chardata[i].y1 = (stbtt_int16) (y + gh);
3849       chardata[i].xadvance = scale * advance;
3850       chardata[i].xoff     = (float) x0;
3851       chardata[i].yoff     = (float) y0;
3852       x = x + gw + 1;
3853       if (y+gh+1 > bottom_y)
3854          bottom_y = y+gh+1;
3855    }
3856    return bottom_y;
3857 }
3858 
3859 STBTT_DEF void stbtt_GetBakedQuad(const stbtt_bakedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int opengl_fillrule)
3860 {
3861    float d3d_bias = opengl_fillrule ? 0 : -0.5f;
3862    float ipw = 1.0f / pw, iph = 1.0f / ph;
3863    const stbtt_bakedchar *b = chardata + char_index;
3864    int round_x = STBTT_ifloor((*xpos + b->xoff) + 0.5f);
3865    int round_y = STBTT_ifloor((*ypos + b->yoff) + 0.5f);
3866 
3867    q->x0 = round_x + d3d_bias;
3868    q->y0 = round_y + d3d_bias;
3869    q->x1 = round_x + b->x1 - b->x0 + d3d_bias;
3870    q->y1 = round_y + b->y1 - b->y0 + d3d_bias;
3871 
3872    q->s0 = b->x0 * ipw;
3873    q->t0 = b->y0 * iph;
3874    q->s1 = b->x1 * ipw;
3875    q->t1 = b->y1 * iph;
3876 
3877    *xpos += b->xadvance;
3878 }
3879 
3880 //////////////////////////////////////////////////////////////////////////////
3881 //
3882 // rectangle packing replacement routines if you don't have stb_rect_pack.h
3883 //
3884 
3885 #ifndef STB_RECT_PACK_VERSION
3886 
3887 typedef int stbrp_coord;
3888 
3889 ////////////////////////////////////////////////////////////////////////////////////
3890 //                                                                                //
3891 //                                                                                //
3892 // COMPILER WARNING ?!?!?                                                         //
3893 //                                                                                //
3894 //                                                                                //
3895 // if you get a compile warning due to these symbols being defined more than      //
3896 // once, move #include "stb_rect_pack.h" before #include "stb_truetype.h"         //
3897 //                                                                                //
3898 ////////////////////////////////////////////////////////////////////////////////////
3899 
3900 typedef struct
3901 {
3902    int width,height;
3903    int x,y,bottom_y;
3904 } stbrp_context;
3905 
3906 typedef struct
3907 {
3908    unsigned char x;
3909 } stbrp_node;
3910 
3911 struct stbrp_rect
3912 {
3913    stbrp_coord x,y;
3914    int id,w,h,was_packed;
3915 };
3916 
3917 static void stbrp_init_target(stbrp_context *con, int pw, int ph, stbrp_node *nodes, int num_nodes)
3918 {
3919    con->width  = pw;
3920    con->height = ph;
3921    con->x = 0;
3922    con->y = 0;
3923    con->bottom_y = 0;
3924    STBTT__NOTUSED(nodes);
3925    STBTT__NOTUSED(num_nodes);
3926 }
3927 
3928 static void stbrp_pack_rects(stbrp_context *con, stbrp_rect *rects, int num_rects)
3929 {
3930    int i;
3931    for (i=0; i < num_rects; ++i) {
3932       if (con->x + rects[i].w > con->width) {
3933          con->x = 0;
3934          con->y = con->bottom_y;
3935       }
3936       if (con->y + rects[i].h > con->height)
3937          break;
3938       rects[i].x = con->x;
3939       rects[i].y = con->y;
3940       rects[i].was_packed = 1;
3941       con->x += rects[i].w;
3942       if (con->y + rects[i].h > con->bottom_y)
3943          con->bottom_y = con->y + rects[i].h;
3944    }
3945    for (   ; i < num_rects; ++i)
3946       rects[i].was_packed = 0;
3947 }
3948 #endif
3949 
3950 //////////////////////////////////////////////////////////////////////////////
3951 //
3952 // bitmap baking
3953 //
3954 // This is SUPER-AWESOME (tm Ryan Gordon) packing using stb_rect_pack.h. If
3955 // stb_rect_pack.h isn't available, it uses the BakeFontBitmap strategy.
3956 
3957 STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int pw, int ph, int stride_in_bytes, int padding, void *alloc_context)
3958 {
3959    stbrp_context *context = (stbrp_context *) STBTT_malloc(sizeof(*context)            ,alloc_context);
3960    int            num_nodes = pw - padding;
3961    stbrp_node    *nodes   = (stbrp_node    *) STBTT_malloc(sizeof(*nodes  ) * num_nodes,alloc_context);
3962 
3963    if (context == NULL || nodes == NULL) {
3964       if (context != NULL) STBTT_free(context, alloc_context);
3965       if (nodes   != NULL) STBTT_free(nodes  , alloc_context);
3966       return 0;
3967    }
3968 
3969    spc->user_allocator_context = alloc_context;
3970    spc->width = pw;
3971    spc->height = ph;
3972    spc->pixels = pixels;
3973    spc->pack_info = context;
3974    spc->nodes = nodes;
3975    spc->padding = padding;
3976    spc->stride_in_bytes = stride_in_bytes != 0 ? stride_in_bytes : pw;
3977    spc->h_oversample = 1;
3978    spc->v_oversample = 1;
3979    spc->skip_missing = 0;
3980 
3981    stbrp_init_target(context, pw-padding, ph-padding, nodes, num_nodes);
3982 
3983    if (pixels)
3984       STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels
3985 
3986    return 1;
3987 }
3988 
3989 STBTT_DEF void stbtt_PackEnd  (stbtt_pack_context *spc)
3990 {
3991    STBTT_free(spc->nodes    , spc->user_allocator_context);
3992    STBTT_free(spc->pack_info, spc->user_allocator_context);
3993 }
3994 
3995 STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample)
3996 {
3997    STBTT_assert(h_oversample <= STBTT_MAX_OVERSAMPLE);
3998    STBTT_assert(v_oversample <= STBTT_MAX_OVERSAMPLE);
3999    if (h_oversample <= STBTT_MAX_OVERSAMPLE)
4000       spc->h_oversample = h_oversample;
4001    if (v_oversample <= STBTT_MAX_OVERSAMPLE)
4002       spc->v_oversample = v_oversample;
4003 }
4004 
4005 STBTT_DEF void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context *spc, int skip)
4006 {
4007    spc->skip_missing = skip;
4008 }
4009 
4010 #define STBTT__OVER_MASK  (STBTT_MAX_OVERSAMPLE-1)
4011 
4012 static void stbtt__h_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width)
4013 {
4014    unsigned char buffer[STBTT_MAX_OVERSAMPLE];
4015    int safe_w = w - kernel_width;
4016    int j;
4017    STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); // suppress bogus warning from VS2013 -analyze
4018    for (j=0; j < h; ++j) {
4019       int i;
4020       unsigned int total;
4021       STBTT_memset(buffer, 0, kernel_width);
4022 
4023       total = 0;
4024 
4025       // make kernel_width a constant in common cases so compiler can optimize out the divide
4026       switch (kernel_width) {
4027          case 2:
4028             for (i=0; i <= safe_w; ++i) {
4029                total += pixels[i] - buffer[i & STBTT__OVER_MASK];
4030                buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
4031                pixels[i] = (unsigned char) (total / 2);
4032             }
4033             break;
4034          case 3:
4035             for (i=0; i <= safe_w; ++i) {
4036                total += pixels[i] - buffer[i & STBTT__OVER_MASK];
4037                buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
4038                pixels[i] = (unsigned char) (total / 3);
4039             }
4040             break;
4041          case 4:
4042             for (i=0; i <= safe_w; ++i) {
4043                total += pixels[i] - buffer[i & STBTT__OVER_MASK];
4044                buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
4045                pixels[i] = (unsigned char) (total / 4);
4046             }
4047             break;
4048          case 5:
4049             for (i=0; i <= safe_w; ++i) {
4050                total += pixels[i] - buffer[i & STBTT__OVER_MASK];
4051                buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
4052                pixels[i] = (unsigned char) (total / 5);
4053             }
4054             break;
4055          default:
4056             for (i=0; i <= safe_w; ++i) {
4057                total += pixels[i] - buffer[i & STBTT__OVER_MASK];
4058                buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
4059                pixels[i] = (unsigned char) (total / kernel_width);
4060             }
4061             break;
4062       }
4063 
4064       for (; i < w; ++i) {
4065          STBTT_assert(pixels[i] == 0);
4066          total -= buffer[i & STBTT__OVER_MASK];
4067          pixels[i] = (unsigned char) (total / kernel_width);
4068       }
4069 
4070       pixels += stride_in_bytes;
4071    }
4072 }
4073 
4074 static void stbtt__v_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width)
4075 {
4076    unsigned char buffer[STBTT_MAX_OVERSAMPLE];
4077    int safe_h = h - kernel_width;
4078    int j;
4079    STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); // suppress bogus warning from VS2013 -analyze
4080    for (j=0; j < w; ++j) {
4081       int i;
4082       unsigned int total;
4083       STBTT_memset(buffer, 0, kernel_width);
4084 
4085       total = 0;
4086 
4087       // make kernel_width a constant in common cases so compiler can optimize out the divide
4088       switch (kernel_width) {
4089          case 2:
4090             for (i=0; i <= safe_h; ++i) {
4091                total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
4092                buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
4093                pixels[i*stride_in_bytes] = (unsigned char) (total / 2);
4094             }
4095             break;
4096          case 3:
4097             for (i=0; i <= safe_h; ++i) {
4098                total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
4099                buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
4100                pixels[i*stride_in_bytes] = (unsigned char) (total / 3);
4101             }
4102             break;
4103          case 4:
4104             for (i=0; i <= safe_h; ++i) {
4105                total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
4106                buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
4107                pixels[i*stride_in_bytes] = (unsigned char) (total / 4);
4108             }
4109             break;
4110          case 5:
4111             for (i=0; i <= safe_h; ++i) {
4112                total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
4113                buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
4114                pixels[i*stride_in_bytes] = (unsigned char) (total / 5);
4115             }
4116             break;
4117          default:
4118             for (i=0; i <= safe_h; ++i) {
4119                total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
4120                buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
4121                pixels[i*stride_in_bytes] = (unsigned char) (total / kernel_width);
4122             }
4123             break;
4124       }
4125 
4126       for (; i < h; ++i) {
4127          STBTT_assert(pixels[i*stride_in_bytes] == 0);
4128          total -= buffer[i & STBTT__OVER_MASK];
4129          pixels[i*stride_in_bytes] = (unsigned char) (total / kernel_width);
4130       }
4131 
4132       pixels += 1;
4133    }
4134 }
4135 
4136 static float stbtt__oversample_shift(int oversample)
4137 {
4138    if (!oversample)
4139       return 0.0f;
4140 
4141    // The prefilter is a box filter of width "oversample",
4142    // which shifts phase by (oversample - 1)/2 pixels in
4143    // oversampled space. We want to shift in the opposite
4144    // direction to counter this.
4145    return (float)-(oversample - 1) / (2.0f * (float)oversample);
4146 }
4147 
4148 // rects array must be big enough to accommodate all characters in the given ranges
4149 STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects)
4150 {
4151    int i,j,k;
4152    int missing_glyph_added = 0;
4153 
4154    k=0;
4155    for (i=0; i < num_ranges; ++i) {
4156       float fh = ranges[i].font_size;
4157       float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh);
4158       ranges[i].h_oversample = (unsigned char) spc->h_oversample;
4159       ranges[i].v_oversample = (unsigned char) spc->v_oversample;
4160       for (j=0; j < ranges[i].num_chars; ++j) {
4161          int x0,y0,x1,y1;
4162          int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
4163          int glyph = stbtt_FindGlyphIndex(info, codepoint);
4164          if (glyph == 0 && (spc->skip_missing || missing_glyph_added)) {
4165             rects[k].w = rects[k].h = 0;
4166          } else {
4167             stbtt_GetGlyphBitmapBoxSubpixel(info,glyph,
4168                                             scale * spc->h_oversample,
4169                                             scale * spc->v_oversample,
4170                                             0,0,
4171                                             &x0,&y0,&x1,&y1);
4172             rects[k].w = (stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1);
4173             rects[k].h = (stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1);
4174             if (glyph == 0)
4175                missing_glyph_added = 1;
4176          }
4177          ++k;
4178       }
4179    }
4180 
4181    return k;
4182 }
4183 
4184 STBTT_DEF void stbtt_MakeGlyphBitmapSubpixelPrefilter(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int prefilter_x, int prefilter_y, float *sub_x, float *sub_y, int glyph)
4185 {
4186    stbtt_MakeGlyphBitmapSubpixel(info,
4187                                  output,
4188                                  out_w - (prefilter_x - 1),
4189                                  out_h - (prefilter_y - 1),
4190                                  out_stride,
4191                                  scale_x,
4192                                  scale_y,
4193                                  shift_x,
4194                                  shift_y,
4195                                  glyph);
4196 
4197    if (prefilter_x > 1)
4198       stbtt__h_prefilter(output, out_w, out_h, out_stride, prefilter_x);
4199 
4200    if (prefilter_y > 1)
4201       stbtt__v_prefilter(output, out_w, out_h, out_stride, prefilter_y);
4202 
4203    *sub_x = stbtt__oversample_shift(prefilter_x);
4204    *sub_y = stbtt__oversample_shift(prefilter_y);
4205 }
4206 
4207 // rects array must be big enough to accommodate all characters in the given ranges
4208 STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects)
4209 {
4210    int i,j,k, missing_glyph = -1, return_value = 1;
4211 
4212    // save current values
4213    int old_h_over = spc->h_oversample;
4214    int old_v_over = spc->v_oversample;
4215 
4216    k = 0;
4217    for (i=0; i < num_ranges; ++i) {
4218       float fh = ranges[i].font_size;
4219       float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh);
4220       float recip_h,recip_v,sub_x,sub_y;
4221       spc->h_oversample = ranges[i].h_oversample;
4222       spc->v_oversample = ranges[i].v_oversample;
4223       recip_h = 1.0f / spc->h_oversample;
4224       recip_v = 1.0f / spc->v_oversample;
4225       sub_x = stbtt__oversample_shift(spc->h_oversample);
4226       sub_y = stbtt__oversample_shift(spc->v_oversample);
4227       for (j=0; j < ranges[i].num_chars; ++j) {
4228          stbrp_rect *r = &rects[k];
4229          if (r->was_packed && r->w != 0 && r->h != 0) {
4230             stbtt_packedchar *bc = &ranges[i].chardata_for_range[j];
4231             int advance, lsb, x0,y0,x1,y1;
4232             int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
4233             int glyph = stbtt_FindGlyphIndex(info, codepoint);
4234             stbrp_coord pad = (stbrp_coord) spc->padding;
4235 
4236             // pad on left and top
4237             r->x += pad;
4238             r->y += pad;
4239             r->w -= pad;
4240             r->h -= pad;
4241             stbtt_GetGlyphHMetrics(info, glyph, &advance, &lsb);
4242             stbtt_GetGlyphBitmapBox(info, glyph,
4243                                     scale * spc->h_oversample,
4244                                     scale * spc->v_oversample,
4245                                     &x0,&y0,&x1,&y1);
4246             stbtt_MakeGlyphBitmapSubpixel(info,
4247                                           spc->pixels + r->x + r->y*spc->stride_in_bytes,
4248                                           r->w - spc->h_oversample+1,
4249                                           r->h - spc->v_oversample+1,
4250                                           spc->stride_in_bytes,
4251                                           scale * spc->h_oversample,
4252                                           scale * spc->v_oversample,
4253                                           0,0,
4254                                           glyph);
4255 
4256             if (spc->h_oversample > 1)
4257                stbtt__h_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes,
4258                                   r->w, r->h, spc->stride_in_bytes,
4259                                   spc->h_oversample);
4260 
4261             if (spc->v_oversample > 1)
4262                stbtt__v_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes,
4263                                   r->w, r->h, spc->stride_in_bytes,
4264                                   spc->v_oversample);
4265 
4266             bc->x0       = (stbtt_int16)  r->x;
4267             bc->y0       = (stbtt_int16)  r->y;
4268             bc->x1       = (stbtt_int16) (r->x + r->w);
4269             bc->y1       = (stbtt_int16) (r->y + r->h);
4270             bc->xadvance =                scale * advance;
4271             bc->xoff     =       (float)  x0 * recip_h + sub_x;
4272             bc->yoff     =       (float)  y0 * recip_v + sub_y;
4273             bc->xoff2    =                (x0 + r->w) * recip_h + sub_x;
4274             bc->yoff2    =                (y0 + r->h) * recip_v + sub_y;
4275 
4276             if (glyph == 0)
4277                missing_glyph = j;
4278          } else if (spc->skip_missing) {
4279             return_value = 0;
4280          } else if (r->was_packed && r->w == 0 && r->h == 0 && missing_glyph >= 0) {
4281             ranges[i].chardata_for_range[j] = ranges[i].chardata_for_range[missing_glyph];
4282          } else {
4283             return_value = 0; // if any fail, report failure
4284          }
4285 
4286          ++k;
4287       }
4288    }
4289 
4290    // restore original values
4291    spc->h_oversample = old_h_over;
4292    spc->v_oversample = old_v_over;
4293 
4294    return return_value;
4295 }
4296 
4297 STBTT_DEF void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect *rects, int num_rects)
4298 {
4299    stbrp_pack_rects((stbrp_context *) spc->pack_info, rects, num_rects);
4300 }
4301 
4302 STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges)
4303 {
4304    stbtt_fontinfo info;
4305    int i,j,n, return_value = 1;
4306    //stbrp_context *context = (stbrp_context *) spc->pack_info;
4307    stbrp_rect    *rects;
4308 
4309    // flag all characters as NOT packed
4310    for (i=0; i < num_ranges; ++i)
4311       for (j=0; j < ranges[i].num_chars; ++j)
4312          ranges[i].chardata_for_range[j].x0 =
4313          ranges[i].chardata_for_range[j].y0 =
4314          ranges[i].chardata_for_range[j].x1 =
4315          ranges[i].chardata_for_range[j].y1 = 0;
4316 
4317    n = 0;
4318    for (i=0; i < num_ranges; ++i)
4319       n += ranges[i].num_chars;
4320 
4321    rects = (stbrp_rect *) STBTT_malloc(sizeof(*rects) * n, spc->user_allocator_context);
4322    if (rects == NULL)
4323       return 0;
4324 
4325    info.userdata = spc->user_allocator_context;
4326    stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata,font_index));
4327 
4328    n = stbtt_PackFontRangesGatherRects(spc, &info, ranges, num_ranges, rects);
4329 
4330    stbtt_PackFontRangesPackRects(spc, rects, n);
4331 
4332    return_value = stbtt_PackFontRangesRenderIntoRects(spc, &info, ranges, num_ranges, rects);
4333 
4334    STBTT_free(rects, spc->user_allocator_context);
4335    return return_value;
4336 }
4337 
4338 STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, float font_size,
4339             int first_unicode_codepoint_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range)
4340 {
4341    stbtt_pack_range range;
4342    range.first_unicode_codepoint_in_range = first_unicode_codepoint_in_range;
4343    range.array_of_unicode_codepoints = NULL;
4344    range.num_chars                   = num_chars_in_range;
4345    range.chardata_for_range          = chardata_for_range;
4346    range.font_size                   = font_size;
4347    return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1);
4348 }
4349 
4350 STBTT_DEF void stbtt_GetScaledFontVMetrics(const unsigned char *fontdata, int index, float size, float *ascent, float *descent, float *lineGap)
4351 {
4352    int i_ascent, i_descent, i_lineGap;
4353    float scale;
4354    stbtt_fontinfo info;
4355    stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata, index));
4356    scale = size > 0 ? stbtt_ScaleForPixelHeight(&info, size) : stbtt_ScaleForMappingEmToPixels(&info, -size);
4357    stbtt_GetFontVMetrics(&info, &i_ascent, &i_descent, &i_lineGap);
4358    *ascent  = (float) i_ascent  * scale;
4359    *descent = (float) i_descent * scale;
4360    *lineGap = (float) i_lineGap * scale;
4361 }
4362 
4363 STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int align_to_integer)
4364 {
4365    float ipw = 1.0f / pw, iph = 1.0f / ph;
4366    const stbtt_packedchar *b = chardata + char_index;
4367 
4368    if (align_to_integer) {
4369       float x = (float) STBTT_ifloor((*xpos + b->xoff) + 0.5f);
4370       float y = (float) STBTT_ifloor((*ypos + b->yoff) + 0.5f);
4371       q->x0 = x;
4372       q->y0 = y;
4373       q->x1 = x + b->xoff2 - b->xoff;
4374       q->y1 = y + b->yoff2 - b->yoff;
4375    } else {
4376       q->x0 = *xpos + b->xoff;
4377       q->y0 = *ypos + b->yoff;
4378       q->x1 = *xpos + b->xoff2;
4379       q->y1 = *ypos + b->yoff2;
4380    }
4381 
4382    q->s0 = b->x0 * ipw;
4383    q->t0 = b->y0 * iph;
4384    q->s1 = b->x1 * ipw;
4385    q->t1 = b->y1 * iph;
4386 
4387    *xpos += b->xadvance;
4388 }
4389 
4390 //////////////////////////////////////////////////////////////////////////////
4391 //
4392 // sdf computation
4393 //
4394 
4395 #define STBTT_min(a,b)  ((a) < (b) ? (a) : (b))
4396 #define STBTT_max(a,b)  ((a) < (b) ? (b) : (a))
4397 
4398 static int stbtt__ray_intersect_bezier(float orig[2], float ray[2], float q0[2], float q1[2], float q2[2], float hits[2][2])
4399 {
4400    float q0perp = q0[1]*ray[0] - q0[0]*ray[1];
4401    float q1perp = q1[1]*ray[0] - q1[0]*ray[1];
4402    float q2perp = q2[1]*ray[0] - q2[0]*ray[1];
4403    float roperp = orig[1]*ray[0] - orig[0]*ray[1];
4404 
4405    float a = q0perp - 2*q1perp + q2perp;
4406    float b = q1perp - q0perp;
4407    float c = q0perp - roperp;
4408 
4409    float s0 = 0., s1 = 0.;
4410    int num_s = 0;
4411 
4412    if (a != 0.0) {
4413       float discr = b*b - a*c;
4414       if (discr > 0.0) {
4415          float rcpna = -1 / a;
4416          float d = (float) STBTT_sqrt(discr);
4417          s0 = (b+d) * rcpna;
4418          s1 = (b-d) * rcpna;
4419          if (s0 >= 0.0 && s0 <= 1.0)
4420             num_s = 1;
4421          if (d > 0.0 && s1 >= 0.0 && s1 <= 1.0) {
4422             if (num_s == 0) s0 = s1;
4423             ++num_s;
4424          }
4425       }
4426    } else {
4427       // 2*b*s + c = 0
4428       // s = -c / (2*b)
4429       s0 = c / (-2 * b);
4430       if (s0 >= 0.0 && s0 <= 1.0)
4431          num_s = 1;
4432    }
4433 
4434    if (num_s == 0)
4435       return 0;
4436    else {
4437       float rcp_len2 = 1 / (ray[0]*ray[0] + ray[1]*ray[1]);
4438       float rayn_x = ray[0] * rcp_len2, rayn_y = ray[1] * rcp_len2;
4439 
4440       float q0d =   q0[0]*rayn_x +   q0[1]*rayn_y;
4441       float q1d =   q1[0]*rayn_x +   q1[1]*rayn_y;
4442       float q2d =   q2[0]*rayn_x +   q2[1]*rayn_y;
4443       float rod = orig[0]*rayn_x + orig[1]*rayn_y;
4444 
4445       float q10d = q1d - q0d;
4446       float q20d = q2d - q0d;
4447       float q0rd = q0d - rod;
4448 
4449       hits[0][0] = q0rd + s0*(2.0f - 2.0f*s0)*q10d + s0*s0*q20d;
4450       hits[0][1] = a*s0+b;
4451 
4452       if (num_s > 1) {
4453          hits[1][0] = q0rd + s1*(2.0f - 2.0f*s1)*q10d + s1*s1*q20d;
4454          hits[1][1] = a*s1+b;
4455          return 2;
4456       } else {
4457          return 1;
4458       }
4459    }
4460 }
4461 
4462 static int equal(float *a, float *b)
4463 {
4464    return (a[0] == b[0] && a[1] == b[1]);
4465 }
4466 
4467 static int stbtt__compute_crossings_x(float x, float y, int nverts, stbtt_vertex *verts)
4468 {
4469    int i;
4470    float orig[2], ray[2] = { 1, 0 };
4471    float y_frac;
4472    int winding = 0;
4473 
4474    // make sure y never passes through a vertex of the shape
4475    y_frac = (float) STBTT_fmod(y, 1.0f);
4476    if (y_frac < 0.01f)
4477       y += 0.01f;
4478    else if (y_frac > 0.99f)
4479       y -= 0.01f;
4480 
4481    orig[0] = x;
4482    orig[1] = y;
4483 
4484    // test a ray from (-infinity,y) to (x,y)
4485    for (i=0; i < nverts; ++i) {
4486       if (verts[i].type == STBTT_vline) {
4487          int x0 = (int) verts[i-1].x, y0 = (int) verts[i-1].y;
4488          int x1 = (int) verts[i  ].x, y1 = (int) verts[i  ].y;
4489          if (y > STBTT_min(y0,y1) && y < STBTT_max(y0,y1) && x > STBTT_min(x0,x1)) {
4490             float x_inter = (y - y0) / (y1 - y0) * (x1-x0) + x0;
4491             if (x_inter < x)
4492                winding += (y0 < y1) ? 1 : -1;
4493          }
4494       }
4495       if (verts[i].type == STBTT_vcurve) {
4496          int x0 = (int) verts[i-1].x , y0 = (int) verts[i-1].y ;
4497          int x1 = (int) verts[i  ].cx, y1 = (int) verts[i  ].cy;
4498          int x2 = (int) verts[i  ].x , y2 = (int) verts[i  ].y ;
4499          int ax = STBTT_min(x0,STBTT_min(x1,x2)), ay = STBTT_min(y0,STBTT_min(y1,y2));
4500          int by = STBTT_max(y0,STBTT_max(y1,y2));
4501          if (y > ay && y < by && x > ax) {
4502             float q0[2],q1[2],q2[2];
4503             float hits[2][2];
4504             q0[0] = (float)x0;
4505             q0[1] = (float)y0;
4506             q1[0] = (float)x1;
4507             q1[1] = (float)y1;
4508             q2[0] = (float)x2;
4509             q2[1] = (float)y2;
4510             if (equal(q0,q1) || equal(q1,q2)) {
4511                x0 = (int)verts[i-1].x;
4512                y0 = (int)verts[i-1].y;
4513                x1 = (int)verts[i  ].x;
4514                y1 = (int)verts[i  ].y;
4515                if (y > STBTT_min(y0,y1) && y < STBTT_max(y0,y1) && x > STBTT_min(x0,x1)) {
4516                   float x_inter = (y - y0) / (y1 - y0) * (x1-x0) + x0;
4517                   if (x_inter < x)
4518                      winding += (y0 < y1) ? 1 : -1;
4519                }
4520             } else {
4521                int num_hits = stbtt__ray_intersect_bezier(orig, ray, q0, q1, q2, hits);
4522                if (num_hits >= 1)
4523                   if (hits[0][0] < 0)
4524                      winding += (hits[0][1] < 0 ? -1 : 1);
4525                if (num_hits >= 2)
4526                   if (hits[1][0] < 0)
4527                      winding += (hits[1][1] < 0 ? -1 : 1);
4528             }
4529          }
4530       }
4531    }
4532    return winding;
4533 }
4534 
4535 static float stbtt__cuberoot( float x )
4536 {
4537    if (x<0)
4538       return -(float) STBTT_pow(-x,1.0f/3.0f);
4539    else
4540       return  (float) STBTT_pow( x,1.0f/3.0f);
4541 }
4542 
4543 // x^3 + a*x^2 + b*x + c = 0
4544 static int stbtt__solve_cubic(float a, float b, float c, float* r)
4545 {
4546    float s = -a / 3;
4547    float p = b - a*a / 3;
4548    float q = a * (2*a*a - 9*b) / 27 + c;
4549    float p3 = p*p*p;
4550    float d = q*q + 4*p3 / 27;
4551    if (d >= 0) {
4552       float z = (float) STBTT_sqrt(d);
4553       float u = (-q + z) / 2;
4554       float v = (-q - z) / 2;
4555       u = stbtt__cuberoot(u);
4556       v = stbtt__cuberoot(v);
4557       r[0] = s + u + v;
4558       return 1;
4559    } else {
4560       float u = (float) STBTT_sqrt(-p/3);
4561       float v = (float) STBTT_acos(-STBTT_sqrt(-27/p3) * q / 2) / 3; // p3 must be negative, since d is negative
4562       float m = (float) STBTT_cos(v);
4563       float n = (float) STBTT_cos(v-3.141592/2)*1.732050808f;
4564       r[0] = s + u * 2 * m;
4565       r[1] = s - u * (m + n);
4566       r[2] = s - u * (m - n);
4567 
4568       //STBTT_assert( STBTT_fabs(((r[0]+a)*r[0]+b)*r[0]+c) < 0.05f);  // these asserts may not be safe at all scales, though they're in bezier t parameter units so maybe?
4569       //STBTT_assert( STBTT_fabs(((r[1]+a)*r[1]+b)*r[1]+c) < 0.05f);
4570       //STBTT_assert( STBTT_fabs(((r[2]+a)*r[2]+b)*r[2]+c) < 0.05f);
4571       return 3;
4572    }
4573 }
4574 
4575 STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float scale, int glyph, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff)
4576 {
4577    float scale_x = scale, scale_y = scale;
4578    int ix0,iy0,ix1,iy1;
4579    int w,h;
4580    unsigned char *data;
4581 
4582    if (scale == 0) return NULL;
4583 
4584    stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale, scale, 0.0f,0.0f, &ix0,&iy0,&ix1,&iy1);
4585 
4586    // if empty, return NULL
4587    if (ix0 == ix1 || iy0 == iy1)
4588       return NULL;
4589 
4590    ix0 -= padding;
4591    iy0 -= padding;
4592    ix1 += padding;
4593    iy1 += padding;
4594 
4595    w = (ix1 - ix0);
4596    h = (iy1 - iy0);
4597 
4598    if (width ) *width  = w;
4599    if (height) *height = h;
4600    if (xoff  ) *xoff   = ix0;
4601    if (yoff  ) *yoff   = iy0;
4602 
4603    // invert for y-downwards bitmaps
4604    scale_y = -scale_y;
4605 
4606    {
4607       // distance from singular values (in the same units as the pixel grid)
4608       const float eps = 1./1024, eps2 = eps*eps;
4609       int x,y,i,j;
4610       float *precompute;
4611       stbtt_vertex *verts;
4612       int num_verts = stbtt_GetGlyphShape(info, glyph, &verts);
4613       data = (unsigned char *) STBTT_malloc(w * h, info->userdata);
4614       precompute = (float *) STBTT_malloc(num_verts * sizeof(float), info->userdata);
4615 
4616       for (i=0,j=num_verts-1; i < num_verts; j=i++) {
4617          if (verts[i].type == STBTT_vline) {
4618             float x0 = verts[i].x*scale_x, y0 = verts[i].y*scale_y;
4619             float x1 = verts[j].x*scale_x, y1 = verts[j].y*scale_y;
4620             float dist = (float) STBTT_sqrt((x1-x0)*(x1-x0) + (y1-y0)*(y1-y0));
4621             precompute[i] = (dist < eps) ? 0.0f : 1.0f / dist;
4622          } else if (verts[i].type == STBTT_vcurve) {
4623             float x2 = verts[j].x *scale_x, y2 = verts[j].y *scale_y;
4624             float x1 = verts[i].cx*scale_x, y1 = verts[i].cy*scale_y;
4625             float x0 = verts[i].x *scale_x, y0 = verts[i].y *scale_y;
4626             float bx = x0 - 2*x1 + x2, by = y0 - 2*y1 + y2;
4627             float len2 = bx*bx + by*by;
4628             if (len2 >= eps2)
4629                precompute[i] = 1.0f / len2;
4630             else
4631                precompute[i] = 0.0f;
4632          } else
4633             precompute[i] = 0.0f;
4634       }
4635 
4636       for (y=iy0; y < iy1; ++y) {
4637          for (x=ix0; x < ix1; ++x) {
4638             float val;
4639             float min_dist = 999999.0f;
4640             float sx = (float) x + 0.5f;
4641             float sy = (float) y + 0.5f;
4642             float x_gspace = (sx / scale_x);
4643             float y_gspace = (sy / scale_y);
4644 
4645             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
4646 
4647             for (i=0; i < num_verts; ++i) {
4648                float x0 = verts[i].x*scale_x, y0 = verts[i].y*scale_y;
4649 
4650                if (verts[i].type == STBTT_vline && precompute[i] != 0.0f) {
4651                   float x1 = verts[i-1].x*scale_x, y1 = verts[i-1].y*scale_y;
4652 
4653                   float dist,dist2 = (x0-sx)*(x0-sx) + (y0-sy)*(y0-sy);
4654                   if (dist2 < min_dist*min_dist)
4655                      min_dist = (float) STBTT_sqrt(dist2);
4656 
4657                   // coarse culling against bbox
4658                   //if (sx > STBTT_min(x0,x1)-min_dist && sx < STBTT_max(x0,x1)+min_dist &&
4659                   //    sy > STBTT_min(y0,y1)-min_dist && sy < STBTT_max(y0,y1)+min_dist)
4660                   dist = (float) STBTT_fabs((x1-x0)*(y0-sy) - (y1-y0)*(x0-sx)) * precompute[i];
4661                   STBTT_assert(i != 0);
4662                   if (dist < min_dist) {
4663                      // check position along line
4664                      // x' = x0 + t*(x1-x0), y' = y0 + t*(y1-y0)
4665                      // minimize (x'-sx)*(x'-sx)+(y'-sy)*(y'-sy)
4666                      float dx = x1-x0, dy = y1-y0;
4667                      float px = x0-sx, py = y0-sy;
4668                      // 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
4669                      // derivative: 2*px*dx + 2*py*dy + (2*dx*dx+2*dy*dy)*t, set to 0 and solve
4670                      float t = -(px*dx + py*dy) / (dx*dx + dy*dy);
4671                      if (t >= 0.0f && t <= 1.0f)
4672                         min_dist = dist;
4673                   }
4674                } else if (verts[i].type == STBTT_vcurve) {
4675                   float x2 = verts[i-1].x *scale_x, y2 = verts[i-1].y *scale_y;
4676                   float x1 = verts[i  ].cx*scale_x, y1 = verts[i  ].cy*scale_y;
4677                   float box_x0 = STBTT_min(STBTT_min(x0,x1),x2);
4678                   float box_y0 = STBTT_min(STBTT_min(y0,y1),y2);
4679                   float box_x1 = STBTT_max(STBTT_max(x0,x1),x2);
4680                   float box_y1 = STBTT_max(STBTT_max(y0,y1),y2);
4681                   // coarse culling against bbox to avoid computing cubic unnecessarily
4682                   if (sx > box_x0-min_dist && sx < box_x1+min_dist && sy > box_y0-min_dist && sy < box_y1+min_dist) {
4683                      int num=0;
4684                      float ax = x1-x0, ay = y1-y0;
4685                      float bx = x0 - 2*x1 + x2, by = y0 - 2*y1 + y2;
4686                      float mx = x0 - sx, my = y0 - sy;
4687                      float res[3] = {0.f,0.f,0.f};
4688                      float px,py,t,it,dist2;
4689                      float a_inv = precompute[i];
4690                      if (a_inv == 0.0) { // if a_inv is 0, it's 2nd degree so use quadratic formula
4691                         float a = 3*(ax*bx + ay*by);
4692                         float b = 2*(ax*ax + ay*ay) + (mx*bx+my*by);
4693                         float c = mx*ax+my*ay;
4694                         if (STBTT_fabs(a) < eps2) { // if a is 0, it's linear
4695                            if (STBTT_fabs(b) >= eps2) {
4696                               res[num++] = -c/b;
4697                            }
4698                         } else {
4699                            float discriminant = b*b - 4*a*c;
4700                            if (discriminant < 0)
4701                               num = 0;
4702                            else {
4703                               float root = (float) STBTT_sqrt(discriminant);
4704                               res[0] = (-b - root)/(2*a);
4705                               res[1] = (-b + root)/(2*a);
4706                               num = 2; // don't bother distinguishing 1-solution case, as code below will still work
4707                            }
4708                         }
4709                      } else {
4710                         float b = 3*(ax*bx + ay*by) * a_inv; // could precompute this as it doesn't depend on sample point
4711                         float c = (2*(ax*ax + ay*ay) + (mx*bx+my*by)) * a_inv;
4712                         float d = (mx*ax+my*ay) * a_inv;
4713                         num = stbtt__solve_cubic(b, c, d, res);
4714                      }
4715                      dist2 = (x0-sx)*(x0-sx) + (y0-sy)*(y0-sy);
4716                      if (dist2 < min_dist*min_dist)
4717                         min_dist = (float) STBTT_sqrt(dist2);
4718 
4719                      if (num >= 1 && res[0] >= 0.0f && res[0] <= 1.0f) {
4720                         t = res[0], it = 1.0f - t;
4721                         px = it*it*x0 + 2*t*it*x1 + t*t*x2;
4722                         py = it*it*y0 + 2*t*it*y1 + t*t*y2;
4723                         dist2 = (px-sx)*(px-sx) + (py-sy)*(py-sy);
4724                         if (dist2 < min_dist * min_dist)
4725                            min_dist = (float) STBTT_sqrt(dist2);
4726                      }
4727                      if (num >= 2 && res[1] >= 0.0f && res[1] <= 1.0f) {
4728                         t = res[1], it = 1.0f - t;
4729                         px = it*it*x0 + 2*t*it*x1 + t*t*x2;
4730                         py = it*it*y0 + 2*t*it*y1 + t*t*y2;
4731                         dist2 = (px-sx)*(px-sx) + (py-sy)*(py-sy);
4732                         if (dist2 < min_dist * min_dist)
4733                            min_dist = (float) STBTT_sqrt(dist2);
4734                      }
4735                      if (num >= 3 && res[2] >= 0.0f && res[2] <= 1.0f) {
4736                         t = res[2], it = 1.0f - t;
4737                         px = it*it*x0 + 2*t*it*x1 + t*t*x2;
4738                         py = it*it*y0 + 2*t*it*y1 + t*t*y2;
4739                         dist2 = (px-sx)*(px-sx) + (py-sy)*(py-sy);
4740                         if (dist2 < min_dist * min_dist)
4741                            min_dist = (float) STBTT_sqrt(dist2);
4742                      }
4743                   }
4744                }
4745             }
4746             if (winding == 0)
4747                min_dist = -min_dist;  // if outside the shape, value is negative
4748             val = onedge_value + pixel_dist_scale * min_dist;
4749             if (val < 0)
4750                val = 0;
4751             else if (val > 255)
4752                val = 255;
4753             data[(y-iy0)*w+(x-ix0)] = (unsigned char) val;
4754          }
4755       }
4756       STBTT_free(precompute, info->userdata);
4757       STBTT_free(verts, info->userdata);
4758    }
4759    return data;
4760 }
4761 
4762 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)
4763 {
4764    return stbtt_GetGlyphSDF(info, scale, stbtt_FindGlyphIndex(info, codepoint), padding, onedge_value, pixel_dist_scale, width, height, xoff, yoff);
4765 }
4766 
4767 STBTT_DEF void stbtt_FreeSDF(unsigned char *bitmap, void *userdata)
4768 {
4769    STBTT_free(bitmap, userdata);
4770 }
4771 
4772 //////////////////////////////////////////////////////////////////////////////
4773 //
4774 // font name matching -- recommended not to use this
4775 //
4776 
4777 // check if a utf8 string contains a prefix which is the utf16 string; if so return length of matching utf8 string
4778 static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(stbtt_uint8 *s1, stbtt_int32 len1, stbtt_uint8 *s2, stbtt_int32 len2)
4779 {
4780    stbtt_int32 i=0;
4781 
4782    // convert utf16 to utf8 and compare the results while converting
4783    while (len2) {
4784       stbtt_uint16 ch = s2[0]*256 + s2[1];
4785       if (ch < 0x80) {
4786          if (i >= len1) return -1;
4787          if (s1[i++] != ch) return -1;
4788       } else if (ch < 0x800) {
4789          if (i+1 >= len1) return -1;
4790          if (s1[i++] != 0xc0 + (ch >> 6)) return -1;
4791          if (s1[i++] != 0x80 + (ch & 0x3f)) return -1;
4792       } else if (ch >= 0xd800 && ch < 0xdc00) {
4793          stbtt_uint32 c;
4794          stbtt_uint16 ch2 = s2[2]*256 + s2[3];
4795          if (i+3 >= len1) return -1;
4796          c = ((ch - 0xd800) << 10) + (ch2 - 0xdc00) + 0x10000;
4797          if (s1[i++] != 0xf0 + (c >> 18)) return -1;
4798          if (s1[i++] != 0x80 + ((c >> 12) & 0x3f)) return -1;
4799          if (s1[i++] != 0x80 + ((c >>  6) & 0x3f)) return -1;
4800          if (s1[i++] != 0x80 + ((c      ) & 0x3f)) return -1;
4801          s2 += 2; // plus another 2 below
4802          len2 -= 2;
4803       } else if (ch >= 0xdc00 && ch < 0xe000) {
4804          return -1;
4805       } else {
4806          if (i+2 >= len1) return -1;
4807          if (s1[i++] != 0xe0 + (ch >> 12)) return -1;
4808          if (s1[i++] != 0x80 + ((ch >> 6) & 0x3f)) return -1;
4809          if (s1[i++] != 0x80 + ((ch     ) & 0x3f)) return -1;
4810       }
4811       s2 += 2;
4812       len2 -= 2;
4813    }
4814    return i;
4815 }
4816 
4817 static int stbtt_CompareUTF8toUTF16_bigendian_internal(char *s1, int len1, char *s2, int len2)
4818 {
4819    return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((stbtt_uint8*) s1, len1, (stbtt_uint8*) s2, len2);
4820 }
4821 
4822 // returns results in whatever encoding you request... but note that 2-byte encodings
4823 // will be BIG-ENDIAN... use stbtt_CompareUTF8toUTF16_bigendian() to compare
4824 STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID)
4825 {
4826    stbtt_int32 i,count,stringOffset;
4827    stbtt_uint8 *fc = font->data;
4828    stbtt_uint32 offset = font->fontstart;
4829    stbtt_uint32 nm = stbtt__find_table(fc, offset, "name");
4830    if (!nm) return NULL;
4831 
4832    count = ttUSHORT(fc+nm+2);
4833    stringOffset = nm + ttUSHORT(fc+nm+4);
4834    for (i=0; i < count; ++i) {
4835       stbtt_uint32 loc = nm + 6 + 12 * i;
4836       if (platformID == ttUSHORT(fc+loc+0) && encodingID == ttUSHORT(fc+loc+2)
4837           && languageID == ttUSHORT(fc+loc+4) && nameID == ttUSHORT(fc+loc+6)) {
4838          *length = ttUSHORT(fc+loc+8);
4839          return (const char *) (fc+stringOffset+ttUSHORT(fc+loc+10));
4840       }
4841    }
4842    return NULL;
4843 }
4844 
4845 static int stbtt__matchpair(stbtt_uint8 *fc, stbtt_uint32 nm, stbtt_uint8 *name, stbtt_int32 nlen, stbtt_int32 target_id, stbtt_int32 next_id)
4846 {
4847    stbtt_int32 i;
4848    stbtt_int32 count = ttUSHORT(fc+nm+2);
4849    stbtt_int32 stringOffset = nm + ttUSHORT(fc+nm+4);
4850 
4851    for (i=0; i < count; ++i) {
4852       stbtt_uint32 loc = nm + 6 + 12 * i;
4853       stbtt_int32 id = ttUSHORT(fc+loc+6);
4854       if (id == target_id) {
4855          // find the encoding
4856          stbtt_int32 platform = ttUSHORT(fc+loc+0), encoding = ttUSHORT(fc+loc+2), language = ttUSHORT(fc+loc+4);
4857 
4858          // is this a Unicode encoding?
4859          if (platform == 0 || (platform == 3 && encoding == 1) || (platform == 3 && encoding == 10)) {
4860             stbtt_int32 slen = ttUSHORT(fc+loc+8);
4861             stbtt_int32 off = ttUSHORT(fc+loc+10);
4862 
4863             // check if there's a prefix match
4864             stbtt_int32 matchlen = stbtt__CompareUTF8toUTF16_bigendian_prefix(name, nlen, fc+stringOffset+off,slen);
4865             if (matchlen >= 0) {
4866                // check for target_id+1 immediately following, with same encoding & language
4867                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) {
4868                   slen = ttUSHORT(fc+loc+12+8);
4869                   off = ttUSHORT(fc+loc+12+10);
4870                   if (slen == 0) {
4871                      if (matchlen == nlen)
4872                         return 1;
4873                   } else if (matchlen < nlen && name[matchlen] == ' ') {
4874                      ++matchlen;
4875                      if (stbtt_CompareUTF8toUTF16_bigendian_internal((char*) (name+matchlen), nlen-matchlen, (char*)(fc+stringOffset+off),slen))
4876                         return 1;
4877                   }
4878                } else {
4879                   // if nothing immediately following
4880                   if (matchlen == nlen)
4881                      return 1;
4882                }
4883             }
4884          }
4885 
4886          // @TODO handle other encodings
4887       }
4888    }
4889    return 0;
4890 }
4891 
4892 static int stbtt__matches(stbtt_uint8 *fc, stbtt_uint32 offset, stbtt_uint8 *name, stbtt_int32 flags)
4893 {
4894    stbtt_int32 nlen = (stbtt_int32) STBTT_strlen((char *) name);
4895    stbtt_uint32 nm,hd;
4896    if (!stbtt__isfont(fc+offset)) return 0;
4897 
4898    // check italics/bold/underline flags in macStyle...
4899    if (flags) {
4900       hd = stbtt__find_table(fc, offset, "head");
4901       if ((ttUSHORT(fc+hd+44) & 7) != (flags & 7)) return 0;
4902    }
4903 
4904    nm = stbtt__find_table(fc, offset, "name");
4905    if (!nm) return 0;
4906 
4907    if (flags) {
4908       // if we checked the macStyle flags, then just check the family and ignore the subfamily
4909       if (stbtt__matchpair(fc, nm, name, nlen, 16, -1))  return 1;
4910       if (stbtt__matchpair(fc, nm, name, nlen,  1, -1))  return 1;
4911       if (stbtt__matchpair(fc, nm, name, nlen,  3, -1))  return 1;
4912    } else {
4913       if (stbtt__matchpair(fc, nm, name, nlen, 16, 17))  return 1;
4914       if (stbtt__matchpair(fc, nm, name, nlen,  1,  2))  return 1;
4915       if (stbtt__matchpair(fc, nm, name, nlen,  3, -1))  return 1;
4916    }
4917 
4918    return 0;
4919 }
4920 
4921 static int stbtt_FindMatchingFont_internal(unsigned char *font_collection, char *name_utf8, stbtt_int32 flags)
4922 {
4923    stbtt_int32 i;
4924    for (i=0;;++i) {
4925       stbtt_int32 off = stbtt_GetFontOffsetForIndex(font_collection, i);
4926       if (off < 0) return off;
4927       if (stbtt__matches((stbtt_uint8 *) font_collection, off, (stbtt_uint8*) name_utf8, flags))
4928          return off;
4929    }
4930 }
4931 
4932 #if defined(__GNUC__) || defined(__clang__)
4933 #pragma GCC diagnostic push
4934 #pragma GCC diagnostic ignored "-Wcast-qual"
4935 #endif
4936 
4937 STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset,
4938                                 float pixel_height, unsigned char *pixels, int pw, int ph,
4939                                 int first_char, int num_chars, stbtt_bakedchar *chardata)
4940 {
4941    return stbtt_BakeFontBitmap_internal((unsigned char *) data, offset, pixel_height, pixels, pw, ph, first_char, num_chars, chardata);
4942 }
4943 
4944 STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index)
4945 {
4946    return stbtt_GetFontOffsetForIndex_internal((unsigned char *) data, index);
4947 }
4948 
4949 STBTT_DEF int stbtt_GetNumberOfFonts(const unsigned char *data)
4950 {
4951    return stbtt_GetNumberOfFonts_internal((unsigned char *) data);
4952 }
4953 
4954 STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset)
4955 {
4956    return stbtt_InitFont_internal(info, (unsigned char *) data, offset);
4957 }
4958 
4959 STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *fontdata, const char *name, int flags)
4960 {
4961    return stbtt_FindMatchingFont_internal((unsigned char *) fontdata, (char *) name, flags);
4962 }
4963 
4964 STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2)
4965 {
4966    return stbtt_CompareUTF8toUTF16_bigendian_internal((char *) s1, len1, (char *) s2, len2);
4967 }
4968 
4969 #if defined(__GNUC__) || defined(__clang__)
4970 #pragma GCC diagnostic pop
4971 #endif
4972 
4973 #endif // STB_TRUETYPE_IMPLEMENTATION
4974 
4975 
4976 // FULL VERSION HISTORY
4977 //
4978 //   1.25 (2021-07-11) many fixes
4979 //   1.24 (2020-02-05) fix warning
4980 //   1.23 (2020-02-02) query SVG data for glyphs; query whole kerning table (but only kern not GPOS)
4981 //   1.22 (2019-08-11) minimize missing-glyph duplication; fix kerning if both 'GPOS' and 'kern' are defined
4982 //   1.21 (2019-02-25) fix warning
4983 //   1.20 (2019-02-07) PackFontRange skips missing codepoints; GetScaleFontVMetrics()
4984 //   1.19 (2018-02-11) OpenType GPOS kerning (horizontal only), STBTT_fmod
4985 //   1.18 (2018-01-29) add missing function
4986 //   1.17 (2017-07-23) make more arguments const; doc fix
4987 //   1.16 (2017-07-12) SDF support
4988 //   1.15 (2017-03-03) make more arguments const
4989 //   1.14 (2017-01-16) num-fonts-in-TTC function
4990 //   1.13 (2017-01-02) support OpenType fonts, certain Apple fonts
4991 //   1.12 (2016-10-25) suppress warnings about casting away const with -Wcast-qual
4992 //   1.11 (2016-04-02) fix unused-variable warning
4993 //   1.10 (2016-04-02) allow user-defined fabs() replacement
4994 //                     fix memory leak if fontsize=0.0
4995 //                     fix warning from duplicate typedef
4996 //   1.09 (2016-01-16) warning fix; avoid crash on outofmem; use alloc userdata for PackFontRanges
4997 //   1.08 (2015-09-13) document stbtt_Rasterize(); fixes for vertical & horizontal edges
4998 //   1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints;
4999 //                     allow PackFontRanges to pack and render in separate phases;
5000 //                     fix stbtt_GetFontOFfsetForIndex (never worked for non-0 input?);
5001 //                     fixed an assert() bug in the new rasterizer
5002 //                     replace assert() with STBTT_assert() in new rasterizer
5003 //   1.06 (2015-07-14) performance improvements (~35% faster on x86 and x64 on test machine)
5004 //                     also more precise AA rasterizer, except if shapes overlap
5005 //                     remove need for STBTT_sort
5006 //   1.05 (2015-04-15) fix misplaced definitions for STBTT_STATIC
5007 //   1.04 (2015-04-15) typo in example
5008 //   1.03 (2015-04-12) STBTT_STATIC, fix memory leak in new packing, various fixes
5009 //   1.02 (2014-12-10) fix various warnings & compile issues w/ stb_rect_pack, C++
5010 //   1.01 (2014-12-08) fix subpixel position when oversampling to exactly match
5011 //                        non-oversampled; STBTT_POINT_SIZE for packed case only
5012 //   1.00 (2014-12-06) add new PackBegin etc. API, w/ support for oversampling
5013 //   0.99 (2014-09-18) fix multiple bugs with subpixel rendering (ryg)
5014 //   0.9  (2014-08-07) support certain mac/iOS fonts without an MS platformID
5015 //   0.8b (2014-07-07) fix a warning
5016 //   0.8  (2014-05-25) fix a few more warnings
5017 //   0.7  (2013-09-25) bugfix: subpixel glyph bug fixed in 0.5 had come back
5018 //   0.6c (2012-07-24) improve documentation
5019 //   0.6b (2012-07-20) fix a few more warnings
5020 //   0.6  (2012-07-17) fix warnings; added stbtt_ScaleForMappingEmToPixels,
5021 //                        stbtt_GetFontBoundingBox, stbtt_IsGlyphEmpty
5022 //   0.5  (2011-12-09) bugfixes:
5023 //                        subpixel glyph renderer computed wrong bounding box
5024 //                        first vertex of shape can be off-curve (FreeSans)
5025 //   0.4b (2011-12-03) fixed an error in the font baking example
5026 //   0.4  (2011-12-01) kerning, subpixel rendering (tor)
5027 //                    bugfixes for:
5028 //                        codepoint-to-glyph conversion using table fmt=12
5029 //                        codepoint-to-glyph conversion using table fmt=4
5030 //                        stbtt_GetBakedQuad with non-square texture (Zer)
5031 //                    updated Hello World! sample to use kerning and subpixel
5032 //                    fixed some warnings
5033 //   0.3  (2009-06-24) cmap fmt=12, compound shapes (MM)
5034 //                    userdata, malloc-from-userdata, non-zero fill (stb)
5035 //   0.2  (2009-03-11) Fix unsigned/signed char warnings
5036 //   0.1  (2009-03-09) First public release
5037 //
5038 
5039 /*
5040 ------------------------------------------------------------------------------
5041 This software is available under 2 licenses -- choose whichever you prefer.
5042 ------------------------------------------------------------------------------
5043 ALTERNATIVE A - MIT License
5044 Copyright (c) 2017 Sean Barrett
5045 Permission is hereby granted, free of charge, to any person obtaining a copy of
5046 this software and associated documentation files (the "Software"), to deal in
5047 the Software without restriction, including without limitation the rights to
5048 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
5049 of the Software, and to permit persons to whom the Software is furnished to do
5050 so, subject to the following conditions:
5051 The above copyright notice and this permission notice shall be included in all
5052 copies or substantial portions of the Software.
5053 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
5054 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
5055 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
5056 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
5057 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
5058 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
5059 SOFTWARE.
5060 ------------------------------------------------------------------------------
5061 ALTERNATIVE B - Public Domain (www.unlicense.org)
5062 This is free and unencumbered software released into the public domain.
5063 Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
5064 software, either in source code form or as a compiled binary, for any purpose,
5065 commercial or non-commercial, and by any means.
5066 In jurisdictions that recognize copyright laws, the author or authors of this
5067 software dedicate any and all copyright interest in the software to the public
5068 domain. We make this dedication for the benefit of the public at large and to
5069 the detriment of our heirs and successors. We intend this dedication to be an
5070 overt act of relinquishment in perpetuity of all present and future rights to
5071 this software under copyright law.
5072 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
5073 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
5074 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
5075 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
5076 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
5077 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
5078 ------------------------------------------------------------------------------
5079 */