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