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