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