Hasty Badger
Small UI library (a branch of Turbo Badger)
 All Classes Namespaces Functions Variables Enumerations Enumerator Friends Groups Pages
stb_truetype.h
1 // stb_truetype.h - v1.11 - public domain
2 // authored from 2009-2015 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 //
10 // Todo:
11 // non-MS cmaps
12 // crashproof on bad data
13 // hinting? (no longer patented)
14 // cleartype-style AA?
15 // optimize: use simple memory allocator for intermediates
16 // optimize: build edge-list directly from curves
17 // optimize: rasterize directly from curves?
18 //
19 // ADDITIONAL CONTRIBUTORS
20 //
21 // Mikko Mononen: compound shape support, more cmap formats
22 // Tor Andersson: kerning, subpixel rendering
23 //
24 // Misc other:
25 // Ryan Gordon
26 // Simon Glass
27 //
28 // Bug/warning reports/fixes:
29 // "Zer" on mollyrocket (with fix)
30 // Cass Everitt
31 // stoiko (Haemimont Games)
32 // Brian Hook
33 // Walter van Niftrik
34 // David Gow
35 // David Given
36 // Ivan-Assen Ivanov
37 // Anthony Pesch
38 // Johan Duparc
39 // Hou Qiming
40 // Fabian "ryg" Giesen
41 // Martins Mozeiko
42 // Cap Petschulat
43 // Omar Cornut
44 // github:aloucks
45 // Peter LaValle
46 // Sergey Popov
47 // Giumo X. Clanjor
48 // Higor Euripedes
49 // Thomas Fields
50 // Derek Vinyard
51 //
52 // VERSION HISTORY
53 //
54 // 1.11 (2016-04-02) fix unused-variable warning
55 // 1.10 (2016-04-02) user-defined fabs(); rare memory leak; remove duplicate typedef
56 // 1.09 (2016-01-16) warning fix; avoid crash on outofmem; use allocation userdata properly
57 // 1.08 (2015-09-13) document stbtt_Rasterize(); fixes for vertical & horizontal edges
58 // 1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints;
59 // variant PackFontRanges to pack and render in separate phases;
60 // fix stbtt_GetFontOFfsetForIndex (never worked for non-0 input?);
61 // fixed an assert() bug in the new rasterizer
62 // replace assert() with STBTT_assert() in new rasterizer
63 // 1.06 (2015-07-14) performance improvements (~35% faster on x86 and x64 on test machine)
64 // also more precise AA rasterizer, except if shapes overlap
65 // remove need for STBTT_sort
66 // 1.05 (2015-04-15) fix misplaced definitions for STBTT_STATIC
67 // 1.04 (2015-04-15) typo in example
68 // 1.03 (2015-04-12) STBTT_STATIC, fix memory leak in new packing, various fixes
69 //
70 // Full history can be found at the end of this file.
71 //
72 // LICENSE
73 //
74 // This software is dual-licensed to the public domain and under the following
75 // license: you are granted a perpetual, irrevocable license to copy, modify,
76 // publish, and distribute this file as you see fit.
77 //
78 // USAGE
79 //
80 // Include this file in whatever places neeed to refer to it. In ONE C/C++
81 // file, write:
82 // #define STB_TRUETYPE_IMPLEMENTATION
83 // before the #include of this file. This expands out the actual
84 // implementation into that C/C++ file.
85 //
86 // To make the implementation private to the file that generates the implementation,
87 // #define STBTT_STATIC
88 //
89 // Simple 3D API (don't ship this, but it's fine for tools and quick start)
90 // stbtt_BakeFontBitmap() -- bake a font to a bitmap for use as texture
91 // stbtt_GetBakedQuad() -- compute quad to draw for a given char
92 //
93 // Improved 3D API (more shippable):
94 // #include "stb_rect_pack.h" -- optional, but you really want it
95 // stbtt_PackBegin()
96 // stbtt_PackSetOversample() -- for improved quality on small fonts
97 // stbtt_PackFontRanges() -- pack and renders
98 // stbtt_PackEnd()
99 // stbtt_GetPackedQuad()
100 //
101 // "Load" a font file from a memory buffer (you have to keep the buffer loaded)
102 // stbtt_InitFont()
103 // stbtt_GetFontOffsetForIndex() -- use for TTC font collections
104 //
105 // Render a unicode codepoint to a bitmap
106 // stbtt_GetCodepointBitmap() -- allocates and returns a bitmap
107 // stbtt_MakeCodepointBitmap() -- renders into bitmap you provide
108 // stbtt_GetCodepointBitmapBox() -- how big the bitmap must be
109 //
110 // Character advance/positioning
111 // stbtt_GetCodepointHMetrics()
112 // stbtt_GetFontVMetrics()
113 // stbtt_GetCodepointKernAdvance()
114 //
115 // Starting with version 1.06, the rasterizer was replaced with a new,
116 // faster and generally-more-precise rasterizer. The new rasterizer more
117 // accurately measures pixel coverage for anti-aliasing, except in the case
118 // where multiple shapes overlap, in which case it overestimates the AA pixel
119 // coverage. Thus, anti-aliasing of intersecting shapes may look wrong. If
120 // this turns out to be a problem, you can re-enable the old rasterizer with
121 // #define STBTT_RASTERIZER_VERSION 1
122 // which will incur about a 15% speed hit.
123 //
124 // ADDITIONAL DOCUMENTATION
125 //
126 // Immediately after this block comment are a series of sample programs.
127 //
128 // After the sample programs is the "header file" section. This section
129 // includes documentation for each API function.
130 //
131 // Some important concepts to understand to use this library:
132 //
133 // Codepoint
134 // Characters are defined by unicode codepoints, e.g. 65 is
135 // uppercase A, 231 is lowercase c with a cedilla, 0x7e30 is
136 // the hiragana for "ma".
137 //
138 // Glyph
139 // A visual character shape (every codepoint is rendered as
140 // some glyph)
141 //
142 // Glyph index
143 // A font-specific integer ID representing a glyph
144 //
145 // Baseline
146 // Glyph shapes are defined relative to a baseline, which is the
147 // bottom of uppercase characters. Characters extend both above
148 // and below the baseline.
149 //
150 // Current Point
151 // As you draw text to the screen, you keep track of a "current point"
152 // which is the origin of each character. The current point's vertical
153 // position is the baseline. Even "baked fonts" use this model.
154 //
155 // Vertical Font Metrics
156 // The vertical qualities of the font, used to vertically position
157 // and space the characters. See docs for stbtt_GetFontVMetrics.
158 //
159 // Font Size in Pixels or Points
160 // The preferred interface for specifying font sizes in stb_truetype
161 // is to specify how tall the font's vertical extent should be in pixels.
162 // If that sounds good enough, skip the next paragraph.
163 //
164 // Most font APIs instead use "points", which are a common typographic
165 // measurement for describing font size, defined as 72 points per inch.
166 // stb_truetype provides a point API for compatibility. However, true
167 // "per inch" conventions don't make much sense on computer displays
168 // since they different monitors have different number of pixels per
169 // inch. For example, Windows traditionally uses a convention that
170 // there are 96 pixels per inch, thus making 'inch' measurements have
171 // nothing to do with inches, and thus effectively defining a point to
172 // be 1.333 pixels. Additionally, the TrueType font data provides
173 // an explicit scale factor to scale a given font's glyphs to points,
174 // but the author has observed that this scale factor is often wrong
175 // for non-commercial fonts, thus making fonts scaled in points
176 // according to the TrueType spec incoherently sized in practice.
177 //
178 // ADVANCED USAGE
179 //
180 // Quality:
181 //
182 // - Use the functions with Subpixel at the end to allow your characters
183 // to have subpixel positioning. Since the font is anti-aliased, not
184 // hinted, this is very import for quality. (This is not possible with
185 // baked fonts.)
186 //
187 // - Kerning is now supported, and if you're supporting subpixel rendering
188 // then kerning is worth using to give your text a polished look.
189 //
190 // Performance:
191 //
192 // - Convert Unicode codepoints to glyph indexes and operate on the glyphs;
193 // if you don't do this, stb_truetype is forced to do the conversion on
194 // every call.
195 //
196 // - There are a lot of memory allocations. We should modify it to take
197 // a temp buffer and allocate from the temp buffer (without freeing),
198 // should help performance a lot.
199 //
200 // NOTES
201 //
202 // The system uses the raw data found in the .ttf file without changing it
203 // and without building auxiliary data structures. This is a bit inefficient
204 // on little-endian systems (the data is big-endian), but assuming you're
205 // caching the bitmaps or glyph shapes this shouldn't be a big deal.
206 //
207 // It appears to be very hard to programmatically determine what font a
208 // given file is in a general way. I provide an API for this, but I don't
209 // recommend it.
210 //
211 //
212 // SOURCE STATISTICS (based on v0.6c, 2050 LOC)
213 //
214 // Documentation & header file 520 LOC \___ 660 LOC documentation
215 // Sample code 140 LOC /
216 // Truetype parsing 620 LOC ---- 620 LOC TrueType
217 // Software rasterization 240 LOC \ .
218 // Curve tesselation 120 LOC \__ 550 LOC Bitmap creation
219 // Bitmap management 100 LOC /
220 // Baked bitmap interface 70 LOC /
221 // Font name matching & access 150 LOC ---- 150
222 // C runtime library abstraction 60 LOC ---- 60
223 //
224 //
225 // PERFORMANCE MEASUREMENTS FOR 1.06:
226 //
227 // 32-bit 64-bit
228 // Previous release: 8.83 s 7.68 s
229 // Pool allocations: 7.72 s 6.34 s
230 // Inline sort : 6.54 s 5.65 s
231 // New rasterizer : 5.63 s 5.00 s
232 
238 //
239 // Incomplete text-in-3d-api example, which draws quads properly aligned to be lossless
240 //
241 #if 0
242 #define STB_TRUETYPE_IMPLEMENTATION // force following include to generate implementation
243 #include "stb_truetype.h"
244 
245 unsigned char ttf_buffer[1<<20];
246 unsigned char temp_bitmap[512*512];
247 
248 stbtt_bakedchar cdata[96]; // ASCII 32..126 is 95 glyphs
249 GLuint ftex;
250 
251 void my_stbtt_initfont(void)
252 {
253  fread(ttf_buffer, 1, 1<<20, fopen("c:/windows/fonts/times.ttf", "rb"));
254  stbtt_BakeFontBitmap(ttf_buffer,0, 32.0, temp_bitmap,512,512, 32,96, cdata); // no guarantee this fits!
255  // can free ttf_buffer at this point
256  glGenTextures(1, &ftex);
257  glBindTexture(GL_TEXTURE_2D, ftex);
258  glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 512,512, 0, GL_ALPHA, GL_UNSIGNED_BYTE, temp_bitmap);
259  // can free temp_bitmap at this point
260  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
261 }
262 
263 void my_stbtt_print(float x, float y, char *text)
264 {
265  // assume orthographic projection with units = screen pixels, origin at top left
266  glEnable(GL_TEXTURE_2D);
267  glBindTexture(GL_TEXTURE_2D, ftex);
268  glBegin(GL_QUADS);
269  while (*text) {
270  if (*text >= 32 && *text < 128) {
272  stbtt_GetBakedQuad(cdata, 512,512, *text-32, &x,&y,&q,1);//1=opengl & d3d10+,0=d3d9
273  glTexCoord2f(q.s0,q.t1); glVertex2f(q.x0,q.y0);
274  glTexCoord2f(q.s1,q.t1); glVertex2f(q.x1,q.y0);
275  glTexCoord2f(q.s1,q.t0); glVertex2f(q.x1,q.y1);
276  glTexCoord2f(q.s0,q.t0); glVertex2f(q.x0,q.y1);
277  }
278  ++text;
279  }
280  glEnd();
281 }
282 #endif
283 //
284 //
286 //
287 // Complete program (this compiles): get a single bitmap, print as ASCII art
288 //
289 #if 0
290 #include <stdio.h>
291 #define STB_TRUETYPE_IMPLEMENTATION // force following include to generate implementation
292 #include "stb_truetype.h"
293 
294 char ttf_buffer[1<<25];
295 
296 int main(int argc, char **argv)
297 {
298  stbtt_fontinfo font;
299  unsigned char *bitmap;
300  int w,h,i,j,c = (argc > 1 ? atoi(argv[1]) : 'a'), s = (argc > 2 ? atoi(argv[2]) : 20);
301 
302  fread(ttf_buffer, 1, 1<<25, fopen(argc > 3 ? argv[3] : "c:/windows/fonts/arialbd.ttf", "rb"));
303 
304  stbtt_InitFont(&font, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer,0));
305  bitmap = stbtt_GetCodepointBitmap(&font, 0,stbtt_ScaleForPixelHeight(&font, s), c, &w, &h, 0,0);
306 
307  for (j=0; j < h; ++j) {
308  for (i=0; i < w; ++i)
309  putchar(" .:ioVM@"[bitmap[j*w+i]>>5]);
310  putchar('\n');
311  }
312  return 0;
313 }
314 #endif
315 //
316 // Output:
317 //
318 // .ii.
319 // @@@@@@.
320 // V@Mio@@o
321 // :i. V@V
322 // :oM@@M
323 // :@@@MM@M
324 // @@o o@M
325 // :@@. M@M
326 // @@@o@@@@
327 // :M@@V:@@.
328 //
330 //
331 // Complete program: print "Hello World!" banner, with bugs
332 //
333 #if 0
334 char buffer[24<<20];
335 unsigned char screen[20][79];
336 
337 int main(int arg, char **argv)
338 {
339  stbtt_fontinfo font;
340  int i,j,ascent,baseline,ch=0;
341  float scale, xpos=2; // leave a little padding in case the character extends left
342  char *text = "Heljo World!"; // intentionally misspelled to show 'lj' brokenness
343 
344  fread(buffer, 1, 1000000, fopen("c:/windows/fonts/arialbd.ttf", "rb"));
345  stbtt_InitFont(&font, buffer, 0);
346 
347  scale = stbtt_ScaleForPixelHeight(&font, 15);
348  stbtt_GetFontVMetrics(&font, &ascent,0,0);
349  baseline = (int) (ascent*scale);
350 
351  while (text[ch]) {
352  int advance,lsb,x0,y0,x1,y1;
353  float x_shift = xpos - (float) floor(xpos);
354  stbtt_GetCodepointHMetrics(&font, text[ch], &advance, &lsb);
355  stbtt_GetCodepointBitmapBoxSubpixel(&font, text[ch], scale,scale,x_shift,0, &x0,&y0,&x1,&y1);
356  stbtt_MakeCodepointBitmapSubpixel(&font, &screen[baseline + y0][(int) xpos + x0], x1-x0,y1-y0, 79, scale,scale,x_shift,0, text[ch]);
357  // note that this stomps the old data, so where character boxes overlap (e.g. 'lj') it's wrong
358  // because this API is really for baking character bitmaps into textures. if you want to render
359  // a sequence of characters, you really need to render each bitmap to a temp buffer, then
360  // "alpha blend" that into the working buffer
361  xpos += (advance * scale);
362  if (text[ch+1])
363  xpos += scale*stbtt_GetCodepointKernAdvance(&font, text[ch],text[ch+1]);
364  ++ch;
365  }
366 
367  for (j=0; j < 20; ++j) {
368  for (i=0; i < 78; ++i)
369  putchar(" .:ioVM@"[screen[j][i]>>5]);
370  putchar('\n');
371  }
372 
373  return 0;
374 }
375 #endif
376 
377 
385 
386 #ifdef STB_TRUETYPE_IMPLEMENTATION
387  // #define your own (u)stbtt_int8/16/32 before including to override this
388  #ifndef stbtt_uint8
389  typedef unsigned char stbtt_uint8;
390  typedef signed char stbtt_int8;
391  typedef unsigned short stbtt_uint16;
392  typedef signed short stbtt_int16;
393  typedef unsigned int stbtt_uint32;
394  typedef signed int stbtt_int32;
395  #endif
396 
397  typedef char stbtt__check_size32[sizeof(stbtt_int32)==4 ? 1 : -1];
398  typedef char stbtt__check_size16[sizeof(stbtt_int16)==2 ? 1 : -1];
399 
400  // #define your own STBTT_ifloor/STBTT_iceil() to avoid math.h
401  #ifndef STBTT_ifloor
402  #include <math.h>
403  #define STBTT_ifloor(x) ((int) floor(x))
404  #define STBTT_iceil(x) ((int) ceil(x))
405  #endif
406 
407  #ifndef STBTT_sqrt
408  #include <math.h>
409  #define STBTT_sqrt(x) sqrt(x)
410  #endif
411 
412  #ifndef STBTT_fabs
413  #include <math.h>
414  #define STBTT_fabs(x) fabs(x)
415  #endif
416 
417  // #define your own functions "STBTT_malloc" / "STBTT_free" to avoid malloc.h
418  #ifndef STBTT_malloc
419  #include <stdlib.h>
420  #define STBTT_malloc(x,u) ((void)(u),malloc(x))
421  #define STBTT_free(x,u) ((void)(u),free(x))
422  #endif
423 
424  #ifndef STBTT_assert
425  #include <assert.h>
426  #define STBTT_assert(x) assert(x)
427  #endif
428 
429  #ifndef STBTT_strlen
430  #include <string.h>
431  #define STBTT_strlen(x) strlen(x)
432  #endif
433 
434  #ifndef STBTT_memcpy
435  #include <memory.h>
436  #define STBTT_memcpy memcpy
437  #define STBTT_memset memset
438  #endif
439 #endif
440 
447 
448 #ifndef __STB_INCLUDE_STB_TRUETYPE_H__
449 #define __STB_INCLUDE_STB_TRUETYPE_H__
450 
451 #ifdef STBTT_STATIC
452 #define STBTT_DEF static
453 #else
454 #define STBTT_DEF extern
455 #endif
456 
457 #ifdef __cplusplus
458 extern "C" {
459 #endif
460 
462 //
463 // TEXTURE BAKING API
464 //
465 // If you use this API, you only have to call two functions ever.
466 //
467 
468 typedef struct
469 {
470  unsigned short x0,y0,x1,y1; // coordinates of bbox in bitmap
471  float xoff,yoff,xadvance;
473 
474 STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // font location (use offset=0 for plain .ttf)
475  float pixel_height, // height of font in pixels
476  unsigned char *pixels, int pw, int ph, // bitmap to be filled in
477  int first_char, int num_chars, // characters to bake
478  stbtt_bakedchar *chardata); // you allocate this, it's num_chars long
479 // if return is positive, the first unused row of the bitmap
480 // if return is negative, returns the negative of the number of characters that fit
481 // if return is 0, no characters fit and no rows were used
482 // This uses a very crappy packing.
483 
484 typedef struct
485 {
486  float x0,y0,s0,t0; // top-left
487  float x1,y1,s1,t1; // bottom-right
489 
490 STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, // same data as above
491  int char_index, // character to display
492  float *xpos, float *ypos, // pointers to current position in screen pixel space
493  stbtt_aligned_quad *q, // output: quad to draw
494  int opengl_fillrule); // true if opengl fill rule; false if DX9 or earlier
495 // Call GetBakedQuad with char_index = 'character - first_char', and it
496 // creates the quad you need to draw and advances the current position.
497 //
498 // The coordinate system used assumes y increases downwards.
499 //
500 // Characters will extend both above and below the current position;
501 // see discussion of "BASELINE" above.
502 //
503 // It's inefficient; you might want to c&p it and optimize it.
504 
505 
506 
508 //
509 // NEW TEXTURE BAKING API
510 //
511 // This provides options for packing multiple fonts into one atlas, not
512 // perfectly but better than nothing.
513 
514 typedef struct
515 {
516  unsigned short x0,y0,x1,y1; // coordinates of bbox in bitmap
517  float xoff,yoff,xadvance;
518  float xoff2,yoff2;
520 
522 typedef struct stbtt_fontinfo stbtt_fontinfo;
523 #ifndef STB_RECT_PACK_VERSION
524 typedef struct stbrp_rect stbrp_rect;
525 #endif
526 
527 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);
528 // Initializes a packing context stored in the passed-in stbtt_pack_context.
529 // Future calls using this context will pack characters into the bitmap passed
530 // in here: a 1-channel bitmap that is weight x height. stride_in_bytes is
531 // the distance from one row to the next (or 0 to mean they are packed tightly
532 // together). "padding" is the amount of padding to leave between each
533 // character (normally you want '1' for bitmaps you'll use as textures with
534 // bilinear filtering).
535 //
536 // Returns 0 on failure, 1 on success.
537 
538 STBTT_DEF void stbtt_PackEnd (stbtt_pack_context *spc);
539 // Cleans up the packing context and frees all memory.
540 
541 #define STBTT_POINT_SIZE(x) (-(x))
542 
543 STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, float font_size,
544  int first_unicode_char_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range);
545 // Creates character bitmaps from the font_index'th font found in fontdata (use
546 // font_index=0 if you don't know what that is). It creates num_chars_in_range
547 // bitmaps for characters with unicode values starting at first_unicode_char_in_range
548 // and increasing. Data for how to render them is stored in chardata_for_range;
549 // pass these to stbtt_GetPackedQuad to get back renderable quads.
550 //
551 // font_size is the full height of the character from ascender to descender,
552 // as computed by stbtt_ScaleForPixelHeight. To use a point size as computed
553 // by stbtt_ScaleForMappingEmToPixels, wrap the point size in STBTT_POINT_SIZE()
554 // and pass that result as 'font_size':
555 // ..., 20 , ... // font max minus min y is 20 pixels tall
556 // ..., STBTT_POINT_SIZE(20), ... // 'M' is 20 pixels tall
557 
558 typedef struct
559 {
560  float font_size;
561  int first_unicode_codepoint_in_range; // if non-zero, then the chars are continuous, and this is the first codepoint
562  int *array_of_unicode_codepoints; // if non-zero, then this is an array of unicode codepoints
563  int num_chars;
564  stbtt_packedchar *chardata_for_range; // output
565  unsigned char h_oversample, v_oversample; // don't set these, they're used internally
567 
568 STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges);
569 // Creates character bitmaps from multiple ranges of characters stored in
570 // ranges. This will usually create a better-packed bitmap than multiple
571 // calls to stbtt_PackFontRange. Note that you can call this multiple
572 // times within a single PackBegin/PackEnd.
573 
574 STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample);
575 // Oversampling a font increases the quality by allowing higher-quality subpixel
576 // positioning, and is especially valuable at smaller text sizes.
577 //
578 // This function sets the amount of oversampling for all following calls to
579 // stbtt_PackFontRange(s) or stbtt_PackFontRangesGatherRects for a given
580 // pack context. The default (no oversampling) is achieved by h_oversample=1
581 // and v_oversample=1. The total number of pixels required is
582 // h_oversample*v_oversample larger than the default; for example, 2x2
583 // oversampling requires 4x the storage of 1x1. For best results, render
584 // oversampled textures with bilinear filtering. Look at the readme in
585 // stb/tests/oversample for information about oversampled fonts
586 //
587 // To use with PackFontRangesGather etc., you must set it before calls
588 // call to PackFontRangesGatherRects.
589 
590 STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, // same data as above
591  int char_index, // character to display
592  float *xpos, float *ypos, // pointers to current position in screen pixel space
593  stbtt_aligned_quad *q, // output: quad to draw
594  int align_to_integer);
595 
596 STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects);
597 STBTT_DEF void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect *rects, int num_rects);
598 STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects);
599 // Calling these functions in sequence is roughly equivalent to calling
600 // stbtt_PackFontRanges(). If you more control over the packing of multiple
601 // fonts, or if you want to pack custom data into a font texture, take a look
602 // at the source to of stbtt_PackFontRanges() and create a custom version
603 // using these functions, e.g. call GatherRects multiple times,
604 // building up a single array of rects, then call PackRects once,
605 // then call RenderIntoRects repeatedly. This may result in a
606 // better packing than calling PackFontRanges multiple times
607 // (or it may not).
608 
609 // this is an opaque structure that you shouldn't mess with which holds
610 // all the context needed from PackBegin to PackEnd.
612  void *user_allocator_context;
613  void *pack_info;
614  int width;
615  int height;
616  int stride_in_bytes;
617  int padding;
618  unsigned int h_oversample, v_oversample;
619  unsigned char *pixels;
620  void *nodes;
621 };
622 
624 //
625 // FONT LOADING
626 //
627 //
628 
629 STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index);
630 // Each .ttf/.ttc file may have more than one font. Each font has a sequential
631 // index number starting from 0. Call this function to get the font offset for
632 // a given index; it returns -1 if the index is out of range. A regular .ttf
633 // file will only define one font and it always be at offset 0, so it will
634 // return '0' for index 0, and -1 for all other indices. You can just skip
635 // this step if you know it's that kind of font.
636 
637 
638 // The following structure is defined publically so you can declare one on
639 // the stack or as a global or etc, but you should treat it as opaque.
641 {
642  void * userdata;
643  unsigned char * data; // pointer to .ttf file
644  int fontstart; // offset of start of font
645 
646  int numGlyphs; // number of glyphs, needed for range checking
647 
648  int loca,head,glyf,hhea,hmtx,kern; // table locations as offset from start of .ttf
649  int index_map; // a cmap mapping for our chosen character encoding
650  int indexToLocFormat; // format needed to map from glyph index to glyph
651 };
652 
653 STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset);
654 // Given an offset into the file that defines a font, this function builds
655 // the necessary cached info for the rest of the system. You must allocate
656 // the stbtt_fontinfo yourself, and stbtt_InitFont will fill it out. You don't
657 // need to do anything special to free it, because the contents are pure
658 // value data with no additional data structures. Returns 0 on failure.
659 
660 
662 //
663 // CHARACTER TO GLYPH-INDEX CONVERSIOn
664 
665 STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint);
666 // If you're going to perform multiple operations on the same character
667 // and you want a speed-up, call this function with the character you're
668 // going to process, then use glyph-based functions instead of the
669 // codepoint-based functions.
670 
671 
673 //
674 // CHARACTER PROPERTIES
675 //
676 
677 STBTT_DEF float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float pixels);
678 // computes a scale factor to produce a font whose "height" is 'pixels' tall.
679 // Height is measured as the distance from the highest ascender to the lowest
680 // descender; in other words, it's equivalent to calling stbtt_GetFontVMetrics
681 // and computing:
682 // scale = pixels / (ascent - descent)
683 // so if you prefer to measure height by the ascent only, use a similar calculation.
684 
685 STBTT_DEF float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels);
686 // computes a scale factor to produce a font whose EM size is mapped to
687 // 'pixels' tall. This is probably what traditional APIs compute, but
688 // I'm not positive.
689 
690 STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap);
691 // ascent is the coordinate above the baseline the font extends; descent
692 // is the coordinate below the baseline the font extends (i.e. it is typically negative)
693 // lineGap is the spacing between one row's descent and the next row's ascent...
694 // so you should advance the vertical position by "*ascent - *descent + *lineGap"
695 // these are expressed in unscaled coordinates, so you must multiply by
696 // the scale factor for a given size
697 
698 STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1);
699 // the bounding box around all possible characters
700 
701 STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing);
702 // leftSideBearing is the offset from the current horizontal position to the left edge of the character
703 // advanceWidth is the offset from the current horizontal position to the next horizontal position
704 // these are expressed in unscaled coordinates
705 
706 STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2);
707 // an additional amount to add to the 'advance' value between ch1 and ch2
708 
709 STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1);
710 // Gets the bounding box of the visible part of the glyph, in unscaled coordinates
711 
712 STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing);
713 STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2);
714 STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1);
715 // as above, but takes one or more glyph indices for greater efficiency
716 
717 
719 //
720 // GLYPH SHAPES (you probably don't need these, but they have to go before
721 // the bitmaps for C declaration-order reasons)
722 //
723 
724 #ifndef STBTT_vmove // you can predefine these to use different values (but why?)
725  enum {
726  STBTT_vmove=1,
727  STBTT_vline,
728  STBTT_vcurve
729  };
730 #endif
731 
732 #ifndef stbtt_vertex // you can predefine this to use different values
733  // (we share this with other code at RAD)
734  #define stbtt_vertex_type short // can't use stbtt_int16 because that's not visible in the header file
735  typedef struct
736  {
737  stbtt_vertex_type x,y,cx,cy;
738  unsigned char type,padding;
739  } stbtt_vertex;
740 #endif
741 
742 STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index);
743 // returns non-zero if nothing is drawn for this glyph
744 
745 STBTT_DEF int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices);
746 STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **vertices);
747 // returns # of vertices and fills *vertices with the pointer to them
748 // these are expressed in "unscaled" coordinates
749 //
750 // The shape is a series of countours. Each one starts with
751 // a STBTT_moveto, then consists of a series of mixed
752 // STBTT_lineto and STBTT_curveto segments. A lineto
753 // draws a line from previous endpoint to its x,y; a curveto
754 // draws a quadratic bezier from previous endpoint to
755 // its x,y, using cx,cy as the bezier control point.
756 
757 STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices);
758 // frees the data allocated above
759 
761 //
762 // BITMAP RENDERING
763 //
764 
765 STBTT_DEF void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata);
766 // frees the bitmap allocated below
767 
768 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);
769 // allocates a large-enough single-channel 8bpp bitmap and renders the
770 // specified character/glyph at the specified scale into it, with
771 // antialiasing. 0 is no coverage (transparent), 255 is fully covered (opaque).
772 // *width & *height are filled out with the width & height of the bitmap,
773 // which is stored left-to-right, top-to-bottom.
774 //
775 // xoff/yoff are the offset it pixel space from the glyph origin to the top-left of the bitmap
776 
777 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);
778 // the same as stbtt_GetCodepoitnBitmap, but you can specify a subpixel
779 // shift for the character
780 
781 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);
782 // the same as stbtt_GetCodepointBitmap, but you pass in storage for the bitmap
783 // in the form of 'output', with row spacing of 'out_stride' bytes. the bitmap
784 // is clipped to out_w/out_h bytes. Call stbtt_GetCodepointBitmapBox to get the
785 // width and height and positioning info for it first.
786 
787 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);
788 // same as stbtt_MakeCodepointBitmap, but you can specify a subpixel
789 // shift for the character
790 
791 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);
792 // get the bbox of the bitmap centered around the glyph origin; so the
793 // bitmap width is ix1-ix0, height is iy1-iy0, and location to place
794 // the bitmap top left is (leftSideBearing*scale,iy0).
795 // (Note that the bitmap uses y-increases-down, but the shape uses
796 // y-increases-up, so CodepointBitmapBox and CodepointBox are inverted.)
797 
798 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);
799 // same as stbtt_GetCodepointBitmapBox, but you can specify a subpixel
800 // shift for the character
801 
802 // the following functions are equivalent to the above functions, but operate
803 // on glyph indices instead of Unicode codepoints (for efficiency)
804 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);
805 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);
806 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);
807 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);
808 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);
809 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);
810 
811 
812 // @TODO: don't expose this structure
813 typedef struct
814 {
815  int w,h,stride;
816  unsigned char *pixels;
817 } stbtt__bitmap;
818 
819 // rasterize a shape with quadratic beziers into a bitmap
820 STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, // 1-channel bitmap to draw into
821  float flatness_in_pixels, // allowable error of curve in pixels
822  stbtt_vertex *vertices, // array of vertices defining shape
823  int num_verts, // number of vertices in above array
824  float scale_x, float scale_y, // scale applied to input vertices
825  float shift_x, float shift_y, // translation applied to input vertices
826  int x_off, int y_off, // another translation applied to input
827  int invert, // if non-zero, vertically flip shape
828  void *userdata); // context for to STBTT_MALLOC
829 
831 //
832 // Finding the right font...
833 //
834 // You should really just solve this offline, keep your own tables
835 // of what font is what, and don't try to get it out of the .ttf file.
836 // That's because getting it out of the .ttf file is really hard, because
837 // the names in the file can appear in many possible encodings, in many
838 // possible languages, and e.g. if you need a case-insensitive comparison,
839 // the details of that depend on the encoding & language in a complex way
840 // (actually underspecified in truetype, but also gigantic).
841 //
842 // But you can use the provided functions in two possible ways:
843 // stbtt_FindMatchingFont() will use *case-sensitive* comparisons on
844 // unicode-encoded names to try to find the font you want;
845 // you can run this before calling stbtt_InitFont()
846 //
847 // stbtt_GetFontNameString() lets you get any of the various strings
848 // from the file yourself and do your own comparisons on them.
849 // You have to have called stbtt_InitFont() first.
850 
851 
852 STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *fontdata, const char *name, int flags);
853 // returns the offset (not index) of the font that matches, or -1 if none
854 // if you use STBTT_MACSTYLE_DONTCARE, use a font name like "Arial Bold".
855 // if you use any other flag, use a font name like "Arial"; this checks
856 // the 'macStyle' header field; i don't know if fonts set this consistently
857 #define STBTT_MACSTYLE_DONTCARE 0
858 #define STBTT_MACSTYLE_BOLD 1
859 #define STBTT_MACSTYLE_ITALIC 2
860 #define STBTT_MACSTYLE_UNDERSCORE 4
861 #define STBTT_MACSTYLE_NONE 8 // <= not same as 0, this makes us check the bitfield is 0
862 
863 STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2);
864 // returns 1/0 whether the first string interpreted as utf8 is identical to
865 // the second string interpreted as big-endian utf16... useful for strings from next func
866 
867 STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID);
868 // returns the string (which may be big-endian double byte, e.g. for unicode)
869 // and puts the length in bytes in *length.
870 //
871 // some of the values for the IDs are below; for more see the truetype spec:
872 // http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6name.html
873 // http://www.microsoft.com/typography/otspec/name.htm
874 
875 enum { // platformID
876  STBTT_PLATFORM_ID_UNICODE =0,
877  STBTT_PLATFORM_ID_MAC =1,
878  STBTT_PLATFORM_ID_ISO =2,
879  STBTT_PLATFORM_ID_MICROSOFT =3
880 };
881 
882 enum { // encodingID for STBTT_PLATFORM_ID_UNICODE
883  STBTT_UNICODE_EID_UNICODE_1_0 =0,
884  STBTT_UNICODE_EID_UNICODE_1_1 =1,
885  STBTT_UNICODE_EID_ISO_10646 =2,
886  STBTT_UNICODE_EID_UNICODE_2_0_BMP=3,
887  STBTT_UNICODE_EID_UNICODE_2_0_FULL=4
888 };
889 
890 enum { // encodingID for STBTT_PLATFORM_ID_MICROSOFT
891  STBTT_MS_EID_SYMBOL =0,
892  STBTT_MS_EID_UNICODE_BMP =1,
893  STBTT_MS_EID_SHIFTJIS =2,
894  STBTT_MS_EID_UNICODE_FULL =10
895 };
896 
897 enum { // encodingID for STBTT_PLATFORM_ID_MAC; same as Script Manager codes
898  STBTT_MAC_EID_ROMAN =0, STBTT_MAC_EID_ARABIC =4,
899  STBTT_MAC_EID_JAPANESE =1, STBTT_MAC_EID_HEBREW =5,
900  STBTT_MAC_EID_CHINESE_TRAD =2, STBTT_MAC_EID_GREEK =6,
901  STBTT_MAC_EID_KOREAN =3, STBTT_MAC_EID_RUSSIAN =7
902 };
903 
904 enum { // languageID for STBTT_PLATFORM_ID_MICROSOFT; same as LCID...
905  // problematic because there are e.g. 16 english LCIDs and 16 arabic LCIDs
906  STBTT_MS_LANG_ENGLISH =0x0409, STBTT_MS_LANG_ITALIAN =0x0410,
907  STBTT_MS_LANG_CHINESE =0x0804, STBTT_MS_LANG_JAPANESE =0x0411,
908  STBTT_MS_LANG_DUTCH =0x0413, STBTT_MS_LANG_KOREAN =0x0412,
909  STBTT_MS_LANG_FRENCH =0x040c, STBTT_MS_LANG_RUSSIAN =0x0419,
910  STBTT_MS_LANG_GERMAN =0x0407, STBTT_MS_LANG_SPANISH =0x0409,
911  STBTT_MS_LANG_HEBREW =0x040d, STBTT_MS_LANG_SWEDISH =0x041D
912 };
913 
914 enum { // languageID for STBTT_PLATFORM_ID_MAC
915  STBTT_MAC_LANG_ENGLISH =0 , STBTT_MAC_LANG_JAPANESE =11,
916  STBTT_MAC_LANG_ARABIC =12, STBTT_MAC_LANG_KOREAN =23,
917  STBTT_MAC_LANG_DUTCH =4 , STBTT_MAC_LANG_RUSSIAN =32,
918  STBTT_MAC_LANG_FRENCH =1 , STBTT_MAC_LANG_SPANISH =6 ,
919  STBTT_MAC_LANG_GERMAN =2 , STBTT_MAC_LANG_SWEDISH =5 ,
920  STBTT_MAC_LANG_HEBREW =10, STBTT_MAC_LANG_CHINESE_SIMPLIFIED =33,
921  STBTT_MAC_LANG_ITALIAN =3 , STBTT_MAC_LANG_CHINESE_TRAD =19
922 };
923 
924 #ifdef __cplusplus
925 }
926 #endif
927 
928 #endif // __STB_INCLUDE_STB_TRUETYPE_H__
929 
936 
937 #ifdef STB_TRUETYPE_IMPLEMENTATION
938 
939 #ifndef STBTT_MAX_OVERSAMPLE
940 #define STBTT_MAX_OVERSAMPLE 8
941 #endif
942 
943 #if STBTT_MAX_OVERSAMPLE > 255
944 #error "STBTT_MAX_OVERSAMPLE cannot be > 255"
945 #endif
946 
947 typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERSAMPLE-1)) == 0 ? 1 : -1];
948 
949 #ifndef STBTT_RASTERIZER_VERSION
950 #define STBTT_RASTERIZER_VERSION 2
951 #endif
952 
953 #ifdef _MSC_VER
954 #define STBTT__NOTUSED(v) (void)(v)
955 #else
956 #define STBTT__NOTUSED(v) (void)sizeof(v)
957 #endif
958 
960 //
961 // accessors to parse data from file
962 //
963 
964 // on platforms that don't allow misaligned reads, if we want to allow
965 // truetype fonts that aren't padded to alignment, define ALLOW_UNALIGNED_TRUETYPE
966 
967 #define ttBYTE(p) (* (stbtt_uint8 *) (p))
968 #define ttCHAR(p) (* (stbtt_int8 *) (p))
969 #define ttFixed(p) ttLONG(p)
970 
971 #if defined(STB_TRUETYPE_BIGENDIAN) && !defined(ALLOW_UNALIGNED_TRUETYPE)
972 
973  #define ttUSHORT(p) (* (stbtt_uint16 *) (p))
974  #define ttSHORT(p) (* (stbtt_int16 *) (p))
975  #define ttULONG(p) (* (stbtt_uint32 *) (p))
976  #define ttLONG(p) (* (stbtt_int32 *) (p))
977 
978 #else
979 
980  static stbtt_uint16 ttUSHORT(const stbtt_uint8 *p) { return p[0]*256 + p[1]; }
981  static stbtt_int16 ttSHORT(const stbtt_uint8 *p) { return p[0]*256 + p[1]; }
982  static stbtt_uint32 ttULONG(const stbtt_uint8 *p) { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; }
983  static stbtt_int32 ttLONG(const stbtt_uint8 *p) { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; }
984 
985 #endif
986 
987 #define stbtt_tag4(p,c0,c1,c2,c3) ((p)[0] == (c0) && (p)[1] == (c1) && (p)[2] == (c2) && (p)[3] == (c3))
988 #define stbtt_tag(p,str) stbtt_tag4(p,str[0],str[1],str[2],str[3])
989 
990 static int stbtt__isfont(const stbtt_uint8 *font)
991 {
992  // check the version number
993  if (stbtt_tag4(font, '1',0,0,0)) return 1; // TrueType 1
994  if (stbtt_tag(font, "typ1")) return 1; // TrueType with type 1 font -- we don't support this!
995  if (stbtt_tag(font, "OTTO")) return 1; // OpenType with CFF
996  if (stbtt_tag4(font, 0,1,0,0)) return 1; // OpenType 1.0
997  return 0;
998 }
999 
1000 // @OPTIMIZE: binary search
1001 static stbtt_uint32 stbtt__find_table(stbtt_uint8 *data, stbtt_uint32 fontstart, const char *tag)
1002 {
1003  stbtt_int32 num_tables = ttUSHORT(data+fontstart+4);
1004  stbtt_uint32 tabledir = fontstart + 12;
1005  stbtt_int32 i;
1006  for (i=0; i < num_tables; ++i) {
1007  stbtt_uint32 loc = tabledir + 16*i;
1008  if (stbtt_tag(data+loc+0, tag))
1009  return ttULONG(data+loc+8);
1010  }
1011  return 0;
1012 }
1013 
1014 STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *font_collection, int index)
1015 {
1016  // if it's just a font, there's only one valid index
1017  if (stbtt__isfont(font_collection))
1018  return index == 0 ? 0 : -1;
1019 
1020  // check if it's a TTC
1021  if (stbtt_tag(font_collection, "ttcf")) {
1022  // version 1?
1023  if (ttULONG(font_collection+4) == 0x00010000 || ttULONG(font_collection+4) == 0x00020000) {
1024  stbtt_int32 n = ttLONG(font_collection+8);
1025  if (index >= n)
1026  return -1;
1027  return ttULONG(font_collection+12+index*4);
1028  }
1029  }
1030  return -1;
1031 }
1032 
1033 STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data2, int fontstart)
1034 {
1035  stbtt_uint8 *data = (stbtt_uint8 *) data2;
1036  stbtt_uint32 cmap, t;
1037  stbtt_int32 i,numTables;
1038 
1039  info->data = data;
1040  info->fontstart = fontstart;
1041 
1042  cmap = stbtt__find_table(data, fontstart, "cmap"); // required
1043  info->loca = stbtt__find_table(data, fontstart, "loca"); // required
1044  info->head = stbtt__find_table(data, fontstart, "head"); // required
1045  info->glyf = stbtt__find_table(data, fontstart, "glyf"); // required
1046  info->hhea = stbtt__find_table(data, fontstart, "hhea"); // required
1047  info->hmtx = stbtt__find_table(data, fontstart, "hmtx"); // required
1048  info->kern = stbtt__find_table(data, fontstart, "kern"); // not required
1049  if (!cmap || !info->loca || !info->head || !info->glyf || !info->hhea || !info->hmtx)
1050  return 0;
1051 
1052  t = stbtt__find_table(data, fontstart, "maxp");
1053  if (t)
1054  info->numGlyphs = ttUSHORT(data+t+4);
1055  else
1056  info->numGlyphs = 0xffff;
1057 
1058  // find a cmap encoding table we understand *now* to avoid searching
1059  // later. (todo: could make this installable)
1060  // the same regardless of glyph.
1061  numTables = ttUSHORT(data + cmap + 2);
1062  info->index_map = 0;
1063  for (i=0; i < numTables; ++i) {
1064  stbtt_uint32 encoding_record = cmap + 4 + 8 * i;
1065  // find an encoding we understand:
1066  switch(ttUSHORT(data+encoding_record)) {
1067  case STBTT_PLATFORM_ID_MICROSOFT:
1068  switch (ttUSHORT(data+encoding_record+2)) {
1069  case STBTT_MS_EID_UNICODE_BMP:
1070  case STBTT_MS_EID_UNICODE_FULL:
1071  // MS/Unicode
1072  info->index_map = cmap + ttULONG(data+encoding_record+4);
1073  break;
1074  }
1075  break;
1076  case STBTT_PLATFORM_ID_UNICODE:
1077  // Mac/iOS has these
1078  // all the encodingIDs are unicode, so we don't bother to check it
1079  info->index_map = cmap + ttULONG(data+encoding_record+4);
1080  break;
1081  }
1082  }
1083  if (info->index_map == 0)
1084  return 0;
1085 
1086  info->indexToLocFormat = ttUSHORT(data+info->head + 50);
1087  return 1;
1088 }
1089 
1090 STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint)
1091 {
1092  stbtt_uint8 *data = info->data;
1093  stbtt_uint32 index_map = info->index_map;
1094 
1095  stbtt_uint16 format = ttUSHORT(data + index_map + 0);
1096  if (format == 0) { // apple byte encoding
1097  stbtt_int32 bytes = ttUSHORT(data + index_map + 2);
1098  if (unicode_codepoint < bytes-6)
1099  return ttBYTE(data + index_map + 6 + unicode_codepoint);
1100  return 0;
1101  } else if (format == 6) {
1102  stbtt_uint32 first = ttUSHORT(data + index_map + 6);
1103  stbtt_uint32 count = ttUSHORT(data + index_map + 8);
1104  if ((stbtt_uint32) unicode_codepoint >= first && (stbtt_uint32) unicode_codepoint < first+count)
1105  return ttUSHORT(data + index_map + 10 + (unicode_codepoint - first)*2);
1106  return 0;
1107  } else if (format == 2) {
1108  STBTT_assert(0); // @TODO: high-byte mapping for japanese/chinese/korean
1109  return 0;
1110  } else if (format == 4) { // standard mapping for windows fonts: binary search collection of ranges
1111  stbtt_uint16 segcount = ttUSHORT(data+index_map+6) >> 1;
1112  stbtt_uint16 searchRange = ttUSHORT(data+index_map+8) >> 1;
1113  stbtt_uint16 entrySelector = ttUSHORT(data+index_map+10);
1114  stbtt_uint16 rangeShift = ttUSHORT(data+index_map+12) >> 1;
1115 
1116  // do a binary search of the segments
1117  stbtt_uint32 endCount = index_map + 14;
1118  stbtt_uint32 search = endCount;
1119 
1120  if (unicode_codepoint > 0xffff)
1121  return 0;
1122 
1123  // they lie from endCount .. endCount + segCount
1124  // but searchRange is the nearest power of two, so...
1125  if (unicode_codepoint >= ttUSHORT(data + search + rangeShift*2))
1126  search += rangeShift*2;
1127 
1128  // now decrement to bias correctly to find smallest
1129  search -= 2;
1130  while (entrySelector) {
1131  stbtt_uint16 end;
1132  searchRange >>= 1;
1133  end = ttUSHORT(data + search + searchRange*2);
1134  if (unicode_codepoint > end)
1135  search += searchRange*2;
1136  --entrySelector;
1137  }
1138  search += 2;
1139 
1140  {
1141  stbtt_uint16 offset, start;
1142  stbtt_uint16 item = (stbtt_uint16) ((search - endCount) >> 1);
1143 
1144  STBTT_assert(unicode_codepoint <= ttUSHORT(data + endCount + 2*item));
1145  start = ttUSHORT(data + index_map + 14 + segcount*2 + 2 + 2*item);
1146  if (unicode_codepoint < start)
1147  return 0;
1148 
1149  offset = ttUSHORT(data + index_map + 14 + segcount*6 + 2 + 2*item);
1150  if (offset == 0)
1151  return (stbtt_uint16) (unicode_codepoint + ttSHORT(data + index_map + 14 + segcount*4 + 2 + 2*item));
1152 
1153  return ttUSHORT(data + offset + (unicode_codepoint-start)*2 + index_map + 14 + segcount*6 + 2 + 2*item);
1154  }
1155  } else if (format == 12 || format == 13) {
1156  stbtt_uint32 ngroups = ttULONG(data+index_map+12);
1157  stbtt_int32 low,high;
1158  low = 0; high = (stbtt_int32)ngroups;
1159  // Binary search the right group.
1160  while (low < high) {
1161  stbtt_int32 mid = low + ((high-low) >> 1); // rounds down, so low <= mid < high
1162  stbtt_uint32 start_char = ttULONG(data+index_map+16+mid*12);
1163  stbtt_uint32 end_char = ttULONG(data+index_map+16+mid*12+4);
1164  if ((stbtt_uint32) unicode_codepoint < start_char)
1165  high = mid;
1166  else if ((stbtt_uint32) unicode_codepoint > end_char)
1167  low = mid+1;
1168  else {
1169  stbtt_uint32 start_glyph = ttULONG(data+index_map+16+mid*12+8);
1170  if (format == 12)
1171  return start_glyph + unicode_codepoint-start_char;
1172  else // format == 13
1173  return start_glyph;
1174  }
1175  }
1176  return 0; // not found
1177  }
1178  // @TODO
1179  STBTT_assert(0);
1180  return 0;
1181 }
1182 
1183 STBTT_DEF int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices)
1184 {
1185  return stbtt_GetGlyphShape(info, stbtt_FindGlyphIndex(info, unicode_codepoint), vertices);
1186 }
1187 
1188 static void stbtt_setvertex(stbtt_vertex *v, stbtt_uint8 type, stbtt_int32 x, stbtt_int32 y, stbtt_int32 cx, stbtt_int32 cy)
1189 {
1190  v->type = type;
1191  v->x = (stbtt_int16) x;
1192  v->y = (stbtt_int16) y;
1193  v->cx = (stbtt_int16) cx;
1194  v->cy = (stbtt_int16) cy;
1195 }
1196 
1197 static int stbtt__GetGlyfOffset(const stbtt_fontinfo *info, int glyph_index)
1198 {
1199  int g1,g2;
1200 
1201  if (glyph_index >= info->numGlyphs) return -1; // glyph index out of range
1202  if (info->indexToLocFormat >= 2) return -1; // unknown index->glyph map format
1203 
1204  if (info->indexToLocFormat == 0) {
1205  g1 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2) * 2;
1206  g2 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2 + 2) * 2;
1207  } else {
1208  g1 = info->glyf + ttULONG (info->data + info->loca + glyph_index * 4);
1209  g2 = info->glyf + ttULONG (info->data + info->loca + glyph_index * 4 + 4);
1210  }
1211 
1212  return g1==g2 ? -1 : g1; // if length is 0, return -1
1213 }
1214 
1215 STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1)
1216 {
1217  int g = stbtt__GetGlyfOffset(info, glyph_index);
1218  if (g < 0) return 0;
1219 
1220  if (x0) *x0 = ttSHORT(info->data + g + 2);
1221  if (y0) *y0 = ttSHORT(info->data + g + 4);
1222  if (x1) *x1 = ttSHORT(info->data + g + 6);
1223  if (y1) *y1 = ttSHORT(info->data + g + 8);
1224  return 1;
1225 }
1226 
1227 STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1)
1228 {
1229  return stbtt_GetGlyphBox(info, stbtt_FindGlyphIndex(info,codepoint), x0,y0,x1,y1);
1230 }
1231 
1232 STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index)
1233 {
1234  stbtt_int16 numberOfContours;
1235  int g = stbtt__GetGlyfOffset(info, glyph_index);
1236  if (g < 0) return 1;
1237  numberOfContours = ttSHORT(info->data + g);
1238  return numberOfContours == 0;
1239 }
1240 
1241 static int stbtt__close_shape(stbtt_vertex *vertices, int num_vertices, int was_off, int start_off,
1242  stbtt_int32 sx, stbtt_int32 sy, stbtt_int32 scx, stbtt_int32 scy, stbtt_int32 cx, stbtt_int32 cy)
1243 {
1244  if (start_off) {
1245  if (was_off)
1246  stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx+scx)>>1, (cy+scy)>>1, cx,cy);
1247  stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, sx,sy,scx,scy);
1248  } else {
1249  if (was_off)
1250  stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve,sx,sy,cx,cy);
1251  else
1252  stbtt_setvertex(&vertices[num_vertices++], STBTT_vline,sx,sy,0,0);
1253  }
1254  return num_vertices;
1255 }
1256 
1257 STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices)
1258 {
1259  stbtt_int16 numberOfContours;
1260  stbtt_uint8 *endPtsOfContours;
1261  stbtt_uint8 *data = info->data;
1262  stbtt_vertex *vertices=0;
1263  int num_vertices=0;
1264  int g = stbtt__GetGlyfOffset(info, glyph_index);
1265 
1266  *pvertices = NULL;
1267 
1268  if (g < 0) return 0;
1269 
1270  numberOfContours = ttSHORT(data + g);
1271 
1272  if (numberOfContours > 0) {
1273  stbtt_uint8 flags=0,flagcount;
1274  stbtt_int32 ins, i,j=0,m,n, next_move, was_off=0, off, start_off=0;
1275  stbtt_int32 x,y,cx,cy,sx,sy, scx,scy;
1276  stbtt_uint8 *points;
1277  endPtsOfContours = (data + g + 10);
1278  ins = ttUSHORT(data + g + 10 + numberOfContours * 2);
1279  points = data + g + 10 + numberOfContours * 2 + 2 + ins;
1280 
1281  n = 1+ttUSHORT(endPtsOfContours + numberOfContours*2-2);
1282 
1283  m = n + 2*numberOfContours; // a loose bound on how many vertices we might need
1284  vertices = (stbtt_vertex *) STBTT_malloc(m * sizeof(vertices[0]), info->userdata);
1285  if (vertices == 0)
1286  return 0;
1287 
1288  next_move = 0;
1289  flagcount=0;
1290 
1291  // in first pass, we load uninterpreted data into the allocated array
1292  // above, shifted to the end of the array so we won't overwrite it when
1293  // we create our final data starting from the front
1294 
1295  off = m - n; // starting offset for uninterpreted data, regardless of how m ends up being calculated
1296 
1297  // first load flags
1298 
1299  for (i=0; i < n; ++i) {
1300  if (flagcount == 0) {
1301  flags = *points++;
1302  if (flags & 8)
1303  flagcount = *points++;
1304  } else
1305  --flagcount;
1306  vertices[off+i].type = flags;
1307  }
1308 
1309  // now load x coordinates
1310  x=0;
1311  for (i=0; i < n; ++i) {
1312  flags = vertices[off+i].type;
1313  if (flags & 2) {
1314  stbtt_int16 dx = *points++;
1315  x += (flags & 16) ? dx : -dx; // ???
1316  } else {
1317  if (!(flags & 16)) {
1318  x = x + (stbtt_int16) (points[0]*256 + points[1]);
1319  points += 2;
1320  }
1321  }
1322  vertices[off+i].x = (stbtt_int16) x;
1323  }
1324 
1325  // now load y coordinates
1326  y=0;
1327  for (i=0; i < n; ++i) {
1328  flags = vertices[off+i].type;
1329  if (flags & 4) {
1330  stbtt_int16 dy = *points++;
1331  y += (flags & 32) ? dy : -dy; // ???
1332  } else {
1333  if (!(flags & 32)) {
1334  y = y + (stbtt_int16) (points[0]*256 + points[1]);
1335  points += 2;
1336  }
1337  }
1338  vertices[off+i].y = (stbtt_int16) y;
1339  }
1340 
1341  // now convert them to our format
1342  num_vertices=0;
1343  sx = sy = cx = cy = scx = scy = 0;
1344  for (i=0; i < n; ++i) {
1345  flags = vertices[off+i].type;
1346  x = (stbtt_int16) vertices[off+i].x;
1347  y = (stbtt_int16) vertices[off+i].y;
1348 
1349  if (next_move == i) {
1350  if (i != 0)
1351  num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
1352 
1353  // now start the new one
1354  start_off = !(flags & 1);
1355  if (start_off) {
1356  // if we start off with an off-curve point, then when we need to find a point on the curve
1357  // where we can start, and we need to save some state for when we wraparound.
1358  scx = x;
1359  scy = y;
1360  if (!(vertices[off+i+1].type & 1)) {
1361  // next point is also a curve point, so interpolate an on-point curve
1362  sx = (x + (stbtt_int32) vertices[off+i+1].x) >> 1;
1363  sy = (y + (stbtt_int32) vertices[off+i+1].y) >> 1;
1364  } else {
1365  // otherwise just use the next point as our start point
1366  sx = (stbtt_int32) vertices[off+i+1].x;
1367  sy = (stbtt_int32) vertices[off+i+1].y;
1368  ++i; // we're using point i+1 as the starting point, so skip it
1369  }
1370  } else {
1371  sx = x;
1372  sy = y;
1373  }
1374  stbtt_setvertex(&vertices[num_vertices++], STBTT_vmove,sx,sy,0,0);
1375  was_off = 0;
1376  next_move = 1 + ttUSHORT(endPtsOfContours+j*2);
1377  ++j;
1378  } else {
1379  if (!(flags & 1)) { // if it's a curve
1380  if (was_off) // two off-curve control points in a row means interpolate an on-curve midpoint
1381  stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx+x)>>1, (cy+y)>>1, cx, cy);
1382  cx = x;
1383  cy = y;
1384  was_off = 1;
1385  } else {
1386  if (was_off)
1387  stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, x,y, cx, cy);
1388  else
1389  stbtt_setvertex(&vertices[num_vertices++], STBTT_vline, x,y,0,0);
1390  was_off = 0;
1391  }
1392  }
1393  }
1394  num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
1395  } else if (numberOfContours == -1) {
1396  // Compound shapes.
1397  int more = 1;
1398  stbtt_uint8 *comp = data + g + 10;
1399  num_vertices = 0;
1400  vertices = 0;
1401  while (more) {
1402  stbtt_uint16 flags, gidx;
1403  int comp_num_verts = 0, i;
1404  stbtt_vertex *comp_verts = 0, *tmp = 0;
1405  float mtx[6] = {1,0,0,1,0,0}, m, n;
1406 
1407  flags = ttSHORT(comp); comp+=2;
1408  gidx = ttSHORT(comp); comp+=2;
1409 
1410  if (flags & 2) { // XY values
1411  if (flags & 1) { // shorts
1412  mtx[4] = ttSHORT(comp); comp+=2;
1413  mtx[5] = ttSHORT(comp); comp+=2;
1414  } else {
1415  mtx[4] = ttCHAR(comp); comp+=1;
1416  mtx[5] = ttCHAR(comp); comp+=1;
1417  }
1418  }
1419  else {
1420  // @TODO handle matching point
1421  STBTT_assert(0);
1422  }
1423  if (flags & (1<<3)) { // WE_HAVE_A_SCALE
1424  mtx[0] = mtx[3] = ttSHORT(comp)/16384.0f; comp+=2;
1425  mtx[1] = mtx[2] = 0;
1426  } else if (flags & (1<<6)) { // WE_HAVE_AN_X_AND_YSCALE
1427  mtx[0] = ttSHORT(comp)/16384.0f; comp+=2;
1428  mtx[1] = mtx[2] = 0;
1429  mtx[3] = ttSHORT(comp)/16384.0f; comp+=2;
1430  } else if (flags & (1<<7)) { // WE_HAVE_A_TWO_BY_TWO
1431  mtx[0] = ttSHORT(comp)/16384.0f; comp+=2;
1432  mtx[1] = ttSHORT(comp)/16384.0f; comp+=2;
1433  mtx[2] = ttSHORT(comp)/16384.0f; comp+=2;
1434  mtx[3] = ttSHORT(comp)/16384.0f; comp+=2;
1435  }
1436 
1437  // Find transformation scales.
1438  m = (float) STBTT_sqrt(mtx[0]*mtx[0] + mtx[1]*mtx[1]);
1439  n = (float) STBTT_sqrt(mtx[2]*mtx[2] + mtx[3]*mtx[3]);
1440 
1441  // Get indexed glyph.
1442  comp_num_verts = stbtt_GetGlyphShape(info, gidx, &comp_verts);
1443  if (comp_num_verts > 0) {
1444  // Transform vertices.
1445  for (i = 0; i < comp_num_verts; ++i) {
1446  stbtt_vertex* v = &comp_verts[i];
1447  stbtt_vertex_type x,y;
1448  x=v->x; y=v->y;
1449  v->x = (stbtt_vertex_type)(m * (mtx[0]*x + mtx[2]*y + mtx[4]));
1450  v->y = (stbtt_vertex_type)(n * (mtx[1]*x + mtx[3]*y + mtx[5]));
1451  x=v->cx; y=v->cy;
1452  v->cx = (stbtt_vertex_type)(m * (mtx[0]*x + mtx[2]*y + mtx[4]));
1453  v->cy = (stbtt_vertex_type)(n * (mtx[1]*x + mtx[3]*y + mtx[5]));
1454  }
1455  // Append vertices.
1456  tmp = (stbtt_vertex*)STBTT_malloc((num_vertices+comp_num_verts)*sizeof(stbtt_vertex), info->userdata);
1457  if (!tmp) {
1458  if (vertices) STBTT_free(vertices, info->userdata);
1459  if (comp_verts) STBTT_free(comp_verts, info->userdata);
1460  return 0;
1461  }
1462  if (num_vertices > 0) STBTT_memcpy(tmp, vertices, num_vertices*sizeof(stbtt_vertex));
1463  STBTT_memcpy(tmp+num_vertices, comp_verts, comp_num_verts*sizeof(stbtt_vertex));
1464  if (vertices) STBTT_free(vertices, info->userdata);
1465  vertices = tmp;
1466  STBTT_free(comp_verts, info->userdata);
1467  num_vertices += comp_num_verts;
1468  }
1469  // More components ?
1470  more = flags & (1<<5);
1471  }
1472  } else if (numberOfContours < 0) {
1473  // @TODO other compound variations?
1474  STBTT_assert(0);
1475  } else {
1476  // numberOfCounters == 0, do nothing
1477  }
1478 
1479  *pvertices = vertices;
1480  return num_vertices;
1481 }
1482 
1483 STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing)
1484 {
1485  stbtt_uint16 numOfLongHorMetrics = ttUSHORT(info->data+info->hhea + 34);
1486  if (glyph_index < numOfLongHorMetrics) {
1487  if (advanceWidth) *advanceWidth = ttSHORT(info->data + info->hmtx + 4*glyph_index);
1488  if (leftSideBearing) *leftSideBearing = ttSHORT(info->data + info->hmtx + 4*glyph_index + 2);
1489  } else {
1490  if (advanceWidth) *advanceWidth = ttSHORT(info->data + info->hmtx + 4*(numOfLongHorMetrics-1));
1491  if (leftSideBearing) *leftSideBearing = ttSHORT(info->data + info->hmtx + 4*numOfLongHorMetrics + 2*(glyph_index - numOfLongHorMetrics));
1492  }
1493 }
1494 
1495 STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2)
1496 {
1497  stbtt_uint8 *data = info->data + info->kern;
1498  stbtt_uint32 needle, straw;
1499  int l, r, m;
1500 
1501  // we only look at the first table. it must be 'horizontal' and format 0.
1502  if (!info->kern)
1503  return 0;
1504  if (ttUSHORT(data+2) < 1) // number of tables, need at least 1
1505  return 0;
1506  if (ttUSHORT(data+8) != 1) // horizontal flag must be set in format
1507  return 0;
1508 
1509  l = 0;
1510  r = ttUSHORT(data+10) - 1;
1511  needle = glyph1 << 16 | glyph2;
1512  while (l <= r) {
1513  m = (l + r) >> 1;
1514  straw = ttULONG(data+18+(m*6)); // note: unaligned read
1515  if (needle < straw)
1516  r = m - 1;
1517  else if (needle > straw)
1518  l = m + 1;
1519  else
1520  return ttSHORT(data+22+(m*6));
1521  }
1522  return 0;
1523 }
1524 
1525 STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2)
1526 {
1527  if (!info->kern) // if no kerning table, don't waste time looking up both codepoint->glyphs
1528  return 0;
1529  return stbtt_GetGlyphKernAdvance(info, stbtt_FindGlyphIndex(info,ch1), stbtt_FindGlyphIndex(info,ch2));
1530 }
1531 
1532 STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing)
1533 {
1534  stbtt_GetGlyphHMetrics(info, stbtt_FindGlyphIndex(info,codepoint), advanceWidth, leftSideBearing);
1535 }
1536 
1537 STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap)
1538 {
1539  if (ascent ) *ascent = ttSHORT(info->data+info->hhea + 4);
1540  if (descent) *descent = ttSHORT(info->data+info->hhea + 6);
1541  if (lineGap) *lineGap = ttSHORT(info->data+info->hhea + 8);
1542 }
1543 
1544 STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1)
1545 {
1546  *x0 = ttSHORT(info->data + info->head + 36);
1547  *y0 = ttSHORT(info->data + info->head + 38);
1548  *x1 = ttSHORT(info->data + info->head + 40);
1549  *y1 = ttSHORT(info->data + info->head + 42);
1550 }
1551 
1552 STBTT_DEF float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float height)
1553 {
1554  int fheight = ttSHORT(info->data + info->hhea + 4) - ttSHORT(info->data + info->hhea + 6);
1555  return (float) height / fheight;
1556 }
1557 
1558 STBTT_DEF float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels)
1559 {
1560  int unitsPerEm = ttUSHORT(info->data + info->head + 18);
1561  return pixels / unitsPerEm;
1562 }
1563 
1564 STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *v)
1565 {
1566  STBTT_free(v, info->userdata);
1567 }
1568 
1570 //
1571 // antialiasing software rasterizer
1572 //
1573 
1574 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)
1575 {
1576  int x0=0,y0=0,x1,y1; // =0 suppresses compiler warning
1577  if (!stbtt_GetGlyphBox(font, glyph, &x0,&y0,&x1,&y1)) {
1578  // e.g. space character
1579  if (ix0) *ix0 = 0;
1580  if (iy0) *iy0 = 0;
1581  if (ix1) *ix1 = 0;
1582  if (iy1) *iy1 = 0;
1583  } else {
1584  // move to integral bboxes (treating pixels as little squares, what pixels get touched)?
1585  if (ix0) *ix0 = STBTT_ifloor( x0 * scale_x + shift_x);
1586  if (iy0) *iy0 = STBTT_ifloor(-y1 * scale_y + shift_y);
1587  if (ix1) *ix1 = STBTT_iceil ( x1 * scale_x + shift_x);
1588  if (iy1) *iy1 = STBTT_iceil (-y0 * scale_y + shift_y);
1589  }
1590 }
1591 
1592 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)
1593 {
1594  stbtt_GetGlyphBitmapBoxSubpixel(font, glyph, scale_x, scale_y,0.0f,0.0f, ix0, iy0, ix1, iy1);
1595 }
1596 
1597 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)
1598 {
1599  stbtt_GetGlyphBitmapBoxSubpixel(font, stbtt_FindGlyphIndex(font,codepoint), scale_x, scale_y,shift_x,shift_y, ix0,iy0,ix1,iy1);
1600 }
1601 
1602 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)
1603 {
1604  stbtt_GetCodepointBitmapBoxSubpixel(font, codepoint, scale_x, scale_y,0.0f,0.0f, ix0,iy0,ix1,iy1);
1605 }
1606 
1608 //
1609 // Rasterizer
1610 
1611 typedef struct stbtt__hheap_chunk
1612 {
1613  struct stbtt__hheap_chunk *next;
1614 } stbtt__hheap_chunk;
1615 
1616 typedef struct stbtt__hheap
1617 {
1618  struct stbtt__hheap_chunk *head;
1619  void *first_free;
1620  int num_remaining_in_head_chunk;
1621 } stbtt__hheap;
1622 
1623 static void *stbtt__hheap_alloc(stbtt__hheap *hh, size_t size, void *userdata)
1624 {
1625  if (hh->first_free) {
1626  void *p = hh->first_free;
1627  hh->first_free = * (void **) p;
1628  return p;
1629  } else {
1630  if (hh->num_remaining_in_head_chunk == 0) {
1631  int count = (size < 32 ? 2000 : size < 128 ? 800 : 100);
1632  stbtt__hheap_chunk *c = (stbtt__hheap_chunk *) STBTT_malloc(sizeof(stbtt__hheap_chunk) + size * count, userdata);
1633  if (c == NULL)
1634  return NULL;
1635  c->next = hh->head;
1636  hh->head = c;
1637  hh->num_remaining_in_head_chunk = count;
1638  }
1639  --hh->num_remaining_in_head_chunk;
1640  return (char *) (hh->head) + size * hh->num_remaining_in_head_chunk;
1641  }
1642 }
1643 
1644 static void stbtt__hheap_free(stbtt__hheap *hh, void *p)
1645 {
1646  *(void **) p = hh->first_free;
1647  hh->first_free = p;
1648 }
1649 
1650 static void stbtt__hheap_cleanup(stbtt__hheap *hh, void *userdata)
1651 {
1652  stbtt__hheap_chunk *c = hh->head;
1653  while (c) {
1654  stbtt__hheap_chunk *n = c->next;
1655  STBTT_free(c, userdata);
1656  c = n;
1657  }
1658 }
1659 
1660 typedef struct stbtt__edge {
1661  float x0,y0, x1,y1;
1662  int invert;
1663 } stbtt__edge;
1664 
1665 
1666 typedef struct stbtt__active_edge
1667 {
1668  struct stbtt__active_edge *next;
1669  #if STBTT_RASTERIZER_VERSION==1
1670  int x,dx;
1671  float ey;
1672  int direction;
1673  #elif STBTT_RASTERIZER_VERSION==2
1674  float fx,fdx,fdy;
1675  float direction;
1676  float sy;
1677  float ey;
1678  #else
1679  #error "Unrecognized value of STBTT_RASTERIZER_VERSION"
1680  #endif
1681 } stbtt__active_edge;
1682 
1683 #if STBTT_RASTERIZER_VERSION == 1
1684 #define STBTT_FIXSHIFT 10
1685 #define STBTT_FIX (1 << STBTT_FIXSHIFT)
1686 #define STBTT_FIXMASK (STBTT_FIX-1)
1687 
1688 static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, int off_x, float start_point, void *userdata)
1689 {
1690  stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh, sizeof(*z), userdata);
1691  float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
1692  STBTT_assert(z != NULL);
1693  if (!z) return z;
1694 
1695  // round dx down to avoid overshooting
1696  if (dxdy < 0)
1697  z->dx = -STBTT_ifloor(STBTT_FIX * -dxdy);
1698  else
1699  z->dx = STBTT_ifloor(STBTT_FIX * dxdy);
1700 
1701  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
1702  z->x -= off_x * STBTT_FIX;
1703 
1704  z->ey = e->y1;
1705  z->next = 0;
1706  z->direction = e->invert ? 1 : -1;
1707  return z;
1708 }
1709 #elif STBTT_RASTERIZER_VERSION == 2
1710 static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, int off_x, float start_point, void *userdata)
1711 {
1712  stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh, sizeof(*z), userdata);
1713  float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
1714  STBTT_assert(z != NULL);
1715  //STBTT_assert(e->y0 <= start_point);
1716  if (!z) return z;
1717  z->fdx = dxdy;
1718  z->fdy = dxdy != 0.0f ? (1.0f/dxdy) : 0.0f;
1719  z->fx = e->x0 + dxdy * (start_point - e->y0);
1720  z->fx -= off_x;
1721  z->direction = e->invert ? 1.0f : -1.0f;
1722  z->sy = e->y0;
1723  z->ey = e->y1;
1724  z->next = 0;
1725  return z;
1726 }
1727 #else
1728 #error "Unrecognized value of STBTT_RASTERIZER_VERSION"
1729 #endif
1730 
1731 #if STBTT_RASTERIZER_VERSION == 1
1732 // note: this routine clips fills that extend off the edges... ideally this
1733 // wouldn't happen, but it could happen if the truetype glyph bounding boxes
1734 // are wrong, or if the user supplies a too-small bitmap
1735 static void stbtt__fill_active_edges(unsigned char *scanline, int len, stbtt__active_edge *e, int max_weight)
1736 {
1737  // non-zero winding fill
1738  int x0=0, w=0;
1739 
1740  while (e) {
1741  if (w == 0) {
1742  // if we're currently at zero, we need to record the edge start point
1743  x0 = e->x; w += e->direction;
1744  } else {
1745  int x1 = e->x; w += e->direction;
1746  // if we went to zero, we need to draw
1747  if (w == 0) {
1748  int i = x0 >> STBTT_FIXSHIFT;
1749  int j = x1 >> STBTT_FIXSHIFT;
1750 
1751  if (i < len && j >= 0) {
1752  if (i == j) {
1753  // x0,x1 are the same pixel, so compute combined coverage
1754  scanline[i] = scanline[i] + (stbtt_uint8) ((x1 - x0) * max_weight >> STBTT_FIXSHIFT);
1755  } else {
1756  if (i >= 0) // add antialiasing for x0
1757  scanline[i] = scanline[i] + (stbtt_uint8) (((STBTT_FIX - (x0 & STBTT_FIXMASK)) * max_weight) >> STBTT_FIXSHIFT);
1758  else
1759  i = -1; // clip
1760 
1761  if (j < len) // add antialiasing for x1
1762  scanline[j] = scanline[j] + (stbtt_uint8) (((x1 & STBTT_FIXMASK) * max_weight) >> STBTT_FIXSHIFT);
1763  else
1764  j = len; // clip
1765 
1766  for (++i; i < j; ++i) // fill pixels between x0 and x1
1767  scanline[i] = scanline[i] + (stbtt_uint8) max_weight;
1768  }
1769  }
1770  }
1771  }
1772 
1773  e = e->next;
1774  }
1775 }
1776 
1777 static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata)
1778 {
1779  stbtt__hheap hh = { 0, 0, 0 };
1780  stbtt__active_edge *active = NULL;
1781  int y,j=0;
1782  int max_weight = (255 / vsubsample); // weight per vertical scanline
1783  int s; // vertical subsample index
1784  unsigned char scanline_data[512], *scanline;
1785 
1786  if (result->w > 512)
1787  scanline = (unsigned char *) STBTT_malloc(result->w, userdata);
1788  else
1789  scanline = scanline_data;
1790 
1791  y = off_y * vsubsample;
1792  e[n].y0 = (off_y + result->h) * (float) vsubsample + 1;
1793 
1794  while (j < result->h) {
1795  STBTT_memset(scanline, 0, result->w);
1796  for (s=0; s < vsubsample; ++s) {
1797  // find center of pixel for this scanline
1798  float scan_y = y + 0.5f;
1799  stbtt__active_edge **step = &active;
1800 
1801  // update all active edges;
1802  // remove all active edges that terminate before the center of this scanline
1803  while (*step) {
1804  stbtt__active_edge * z = *step;
1805  if (z->ey <= scan_y) {
1806  *step = z->next; // delete from list
1807  STBTT_assert(z->direction);
1808  z->direction = 0;
1809  stbtt__hheap_free(&hh, z);
1810  } else {
1811  z->x += z->dx; // advance to position for current scanline
1812  step = &((*step)->next); // advance through list
1813  }
1814  }
1815 
1816  // resort the list if needed
1817  for(;;) {
1818  int changed=0;
1819  step = &active;
1820  while (*step && (*step)->next) {
1821  if ((*step)->x > (*step)->next->x) {
1822  stbtt__active_edge *t = *step;
1823  stbtt__active_edge *q = t->next;
1824 
1825  t->next = q->next;
1826  q->next = t;
1827  *step = q;
1828  changed = 1;
1829  }
1830  step = &(*step)->next;
1831  }
1832  if (!changed) break;
1833  }
1834 
1835  // insert all edges that start before the center of this scanline -- omit ones that also end on this scanline
1836  while (e->y0 <= scan_y) {
1837  if (e->y1 > scan_y) {
1838  stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y, userdata);
1839  if (z != NULL) {
1840  // find insertion point
1841  if (active == NULL)
1842  active = z;
1843  else if (z->x < active->x) {
1844  // insert at front
1845  z->next = active;
1846  active = z;
1847  } else {
1848  // find thing to insert AFTER
1849  stbtt__active_edge *p = active;
1850  while (p->next && p->next->x < z->x)
1851  p = p->next;
1852  // at this point, p->next->x is NOT < z->x
1853  z->next = p->next;
1854  p->next = z;
1855  }
1856  }
1857  }
1858  ++e;
1859  }
1860 
1861  // now process all active edges in XOR fashion
1862  if (active)
1863  stbtt__fill_active_edges(scanline, result->w, active, max_weight);
1864 
1865  ++y;
1866  }
1867  STBTT_memcpy(result->pixels + j * result->stride, scanline, result->w);
1868  ++j;
1869  }
1870 
1871  stbtt__hheap_cleanup(&hh, userdata);
1872 
1873  if (scanline != scanline_data)
1874  STBTT_free(scanline, userdata);
1875 }
1876 
1877 #elif STBTT_RASTERIZER_VERSION == 2
1878 
1879 // the edge passed in here does not cross the vertical line at x or the vertical line at x+1
1880 // (i.e. it has already been clipped to those)
1881 static void stbtt__handle_clipped_edge(float *scanline, int x, stbtt__active_edge *e, float x0, float y0, float x1, float y1)
1882 {
1883  if (y0 == y1) return;
1884  STBTT_assert(y0 < y1);
1885  STBTT_assert(e->sy <= e->ey);
1886  if (y0 > e->ey) return;
1887  if (y1 < e->sy) return;
1888  if (y0 < e->sy) {
1889  x0 += (x1-x0) * (e->sy - y0) / (y1-y0);
1890  y0 = e->sy;
1891  }
1892  if (y1 > e->ey) {
1893  x1 += (x1-x0) * (e->ey - y1) / (y1-y0);
1894  y1 = e->ey;
1895  }
1896 
1897  if (x0 == x)
1898  STBTT_assert(x1 <= x+1);
1899  else if (x0 == x+1)
1900  STBTT_assert(x1 >= x);
1901  else if (x0 <= x)
1902  STBTT_assert(x1 <= x);
1903  else if (x0 >= x+1)
1904  STBTT_assert(x1 >= x+1);
1905  else
1906  STBTT_assert(x1 >= x && x1 <= x+1);
1907 
1908  if (x0 <= x && x1 <= x)
1909  scanline[x] += e->direction * (y1-y0);
1910  else if (x0 >= x+1 && x1 >= x+1)
1911  ;
1912  else {
1913  STBTT_assert(x0 >= x && x0 <= x+1 && x1 >= x && x1 <= x+1);
1914  scanline[x] += e->direction * (y1-y0) * (1-((x0-x)+(x1-x))/2); // coverage = 1 - average x position
1915  }
1916 }
1917 
1918 static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill, int len, stbtt__active_edge *e, float y_top)
1919 {
1920  float y_bottom = y_top+1;
1921 
1922  while (e) {
1923  // brute force every pixel
1924 
1925  // compute intersection points with top & bottom
1926  STBTT_assert(e->ey >= y_top);
1927 
1928  if (e->fdx == 0) {
1929  float x0 = e->fx;
1930  if (x0 < len) {
1931  if (x0 >= 0) {
1932  stbtt__handle_clipped_edge(scanline,(int) x0,e, x0,y_top, x0,y_bottom);
1933  stbtt__handle_clipped_edge(scanline_fill-1,(int) x0+1,e, x0,y_top, x0,y_bottom);
1934  } else {
1935  stbtt__handle_clipped_edge(scanline_fill-1,0,e, x0,y_top, x0,y_bottom);
1936  }
1937  }
1938  } else {
1939  float x0 = e->fx;
1940  float dx = e->fdx;
1941  float xb = x0 + dx;
1942  float x_top, x_bottom;
1943  float sy0,sy1;
1944  float dy = e->fdy;
1945  STBTT_assert(e->sy <= y_bottom && e->ey >= y_top);
1946 
1947  // compute endpoints of line segment clipped to this scanline (if the
1948  // line segment starts on this scanline. x0 is the intersection of the
1949  // line with y_top, but that may be off the line segment.
1950  if (e->sy > y_top) {
1951  x_top = x0 + dx * (e->sy - y_top);
1952  sy0 = e->sy;
1953  } else {
1954  x_top = x0;
1955  sy0 = y_top;
1956  }
1957  if (e->ey < y_bottom) {
1958  x_bottom = x0 + dx * (e->ey - y_top);
1959  sy1 = e->ey;
1960  } else {
1961  x_bottom = xb;
1962  sy1 = y_bottom;
1963  }
1964 
1965  if (x_top >= 0 && x_bottom >= 0 && x_top < len && x_bottom < len) {
1966  // from here on, we don't have to range check x values
1967 
1968  if ((int) x_top == (int) x_bottom) {
1969  float height;
1970  // simple case, only spans one pixel
1971  int x = (int) x_top;
1972  height = sy1 - sy0;
1973  STBTT_assert(x >= 0 && x < len);
1974  scanline[x] += e->direction * (1-((x_top - x) + (x_bottom-x))/2) * height;
1975  scanline_fill[x] += e->direction * height; // everything right of this pixel is filled
1976  } else {
1977  int x,x1,x2;
1978  float y_crossing, step, sign, area;
1979  // covers 2+ pixels
1980  if (x_top > x_bottom) {
1981  // flip scanline vertically; signed area is the same
1982  float t;
1983  sy0 = y_bottom - (sy0 - y_top);
1984  sy1 = y_bottom - (sy1 - y_top);
1985  t = sy0, sy0 = sy1, sy1 = t;
1986  t = x_bottom, x_bottom = x_top, x_top = t;
1987  dx = -dx;
1988  dy = -dy;
1989  t = x0, x0 = xb, xb = t;
1990  }
1991 
1992  x1 = (int) x_top;
1993  x2 = (int) x_bottom;
1994  // compute intersection with y axis at x1+1
1995  y_crossing = (x1+1 - x0) * dy + y_top;
1996 
1997  sign = e->direction;
1998  // area of the rectangle covered from y0..y_crossing
1999  area = sign * (y_crossing-sy0);
2000  // area of the triangle (x_top,y0), (x+1,y0), (x+1,y_crossing)
2001  scanline[x1] += area * (1-((x_top - x1)+(x1+1-x1))/2);
2002 
2003  step = sign * dy;
2004  for (x = x1+1; x < x2; ++x) {
2005  scanline[x] += area + step/2;
2006  area += step;
2007  }
2008  y_crossing += dy * (x2 - (x1+1));
2009 
2010  STBTT_assert(STBTT_fabs(area) <= 1.01f);
2011 
2012  scanline[x2] += area + sign * (1-((x2-x2)+(x_bottom-x2))/2) * (sy1-y_crossing);
2013 
2014  scanline_fill[x2] += sign * (sy1-sy0);
2015  }
2016  } else {
2017  // if edge goes outside of box we're drawing, we require
2018  // clipping logic. since this does not match the intended use
2019  // of this library, we use a different, very slow brute
2020  // force implementation
2021  int x;
2022  for (x=0; x < len; ++x) {
2023  // cases:
2024  //
2025  // there can be up to two intersections with the pixel. any intersection
2026  // with left or right edges can be handled by splitting into two (or three)
2027  // regions. intersections with top & bottom do not necessitate case-wise logic.
2028  //
2029  // the old way of doing this found the intersections with the left & right edges,
2030  // then used some simple logic to produce up to three segments in sorted order
2031  // from top-to-bottom. however, this had a problem: if an x edge was epsilon
2032  // across the x border, then the corresponding y position might not be distinct
2033  // from the other y segment, and it might ignored as an empty segment. to avoid
2034  // that, we need to explicitly produce segments based on x positions.
2035 
2036  // rename variables to clear pairs
2037  float y0 = y_top;
2038  float x1 = (float) (x);
2039  float x2 = (float) (x+1);
2040  float x3 = xb;
2041  float y3 = y_bottom;
2042  float y1,y2;
2043 
2044  // x = e->x + e->dx * (y-y_top)
2045  // (y-y_top) = (x - e->x) / e->dx
2046  // y = (x - e->x) / e->dx + y_top
2047  y1 = (x - x0) / dx + y_top;
2048  y2 = (x+1 - x0) / dx + y_top;
2049 
2050  if (x0 < x1 && x3 > x2) { // three segments descending down-right
2051  stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1);
2052  stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x2,y2);
2053  stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3);
2054  } else if (x3 < x1 && x0 > x2) { // three segments descending down-left
2055  stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2);
2056  stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x1,y1);
2057  stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3);
2058  } else if (x0 < x1 && x3 > x1) { // two segments across x, down-right
2059  stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1);
2060  stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3);
2061  } else if (x3 < x1 && x0 > x1) { // two segments across x, down-left
2062  stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1);
2063  stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3);
2064  } else if (x0 < x2 && x3 > x2) { // two segments across x+1, down-right
2065  stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2);
2066  stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3);
2067  } else if (x3 < x2 && x0 > x2) { // two segments across x+1, down-left
2068  stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2);
2069  stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3);
2070  } else { // one segment
2071  stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x3,y3);
2072  }
2073  }
2074  }
2075  }
2076  e = e->next;
2077  }
2078 }
2079 
2080 // directly AA rasterize edges w/o supersampling
2081 static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata)
2082 {
2083  stbtt__hheap hh = { 0, 0, 0 };
2084  stbtt__active_edge *active = NULL;
2085  int y,j=0, i;
2086  float scanline_data[129], *scanline, *scanline2;
2087 
2088  STBTT__NOTUSED(vsubsample);
2089 
2090  if (result->w > 64)
2091  scanline = (float *) STBTT_malloc((result->w*2+1) * sizeof(float), userdata);
2092  else
2093  scanline = scanline_data;
2094 
2095  scanline2 = scanline + result->w;
2096 
2097  y = off_y;
2098  e[n].y0 = (float) (off_y + result->h) + 1;
2099 
2100  while (j < result->h) {
2101  // find center of pixel for this scanline
2102  float scan_y_top = y + 0.0f;
2103  float scan_y_bottom = y + 1.0f;
2104  stbtt__active_edge **step = &active;
2105 
2106  STBTT_memset(scanline , 0, result->w*sizeof(scanline[0]));
2107  STBTT_memset(scanline2, 0, (result->w+1)*sizeof(scanline[0]));
2108 
2109  // update all active edges;
2110  // remove all active edges that terminate before the top of this scanline
2111  while (*step) {
2112  stbtt__active_edge * z = *step;
2113  if (z->ey <= scan_y_top) {
2114  *step = z->next; // delete from list
2115  STBTT_assert(z->direction);
2116  z->direction = 0;
2117  stbtt__hheap_free(&hh, z);
2118  } else {
2119  step = &((*step)->next); // advance through list
2120  }
2121  }
2122 
2123  // insert all edges that start before the bottom of this scanline
2124  while (e->y0 <= scan_y_bottom) {
2125  if (e->y0 != e->y1) {
2126  stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata);
2127  if (z != NULL) {
2128  STBTT_assert(z->ey >= scan_y_top);
2129  // insert at front
2130  z->next = active;
2131  active = z;
2132  }
2133  }
2134  ++e;
2135  }
2136 
2137  // now process all active edges
2138  if (active)
2139  stbtt__fill_active_edges_new(scanline, scanline2+1, result->w, active, scan_y_top);
2140 
2141  {
2142  float sum = 0;
2143  for (i=0; i < result->w; ++i) {
2144  float k;
2145  int m;
2146  sum += scanline2[i];
2147  k = scanline[i] + sum;
2148  k = (float) STBTT_fabs(k)*255 + 0.5f;
2149  m = (int) k;
2150  if (m > 255) m = 255;
2151  result->pixels[j*result->stride + i] = (unsigned char) m;
2152  }
2153  }
2154  // advance all the edges
2155  step = &active;
2156  while (*step) {
2157  stbtt__active_edge *z = *step;
2158  z->fx += z->fdx; // advance to position for current scanline
2159  step = &((*step)->next); // advance through list
2160  }
2161 
2162  ++y;
2163  ++j;
2164  }
2165 
2166  stbtt__hheap_cleanup(&hh, userdata);
2167 
2168  if (scanline != scanline_data)
2169  STBTT_free(scanline, userdata);
2170 }
2171 #else
2172 #error "Unrecognized value of STBTT_RASTERIZER_VERSION"
2173 #endif
2174 
2175 #define STBTT__COMPARE(a,b) ((a)->y0 < (b)->y0)
2176 
2177 static void stbtt__sort_edges_ins_sort(stbtt__edge *p, int n)
2178 {
2179  int i,j;
2180  for (i=1; i < n; ++i) {
2181  stbtt__edge t = p[i], *a = &t;
2182  j = i;
2183  while (j > 0) {
2184  stbtt__edge *b = &p[j-1];
2185  int c = STBTT__COMPARE(a,b);
2186  if (!c) break;
2187  p[j] = p[j-1];
2188  --j;
2189  }
2190  if (i != j)
2191  p[j] = t;
2192  }
2193 }
2194 
2195 static void stbtt__sort_edges_quicksort(stbtt__edge *p, int n)
2196 {
2197  /* threshhold for transitioning to insertion sort */
2198  while (n > 12) {
2199  stbtt__edge t;
2200  int c01,c12,c,m,i,j;
2201 
2202  /* compute median of three */
2203  m = n >> 1;
2204  c01 = STBTT__COMPARE(&p[0],&p[m]);
2205  c12 = STBTT__COMPARE(&p[m],&p[n-1]);
2206  /* if 0 >= mid >= end, or 0 < mid < end, then use mid */
2207  if (c01 != c12) {
2208  /* otherwise, we'll need to swap something else to middle */
2209  int z;
2210  c = STBTT__COMPARE(&p[0],&p[n-1]);
2211  /* 0>mid && mid<n: 0>n => n; 0<n => 0 */
2212  /* 0<mid && mid>n: 0>n => 0; 0<n => n */
2213  z = (c == c12) ? 0 : n-1;
2214  t = p[z];
2215  p[z] = p[m];
2216  p[m] = t;
2217  }
2218  /* now p[m] is the median-of-three */
2219  /* swap it to the beginning so it won't move around */
2220  t = p[0];
2221  p[0] = p[m];
2222  p[m] = t;
2223 
2224  /* partition loop */
2225  i=1;
2226  j=n-1;
2227  for(;;) {
2228  /* handling of equality is crucial here */
2229  /* for sentinels & efficiency with duplicates */
2230  for (;;++i) {
2231  if (!STBTT__COMPARE(&p[i], &p[0])) break;
2232  }
2233  for (;;--j) {
2234  if (!STBTT__COMPARE(&p[0], &p[j])) break;
2235  }
2236  /* make sure we haven't crossed */
2237  if (i >= j) break;
2238  t = p[i];
2239  p[i] = p[j];
2240  p[j] = t;
2241 
2242  ++i;
2243  --j;
2244  }
2245  /* recurse on smaller side, iterate on larger */
2246  if (j < (n-i)) {
2247  stbtt__sort_edges_quicksort(p,j);
2248  p = p+i;
2249  n = n-i;
2250  } else {
2251  stbtt__sort_edges_quicksort(p+i, n-i);
2252  n = j;
2253  }
2254  }
2255 }
2256 
2257 static void stbtt__sort_edges(stbtt__edge *p, int n)
2258 {
2259  stbtt__sort_edges_quicksort(p, n);
2260  stbtt__sort_edges_ins_sort(p, n);
2261 }
2262 
2263 typedef struct
2264 {
2265  float x,y;
2266 } stbtt__point;
2267 
2268 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)
2269 {
2270  float y_scale_inv = invert ? -scale_y : scale_y;
2271  stbtt__edge *e;
2272  int n,i,j,k,m;
2273 #if STBTT_RASTERIZER_VERSION == 1
2274  int vsubsample = result->h < 8 ? 15 : 5;
2275 #elif STBTT_RASTERIZER_VERSION == 2
2276  int vsubsample = 1;
2277 #else
2278  #error "Unrecognized value of STBTT_RASTERIZER_VERSION"
2279 #endif
2280  // vsubsample should divide 255 evenly; otherwise we won't reach full opacity
2281 
2282  // now we have to blow out the windings into explicit edge lists
2283  n = 0;
2284  for (i=0; i < windings; ++i)
2285  n += wcount[i];
2286 
2287  e = (stbtt__edge *) STBTT_malloc(sizeof(*e) * (n+1), userdata); // add an extra one as a sentinel
2288  if (e == 0) return;
2289  n = 0;
2290 
2291  m=0;
2292  for (i=0; i < windings; ++i) {
2293  stbtt__point *p = pts + m;
2294  m += wcount[i];
2295  j = wcount[i]-1;
2296  for (k=0; k < wcount[i]; j=k++) {
2297  int a=k,b=j;
2298  // skip the edge if horizontal
2299  if (p[j].y == p[k].y)
2300  continue;
2301  // add edge from j to k to the list
2302  e[n].invert = 0;
2303  if (invert ? p[j].y > p[k].y : p[j].y < p[k].y) {
2304  e[n].invert = 1;
2305  a=j,b=k;
2306  }
2307  e[n].x0 = p[a].x * scale_x + shift_x;
2308  e[n].y0 = (p[a].y * y_scale_inv + shift_y) * vsubsample;
2309  e[n].x1 = p[b].x * scale_x + shift_x;
2310  e[n].y1 = (p[b].y * y_scale_inv + shift_y) * vsubsample;
2311  ++n;
2312  }
2313  }
2314 
2315  // now sort the edges by their highest point (should snap to integer, and then by x)
2316  //STBTT_sort(e, n, sizeof(e[0]), stbtt__edge_compare);
2317  stbtt__sort_edges(e, n);
2318 
2319  // now, traverse the scanlines and find the intersections on each scanline, use xor winding rule
2320  stbtt__rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y, userdata);
2321 
2322  STBTT_free(e, userdata);
2323 }
2324 
2325 static void stbtt__add_point(stbtt__point *points, int n, float x, float y)
2326 {
2327  if (!points) return; // during first pass, it's unallocated
2328  points[n].x = x;
2329  points[n].y = y;
2330 }
2331 
2332 // tesselate until threshhold p is happy... @TODO warped to compensate for non-linear stretching
2333 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)
2334 {
2335  // midpoint
2336  float mx = (x0 + 2*x1 + x2)/4;
2337  float my = (y0 + 2*y1 + y2)/4;
2338  // versus directly drawn line
2339  float dx = (x0+x2)/2 - mx;
2340  float dy = (y0+y2)/2 - my;
2341  if (n > 16) // 65536 segments on one curve better be enough!
2342  return 1;
2343  if (dx*dx+dy*dy > objspace_flatness_squared) { // half-pixel error allowed... need to be smaller if AA
2344  stbtt__tesselate_curve(points, num_points, x0,y0, (x0+x1)/2.0f,(y0+y1)/2.0f, mx,my, objspace_flatness_squared,n+1);
2345  stbtt__tesselate_curve(points, num_points, mx,my, (x1+x2)/2.0f,(y1+y2)/2.0f, x2,y2, objspace_flatness_squared,n+1);
2346  } else {
2347  stbtt__add_point(points, *num_points,x2,y2);
2348  *num_points = *num_points+1;
2349  }
2350  return 1;
2351 }
2352 
2353 // returns number of contours
2354 static stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts, float objspace_flatness, int **contour_lengths, int *num_contours, void *userdata)
2355 {
2356  stbtt__point *points=0;
2357  int num_points=0;
2358 
2359  float objspace_flatness_squared = objspace_flatness * objspace_flatness;
2360  int i,n=0,start=0, pass;
2361 
2362  // count how many "moves" there are to get the contour count
2363  for (i=0; i < num_verts; ++i)
2364  if (vertices[i].type == STBTT_vmove)
2365  ++n;
2366 
2367  *num_contours = n;
2368  if (n == 0) return 0;
2369 
2370  *contour_lengths = (int *) STBTT_malloc(sizeof(**contour_lengths) * n, userdata);
2371 
2372  if (*contour_lengths == 0) {
2373  *num_contours = 0;
2374  return 0;
2375  }
2376 
2377  // make two passes through the points so we don't need to realloc
2378  for (pass=0; pass < 2; ++pass) {
2379  float x=0,y=0;
2380  if (pass == 1) {
2381  points = (stbtt__point *) STBTT_malloc(num_points * sizeof(points[0]), userdata);
2382  if (points == NULL) goto error;
2383  }
2384  num_points = 0;
2385  n= -1;
2386  for (i=0; i < num_verts; ++i) {
2387  switch (vertices[i].type) {
2388  case STBTT_vmove:
2389  // start the next contour
2390  if (n >= 0)
2391  (*contour_lengths)[n] = num_points - start;
2392  ++n;
2393  start = num_points;
2394 
2395  x = vertices[i].x, y = vertices[i].y;
2396  stbtt__add_point(points, num_points++, x,y);
2397  break;
2398  case STBTT_vline:
2399  x = vertices[i].x, y = vertices[i].y;
2400  stbtt__add_point(points, num_points++, x, y);
2401  break;
2402  case STBTT_vcurve:
2403  stbtt__tesselate_curve(points, &num_points, x,y,
2404  vertices[i].cx, vertices[i].cy,
2405  vertices[i].x, vertices[i].y,
2406  objspace_flatness_squared, 0);
2407  x = vertices[i].x, y = vertices[i].y;
2408  break;
2409  }
2410  }
2411  (*contour_lengths)[n] = num_points - start;
2412  }
2413 
2414  return points;
2415 error:
2416  STBTT_free(points, userdata);
2417  STBTT_free(*contour_lengths, userdata);
2418  *contour_lengths = 0;
2419  *num_contours = 0;
2420  return NULL;
2421 }
2422 
2423 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)
2424 {
2425  float scale = scale_x > scale_y ? scale_y : scale_x;
2426  int winding_count, *winding_lengths;
2427  stbtt__point *windings = stbtt_FlattenCurves(vertices, num_verts, flatness_in_pixels / scale, &winding_lengths, &winding_count, userdata);
2428  if (windings) {
2429  stbtt__rasterize(result, windings, winding_lengths, winding_count, scale_x, scale_y, shift_x, shift_y, x_off, y_off, invert, userdata);
2430  STBTT_free(winding_lengths, userdata);
2431  STBTT_free(windings, userdata);
2432  }
2433 }
2434 
2435 STBTT_DEF void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata)
2436 {
2437  STBTT_free(bitmap, userdata);
2438 }
2439 
2440 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)
2441 {
2442  int ix0,iy0,ix1,iy1;
2443  stbtt__bitmap gbm;
2444  stbtt_vertex *vertices;
2445  int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices);
2446 
2447  if (scale_x == 0) scale_x = scale_y;
2448  if (scale_y == 0) {
2449  if (scale_x == 0) {
2450  STBTT_free(vertices, info->userdata);
2451  return NULL;
2452  }
2453  scale_y = scale_x;
2454  }
2455 
2456  stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,&ix1,&iy1);
2457 
2458  // now we get the size
2459  gbm.w = (ix1 - ix0);
2460  gbm.h = (iy1 - iy0);
2461  gbm.pixels = NULL; // in case we error
2462 
2463  if (width ) *width = gbm.w;
2464  if (height) *height = gbm.h;
2465  if (xoff ) *xoff = ix0;
2466  if (yoff ) *yoff = iy0;
2467 
2468  if (gbm.w && gbm.h) {
2469  gbm.pixels = (unsigned char *) STBTT_malloc(gbm.w * gbm.h, info->userdata);
2470  if (gbm.pixels) {
2471  gbm.stride = gbm.w;
2472 
2473  stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0, iy0, 1, info->userdata);
2474  }
2475  }
2476  STBTT_free(vertices, info->userdata);
2477  return gbm.pixels;
2478 }
2479 
2480 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)
2481 {
2482  return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y, 0.0f, 0.0f, glyph, width, height, xoff, yoff);
2483 }
2484 
2485 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)
2486 {
2487  int ix0,iy0;
2488  stbtt_vertex *vertices;
2489  int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices);
2490  stbtt__bitmap gbm;
2491 
2492  stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,0,0);
2493  gbm.pixels = output;
2494  gbm.w = out_w;
2495  gbm.h = out_h;
2496  gbm.stride = out_stride;
2497 
2498  if (gbm.w && gbm.h)
2499  stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0,iy0, 1, info->userdata);
2500 
2501  STBTT_free(vertices, info->userdata);
2502 }
2503 
2504 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)
2505 {
2506  stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f,0.0f, glyph);
2507 }
2508 
2509 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)
2510 {
2511  return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y,shift_x,shift_y, stbtt_FindGlyphIndex(info,codepoint), width,height,xoff,yoff);
2512 }
2513 
2514 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)
2515 {
2516  stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y, stbtt_FindGlyphIndex(info,codepoint));
2517 }
2518 
2519 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)
2520 {
2521  return stbtt_GetCodepointBitmapSubpixel(info, scale_x, scale_y, 0.0f,0.0f, codepoint, width,height,xoff,yoff);
2522 }
2523 
2524 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)
2525 {
2526  stbtt_MakeCodepointBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f,0.0f, codepoint);
2527 }
2528 
2530 //
2531 // bitmap baking
2532 //
2533 // This is SUPER-CRAPPY packing to keep source code small
2534 
2535 STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // font location (use offset=0 for plain .ttf)
2536  float pixel_height, // height of font in pixels
2537  unsigned char *pixels, int pw, int ph, // bitmap to be filled in
2538  int first_char, int num_chars, // characters to bake
2539  stbtt_bakedchar *chardata)
2540 {
2541  float scale;
2542  int x,y,bottom_y, i;
2543  stbtt_fontinfo f;
2544  f.userdata = NULL;
2545  if (!stbtt_InitFont(&f, data, offset))
2546  return -1;
2547  STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels
2548  x=y=1;
2549  bottom_y = 1;
2550 
2551  scale = stbtt_ScaleForPixelHeight(&f, pixel_height);
2552 
2553  for (i=0; i < num_chars; ++i) {
2554  int advance, lsb, x0,y0,x1,y1,gw,gh;
2555  int g = stbtt_FindGlyphIndex(&f, first_char + i);
2556  stbtt_GetGlyphHMetrics(&f, g, &advance, &lsb);
2557  stbtt_GetGlyphBitmapBox(&f, g, scale,scale, &x0,&y0,&x1,&y1);
2558  gw = x1-x0;
2559  gh = y1-y0;
2560  if (x + gw + 1 >= pw)
2561  y = bottom_y, x = 1; // advance to next row
2562  if (y + gh + 1 >= ph) // check if it fits vertically AFTER potentially moving to next row
2563  return -i;
2564  STBTT_assert(x+gw < pw);
2565  STBTT_assert(y+gh < ph);
2566  stbtt_MakeGlyphBitmap(&f, pixels+x+y*pw, gw,gh,pw, scale,scale, g);
2567  chardata[i].x0 = (stbtt_int16) x;
2568  chardata[i].y0 = (stbtt_int16) y;
2569  chardata[i].x1 = (stbtt_int16) (x + gw);
2570  chardata[i].y1 = (stbtt_int16) (y + gh);
2571  chardata[i].xadvance = scale * advance;
2572  chardata[i].xoff = (float) x0;
2573  chardata[i].yoff = (float) y0;
2574  x = x + gw + 1;
2575  if (y+gh+1 > bottom_y)
2576  bottom_y = y+gh+1;
2577  }
2578  return bottom_y;
2579 }
2580 
2581 STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int opengl_fillrule)
2582 {
2583  float d3d_bias = opengl_fillrule ? 0 : -0.5f;
2584  float ipw = 1.0f / pw, iph = 1.0f / ph;
2585  stbtt_bakedchar *b = chardata + char_index;
2586  int round_x = STBTT_ifloor((*xpos + b->xoff) + 0.5f);
2587  int round_y = STBTT_ifloor((*ypos + b->yoff) + 0.5f);
2588 
2589  q->x0 = round_x + d3d_bias;
2590  q->y0 = round_y + d3d_bias;
2591  q->x1 = round_x + b->x1 - b->x0 + d3d_bias;
2592  q->y1 = round_y + b->y1 - b->y0 + d3d_bias;
2593 
2594  q->s0 = b->x0 * ipw;
2595  q->t0 = b->y0 * iph;
2596  q->s1 = b->x1 * ipw;
2597  q->t1 = b->y1 * iph;
2598 
2599  *xpos += b->xadvance;
2600 }
2601 
2603 //
2604 // rectangle packing replacement routines if you don't have stb_rect_pack.h
2605 //
2606 
2607 #ifndef STB_RECT_PACK_VERSION
2608 
2609 typedef int stbrp_coord;
2610 
2612 // //
2613 // //
2614 // COMPILER WARNING ?!?!? //
2615 // //
2616 // //
2617 // if you get a compile warning due to these symbols being defined more than //
2618 // once, move #include "stb_rect_pack.h" before #include "stb_truetype.h" //
2619 // //
2621 
2622 typedef struct
2623 {
2624  int width,height;
2625  int x,y,bottom_y;
2626 } stbrp_context;
2627 
2628 typedef struct
2629 {
2630  unsigned char x;
2631 } stbrp_node;
2632 
2633 struct stbrp_rect
2634 {
2635  stbrp_coord x,y;
2636  int id,w,h,was_packed;
2637 };
2638 
2639 static void stbrp_init_target(stbrp_context *con, int pw, int ph, stbrp_node *nodes, int num_nodes)
2640 {
2641  con->width = pw;
2642  con->height = ph;
2643  con->x = 0;
2644  con->y = 0;
2645  con->bottom_y = 0;
2646  STBTT__NOTUSED(nodes);
2647  STBTT__NOTUSED(num_nodes);
2648 }
2649 
2650 static void stbrp_pack_rects(stbrp_context *con, stbrp_rect *rects, int num_rects)
2651 {
2652  int i;
2653  for (i=0; i < num_rects; ++i) {
2654  if (con->x + rects[i].w > con->width) {
2655  con->x = 0;
2656  con->y = con->bottom_y;
2657  }
2658  if (con->y + rects[i].h > con->height)
2659  break;
2660  rects[i].x = con->x;
2661  rects[i].y = con->y;
2662  rects[i].was_packed = 1;
2663  con->x += rects[i].w;
2664  if (con->y + rects[i].h > con->bottom_y)
2665  con->bottom_y = con->y + rects[i].h;
2666  }
2667  for ( ; i < num_rects; ++i)
2668  rects[i].was_packed = 0;
2669 }
2670 #endif
2671 
2673 //
2674 // bitmap baking
2675 //
2676 // This is SUPER-AWESOME (tm Ryan Gordon) packing using stb_rect_pack.h. If
2677 // stb_rect_pack.h isn't available, it uses the BakeFontBitmap strategy.
2678 
2679 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)
2680 {
2681  stbrp_context *context = (stbrp_context *) STBTT_malloc(sizeof(*context) ,alloc_context);
2682  int num_nodes = pw - padding;
2683  stbrp_node *nodes = (stbrp_node *) STBTT_malloc(sizeof(*nodes ) * num_nodes,alloc_context);
2684 
2685  if (context == NULL || nodes == NULL) {
2686  if (context != NULL) STBTT_free(context, alloc_context);
2687  if (nodes != NULL) STBTT_free(nodes , alloc_context);
2688  return 0;
2689  }
2690 
2691  spc->user_allocator_context = alloc_context;
2692  spc->width = pw;
2693  spc->height = ph;
2694  spc->pixels = pixels;
2695  spc->pack_info = context;
2696  spc->nodes = nodes;
2697  spc->padding = padding;
2698  spc->stride_in_bytes = stride_in_bytes != 0 ? stride_in_bytes : pw;
2699  spc->h_oversample = 1;
2700  spc->v_oversample = 1;
2701 
2702  stbrp_init_target(context, pw-padding, ph-padding, nodes, num_nodes);
2703 
2704  if (pixels)
2705  STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels
2706 
2707  return 1;
2708 }
2709 
2710 STBTT_DEF void stbtt_PackEnd (stbtt_pack_context *spc)
2711 {
2712  STBTT_free(spc->nodes , spc->user_allocator_context);
2713  STBTT_free(spc->pack_info, spc->user_allocator_context);
2714 }
2715 
2716 STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample)
2717 {
2718  STBTT_assert(h_oversample <= STBTT_MAX_OVERSAMPLE);
2719  STBTT_assert(v_oversample <= STBTT_MAX_OVERSAMPLE);
2720  if (h_oversample <= STBTT_MAX_OVERSAMPLE)
2721  spc->h_oversample = h_oversample;
2722  if (v_oversample <= STBTT_MAX_OVERSAMPLE)
2723  spc->v_oversample = v_oversample;
2724 }
2725 
2726 #define STBTT__OVER_MASK (STBTT_MAX_OVERSAMPLE-1)
2727 
2728 static void stbtt__h_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width)
2729 {
2730  unsigned char buffer[STBTT_MAX_OVERSAMPLE];
2731  int safe_w = w - kernel_width;
2732  int j;
2733  STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); // suppress bogus warning from VS2013 -analyze
2734  for (j=0; j < h; ++j) {
2735  int i;
2736  unsigned int total;
2737  STBTT_memset(buffer, 0, kernel_width);
2738 
2739  total = 0;
2740 
2741  // make kernel_width a constant in common cases so compiler can optimize out the divide
2742  switch (kernel_width) {
2743  case 2:
2744  for (i=0; i <= safe_w; ++i) {
2745  total += pixels[i] - buffer[i & STBTT__OVER_MASK];
2746  buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
2747  pixels[i] = (unsigned char) (total / 2);
2748  }
2749  break;
2750  case 3:
2751  for (i=0; i <= safe_w; ++i) {
2752  total += pixels[i] - buffer[i & STBTT__OVER_MASK];
2753  buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
2754  pixels[i] = (unsigned char) (total / 3);
2755  }
2756  break;
2757  case 4:
2758  for (i=0; i <= safe_w; ++i) {
2759  total += pixels[i] - buffer[i & STBTT__OVER_MASK];
2760  buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
2761  pixels[i] = (unsigned char) (total / 4);
2762  }
2763  break;
2764  case 5:
2765  for (i=0; i <= safe_w; ++i) {
2766  total += pixels[i] - buffer[i & STBTT__OVER_MASK];
2767  buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
2768  pixels[i] = (unsigned char) (total / 5);
2769  }
2770  break;
2771  default:
2772  for (i=0; i <= safe_w; ++i) {
2773  total += pixels[i] - buffer[i & STBTT__OVER_MASK];
2774  buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
2775  pixels[i] = (unsigned char) (total / kernel_width);
2776  }
2777  break;
2778  }
2779 
2780  for (; i < w; ++i) {
2781  STBTT_assert(pixels[i] == 0);
2782  total -= buffer[i & STBTT__OVER_MASK];
2783  pixels[i] = (unsigned char) (total / kernel_width);
2784  }
2785 
2786  pixels += stride_in_bytes;
2787  }
2788 }
2789 
2790 static void stbtt__v_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width)
2791 {
2792  unsigned char buffer[STBTT_MAX_OVERSAMPLE];
2793  int safe_h = h - kernel_width;
2794  int j;
2795  STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); // suppress bogus warning from VS2013 -analyze
2796  for (j=0; j < w; ++j) {
2797  int i;
2798  unsigned int total;
2799  STBTT_memset(buffer, 0, kernel_width);
2800 
2801  total = 0;
2802 
2803  // make kernel_width a constant in common cases so compiler can optimize out the divide
2804  switch (kernel_width) {
2805  case 2:
2806  for (i=0; i <= safe_h; ++i) {
2807  total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
2808  buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
2809  pixels[i*stride_in_bytes] = (unsigned char) (total / 2);
2810  }
2811  break;
2812  case 3:
2813  for (i=0; i <= safe_h; ++i) {
2814  total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
2815  buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
2816  pixels[i*stride_in_bytes] = (unsigned char) (total / 3);
2817  }
2818  break;
2819  case 4:
2820  for (i=0; i <= safe_h; ++i) {
2821  total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
2822  buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
2823  pixels[i*stride_in_bytes] = (unsigned char) (total / 4);
2824  }
2825  break;
2826  case 5:
2827  for (i=0; i <= safe_h; ++i) {
2828  total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
2829  buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
2830  pixels[i*stride_in_bytes] = (unsigned char) (total / 5);
2831  }
2832  break;
2833  default:
2834  for (i=0; i <= safe_h; ++i) {
2835  total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
2836  buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
2837  pixels[i*stride_in_bytes] = (unsigned char) (total / kernel_width);
2838  }
2839  break;
2840  }
2841 
2842  for (; i < h; ++i) {
2843  STBTT_assert(pixels[i*stride_in_bytes] == 0);
2844  total -= buffer[i & STBTT__OVER_MASK];
2845  pixels[i*stride_in_bytes] = (unsigned char) (total / kernel_width);
2846  }
2847 
2848  pixels += 1;
2849  }
2850 }
2851 
2852 static float stbtt__oversample_shift(int oversample)
2853 {
2854  if (!oversample)
2855  return 0.0f;
2856 
2857  // The prefilter is a box filter of width "oversample",
2858  // which shifts phase by (oversample - 1)/2 pixels in
2859  // oversampled space. We want to shift in the opposite
2860  // direction to counter this.
2861  return (float)-(oversample - 1) / (2.0f * (float)oversample);
2862 }
2863 
2864 // rects array must be big enough to accommodate all characters in the given ranges
2865 STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects)
2866 {
2867  int i,j,k;
2868 
2869  k=0;
2870  for (i=0; i < num_ranges; ++i) {
2871  float fh = ranges[i].font_size;
2872  float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh);
2873  ranges[i].h_oversample = (unsigned char) spc->h_oversample;
2874  ranges[i].v_oversample = (unsigned char) spc->v_oversample;
2875  for (j=0; j < ranges[i].num_chars; ++j) {
2876  int x0,y0,x1,y1;
2877  int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
2878  int glyph = stbtt_FindGlyphIndex(info, codepoint);
2879  stbtt_GetGlyphBitmapBoxSubpixel(info,glyph,
2880  scale * spc->h_oversample,
2881  scale * spc->v_oversample,
2882  0,0,
2883  &x0,&y0,&x1,&y1);
2884  rects[k].w = (stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1);
2885  rects[k].h = (stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1);
2886  ++k;
2887  }
2888  }
2889 
2890  return k;
2891 }
2892 
2893 // rects array must be big enough to accommodate all characters in the given ranges
2894 STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects)
2895 {
2896  int i,j,k, return_value = 1;
2897 
2898  // save current values
2899  int old_h_over = spc->h_oversample;
2900  int old_v_over = spc->v_oversample;
2901 
2902  k = 0;
2903  for (i=0; i < num_ranges; ++i) {
2904  float fh = ranges[i].font_size;
2905  float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh);
2906  float recip_h,recip_v,sub_x,sub_y;
2907  spc->h_oversample = ranges[i].h_oversample;
2908  spc->v_oversample = ranges[i].v_oversample;
2909  recip_h = 1.0f / spc->h_oversample;
2910  recip_v = 1.0f / spc->v_oversample;
2911  sub_x = stbtt__oversample_shift(spc->h_oversample);
2912  sub_y = stbtt__oversample_shift(spc->v_oversample);
2913  for (j=0; j < ranges[i].num_chars; ++j) {
2914  stbrp_rect *r = &rects[k];
2915  if (r->was_packed) {
2916  stbtt_packedchar *bc = &ranges[i].chardata_for_range[j];
2917  int advance, lsb, x0,y0,x1,y1;
2918  int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
2919  int glyph = stbtt_FindGlyphIndex(info, codepoint);
2920  stbrp_coord pad = (stbrp_coord) spc->padding;
2921 
2922  // pad on left and top
2923  r->x += pad;
2924  r->y += pad;
2925  r->w -= pad;
2926  r->h -= pad;
2927  stbtt_GetGlyphHMetrics(info, glyph, &advance, &lsb);
2928  stbtt_GetGlyphBitmapBox(info, glyph,
2929  scale * spc->h_oversample,
2930  scale * spc->v_oversample,
2931  &x0,&y0,&x1,&y1);
2932  stbtt_MakeGlyphBitmapSubpixel(info,
2933  spc->pixels + r->x + r->y*spc->stride_in_bytes,
2934  r->w - spc->h_oversample+1,
2935  r->h - spc->v_oversample+1,
2936  spc->stride_in_bytes,
2937  scale * spc->h_oversample,
2938  scale * spc->v_oversample,
2939  0,0,
2940  glyph);
2941 
2942  if (spc->h_oversample > 1)
2943  stbtt__h_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes,
2944  r->w, r->h, spc->stride_in_bytes,
2945  spc->h_oversample);
2946 
2947  if (spc->v_oversample > 1)
2948  stbtt__v_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes,
2949  r->w, r->h, spc->stride_in_bytes,
2950  spc->v_oversample);
2951 
2952  bc->x0 = (stbtt_int16) r->x;
2953  bc->y0 = (stbtt_int16) r->y;
2954  bc->x1 = (stbtt_int16) (r->x + r->w);
2955  bc->y1 = (stbtt_int16) (r->y + r->h);
2956  bc->xadvance = scale * advance;
2957  bc->xoff = (float) x0 * recip_h + sub_x;
2958  bc->yoff = (float) y0 * recip_v + sub_y;
2959  bc->xoff2 = (x0 + r->w) * recip_h + sub_x;
2960  bc->yoff2 = (y0 + r->h) * recip_v + sub_y;
2961  } else {
2962  return_value = 0; // if any fail, report failure
2963  }
2964 
2965  ++k;
2966  }
2967  }
2968 
2969  // restore original values
2970  spc->h_oversample = old_h_over;
2971  spc->v_oversample = old_v_over;
2972 
2973  return return_value;
2974 }
2975 
2976 STBTT_DEF void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect *rects, int num_rects)
2977 {
2978  stbrp_pack_rects((stbrp_context *) spc->pack_info, rects, num_rects);
2979 }
2980 
2981 STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges)
2982 {
2983  stbtt_fontinfo info;
2984  int i,j,n, return_value = 1;
2985  //stbrp_context *context = (stbrp_context *) spc->pack_info;
2986  stbrp_rect *rects;
2987 
2988  // flag all characters as NOT packed
2989  for (i=0; i < num_ranges; ++i)
2990  for (j=0; j < ranges[i].num_chars; ++j)
2991  ranges[i].chardata_for_range[j].x0 =
2992  ranges[i].chardata_for_range[j].y0 =
2993  ranges[i].chardata_for_range[j].x1 =
2994  ranges[i].chardata_for_range[j].y1 = 0;
2995 
2996  n = 0;
2997  for (i=0; i < num_ranges; ++i)
2998  n += ranges[i].num_chars;
2999 
3000  rects = (stbrp_rect *) STBTT_malloc(sizeof(*rects) * n, spc->user_allocator_context);
3001  if (rects == NULL)
3002  return 0;
3003 
3004  info.userdata = spc->user_allocator_context;
3005  stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata,font_index));
3006 
3007  n = stbtt_PackFontRangesGatherRects(spc, &info, ranges, num_ranges, rects);
3008 
3009  stbtt_PackFontRangesPackRects(spc, rects, n);
3010 
3011  return_value = stbtt_PackFontRangesRenderIntoRects(spc, &info, ranges, num_ranges, rects);
3012 
3013  STBTT_free(rects, spc->user_allocator_context);
3014  return return_value;
3015 }
3016 
3017 STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, float font_size,
3018  int first_unicode_codepoint_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range)
3019 {
3020  stbtt_pack_range range;
3021  range.first_unicode_codepoint_in_range = first_unicode_codepoint_in_range;
3022  range.array_of_unicode_codepoints = NULL;
3023  range.num_chars = num_chars_in_range;
3024  range.chardata_for_range = chardata_for_range;
3025  range.font_size = font_size;
3026  return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1);
3027 }
3028 
3029 STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int align_to_integer)
3030 {
3031  float ipw = 1.0f / pw, iph = 1.0f / ph;
3032  stbtt_packedchar *b = chardata + char_index;
3033 
3034  if (align_to_integer) {
3035  float x = (float) STBTT_ifloor((*xpos + b->xoff) + 0.5f);
3036  float y = (float) STBTT_ifloor((*ypos + b->yoff) + 0.5f);
3037  q->x0 = x;
3038  q->y0 = y;
3039  q->x1 = x + b->xoff2 - b->xoff;
3040  q->y1 = y + b->yoff2 - b->yoff;
3041  } else {
3042  q->x0 = *xpos + b->xoff;
3043  q->y0 = *ypos + b->yoff;
3044  q->x1 = *xpos + b->xoff2;
3045  q->y1 = *ypos + b->yoff2;
3046  }
3047 
3048  q->s0 = b->x0 * ipw;
3049  q->t0 = b->y0 * iph;
3050  q->s1 = b->x1 * ipw;
3051  q->t1 = b->y1 * iph;
3052 
3053  *xpos += b->xadvance;
3054 }
3055 
3056 
3058 //
3059 // font name matching -- recommended not to use this
3060 //
3061 
3062 // check if a utf8 string contains a prefix which is the utf16 string; if so return length of matching utf8 string
3063 static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(const stbtt_uint8 *s1, stbtt_int32 len1, const stbtt_uint8 *s2, stbtt_int32 len2)
3064 {
3065  stbtt_int32 i=0;
3066 
3067  // convert utf16 to utf8 and compare the results while converting
3068  while (len2) {
3069  stbtt_uint16 ch = s2[0]*256 + s2[1];
3070  if (ch < 0x80) {
3071  if (i >= len1) return -1;
3072  if (s1[i++] != ch) return -1;
3073  } else if (ch < 0x800) {
3074  if (i+1 >= len1) return -1;
3075  if (s1[i++] != 0xc0 + (ch >> 6)) return -1;
3076  if (s1[i++] != 0x80 + (ch & 0x3f)) return -1;
3077  } else if (ch >= 0xd800 && ch < 0xdc00) {
3078  stbtt_uint32 c;
3079  stbtt_uint16 ch2 = s2[2]*256 + s2[3];
3080  if (i+3 >= len1) return -1;
3081  c = ((ch - 0xd800) << 10) + (ch2 - 0xdc00) + 0x10000;
3082  if (s1[i++] != 0xf0 + (c >> 18)) return -1;
3083  if (s1[i++] != 0x80 + ((c >> 12) & 0x3f)) return -1;
3084  if (s1[i++] != 0x80 + ((c >> 6) & 0x3f)) return -1;
3085  if (s1[i++] != 0x80 + ((c ) & 0x3f)) return -1;
3086  s2 += 2; // plus another 2 below
3087  len2 -= 2;
3088  } else if (ch >= 0xdc00 && ch < 0xe000) {
3089  return -1;
3090  } else {
3091  if (i+2 >= len1) return -1;
3092  if (s1[i++] != 0xe0 + (ch >> 12)) return -1;
3093  if (s1[i++] != 0x80 + ((ch >> 6) & 0x3f)) return -1;
3094  if (s1[i++] != 0x80 + ((ch ) & 0x3f)) return -1;
3095  }
3096  s2 += 2;
3097  len2 -= 2;
3098  }
3099  return i;
3100 }
3101 
3102 STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2)
3103 {
3104  return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((const stbtt_uint8*) s1, len1, (const stbtt_uint8*) s2, len2);
3105 }
3106 
3107 // returns results in whatever encoding you request... but note that 2-byte encodings
3108 // will be BIG-ENDIAN... use stbtt_CompareUTF8toUTF16_bigendian() to compare
3109 STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID)
3110 {
3111  stbtt_int32 i,count,stringOffset;
3112  stbtt_uint8 *fc = font->data;
3113  stbtt_uint32 offset = font->fontstart;
3114  stbtt_uint32 nm = stbtt__find_table(fc, offset, "name");
3115  if (!nm) return NULL;
3116 
3117  count = ttUSHORT(fc+nm+2);
3118  stringOffset = nm + ttUSHORT(fc+nm+4);
3119  for (i=0; i < count; ++i) {
3120  stbtt_uint32 loc = nm + 6 + 12 * i;
3121  if (platformID == ttUSHORT(fc+loc+0) && encodingID == ttUSHORT(fc+loc+2)
3122  && languageID == ttUSHORT(fc+loc+4) && nameID == ttUSHORT(fc+loc+6)) {
3123  *length = ttUSHORT(fc+loc+8);
3124  return (const char *) (fc+stringOffset+ttUSHORT(fc+loc+10));
3125  }
3126  }
3127  return NULL;
3128 }
3129 
3130 static int stbtt__matchpair(stbtt_uint8 *fc, stbtt_uint32 nm, stbtt_uint8 *name, stbtt_int32 nlen, stbtt_int32 target_id, stbtt_int32 next_id)
3131 {
3132  stbtt_int32 i;
3133  stbtt_int32 count = ttUSHORT(fc+nm+2);
3134  stbtt_int32 stringOffset = nm + ttUSHORT(fc+nm+4);
3135 
3136  for (i=0; i < count; ++i) {
3137  stbtt_uint32 loc = nm + 6 + 12 * i;
3138  stbtt_int32 id = ttUSHORT(fc+loc+6);
3139  if (id == target_id) {
3140  // find the encoding
3141  stbtt_int32 platform = ttUSHORT(fc+loc+0), encoding = ttUSHORT(fc+loc+2), language = ttUSHORT(fc+loc+4);
3142 
3143  // is this a Unicode encoding?
3144  if (platform == 0 || (platform == 3 && encoding == 1) || (platform == 3 && encoding == 10)) {
3145  stbtt_int32 slen = ttUSHORT(fc+loc+8);
3146  stbtt_int32 off = ttUSHORT(fc+loc+10);
3147 
3148  // check if there's a prefix match
3149  stbtt_int32 matchlen = stbtt__CompareUTF8toUTF16_bigendian_prefix(name, nlen, fc+stringOffset+off,slen);
3150  if (matchlen >= 0) {
3151  // check for target_id+1 immediately following, with same encoding & language
3152  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) {
3153  slen = ttUSHORT(fc+loc+12+8);
3154  off = ttUSHORT(fc+loc+12+10);
3155  if (slen == 0) {
3156  if (matchlen == nlen)
3157  return 1;
3158  } else if (matchlen < nlen && name[matchlen] == ' ') {
3159  ++matchlen;
3160  if (stbtt_CompareUTF8toUTF16_bigendian((char*) (name+matchlen), nlen-matchlen, (char*)(fc+stringOffset+off),slen))
3161  return 1;
3162  }
3163  } else {
3164  // if nothing immediately following
3165  if (matchlen == nlen)
3166  return 1;
3167  }
3168  }
3169  }
3170 
3171  // @TODO handle other encodings
3172  }
3173  }
3174  return 0;
3175 }
3176 
3177 static int stbtt__matches(stbtt_uint8 *fc, stbtt_uint32 offset, stbtt_uint8 *name, stbtt_int32 flags)
3178 {
3179  stbtt_int32 nlen = (stbtt_int32) STBTT_strlen((char *) name);
3180  stbtt_uint32 nm,hd;
3181  if (!stbtt__isfont(fc+offset)) return 0;
3182 
3183  // check italics/bold/underline flags in macStyle...
3184  if (flags) {
3185  hd = stbtt__find_table(fc, offset, "head");
3186  if ((ttUSHORT(fc+hd+44) & 7) != (flags & 7)) return 0;
3187  }
3188 
3189  nm = stbtt__find_table(fc, offset, "name");
3190  if (!nm) return 0;
3191 
3192  if (flags) {
3193  // if we checked the macStyle flags, then just check the family and ignore the subfamily
3194  if (stbtt__matchpair(fc, nm, name, nlen, 16, -1)) return 1;
3195  if (stbtt__matchpair(fc, nm, name, nlen, 1, -1)) return 1;
3196  if (stbtt__matchpair(fc, nm, name, nlen, 3, -1)) return 1;
3197  } else {
3198  if (stbtt__matchpair(fc, nm, name, nlen, 16, 17)) return 1;
3199  if (stbtt__matchpair(fc, nm, name, nlen, 1, 2)) return 1;
3200  if (stbtt__matchpair(fc, nm, name, nlen, 3, -1)) return 1;
3201  }
3202 
3203  return 0;
3204 }
3205 
3206 STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *font_collection, const char *name_utf8, stbtt_int32 flags)
3207 {
3208  stbtt_int32 i;
3209  for (i=0;;++i) {
3210  stbtt_int32 off = stbtt_GetFontOffsetForIndex(font_collection, i);
3211  if (off < 0) return off;
3212  if (stbtt__matches((stbtt_uint8 *) font_collection, off, (stbtt_uint8*) name_utf8, flags))
3213  return off;
3214  }
3215 }
3216 
3217 #endif // STB_TRUETYPE_IMPLEMENTATION
3218 
3219 
3220 // FULL VERSION HISTORY
3221 //
3222 // 1.11 (2016-04-02) fix unused-variable warning
3223 // 1.10 (2016-04-02) allow user-defined fabs() replacement
3224 // fix memory leak if fontsize=0.0
3225 // fix warning from duplicate typedef
3226 // 1.09 (2016-01-16) warning fix; avoid crash on outofmem; use alloc userdata for PackFontRanges
3227 // 1.08 (2015-09-13) document stbtt_Rasterize(); fixes for vertical & horizontal edges
3228 // 1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints;
3229 // allow PackFontRanges to pack and render in separate phases;
3230 // fix stbtt_GetFontOFfsetForIndex (never worked for non-0 input?);
3231 // fixed an assert() bug in the new rasterizer
3232 // replace assert() with STBTT_assert() in new rasterizer
3233 // 1.06 (2015-07-14) performance improvements (~35% faster on x86 and x64 on test machine)
3234 // also more precise AA rasterizer, except if shapes overlap
3235 // remove need for STBTT_sort
3236 // 1.05 (2015-04-15) fix misplaced definitions for STBTT_STATIC
3237 // 1.04 (2015-04-15) typo in example
3238 // 1.03 (2015-04-12) STBTT_STATIC, fix memory leak in new packing, various fixes
3239 // 1.02 (2014-12-10) fix various warnings & compile issues w/ stb_rect_pack, C++
3240 // 1.01 (2014-12-08) fix subpixel position when oversampling to exactly match
3241 // non-oversampled; STBTT_POINT_SIZE for packed case only
3242 // 1.00 (2014-12-06) add new PackBegin etc. API, w/ support for oversampling
3243 // 0.99 (2014-09-18) fix multiple bugs with subpixel rendering (ryg)
3244 // 0.9 (2014-08-07) support certain mac/iOS fonts without an MS platformID
3245 // 0.8b (2014-07-07) fix a warning
3246 // 0.8 (2014-05-25) fix a few more warnings
3247 // 0.7 (2013-09-25) bugfix: subpixel glyph bug fixed in 0.5 had come back
3248 // 0.6c (2012-07-24) improve documentation
3249 // 0.6b (2012-07-20) fix a few more warnings
3250 // 0.6 (2012-07-17) fix warnings; added stbtt_ScaleForMappingEmToPixels,
3251 // stbtt_GetFontBoundingBox, stbtt_IsGlyphEmpty
3252 // 0.5 (2011-12-09) bugfixes:
3253 // subpixel glyph renderer computed wrong bounding box
3254 // first vertex of shape can be off-curve (FreeSans)
3255 // 0.4b (2011-12-03) fixed an error in the font baking example
3256 // 0.4 (2011-12-01) kerning, subpixel rendering (tor)
3257 // bugfixes for:
3258 // codepoint-to-glyph conversion using table fmt=12
3259 // codepoint-to-glyph conversion using table fmt=4
3260 // stbtt_GetBakedQuad with non-square texture (Zer)
3261 // updated Hello World! sample to use kerning and subpixel
3262 // fixed some warnings
3263 // 0.3 (2009-06-24) cmap fmt=12, compound shapes (MM)
3264 // userdata, malloc-from-userdata, non-zero fill (stb)
3265 // 0.2 (2009-03-11) Fix unsigned/signed char warnings
3266 // 0.1 (2009-03-09) First public release
3267 //
Definition: stb_truetype.h:468
Definition: stb_truetype.h:484
Definition: stb_truetype.h:558
Definition: stb_truetype.h:611
Definition: stb_truetype.h:514
Definition: stb_truetype.h:640
Definition: stb_truetype.h:735
Definition: stb_truetype.h:813