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