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