Customized fork of github.com/rxi/lite

Merge pull request #233 from takase1121/update_stb

update stb_truetype

authored by rxi and committed by GitHub 38bd9b33 806f0e39

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 3 // 4 // This library processes TrueType files: 5 // parse files ··· 32 // Daniel Ribeiro Maciel 33 // 34 // 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 40 // David Gow Peter LaValle 41 // David Given Sergey Popov 42 // Ivan-Assen Ivanov Giumo X. Clanjor ··· 44 // Johan Duparc Thomas Fields 45 // Hou Qiming Derek Vinyard 46 // Rob Loach Cort Stratton 47 - // Kenney Phillis Jr. github:oyvindjam 48 - // Brian Costabile github:vassvik 49 - // 50 // VERSION HISTORY 51 // 52 // 1.19 (2018-02-11) GPOS kerning, STBTT_fmod 53 // 1.18 (2018-01-29) add missing function 54 // 1.17 (2017-07-23) make more arguments const; doc fix ··· 75 // 76 // USAGE 77 // 78 - // Include this file in whatever places neeed to refer to it. In ONE C/C++ 79 // file, write: 80 // #define STB_TRUETYPE_IMPLEMENTATION 81 // before the #include of this file. This expands out the actual ··· 206 // 207 // Advancing for the next character: 208 // Call GlyphHMetrics, and compute 'current_point += SF * advance'. 209 - // 210 // 211 // ADVANCED USAGE 212 // ··· 242 // recommend it. 243 // 244 // 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 // PERFORMANCE MEASUREMENTS FOR 1.06: 259 // 260 // 32-bit 64-bit ··· 344 } 345 return 0; 346 } 347 - #endif 348 // 349 // Output: 350 // ··· 358 // :@@. M@M 359 // @@@o@@@@ 360 // :M@@V:@@. 361 - // 362 ////////////////////////////////////////////////////////////////////////////// 363 - // 364 // Complete program: print "Hello World!" banner, with bugs 365 // 366 #if 0 ··· 556 // 557 // It's inefficient; you might want to c&p it and optimize it. 558 559 560 561 ////////////////////////////////////////////////////////////////////////////// ··· 641 // To use with PackFontRangesGather etc., you must set it before calls 642 // call to PackFontRangesGatherRects. 643 644 STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, // same data as above 645 int char_index, // character to display 646 float *xpos, float *ypos, // pointers to current position in screen pixel space ··· 653 // Calling these functions in sequence is roughly equivalent to calling 654 // stbtt_PackFontRanges(). If you more control over the packing of multiple 655 // 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 657 // using these functions, e.g. call GatherRects multiple times, 658 // building up a single array of rects, then call PackRects once, 659 // then call RenderIntoRects repeatedly. This may result in a ··· 669 int height; 670 int stride_in_bytes; 671 int padding; 672 unsigned int h_oversample, v_oversample; 673 unsigned char *pixels; 674 void *nodes; ··· 694 // file will only define one font and it always be at offset 0, so it will 695 // return '0' for index 0, and -1 for all other indices. 696 697 - // The following structure is defined publically so you can declare one on 698 // the stack or as a global or etc, but you should treat it as opaque. 699 struct stbtt_fontinfo 700 { ··· 704 705 int numGlyphs; // number of glyphs, needed for range checking 706 707 - int loca,head,glyf,hhea,hmtx,kern,gpos; // table locations as offset from start of .ttf 708 int index_map; // a cmap mapping for our chosen character encoding 709 int indexToLocFormat; // format needed to map from glyph index to glyph 710 ··· 733 // and you want a speed-up, call this function with the character you're 734 // going to process, then use glyph-based functions instead of the 735 // codepoint-based functions. 736 737 738 ////////////////////////////////////////////////////////////////////////////// ··· 786 STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1); 787 // as above, but takes one or more glyph indices for greater efficiency 788 789 790 ////////////////////////////////////////////////////////////////////////////// 791 // ··· 820 // returns # of vertices and fills *vertices with the pointer to them 821 // these are expressed in "unscaled" coordinates 822 // 823 - // The shape is a series of countours. Each one starts with 824 // a STBTT_moveto, then consists of a series of mixed 825 // STBTT_lineto and STBTT_curveto segments. A lineto 826 // draws a line from previous endpoint to its x,y; a curveto ··· 829 830 STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices); 831 // frees the data allocated above 832 833 ////////////////////////////////////////////////////////////////////////////// 834 // ··· 916 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 // These functions compute a discretized SDF field for a single character, suitable for storing 918 // in a single-channel texture, sampling with bilinear filtering, and testing against 919 - // larger than some threshhold to produce scalable fonts. 920 // info -- the font 921 // scale -- controls the size of the resulting SDF bitmap, same as it would be creating a regular bitmap 922 // glyph/codepoint -- the character to generate the SDF for ··· 959 // and computing from that can allow drop-out prevention). 960 // 961 // The algorithm has not been optimized at all, so expect it to be slow 962 - // if computing lots of characters or very large sizes. 963 964 965 ··· 1331 return stbtt__cff_get_index(&cff); 1332 } 1333 1334 static int stbtt_InitFont_internal(stbtt_fontinfo *info, unsigned char *data, int fontstart) 1335 { 1336 stbtt_uint32 cmap, t; ··· 1409 info->numGlyphs = ttUSHORT(data+t+4); 1410 else 1411 info->numGlyphs = 0xffff; 1412 1413 // find a cmap encoding table we understand *now* to avoid searching 1414 // later. (todo: could make this installable) ··· 1716 if (i != 0) 1717 num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy); 1718 1719 - // now start the new one 1720 start_off = !(flags & 1); 1721 if (start_off) { 1722 // if we start off with an off-curve point, then when we need to find a point on the curve ··· 1758 } 1759 } 1760 num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy); 1761 - } else if (numberOfContours == -1) { 1762 // Compound shapes. 1763 int more = 1; 1764 stbtt_uint8 *comp = data + g + 10; ··· 1769 int comp_num_verts = 0, i; 1770 stbtt_vertex *comp_verts = 0, *tmp = 0; 1771 float mtx[6] = {1,0,0,1,0,0}, m, n; 1772 - 1773 flags = ttSHORT(comp); comp+=2; 1774 gidx = ttSHORT(comp); comp+=2; 1775 ··· 1799 mtx[2] = ttSHORT(comp)/16384.0f; comp+=2; 1800 mtx[3] = ttSHORT(comp)/16384.0f; comp+=2; 1801 } 1802 - 1803 // Find transformation scales. 1804 m = (float) STBTT_sqrt(mtx[0]*mtx[0] + mtx[1]*mtx[1]); 1805 n = (float) STBTT_sqrt(mtx[2]*mtx[2] + mtx[3]*mtx[3]); ··· 1835 // More components ? 1836 more = flags & (1<<5); 1837 } 1838 - } else if (numberOfContours < 0) { 1839 - // @TODO other compound variations? 1840 - STBTT_assert(0); 1841 } else { 1842 // numberOfCounters == 0, do nothing 1843 } ··· 2266 } 2267 } 2268 2269 static int stbtt__GetGlyphKernInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2) 2270 { 2271 stbtt_uint8 *data = info->data + info->kern; ··· 2463 if (valueFormat2 != 0) return 0; 2464 2465 STBTT_assert(coverageIndex < pairSetCount); 2466 2467 needle=glyph2; 2468 r=pairValueCount-1; ··· 2540 2541 if (info->gpos) 2542 xAdvance += stbtt__GetGlyphGPOSInfoAdvance(info, g1, g2); 2543 - 2544 - if (info->kern) 2545 xAdvance += stbtt__GetGlyphKernInfoAdvance(info, g1, g2); 2546 2547 return xAdvance; ··· 2602 STBTT_free(v, info->userdata); 2603 } 2604 2605 ////////////////////////////////////////////////////////////////////////////// 2606 // 2607 // antialiasing software rasterizer ··· 2727 float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); 2728 STBTT_assert(z != NULL); 2729 if (!z) return z; 2730 - 2731 // round dx down to avoid overshooting 2732 if (dxdy < 0) 2733 z->dx = -STBTT_ifloor(STBTT_FIX * -dxdy); ··· 2805 } 2806 } 2807 } 2808 - 2809 e = e->next; 2810 } 2811 } ··· 3160 if (e->y0 != e->y1) { 3161 stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata); 3162 if (z != NULL) { 3163 - STBTT_assert(z->ey >= scan_y_top); 3164 // insert at front 3165 z->next = active; 3166 active = z; ··· 3229 3230 static void stbtt__sort_edges_quicksort(stbtt__edge *p, int n) 3231 { 3232 - /* threshhold for transitioning to insertion sort */ 3233 while (n > 12) { 3234 stbtt__edge t; 3235 int c01,c12,c,m,i,j; ··· 3364 points[n].y = y; 3365 } 3366 3367 - // tesselate until threshhold p is happy... @TODO warped to compensate for non-linear stretching 3368 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 { 3370 // midpoint ··· 3527 { 3528 int ix0,iy0,ix1,iy1; 3529 stbtt__bitmap gbm; 3530 - stbtt_vertex *vertices; 3531 int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices); 3532 3533 if (scale_x == 0) scale_x = scale_y; ··· 3550 if (height) *height = gbm.h; 3551 if (xoff ) *xoff = ix0; 3552 if (yoff ) *yoff = iy0; 3553 - 3554 if (gbm.w && gbm.h) { 3555 gbm.pixels = (unsigned char *) STBTT_malloc(gbm.w * gbm.h, info->userdata); 3556 if (gbm.pixels) { ··· 3561 } 3562 STBTT_free(vertices, info->userdata); 3563 return gbm.pixels; 3564 - } 3565 3566 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 { ··· 3573 int ix0,iy0; 3574 stbtt_vertex *vertices; 3575 int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices); 3576 - stbtt__bitmap gbm; 3577 3578 stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,0,0); 3579 gbm.pixels = output; ··· 3595 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 { 3597 return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y,shift_x,shift_y, stbtt_FindGlyphIndex(info,codepoint), width,height,xoff,yoff); 3598 - } 3599 3600 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 { ··· 3610 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 { 3612 return stbtt_GetCodepointBitmapSubpixel(info, scale_x, scale_y, 0.0f,0.0f, codepoint, width,height,xoff,yoff); 3613 - } 3614 3615 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 { ··· 3735 con->y = 0; 3736 con->bottom_y = 0; 3737 STBTT__NOTUSED(nodes); 3738 - STBTT__NOTUSED(num_nodes); 3739 } 3740 3741 static void stbrp_pack_rects(stbrp_context *con, stbrp_rect *rects, int num_rects) ··· 3789 spc->stride_in_bytes = stride_in_bytes != 0 ? stride_in_bytes : pw; 3790 spc->h_oversample = 1; 3791 spc->v_oversample = 1; 3792 3793 stbrp_init_target(context, pw-padding, ph-padding, nodes, num_nodes); 3794 ··· 3814 spc->v_oversample = v_oversample; 3815 } 3816 3817 #define STBTT__OVER_MASK (STBTT_MAX_OVERSAMPLE-1) 3818 3819 static void stbtt__h_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width) ··· 3956 STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects) 3957 { 3958 int i,j,k; 3959 3960 k=0; 3961 for (i=0; i < num_ranges; ++i) { ··· 3967 int x0,y0,x1,y1; 3968 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 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); 3977 ++k; 3978 } 3979 } ··· 4007 // rects array must be big enough to accommodate all characters in the given ranges 4008 STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects) 4009 { 4010 - int i,j,k, return_value = 1; 4011 4012 // save current values 4013 int old_h_over = spc->h_oversample; ··· 4026 sub_y = stbtt__oversample_shift(spc->v_oversample); 4027 for (j=0; j < ranges[i].num_chars; ++j) { 4028 stbrp_rect *r = &rects[k]; 4029 - if (r->was_packed) { 4030 stbtt_packedchar *bc = &ranges[i].chardata_for_range[j]; 4031 int advance, lsb, x0,y0,x1,y1; 4032 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 bc->yoff = (float) y0 * recip_v + sub_y; 4073 bc->xoff2 = (x0 + r->w) * recip_h + sub_x; 4074 bc->yoff2 = (y0 + r->h) * recip_v + sub_y; 4075 } else { 4076 return_value = 0; // if any fail, report failure 4077 } ··· 4110 n = 0; 4111 for (i=0; i < num_ranges; ++i) 4112 n += ranges[i].num_chars; 4113 - 4114 rects = (stbrp_rect *) STBTT_malloc(sizeof(*rects) * n, spc->user_allocator_context); 4115 if (rects == NULL) 4116 return 0; ··· 4121 n = stbtt_PackFontRangesGatherRects(spc, &info, ranges, num_ranges, rects); 4122 4123 stbtt_PackFontRangesPackRects(spc, rects, n); 4124 - 4125 return_value = stbtt_PackFontRangesRenderIntoRects(spc, &info, ranges, num_ranges, rects); 4126 4127 STBTT_free(rects, spc->user_allocator_context); ··· 4138 range.chardata_for_range = chardata_for_range; 4139 range.font_size = font_size; 4140 return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1); 4141 } 4142 4143 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 int x1 = (int) verts[i ].x, y1 = (int) verts[i ].y; 4270 if (y > STBTT_min(y0,y1) && y < STBTT_max(y0,y1) && x > STBTT_min(x0,x1)) { 4271 float x_inter = (y - y0) / (y1 - y0) * (x1-x0) + x0; 4272 - if (x_inter < x) 4273 winding += (y0 < y1) ? 1 : -1; 4274 } 4275 } ··· 4295 y1 = (int)verts[i ].y; 4296 if (y > STBTT_min(y0,y1) && y < STBTT_max(y0,y1) && x > STBTT_min(x0,x1)) { 4297 float x_inter = (y - y0) / (y1 - y0) * (x1-x0) + x0; 4298 - if (x_inter < x) 4299 winding += (y0 < y1) ? 1 : -1; 4300 } 4301 } else { ··· 4307 if (hits[1][0] < 0) 4308 winding += (hits[1][1] < 0 ? -1 : 1); 4309 } 4310 - } 4311 } 4312 } 4313 return winding; ··· 4360 int w,h; 4361 unsigned char *data; 4362 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 - } 4369 4370 stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale, scale, 0.0f,0.0f, &ix0,&iy0,&ix1,&iy1); 4371 ··· 4388 4389 // invert for y-downwards bitmaps 4390 scale_y = -scale_y; 4391 - 4392 { 4393 int x,y,i,j; 4394 float *precompute; ··· 4537 STBTT_free(verts, info->userdata); 4538 } 4539 return data; 4540 - } 4541 4542 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 { ··· 4555 // 4556 4557 // 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) 4559 { 4560 stbtt_int32 i=0; 4561 ··· 4594 return i; 4595 } 4596 4597 - static int stbtt_CompareUTF8toUTF16_bigendian_internal(char *s1, int len1, char *s2, int len2) 4598 { 4599 return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((stbtt_uint8*) s1, len1, (stbtt_uint8*) s2, len2); 4600 } ··· 4723 4724 STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index) 4725 { 4726 - return stbtt_GetFontOffsetForIndex_internal((unsigned char *) data, index); 4727 } 4728 4729 STBTT_DEF int stbtt_GetNumberOfFonts(const unsigned char *data) ··· 4816 ------------------------------------------------------------------------------ 4817 ALTERNATIVE A - MIT License 4818 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 4824 so, subject to the following conditions: 4825 - The above copyright notice and this permission notice shall be included in all 4826 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 4833 SOFTWARE. 4834 ------------------------------------------------------------------------------ 4835 ALTERNATIVE B - Public Domain (www.unlicense.org) 4836 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, 4839 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 4845 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 4851 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 4852 ------------------------------------------------------------------------------ 4853 */
··· 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 + // ======================================================================= 12 // 13 // This library processes TrueType files: 14 // parse files ··· 41 // Daniel Ribeiro Maciel 42 // 43 // Bug/warning reports/fixes: 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 49 // David Gow Peter LaValle 50 // David Given Sergey Popov 51 // Ivan-Assen Ivanov Giumo X. Clanjor ··· 53 // Johan Duparc Thomas Fields 54 // Hou Qiming Derek Vinyard 55 // Rob Loach Cort Stratton 56 + // Kenney Phillis Jr. Brian Costabile 57 + // Ken Voskuil (kaesve) 58 + // 59 // VERSION HISTORY 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() 66 // 1.19 (2018-02-11) GPOS kerning, STBTT_fmod 67 // 1.18 (2018-01-29) add missing function 68 // 1.17 (2017-07-23) make more arguments const; doc fix ··· 89 // 90 // USAGE 91 // 92 + // Include this file in whatever places need 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 ··· 220 // 221 // Advancing for the next character: 222 // Call GlyphHMetrics, and compute 'current_point += SF * advance'. 223 + // 224 // 225 // ADVANCED USAGE 226 // ··· 256 // recommend it. 257 // 258 // 259 // PERFORMANCE MEASUREMENTS FOR 1.06: 260 // 261 // 32-bit 64-bit ··· 345 } 346 return 0; 347 } 348 + #endif 349 // 350 // Output: 351 // ··· 359 // :@@. M@M 360 // @@@o@@@@ 361 // :M@@V:@@. 362 + // 363 ////////////////////////////////////////////////////////////////////////////// 364 + // 365 // Complete program: print "Hello World!" banner, with bugs 366 // 367 #if 0 ··· 557 // 558 // It's inefficient; you might want to c&p it and optimize it. 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. 562 563 564 ////////////////////////////////////////////////////////////////////////////// ··· 644 // To use with PackFontRangesGather etc., you must set it before calls 645 // call to PackFontRangesGatherRects. 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 + 653 STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, // same data as above 654 int char_index, // character to display 655 float *xpos, float *ypos, // pointers to current position in screen pixel space ··· 662 // Calling these functions in sequence is roughly equivalent to calling 663 // stbtt_PackFontRanges(). If you more control over the packing of multiple 664 // fonts, or if you want to pack custom data into a font texture, take a look 665 + // at the source to of stbtt_PackFontRanges() and create a custom version 666 // using these functions, e.g. call GatherRects multiple times, 667 // building up a single array of rects, then call PackRects once, 668 // then call RenderIntoRects repeatedly. This may result in a ··· 678 int height; 679 int stride_in_bytes; 680 int padding; 681 + int skip_missing; 682 unsigned int h_oversample, v_oversample; 683 unsigned char *pixels; 684 void *nodes; ··· 704 // file will only define one font and it always be at offset 0, so it will 705 // return '0' for index 0, and -1 for all other indices. 706 707 + // The following structure is defined publicly so you can declare one on 708 // the stack or as a global or etc, but you should treat it as opaque. 709 struct stbtt_fontinfo 710 { ··· 714 715 int numGlyphs; // number of glyphs, needed for range checking 716 717 + int loca,head,glyf,hhea,hmtx,kern,gpos,svg; // table locations as offset from start of .ttf 718 int index_map; // a cmap mapping for our chosen character encoding 719 int indexToLocFormat; // format needed to map from glyph index to glyph 720 ··· 743 // and you want a speed-up, call this function with the character you're 744 // going to process, then use glyph-based functions instead of the 745 // codepoint-based functions. 746 + // Returns 0 if the character codepoint is not defined in the font. 747 748 749 ////////////////////////////////////////////////////////////////////////////// ··· 797 STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1); 798 // as above, but takes one or more glyph indices for greater efficiency 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) 812 813 ////////////////////////////////////////////////////////////////////////////// 814 // ··· 843 // returns # of vertices and fills *vertices with the pointer to them 844 // these are expressed in "unscaled" coordinates 845 // 846 + // The shape is a series of contours. Each one starts with 847 // a STBTT_moveto, then consists of a series of mixed 848 // STBTT_lineto and STBTT_curveto segments. A lineto 849 // draws a line from previous endpoint to its x,y; a curveto ··· 852 853 STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices); 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. 860 861 ////////////////////////////////////////////////////////////////////////////// 862 // ··· 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); 945 // These functions compute a discretized SDF field for a single character, suitable for storing 946 // in a single-channel texture, sampling with bilinear filtering, and testing against 947 + // larger than some threshold to produce scalable fonts. 948 // info -- the font 949 // scale -- controls the size of the resulting SDF bitmap, same as it would be creating a regular bitmap 950 // glyph/codepoint -- the character to generate the SDF for ··· 987 // and computing from that can allow drop-out prevention). 988 // 989 // The algorithm has not been optimized at all, so expect it to be slow 990 + // if computing lots of characters or very large sizes. 991 992 993 ··· 1359 return stbtt__cff_get_index(&cff); 1360 } 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 + 1378 static int stbtt_InitFont_internal(stbtt_fontinfo *info, unsigned char *data, int fontstart) 1379 { 1380 stbtt_uint32 cmap, t; ··· 1453 info->numGlyphs = ttUSHORT(data+t+4); 1454 else 1455 info->numGlyphs = 0xffff; 1456 + 1457 + info->svg = -1; 1458 1459 // find a cmap encoding table we understand *now* to avoid searching 1460 // later. (todo: could make this installable) ··· 1762 if (i != 0) 1763 num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy); 1764 1765 + // now start the new one 1766 start_off = !(flags & 1); 1767 if (start_off) { 1768 // if we start off with an off-curve point, then when we need to find a point on the curve ··· 1804 } 1805 } 1806 num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy); 1807 + } else if (numberOfContours < 0) { 1808 // Compound shapes. 1809 int more = 1; 1810 stbtt_uint8 *comp = data + g + 10; ··· 1815 int comp_num_verts = 0, i; 1816 stbtt_vertex *comp_verts = 0, *tmp = 0; 1817 float mtx[6] = {1,0,0,1,0,0}, m, n; 1818 + 1819 flags = ttSHORT(comp); comp+=2; 1820 gidx = ttSHORT(comp); comp+=2; 1821 ··· 1845 mtx[2] = ttSHORT(comp)/16384.0f; comp+=2; 1846 mtx[3] = ttSHORT(comp)/16384.0f; comp+=2; 1847 } 1848 + 1849 // Find transformation scales. 1850 m = (float) STBTT_sqrt(mtx[0]*mtx[0] + mtx[1]*mtx[1]); 1851 n = (float) STBTT_sqrt(mtx[2]*mtx[2] + mtx[3]*mtx[3]); ··· 1881 // More components ? 1882 more = flags & (1<<5); 1883 } 1884 } else { 1885 // numberOfCounters == 0, do nothing 1886 } ··· 2309 } 2310 } 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 + 2354 static int stbtt__GetGlyphKernInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2) 2355 { 2356 stbtt_uint8 *data = info->data + info->kern; ··· 2548 if (valueFormat2 != 0) return 0; 2549 2550 STBTT_assert(coverageIndex < pairSetCount); 2551 + STBTT__NOTUSED(pairSetCount); 2552 2553 needle=glyph2; 2554 r=pairValueCount-1; ··· 2626 2627 if (info->gpos) 2628 xAdvance += stbtt__GetGlyphGPOSInfoAdvance(info, g1, g2); 2629 + else if (info->kern) 2630 xAdvance += stbtt__GetGlyphKernInfoAdvance(info, g1, g2); 2631 2632 return xAdvance; ··· 2687 STBTT_free(v, info->userdata); 2688 } 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 + 2729 ////////////////////////////////////////////////////////////////////////////// 2730 // 2731 // antialiasing software rasterizer ··· 2851 float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); 2852 STBTT_assert(z != NULL); 2853 if (!z) return z; 2854 + 2855 // round dx down to avoid overshooting 2856 if (dxdy < 0) 2857 z->dx = -STBTT_ifloor(STBTT_FIX * -dxdy); ··· 2929 } 2930 } 2931 } 2932 + 2933 e = e->next; 2934 } 2935 } ··· 3284 if (e->y0 != e->y1) { 3285 stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata); 3286 if (z != NULL) { 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 3294 // insert at front 3295 z->next = active; 3296 active = z; ··· 3359 3360 static void stbtt__sort_edges_quicksort(stbtt__edge *p, int n) 3361 { 3362 + /* threshold for transitioning to insertion sort */ 3363 while (n > 12) { 3364 stbtt__edge t; 3365 int c01,c12,c,m,i,j; ··· 3494 points[n].y = y; 3495 } 3496 3497 + // tessellate until threshold p is happy... @TODO warped to compensate for non-linear stretching 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) 3499 { 3500 // midpoint ··· 3657 { 3658 int ix0,iy0,ix1,iy1; 3659 stbtt__bitmap gbm; 3660 + stbtt_vertex *vertices; 3661 int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices); 3662 3663 if (scale_x == 0) scale_x = scale_y; ··· 3680 if (height) *height = gbm.h; 3681 if (xoff ) *xoff = ix0; 3682 if (yoff ) *yoff = iy0; 3683 + 3684 if (gbm.w && gbm.h) { 3685 gbm.pixels = (unsigned char *) STBTT_malloc(gbm.w * gbm.h, info->userdata); 3686 if (gbm.pixels) { ··· 3691 } 3692 STBTT_free(vertices, info->userdata); 3693 return gbm.pixels; 3694 + } 3695 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) 3697 { ··· 3703 int ix0,iy0; 3704 stbtt_vertex *vertices; 3705 int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices); 3706 + stbtt__bitmap gbm; 3707 3708 stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,0,0); 3709 gbm.pixels = output; ··· 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) 3726 { 3727 return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y,shift_x,shift_y, stbtt_FindGlyphIndex(info,codepoint), width,height,xoff,yoff); 3728 + } 3729 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) 3731 { ··· 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) 3741 { 3742 return stbtt_GetCodepointBitmapSubpixel(info, scale_x, scale_y, 0.0f,0.0f, codepoint, width,height,xoff,yoff); 3743 + } 3744 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) 3746 { ··· 3865 con->y = 0; 3866 con->bottom_y = 0; 3867 STBTT__NOTUSED(nodes); 3868 + STBTT__NOTUSED(num_nodes); 3869 } 3870 3871 static void stbrp_pack_rects(stbrp_context *con, stbrp_rect *rects, int num_rects) ··· 3919 spc->stride_in_bytes = stride_in_bytes != 0 ? stride_in_bytes : pw; 3920 spc->h_oversample = 1; 3921 spc->v_oversample = 1; 3922 + spc->skip_missing = 0; 3923 3924 stbrp_init_target(context, pw-padding, ph-padding, nodes, num_nodes); 3925 ··· 3945 spc->v_oversample = v_oversample; 3946 } 3947 3948 + STBTT_DEF void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context *spc, int skip) 3949 + { 3950 + spc->skip_missing = skip; 3951 + } 3952 + 3953 #define STBTT__OVER_MASK (STBTT_MAX_OVERSAMPLE-1) 3954 3955 static void stbtt__h_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width) ··· 4092 STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects) 4093 { 4094 int i,j,k; 4095 + int missing_glyph_added = 0; 4096 4097 k=0; 4098 for (i=0; i < num_ranges; ++i) { ··· 4104 int x0,y0,x1,y1; 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]; 4106 int glyph = stbtt_FindGlyphIndex(info, codepoint); 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 + } 4120 ++k; 4121 } 4122 } ··· 4150 // rects array must be big enough to accommodate all characters in the given ranges 4151 STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects) 4152 { 4153 + int i,j,k, missing_glyph = -1, return_value = 1; 4154 4155 // save current values 4156 int old_h_over = spc->h_oversample; ··· 4169 sub_y = stbtt__oversample_shift(spc->v_oversample); 4170 for (j=0; j < ranges[i].num_chars; ++j) { 4171 stbrp_rect *r = &rects[k]; 4172 + if (r->was_packed && r->w != 0 && r->h != 0) { 4173 stbtt_packedchar *bc = &ranges[i].chardata_for_range[j]; 4174 int advance, lsb, x0,y0,x1,y1; 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]; ··· 4215 bc->yoff = (float) y0 * recip_v + sub_y; 4216 bc->xoff2 = (x0 + r->w) * recip_h + sub_x; 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]; 4225 } else { 4226 return_value = 0; // if any fail, report failure 4227 } ··· 4260 n = 0; 4261 for (i=0; i < num_ranges; ++i) 4262 n += ranges[i].num_chars; 4263 + 4264 rects = (stbrp_rect *) STBTT_malloc(sizeof(*rects) * n, spc->user_allocator_context); 4265 if (rects == NULL) 4266 return 0; ··· 4271 n = stbtt_PackFontRangesGatherRects(spc, &info, ranges, num_ranges, rects); 4272 4273 stbtt_PackFontRangesPackRects(spc, rects, n); 4274 + 4275 return_value = stbtt_PackFontRangesRenderIntoRects(spc, &info, ranges, num_ranges, rects); 4276 4277 STBTT_free(rects, spc->user_allocator_context); ··· 4288 range.chardata_for_range = chardata_for_range; 4289 range.font_size = font_size; 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; 4304 } 4305 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) ··· 4432 int x1 = (int) verts[i ].x, y1 = (int) verts[i ].y; 4433 if (y > STBTT_min(y0,y1) && y < STBTT_max(y0,y1) && x > STBTT_min(x0,x1)) { 4434 float x_inter = (y - y0) / (y1 - y0) * (x1-x0) + x0; 4435 + if (x_inter < x) 4436 winding += (y0 < y1) ? 1 : -1; 4437 } 4438 } ··· 4458 y1 = (int)verts[i ].y; 4459 if (y > STBTT_min(y0,y1) && y < STBTT_max(y0,y1) && x > STBTT_min(x0,x1)) { 4460 float x_inter = (y - y0) / (y1 - y0) * (x1-x0) + x0; 4461 + if (x_inter < x) 4462 winding += (y0 < y1) ? 1 : -1; 4463 } 4464 } else { ··· 4470 if (hits[1][0] < 0) 4471 winding += (hits[1][1] < 0 ? -1 : 1); 4472 } 4473 + } 4474 } 4475 } 4476 return winding; ··· 4523 int w,h; 4524 unsigned char *data; 4525 4526 + if (scale == 0) return NULL; 4527 4528 stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale, scale, 0.0f,0.0f, &ix0,&iy0,&ix1,&iy1); 4529 ··· 4546 4547 // invert for y-downwards bitmaps 4548 scale_y = -scale_y; 4549 + 4550 { 4551 int x,y,i,j; 4552 float *precompute; ··· 4695 STBTT_free(verts, info->userdata); 4696 } 4697 return data; 4698 + } 4699 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) 4701 { ··· 4713 // 4714 4715 // check if a utf8 string contains a prefix which is the utf16 string; if so return length of matching utf8 string 4716 + static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(stbtt_uint8 *s1, stbtt_int32 len1, stbtt_uint8 *s2, stbtt_int32 len2) 4717 { 4718 stbtt_int32 i=0; 4719 ··· 4752 return i; 4753 } 4754 4755 + static int stbtt_CompareUTF8toUTF16_bigendian_internal(char *s1, int len1, char *s2, int len2) 4756 { 4757 return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((stbtt_uint8*) s1, len1, (stbtt_uint8*) s2, len2); 4758 } ··· 4881 4882 STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index) 4883 { 4884 + return stbtt_GetFontOffsetForIndex_internal((unsigned char *) data, index); 4885 } 4886 4887 STBTT_DEF int stbtt_GetNumberOfFonts(const unsigned char *data) ··· 4974 ------------------------------------------------------------------------------ 4975 ALTERNATIVE A - MIT License 4976 Copyright (c) 2017 Sean Barrett 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 4982 so, subject to the following conditions: 4983 + The above copyright notice and this permission notice shall be included in all 4984 copies or substantial portions of the Software. 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 4991 SOFTWARE. 4992 ------------------------------------------------------------------------------ 4993 ALTERNATIVE B - Public Domain (www.unlicense.org) 4994 This is free and unencumbered software released into the public domain. 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, 4997 commercial or non-commercial, and by any means. 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 5003 this software under copyright law. 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 5009 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 5010 ------------------------------------------------------------------------------ 5011 */