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