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
281unsigned char ttf_buffer[1<<20];
282unsigned char temp_bitmap[512*512];
283
284stbtt_bakedchar cdata[96]; // ASCII 32..126 is 95 glyphs
285GLuint ftex;
286
287void 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
299void 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
332char ttf_buffer[1<<25];
333
334int 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
372char buffer[24<<20];
373unsigned char screen[20][79];
374
375int 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 <memory.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
509extern "C" {
510#endif
511
512// private structure
513typedef 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
527typedef struct
528{
529   unsigned short x0,y0,x1,y1; // coordinates of bbox in bitmap
530   float xoff,yoff,xadvance;
531} stbtt_bakedchar;
532
533STBTT_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
543typedef struct
544{
545   float x0,y0,s0,t0; // top-left
546   float x1,y1,s1,t1; // bottom-right
547} stbtt_aligned_quad;
548
549STBTT_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
564STBTT_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
575typedef 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
582typedef struct stbtt_pack_context stbtt_pack_context;
583typedef struct stbtt_fontinfo stbtt_fontinfo;
584#ifndef STB_RECT_PACK_VERSION
585typedef struct stbrp_rect stbrp_rect;
586#endif
587
588STBTT_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
599STBTT_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
604STBTT_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
619typedef 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
629STBTT_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
635STBTT_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
651STBTT_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
657STBTT_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
663STBTT_DEF int  stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects);
664STBTT_DEF void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect *rects, int num_rects);
665STBTT_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.
678struct 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
697STBTT_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
704STBTT_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.
713struct 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
733STBTT_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
745STBTT_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
758STBTT_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
766STBTT_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
771STBTT_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
779STBTT_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
785STBTT_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
788STBTT_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
793STBTT_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
796STBTT_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
799STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing);
800STBTT_DEF int  stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2);
801STBTT_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
804typedef struct stbtt_kerningentry
805{
806   int glyph1; // use stbtt_FindGlyphIndex
807   int glyph2;
808   int advance;
809} stbtt_kerningentry;
810
811STBTT_DEF int  stbtt_GetKerningTableLength(const stbtt_fontinfo *info);
812STBTT_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
842STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index);
843// returns non-zero if nothing is drawn for this glyph
844
845STBTT_DEF int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices);
846STBTT_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
857STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices);
858// frees the data allocated above
859
860STBTT_DEF unsigned char *stbtt_FindSVGDoc(const stbtt_fontinfo *info, int gl);
861STBTT_DEF int stbtt_GetCodepointSVG(const stbtt_fontinfo *info, int unicode_codepoint, const char **svg);
862STBTT_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
871STBTT_DEF void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata);
872// frees the bitmap allocated below
873
874STBTT_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
883STBTT_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
887STBTT_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
893STBTT_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
897STBTT_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
901STBTT_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
908STBTT_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)
914STBTT_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);
915STBTT_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);
916STBTT_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);
917STBTT_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);
918STBTT_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);
919STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1);
920STBTT_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
924typedef 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
931STBTT_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
945STBTT_DEF void stbtt_FreeSDF(unsigned char *bitmap, void *userdata);
946// frees the SDF bitmap allocated below
947
948STBTT_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);
949STBTT_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
1021STBTT_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
1032STBTT_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
1036STBTT_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
1044enum { // 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
1051enum { // 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
1059enum { // 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
1066enum { // 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
1073enum { // 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
1083enum { // 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
1116typedef 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
1133static 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
1140static 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
1147static 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
1153static void stbtt__buf_skip(stbtt__buf *b, int o)
1154{
1155   stbtt__buf_seek(b, b->cursor + o);
1156}
1157
1158static 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
1168static 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
1181static 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
1190static 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
1204static 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
1216static 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
1231static 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
1246static 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
1254static int stbtt__cff_index_count(stbtt__buf *b)
1255{
1256   stbtt__buf_seek(b, 0);
1257   return stbtt__buf_get16(b);
1258}
1259
1260static 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
1286static stbtt_uint16 ttUSHORT(stbtt_uint8 *p) { return p[0]*256 + p[1]; }
1287static stbtt_int16 ttSHORT(stbtt_uint8 *p)   { return p[0]*256 + p[1]; }
1288static stbtt_uint32 ttULONG(stbtt_uint8 *p)  { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; }
1289static 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
1294static 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
1306static 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
1319static 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
1338static 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
1354static 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
1368static 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
1383static 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
1496STBTT_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
1589STBTT_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
1594static 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
1603static 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
1623static int stbtt__GetGlyphInfoT2(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1);
1624
1625STBTT_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
1641STBTT_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
1646STBTT_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
1658static 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
1674static 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
1897typedef 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
1911static 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
1920static 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
1936static 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
1942static 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
1950static 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
1957static 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
1968static 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
1982static 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
2010static 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
2269static 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
2286static 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
2297STBTT_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
2305STBTT_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
2317STBTT_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
2332STBTT_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
2359static 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
2389static 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
2447static 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
2496static 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
2610STBTT_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
2622STBTT_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
2629STBTT_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
2634STBTT_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
2641STBTT_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
2652STBTT_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
2660STBTT_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
2666STBTT_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
2672STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *v)
2673{
2674   STBTT_free(v, info->userdata);
2675}
2676
2677STBTT_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
2694STBTT_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
2711STBTT_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
2721STBTT_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
2739STBTT_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
2744STBTT_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
2749STBTT_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
2758typedef struct stbtt__hheap_chunk
2759{
2760   struct stbtt__hheap_chunk *next;
2761} stbtt__hheap_chunk;
2762
2763typedef 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
2770static 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
2791static void stbtt__hheap_free(stbtt__hheap *hh, void *p)
2792{
2793   *(void **) p = hh->first_free;
2794   hh->first_free = p;
2795}
2796
2797static 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
2807typedef struct stbtt__edge {
2808   float x0,y0, x1,y1;
2809   int invert;
2810} stbtt__edge;
2811
2812
2813typedef 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
2835static 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
2857static 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
2882static 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
2924static 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)
3028static 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
3065static 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
3072static 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
3077static float stbtt__sized_triangle_area(float height, float width)
3078{
3079   return height * width / 2;
3080}
3081
3082static 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
3297static 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
3399static 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
3417static 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
3479static 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
3485typedef struct
3486{
3487   float x,y;
3488} stbtt__point;
3489
3490static 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
3547static 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
3555static 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
3575static 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
3618static 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;
3687error:
3688   STBTT_free(points, userdata);
3689   STBTT_free(*contour_lengths, userdata);
3690   *contour_lengths = 0;
3691   *num_contours = 0;
3692   return NULL;
3693}
3694
3695STBTT_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
3708STBTT_DEF void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata)
3709{
3710   STBTT_free(bitmap, userdata);
3711}
3712
3713STBTT_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
3753STBTT_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
3758STBTT_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
3777STBTT_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
3782STBTT_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
3787STBTT_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
3792STBTT_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
3797STBTT_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
3802STBTT_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
3813static 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
3859STBTT_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
3887typedef 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
3900typedef struct
3901{
3902   int width,height;
3903   int x,y,bottom_y;
3904} stbrp_context;
3905
3906typedef struct
3907{
3908   unsigned char x;
3909} stbrp_node;
3910
3911struct stbrp_rect
3912{
3913   stbrp_coord x,y;
3914   int id,w,h,was_packed;
3915};
3916
3917static 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
3928static 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
3957STBTT_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
3989STBTT_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
3995STBTT_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
4005STBTT_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
4012static 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
4074static 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
4136static 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
4149STBTT_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
4184STBTT_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
4208STBTT_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
4297STBTT_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
4302STBTT_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
4338STBTT_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
4350STBTT_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
4363STBTT_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
4398static 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
4462static int equal(float *a, float *b)
4463{
4464   return (a[0] == b[0] && a[1] == b[1]);
4465}
4466
4467static 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
4535static 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
4544static 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
4575STBTT_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
4760STBTT_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
4765STBTT_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
4776static 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
4815static 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
4822STBTT_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
4843static 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
4890static 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
4919static 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
4935STBTT_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
4942STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index)
4943{
4944   return stbtt_GetFontOffsetForIndex_internal((unsigned char *) data, index);
4945}
4946
4947STBTT_DEF int stbtt_GetNumberOfFonts(const unsigned char *data)
4948{
4949   return stbtt_GetNumberOfFonts_internal((unsigned char *) data);
4950}
4951
4952STBTT_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
4957STBTT_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
4962STBTT_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------------------------------------------------------------------------------
5039This software is available under 2 licenses -- choose whichever you prefer.
5040------------------------------------------------------------------------------
5041ALTERNATIVE A - MIT License
5042Copyright (c) 2017 Sean Barrett
5043Permission is hereby granted, free of charge, to any person obtaining a copy of
5044this software and associated documentation files (the "Software"), to deal in
5045the Software without restriction, including without limitation the rights to
5046use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
5047of the Software, and to permit persons to whom the Software is furnished to do
5048so, subject to the following conditions:
5049The above copyright notice and this permission notice shall be included in all
5050copies or substantial portions of the Software.
5051THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
5052IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
5053FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
5054AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
5055LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
5056OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
5057SOFTWARE.
5058------------------------------------------------------------------------------
5059ALTERNATIVE B - Public Domain (www.unlicense.org)
5060This is free and unencumbered software released into the public domain.
5061Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
5062software, either in source code form or as a compiled binary, for any purpose,
5063commercial or non-commercial, and by any means.
5064In jurisdictions that recognize copyright laws, the author or authors of this
5065software dedicate any and all copyright interest in the software to the public
5066domain. We make this dedication for the benefit of the public at large and to
5067the detriment of our heirs and successors. We intend this dedication to be an
5068overt act of relinquishment in perpetuity of all present and future rights to
5069this software under copyright law.
5070THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
5071IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
5072FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
5073AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
5074ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
5075WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
5076------------------------------------------------------------------------------
5077*/
5078