Customized fork of github.com/rxi/lite

update stb_truetype

Changed files
+262 -104
src
lib
+262 -104
src/lib/stb/stb_truetype.h
··· 1 - // stb_truetype.h - v1.19 - public domain 2 - // authored from 2009-2016 by Sean Barrett / RAD Game Tools 1 + // stb_truetype.h - v1.24 - public domain 2 + // authored from 2009-2020 by Sean Barrett / RAD Game Tools 3 + // 4 + // ======================================================================= 5 + // 6 + // NO SECURITY GUARANTEE -- DO NOT USE THIS ON UNTRUSTED FONT FILES 7 + // 8 + // This library does no range checking of the offsets found in the file, 9 + // meaning an attacker can use it to read arbitrary memory. 10 + // 11 + // ======================================================================= 3 12 // 4 13 // This library processes TrueType files: 5 14 // parse files ··· 32 41 // Daniel Ribeiro Maciel 33 42 // 34 43 // Bug/warning reports/fixes: 35 - // "Zer" on mollyrocket Fabian "ryg" Giesen 36 - // Cass Everitt Martins Mozeiko 37 - // stoiko (Haemimont Games) Cap Petschulat 38 - // Brian Hook Omar Cornut 39 - // Walter van Niftrik github:aloucks 44 + // "Zer" on mollyrocket Fabian "ryg" Giesen github:NiLuJe 45 + // Cass Everitt Martins Mozeiko github:aloucks 46 + // stoiko (Haemimont Games) Cap Petschulat github:oyvindjam 47 + // Brian Hook Omar Cornut github:vassvik 48 + // Walter van Niftrik Ryan Griege 40 49 // David Gow Peter LaValle 41 50 // David Given Sergey Popov 42 51 // Ivan-Assen Ivanov Giumo X. Clanjor ··· 44 53 // Johan Duparc Thomas Fields 45 54 // Hou Qiming Derek Vinyard 46 55 // Rob Loach Cort Stratton 47 - // Kenney Phillis Jr. github:oyvindjam 48 - // Brian Costabile github:vassvik 49 - // 56 + // Kenney Phillis Jr. Brian Costabile 57 + // Ken Voskuil (kaesve) 58 + // 50 59 // VERSION HISTORY 51 60 // 61 + // 1.24 (2020-02-05) fix warning 62 + // 1.23 (2020-02-02) query SVG data for glyphs; query whole kerning table (but only kern not GPOS) 63 + // 1.22 (2019-08-11) minimize missing-glyph duplication; fix kerning if both 'GPOS' and 'kern' are defined 64 + // 1.21 (2019-02-25) fix warning 65 + // 1.20 (2019-02-07) PackFontRange skips missing codepoints; GetScaleFontVMetrics() 52 66 // 1.19 (2018-02-11) GPOS kerning, STBTT_fmod 53 67 // 1.18 (2018-01-29) add missing function 54 68 // 1.17 (2017-07-23) make more arguments const; doc fix ··· 75 89 // 76 90 // USAGE 77 91 // 78 - // Include this file in whatever places neeed to refer to it. In ONE C/C++ 92 + // Include this file in whatever places need to refer to it. In ONE C/C++ 79 93 // file, write: 80 94 // #define STB_TRUETYPE_IMPLEMENTATION 81 95 // before the #include of this file. This expands out the actual ··· 206 220 // 207 221 // Advancing for the next character: 208 222 // Call GlyphHMetrics, and compute 'current_point += SF * advance'. 209 - // 223 + // 210 224 // 211 225 // ADVANCED USAGE 212 226 // ··· 242 256 // recommend it. 243 257 // 244 258 // 245 - // SOURCE STATISTICS (based on v0.6c, 2050 LOC) 246 - // 247 - // Documentation & header file 520 LOC \___ 660 LOC documentation 248 - // Sample code 140 LOC / 249 - // Truetype parsing 620 LOC ---- 620 LOC TrueType 250 - // Software rasterization 240 LOC \ . 251 - // Curve tesselation 120 LOC \__ 550 LOC Bitmap creation 252 - // Bitmap management 100 LOC / 253 - // Baked bitmap interface 70 LOC / 254 - // Font name matching & access 150 LOC ---- 150 255 - // C runtime library abstraction 60 LOC ---- 60 256 - // 257 - // 258 259 // PERFORMANCE MEASUREMENTS FOR 1.06: 259 260 // 260 261 // 32-bit 64-bit ··· 344 345 } 345 346 return 0; 346 347 } 347 - #endif 348 + #endif 348 349 // 349 350 // Output: 350 351 // ··· 358 359 // :@@. M@M 359 360 // @@@o@@@@ 360 361 // :M@@V:@@. 361 - // 362 + // 362 363 ////////////////////////////////////////////////////////////////////////////// 363 - // 364 + // 364 365 // Complete program: print "Hello World!" banner, with bugs 365 366 // 366 367 #if 0 ··· 556 557 // 557 558 // It's inefficient; you might want to c&p it and optimize it. 558 559 560 + STBTT_DEF void stbtt_GetScaledFontVMetrics(const unsigned char *fontdata, int index, float size, float *ascent, float *descent, float *lineGap); 561 + // Query the font vertical metrics without having to create a font first. 559 562 560 563 561 564 ////////////////////////////////////////////////////////////////////////////// ··· 641 644 // To use with PackFontRangesGather etc., you must set it before calls 642 645 // call to PackFontRangesGatherRects. 643 646 647 + STBTT_DEF void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context *spc, int skip); 648 + // If skip != 0, this tells stb_truetype to skip any codepoints for which 649 + // there is no corresponding glyph. If skip=0, which is the default, then 650 + // codepoints without a glyph recived the font's "missing character" glyph, 651 + // typically an empty box by convention. 652 + 644 653 STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, // same data as above 645 654 int char_index, // character to display 646 655 float *xpos, float *ypos, // pointers to current position in screen pixel space ··· 653 662 // Calling these functions in sequence is roughly equivalent to calling 654 663 // stbtt_PackFontRanges(). If you more control over the packing of multiple 655 664 // fonts, or if you want to pack custom data into a font texture, take a look 656 - // at the source to of stbtt_PackFontRanges() and create a custom version 665 + // at the source to of stbtt_PackFontRanges() and create a custom version 657 666 // using these functions, e.g. call GatherRects multiple times, 658 667 // building up a single array of rects, then call PackRects once, 659 668 // then call RenderIntoRects repeatedly. This may result in a ··· 669 678 int height; 670 679 int stride_in_bytes; 671 680 int padding; 681 + int skip_missing; 672 682 unsigned int h_oversample, v_oversample; 673 683 unsigned char *pixels; 674 684 void *nodes; ··· 694 704 // file will only define one font and it always be at offset 0, so it will 695 705 // return '0' for index 0, and -1 for all other indices. 696 706 697 - // The following structure is defined publically so you can declare one on 707 + // The following structure is defined publicly so you can declare one on 698 708 // the stack or as a global or etc, but you should treat it as opaque. 699 709 struct stbtt_fontinfo 700 710 { ··· 704 714 705 715 int numGlyphs; // number of glyphs, needed for range checking 706 716 707 - int loca,head,glyf,hhea,hmtx,kern,gpos; // table locations as offset from start of .ttf 717 + int loca,head,glyf,hhea,hmtx,kern,gpos,svg; // table locations as offset from start of .ttf 708 718 int index_map; // a cmap mapping for our chosen character encoding 709 719 int indexToLocFormat; // format needed to map from glyph index to glyph 710 720 ··· 733 743 // and you want a speed-up, call this function with the character you're 734 744 // going to process, then use glyph-based functions instead of the 735 745 // codepoint-based functions. 746 + // Returns 0 if the character codepoint is not defined in the font. 736 747 737 748 738 749 ////////////////////////////////////////////////////////////////////////////// ··· 786 797 STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1); 787 798 // as above, but takes one or more glyph indices for greater efficiency 788 799 800 + typedef struct stbtt_kerningentry 801 + { 802 + int glyph1; // use stbtt_FindGlyphIndex 803 + int glyph2; 804 + int advance; 805 + } stbtt_kerningentry; 806 + 807 + STBTT_DEF int stbtt_GetKerningTableLength(const stbtt_fontinfo *info); 808 + STBTT_DEF int stbtt_GetKerningTable(const stbtt_fontinfo *info, stbtt_kerningentry* table, int table_length); 809 + // Retrieves a complete list of all of the kerning pairs provided by the font 810 + // stbtt_GetKerningTable never writes more than table_length entries and returns how many entries it did write. 811 + // The table will be sorted by (a.glyph1 == b.glyph1)?(a.glyph2 < b.glyph2):(a.glyph1 < b.glyph1) 789 812 790 813 ////////////////////////////////////////////////////////////////////////////// 791 814 // ··· 820 843 // returns # of vertices and fills *vertices with the pointer to them 821 844 // these are expressed in "unscaled" coordinates 822 845 // 823 - // The shape is a series of countours. Each one starts with 846 + // The shape is a series of contours. Each one starts with 824 847 // a STBTT_moveto, then consists of a series of mixed 825 848 // STBTT_lineto and STBTT_curveto segments. A lineto 826 849 // draws a line from previous endpoint to its x,y; a curveto ··· 829 852 830 853 STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices); 831 854 // frees the data allocated above 855 + 856 + STBTT_DEF int stbtt_GetCodepointSVG(const stbtt_fontinfo *info, int unicode_codepoint, const char **svg); 857 + STBTT_DEF int stbtt_GetGlyphSVG(const stbtt_fontinfo *info, int gl, const char **svg); 858 + // fills svg with the character's SVG data. 859 + // returns data size or 0 if SVG not found. 832 860 833 861 ////////////////////////////////////////////////////////////////////////////// 834 862 // ··· 916 944 STBTT_DEF unsigned char * stbtt_GetCodepointSDF(const stbtt_fontinfo *info, float scale, int codepoint, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff); 917 945 // These functions compute a discretized SDF field for a single character, suitable for storing 918 946 // in a single-channel texture, sampling with bilinear filtering, and testing against 919 - // larger than some threshhold to produce scalable fonts. 947 + // larger than some threshold to produce scalable fonts. 920 948 // info -- the font 921 949 // scale -- controls the size of the resulting SDF bitmap, same as it would be creating a regular bitmap 922 950 // glyph/codepoint -- the character to generate the SDF for ··· 959 987 // and computing from that can allow drop-out prevention). 960 988 // 961 989 // The algorithm has not been optimized at all, so expect it to be slow 962 - // if computing lots of characters or very large sizes. 990 + // if computing lots of characters or very large sizes. 963 991 964 992 965 993 ··· 1331 1359 return stbtt__cff_get_index(&cff); 1332 1360 } 1333 1361 1362 + // since most people won't use this, find this table the first time it's needed 1363 + static int stbtt__get_svg(stbtt_fontinfo *info) 1364 + { 1365 + stbtt_uint32 t; 1366 + if (info->svg < 0) { 1367 + t = stbtt__find_table(info->data, info->fontstart, "SVG "); 1368 + if (t) { 1369 + stbtt_uint32 offset = ttULONG(info->data + t + 2); 1370 + info->svg = t + offset; 1371 + } else { 1372 + info->svg = 0; 1373 + } 1374 + } 1375 + return info->svg; 1376 + } 1377 + 1334 1378 static int stbtt_InitFont_internal(stbtt_fontinfo *info, unsigned char *data, int fontstart) 1335 1379 { 1336 1380 stbtt_uint32 cmap, t; ··· 1409 1453 info->numGlyphs = ttUSHORT(data+t+4); 1410 1454 else 1411 1455 info->numGlyphs = 0xffff; 1456 + 1457 + info->svg = -1; 1412 1458 1413 1459 // find a cmap encoding table we understand *now* to avoid searching 1414 1460 // later. (todo: could make this installable) ··· 1716 1762 if (i != 0) 1717 1763 num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy); 1718 1764 1719 - // now start the new one 1765 + // now start the new one 1720 1766 start_off = !(flags & 1); 1721 1767 if (start_off) { 1722 1768 // if we start off with an off-curve point, then when we need to find a point on the curve ··· 1758 1804 } 1759 1805 } 1760 1806 num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy); 1761 - } else if (numberOfContours == -1) { 1807 + } else if (numberOfContours < 0) { 1762 1808 // Compound shapes. 1763 1809 int more = 1; 1764 1810 stbtt_uint8 *comp = data + g + 10; ··· 1769 1815 int comp_num_verts = 0, i; 1770 1816 stbtt_vertex *comp_verts = 0, *tmp = 0; 1771 1817 float mtx[6] = {1,0,0,1,0,0}, m, n; 1772 - 1818 + 1773 1819 flags = ttSHORT(comp); comp+=2; 1774 1820 gidx = ttSHORT(comp); comp+=2; 1775 1821 ··· 1799 1845 mtx[2] = ttSHORT(comp)/16384.0f; comp+=2; 1800 1846 mtx[3] = ttSHORT(comp)/16384.0f; comp+=2; 1801 1847 } 1802 - 1848 + 1803 1849 // Find transformation scales. 1804 1850 m = (float) STBTT_sqrt(mtx[0]*mtx[0] + mtx[1]*mtx[1]); 1805 1851 n = (float) STBTT_sqrt(mtx[2]*mtx[2] + mtx[3]*mtx[3]); ··· 1835 1881 // More components ? 1836 1882 more = flags & (1<<5); 1837 1883 } 1838 - } else if (numberOfContours < 0) { 1839 - // @TODO other compound variations? 1840 - STBTT_assert(0); 1841 1884 } else { 1842 1885 // numberOfCounters == 0, do nothing 1843 1886 } ··· 2266 2309 } 2267 2310 } 2268 2311 2312 + STBTT_DEF int stbtt_GetKerningTableLength(const stbtt_fontinfo *info) 2313 + { 2314 + stbtt_uint8 *data = info->data + info->kern; 2315 + 2316 + // we only look at the first table. it must be 'horizontal' and format 0. 2317 + if (!info->kern) 2318 + return 0; 2319 + if (ttUSHORT(data+2) < 1) // number of tables, need at least 1 2320 + return 0; 2321 + if (ttUSHORT(data+8) != 1) // horizontal flag must be set in format 2322 + return 0; 2323 + 2324 + return ttUSHORT(data+10); 2325 + } 2326 + 2327 + STBTT_DEF int stbtt_GetKerningTable(const stbtt_fontinfo *info, stbtt_kerningentry* table, int table_length) 2328 + { 2329 + stbtt_uint8 *data = info->data + info->kern; 2330 + int k, length; 2331 + 2332 + // we only look at the first table. it must be 'horizontal' and format 0. 2333 + if (!info->kern) 2334 + return 0; 2335 + if (ttUSHORT(data+2) < 1) // number of tables, need at least 1 2336 + return 0; 2337 + if (ttUSHORT(data+8) != 1) // horizontal flag must be set in format 2338 + return 0; 2339 + 2340 + length = ttUSHORT(data+10); 2341 + if (table_length < length) 2342 + length = table_length; 2343 + 2344 + for (k = 0; k < length; k++) 2345 + { 2346 + table[k].glyph1 = ttUSHORT(data+18+(k*6)); 2347 + table[k].glyph2 = ttUSHORT(data+20+(k*6)); 2348 + table[k].advance = ttSHORT(data+22+(k*6)); 2349 + } 2350 + 2351 + return length; 2352 + } 2353 + 2269 2354 static int stbtt__GetGlyphKernInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2) 2270 2355 { 2271 2356 stbtt_uint8 *data = info->data + info->kern; ··· 2463 2548 if (valueFormat2 != 0) return 0; 2464 2549 2465 2550 STBTT_assert(coverageIndex < pairSetCount); 2551 + STBTT__NOTUSED(pairSetCount); 2466 2552 2467 2553 needle=glyph2; 2468 2554 r=pairValueCount-1; ··· 2540 2626 2541 2627 if (info->gpos) 2542 2628 xAdvance += stbtt__GetGlyphGPOSInfoAdvance(info, g1, g2); 2543 - 2544 - if (info->kern) 2629 + else if (info->kern) 2545 2630 xAdvance += stbtt__GetGlyphKernInfoAdvance(info, g1, g2); 2546 2631 2547 2632 return xAdvance; ··· 2602 2687 STBTT_free(v, info->userdata); 2603 2688 } 2604 2689 2690 + STBTT_DEF stbtt_uint8 *stbtt_FindSVGDoc(const stbtt_fontinfo *info, int gl) 2691 + { 2692 + int i; 2693 + stbtt_uint8 *data = info->data; 2694 + stbtt_uint8 *svg_doc_list = data + stbtt__get_svg((stbtt_fontinfo *) info); 2695 + 2696 + int numEntries = ttUSHORT(svg_doc_list); 2697 + stbtt_uint8 *svg_docs = svg_doc_list + 2; 2698 + 2699 + for(i=0; i<numEntries; i++) { 2700 + stbtt_uint8 *svg_doc = svg_docs + (12 * i); 2701 + if ((gl >= ttUSHORT(svg_doc)) && (gl <= ttUSHORT(svg_doc + 2))) 2702 + return svg_doc; 2703 + } 2704 + return 0; 2705 + } 2706 + 2707 + STBTT_DEF int stbtt_GetGlyphSVG(const stbtt_fontinfo *info, int gl, const char **svg) 2708 + { 2709 + stbtt_uint8 *data = info->data; 2710 + stbtt_uint8 *svg_doc; 2711 + 2712 + if (info->svg == 0) 2713 + return 0; 2714 + 2715 + svg_doc = stbtt_FindSVGDoc(info, gl); 2716 + if (svg_doc != NULL) { 2717 + *svg = (char *) data + info->svg + ttULONG(svg_doc + 4); 2718 + return ttULONG(svg_doc + 8); 2719 + } else { 2720 + return 0; 2721 + } 2722 + } 2723 + 2724 + STBTT_DEF int stbtt_GetCodepointSVG(const stbtt_fontinfo *info, int unicode_codepoint, const char **svg) 2725 + { 2726 + return stbtt_GetGlyphSVG(info, stbtt_FindGlyphIndex(info, unicode_codepoint), svg); 2727 + } 2728 + 2605 2729 ////////////////////////////////////////////////////////////////////////////// 2606 2730 // 2607 2731 // antialiasing software rasterizer ··· 2727 2851 float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); 2728 2852 STBTT_assert(z != NULL); 2729 2853 if (!z) return z; 2730 - 2854 + 2731 2855 // round dx down to avoid overshooting 2732 2856 if (dxdy < 0) 2733 2857 z->dx = -STBTT_ifloor(STBTT_FIX * -dxdy); ··· 2805 2929 } 2806 2930 } 2807 2931 } 2808 - 2932 + 2809 2933 e = e->next; 2810 2934 } 2811 2935 } ··· 3160 3284 if (e->y0 != e->y1) { 3161 3285 stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata); 3162 3286 if (z != NULL) { 3163 - STBTT_assert(z->ey >= scan_y_top); 3287 + if (j == 0 && off_y != 0) { 3288 + if (z->ey < scan_y_top) { 3289 + // this can happen due to subpixel positioning and some kind of fp rounding error i think 3290 + z->ey = scan_y_top; 3291 + } 3292 + } 3293 + STBTT_assert(z->ey >= scan_y_top); // if we get really unlucky a tiny bit of an edge can be out of bounds 3164 3294 // insert at front 3165 3295 z->next = active; 3166 3296 active = z; ··· 3229 3359 3230 3360 static void stbtt__sort_edges_quicksort(stbtt__edge *p, int n) 3231 3361 { 3232 - /* threshhold for transitioning to insertion sort */ 3362 + /* threshold for transitioning to insertion sort */ 3233 3363 while (n > 12) { 3234 3364 stbtt__edge t; 3235 3365 int c01,c12,c,m,i,j; ··· 3364 3494 points[n].y = y; 3365 3495 } 3366 3496 3367 - // tesselate until threshhold p is happy... @TODO warped to compensate for non-linear stretching 3497 + // tessellate until threshold p is happy... @TODO warped to compensate for non-linear stretching 3368 3498 static int stbtt__tesselate_curve(stbtt__point *points, int *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float objspace_flatness_squared, int n) 3369 3499 { 3370 3500 // midpoint ··· 3527 3657 { 3528 3658 int ix0,iy0,ix1,iy1; 3529 3659 stbtt__bitmap gbm; 3530 - stbtt_vertex *vertices; 3660 + stbtt_vertex *vertices; 3531 3661 int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices); 3532 3662 3533 3663 if (scale_x == 0) scale_x = scale_y; ··· 3550 3680 if (height) *height = gbm.h; 3551 3681 if (xoff ) *xoff = ix0; 3552 3682 if (yoff ) *yoff = iy0; 3553 - 3683 + 3554 3684 if (gbm.w && gbm.h) { 3555 3685 gbm.pixels = (unsigned char *) STBTT_malloc(gbm.w * gbm.h, info->userdata); 3556 3686 if (gbm.pixels) { ··· 3561 3691 } 3562 3692 STBTT_free(vertices, info->userdata); 3563 3693 return gbm.pixels; 3564 - } 3694 + } 3565 3695 3566 3696 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) 3567 3697 { ··· 3573 3703 int ix0,iy0; 3574 3704 stbtt_vertex *vertices; 3575 3705 int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices); 3576 - stbtt__bitmap gbm; 3706 + stbtt__bitmap gbm; 3577 3707 3578 3708 stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,0,0); 3579 3709 gbm.pixels = output; ··· 3595 3725 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) 3596 3726 { 3597 3727 return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y,shift_x,shift_y, stbtt_FindGlyphIndex(info,codepoint), width,height,xoff,yoff); 3598 - } 3728 + } 3599 3729 3600 3730 STBTT_DEF void stbtt_MakeCodepointBitmapSubpixelPrefilter(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int oversample_x, int oversample_y, float *sub_x, float *sub_y, int codepoint) 3601 3731 { ··· 3610 3740 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) 3611 3741 { 3612 3742 return stbtt_GetCodepointBitmapSubpixel(info, scale_x, scale_y, 0.0f,0.0f, codepoint, width,height,xoff,yoff); 3613 - } 3743 + } 3614 3744 3615 3745 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) 3616 3746 { ··· 3735 3865 con->y = 0; 3736 3866 con->bottom_y = 0; 3737 3867 STBTT__NOTUSED(nodes); 3738 - STBTT__NOTUSED(num_nodes); 3868 + STBTT__NOTUSED(num_nodes); 3739 3869 } 3740 3870 3741 3871 static void stbrp_pack_rects(stbrp_context *con, stbrp_rect *rects, int num_rects) ··· 3789 3919 spc->stride_in_bytes = stride_in_bytes != 0 ? stride_in_bytes : pw; 3790 3920 spc->h_oversample = 1; 3791 3921 spc->v_oversample = 1; 3922 + spc->skip_missing = 0; 3792 3923 3793 3924 stbrp_init_target(context, pw-padding, ph-padding, nodes, num_nodes); 3794 3925 ··· 3814 3945 spc->v_oversample = v_oversample; 3815 3946 } 3816 3947 3948 + STBTT_DEF void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context *spc, int skip) 3949 + { 3950 + spc->skip_missing = skip; 3951 + } 3952 + 3817 3953 #define STBTT__OVER_MASK (STBTT_MAX_OVERSAMPLE-1) 3818 3954 3819 3955 static void stbtt__h_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width) ··· 3956 4092 STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects) 3957 4093 { 3958 4094 int i,j,k; 4095 + int missing_glyph_added = 0; 3959 4096 3960 4097 k=0; 3961 4098 for (i=0; i < num_ranges; ++i) { ··· 3967 4104 int x0,y0,x1,y1; 3968 4105 int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j]; 3969 4106 int glyph = stbtt_FindGlyphIndex(info, codepoint); 3970 - stbtt_GetGlyphBitmapBoxSubpixel(info,glyph, 3971 - scale * spc->h_oversample, 3972 - scale * spc->v_oversample, 3973 - 0,0, 3974 - &x0,&y0,&x1,&y1); 3975 - rects[k].w = (stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1); 3976 - rects[k].h = (stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1); 4107 + if (glyph == 0 && (spc->skip_missing || missing_glyph_added)) { 4108 + rects[k].w = rects[k].h = 0; 4109 + } else { 4110 + stbtt_GetGlyphBitmapBoxSubpixel(info,glyph, 4111 + scale * spc->h_oversample, 4112 + scale * spc->v_oversample, 4113 + 0,0, 4114 + &x0,&y0,&x1,&y1); 4115 + rects[k].w = (stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1); 4116 + rects[k].h = (stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1); 4117 + if (glyph == 0) 4118 + missing_glyph_added = 1; 4119 + } 3977 4120 ++k; 3978 4121 } 3979 4122 } ··· 4007 4150 // rects array must be big enough to accommodate all characters in the given ranges 4008 4151 STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects) 4009 4152 { 4010 - int i,j,k, return_value = 1; 4153 + int i,j,k, missing_glyph = -1, return_value = 1; 4011 4154 4012 4155 // save current values 4013 4156 int old_h_over = spc->h_oversample; ··· 4026 4169 sub_y = stbtt__oversample_shift(spc->v_oversample); 4027 4170 for (j=0; j < ranges[i].num_chars; ++j) { 4028 4171 stbrp_rect *r = &rects[k]; 4029 - if (r->was_packed) { 4172 + if (r->was_packed && r->w != 0 && r->h != 0) { 4030 4173 stbtt_packedchar *bc = &ranges[i].chardata_for_range[j]; 4031 4174 int advance, lsb, x0,y0,x1,y1; 4032 4175 int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j]; ··· 4072 4215 bc->yoff = (float) y0 * recip_v + sub_y; 4073 4216 bc->xoff2 = (x0 + r->w) * recip_h + sub_x; 4074 4217 bc->yoff2 = (y0 + r->h) * recip_v + sub_y; 4218 + 4219 + if (glyph == 0) 4220 + missing_glyph = j; 4221 + } else if (spc->skip_missing) { 4222 + return_value = 0; 4223 + } else if (r->was_packed && r->w == 0 && r->h == 0 && missing_glyph >= 0) { 4224 + ranges[i].chardata_for_range[j] = ranges[i].chardata_for_range[missing_glyph]; 4075 4225 } else { 4076 4226 return_value = 0; // if any fail, report failure 4077 4227 } ··· 4110 4260 n = 0; 4111 4261 for (i=0; i < num_ranges; ++i) 4112 4262 n += ranges[i].num_chars; 4113 - 4263 + 4114 4264 rects = (stbrp_rect *) STBTT_malloc(sizeof(*rects) * n, spc->user_allocator_context); 4115 4265 if (rects == NULL) 4116 4266 return 0; ··· 4121 4271 n = stbtt_PackFontRangesGatherRects(spc, &info, ranges, num_ranges, rects); 4122 4272 4123 4273 stbtt_PackFontRangesPackRects(spc, rects, n); 4124 - 4274 + 4125 4275 return_value = stbtt_PackFontRangesRenderIntoRects(spc, &info, ranges, num_ranges, rects); 4126 4276 4127 4277 STBTT_free(rects, spc->user_allocator_context); ··· 4138 4288 range.chardata_for_range = chardata_for_range; 4139 4289 range.font_size = font_size; 4140 4290 return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1); 4291 + } 4292 + 4293 + STBTT_DEF void stbtt_GetScaledFontVMetrics(const unsigned char *fontdata, int index, float size, float *ascent, float *descent, float *lineGap) 4294 + { 4295 + int i_ascent, i_descent, i_lineGap; 4296 + float scale; 4297 + stbtt_fontinfo info; 4298 + stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata, index)); 4299 + scale = size > 0 ? stbtt_ScaleForPixelHeight(&info, size) : stbtt_ScaleForMappingEmToPixels(&info, -size); 4300 + stbtt_GetFontVMetrics(&info, &i_ascent, &i_descent, &i_lineGap); 4301 + *ascent = (float) i_ascent * scale; 4302 + *descent = (float) i_descent * scale; 4303 + *lineGap = (float) i_lineGap * scale; 4141 4304 } 4142 4305 4143 4306 STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int align_to_integer) ··· 4269 4432 int x1 = (int) verts[i ].x, y1 = (int) verts[i ].y; 4270 4433 if (y > STBTT_min(y0,y1) && y < STBTT_max(y0,y1) && x > STBTT_min(x0,x1)) { 4271 4434 float x_inter = (y - y0) / (y1 - y0) * (x1-x0) + x0; 4272 - if (x_inter < x) 4435 + if (x_inter < x) 4273 4436 winding += (y0 < y1) ? 1 : -1; 4274 4437 } 4275 4438 } ··· 4295 4458 y1 = (int)verts[i ].y; 4296 4459 if (y > STBTT_min(y0,y1) && y < STBTT_max(y0,y1) && x > STBTT_min(x0,x1)) { 4297 4460 float x_inter = (y - y0) / (y1 - y0) * (x1-x0) + x0; 4298 - if (x_inter < x) 4461 + if (x_inter < x) 4299 4462 winding += (y0 < y1) ? 1 : -1; 4300 4463 } 4301 4464 } else { ··· 4307 4470 if (hits[1][0] < 0) 4308 4471 winding += (hits[1][1] < 0 ? -1 : 1); 4309 4472 } 4310 - } 4473 + } 4311 4474 } 4312 4475 } 4313 4476 return winding; ··· 4360 4523 int w,h; 4361 4524 unsigned char *data; 4362 4525 4363 - // if one scale is 0, use same scale for both 4364 - if (scale_x == 0) scale_x = scale_y; 4365 - if (scale_y == 0) { 4366 - if (scale_x == 0) return NULL; // if both scales are 0, return NULL 4367 - scale_y = scale_x; 4368 - } 4526 + if (scale == 0) return NULL; 4369 4527 4370 4528 stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale, scale, 0.0f,0.0f, &ix0,&iy0,&ix1,&iy1); 4371 4529 ··· 4388 4546 4389 4547 // invert for y-downwards bitmaps 4390 4548 scale_y = -scale_y; 4391 - 4549 + 4392 4550 { 4393 4551 int x,y,i,j; 4394 4552 float *precompute; ··· 4537 4695 STBTT_free(verts, info->userdata); 4538 4696 } 4539 4697 return data; 4540 - } 4698 + } 4541 4699 4542 4700 STBTT_DEF unsigned char * stbtt_GetCodepointSDF(const stbtt_fontinfo *info, float scale, int codepoint, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff) 4543 4701 { ··· 4555 4713 // 4556 4714 4557 4715 // check if a utf8 string contains a prefix which is the utf16 string; if so return length of matching utf8 string 4558 - static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(stbtt_uint8 *s1, stbtt_int32 len1, stbtt_uint8 *s2, stbtt_int32 len2) 4716 + static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(stbtt_uint8 *s1, stbtt_int32 len1, stbtt_uint8 *s2, stbtt_int32 len2) 4559 4717 { 4560 4718 stbtt_int32 i=0; 4561 4719 ··· 4594 4752 return i; 4595 4753 } 4596 4754 4597 - static int stbtt_CompareUTF8toUTF16_bigendian_internal(char *s1, int len1, char *s2, int len2) 4755 + static int stbtt_CompareUTF8toUTF16_bigendian_internal(char *s1, int len1, char *s2, int len2) 4598 4756 { 4599 4757 return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((stbtt_uint8*) s1, len1, (stbtt_uint8*) s2, len2); 4600 4758 } ··· 4723 4881 4724 4882 STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index) 4725 4883 { 4726 - return stbtt_GetFontOffsetForIndex_internal((unsigned char *) data, index); 4884 + return stbtt_GetFontOffsetForIndex_internal((unsigned char *) data, index); 4727 4885 } 4728 4886 4729 4887 STBTT_DEF int stbtt_GetNumberOfFonts(const unsigned char *data) ··· 4816 4974 ------------------------------------------------------------------------------ 4817 4975 ALTERNATIVE A - MIT License 4818 4976 Copyright (c) 2017 Sean Barrett 4819 - Permission is hereby granted, free of charge, to any person obtaining a copy of 4820 - this software and associated documentation files (the "Software"), to deal in 4821 - the Software without restriction, including without limitation the rights to 4822 - use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 4823 - of the Software, and to permit persons to whom the Software is furnished to do 4977 + Permission is hereby granted, free of charge, to any person obtaining a copy of 4978 + this software and associated documentation files (the "Software"), to deal in 4979 + the Software without restriction, including without limitation the rights to 4980 + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 4981 + of the Software, and to permit persons to whom the Software is furnished to do 4824 4982 so, subject to the following conditions: 4825 - The above copyright notice and this permission notice shall be included in all 4983 + The above copyright notice and this permission notice shall be included in all 4826 4984 copies or substantial portions of the Software. 4827 - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4828 - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 4829 - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 4830 - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 4831 - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 4832 - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 4985 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4986 + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 4987 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 4988 + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 4989 + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 4990 + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 4833 4991 SOFTWARE. 4834 4992 ------------------------------------------------------------------------------ 4835 4993 ALTERNATIVE B - Public Domain (www.unlicense.org) 4836 4994 This is free and unencumbered software released into the public domain. 4837 - Anyone is free to copy, modify, publish, use, compile, sell, or distribute this 4838 - software, either in source code form or as a compiled binary, for any purpose, 4995 + Anyone is free to copy, modify, publish, use, compile, sell, or distribute this 4996 + software, either in source code form or as a compiled binary, for any purpose, 4839 4997 commercial or non-commercial, and by any means. 4840 - In jurisdictions that recognize copyright laws, the author or authors of this 4841 - software dedicate any and all copyright interest in the software to the public 4842 - domain. We make this dedication for the benefit of the public at large and to 4843 - the detriment of our heirs and successors. We intend this dedication to be an 4844 - overt act of relinquishment in perpetuity of all present and future rights to 4998 + In jurisdictions that recognize copyright laws, the author or authors of this 4999 + software dedicate any and all copyright interest in the software to the public 5000 + domain. We make this dedication for the benefit of the public at large and to 5001 + the detriment of our heirs and successors. We intend this dedication to be an 5002 + overt act of relinquishment in perpetuity of all present and future rights to 4845 5003 this software under copyright law. 4846 - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4847 - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 4848 - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 4849 - AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 4850 - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 5004 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 5005 + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5006 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 5007 + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 5008 + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 4851 5009 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 4852 5010 ------------------------------------------------------------------------------ 4853 5011 */