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