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


mvsim
Author(s):
autogenerated on Wed May 28 2025 02:13:08