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