github.com/Konstantin8105/c4go@v0.0.0-20240505174241-768bb1c65a51/tests/raylib/external/stb_truetype.h (about)

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