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