VR-Forces Developer's Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
stb_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);
290  glBindTexture(GL_TEXTURE_2D, 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
293  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
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
299  glEnable(GL_TEXTURE_2D);
300  glBindTexture(GL_TEXTURE_2D, ftex);
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 
569 {
570  unsigned short x0,y0,x1,y1; // coordinates of bbox in bitmap
572  float xoff2,yoff2;
573 } ;
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 #pragma warning( push )
2411 #pragma warning( disable : 4189)
2412 
2413 static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2)
2414 {
2415  stbtt_uint16 lookupListOffset;
2416  stbtt_uint8 *lookupList;
2417  stbtt_uint16 lookupCount;
2418  stbtt_uint8 *data;
2419  stbtt_int32 i;
2420 
2421  if (!info->gpos) return 0;
2422 
2423  data = info->data + info->gpos;
2424 
2425  if (ttUSHORT(data+0) != 1) return 0; // Major version 1
2426  if (ttUSHORT(data+2) != 0) return 0; // Minor version 0
2427 
2428  lookupListOffset = ttUSHORT(data+8);
2429  lookupList = data + lookupListOffset;
2430  lookupCount = ttUSHORT(lookupList);
2431 
2432  for (i=0; i<lookupCount; ++i) {
2433  stbtt_uint16 lookupOffset = ttUSHORT(lookupList + 2 + 2 * i);
2434  stbtt_uint8 *lookupTable = lookupList + lookupOffset;
2435 
2436  stbtt_uint16 lookupType = ttUSHORT(lookupTable);
2437  stbtt_uint16 subTableCount = ttUSHORT(lookupTable + 4);
2438  stbtt_uint8 *subTableOffsets = lookupTable + 6;
2439  switch(lookupType) {
2440  case 2: { // Pair Adjustment Positioning Subtable
2441  stbtt_int32 sti;
2442  for (sti=0; sti<subTableCount; sti++) {
2443  stbtt_uint16 subtableOffset = ttUSHORT(subTableOffsets + 2 * sti);
2444  stbtt_uint8 *table = lookupTable + subtableOffset;
2445  stbtt_uint16 posFormat = ttUSHORT(table);
2446  stbtt_uint16 coverageOffset = ttUSHORT(table + 2);
2447  stbtt_int32 coverageIndex = stbtt__GetCoverageIndex(table + coverageOffset, glyph1);
2448  if (coverageIndex == -1) continue;
2449 
2450  switch (posFormat) {
2451  case 1: {
2452  stbtt_int32 l, r, m;
2453  int straw, needle;
2454  stbtt_uint16 valueFormat1 = ttUSHORT(table + 4);
2455  stbtt_uint16 valueFormat2 = ttUSHORT(table + 6);
2456  stbtt_int32 valueRecordPairSizeInBytes = 2;
2457  stbtt_uint16 pairSetCount = ttUSHORT(table + 8);
2458  stbtt_uint16 pairPosOffset = ttUSHORT(table + 10 + 2 * coverageIndex);
2459  stbtt_uint8 *pairValueTable = table + pairPosOffset;
2460  stbtt_uint16 pairValueCount = ttUSHORT(pairValueTable);
2461  stbtt_uint8 *pairValueArray = pairValueTable + 2;
2462  // TODO: Support more formats.
2463  STBTT_GPOS_TODO_assert(valueFormat1 == 4);
2464  if (valueFormat1 != 4) return 0;
2465  STBTT_GPOS_TODO_assert(valueFormat2 == 0);
2466  if (valueFormat2 != 0) return 0;
2467 
2468  STBTT_assert(coverageIndex < pairSetCount);
2469 
2470  needle=glyph2;
2471  r=pairValueCount-1;
2472  l=0;
2473 
2474  // Binary search.
2475  while (l <= r) {
2476  stbtt_uint16 secondGlyph;
2477  stbtt_uint8 *pairValue;
2478  m = (l + r) >> 1;
2479  pairValue = pairValueArray + (2 + valueRecordPairSizeInBytes) * m;
2480  secondGlyph = ttUSHORT(pairValue);
2481  straw = secondGlyph;
2482  if (needle < straw)
2483  r = m - 1;
2484  else if (needle > straw)
2485  l = m + 1;
2486  else {
2487  stbtt_int16 xAdvance = ttSHORT(pairValue + 2);
2488  return xAdvance;
2489  }
2490  }
2491  } break;
2492 
2493  case 2: {
2494  stbtt_uint16 valueFormat1 = ttUSHORT(table + 4);
2495  stbtt_uint16 valueFormat2 = ttUSHORT(table + 6);
2496 
2497  stbtt_uint16 classDef1Offset = ttUSHORT(table + 8);
2498  stbtt_uint16 classDef2Offset = ttUSHORT(table + 10);
2499  int glyph1class = stbtt__GetGlyphClass(table + classDef1Offset, glyph1);
2500  int glyph2class = stbtt__GetGlyphClass(table + classDef2Offset, glyph2);
2501 
2502  stbtt_uint16 class1Count = ttUSHORT(table + 12);
2503  stbtt_uint16 class2Count = ttUSHORT(table + 14);
2504  STBTT_assert(glyph1class < class1Count);
2505  STBTT_assert(glyph2class < class2Count);
2506 
2507  // TODO: Support more formats.
2508  STBTT_GPOS_TODO_assert(valueFormat1 == 4);
2509  if (valueFormat1 != 4) return 0;
2510  STBTT_GPOS_TODO_assert(valueFormat2 == 0);
2511  if (valueFormat2 != 0) return 0;
2512 
2513  if (glyph1class >= 0 && glyph1class < class1Count && glyph2class >= 0 && glyph2class < class2Count) {
2514  stbtt_uint8 *class1Records = table + 16;
2515  stbtt_uint8 *class2Records = class1Records + 2 * (glyph1class * class2Count);
2516  stbtt_int16 xAdvance = ttSHORT(class2Records + 2 * glyph2class);
2517  return xAdvance;
2518  }
2519  } break;
2520 
2521  default: {
2522  // There are no other cases.
2523  STBTT_assert(0);
2524  break;
2525  };
2526  }
2527  }
2528  break;
2529  };
2530 
2531  default:
2532  // TODO: Implement other stuff.
2533  break;
2534  }
2535  }
2536 
2537  return 0;
2538 }
2539 
2540 #pragma warning( pop )
2541 
2542 STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int g1, int g2)
2543 {
2544  int xAdvance = 0;
2545 
2546  if (info->gpos)
2547  xAdvance += stbtt__GetGlyphGPOSInfoAdvance(info, g1, g2);
2548 
2549  if (info->kern)
2550  xAdvance += stbtt__GetGlyphKernInfoAdvance(info, g1, g2);
2551 
2552  return xAdvance;
2553 }
2554 
2555 STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2)
2556 {
2557  if (!info->kern && !info->gpos) // if no kerning table, don't waste time looking up both codepoint->glyphs
2558  return 0;
2559  return stbtt_GetGlyphKernAdvance(info, stbtt_FindGlyphIndex(info,ch1), stbtt_FindGlyphIndex(info,ch2));
2560 }
2561 
2562 STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing)
2563 {
2564  stbtt_GetGlyphHMetrics(info, stbtt_FindGlyphIndex(info,codepoint), advanceWidth, leftSideBearing);
2565 }
2566 
2567 STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap)
2568 {
2569  if (ascent ) *ascent = ttSHORT(info->data+info->hhea + 4);
2570  if (descent) *descent = ttSHORT(info->data+info->hhea + 6);
2571  if (lineGap) *lineGap = ttSHORT(info->data+info->hhea + 8);
2572 }
2573 
2574 STBTT_DEF int stbtt_GetFontVMetricsOS2(const stbtt_fontinfo *info, int *typoAscent, int *typoDescent, int *typoLineGap)
2575 {
2576  int tab = stbtt__find_table(info->data, info->fontstart, "OS/2");
2577  if (!tab)
2578  return 0;
2579  if (typoAscent ) *typoAscent = ttSHORT(info->data+tab + 68);
2580  if (typoDescent) *typoDescent = ttSHORT(info->data+tab + 70);
2581  if (typoLineGap) *typoLineGap = ttSHORT(info->data+tab + 72);
2582  return 1;
2583 }
2584 
2585 STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1)
2586 {
2587  *x0 = ttSHORT(info->data + info->head + 36);
2588  *y0 = ttSHORT(info->data + info->head + 38);
2589  *x1 = ttSHORT(info->data + info->head + 40);
2590  *y1 = ttSHORT(info->data + info->head + 42);
2591 }
2592 
2593 STBTT_DEF float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float height)
2594 {
2595  int fheight = ttSHORT(info->data + info->hhea + 4) - ttSHORT(info->data + info->hhea + 6);
2596  return (float) height / fheight;
2597 }
2598 
2599 STBTT_DEF float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels)
2600 {
2601  int unitsPerEm = ttUSHORT(info->data + info->head + 18);
2602  return pixels / unitsPerEm;
2603 }
2604 
2606 {
2607  STBTT_free(v, info->userdata);
2608 }
2609 
2611 //
2612 // antialiasing software rasterizer
2613 //
2614 
2615 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)
2616 {
2617  int x0=0,y0=0,x1,y1; // =0 suppresses compiler warning
2618  if (!stbtt_GetGlyphBox(font, glyph, &x0,&y0,&x1,&y1)) {
2619  // e.g. space character
2620  if (ix0) *ix0 = 0;
2621  if (iy0) *iy0 = 0;
2622  if (ix1) *ix1 = 0;
2623  if (iy1) *iy1 = 0;
2624  } else {
2625  // move to integral bboxes (treating pixels as little squares, what pixels get touched)?
2626  if (ix0) *ix0 = STBTT_ifloor( x0 * scale_x + shift_x);
2627  if (iy0) *iy0 = STBTT_ifloor(-y1 * scale_y + shift_y);
2628  if (ix1) *ix1 = STBTT_iceil ( x1 * scale_x + shift_x);
2629  if (iy1) *iy1 = STBTT_iceil (-y0 * scale_y + shift_y);
2630  }
2631 }
2632 
2633 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)
2634 {
2635  stbtt_GetGlyphBitmapBoxSubpixel(font, glyph, scale_x, scale_y,0.0f,0.0f, ix0, iy0, ix1, iy1);
2636 }
2637 
2638 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)
2639 {
2640  stbtt_GetGlyphBitmapBoxSubpixel(font, stbtt_FindGlyphIndex(font,codepoint), scale_x, scale_y,shift_x,shift_y, ix0,iy0,ix1,iy1);
2641 }
2642 
2643 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)
2644 {
2645  stbtt_GetCodepointBitmapBoxSubpixel(font, codepoint, scale_x, scale_y,0.0f,0.0f, ix0,iy0,ix1,iy1);
2646 }
2647 
2649 //
2650 // Rasterizer
2651 
2652 typedef struct stbtt__hheap_chunk
2653 {
2654  struct stbtt__hheap_chunk *next;
2655 } stbtt__hheap_chunk;
2656 
2657 typedef struct stbtt__hheap
2658 {
2659  struct stbtt__hheap_chunk *head;
2660  void *first_free;
2661  int num_remaining_in_head_chunk;
2662 } stbtt__hheap;
2663 
2664 static void *stbtt__hheap_alloc(stbtt__hheap *hh, size_t size, void *userdata)
2665 {
2666  if (hh->first_free) {
2667  void *p = hh->first_free;
2668  hh->first_free = * (void **) p;
2669  return p;
2670  } else {
2671  if (hh->num_remaining_in_head_chunk == 0) {
2672  int count = (size < 32 ? 2000 : size < 128 ? 800 : 100);
2673  stbtt__hheap_chunk *c = (stbtt__hheap_chunk *) STBTT_malloc(sizeof(stbtt__hheap_chunk) + size * count, userdata);
2674  if (c == NULL)
2675  return NULL;
2676  c->next = hh->head;
2677  hh->head = c;
2678  hh->num_remaining_in_head_chunk = count;
2679  }
2680  --hh->num_remaining_in_head_chunk;
2681  return (char *) (hh->head) + sizeof(stbtt__hheap_chunk) + size * hh->num_remaining_in_head_chunk;
2682  }
2683 }
2684 
2685 static void stbtt__hheap_free(stbtt__hheap *hh, void *p)
2686 {
2687  *(void **) p = hh->first_free;
2688  hh->first_free = p;
2689 }
2690 
2691 static void stbtt__hheap_cleanup(stbtt__hheap *hh, void *userdata)
2692 {
2693  stbtt__hheap_chunk *c = hh->head;
2694  while (c) {
2695  stbtt__hheap_chunk *n = c->next;
2696  STBTT_free(c, userdata);
2697  c = n;
2698  }
2699 }
2700 
2701 typedef struct stbtt__edge {
2702  float x0,y0, x1,y1;
2703  int invert;
2704 } stbtt__edge;
2705 
2706 
2707 typedef struct stbtt__active_edge
2708 {
2709  struct stbtt__active_edge *next;
2710  #if STBTT_RASTERIZER_VERSION==1
2711  int x,dx;
2712  float ey;
2713  int direction;
2714  #elif STBTT_RASTERIZER_VERSION==2
2715  float fx,fdx,fdy;
2716  float direction;
2717  float sy;
2718  float ey;
2719  #else
2720  #error "Unrecognized value of STBTT_RASTERIZER_VERSION"
2721  #endif
2722 } stbtt__active_edge;
2723 
2724 #if STBTT_RASTERIZER_VERSION == 1
2725 #define STBTT_FIXSHIFT 10
2726 #define STBTT_FIX (1 << STBTT_FIXSHIFT)
2727 #define STBTT_FIXMASK (STBTT_FIX-1)
2728 
2729 static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, int off_x, float start_point, void *userdata)
2730 {
2731  stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh, sizeof(*z), userdata);
2732  float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
2733  STBTT_assert(z != NULL);
2734  if (!z) return z;
2735 
2736  // round dx down to avoid overshooting
2737  if (dxdy < 0)
2738  z->dx = -STBTT_ifloor(STBTT_FIX * -dxdy);
2739  else
2740  z->dx = STBTT_ifloor(STBTT_FIX * dxdy);
2741 
2742  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
2743  z->x -= off_x * STBTT_FIX;
2744 
2745  z->ey = e->y1;
2746  z->next = 0;
2747  z->direction = e->invert ? 1 : -1;
2748  return z;
2749 }
2750 #elif STBTT_RASTERIZER_VERSION == 2
2751 static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, int off_x, float start_point, void *userdata)
2752 {
2753  stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh, sizeof(*z), userdata);
2754  float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
2755  STBTT_assert(z != NULL);
2756  //STBTT_assert(e->y0 <= start_point);
2757  if (!z) return z;
2758  z->fdx = dxdy;
2759  z->fdy = dxdy != 0.0f ? (1.0f/dxdy) : 0.0f;
2760  z->fx = e->x0 + dxdy * (start_point - e->y0);
2761  z->fx -= off_x;
2762  z->direction = e->invert ? 1.0f : -1.0f;
2763  z->sy = e->y0;
2764  z->ey = e->y1;
2765  z->next = 0;
2766  return z;
2767 }
2768 #else
2769 #error "Unrecognized value of STBTT_RASTERIZER_VERSION"
2770 #endif
2771 
2772 #if STBTT_RASTERIZER_VERSION == 1
2773 // note: this routine clips fills that extend off the edges... ideally this
2774 // wouldn't happen, but it could happen if the truetype glyph bounding boxes
2775 // are wrong, or if the user supplies a too-small bitmap
2776 static void stbtt__fill_active_edges(unsigned char *scanline, int len, stbtt__active_edge *e, int max_weight)
2777 {
2778  // non-zero winding fill
2779  int x0=0, w=0;
2780 
2781  while (e) {
2782  if (w == 0) {
2783  // if we're currently at zero, we need to record the edge start point
2784  x0 = e->x; w += e->direction;
2785  } else {
2786  int x1 = e->x; w += e->direction;
2787  // if we went to zero, we need to draw
2788  if (w == 0) {
2789  int i = x0 >> STBTT_FIXSHIFT;
2790  int j = x1 >> STBTT_FIXSHIFT;
2791 
2792  if (i < len && j >= 0) {
2793  if (i == j) {
2794  // x0,x1 are the same pixel, so compute combined coverage
2795  scanline[i] = scanline[i] + (stbtt_uint8) ((x1 - x0) * max_weight >> STBTT_FIXSHIFT);
2796  } else {
2797  if (i >= 0) // add antialiasing for x0
2798  scanline[i] = scanline[i] + (stbtt_uint8) (((STBTT_FIX - (x0 & STBTT_FIXMASK)) * max_weight) >> STBTT_FIXSHIFT);
2799  else
2800  i = -1; // clip
2801 
2802  if (j < len) // add antialiasing for x1
2803  scanline[j] = scanline[j] + (stbtt_uint8) (((x1 & STBTT_FIXMASK) * max_weight) >> STBTT_FIXSHIFT);
2804  else
2805  j = len; // clip
2806 
2807  for (++i; i < j; ++i) // fill pixels between x0 and x1
2808  scanline[i] = scanline[i] + (stbtt_uint8) max_weight;
2809  }
2810  }
2811  }
2812  }
2813 
2814  e = e->next;
2815  }
2816 }
2817 
2818 static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata)
2819 {
2820  stbtt__hheap hh = { 0, 0, 0 };
2821  stbtt__active_edge *active = NULL;
2822  int y,j=0;
2823  int max_weight = (255 / vsubsample); // weight per vertical scanline
2824  int s; // vertical subsample index
2825  unsigned char scanline_data[512], *scanline;
2826 
2827  if (result->w > 512)
2828  scanline = (unsigned char *) STBTT_malloc(result->w, userdata);
2829  else
2830  scanline = scanline_data;
2831 
2832  y = off_y * vsubsample;
2833  e[n].y0 = (off_y + result->h) * (float) vsubsample + 1;
2834 
2835  while (j < result->h) {
2836  STBTT_memset(scanline, 0, result->w);
2837  for (s=0; s < vsubsample; ++s) {
2838  // find center of pixel for this scanline
2839  float scan_y = y + 0.5f;
2840  stbtt__active_edge **step = &active;
2841 
2842  // update all active edges;
2843  // remove all active edges that terminate before the center of this scanline
2844  while (*step) {
2845  stbtt__active_edge * z = *step;
2846  if (z->ey <= scan_y) {
2847  *step = z->next; // delete from list
2848  STBTT_assert(z->direction);
2849  z->direction = 0;
2850  stbtt__hheap_free(&hh, z);
2851  } else {
2852  z->x += z->dx; // advance to position for current scanline
2853  step = &((*step)->next); // advance through list
2854  }
2855  }
2856 
2857  // resort the list if needed
2858  for(;;) {
2859  int changed=0;
2860  step = &active;
2861  while (*step && (*step)->next) {
2862  if ((*step)->x > (*step)->next->x) {
2863  stbtt__active_edge *t = *step;
2864  stbtt__active_edge *q = t->next;
2865 
2866  t->next = q->next;
2867  q->next = t;
2868  *step = q;
2869  changed = 1;
2870  }
2871  step = &(*step)->next;
2872  }
2873  if (!changed) break;
2874  }
2875 
2876  // insert all edges that start before the center of this scanline -- omit ones that also end on this scanline
2877  while (e->y0 <= scan_y) {
2878  if (e->y1 > scan_y) {
2879  stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y, userdata);
2880  if (z != NULL) {
2881  // find insertion point
2882  if (active == NULL)
2883  active = z;
2884  else if (z->x < active->x) {
2885  // insert at front
2886  z->next = active;
2887  active = z;
2888  } else {
2889  // find thing to insert AFTER
2890  stbtt__active_edge *p = active;
2891  while (p->next && p->next->x < z->x)
2892  p = p->next;
2893  // at this point, p->next->x is NOT < z->x
2894  z->next = p->next;
2895  p->next = z;
2896  }
2897  }
2898  }
2899  ++e;
2900  }
2901 
2902  // now process all active edges in XOR fashion
2903  if (active)
2904  stbtt__fill_active_edges(scanline, result->w, active, max_weight);
2905 
2906  ++y;
2907  }
2908  STBTT_memcpy(result->pixels + j * result->stride, scanline, result->w);
2909  ++j;
2910  }
2911 
2912  stbtt__hheap_cleanup(&hh, userdata);
2913 
2914  if (scanline != scanline_data)
2915  STBTT_free(scanline, userdata);
2916 }
2917 
2918 #elif STBTT_RASTERIZER_VERSION == 2
2919 
2920 // the edge passed in here does not cross the vertical line at x or the vertical line at x+1
2921 // (i.e. it has already been clipped to those)
2922 static void stbtt__handle_clipped_edge(float *scanline, int x, stbtt__active_edge *e, float x0, float y0, float x1, float y1)
2923 {
2924  if (y0 == y1) return;
2925  STBTT_assert(y0 < y1);
2926  STBTT_assert(e->sy <= e->ey);
2927  if (y0 > e->ey) return;
2928  if (y1 < e->sy) return;
2929  if (y0 < e->sy) {
2930  x0 += (x1-x0) * (e->sy - y0) / (y1-y0);
2931  y0 = e->sy;
2932  }
2933  if (y1 > e->ey) {
2934  x1 += (x1-x0) * (e->ey - y1) / (y1-y0);
2935  y1 = e->ey;
2936  }
2937 
2938  if (x0 == x)
2939  STBTT_assert(x1 <= x+1);
2940  else if (x0 == x+1)
2941  STBTT_assert(x1 >= x);
2942  else if (x0 <= x)
2943  STBTT_assert(x1 <= x);
2944  else if (x0 >= x+1)
2945  STBTT_assert(x1 >= x+1);
2946  else
2947  STBTT_assert(x1 >= x && x1 <= x+1);
2948 
2949  if (x0 <= x && x1 <= x)
2950  scanline[x] += e->direction * (y1-y0);
2951  else if (x0 >= x+1 && x1 >= x+1)
2952  ;
2953  else {
2954  STBTT_assert(x0 >= x && x0 <= x+1 && x1 >= x && x1 <= x+1);
2955  scanline[x] += e->direction * (y1-y0) * (1-((x0-x)+(x1-x))/2); // coverage = 1 - average x position
2956  }
2957 }
2958 
2959 static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill, int len, stbtt__active_edge *e, float y_top)
2960 {
2961  float y_bottom = y_top+1;
2962 
2963  while (e) {
2964  // brute force every pixel
2965 
2966  // compute intersection points with top & bottom
2967  STBTT_assert(e->ey >= y_top);
2968 
2969  if (e->fdx == 0) {
2970  float x0 = e->fx;
2971  if (x0 < len) {
2972  if (x0 >= 0) {
2973  stbtt__handle_clipped_edge(scanline,(int) x0,e, x0,y_top, x0,y_bottom);
2974  stbtt__handle_clipped_edge(scanline_fill-1,(int) x0+1,e, x0,y_top, x0,y_bottom);
2975  } else {
2976  stbtt__handle_clipped_edge(scanline_fill-1,0,e, x0,y_top, x0,y_bottom);
2977  }
2978  }
2979  } else {
2980  float x0 = e->fx;
2981  float dx = e->fdx;
2982  float xb = x0 + dx;
2983  float x_top, x_bottom;
2984  float sy0,sy1;
2985  float dy = e->fdy;
2986  STBTT_assert(e->sy <= y_bottom && e->ey >= y_top);
2987 
2988  // compute endpoints of line segment clipped to this scanline (if the
2989  // line segment starts on this scanline. x0 is the intersection of the
2990  // line with y_top, but that may be off the line segment.
2991  if (e->sy > y_top) {
2992  x_top = x0 + dx * (e->sy - y_top);
2993  sy0 = e->sy;
2994  } else {
2995  x_top = x0;
2996  sy0 = y_top;
2997  }
2998  if (e->ey < y_bottom) {
2999  x_bottom = x0 + dx * (e->ey - y_top);
3000  sy1 = e->ey;
3001  } else {
3002  x_bottom = xb;
3003  sy1 = y_bottom;
3004  }
3005 
3006  if (x_top >= 0 && x_bottom >= 0 && x_top < len && x_bottom < len) {
3007  // from here on, we don't have to range check x values
3008 
3009  if ((int) x_top == (int) x_bottom) {
3010  float height;
3011  // simple case, only spans one pixel
3012  int x = (int) x_top;
3013  height = sy1 - sy0;
3014  STBTT_assert(x >= 0 && x < len);
3015  scanline[x] += e->direction * (1-((x_top - x) + (x_bottom-x))/2) * height;
3016  scanline_fill[x] += e->direction * height; // everything right of this pixel is filled
3017  } else {
3018  int x,x1,x2;
3019  float y_crossing, step, sign, area;
3020  // covers 2+ pixels
3021  if (x_top > x_bottom) {
3022  // flip scanline vertically; signed area is the same
3023  float t;
3024  sy0 = y_bottom - (sy0 - y_top);
3025  sy1 = y_bottom - (sy1 - y_top);
3026  t = sy0, sy0 = sy1, sy1 = t;
3027  t = x_bottom, x_bottom = x_top, x_top = t;
3028  dx = -dx;
3029  dy = -dy;
3030  t = x0, x0 = xb, xb = t;
3031  }
3032 
3033  x1 = (int) x_top;
3034  x2 = (int) x_bottom;
3035  // compute intersection with y axis at x1+1
3036  y_crossing = (x1+1 - x0) * dy + y_top;
3037 
3038  sign = e->direction;
3039  // area of the rectangle covered from y0..y_crossing
3040  area = sign * (y_crossing-sy0);
3041  // area of the triangle (x_top,y0), (x+1,y0), (x+1,y_crossing)
3042  scanline[x1] += area * (1-((x_top - x1)+(x1+1-x1))/2);
3043 
3044  step = sign * dy;
3045  for (x = x1+1; x < x2; ++x) {
3046  scanline[x] += area + step/2;
3047  area += step;
3048  }
3049  y_crossing += dy * (x2 - (x1+1));
3050 
3051  STBTT_assert(STBTT_fabs(area) <= 1.01f);
3052 
3053  scanline[x2] += area + sign * (1-((x2-x2)+(x_bottom-x2))/2) * (sy1-y_crossing);
3054 
3055  scanline_fill[x2] += sign * (sy1-sy0);
3056  }
3057  } else {
3058  // if edge goes outside of box we're drawing, we require
3059  // clipping logic. since this does not match the intended use
3060  // of this library, we use a different, very slow brute
3061  // force implementation
3062  int x;
3063  for (x=0; x < len; ++x) {
3064  // cases:
3065  //
3066  // there can be up to two intersections with the pixel. any intersection
3067  // with left or right edges can be handled by splitting into two (or three)
3068  // regions. intersections with top & bottom do not necessitate case-wise logic.
3069  //
3070  // the old way of doing this found the intersections with the left & right edges,
3071  // then used some simple logic to produce up to three segments in sorted order
3072  // from top-to-bottom. however, this had a problem: if an x edge was epsilon
3073  // across the x border, then the corresponding y position might not be distinct
3074  // from the other y segment, and it might ignored as an empty segment. to avoid
3075  // that, we need to explicitly produce segments based on x positions.
3076 
3077  // rename variables to clearly-defined pairs
3078  float y0 = y_top;
3079  float x1 = (float) (x);
3080  float x2 = (float) (x+1);
3081  float x3 = xb;
3082  float y3 = y_bottom;
3083 
3084  // x = e->x + e->dx * (y-y_top)
3085  // (y-y_top) = (x - e->x) / e->dx
3086  // y = (x - e->x) / e->dx + y_top
3087  float y1 = (x - x0) / dx + y_top;
3088  float y2 = (x+1 - x0) / dx + y_top;
3089 
3090  if (x0 < x1 && x3 > x2) { // three segments descending down-right
3091  stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1);
3092  stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x2,y2);
3093  stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3);
3094  } else if (x3 < x1 && x0 > x2) { // three segments descending down-left
3095  stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2);
3096  stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x1,y1);
3097  stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3);
3098  } else if (x0 < x1 && x3 > x1) { // two segments across x, down-right
3099  stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1);
3100  stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3);
3101  } else if (x3 < x1 && x0 > x1) { // two segments across x, down-left
3102  stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1);
3103  stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3);
3104  } else if (x0 < x2 && x3 > x2) { // two segments across x+1, down-right
3105  stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2);
3106  stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3);
3107  } else if (x3 < x2 && x0 > x2) { // two segments across x+1, down-left
3108  stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2);
3109  stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3);
3110  } else { // one segment
3111  stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x3,y3);
3112  }
3113  }
3114  }
3115  }
3116  e = e->next;
3117  }
3118 }
3119 
3120 // directly AA rasterize edges w/o supersampling
3121 static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata)
3122 {
3123  stbtt__hheap hh = { 0, 0, 0 };
3124  stbtt__active_edge *active = NULL;
3125  int y,j=0, i;
3126  float scanline_data[129], *scanline, *scanline2;
3127 
3128  STBTT__NOTUSED(vsubsample);
3129 
3130  if (result->w > 64)
3131  scanline = (float *) STBTT_malloc((result->w*2+1) * sizeof(float), userdata);
3132  else
3133  scanline = scanline_data;
3134 
3135  scanline2 = scanline + result->w;
3136 
3137  y = off_y;
3138  e[n].y0 = (float) (off_y + result->h) + 1;
3139 
3140  while (j < result->h) {
3141  // find center of pixel for this scanline
3142  float scan_y_top = y + 0.0f;
3143  float scan_y_bottom = y + 1.0f;
3144  stbtt__active_edge **step = &active;
3145 
3146  STBTT_memset(scanline , 0, result->w*sizeof(scanline[0]));
3147  STBTT_memset(scanline2, 0, (result->w+1)*sizeof(scanline[0]));
3148 
3149  // update all active edges;
3150  // remove all active edges that terminate before the top of this scanline
3151  while (*step) {
3152  stbtt__active_edge * z = *step;
3153  if (z->ey <= scan_y_top) {
3154  *step = z->next; // delete from list
3155  STBTT_assert(z->direction);
3156  z->direction = 0;
3157  stbtt__hheap_free(&hh, z);
3158  } else {
3159  step = &((*step)->next); // advance through list
3160  }
3161  }
3162 
3163  // insert all edges that start before the bottom of this scanline
3164  while (e->y0 <= scan_y_bottom) {
3165  if (e->y0 != e->y1) {
3166  stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata);
3167  if (z != NULL) {
3168  STBTT_assert(z->ey >= scan_y_top);
3169  // insert at front
3170  z->next = active;
3171  active = z;
3172  }
3173  }
3174  ++e;
3175  }
3176 
3177  // now process all active edges
3178  if (active)
3179  stbtt__fill_active_edges_new(scanline, scanline2+1, result->w, active, scan_y_top);
3180 
3181  {
3182  float sum = 0;
3183  for (i=0; i < result->w; ++i) {
3184  float k;
3185  int m;
3186  sum += scanline2[i];
3187  k = scanline[i] + sum;
3188  k = (float) STBTT_fabs(k)*255 + 0.5f;
3189  m = (int) k;
3190  if (m > 255) m = 255;
3191  result->pixels[j*result->stride + i] = (unsigned char) m;
3192  }
3193  }
3194  // advance all the edges
3195  step = &active;
3196  while (*step) {
3197  stbtt__active_edge *z = *step;
3198  z->fx += z->fdx; // advance to position for current scanline
3199  step = &((*step)->next); // advance through list
3200  }
3201 
3202  ++y;
3203  ++j;
3204  }
3205 
3206  stbtt__hheap_cleanup(&hh, userdata);
3207 
3208  if (scanline != scanline_data)
3209  STBTT_free(scanline, userdata);
3210 }
3211 #else
3212 #error "Unrecognized value of STBTT_RASTERIZER_VERSION"
3213 #endif
3214 
3215 #define STBTT__COMPARE(a,b) ((a)->y0 < (b)->y0)
3216 
3217 static void stbtt__sort_edges_ins_sort(stbtt__edge *p, int n)
3218 {
3219  int i,j;
3220  for (i=1; i < n; ++i) {
3221  stbtt__edge t = p[i], *a = &t;
3222  j = i;
3223  while (j > 0) {
3224  stbtt__edge *b = &p[j-1];
3225  int c = STBTT__COMPARE(a,b);
3226  if (!c) break;
3227  p[j] = p[j-1];
3228  --j;
3229  }
3230  if (i != j)
3231  p[j] = t;
3232  }
3233 }
3234 
3235 static void stbtt__sort_edges_quicksort(stbtt__edge *p, int n)
3236 {
3237  /* threshhold for transitioning to insertion sort */
3238  while (n > 12) {
3239  stbtt__edge t;
3240  int c01,c12,c,m,i,j;
3241 
3242  /* compute median of three */
3243  m = n >> 1;
3244  c01 = STBTT__COMPARE(&p[0],&p[m]);
3245  c12 = STBTT__COMPARE(&p[m],&p[n-1]);
3246  /* if 0 >= mid >= end, or 0 < mid < end, then use mid */
3247  if (c01 != c12) {
3248  /* otherwise, we'll need to swap something else to middle */
3249  int z;
3250  c = STBTT__COMPARE(&p[0],&p[n-1]);
3251  /* 0>mid && mid<n: 0>n => n; 0<n => 0 */
3252  /* 0<mid && mid>n: 0>n => 0; 0<n => n */
3253  z = (c == c12) ? 0 : n-1;
3254  t = p[z];
3255  p[z] = p[m];
3256  p[m] = t;
3257  }
3258  /* now p[m] is the median-of-three */
3259  /* swap it to the beginning so it won't move around */
3260  t = p[0];
3261  p[0] = p[m];
3262  p[m] = t;
3263 
3264  /* partition loop */
3265  i=1;
3266  j=n-1;
3267  for(;;) {
3268  /* handling of equality is crucial here */
3269  /* for sentinels & efficiency with duplicates */
3270  for (;;++i) {
3271  if (!STBTT__COMPARE(&p[i], &p[0])) break;
3272  }
3273  for (;;--j) {
3274  if (!STBTT__COMPARE(&p[0], &p[j])) break;
3275  }
3276  /* make sure we haven't crossed */
3277  if (i >= j) break;
3278  t = p[i];
3279  p[i] = p[j];
3280  p[j] = t;
3281 
3282  ++i;
3283  --j;
3284  }
3285  /* recurse on smaller side, iterate on larger */
3286  if (j < (n-i)) {
3287  stbtt__sort_edges_quicksort(p,j);
3288  p = p+i;
3289  n = n-i;
3290  } else {
3291  stbtt__sort_edges_quicksort(p+i, n-i);
3292  n = j;
3293  }
3294  }
3295 }
3296 
3297 static void stbtt__sort_edges(stbtt__edge *p, int n)
3298 {
3299  stbtt__sort_edges_quicksort(p, n);
3300  stbtt__sort_edges_ins_sort(p, n);
3301 }
3302 
3303 typedef struct
3304 {
3305  float x,y;
3306 } stbtt__point;
3307 
3308 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)
3309 {
3310  float y_scale_inv = invert ? -scale_y : scale_y;
3311  stbtt__edge *e;
3312  int n,i,j,k,m;
3313 #if STBTT_RASTERIZER_VERSION == 1
3314  int vsubsample = result->h < 8 ? 15 : 5;
3315 #elif STBTT_RASTERIZER_VERSION == 2
3316  int vsubsample = 1;
3317 #else
3318  #error "Unrecognized value of STBTT_RASTERIZER_VERSION"
3319 #endif
3320  // vsubsample should divide 255 evenly; otherwise we won't reach full opacity
3321 
3322  // now we have to blow out the windings into explicit edge lists
3323  n = 0;
3324  for (i=0; i < windings; ++i)
3325  n += wcount[i];
3326 
3327  e = (stbtt__edge *) STBTT_malloc(sizeof(*e) * (n+1), userdata); // add an extra one as a sentinel
3328  if (e == 0) return;
3329  n = 0;
3330 
3331  m=0;
3332  for (i=0; i < windings; ++i) {
3333  stbtt__point *p = pts + m;
3334  m += wcount[i];
3335  j = wcount[i]-1;
3336  for (k=0; k < wcount[i]; j=k++) {
3337  int a=k,b=j;
3338  // skip the edge if horizontal
3339  if (p[j].y == p[k].y)
3340  continue;
3341  // add edge from j to k to the list
3342  e[n].invert = 0;
3343  if (invert ? p[j].y > p[k].y : p[j].y < p[k].y) {
3344  e[n].invert = 1;
3345  a=j,b=k;
3346  }
3347  e[n].x0 = p[a].x * scale_x + shift_x;
3348  e[n].y0 = (p[a].y * y_scale_inv + shift_y) * vsubsample;
3349  e[n].x1 = p[b].x * scale_x + shift_x;
3350  e[n].y1 = (p[b].y * y_scale_inv + shift_y) * vsubsample;
3351  ++n;
3352  }
3353  }
3354 
3355  // now sort the edges by their highest point (should snap to integer, and then by x)
3356  //STBTT_sort(e, n, sizeof(e[0]), stbtt__edge_compare);
3357  stbtt__sort_edges(e, n);
3358 
3359  // now, traverse the scanlines and find the intersections on each scanline, use xor winding rule
3360  stbtt__rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y, userdata);
3361 
3362  STBTT_free(e, userdata);
3363 }
3364 
3365 static void stbtt__add_point(stbtt__point *points, int n, float x, float y)
3366 {
3367  if (!points) return; // during first pass, it's unallocated
3368  points[n].x = x;
3369  points[n].y = y;
3370 }
3371 
3372 // tesselate until threshhold p is happy... @TODO warped to compensate for non-linear stretching
3373 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)
3374 {
3375  // midpoint
3376  float mx = (x0 + 2*x1 + x2)/4;
3377  float my = (y0 + 2*y1 + y2)/4;
3378  // versus directly drawn line
3379  float dx = (x0+x2)/2 - mx;
3380  float dy = (y0+y2)/2 - my;
3381  if (n > 16) // 65536 segments on one curve better be enough!
3382  return 1;
3383  if (dx*dx+dy*dy > objspace_flatness_squared) { // half-pixel error allowed... need to be smaller if AA
3384  stbtt__tesselate_curve(points, num_points, x0,y0, (x0+x1)/2.0f,(y0+y1)/2.0f, mx,my, objspace_flatness_squared,n+1);
3385  stbtt__tesselate_curve(points, num_points, mx,my, (x1+x2)/2.0f,(y1+y2)/2.0f, x2,y2, objspace_flatness_squared,n+1);
3386  } else {
3387  stbtt__add_point(points, *num_points,x2,y2);
3388  *num_points = *num_points+1;
3389  }
3390  return 1;
3391 }
3392 
3393 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)
3394 {
3395  // @TODO this "flatness" calculation is just made-up nonsense that seems to work well enough
3396  float dx0 = x1-x0;
3397  float dy0 = y1-y0;
3398  float dx1 = x2-x1;
3399  float dy1 = y2-y1;
3400  float dx2 = x3-x2;
3401  float dy2 = y3-y2;
3402  float dx = x3-x0;
3403  float dy = y3-y0;
3404  float longlen = (float) (STBTT_sqrt(dx0*dx0+dy0*dy0)+STBTT_sqrt(dx1*dx1+dy1*dy1)+STBTT_sqrt(dx2*dx2+dy2*dy2));
3405  float shortlen = (float) STBTT_sqrt(dx*dx+dy*dy);
3406  float flatness_squared = longlen*longlen-shortlen*shortlen;
3407 
3408  if (n > 16) // 65536 segments on one curve better be enough!
3409  return;
3410 
3411  if (flatness_squared > objspace_flatness_squared) {
3412  float x01 = (x0+x1)/2;
3413  float y01 = (y0+y1)/2;
3414  float x12 = (x1+x2)/2;
3415  float y12 = (y1+y2)/2;
3416  float x23 = (x2+x3)/2;
3417  float y23 = (y2+y3)/2;
3418 
3419  float xa = (x01+x12)/2;
3420  float ya = (y01+y12)/2;
3421  float xb = (x12+x23)/2;
3422  float yb = (y12+y23)/2;
3423 
3424  float mx = (xa+xb)/2;
3425  float my = (ya+yb)/2;
3426 
3427  stbtt__tesselate_cubic(points, num_points, x0,y0, x01,y01, xa,ya, mx,my, objspace_flatness_squared,n+1);
3428  stbtt__tesselate_cubic(points, num_points, mx,my, xb,yb, x23,y23, x3,y3, objspace_flatness_squared,n+1);
3429  } else {
3430  stbtt__add_point(points, *num_points,x3,y3);
3431  *num_points = *num_points+1;
3432  }
3433 }
3434 
3435 // returns number of contours
3436 static stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts, float objspace_flatness, int **contour_lengths, int *num_contours, void *userdata)
3437 {
3438  stbtt__point *points=0;
3439  int num_points=0;
3440 
3441  float objspace_flatness_squared = objspace_flatness * objspace_flatness;
3442  int i,n=0,start=0, pass;
3443 
3444  // count how many "moves" there are to get the contour count
3445  for (i=0; i < num_verts; ++i)
3446  if (vertices[i].type == STBTT_vmove)
3447  ++n;
3448 
3449  *num_contours = n;
3450  if (n == 0) return 0;
3451 
3452  *contour_lengths = (int *) STBTT_malloc(sizeof(**contour_lengths) * n, userdata);
3453 
3454  if (*contour_lengths == 0) {
3455  *num_contours = 0;
3456  return 0;
3457  }
3458 
3459  // make two passes through the points so we don't need to realloc
3460  for (pass=0; pass < 2; ++pass) {
3461  float x=0,y=0;
3462  if (pass == 1) {
3463  points = (stbtt__point *) STBTT_malloc(num_points * sizeof(points[0]), userdata);
3464  if (points == NULL) goto error;
3465  }
3466  num_points = 0;
3467  n= -1;
3468  for (i=0; i < num_verts; ++i) {
3469  switch (vertices[i].type) {
3470  case STBTT_vmove:
3471  // start the next contour
3472  if (n >= 0)
3473  (*contour_lengths)[n] = num_points - start;
3474  ++n;
3475  start = num_points;
3476 
3477  x = vertices[i].x, y = vertices[i].y;
3478  stbtt__add_point(points, num_points++, x,y);
3479  break;
3480  case STBTT_vline:
3481  x = vertices[i].x, y = vertices[i].y;
3482  stbtt__add_point(points, num_points++, x, y);
3483  break;
3484  case STBTT_vcurve:
3485  stbtt__tesselate_curve(points, &num_points, x,y,
3486  vertices[i].cx, vertices[i].cy,
3487  vertices[i].x, vertices[i].y,
3488  objspace_flatness_squared, 0);
3489  x = vertices[i].x, y = vertices[i].y;
3490  break;
3491  case STBTT_vcubic:
3492  stbtt__tesselate_cubic(points, &num_points, x,y,
3493  vertices[i].cx, vertices[i].cy,
3494  vertices[i].cx1, vertices[i].cy1,
3495  vertices[i].x, vertices[i].y,
3496  objspace_flatness_squared, 0);
3497  x = vertices[i].x, y = vertices[i].y;
3498  break;
3499  }
3500  }
3501  (*contour_lengths)[n] = num_points - start;
3502  }
3503 
3504  return points;
3505 error:
3506  STBTT_free(points, userdata);
3507  STBTT_free(*contour_lengths, userdata);
3508  *contour_lengths = 0;
3509  *num_contours = 0;
3510  return NULL;
3511 }
3512 
3513 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)
3514 {
3515  float scale = scale_x > scale_y ? scale_y : scale_x;
3516  int winding_count = 0;
3517  int *winding_lengths = NULL;
3518  stbtt__point *windings = stbtt_FlattenCurves(vertices, num_verts, flatness_in_pixels / scale, &winding_lengths, &winding_count, userdata);
3519  if (windings) {
3520  stbtt__rasterize(result, windings, winding_lengths, winding_count, scale_x, scale_y, shift_x, shift_y, x_off, y_off, invert, userdata);
3521  STBTT_free(winding_lengths, userdata);
3522  STBTT_free(windings, userdata);
3523  }
3524 }
3525 
3526 STBTT_DEF void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata)
3527 {
3528  STBTT_free(bitmap, userdata);
3529 }
3530 
3531 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)
3532 {
3533  int ix0,iy0,ix1,iy1;
3534  stbtt__bitmap gbm;
3535  stbtt_vertex *vertices;
3536  int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices);
3537 
3538  if (scale_x == 0) scale_x = scale_y;
3539  if (scale_y == 0) {
3540  if (scale_x == 0) {
3541  STBTT_free(vertices, info->userdata);
3542  return NULL;
3543  }
3544  scale_y = scale_x;
3545  }
3546 
3547  stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,&ix1,&iy1);
3548 
3549  // now we get the size
3550  gbm.w = (ix1 - ix0);
3551  gbm.h = (iy1 - iy0);
3552  gbm.pixels = NULL; // in case we error
3553 
3554  if (width ) *width = gbm.w;
3555  if (height) *height = gbm.h;
3556  if (xoff ) *xoff = ix0;
3557  if (yoff ) *yoff = iy0;
3558 
3559  if (gbm.w && gbm.h) {
3560  gbm.pixels = (unsigned char *) STBTT_malloc(gbm.w * gbm.h, info->userdata);
3561  if (gbm.pixels) {
3562  gbm.stride = gbm.w;
3563 
3564  stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0, iy0, 1, info->userdata);
3565  }
3566  }
3567  STBTT_free(vertices, info->userdata);
3568  return gbm.pixels;
3569 }
3570 
3571 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)
3572 {
3573  return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y, 0.0f, 0.0f, glyph, width, height, xoff, yoff);
3574 }
3575 
3576 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)
3577 {
3578  int ix0,iy0;
3579  stbtt_vertex *vertices;
3580  int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices);
3581  stbtt__bitmap gbm;
3582 
3583  stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,0,0);
3584  gbm.pixels = output;
3585  gbm.w = out_w;
3586  gbm.h = out_h;
3587  gbm.stride = out_stride;
3588 
3589  if (gbm.w && gbm.h)
3590  stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0,iy0, 1, info->userdata);
3591 
3592  STBTT_free(vertices, info->userdata);
3593 }
3594 
3595 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)
3596 {
3597  stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f,0.0f, glyph);
3598 }
3599 
3600 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)
3601 {
3602  return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y,shift_x,shift_y, stbtt_FindGlyphIndex(info,codepoint), width,height,xoff,yoff);
3603 }
3604 
3605 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)
3606 {
3607  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));
3608 }
3609 
3610 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)
3611 {
3612  stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y, stbtt_FindGlyphIndex(info,codepoint));
3613 }
3614 
3615 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)
3616 {
3617  return stbtt_GetCodepointBitmapSubpixel(info, scale_x, scale_y, 0.0f,0.0f, codepoint, width,height,xoff,yoff);
3618 }
3619 
3620 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)
3621 {
3622  stbtt_MakeCodepointBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f,0.0f, codepoint);
3623 }
3624 
3626 //
3627 // bitmap baking
3628 //
3629 // This is SUPER-CRAPPY packing to keep source code small
3630 
3631 static int stbtt_BakeFontBitmap_internal(unsigned char *data, int offset, // font location (use offset=0 for plain .ttf)
3632  float pixel_height, // height of font in pixels
3633  unsigned char *pixels, int pw, int ph, // bitmap to be filled in
3634  int first_char, int num_chars, // characters to bake
3635  stbtt_bakedchar *chardata)
3636 {
3637  float scale;
3638  int x,y,bottom_y, i;
3639  stbtt_fontinfo f;
3640  f.userdata = NULL;
3641  if (!stbtt_InitFont(&f, data, offset))
3642  return -1;
3643  STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels
3644  x=y=1;
3645  bottom_y = 1;
3646 
3647  scale = stbtt_ScaleForPixelHeight(&f, pixel_height);
3648 
3649  for (i=0; i < num_chars; ++i) {
3650  int advance, lsb, x0,y0,x1,y1,gw,gh;
3651  int g = stbtt_FindGlyphIndex(&f, first_char + i);
3652  stbtt_GetGlyphHMetrics(&f, g, &advance, &lsb);
3653  stbtt_GetGlyphBitmapBox(&f, g, scale,scale, &x0,&y0,&x1,&y1);
3654  gw = x1-x0;
3655  gh = y1-y0;
3656  if (x + gw + 1 >= pw)
3657  y = bottom_y, x = 1; // advance to next row
3658  if (y + gh + 1 >= ph) // check if it fits vertically AFTER potentially moving to next row
3659  return -i;
3660  STBTT_assert(x+gw < pw);
3661  STBTT_assert(y+gh < ph);
3662  stbtt_MakeGlyphBitmap(&f, pixels+x+y*pw, gw,gh,pw, scale,scale, g);
3663  chardata[i].x0 = (stbtt_int16) x;
3664  chardata[i].y0 = (stbtt_int16) y;
3665  chardata[i].x1 = (stbtt_int16) (x + gw);
3666  chardata[i].y1 = (stbtt_int16) (y + gh);
3667  chardata[i].xadvance = scale * advance;
3668  chardata[i].xoff = (float) x0;
3669  chardata[i].yoff = (float) y0;
3670  x = x + gw + 1;
3671  if (y+gh+1 > bottom_y)
3672  bottom_y = y+gh+1;
3673  }
3674  return bottom_y;
3675 }
3676 
3677 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)
3678 {
3679  float d3d_bias = opengl_fillrule ? 0 : -0.5f;
3680  float ipw = 1.0f / pw, iph = 1.0f / ph;
3681  const stbtt_bakedchar *b = chardata + char_index;
3682  int round_x = STBTT_ifloor((*xpos + b->xoff) + 0.5f);
3683  int round_y = STBTT_ifloor((*ypos + b->yoff) + 0.5f);
3684 
3685  q->x0 = round_x + d3d_bias;
3686  q->y0 = round_y + d3d_bias;
3687  q->x1 = round_x + b->x1 - b->x0 + d3d_bias;
3688  q->y1 = round_y + b->y1 - b->y0 + d3d_bias;
3689 
3690  q->s0 = b->x0 * ipw;
3691  q->t0 = b->y0 * iph;
3692  q->s1 = b->x1 * ipw;
3693  q->t1 = b->y1 * iph;
3694 
3695  *xpos += b->xadvance;
3696 }
3697 
3699 //
3700 // rectangle packing replacement routines if you don't have stb_rect_pack.h
3701 //
3702 
3703 #ifndef STB_RECT_PACK_VERSION
3704 
3705 typedef int stbrp_coord;
3706 
3708 // //
3709 // //
3710 // COMPILER WARNING ?!?!? //
3711 // //
3712 // //
3713 // if you get a compile warning due to these symbols being defined more than //
3714 // once, move #include "stb_rect_pack.h" before #include "stb_truetype.h" //
3715 // //
3717 
3718 typedef struct
3719 {
3720  int width,height;
3721  int x,y,bottom_y;
3722 } stbrp_context;
3723 
3724 typedef struct
3725 {
3726  unsigned char x;
3727 } stbrp_node;
3728 
3729 struct stbrp_rect
3730 {
3731  stbrp_coord x,y;
3732  int id,w,h,was_packed;
3733 };
3734 
3735 static void stbrp_init_target(stbrp_context *con, int pw, int ph, stbrp_node *nodes, int num_nodes)
3736 {
3737  con->width = pw;
3738  con->height = ph;
3739  con->x = 0;
3740  con->y = 0;
3741  con->bottom_y = 0;
3742  STBTT__NOTUSED(nodes);
3743  STBTT__NOTUSED(num_nodes);
3744 }
3745 
3746 static void stbrp_pack_rects(stbrp_context *con, stbrp_rect *rects, int num_rects)
3747 {
3748  int i;
3749  for (i=0; i < num_rects; ++i) {
3750  if (con->x + rects[i].w > con->width) {
3751  con->x = 0;
3752  con->y = con->bottom_y;
3753  }
3754  if (con->y + rects[i].h > con->height)
3755  break;
3756  rects[i].x = con->x;
3757  rects[i].y = con->y;
3758  rects[i].was_packed = 1;
3759  con->x += rects[i].w;
3760  if (con->y + rects[i].h > con->bottom_y)
3761  con->bottom_y = con->y + rects[i].h;
3762  }
3763  for ( ; i < num_rects; ++i)
3764  rects[i].was_packed = 0;
3765 }
3766 #endif
3767 
3769 //
3770 // bitmap baking
3771 //
3772 // This is SUPER-AWESOME (tm Ryan Gordon) packing using stb_rect_pack.h. If
3773 // stb_rect_pack.h isn't available, it uses the BakeFontBitmap strategy.
3774 
3775 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)
3776 {
3777  stbrp_context *context = (stbrp_context *) STBTT_malloc(sizeof(*context) ,alloc_context);
3778  int num_nodes = pw - padding;
3779  stbrp_node *nodes = (stbrp_node *) STBTT_malloc(sizeof(*nodes ) * num_nodes,alloc_context);
3780 
3781  if (context == NULL || nodes == NULL) {
3782  if (context != NULL) STBTT_free(context, alloc_context);
3783  if (nodes != NULL) STBTT_free(nodes , alloc_context);
3784  return 0;
3785  }
3786 
3787  spc->user_allocator_context = alloc_context;
3788  spc->width = pw;
3789  spc->height = ph;
3790  spc->pixels = pixels;
3791  spc->pack_info = context;
3792  spc->nodes = nodes;
3793  spc->padding = padding;
3794  spc->stride_in_bytes = stride_in_bytes != 0 ? stride_in_bytes : pw;
3795  spc->h_oversample = 1;
3796  spc->v_oversample = 1;
3797 
3798  stbrp_init_target(context, pw-padding, ph-padding, nodes, num_nodes);
3799 
3800  if (pixels)
3801  STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels
3802 
3803  return 1;
3804 }
3805 
3807 {
3808  STBTT_free(spc->nodes , spc->user_allocator_context);
3809  STBTT_free(spc->pack_info, spc->user_allocator_context);
3810 }
3811 
3812 STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample)
3813 {
3814  STBTT_assert(h_oversample <= STBTT_MAX_OVERSAMPLE);
3815  STBTT_assert(v_oversample <= STBTT_MAX_OVERSAMPLE);
3816  if (h_oversample <= STBTT_MAX_OVERSAMPLE)
3817  spc->h_oversample = h_oversample;
3818  if (v_oversample <= STBTT_MAX_OVERSAMPLE)
3819  spc->v_oversample = v_oversample;
3820 }
3821 
3822 #define STBTT__OVER_MASK (STBTT_MAX_OVERSAMPLE-1)
3823 
3824 static void stbtt__h_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width)
3825 {
3826  unsigned char buffer[STBTT_MAX_OVERSAMPLE];
3827  int safe_w = w - kernel_width;
3828  int j;
3829  STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); // suppress bogus warning from VS2013 -analyze
3830  for (j=0; j < h; ++j) {
3831  int i;
3832  unsigned int total;
3833  STBTT_memset(buffer, 0, kernel_width);
3834 
3835  total = 0;
3836 
3837  // make kernel_width a constant in common cases so compiler can optimize out the divide
3838  switch (kernel_width) {
3839  case 2:
3840  for (i=0; i <= safe_w; ++i) {
3841  total += pixels[i] - buffer[i & STBTT__OVER_MASK];
3842  buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
3843  pixels[i] = (unsigned char) (total / 2);
3844  }
3845  break;
3846  case 3:
3847  for (i=0; i <= safe_w; ++i) {
3848  total += pixels[i] - buffer[i & STBTT__OVER_MASK];
3849  buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
3850  pixels[i] = (unsigned char) (total / 3);
3851  }
3852  break;
3853  case 4:
3854  for (i=0; i <= safe_w; ++i) {
3855  total += pixels[i] - buffer[i & STBTT__OVER_MASK];
3856  buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
3857  pixels[i] = (unsigned char) (total / 4);
3858  }
3859  break;
3860  case 5:
3861  for (i=0; i <= safe_w; ++i) {
3862  total += pixels[i] - buffer[i & STBTT__OVER_MASK];
3863  buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
3864  pixels[i] = (unsigned char) (total / 5);
3865  }
3866  break;
3867  default:
3868  for (i=0; i <= safe_w; ++i) {
3869  total += pixels[i] - buffer[i & STBTT__OVER_MASK];
3870  buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
3871  pixels[i] = (unsigned char) (total / kernel_width);
3872  }
3873  break;
3874  }
3875 
3876  for (; i < w; ++i) {
3877  STBTT_assert(pixels[i] == 0);
3878  total -= buffer[i & STBTT__OVER_MASK];
3879  pixels[i] = (unsigned char) (total / kernel_width);
3880  }
3881 
3882  pixels += stride_in_bytes;
3883  }
3884 }
3885 
3886 static void stbtt__v_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width)
3887 {
3888  unsigned char buffer[STBTT_MAX_OVERSAMPLE];
3889  int safe_h = h - kernel_width;
3890  int j;
3891  STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); // suppress bogus warning from VS2013 -analyze
3892  for (j=0; j < w; ++j) {
3893  int i;
3894  unsigned int total;
3895  STBTT_memset(buffer, 0, kernel_width);
3896 
3897  total = 0;
3898 
3899  // make kernel_width a constant in common cases so compiler can optimize out the divide
3900  switch (kernel_width) {
3901  case 2:
3902  for (i=0; i <= safe_h; ++i) {
3903  total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
3904  buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
3905  pixels[i*stride_in_bytes] = (unsigned char) (total / 2);
3906  }
3907  break;
3908  case 3:
3909  for (i=0; i <= safe_h; ++i) {
3910  total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
3911  buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
3912  pixels[i*stride_in_bytes] = (unsigned char) (total / 3);
3913  }
3914  break;
3915  case 4:
3916  for (i=0; i <= safe_h; ++i) {
3917  total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
3918  buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
3919  pixels[i*stride_in_bytes] = (unsigned char) (total / 4);
3920  }
3921  break;
3922  case 5:
3923  for (i=0; i <= safe_h; ++i) {
3924  total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
3925  buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
3926  pixels[i*stride_in_bytes] = (unsigned char) (total / 5);
3927  }
3928  break;
3929  default:
3930  for (i=0; i <= safe_h; ++i) {
3931  total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
3932  buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
3933  pixels[i*stride_in_bytes] = (unsigned char) (total / kernel_width);
3934  }
3935  break;
3936  }
3937 
3938  for (; i < h; ++i) {
3939  STBTT_assert(pixels[i*stride_in_bytes] == 0);
3940  total -= buffer[i & STBTT__OVER_MASK];
3941  pixels[i*stride_in_bytes] = (unsigned char) (total / kernel_width);
3942  }
3943 
3944  pixels += 1;
3945  }
3946 }
3947 
3948 static float stbtt__oversample_shift(int oversample)
3949 {
3950  if (!oversample)
3951  return 0.0f;
3952 
3953  // The prefilter is a box filter of width "oversample",
3954  // which shifts phase by (oversample - 1)/2 pixels in
3955  // oversampled space. We want to shift in the opposite
3956  // direction to counter this.
3957  return (float)-(oversample - 1) / (2.0f * (float)oversample);
3958 }
3959 
3960 // rects array must be big enough to accommodate all characters in the given ranges
3961 STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects)
3962 {
3963  int i,j,k;
3964 
3965  k=0;
3966  for (i=0; i < num_ranges; ++i) {
3967  float fh = ranges[i].font_size;
3968  float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh);
3969  ranges[i].h_oversample = (unsigned char) spc->h_oversample;
3970  ranges[i].v_oversample = (unsigned char) spc->v_oversample;
3971  for (j=0; j < ranges[i].num_chars; ++j) {
3972  int x0,y0,x1,y1;
3973  int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
3974  int glyph = stbtt_FindGlyphIndex(info, codepoint);
3976  scale * spc->h_oversample,
3977  scale * spc->v_oversample,
3978  0,0,
3979  &x0,&y0,&x1,&y1);
3980  rects[k].w = (stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1);
3981  rects[k].h = (stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1);
3982  ++k;
3983  }
3984  }
3985 
3986  return k;
3987 }
3988 
3989 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)
3990 {
3992  output,
3993  out_w - (prefilter_x - 1),
3994  out_h - (prefilter_y - 1),
3995  out_stride,
3996  scale_x,
3997  scale_y,
3998  shift_x,
3999  shift_y,
4000  glyph);
4001 
4002  if (prefilter_x > 1)
4003  stbtt__h_prefilter(output, out_w, out_h, out_stride, prefilter_x);
4004 
4005  if (prefilter_y > 1)
4006  stbtt__v_prefilter(output, out_w, out_h, out_stride, prefilter_y);
4007 
4008  *sub_x = stbtt__oversample_shift(prefilter_x);
4009  *sub_y = stbtt__oversample_shift(prefilter_y);
4010 }
4011 
4012 // rects array must be big enough to accommodate all characters in the given ranges
4013 STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects)
4014 {
4015  int i,j,k, return_value = 1;
4016 
4017  // save current values
4018  int old_h_over = spc->h_oversample;
4019  int old_v_over = spc->v_oversample;
4020 
4021  k = 0;
4022  for (i=0; i < num_ranges; ++i) {
4023  float fh = ranges[i].font_size;
4024  float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh);
4025  float recip_h,recip_v,sub_x,sub_y;
4026  spc->h_oversample = ranges[i].h_oversample;
4027  spc->v_oversample = ranges[i].v_oversample;
4028  recip_h = 1.0f / spc->h_oversample;
4029  recip_v = 1.0f / spc->v_oversample;
4030  sub_x = stbtt__oversample_shift(spc->h_oversample);
4031  sub_y = stbtt__oversample_shift(spc->v_oversample);
4032  for (j=0; j < ranges[i].num_chars; ++j) {
4033  stbrp_rect *r = &rects[k];
4034  if (r->was_packed) {
4035  stbtt_packedchar *bc = &ranges[i].chardata_for_range[j];
4036  int advance, lsb, x0,y0,x1,y1;
4037  int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
4038  int glyph = stbtt_FindGlyphIndex(info, codepoint);
4039  stbrp_coord pad = (stbrp_coord) spc->padding;
4040 
4041  // pad on left and top
4042  r->x += pad;
4043  r->y += pad;
4044  r->w -= pad;
4045  r->h -= pad;
4046  stbtt_GetGlyphHMetrics(info, glyph, &advance, &lsb);
4047  stbtt_GetGlyphBitmapBox(info, glyph,
4048  scale * spc->h_oversample,
4049  scale * spc->v_oversample,
4050  &x0,&y0,&x1,&y1);
4052  spc->pixels + r->x + r->y*spc->stride_in_bytes,
4053  r->w - spc->h_oversample+1,
4054  r->h - spc->v_oversample+1,
4055  spc->stride_in_bytes,
4056  scale * spc->h_oversample,
4057  scale * spc->v_oversample,
4058  0,0,
4059  glyph);
4060 
4061  if (spc->h_oversample > 1)
4062  stbtt__h_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes,
4063  r->w, r->h, spc->stride_in_bytes,
4064  spc->h_oversample);
4065 
4066  if (spc->v_oversample > 1)
4067  stbtt__v_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes,
4068  r->w, r->h, spc->stride_in_bytes,
4069  spc->v_oversample);
4070 
4071  bc->x0 = (stbtt_int16) r->x;
4072  bc->y0 = (stbtt_int16) r->y;
4073  bc->x1 = (stbtt_int16) (r->x + r->w);
4074  bc->y1 = (stbtt_int16) (r->y + r->h);
4075  bc->xadvance = scale * advance;
4076  bc->xoff = (float) x0 * recip_h + sub_x;
4077  bc->yoff = (float) y0 * recip_v + sub_y;
4078  bc->xoff2 = (x0 + r->w) * recip_h + sub_x;
4079  bc->yoff2 = (y0 + r->h) * recip_v + sub_y;
4080  } else {
4081  return_value = 0; // if any fail, report failure
4082  }
4083 
4084  ++k;
4085  }
4086  }
4087 
4088  // restore original values
4089  spc->h_oversample = old_h_over;
4090  spc->v_oversample = old_v_over;
4091 
4092  return return_value;
4093 }
4094 
4095 STBTT_DEF void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect *rects, int num_rects)
4096 {
4097  stbrp_pack_rects((stbrp_context *) spc->pack_info, rects, num_rects);
4098 }
4099 
4100 STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges)
4101 {
4102  stbtt_fontinfo info;
4103  int i,j,n, return_value = 1;
4104  //stbrp_context *context = (stbrp_context *) spc->pack_info;
4105  stbrp_rect *rects;
4106 
4107  // flag all characters as NOT packed
4108  for (i=0; i < num_ranges; ++i)
4109  for (j=0; j < ranges[i].num_chars; ++j)
4110  ranges[i].chardata_for_range[j].x0 =
4111  ranges[i].chardata_for_range[j].y0 =
4112  ranges[i].chardata_for_range[j].x1 =
4113  ranges[i].chardata_for_range[j].y1 = 0;
4114 
4115  n = 0;
4116  for (i=0; i < num_ranges; ++i)
4117  n += ranges[i].num_chars;
4118 
4119  rects = (stbrp_rect *) STBTT_malloc(sizeof(*rects) * n, spc->user_allocator_context);
4120  if (rects == NULL)
4121  return 0;
4122 
4123  info.userdata = spc->user_allocator_context;
4124  stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata,font_index));
4125 
4126  n = stbtt_PackFontRangesGatherRects(spc, &info, ranges, num_ranges, rects);
4127 
4128  stbtt_PackFontRangesPackRects(spc, rects, n);
4129 
4130  return_value = stbtt_PackFontRangesRenderIntoRects(spc, &info, ranges, num_ranges, rects);
4131 
4132  STBTT_free(rects, spc->user_allocator_context);
4133  return return_value;
4134 }
4135 
4136 STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, float font_size,
4137  int first_unicode_codepoint_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range)
4138 {
4139  stbtt_pack_range range;
4140  range.first_unicode_codepoint_in_range = first_unicode_codepoint_in_range;
4141  range.array_of_unicode_codepoints = NULL;
4142  range.num_chars = num_chars_in_range;
4143  range.chardata_for_range = chardata_for_range;
4144  range.font_size = font_size;
4145  return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1);
4146 }
4147 
4148 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)
4149 {
4150  float ipw = 1.0f / pw, iph = 1.0f / ph;
4151  const stbtt_packedchar *b = chardata + char_index;
4152 
4153  if (align_to_integer) {
4154  float x = (float) STBTT_ifloor((*xpos + b->xoff) + 0.5f);
4155  float y = (float) STBTT_ifloor((*ypos + b->yoff) + 0.5f);
4156  q->x0 = x;
4157  q->y0 = y;
4158  q->x1 = x + b->xoff2 - b->xoff;
4159  q->y1 = y + b->yoff2 - b->yoff;
4160  } else {
4161  q->x0 = *xpos + b->xoff;
4162  q->y0 = *ypos + b->yoff;
4163  q->x1 = *xpos + b->xoff2;
4164  q->y1 = *ypos + b->yoff2;
4165  }
4166 
4167  q->s0 = b->x0 * ipw;
4168  q->t0 = b->y0 * iph;
4169  q->s1 = b->x1 * ipw;
4170  q->t1 = b->y1 * iph;
4171 
4172  *xpos += b->xadvance;
4173 }
4174 
4176 //
4177 // sdf computation
4178 //
4179 
4180 #define STBTT_min(a,b) ((a) < (b) ? (a) : (b))
4181 #define STBTT_max(a,b) ((a) < (b) ? (b) : (a))
4182 
4183 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])
4184 {
4185  float q0perp = q0[1]*ray[0] - q0[0]*ray[1];
4186  float q1perp = q1[1]*ray[0] - q1[0]*ray[1];
4187  float q2perp = q2[1]*ray[0] - q2[0]*ray[1];
4188  float roperp = orig[1]*ray[0] - orig[0]*ray[1];
4189 
4190  float a = q0perp - 2*q1perp + q2perp;
4191  float b = q1perp - q0perp;
4192  float c = q0perp - roperp;
4193 
4194  float s0 = 0., s1 = 0.;
4195  int num_s = 0;
4196 
4197  if (a != 0.0) {
4198  float discr = b*b - a*c;
4199  if (discr > 0.0) {
4200  float rcpna = -1 / a;
4201  float d = (float) STBTT_sqrt(discr);
4202  s0 = (b+d) * rcpna;
4203  s1 = (b-d) * rcpna;
4204  if (s0 >= 0.0 && s0 <= 1.0)
4205  num_s = 1;
4206  if (d > 0.0 && s1 >= 0.0 && s1 <= 1.0) {
4207  if (num_s == 0) s0 = s1;
4208  ++num_s;
4209  }
4210  }
4211  } else {
4212  // 2*b*s + c = 0
4213  // s = -c / (2*b)
4214  s0 = c / (-2 * b);
4215  if (s0 >= 0.0 && s0 <= 1.0)
4216  num_s = 1;
4217  }
4218 
4219  if (num_s == 0)
4220  return 0;
4221  else {
4222  float rcp_len2 = 1 / (ray[0]*ray[0] + ray[1]*ray[1]);
4223  float rayn_x = ray[0] * rcp_len2, rayn_y = ray[1] * rcp_len2;
4224 
4225  float q0d = q0[0]*rayn_x + q0[1]*rayn_y;
4226  float q1d = q1[0]*rayn_x + q1[1]*rayn_y;
4227  float q2d = q2[0]*rayn_x + q2[1]*rayn_y;
4228  float rod = orig[0]*rayn_x + orig[1]*rayn_y;
4229 
4230  float q10d = q1d - q0d;
4231  float q20d = q2d - q0d;
4232  float q0rd = q0d - rod;
4233 
4234  hits[0][0] = q0rd + s0*(2.0f - 2.0f*s0)*q10d + s0*s0*q20d;
4235  hits[0][1] = a*s0+b;
4236 
4237  if (num_s > 1) {
4238  hits[1][0] = q0rd + s1*(2.0f - 2.0f*s1)*q10d + s1*s1*q20d;
4239  hits[1][1] = a*s1+b;
4240  return 2;
4241  } else {
4242  return 1;
4243  }
4244  }
4245 }
4246 
4247 static int equal(float *a, float *b)
4248 {
4249  return (a[0] == b[0] && a[1] == b[1]);
4250 }
4251 
4252 static int stbtt__compute_crossings_x(float x, float y, int nverts, stbtt_vertex *verts)
4253 {
4254  int i;
4255  float orig[2], ray[2] = { 1, 0 };
4256  float y_frac;
4257  int winding = 0;
4258 
4259  orig[0] = x;
4260  orig[1] = y;
4261 
4262  // make sure y never passes through a vertex of the shape
4263  y_frac = (float) STBTT_fmod(y, 1.0f);
4264  if (y_frac < 0.01f)
4265  y += 0.01f;
4266  else if (y_frac > 0.99f)
4267  y -= 0.01f;
4268  orig[1] = y;
4269 
4270  // test a ray from (-infinity,y) to (x,y)
4271  for (i=0; i < nverts; ++i) {
4272  if (verts[i].type == STBTT_vline) {
4273  int x0 = (int) verts[i-1].x, y0 = (int) verts[i-1].y;
4274  int x1 = (int) verts[i ].x, y1 = (int) verts[i ].y;
4275  if (y > STBTT_min(y0,y1) && y < STBTT_max(y0,y1) && x > STBTT_min(x0,x1)) {
4276  float x_inter = (y - y0) / (y1 - y0) * (x1-x0) + x0;
4277  if (x_inter < x)
4278  winding += (y0 < y1) ? 1 : -1;
4279  }
4280  }
4281  if (verts[i].type == STBTT_vcurve) {
4282  int x0 = (int) verts[i-1].x , y0 = (int) verts[i-1].y ;
4283  int x1 = (int) verts[i ].cx, y1 = (int) verts[i ].cy;
4284  int x2 = (int) verts[i ].x , y2 = (int) verts[i ].y ;
4285  int ax = STBTT_min(x0,STBTT_min(x1,x2)), ay = STBTT_min(y0,STBTT_min(y1,y2));
4286  int by = STBTT_max(y0,STBTT_max(y1,y2));
4287  if (y > ay && y < by && x > ax) {
4288  float q0[2],q1[2],q2[2];
4289  float hits[2][2];
4290  q0[0] = (float)x0;
4291  q0[1] = (float)y0;
4292  q1[0] = (float)x1;
4293  q1[1] = (float)y1;
4294  q2[0] = (float)x2;
4295  q2[1] = (float)y2;
4296  if (equal(q0,q1) || equal(q1,q2)) {
4297  x0 = (int)verts[i-1].x;
4298  y0 = (int)verts[i-1].y;
4299  x1 = (int)verts[i ].x;
4300  y1 = (int)verts[i ].y;
4301  if (y > STBTT_min(y0,y1) && y < STBTT_max(y0,y1) && x > STBTT_min(x0,x1)) {
4302  float x_inter = (y - y0) / (y1 - y0) * (x1-x0) + x0;
4303  if (x_inter < x)
4304  winding += (y0 < y1) ? 1 : -1;
4305  }
4306  } else {
4307  int num_hits = stbtt__ray_intersect_bezier(orig, ray, q0, q1, q2, hits);
4308  if (num_hits >= 1)
4309  if (hits[0][0] < 0)
4310  winding += (hits[0][1] < 0 ? -1 : 1);
4311  if (num_hits >= 2)
4312  if (hits[1][0] < 0)
4313  winding += (hits[1][1] < 0 ? -1 : 1);
4314  }
4315  }
4316  }
4317  }
4318  return winding;
4319 }
4320 
4321 static float stbtt__cuberoot( float x )
4322 {
4323  if (x<0)
4324  return -(float) STBTT_pow(-x,1.0f/3.0f);
4325  else
4326  return (float) STBTT_pow( x,1.0f/3.0f);
4327 }
4328 
4329 // x^3 + c*x^2 + b*x + a = 0
4330 static int stbtt__solve_cubic(float a, float b, float c, float* r)
4331 {
4332  float s = -a / 3;
4333  float p = b - a*a / 3;
4334  float q = a * (2*a*a - 9*b) / 27 + c;
4335  float p3 = p*p*p;
4336  float d = q*q + 4*p3 / 27;
4337  if (d >= 0) {
4338  float z = (float) STBTT_sqrt(d);
4339  float u = (-q + z) / 2;
4340  float v = (-q - z) / 2;
4341  u = stbtt__cuberoot(u);
4342  v = stbtt__cuberoot(v);
4343  r[0] = s + u + v;
4344  return 1;
4345  } else {
4346  float u = (float) STBTT_sqrt(-p/3);
4347  float v = (float) STBTT_acos(-STBTT_sqrt(-27/p3) * q / 2) / 3; // p3 must be negative, since d is negative
4348  float m = (float) STBTT_cos(v);
4349  float n = (float) STBTT_cos(v-3.141592/2)*1.732050808f;
4350  r[0] = s + u * 2 * m;
4351  r[1] = s - u * (m + n);
4352  r[2] = s - u * (m - n);
4353 
4354  //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?
4355  //STBTT_assert( STBTT_fabs(((r[1]+a)*r[1]+b)*r[1]+c) < 0.05f);
4356  //STBTT_assert( STBTT_fabs(((r[2]+a)*r[2]+b)*r[2]+c) < 0.05f);
4357  return 3;
4358  }
4359 }
4360 
4361 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)
4362 {
4363  float scale_x = scale, scale_y = scale;
4364  int ix0,iy0,ix1,iy1;
4365  int w,h;
4366  unsigned char *data;
4367 
4368  // if one scale is 0, use same scale for both
4369  if (scale_x == 0) scale_x = scale_y;
4370  if (scale_y == 0) {
4371  if (scale_x == 0) return NULL; // if both scales are 0, return NULL
4372  scale_y = scale_x;
4373  }
4374 
4375  stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale, scale, 0.0f,0.0f, &ix0,&iy0,&ix1,&iy1);
4376 
4377  // if empty, return NULL
4378  if (ix0 == ix1 || iy0 == iy1)
4379  return NULL;
4380 
4381  ix0 -= padding;
4382  iy0 -= padding;
4383  ix1 += padding;
4384  iy1 += padding;
4385 
4386  w = (ix1 - ix0);
4387  h = (iy1 - iy0);
4388 
4389  if (width ) *width = w;
4390  if (height) *height = h;
4391  if (xoff ) *xoff = ix0;
4392  if (yoff ) *yoff = iy0;
4393 
4394  // invert for y-downwards bitmaps
4395  scale_y = -scale_y;
4396 
4397  {
4398  int x,y,i,j;
4399  float *precompute;
4400  stbtt_vertex *verts;
4401  int num_verts = stbtt_GetGlyphShape(info, glyph, &verts);
4402  data = (unsigned char *) STBTT_malloc(w * h, info->userdata);
4403  precompute = (float *) STBTT_malloc(num_verts * sizeof(float), info->userdata);
4404 
4405  for (i=0,j=num_verts-1; i < num_verts; j=i++) {
4406  if (verts[i].type == STBTT_vline) {
4407  float x0 = verts[i].x*scale_x, y0 = verts[i].y*scale_y;
4408  float x1 = verts[j].x*scale_x, y1 = verts[j].y*scale_y;
4409  float dist = (float) STBTT_sqrt((x1-x0)*(x1-x0) + (y1-y0)*(y1-y0));
4410  precompute[i] = (dist == 0) ? 0.0f : 1.0f / dist;
4411  } else if (verts[i].type == STBTT_vcurve) {
4412  float x2 = verts[j].x *scale_x, y2 = verts[j].y *scale_y;
4413  float x1 = verts[i].cx*scale_x, y1 = verts[i].cy*scale_y;
4414  float x0 = verts[i].x *scale_x, y0 = verts[i].y *scale_y;
4415  float bx = x0 - 2*x1 + x2, by = y0 - 2*y1 + y2;
4416  float len2 = bx*bx + by*by;
4417  if (len2 != 0.0f)
4418  precompute[i] = 1.0f / (bx*bx + by*by);
4419  else
4420  precompute[i] = 0.0f;
4421  } else
4422  precompute[i] = 0.0f;
4423  }
4424 
4425  for (y=iy0; y < iy1; ++y) {
4426  for (x=ix0; x < ix1; ++x) {
4427  float val;
4428  float min_dist = 999999.0f;
4429  float sx = (float) x + 0.5f;
4430  float sy = (float) y + 0.5f;
4431  float x_gspace = (sx / scale_x);
4432  float y_gspace = (sy / scale_y);
4433 
4434  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
4435 
4436  for (i=0; i < num_verts; ++i) {
4437  float x0 = verts[i].x*scale_x, y0 = verts[i].y*scale_y;
4438 
4439  // 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
4440  float dist2 = (x0-sx)*(x0-sx) + (y0-sy)*(y0-sy);
4441  if (dist2 < min_dist*min_dist)
4442  min_dist = (float) STBTT_sqrt(dist2);
4443 
4444  if (verts[i].type == STBTT_vline) {
4445  float x1 = verts[i-1].x*scale_x, y1 = verts[i-1].y*scale_y;
4446 
4447  // coarse culling against bbox
4448  //if (sx > STBTT_min(x0,x1)-min_dist && sx < STBTT_max(x0,x1)+min_dist &&
4449  // sy > STBTT_min(y0,y1)-min_dist && sy < STBTT_max(y0,y1)+min_dist)
4450  float dist = (float) STBTT_fabs((x1-x0)*(y0-sy) - (y1-y0)*(x0-sx)) * precompute[i];
4451  STBTT_assert(i != 0);
4452  if (dist < min_dist) {
4453  // check position along line
4454  // x' = x0 + t*(x1-x0), y' = y0 + t*(y1-y0)
4455  // minimize (x'-sx)*(x'-sx)+(y'-sy)*(y'-sy)
4456  float dx = x1-x0, dy = y1-y0;
4457  float px = x0-sx, py = y0-sy;
4458  // 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
4459  // derivative: 2*px*dx + 2*py*dy + (2*dx*dx+2*dy*dy)*t, set to 0 and solve
4460  float t = -(px*dx + py*dy) / (dx*dx + dy*dy);
4461  if (t >= 0.0f && t <= 1.0f)
4462  min_dist = dist;
4463  }
4464  } else if (verts[i].type == STBTT_vcurve) {
4465  float x2 = verts[i-1].x *scale_x, y2 = verts[i-1].y *scale_y;
4466  float x1 = verts[i ].cx*scale_x, y1 = verts[i ].cy*scale_y;
4467  float box_x0 = STBTT_min(STBTT_min(x0,x1),x2);
4468  float box_y0 = STBTT_min(STBTT_min(y0,y1),y2);
4469  float box_x1 = STBTT_max(STBTT_max(x0,x1),x2);
4470  float box_y1 = STBTT_max(STBTT_max(y0,y1),y2);
4471  // coarse culling against bbox to avoid computing cubic unnecessarily
4472  if (sx > box_x0-min_dist && sx < box_x1+min_dist && sy > box_y0-min_dist && sy < box_y1+min_dist) {
4473  int num=0;
4474  float ax = x1-x0, ay = y1-y0;
4475  float bx = x0 - 2*x1 + x2, by = y0 - 2*y1 + y2;
4476  float mx = x0 - sx, my = y0 - sy;
4477  float res[3],px,py,t,it;
4478  float a_inv = precompute[i];
4479  if (a_inv == 0.0) { // if a_inv is 0, it's 2nd degree so use quadratic formula
4480  float a = 3*(ax*bx + ay*by);
4481  float b = 2*(ax*ax + ay*ay) + (mx*bx+my*by);
4482  float c = mx*ax+my*ay;
4483  if (a == 0.0) { // if a is 0, it's linear
4484  if (b != 0.0) {
4485  res[num++] = -c/b;
4486  }
4487  } else {
4488  float discriminant = b*b - 4*a*c;
4489  if (discriminant < 0)
4490  num = 0;
4491  else {
4492  float root = (float) STBTT_sqrt(discriminant);
4493  res[0] = (-b - root)/(2*a);
4494  res[1] = (-b + root)/(2*a);
4495  num = 2; // don't bother distinguishing 1-solution case, as code below will still work
4496  }
4497  }
4498  } else {
4499  float b = 3*(ax*bx + ay*by) * a_inv; // could precompute this as it doesn't depend on sample point
4500  float c = (2*(ax*ax + ay*ay) + (mx*bx+my*by)) * a_inv;
4501  float d = (mx*ax+my*ay) * a_inv;
4502  num = stbtt__solve_cubic(b, c, d, res);
4503  }
4504  if (num >= 1 && res[0] >= 0.0f && res[0] <= 1.0f) {
4505  t = res[0], it = 1.0f - t;
4506  px = it*it*x0 + 2*t*it*x1 + t*t*x2;
4507  py = it*it*y0 + 2*t*it*y1 + t*t*y2;
4508  dist2 = (px-sx)*(px-sx) + (py-sy)*(py-sy);
4509  if (dist2 < min_dist * min_dist)
4510  min_dist = (float) STBTT_sqrt(dist2);
4511  }
4512  if (num >= 2 && res[1] >= 0.0f && res[1] <= 1.0f) {
4513  t = res[1], it = 1.0f - t;
4514  px = it*it*x0 + 2*t*it*x1 + t*t*x2;
4515  py = it*it*y0 + 2*t*it*y1 + t*t*y2;
4516  dist2 = (px-sx)*(px-sx) + (py-sy)*(py-sy);
4517  if (dist2 < min_dist * min_dist)
4518  min_dist = (float) STBTT_sqrt(dist2);
4519  }
4520  if (num >= 3 && res[2] >= 0.0f && res[2] <= 1.0f) {
4521  t = res[2], it = 1.0f - t;
4522  px = it*it*x0 + 2*t*it*x1 + t*t*x2;
4523  py = it*it*y0 + 2*t*it*y1 + t*t*y2;
4524  dist2 = (px-sx)*(px-sx) + (py-sy)*(py-sy);
4525  if (dist2 < min_dist * min_dist)
4526  min_dist = (float) STBTT_sqrt(dist2);
4527  }
4528  }
4529  }
4530  }
4531  if (winding == 0)
4532  min_dist = -min_dist; // if outside the shape, value is negative
4533  val = onedge_value + pixel_dist_scale * min_dist;
4534  if (val < 0)
4535  val = 0;
4536  else if (val > 255)
4537  val = 255;
4538  data[(y-iy0)*w+(x-ix0)] = (unsigned char) val;
4539  }
4540  }
4541  STBTT_free(precompute, info->userdata);
4542  STBTT_free(verts, info->userdata);
4543  }
4544  return data;
4545 }
4546 
4547 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)
4548 {
4549  return stbtt_GetGlyphSDF(info, scale, stbtt_FindGlyphIndex(info, codepoint), padding, onedge_value, pixel_dist_scale, width, height, xoff, yoff);
4550 }
4551 
4552 STBTT_DEF void stbtt_FreeSDF(unsigned char *bitmap, void *userdata)
4553 {
4554  STBTT_free(bitmap, userdata);
4555 }
4556 
4558 //
4559 // font name matching -- recommended not to use this
4560 //
4561 
4562 // check if a utf8 string contains a prefix which is the utf16 string; if so return length of matching utf8 string
4563 static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(stbtt_uint8 *s1, stbtt_int32 len1, stbtt_uint8 *s2, stbtt_int32 len2)
4564 {
4565  stbtt_int32 i=0;
4566 
4567  // convert utf16 to utf8 and compare the results while converting
4568  while (len2) {
4569  stbtt_uint16 ch = s2[0]*256 + s2[1];
4570  if (ch < 0x80) {
4571  if (i >= len1) return -1;
4572  if (s1[i++] != ch) return -1;
4573  } else if (ch < 0x800) {
4574  if (i+1 >= len1) return -1;
4575  if (s1[i++] != 0xc0 + (ch >> 6)) return -1;
4576  if (s1[i++] != 0x80 + (ch & 0x3f)) return -1;
4577  } else if (ch >= 0xd800 && ch < 0xdc00) {
4578  stbtt_uint32 c;
4579  stbtt_uint16 ch2 = s2[2]*256 + s2[3];
4580  if (i+3 >= len1) return -1;
4581  c = ((ch - 0xd800) << 10) + (ch2 - 0xdc00) + 0x10000;
4582  if (s1[i++] != 0xf0 + (c >> 18)) return -1;
4583  if (s1[i++] != 0x80 + ((c >> 12) & 0x3f)) return -1;
4584  if (s1[i++] != 0x80 + ((c >> 6) & 0x3f)) return -1;
4585  if (s1[i++] != 0x80 + ((c ) & 0x3f)) return -1;
4586  s2 += 2; // plus another 2 below
4587  len2 -= 2;
4588  } else if (ch >= 0xdc00 && ch < 0xe000) {
4589  return -1;
4590  } else {
4591  if (i+2 >= len1) return -1;
4592  if (s1[i++] != 0xe0 + (ch >> 12)) return -1;
4593  if (s1[i++] != 0x80 + ((ch >> 6) & 0x3f)) return -1;
4594  if (s1[i++] != 0x80 + ((ch ) & 0x3f)) return -1;
4595  }
4596  s2 += 2;
4597  len2 -= 2;
4598  }
4599  return i;
4600 }
4601 
4602 static int stbtt_CompareUTF8toUTF16_bigendian_internal(char *s1, int len1, char *s2, int len2)
4603 {
4604  return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((stbtt_uint8*) s1, len1, (stbtt_uint8*) s2, len2);
4605 }
4606 
4607 // returns results in whatever encoding you request... but note that 2-byte encodings
4608 // will be BIG-ENDIAN... use stbtt_CompareUTF8toUTF16_bigendian() to compare
4609 STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID)
4610 {
4611  stbtt_int32 i,count,stringOffset;
4612  stbtt_uint8 *fc = font->data;
4613  stbtt_uint32 offset = font->fontstart;
4614  stbtt_uint32 nm = stbtt__find_table(fc, offset, "name");
4615  if (!nm) return NULL;
4616 
4617  count = ttUSHORT(fc+nm+2);
4618  stringOffset = nm + ttUSHORT(fc+nm+4);
4619  for (i=0; i < count; ++i) {
4620  stbtt_uint32 loc = nm + 6 + 12 * i;
4621  if (platformID == ttUSHORT(fc+loc+0) && encodingID == ttUSHORT(fc+loc+2)
4622  && languageID == ttUSHORT(fc+loc+4) && nameID == ttUSHORT(fc+loc+6)) {
4623  *length = ttUSHORT(fc+loc+8);
4624  return (const char *) (fc+stringOffset+ttUSHORT(fc+loc+10));
4625  }
4626  }
4627  return NULL;
4628 }
4629 
4630 static int stbtt__matchpair(stbtt_uint8 *fc, stbtt_uint32 nm, stbtt_uint8 *name, stbtt_int32 nlen, stbtt_int32 target_id, stbtt_int32 next_id)
4631 {
4632  stbtt_int32 i;
4633  stbtt_int32 count = ttUSHORT(fc+nm+2);
4634  stbtt_int32 stringOffset = nm + ttUSHORT(fc+nm+4);
4635 
4636  for (i=0; i < count; ++i) {
4637  stbtt_uint32 loc = nm + 6 + 12 * i;
4638  stbtt_int32 id = ttUSHORT(fc+loc+6);
4639  if (id == target_id) {
4640  // find the encoding
4641  stbtt_int32 platform = ttUSHORT(fc+loc+0), encoding = ttUSHORT(fc+loc+2), language = ttUSHORT(fc+loc+4);
4642 
4643  // is this a Unicode encoding?
4644  if (platform == 0 || (platform == 3 && encoding == 1) || (platform == 3 && encoding == 10)) {
4645  stbtt_int32 slen = ttUSHORT(fc+loc+8);
4646  stbtt_int32 off = ttUSHORT(fc+loc+10);
4647 
4648  // check if there's a prefix match
4649  stbtt_int32 matchlen = stbtt__CompareUTF8toUTF16_bigendian_prefix(name, nlen, fc+stringOffset+off,slen);
4650  if (matchlen >= 0) {
4651  // check for target_id+1 immediately following, with same encoding & language
4652  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) {
4653  slen = ttUSHORT(fc+loc+12+8);
4654  off = ttUSHORT(fc+loc+12+10);
4655  if (slen == 0) {
4656  if (matchlen == nlen)
4657  return 1;
4658  } else if (matchlen < nlen && name[matchlen] == ' ') {
4659  ++matchlen;
4660  if (stbtt_CompareUTF8toUTF16_bigendian_internal((char*) (name+matchlen), nlen-matchlen, (char*)(fc+stringOffset+off),slen))
4661  return 1;
4662  }
4663  } else {
4664  // if nothing immediately following
4665  if (matchlen == nlen)
4666  return 1;
4667  }
4668  }
4669  }
4670 
4671  // @TODO handle other encodings
4672  }
4673  }
4674  return 0;
4675 }
4676 
4677 static int stbtt__matches(stbtt_uint8 *fc, stbtt_uint32 offset, stbtt_uint8 *name, stbtt_int32 flags)
4678 {
4679  stbtt_int32 nlen = (stbtt_int32) STBTT_strlen((char *) name);
4680  stbtt_uint32 nm,hd;
4681  if (!stbtt__isfont(fc+offset)) return 0;
4682 
4683  // check italics/bold/underline flags in macStyle...
4684  if (flags) {
4685  hd = stbtt__find_table(fc, offset, "head");
4686  if ((ttUSHORT(fc+hd+44) & 7) != (flags & 7)) return 0;
4687  }
4688 
4689  nm = stbtt__find_table(fc, offset, "name");
4690  if (!nm) return 0;
4691 
4692  if (flags) {
4693  // if we checked the macStyle flags, then just check the family and ignore the subfamily
4694  if (stbtt__matchpair(fc, nm, name, nlen, 16, -1)) return 1;
4695  if (stbtt__matchpair(fc, nm, name, nlen, 1, -1)) return 1;
4696  if (stbtt__matchpair(fc, nm, name, nlen, 3, -1)) return 1;
4697  } else {
4698  if (stbtt__matchpair(fc, nm, name, nlen, 16, 17)) return 1;
4699  if (stbtt__matchpair(fc, nm, name, nlen, 1, 2)) return 1;
4700  if (stbtt__matchpair(fc, nm, name, nlen, 3, -1)) return 1;
4701  }
4702 
4703  return 0;
4704 }
4705 
4706 static int stbtt_FindMatchingFont_internal(unsigned char *font_collection, char *name_utf8, stbtt_int32 flags)
4707 {
4708  stbtt_int32 i;
4709  for (i=0;;++i) {
4710  stbtt_int32 off = stbtt_GetFontOffsetForIndex(font_collection, i);
4711  if (off < 0) return off;
4712  if (stbtt__matches((stbtt_uint8 *) font_collection, off, (stbtt_uint8*) name_utf8, flags))
4713  return off;
4714  }
4715 }
4716 
4717 #if defined(__GNUC__) || defined(__clang__)
4718 #pragma GCC diagnostic push
4719 #pragma GCC diagnostic ignored "-Wcast-qual"
4720 #endif
4721 
4722 STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset,
4723  float pixel_height, unsigned char *pixels, int pw, int ph,
4724  int first_char, int num_chars, stbtt_bakedchar *chardata)
4725 {
4726  return stbtt_BakeFontBitmap_internal((unsigned char *) data, offset, pixel_height, pixels, pw, ph, first_char, num_chars, chardata);
4727 }
4728 
4729 STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index)
4730 {
4731  return stbtt_GetFontOffsetForIndex_internal((unsigned char *) data, index);
4732 }
4733 
4734 STBTT_DEF int stbtt_GetNumberOfFonts(const unsigned char *data)
4735 {
4736  return stbtt_GetNumberOfFonts_internal((unsigned char *) data);
4737 }
4738 
4739 STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset)
4740 {
4741  return stbtt_InitFont_internal(info, (unsigned char *) data, offset);
4742 }
4743 
4744 STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *fontdata, const char *name, int flags)
4745 {
4746  return stbtt_FindMatchingFont_internal((unsigned char *) fontdata, (char *) name, flags);
4747 }
4748 
4749 STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2)
4750 {
4751  return stbtt_CompareUTF8toUTF16_bigendian_internal((char *) s1, len1, (char *) s2, len2);
4752 }
4753 
4754 #if defined(__GNUC__) || defined(__clang__)
4755 #pragma GCC diagnostic pop
4756 #endif
4757 
4758 #endif // STB_TRUETYPE_IMPLEMENTATION
4759 
4760 
4761 // FULL VERSION HISTORY
4762 //
4763 // 1.19 (2018-02-11) OpenType GPOS kerning (horizontal only), STBTT_fmod
4764 // 1.18 (2018-01-29) add missing function
4765 // 1.17 (2017-07-23) make more arguments const; doc fix
4766 // 1.16 (2017-07-12) SDF support
4767 // 1.15 (2017-03-03) make more arguments const
4768 // 1.14 (2017-01-16) num-fonts-in-TTC function
4769 // 1.13 (2017-01-02) support OpenType fonts, certain Apple fonts
4770 // 1.12 (2016-10-25) suppress warnings about casting away const with -Wcast-qual
4771 // 1.11 (2016-04-02) fix unused-variable warning
4772 // 1.10 (2016-04-02) allow user-defined fabs() replacement
4773 // fix memory leak if fontsize=0.0
4774 // fix warning from duplicate typedef
4775 // 1.09 (2016-01-16) warning fix; avoid crash on outofmem; use alloc userdata for PackFontRanges
4776 // 1.08 (2015-09-13) document stbtt_Rasterize(); fixes for vertical & horizontal edges
4777 // 1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints;
4778 // allow PackFontRanges to pack and render in separate phases;
4779 // fix stbtt_GetFontOFfsetForIndex (never worked for non-0 input?);
4780 // fixed an assert() bug in the new rasterizer
4781 // replace assert() with STBTT_assert() in new rasterizer
4782 // 1.06 (2015-07-14) performance improvements (~35% faster on x86 and x64 on test machine)
4783 // also more precise AA rasterizer, except if shapes overlap
4784 // remove need for STBTT_sort
4785 // 1.05 (2015-04-15) fix misplaced definitions for STBTT_STATIC
4786 // 1.04 (2015-04-15) typo in example
4787 // 1.03 (2015-04-12) STBTT_STATIC, fix memory leak in new packing, various fixes
4788 // 1.02 (2014-12-10) fix various warnings & compile issues w/ stb_rect_pack, C++
4789 // 1.01 (2014-12-08) fix subpixel position when oversampling to exactly match
4790 // non-oversampled; STBTT_POINT_SIZE for packed case only
4791 // 1.00 (2014-12-06) add new PackBegin etc. API, w/ support for oversampling
4792 // 0.99 (2014-09-18) fix multiple bugs with subpixel rendering (ryg)
4793 // 0.9 (2014-08-07) support certain mac/iOS fonts without an MS platformID
4794 // 0.8b (2014-07-07) fix a warning
4795 // 0.8 (2014-05-25) fix a few more warnings
4796 // 0.7 (2013-09-25) bugfix: subpixel glyph bug fixed in 0.5 had come back
4797 // 0.6c (2012-07-24) improve documentation
4798 // 0.6b (2012-07-20) fix a few more warnings
4799 // 0.6 (2012-07-17) fix warnings; added stbtt_ScaleForMappingEmToPixels,
4800 // stbtt_GetFontBoundingBox, stbtt_IsGlyphEmpty
4801 // 0.5 (2011-12-09) bugfixes:
4802 // subpixel glyph renderer computed wrong bounding box
4803 // first vertex of shape can be off-curve (FreeSans)
4804 // 0.4b (2011-12-03) fixed an error in the font baking example
4805 // 0.4 (2011-12-01) kerning, subpixel rendering (tor)
4806 // bugfixes for:
4807 // codepoint-to-glyph conversion using table fmt=12
4808 // codepoint-to-glyph conversion using table fmt=4
4809 // stbtt_GetBakedQuad with non-square texture (Zer)
4810 // updated Hello World! sample to use kerning and subpixel
4811 // fixed some warnings
4812 // 0.3 (2009-06-24) cmap fmt=12, compound shapes (MM)
4813 // userdata, malloc-from-userdata, non-zero fill (stb)
4814 // 0.2 (2009-03-11) Fix unsigned/signed char warnings
4815 // 0.1 (2009-03-09) First public release
4816 //
4817 
4818 /*
4819 ------------------------------------------------------------------------------
4820 This software is available under 2 licenses -- choose whichever you prefer.
4821 ------------------------------------------------------------------------------
4822 ALTERNATIVE A - MIT License
4823 Copyright (c) 2017 Sean Barrett
4824 Permission is hereby granted, free of charge, to any person obtaining a copy of
4825 this software and associated documentation files (the "Software"), to deal in
4826 the Software without restriction, including without limitation the rights to
4827 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
4828 of the Software, and to permit persons to whom the Software is furnished to do
4829 so, subject to the following conditions:
4830 The above copyright notice and this permission notice shall be included in all
4831 copies or substantial portions of the Software.
4832 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4833 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4834 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
4835 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
4836 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
4837 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
4838 SOFTWARE.
4839 ------------------------------------------------------------------------------
4840 ALTERNATIVE B - Public Domain (www.unlicense.org)
4841 This is free and unencumbered software released into the public domain.
4842 Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
4843 software, either in source code form or as a compiled binary, for any purpose,
4844 commercial or non-commercial, and by any means.
4845 In jurisdictions that recognize copyright laws, the author or authors of this
4846 software dedicate any and all copyright interest in the software to the public
4847 domain. We make this dedication for the benefit of the public at large and to
4848 the detriment of our heirs and successors. We intend this dedication to be an
4849 overt act of relinquishment in perpetuity of all present and future rights to
4850 this software under copyright law.
4851 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4852 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4853 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
4854 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
4855 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
4856 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
4857 ------------------------------------------------------------------------------
4858 */
int w
Definition: stb_truetype.h:893
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_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2)
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)
int kern
Definition: stb_truetype.h:707
Definition: stb_truetype.h:1044
int cursor
Definition: stb_truetype.h:511
float t0
Definition: stb_truetype.h:540
unsigned short x1
Definition: stb_truetype.h:524
STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
Definition: stb_truetype.h:1014
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)
Definition: stb_truetype.h:522
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_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2)
stbtt_packedchar * chardata_for_range
Definition: stb_truetype.h:618
Definition: stb_truetype.h:1036
int index_map
Definition: stb_truetype.h:708
unsigned int v_oversample
Definition: stb_truetype.h:672
Definition: stb_truetype.h:1020
float x1
Definition: stb_truetype.h:541
STBTT_DEF int stbtt_GetNumberOfFonts(const unsigned char *data)
Definition: stb_truetype.h:1056
Definition: stb_truetype.h:1027
float xoff
Definition: stb_truetype.h:525
int * array_of_unicode_codepoints
Definition: stb_truetype.h:616
int stride
Definition: stb_truetype.h:893
float x0
Definition: stb_truetype.h:540
STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **vertices)
Definition: stb_truetype.h:1045
unsigned char type
Definition: stb_truetype.h:811
stbtt_vertex_type cy
Definition: stb_truetype.h:810
Definition: stb_truetype.h:1051
Definition: stb_truetype.h:1047
int height
Definition: stb_rect_pack.h:175
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)
Definition: stb_rect_pack.h:106
Definition: stb_truetype.h:1030
Definition: stb_rect_pack.h:166
Definition: stb_truetype.h:1042
STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects)
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)
Definition: stb_truetype.h:538
STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1)
Definition: stb_truetype.h:1036
STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes)
Definition: stb_truetype.h:1029
voidpf void uLong size
Definition: ioapi.h:39
STBTT_DEF void stbtt_PackEnd(stbtt_pack_context *spc)
STBTT_DEF void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect *rects, int num_rects)
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__buf fdselect
Definition: stb_truetype.h:716
Definition: stb_truetype.h:800
Definition: stb_truetype.h:1043
STBTT_DEF void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata)
Definition: stb_truetype.h:1037
unsigned int h_oversample
Definition: stb_truetype.h:672
unsigned int GLuint
Definition: DtGlTextureBufferObject.h:18
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
Definition: stb_truetype.h:1045
Definition: stb_truetype.h:1035
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__buf cff
Definition: stb_truetype.h:711
unsigned short y1
Definition: stb_truetype.h:570
unsigned char * pixels
Definition: stb_truetype.h:894
STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1)
STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph)
stbtt__buf subrs
Definition: stb_truetype.h:714
Definition: stb_truetype.h:1023
void * nodes
Definition: stb_truetype.h:674
struct stbrp_context stbrp_context
Definition: stb_rect_pack.h:71
Definition: stb_truetype.h:1054
unsigned char v_oversample
Definition: stb_truetype.h:619
unsigned short stbrp_coord
Definition: stb_rect_pack.h:78
stbtt_vertex_type y
Definition: stb_truetype.h:810
#define stbtt_vertex_type
Definition: stb_truetype.h:807
int numGlyphs
Definition: stb_truetype.h:705
Definition: stb_truetype.h:1053
Definition: stb_truetype.h:612
stbrp_coord y
Definition: stb_rect_pack.h:115
Definition: stb_truetype.h:1051
Definition: stb_truetype.h:1046
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_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_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges)
Definition: stb_truetype.h:1021
STBTT_DEF const char * stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID)
stbtt__buf charstrings
Definition: stb_truetype.h:712
Definition: stb_truetype.h:1054
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)
Definition: stb_truetype.h:1055
int hmtx
Definition: stb_truetype.h:707
int was_packed
Definition: stb_rect_pack.h:116
Definition: stb_truetype.h:1044
Definition: stb_truetype.h:1047
STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices)
STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing)
float xadvance
Definition: stb_truetype.h:525
stbtt__buf gsubrs
Definition: stb_truetype.h:713
int height
Definition: stb_truetype.h:669
int head
Definition: stb_truetype.h:707
STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap)
STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset)
int hhea
Definition: stb_truetype.h:707
int glyf
Definition: stb_truetype.h:707
Definition: stb_truetype.h:1028
Definition: stb_truetype.h:1057
stbrp_coord x
Definition: stb_rect_pack.h:115
stbtt_vertex_type x
Definition: stb_truetype.h:810
float yoff2
Definition: stb_truetype.h:572
Definition: stb_truetype.h:1034
unsigned short x1
Definition: stb_truetype.h:570
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)
Definition: stb_truetype.h:665
STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2)
float s0
Definition: stb_truetype.h:540
int fontstart
Definition: stb_truetype.h:703
Definition: stb_truetype.h:1055
float yoff
Definition: stb_truetype.h:571
stbrp_coord w
Definition: stb_rect_pack.h:112
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)
void * pack_info
Definition: stb_truetype.h:667
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)
struct stbrp_node stbrp_node
Definition: stb_rect_pack.h:72
Definition: stb_truetype.h:1035
Definition: stb_truetype.h:799
unsigned short y0
Definition: stb_truetype.h:570
Definition: stb_rect_pack.h:172
float xoff
Definition: stb_truetype.h:571
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)
Definition: asyncJobServer.h:39
unsigned char * data
Definition: stb_truetype.h:702
unsigned char h_oversample
Definition: stb_truetype.h:619
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)
Definition: stb_truetype.h:568
Definition: stb_truetype.h:1019
void * user_allocator_context
Definition: stb_truetype.h:666
#define STBTT_DEF
Definition: stb_truetype.h:500
Definition: stb_truetype.h:1015
Definition: stb_truetype.h:508
Definition: stb_truetype.h:1043
stbtt_vertex_type cx
Definition: stb_truetype.h:810
Definition: stb_truetype.h:1034
float s1
Definition: stb_truetype.h:541
Definition: stb_truetype.h:1013
stbtt__buf fontdicts
Definition: stb_truetype.h:715
int width
Definition: stb_rect_pack.h:174
float font_size
Definition: stb_truetype.h:614
unsigned short x0
Definition: stb_truetype.h:524
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)
Definition: stb_truetype.h:1012
Definition: stb_truetype.h:1037
int size
Definition: stb_truetype.h:512
Definition: stb_truetype.h:1053
STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index)
DT_DLL_VRVCORE double length(const makVrv::DtCoordinateSystem &, const std::vector< DtVector > &vertices)
Returns the total distance of a segmented line defined by the provided vector of vertices. Coordinates are in local database coordinates. The coordinate system is used to convert between the local database coordinates and geocentric. All distance is in 2D – the Z value is ignored.
STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1)
unsigned char * data
Definition: stb_truetype.h:510
Definition: stb_truetype.h:699
STBTT_DEF float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels)
stbrp_coord h
Definition: stb_rect_pack.h:112
int first_unicode_codepoint_in_range
Definition: stb_truetype.h:615
float y0
Definition: stb_truetype.h:540
STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing)
Definition: stb_truetype.h:1042
int h
Definition: stb_truetype.h:893
STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample)
STBTT_DEF int stbtt_GetFontVMetricsOS2(const stbtt_fontinfo *info, int *typoAscent, int *typoDescent, int *typoLineGap)
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)
unsigned char * pixels
Definition: stb_truetype.h:673
unsigned short y0
Definition: stb_truetype.h:524
STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint)
int indexToLocFormat
Definition: stb_truetype.h:709
float yoff
Definition: stb_truetype.h:525
Definition: stb_truetype.h:798
STBTT_DEF void stbtt_FreeSDF(unsigned char *bitmap, void *userdata)
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)
int id
Definition: stb_rect_pack.h:109
Definition: stb_truetype.h:1046
float xadvance
Definition: stb_truetype.h:571
STBTT_DEF float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float pixels)
Definition: stb_truetype.h:1056
unsigned short y1
Definition: stb_truetype.h:524
float xoff2
Definition: stb_truetype.h:572
Definition: stb_truetype.h:1057
voidpf uLong offset
Definition: ioapi.h:42
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_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index)
int stride_in_bytes
Definition: stb_truetype.h:670
Definition: stb_truetype.h:808
int gpos
Definition: stb_truetype.h:707
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)
int padding
Definition: stb_truetype.h:671
int num_chars
Definition: stb_truetype.h:617
float y1
Definition: stb_truetype.h:541
void * userdata
Definition: stb_truetype.h:701
Definition: stb_truetype.h:1052
Definition: stb_truetype.h:801
float t1
Definition: stb_truetype.h:541
int loca
Definition: stb_truetype.h:707
STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *fontdata, const char *name, int flags)
Definition: stb_truetype.h:891
unsigned short x0
Definition: stb_truetype.h:570
STBTT_DEF int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices)
Definition: stb_truetype.h:1052
int width
Definition: stb_truetype.h:668
STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects)
Definition: stb_truetype.h:1022

Document ID: Generated on Thu Oct 23 22:29:17 EDT 2025 from SVN revision 280951
Copyright © 2005-2024 MAK Technologies. All Rights Reserved (www.mak.com)