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