294#define STBTT_malloc(x,u) ((void)(u), fl::malloc(x))
295#define STBTT_free(x,u) ((void)(u), fl::free(x))
296#define STBTT_ifloor(x) ((int)fl::floor(x))
297#define STBTT_iceil(x) ((int)fl::ceil(x))
298#define STBTT_sqrt(x) fl::sqrt(x)
299#define STBTT_pow(x,y) fl::pow(x,y)
300#define STBTT_fmod(x,y) fl::fmod(x,y)
301#define STBTT_cos(x) fl::cos(x)
302#define STBTT_acos(x) fl::acos(x)
303#define STBTT_fabs(x) fl::fabs(x)
304#define STBTT_strlen(x) fl::strlen(x)
305#define STBTT_memcpy fl::memcpy
306#define STBTT_memset fl::memset
307#define STBTT_assert(x) FL_ASSERT(x, "stb_truetype assertion failed")
310#define STB_TRUETYPE_IMPLEMENTATION
313namespace third_party {
317#define STB_TRUETYPE_IMPLEMENTATION
320unsigned char ttf_buffer[1<<20];
321unsigned char temp_bitmap[512*512];
326void my_stbtt_initfont(
void)
328 fread(ttf_buffer, 1, 1<<20,
fopen(
"c:/windows/fonts/times.ttf",
"rb"));
331 glGenTextures(1, &ftex);
332 glBindTexture(GL_TEXTURE_2D, ftex);
333 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 512,512, 0, GL_ALPHA, GL_UNSIGNED_BYTE, temp_bitmap);
335 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
338void my_stbtt_print(
float x,
float y,
char *text)
342 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
343 glEnable(GL_TEXTURE_2D);
344 glBindTexture(GL_TEXTURE_2D, ftex);
347 if (*text >= 32 && *text < 128) {
350 glTexCoord2f(q.
s0,q.
t0); glVertex2f(q.
x0,q.
y0);
351 glTexCoord2f(q.
s1,q.
t0); glVertex2f(q.
x1,q.
y0);
352 glTexCoord2f(q.
s1,q.
t1); glVertex2f(q.
x1,q.
y1);
353 glTexCoord2f(q.
s0,q.
t1); glVertex2f(q.
x0,q.
y1);
368#define STB_TRUETYPE_IMPLEMENTATION
371char ttf_buffer[1<<25];
376 unsigned char *bitmap;
377 int32_t w,h,i,j,c = (argc > 1 ?
atoi(argv[1]) :
'a'), s = (argc > 2 ?
atoi(argv[2]) : 20);
379 fread(ttf_buffer, 1, 1<<25,
fopen(argc > 3 ? argv[3] :
"c:/windows/fonts/arialbd.ttf",
"rb"));
384 for (j=0; j < h; ++j) {
385 for (i=0; i < w; ++i)
386 putchar(
" .:ioVM@"[bitmap[j*w+i]>>5]);
412unsigned char screen[20][79];
417 int32_t i,j,ascent,baseline,ch=0;
419 char *text =
"Heljo World!";
421 fread(buffer, 1, 1000000,
fopen(
"c:/windows/fonts/arialbd.ttf",
"rb"));
426 baseline = (int) (ascent*
scale);
429 int32_t advance,lsb,x0,y0,x1,y1;
430 float x_shift = xpos - (float)
floor(xpos);
438 xpos += (advance *
scale);
444 for (j=0; j < 20; ++j) {
445 for (i=0; i < 78; ++i)
446 putchar(
" .:ioVM@"[
screen[j][i]>>5]);
464#ifdef STB_TRUETYPE_IMPLEMENTATION
481 #define STBTT_ifloor(x) ((int) floor(x))
482 #define STBTT_iceil(x) ((int) ceil(x))
487 #define STBTT_sqrt(x) sqrt(x)
488 #define STBTT_pow(x,y) pow(x,y)
493 #define STBTT_fmod(x,y) fmod(x,y)
498 #define STBTT_cos(x) cos(x)
499 #define STBTT_acos(x) acos(x)
504 #define STBTT_fabs(x) fabs(x)
510 #define STBTT_malloc(x,u) ((void)(u),malloc(x))
511 #define STBTT_free(x,u) ((void)(u),free(x))
515 #include "fl/stl/cassert.h"
516 #define STBTT_assert(x) assert(x)
521 #define STBTT_strlen(x) strlen(x)
526 #define STBTT_memcpy memcpy
527 #define STBTT_memset memset
538#ifndef __STB_INCLUDE_STB_TRUETYPE_H__
539#define __STB_INCLUDE_STB_TRUETYPE_H__
581 float *xpos,
float *ypos,
614#ifndef STB_RECT_PACK_VERSION
632#define STBTT_POINT_SIZE(x) (-(x))
689 float *xpos,
float *ypos,
864 #define stbtt_vertex_type short
927void stbtt_MakeCodepointBitmapSubpixelPrefilter(
const stbtt_fontinfo *info,
unsigned char *output,
int32_t out_w,
int32_t out_h,
int32_t out_stride,
float scale_x,
float scale_y,
float shift_x,
float shift_y,
int32_t oversample_x,
int32_t oversample_y,
float *sub_x,
float *sub_y,
int32_t codepoint)
FL_NOEXCEPT;
948void stbtt_MakeGlyphBitmapSubpixelPrefilter(
const stbtt_fontinfo *info,
unsigned char *output,
int32_t out_w,
int32_t out_h,
int32_t out_stride,
float scale_x,
float scale_y,
float shift_x,
float shift_y,
int32_t oversample_x,
int32_t oversample_y,
float *sub_x,
float *sub_y,
int32_t glyph)
FL_NOEXCEPT;
962 float flatness_in_pixels,
966 float shift_x,
float shift_y,
1056#define STBTT_MACSTYLE_DONTCARE 0
1057#define STBTT_MACSTYLE_BOLD 1
1058#define STBTT_MACSTYLE_ITALIC 2
1059#define STBTT_MACSTYLE_UNDERSCORE 4
1060#define STBTT_MACSTYLE_NONE 8
1132#ifdef STB_TRUETYPE_IMPLEMENTATION
1134#ifndef STBTT_MAX_OVERSAMPLE
1135#define STBTT_MAX_OVERSAMPLE 8
1138#if STBTT_MAX_OVERSAMPLE > 255
1139#error "STBTT_MAX_OVERSAMPLE cannot be > 255"
1144#ifndef STBTT_RASTERIZER_VERSION
1145#define STBTT_RASTERIZER_VERSION 2
1149#define STBTT__NOTUSED(v) (void)(v)
1151#define STBTT__NOTUSED(v) (void)sizeof(v)
1161 if (b->cursor >= b->size)
1163 return b->data[b->cursor++];
1168 if (b->cursor >= b->size)
1170 return b->data[b->cursor];
1176 b->cursor = (o > b->size || o < 0) ? b->size : o;
1189 for (i = 0; i < n; i++)
1199 r.
size = (int) size;
1204#define stbtt__buf_get16(b) stbtt__buf_get((b), 2)
1205#define stbtt__buf_get32(b) stbtt__buf_get((b), 4)
1210 if (o < 0 || s < 0 || o > b->size || s > b->size - o)
return r;
1211 r.
data = b->data + o;
1218 int32_t count, start, offsize;
1233 if (b0 >= 32 && b0 <= 246)
return b0 - 139;
1234 else if (b0 >= 247 && b0 <= 250)
return (b0 - 247)*256 +
stbtt__buf_get8(b) + 108;
1235 else if (b0 >= 251 && b0 <= 254)
return -(b0 - 251)*256 -
stbtt__buf_get8(b) - 108;
1247 while (b->cursor < b->size) {
1249 if ((v & 0xF) == 0xF || (v >> 4) == 0xF)
1260 while (b->cursor < b->size) {
1276 for (i = 0; i < outcount && operands.
cursor < operands.
size; i++)
1308#define ttBYTE(p) (* (stbtt_uint8 *) (p))
1309#define ttCHAR(p) (* (stbtt_int8 *) (p))
1310#define ttFixed(p) ttLONG(p)
1317#define stbtt_tag4(p,c0,c1,c2,c3) ((p)[0] == (c0) && (p)[1] == (c1) && (p)[2] == (c2) && (p)[3] == (c3))
1318#define stbtt_tag(p,str) stbtt_tag4(p,str[0],str[1],str[2],str[3])
1337 for (i=0; i < num_tables; ++i) {
1349 return index == 0 ? 0 : -1;
1352 if (
stbtt_tag(font_collection,
"ttcf")) {
1354 if (
ttULONG(font_collection+4) == 0x00010000 ||
ttULONG(font_collection+4) == 0x00020000) {
1358 return ttULONG(font_collection+12+index*4);
1371 if (
stbtt_tag(font_collection,
"ttcf")) {
1373 if (
ttULONG(font_collection+4) == 0x00010000 ||
ttULONG(font_collection+4) == 0x00020000) {
1374 return ttLONG(font_collection+8);
1385 if (!private_loc[1] || !private_loc[0])
return stbtt__new_buf(
nullptr, 0);
1397 if (info->svg < 0) {
1415 info->fontstart = fontstart;
1427 if (!cmap || !info->head || !info->hhea || !info->hmtx)
1431 if (!info->loca)
return 0;
1435 stbtt_uint32 cstype = 2, charstrings = 0, fdarrayoff = 0, fdselectoff = 0;
1446 #define STBTT_CFF_SIZE_LIMIT (512L*1024L*1024L)
1470 if (cstype != 2)
return 0;
1471 if (charstrings == 0)
return 0;
1475 if (!fdselectoff)
return 0;
1489 info->numGlyphs = 0xffff;
1496 numTables =
ttUSHORT(data + cmap + 2);
1497 info->index_map = 0;
1498 for (i=0; i < numTables; ++i) {
1501 switch(
ttUSHORT(data+encoding_record)) {
1503 switch (
ttUSHORT(data+encoding_record+2)) {
1507 info->index_map = cmap +
ttULONG(data+encoding_record+4);
1514 info->index_map = cmap +
ttULONG(data+encoding_record+4);
1518 if (info->index_map == 0)
1521 info->indexToLocFormat =
ttUSHORT(data+info->head + 50);
1533 if (unicode_codepoint < bytes-6)
1534 return ttBYTE(data + index_map + 6 + unicode_codepoint);
1536 }
else if (
format == 6) {
1540 return ttUSHORT(data + index_map + 10 + (unicode_codepoint - first)*2);
1542 }
else if (
format == 2) {
1545 }
else if (
format == 4) {
1555 if (unicode_codepoint > 0xffff)
1560 if (unicode_codepoint >=
ttUSHORT(data + search + rangeShift*2))
1561 search += rangeShift*2;
1565 while (entrySelector) {
1569 if (unicode_codepoint >
end)
1570 search += searchRange*2;
1579 start =
ttUSHORT(data + index_map + 14 + segcount*2 + 2 + 2*item);
1580 last =
ttUSHORT(data + endCount + 2*item);
1581 if (unicode_codepoint < start || unicode_codepoint > last)
1584 offset =
ttUSHORT(data + index_map + 14 + segcount*6 + 2 + 2*item);
1586 return (
stbtt_uint16) (unicode_codepoint +
ttSHORT(data + index_map + 14 + segcount*4 + 2 + 2*item));
1588 return ttUSHORT(data +
offset + (unicode_codepoint-start)*2 + index_map + 14 + segcount*6 + 2 + 2*item);
1595 while (low < high) {
1606 return start_glyph + unicode_codepoint-start_char;
1638 if (glyph_index >= info->numGlyphs)
return -1;
1639 if (info->indexToLocFormat >= 2)
return -1;
1641 if (info->indexToLocFormat == 0) {
1642 g1 = info->glyf +
ttUSHORT(info->data + info->loca + glyph_index * 2) * 2;
1643 g2 = info->glyf +
ttUSHORT(info->data + info->loca + glyph_index * 2 + 2) * 2;
1645 g1 = info->glyf +
ttULONG (info->data + info->loca + glyph_index * 4);
1646 g2 = info->glyf +
ttULONG (info->data + info->loca + glyph_index * 4 + 4);
1649 return g1==g2 ? -1 : g1;
1656 if (info->cff.size) {
1660 if (g < 0)
return 0;
1662 if (x0) *x0 =
ttSHORT(info->data + g + 2);
1663 if (y0) *y0 =
ttSHORT(info->data + g + 4);
1664 if (x1) *x1 =
ttSHORT(info->data + g + 6);
1665 if (y1) *y1 =
ttSHORT(info->data + g + 8);
1682 if (g < 0)
return 1;
1683 numberOfContours =
ttSHORT(info->data + g);
1684 return numberOfContours == 0;
1700 return num_vertices;
1712 *pvertices =
nullptr;
1714 if (g < 0)
return 0;
1716 numberOfContours =
ttSHORT(data + g);
1718 if (numberOfContours > 0) {
1720 stbtt_int32 ins, i,j=0,m,n, next_move, was_off=0, off, start_off=0;
1723 endPtsOfContours = (data + g + 10);
1724 ins =
ttUSHORT(data + g + 10 + numberOfContours * 2);
1725 points = data + g + 10 + numberOfContours * 2 + 2 + ins;
1727 n = 1+
ttUSHORT(endPtsOfContours + numberOfContours*2-2);
1729 m = n + 2*numberOfContours;
1745 for (i=0; i < n; ++i) {
1746 if (flagcount == 0) {
1749 flagcount = *points++;
1752 vertices[off+i].
type = flags;
1757 for (i=0; i < n; ++i) {
1758 flags = vertices[off+i].
type;
1761 x += (flags & 16) ? dx : -dx;
1763 if (!(flags & 16)) {
1773 for (i=0; i < n; ++i) {
1774 flags = vertices[off+i].
type;
1777 y += (flags & 32) ? dy : -dy;
1779 if (!(flags & 32)) {
1789 sx = sy = cx = cy = scx = scy = 0;
1790 for (i=0; i < n; ++i) {
1791 flags = vertices[off+i].
type;
1795 if (next_move == i) {
1797 num_vertices =
stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
1800 start_off = !(flags & 1);
1806 if (!(vertices[off+i+1].
type & 1)) {
1822 next_move = 1 +
ttUSHORT(endPtsOfContours+j*2);
1840 num_vertices =
stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
1841 }
else if (numberOfContours < 0) {
1849 int32_t comp_num_verts = 0, i;
1851 float mtx[6] = {1,0,0,1,0,0}, m, n;
1853 flags =
ttSHORT(comp); comp+=2;
1854 gidx =
ttSHORT(comp); comp+=2;
1858 mtx[4] =
ttSHORT(comp); comp+=2;
1859 mtx[5] =
ttSHORT(comp); comp+=2;
1861 mtx[4] =
ttCHAR(comp); comp+=1;
1862 mtx[5] =
ttCHAR(comp); comp+=1;
1869 if (flags & (1<<3)) {
1870 mtx[0] = mtx[3] =
ttSHORT(comp)/16384.0f; comp+=2;
1871 mtx[1] = mtx[2] = 0;
1872 }
else if (flags & (1<<6)) {
1873 mtx[0] =
ttSHORT(comp)/16384.0f; comp+=2;
1874 mtx[1] = mtx[2] = 0;
1875 mtx[3] =
ttSHORT(comp)/16384.0f; comp+=2;
1876 }
else if (flags & (1<<7)) {
1877 mtx[0] =
ttSHORT(comp)/16384.0f; comp+=2;
1878 mtx[1] =
ttSHORT(comp)/16384.0f; comp+=2;
1879 mtx[2] =
ttSHORT(comp)/16384.0f; comp+=2;
1880 mtx[3] =
ttSHORT(comp)/16384.0f; comp+=2;
1884 m = (float)
STBTT_sqrt(mtx[0]*mtx[0] + mtx[1]*mtx[1]);
1885 n = (float)
STBTT_sqrt(mtx[2]*mtx[2] + mtx[3]*mtx[3]);
1889 if (comp_num_verts > 0) {
1891 for (i = 0; i < comp_num_verts; ++i) {
1904 if (vertices)
STBTT_free(vertices, info->userdata);
1905 if (comp_verts)
STBTT_free(comp_verts, info->userdata);
1910 if (vertices)
STBTT_free(vertices, info->userdata);
1913 num_vertices += comp_num_verts;
1916 more = flags & (1<<5);
1922 *pvertices = vertices;
1923 return num_vertices;
1938#define STBTT__CSCTX_INIT(bounds) {bounds,0, 0,0, 0,0, 0,0,0,0, nullptr, 0}
1942 if (
x > c->max_x || !c->started) c->max_x =
x;
1943 if (
y > c->max_y || !c->started) c->max_y =
y;
1944 if (
x < c->min_x || !c->started) c->min_x =
x;
1945 if (
y < c->min_y || !c->started) c->min_y =
y;
1959 c->pvertices[c->num_vertices].cx1 = (
stbtt_int16) cx1;
1960 c->pvertices[c->num_vertices].cy1 = (
stbtt_int16) cy1;
1967 if (ctx->first_x != ctx->x || ctx->first_y != ctx->y)
1974 ctx->first_x = ctx->x = ctx->x + dx;
1975 ctx->first_y = ctx->y = ctx->y + dy;
1988 float cx1 = ctx->x + dx1;
1989 float cy1 = ctx->y + dy1;
1990 float cx2 = cx1 + dx2;
1991 float cy2 = cy1 + dy2;
2003 else if (count >= 1240)
2006 if (n < 0 || n >= count)
2014 int32_t nranges, start,
end, v, fmt, fdselector = -1, i;
2022 }
else if (fmt == 3) {
2025 for (i = 0; i < nranges; i++) {
2028 if (glyph_index >= start && glyph_index <
end) {
2041 int32_t in_header = 1, maskbits = 0, subr_stack_height = 0, sp = 0, v, i, b0;
2042 int32_t has_subrs = 0, clear_stack;
2044 stbtt__buf subr_stack[10], subrs = info->subrs, b;
2047#define STBTT__CSERR(s) (0)
2051 while (b.cursor < b.size) {
2060 maskbits += (sp / 2);
2069 maskbits += (sp / 2);
2090 for (; i + 1 < sp; i += 2)
2119 if (i + 3 >= sp)
break;
2123 if (i + 3 >= sp)
break;
2131 for (; i + 5 < sp; i += 6)
2137 for (; i + 5 < sp - 2; i += 6)
2139 if (i + 1 >= sp)
return STBTT__CSERR(
"rcurveline stack");
2145 for (; i + 1 < sp - 6; i += 2)
2147 if (i + 5 >= sp)
return STBTT__CSERR(
"rlinecurve stack");
2153 if (sp < 4)
return STBTT__CSERR(
"(vv|hh)curveto stack");
2155 if (sp & 1) { f = s[i]; i++; }
2156 for (; i + 3 < sp; i += 4) {
2167 if (info->fdselect.size)
2175 if (subr_stack_height >= 10)
return STBTT__CSERR(
"recursion limit");
2176 subr_stack[subr_stack_height++] = b;
2178 if (b.size == 0)
return STBTT__CSERR(
"subr not found");
2184 if (subr_stack_height <= 0)
return STBTT__CSERR(
"return outside subr");
2185 b = subr_stack[--subr_stack_height];
2194 float dx1, dx2, dx3, dx4, dx5, dx6, dy1, dy2, dy3, dy4, dy5, dy6;
2260 dx = dx1+dx2+dx3+dx4+dx5;
2261 dy = dy1+dy2+dy3+dy4+dy5;
2276 if (b0 != 255 && b0 != 28 && b0 < 32)
2286 if (sp >= 48)
return STBTT__CSERR(
"push stack overflow");
2291 if (clear_stack) sp = 0;
2311 *pvertices =
nullptr;
2319 if (x0) *x0 = r ? c.
min_x : 0;
2320 if (y0) *y0 = r ? c.
min_y : 0;
2321 if (x1) *x1 = r ? c.
max_x : 0;
2322 if (y1) *y1 = r ? c.
max_y : 0;
2328 if (!info->cff.size)
2337 if (glyph_index < numOfLongHorMetrics) {
2338 if (advanceWidth) *advanceWidth =
ttSHORT(info->data + info->hmtx + 4*glyph_index);
2339 if (leftSideBearing) *leftSideBearing =
ttSHORT(info->data + info->hmtx + 4*glyph_index + 2);
2341 if (advanceWidth) *advanceWidth =
ttSHORT(info->data + info->hmtx + 4*(numOfLongHorMetrics-1));
2342 if (leftSideBearing) *leftSideBearing =
ttSHORT(info->data + info->hmtx + 4*numOfLongHorMetrics + 2*(glyph_index - numOfLongHorMetrics));
2375 if (table_length <
length)
2378 for (k = 0; k <
length; k++)
2380 table[k].glyph1 =
ttUSHORT(data+18+(k*6));
2381 table[k].glyph2 =
ttUSHORT(data+20+(k*6));
2382 table[k].advance =
ttSHORT(data+22+(k*6));
2404 needle = glyph1 << 16 | glyph2;
2407 straw =
ttULONG(data+18+(m*6));
2410 else if (needle > straw)
2413 return ttSHORT(data+22+(m*6));
2421 switch (coverageFormat) {
2432 glyphID =
ttUSHORT(glyphArray + 2 * m);
2436 else if (needle > straw)
2451 int32_t strawStart, strawEnd, needle=glyph;
2455 rangeRecord = rangeArray + 6 * m;
2456 strawStart =
ttUSHORT(rangeRecord);
2457 strawEnd =
ttUSHORT(rangeRecord + 2);
2458 if (needle < strawStart)
2460 else if (needle > strawEnd)
2464 return startCoverageIndex + glyph - strawStart;
2479 switch (classDefFormat)
2484 stbtt_uint8 *classDef1ValueArray = classDefTable + 6;
2486 if (glyph >= startGlyphID && glyph < startGlyphID + glyphCount)
2493 stbtt_uint8 *classRangeRecords = classDefTable + 4;
2497 int32_t strawStart, strawEnd, needle=glyph;
2501 classRangeRecord = classRangeRecords + 6 * m;
2502 strawStart =
ttUSHORT(classRangeRecord);
2503 strawEnd =
ttUSHORT(classRangeRecord + 2);
2504 if (needle < strawStart)
2506 else if (needle > strawEnd)
2523#define STBTT_GPOS_TODO_assert(x)
2533 if (!info->gpos)
return 0;
2535 data = info->data + info->gpos;
2537 if (
ttUSHORT(data+0) != 1)
return 0;
2538 if (
ttUSHORT(data+2) != 0)
return 0;
2540 lookupListOffset =
ttUSHORT(data+8);
2541 lookupList = data + lookupListOffset;
2542 lookupCount =
ttUSHORT(lookupList);
2544 for (i=0; i<lookupCount; ++i) {
2546 stbtt_uint8 *lookupTable = lookupList + lookupOffset;
2551 if (lookupType != 2)
2554 for (sti=0; sti<subTableCount; sti++) {
2556 stbtt_uint8 *table = lookupTable + subtableOffset;
2560 if (coverageIndex == -1)
continue;
2562 switch (posFormat) {
2568 if (valueFormat1 == 4 && valueFormat2 == 0) {
2572 stbtt_uint8 *pairValueTable = table + pairPosOffset;
2576 if (coverageIndex >= pairSetCount)
return 0;
2587 pairValue = pairValueArray + (2 + valueRecordPairSizeInBytes) * m;
2589 straw = secondGlyph;
2592 else if (needle > straw)
2607 if (valueFormat1 == 4 && valueFormat2 == 0) {
2618 if (glyph1class < 0 || glyph1class >= class1Count)
return 0;
2619 if (glyph2class < 0 || glyph2class >= class2Count)
return 0;
2621 class1Records = table + 16;
2622 class2Records = class1Records + 2 * (glyph1class * class2Count);
2623 xAdvance =
ttSHORT(class2Records + 2 * glyph2class);
2645 else if (info->kern)
2653 if (!info->kern && !info->gpos)
2665 if (ascent ) *ascent =
ttSHORT(info->data+info->hhea + 4);
2666 if (descent) *descent =
ttSHORT(info->data+info->hhea + 6);
2667 if (lineGap) *lineGap =
ttSHORT(info->data+info->hhea + 8);
2675 if (typoAscent ) *typoAscent =
ttSHORT(info->data+tab + 68);
2676 if (typoDescent) *typoDescent =
ttSHORT(info->data+tab + 70);
2677 if (typoLineGap) *typoLineGap =
ttSHORT(info->data+tab + 72);
2683 *x0 =
ttSHORT(info->data + info->head + 36);
2684 *y0 =
ttSHORT(info->data + info->head + 38);
2685 *x1 =
ttSHORT(info->data + info->head + 40);
2686 *y1 =
ttSHORT(info->data + info->head + 42);
2692 return (
float)
height / fheight;
2698 return pixels / unitsPerEm;
2715 for(i=0; i<numEntries; i++) {
2732 if (svg_doc !=
nullptr) {
2733 *svg = (
char *) data + info->svg +
ttULONG(svg_doc + 4);
2775 stbtt_GetGlyphBitmapBoxSubpixel(font,
stbtt_FindGlyphIndex(font,codepoint),
scale_x,
scale_y,shift_x,shift_y, ix0,iy0,ix1,iy1);
2801 if (hh->first_free) {
2802 void *p = hh->first_free;
2803 hh->first_free = * (
void **) p;
2806 if (hh->num_remaining_in_head_chunk == 0) {
2807 int32_t count = (size < 32 ? 2000 : size < 128 ? 800 : 100);
2813 hh->num_remaining_in_head_chunk = count;
2815 --hh->num_remaining_in_head_chunk;
2816 return (
char *) (hh->head) +
sizeof(
stbtt__hheap_chunk) + size * hh->num_remaining_in_head_chunk;
2822 *(
void **) p = hh->first_free;
2845 #if STBTT_RASTERIZER_VERSION==1
2849 #elif STBTT_RASTERIZER_VERSION==2
2855 #error "Unrecognized value of STBTT_RASTERIZER_VERSION"
2859#if STBTT_RASTERIZER_VERSION == 1
2860#define STBTT_FIXSHIFT 10
2861#define STBTT_FIX (1 << STBTT_FIXSHIFT)
2862#define STBTT_FIXMASK (STBTT_FIX-1)
2867 float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
2877 z->x =
STBTT_ifloor(STBTT_FIX * e->x0 +
z->dx * (start_point - e->y0));
2878 z->x -= off_x * STBTT_FIX;
2882 z->direction = e->invert ? 1 : -1;
2885#elif STBTT_RASTERIZER_VERSION == 2
2889 float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
2894 z->fdy = dxdy != 0.0f ? (1.0f/dxdy) : 0.0f;
2895 z->fx = e->x0 + dxdy * (start_point - e->y0);
2897 z->direction = e->invert ? 1.0f : -1.0f;
2904#error "Unrecognized value of STBTT_RASTERIZER_VERSION"
2907#if STBTT_RASTERIZER_VERSION == 1
2919 x0 = e->x; w += e->direction;
2921 int32_t x1 = e->x; w += e->direction;
2924 int32_t i = x0 >> STBTT_FIXSHIFT;
2925 int32_t j = x1 >> STBTT_FIXSHIFT;
2927 if (i < len && j >= 0) {
2930 scanline[i] = scanline[i] + (
stbtt_uint8) ((x1 - x0) * max_weight >> STBTT_FIXSHIFT);
2933 scanline[i] = scanline[i] + (
stbtt_uint8) (((STBTT_FIX - (x0 & STBTT_FIXMASK)) * max_weight) >> STBTT_FIXSHIFT);
2938 scanline[j] = scanline[j] + (
stbtt_uint8) (((x1 & STBTT_FIXMASK) * max_weight) >> STBTT_FIXSHIFT);
2942 for (++i; i < j; ++i)
2943 scanline[i] = scanline[i] + (
stbtt_uint8) max_weight;
2958 int32_t max_weight = (255 / vsubsample);
2960 unsigned char scanline_data[512], *scanline;
2965 scanline = scanline_data;
2967 y = off_y * vsubsample;
2968 e[n].y0 = (off_y +
result->h) * (
float) vsubsample + 1;
2970 while (j < result->h) {
2972 for (s=0; s < vsubsample; ++s) {
2974 float scan_y =
y + 0.5f;
2981 if (
z->ey <= scan_y) {
2988 step = &((*step)->next);
2996 while (*
step && (*step)->next) {
2997 if ((*step)->x > (*step)->next->x) {
3006 step = &(*step)->next;
3008 if (!changed)
break;
3012 while (e->y0 <= scan_y) {
3013 if (e->y1 > scan_y) {
3017 if (active ==
nullptr)
3019 else if (
z->x < active->x) {
3026 while (p->next && p->next->x <
z->x)
3039 stbtt__fill_active_edges(scanline,
result->w, active, max_weight);
3049 if (scanline != scanline_data)
3053#elif STBTT_RASTERIZER_VERSION == 2
3057static void stbtt__handle_clipped_edge(
float *scanline,
int32_t x,
stbtt__active_edge *e,
float x0,
float y0,
float x1,
float y1)
3059 if (y0 == y1)
return;
3062 if (y0 > e->ey)
return;
3063 if (y1 < e->sy)
return;
3065 x0 += (x1-x0) * (e->sy - y0) / (y1-y0);
3069 x1 += (x1-x0) * (e->ey - y1) / (y1-y0);
3075 }
else if (x0 ==
x+1) {
3077 }
else if (x0 <=
x) {
3079 }
else if (x0 >=
x+1) {
3085 if (x0 <=
x && x1 <=
x)
3086 scanline[
x] += e->direction * (y1-y0);
3087 else if (x0 >=
x+1 && x1 >=
x+1)
3091 scanline[
x] += e->direction * (y1-y0) * (1-((x0-
x)+(x1-
x))/2);
3095static float stbtt__sized_trapezoid_area(
float height,
float top_width,
float bottom_width)
3099 return (top_width + bottom_width) / 2.0f *
height;
3102static float stbtt__position_trapezoid_area(
float height,
float tx0,
float tx1,
float bx0,
float bx1)
3104 return stbtt__sized_trapezoid_area(
height, tx1 - tx0, bx1 - bx0);
3107static float stbtt__sized_triangle_area(
float height,
float width)
3112static void stbtt__fill_active_edges_new(
float *scanline,
float *scanline_fill,
int32_t len,
stbtt__active_edge *e,
float y_top)
3114 float y_bottom = y_top+1;
3126 stbtt__handle_clipped_edge(scanline,(
int) x0,e, x0,y_top, x0,y_bottom);
3127 stbtt__handle_clipped_edge(scanline_fill-1,(
int) x0+1,e, x0,y_top, x0,y_bottom);
3129 stbtt__handle_clipped_edge(scanline_fill-1,0,e, x0,y_top, x0,y_bottom);
3136 float x_top, x_bottom;
3144 if (e->sy > y_top) {
3145 x_top = x0 + dx * (e->sy - y_top);
3151 if (e->ey < y_bottom) {
3152 x_bottom = x0 + dx * (e->ey - y_top);
3159 if (x_top >= 0 && x_bottom >= 0 && x_top < len && x_bottom < len) {
3162 if ((
int) x_top == (
int) x_bottom) {
3166 height = (sy1 - sy0) * e->direction;
3168 scanline[
x] += stbtt__position_trapezoid_area(
height, x_top,
x+1.0f, x_bottom,
x+1.0f);
3172 float y_crossing, y_final,
step,
sign, area;
3174 if (x_top > x_bottom) {
3177 sy0 = y_bottom - (sy0 - y_top);
3178 sy1 = y_bottom - (sy1 - y_top);
3179 t = sy0, sy0 = sy1, sy1 =
t;
3180 t = x_bottom, x_bottom = x_top, x_top =
t;
3183 t = x0, x0 = xb, xb =
t;
3189 x2 = (int) x_bottom;
3191 y_crossing = y_top + dy * (x1+1 - x0);
3194 y_final = y_top + dy * (x2 - x0);
3215 if (y_crossing > y_bottom)
3216 y_crossing = y_bottom;
3218 sign = e->direction;
3221 area =
sign * (y_crossing-sy0);
3224 scanline[x1] += stbtt__sized_triangle_area(area, x1+1 - x_top);
3227 if (y_final > y_bottom) {
3229 dy = (y_final - y_crossing ) / (x2 - (x1+1));
3246 for (
x = x1+1;
x < x2; ++
x) {
3247 scanline[
x] += area +
step/2;
3255 scanline[x2] += area +
sign * stbtt__position_trapezoid_area(sy1-y_final, (
float) x2, x2+1.0f, x_bottom, x2+1.0f);
3258 scanline_fill[x2] +=
sign * (sy1-sy0);
3269 for (
x=0;
x < len; ++
x) {
3285 float x1 = (float) (
x);
3286 float x2 = (float) (
x+1);
3288 float y3 = y_bottom;
3293 float y1 = (
x - x0) / dx + y_top;
3294 float y2 = (
x+1 - x0) / dx + y_top;
3296 if (x0 < x1 && x3 > x2) {
3297 stbtt__handle_clipped_edge(scanline,
x,e, x0,y0, x1,y1);
3298 stbtt__handle_clipped_edge(scanline,
x,e, x1,y1, x2,y2);
3299 stbtt__handle_clipped_edge(scanline,
x,e, x2,y2, x3,y3);
3300 }
else if (x3 < x1 && x0 > x2) {
3301 stbtt__handle_clipped_edge(scanline,
x,e, x0,y0, x2,y2);
3302 stbtt__handle_clipped_edge(scanline,
x,e, x2,y2, x1,y1);
3303 stbtt__handle_clipped_edge(scanline,
x,e, x1,y1, x3,y3);
3304 }
else if (x0 < x1 && x3 > x1) {
3305 stbtt__handle_clipped_edge(scanline,
x,e, x0,y0, x1,y1);
3306 stbtt__handle_clipped_edge(scanline,
x,e, x1,y1, x3,y3);
3307 }
else if (x3 < x1 && x0 > x1) {
3308 stbtt__handle_clipped_edge(scanline,
x,e, x0,y0, x1,y1);
3309 stbtt__handle_clipped_edge(scanline,
x,e, x1,y1, x3,y3);
3310 }
else if (x0 < x2 && x3 > x2) {
3311 stbtt__handle_clipped_edge(scanline,
x,e, x0,y0, x2,y2);
3312 stbtt__handle_clipped_edge(scanline,
x,e, x2,y2, x3,y3);
3313 }
else if (x3 < x2 && x0 > x2) {
3314 stbtt__handle_clipped_edge(scanline,
x,e, x0,y0, x2,y2);
3315 stbtt__handle_clipped_edge(scanline,
x,e, x2,y2, x3,y3);
3317 stbtt__handle_clipped_edge(scanline,
x,e, x0,y0, x3,y3);
3332 float scanline_data[129], *scanline, *scanline2;
3339 scanline = scanline_data;
3341 scanline2 = scanline +
result->w;
3344 e[n].y0 = (float) (off_y +
result->h) + 1;
3346 while (j < result->h) {
3348 float scan_y_top =
y + 0.0f;
3349 float scan_y_bottom =
y + 1.0f;
3359 if (
z->ey <= scan_y_top) {
3365 step = &((*step)->next);
3370 while (e->y0 <= scan_y_bottom) {
3371 if (e->y0 != e->y1) {
3374 if (j == 0 && off_y != 0) {
3375 if (
z->ey < scan_y_top) {
3391 stbtt__fill_active_edges_new(scanline, scanline2+1,
result->w, active, scan_y_top);
3395 for (i=0; i <
result->w; ++i) {
3398 sum += scanline2[i];
3399 k = scanline[i] + sum;
3402 if (m > 255) m = 255;
3403 result->pixels[j*
result->stride + i] = (
unsigned char) m;
3411 step = &((*step)->next);
3420 if (scanline != scanline_data)
3424#error "Unrecognized value of STBTT_RASTERIZER_VERSION"
3427#define STBTT__COMPARE(a,b) ((a)->y0 < (b)->y0)
3432 for (i=1; i < n; ++i) {
3465 z = (c == c12) ? 0 : n-1;
3520static void stbtt__rasterize(
stbtt__bitmap *
result,
stbtt__point *pts,
int32_t *wcount,
int32_t windings,
float scale_x,
float scale_y,
float shift_x,
float shift_y,
int32_t off_x,
int32_t off_y,
int32_t invert,
void *userdata)
3525#if STBTT_RASTERIZER_VERSION == 1
3527#elif STBTT_RASTERIZER_VERSION == 2
3530 #error "Unrecognized value of STBTT_RASTERIZER_VERSION"
3536 for (i=0; i < windings; ++i)
3544 for (i=0; i < windings; ++i) {
3548 for (k=0; k < wcount[i]; j=k++) {
3551 if (p[j].
y == p[k].
y)
3555 if (invert ? p[j].
y > p[k].
y : p[j].
y < p[k].
y) {
3560 e[n].
y0 = (p[a].
y * y_scale_inv + shift_y) * vsubsample;
3562 e[n].
y1 = (p[b].
y * y_scale_inv + shift_y) * vsubsample;
3572 stbtt__rasterize_sorted_edges(
result, e, n, vsubsample, off_x, off_y, userdata);
3579 if (!points)
return;
3588 float mx = (x0 + 2*x1 + x2)/4;
3589 float my = (y0 + 2*y1 + y2)/4;
3591 float dx = (x0+x2)/2 - mx;
3592 float dy = (y0+y2)/2 - my;
3595 if (dx*dx+dy*dy > objspace_flatness_squared) {
3596 stbtt__tesselate_curve(points, num_points, x0,y0, (x0+x1)/2.0f,(y0+y1)/2.0f, mx,my, objspace_flatness_squared,n+1);
3597 stbtt__tesselate_curve(points, num_points, mx,my, (x1+x2)/2.0f,(y1+y2)/2.0f, x2,y2, objspace_flatness_squared,n+1);
3600 *num_points = *num_points+1;
3605static void stbtt__tesselate_cubic(
stbtt__point *points,
int32_t *num_points,
float x0,
float y0,
float x1,
float y1,
float x2,
float y2,
float x3,
float y3,
float objspace_flatness_squared,
int32_t n)
3617 float shortlen = (float)
STBTT_sqrt(dx*dx+dy*dy);
3618 float flatness_squared = longlen*longlen-shortlen*shortlen;
3623 if (flatness_squared > objspace_flatness_squared) {
3624 float x01 = (x0+x1)/2;
3625 float y01 = (y0+y1)/2;
3626 float x12 = (x1+x2)/2;
3627 float y12 = (y1+y2)/2;
3628 float x23 = (x2+x3)/2;
3629 float y23 = (y2+y3)/2;
3631 float xa = (x01+x12)/2;
3632 float ya = (y01+y12)/2;
3633 float xb = (x12+x23)/2;
3634 float yb = (y12+y23)/2;
3636 float mx = (xa+xb)/2;
3637 float my = (ya+yb)/2;
3639 stbtt__tesselate_cubic(points, num_points, x0,y0, x01,y01, xa,ya, mx,my, objspace_flatness_squared,n+1);
3640 stbtt__tesselate_cubic(points, num_points, mx,my, xb,yb, x23,y23, x3,y3, objspace_flatness_squared,n+1);
3643 *num_points = *num_points+1;
3653 float objspace_flatness_squared = objspace_flatness * objspace_flatness;
3657 for (i=0; i < num_verts; ++i)
3662 if (n == 0)
return 0;
3666 if (*contour_lengths == 0) {
3672 for (pass=0; pass < 2; ++pass) {
3676 if (points ==
nullptr)
goto error;
3680 for (i=0; i < num_verts; ++i) {
3681 switch (vertices[i].
type) {
3685 (*contour_lengths)[n] = num_points - start;
3689 x = vertices[i].x,
y = vertices[i].y;
3693 x = vertices[i].x,
y = vertices[i].y;
3698 vertices[i].cx, vertices[i].cy,
3699 vertices[i].
x, vertices[i].
y,
3700 objspace_flatness_squared, 0);
3701 x = vertices[i].x,
y = vertices[i].y;
3705 vertices[i].cx, vertices[i].cy,
3706 vertices[i].cx1, vertices[i].cy1,
3707 vertices[i].
x, vertices[i].
y,
3708 objspace_flatness_squared, 0);
3709 x = vertices[i].x,
y = vertices[i].y;
3713 (*contour_lengths)[n] = num_points - start;
3720 *contour_lengths = 0;
3725void stbtt_Rasterize(
stbtt__bitmap *
result,
float flatness_in_pixels,
stbtt_vertex *vertices,
int32_t num_verts,
float scale_x,
float scale_y,
float shift_x,
float shift_y,
int32_t x_off,
int32_t y_off,
int32_t invert,
void *userdata)
3729 int32_t *winding_lengths =
nullptr;
3732 stbtt__rasterize(
result, windings, winding_lengths, winding_count,
scale_x,
scale_y, shift_x, shift_y, x_off, y_off, invert, userdata);
3762 gbm.
w = (ix1 - ix0);
3763 gbm.
h = (iy1 - iy0);
3768 if (xoff ) *xoff = ix0;
3769 if (yoff ) *yoff = iy0;
3771 if (gbm.
w && gbm.
h) {
3776 stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts,
scale_x,
scale_y, shift_x, shift_y, ix0, iy0, 1, info->userdata);
3802 stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts,
scale_x,
scale_y, shift_x, shift_y, ix0,iy0, 1, info->userdata);
3814 return stbtt_GetGlyphBitmapSubpixel(info,
scale_x,
scale_y,shift_x,shift_y,
stbtt_FindGlyphIndex(info,codepoint),
width,
height,xoff,yoff);
3817void stbtt_MakeCodepointBitmapSubpixelPrefilter(
const stbtt_fontinfo *info,
unsigned char *output,
int32_t out_w,
int32_t out_h,
int32_t out_stride,
float scale_x,
float scale_y,
float shift_x,
float shift_y,
int32_t oversample_x,
int32_t oversample_y,
float *sub_x,
float *sub_y,
int32_t codepoint)
3819 stbtt_MakeGlyphBitmapSubpixelPrefilter(info, output, out_w, out_h, out_stride,
scale_x,
scale_y, shift_x, shift_y, oversample_x, oversample_y, sub_x, sub_y,
stbtt_FindGlyphIndex(info,codepoint));
3824 stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride,
scale_x,
scale_y, shift_x, shift_y,
stbtt_FindGlyphIndex(info,codepoint));
3861 for (i=0; i < num_chars; ++i) {
3862 int32_t advance, lsb, x0,y0,x1,y1,gw,gh;
3868 if (
x + gw + 1 >= pw)
3869 y = bottom_y,
x = 1;
3870 if (
y + gh + 1 >= ph)
3879 chardata[i].xadvance =
scale * advance;
3880 chardata[i].xoff = (float) x0;
3881 chardata[i].yoff = (float) y0;
3883 if (
y+gh+1 > bottom_y)
3891 float d3d_bias = opengl_fillrule ? 0 : -0.5f;
3892 float ipw = 1.0f / pw, iph = 1.0f / ph;
3897 q->x0 = round_x + d3d_bias;
3898 q->y0 = round_y + d3d_bias;
3899 q->x1 = round_x + b->
x1 - b->
x0 + d3d_bias;
3900 q->y1 = round_y + b->
y1 - b->
y0 + d3d_bias;
3902 q->s0 = b->
x0 * ipw;
3903 q->t0 = b->
y0 * iph;
3904 q->s1 = b->
x1 * ipw;
3905 q->t1 = b->
y1 * iph;
3915#ifndef STB_RECT_PACK_VERSION
3961 for (i=0; i < num_rects; ++i) {
3962 if (con->x + rects[i].w > con->width) {
3964 con->y = con->bottom_y;
3966 if (con->y + rects[i].h > con->height)
3968 rects[i].x = con->x;
3969 rects[i].y = con->y;
3970 rects[i].was_packed = 1;
3971 con->x += rects[i].w;
3972 if (con->y + rects[i].h > con->bottom_y)
3973 con->bottom_y = con->y + rects[i].h;
3975 for ( ; i < num_rects; ++i)
3976 rects[i].was_packed = 0;
3990 int32_t num_nodes = pw - padding;
3993 if (context ==
nullptr || nodes ==
nullptr) {
3994 if (context !=
nullptr)
STBTT_free(context, alloc_context);
3995 if (nodes !=
nullptr)
STBTT_free(nodes , alloc_context);
3999 spc->user_allocator_context = alloc_context;
4002 spc->pixels = pixels;
4003 spc->pack_info = context;
4005 spc->padding = padding;
4006 spc->stride_in_bytes = stride_in_bytes != 0 ? stride_in_bytes : pw;
4007 spc->h_oversample = 1;
4008 spc->v_oversample = 1;
4009 spc->skip_missing = 0;
4021 STBTT_free(spc->nodes , spc->user_allocator_context);
4022 STBTT_free(spc->pack_info, spc->user_allocator_context);
4030 spc->h_oversample = h_oversample;
4032 spc->v_oversample = v_oversample;
4037 spc->skip_missing = skip;
4040#define STBTT__OVER_MASK (STBTT_MAX_OVERSAMPLE-1)
4045 int32_t safe_w = w - kernel_width;
4048 for (j=0; j < h; ++j) {
4056 switch (kernel_width) {
4058 for (i=0; i <= safe_w; ++i) {
4061 pixels[i] = (
unsigned char) (total / 2);
4065 for (i=0; i <= safe_w; ++i) {
4068 pixels[i] = (
unsigned char) (total / 3);
4072 for (i=0; i <= safe_w; ++i) {
4075 pixels[i] = (
unsigned char) (total / 4);
4079 for (i=0; i <= safe_w; ++i) {
4082 pixels[i] = (
unsigned char) (total / 5);
4086 for (i=0; i <= safe_w; ++i) {
4089 pixels[i] = (
unsigned char) (total / kernel_width);
4094 for (; i < w; ++i) {
4097 pixels[i] = (
unsigned char) (total / kernel_width);
4100 pixels += stride_in_bytes;
4107 int32_t safe_h = h - kernel_width;
4110 for (j=0; j < w; ++j) {
4118 switch (kernel_width) {
4120 for (i=0; i <= safe_h; ++i) {
4123 pixels[i*stride_in_bytes] = (
unsigned char) (total / 2);
4127 for (i=0; i <= safe_h; ++i) {
4130 pixels[i*stride_in_bytes] = (
unsigned char) (total / 3);
4134 for (i=0; i <= safe_h; ++i) {
4137 pixels[i*stride_in_bytes] = (
unsigned char) (total / 4);
4141 for (i=0; i <= safe_h; ++i) {
4144 pixels[i*stride_in_bytes] = (
unsigned char) (total / 5);
4148 for (i=0; i <= safe_h; ++i) {
4151 pixels[i*stride_in_bytes] = (
unsigned char) (total / kernel_width);
4156 for (; i < h; ++i) {
4159 pixels[i*stride_in_bytes] = (
unsigned char) (total / kernel_width);
4175 return (
float)-(oversample - 1) / (2.0f * (
float)oversample);
4182 int32_t missing_glyph_added = 0;
4185 for (i=0; i < num_ranges; ++i) {
4186 float fh = ranges[i].font_size;
4188 ranges[i].h_oversample = (
unsigned char) spc->h_oversample;
4189 ranges[i].v_oversample = (
unsigned char) spc->v_oversample;
4190 for (j=0; j < ranges[i].num_chars; ++j) {
4192 int32_t codepoint = ranges[i].array_of_unicode_codepoints ==
nullptr ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
4194 if (glyph == 0 && (spc->skip_missing || missing_glyph_added)) {
4195 rects[k].w = rects[k].h = 0;
4198 scale * spc->h_oversample,
4199 scale * spc->v_oversample,
4202 rects[k].w = (
stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1);
4203 rects[k].h = (
stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1);
4205 missing_glyph_added = 1;
4214void stbtt_MakeGlyphBitmapSubpixelPrefilter(
const stbtt_fontinfo *info,
unsigned char *output,
int32_t out_w,
int32_t out_h,
int32_t out_stride,
float scale_x,
float scale_y,
float shift_x,
float shift_y,
int32_t prefilter_x,
int32_t prefilter_y,
float *sub_x,
float *sub_y,
int32_t glyph)
4218 out_w - (prefilter_x - 1),
4219 out_h - (prefilter_y - 1),
4227 if (prefilter_x > 1)
4230 if (prefilter_y > 1)
4240 int32_t i,j,k, missing_glyph = -1, return_value = 1;
4243 int32_t old_h_over = spc->h_oversample;
4244 int32_t old_v_over = spc->v_oversample;
4247 for (i=0; i < num_ranges; ++i) {
4248 float fh = ranges[i].font_size;
4250 float recip_h,recip_v,sub_x,sub_y;
4251 spc->h_oversample = ranges[i].h_oversample;
4252 spc->v_oversample = ranges[i].v_oversample;
4253 recip_h = 1.0f / spc->h_oversample;
4254 recip_v = 1.0f / spc->v_oversample;
4257 for (j=0; j < ranges[i].num_chars; ++j) {
4261 int32_t advance, lsb, x0,y0,x1,y1;
4262 int32_t codepoint = ranges[i].array_of_unicode_codepoints ==
nullptr ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
4273 scale * spc->h_oversample,
4274 scale * spc->v_oversample,
4277 spc->pixels + r->
x + r->
y*spc->stride_in_bytes,
4278 r->
w - spc->h_oversample+1,
4279 r->
h - spc->v_oversample+1,
4280 spc->stride_in_bytes,
4281 scale * spc->h_oversample,
4282 scale * spc->v_oversample,
4286 if (spc->h_oversample > 1)
4288 r->
w, r->
h, spc->stride_in_bytes,
4291 if (spc->v_oversample > 1)
4293 r->
w, r->
h, spc->stride_in_bytes,
4301 bc->
xoff = (float) x0 * recip_h + sub_x;
4302 bc->
yoff = (float) y0 * recip_v + sub_y;
4303 bc->
xoff2 = (x0 + r->
w) * recip_h + sub_x;
4304 bc->
yoff2 = (y0 + r->
h) * recip_v + sub_y;
4308 }
else if (spc->skip_missing) {
4310 }
else if (r->
was_packed && r->
w == 0 && r->
h == 0 && missing_glyph >= 0) {
4311 ranges[i].chardata_for_range[j] = ranges[i].chardata_for_range[missing_glyph];
4321 spc->h_oversample = old_h_over;
4322 spc->v_oversample = old_v_over;
4324 return return_value;
4335 int32_t i,j,n, return_value = 1;
4340 for (i=0; i < num_ranges; ++i)
4341 for (j=0; j < ranges[i].num_chars; ++j)
4342 ranges[i].chardata_for_range[j].x0 =
4343 ranges[i].chardata_for_range[j].y0 =
4344 ranges[i].chardata_for_range[j].x1 =
4345 ranges[i].chardata_for_range[j].y1 = 0;
4348 for (i=0; i < num_ranges; ++i)
4349 n += ranges[i].num_chars;
4352 if (rects ==
nullptr)
4355 info.
userdata = spc->user_allocator_context;
4364 STBTT_free(rects, spc->user_allocator_context);
4365 return return_value;
4382 int32_t i_ascent, i_descent, i_lineGap;
4388 *ascent = (float) i_ascent *
scale;
4389 *descent = (float) i_descent *
scale;
4390 *lineGap = (float) i_lineGap *
scale;
4395 float ipw = 1.0f / pw, iph = 1.0f / ph;
4398 if (align_to_integer) {
4406 q->x0 = *xpos + b->
xoff;
4407 q->y0 = *ypos + b->
yoff;
4408 q->x1 = *xpos + b->
xoff2;
4409 q->y1 = *ypos + b->
yoff2;
4412 q->s0 = b->
x0 * ipw;
4413 q->t0 = b->
y0 * iph;
4414 q->s1 = b->
x1 * ipw;
4415 q->t1 = b->
y1 * iph;
4425#define STBTT_min(a,b) ((a) < (b) ? (a) : (b))
4426#define STBTT_max(a,b) ((a) < (b) ? (b) : (a))
4430 float q0perp = q0[1]*ray[0] - q0[0]*ray[1];
4431 float q1perp = q1[1]*ray[0] - q1[0]*ray[1];
4432 float q2perp = q2[1]*ray[0] - q2[0]*ray[1];
4433 float roperp = orig[1]*ray[0] - orig[0]*ray[1];
4435 float a = q0perp - 2*q1perp + q2perp;
4436 float b = q1perp - q0perp;
4437 float c = q0perp - roperp;
4439 float s0 = 0., s1 = 0.;
4443 float discr = b*b - a*c;
4445 float rcpna = -1 / a;
4449 if (s0 >= 0.0 && s0 <= 1.0)
4451 if (d > 0.0 && s1 >= 0.0 && s1 <= 1.0) {
4452 if (num_s == 0) s0 = s1;
4460 if (s0 >= 0.0 && s0 <= 1.0)
4467 float rcp_len2 = 1 / (ray[0]*ray[0] + ray[1]*ray[1]);
4468 float rayn_x = ray[0] * rcp_len2, rayn_y = ray[1] * rcp_len2;
4470 float q0d = q0[0]*rayn_x + q0[1]*rayn_y;
4471 float q1d = q1[0]*rayn_x + q1[1]*rayn_y;
4472 float q2d = q2[0]*rayn_x + q2[1]*rayn_y;
4473 float rod = orig[0]*rayn_x + orig[1]*rayn_y;
4475 float q10d = q1d - q0d;
4476 float q20d = q2d - q0d;
4477 float q0rd = q0d - rod;
4479 hits[0][0] = q0rd + s0*(2.0f - 2.0f*s0)*q10d + s0*s0*q20d;
4480 hits[0][1] = a*s0+b;
4483 hits[1][0] = q0rd + s1*(2.0f - 2.0f*s1)*q10d + s1*s1*q20d;
4484 hits[1][1] = a*s1+b;
4494 return (a[0] == b[0] && a[1] == b[1]);
4500 float orig[2], ray[2] = { 1, 0 };
4508 else if (y_frac > 0.99f)
4515 for (i=0; i < nverts; ++i) {
4517 int32_t x0 = (int) verts[i-1].
x, y0 = (
int) verts[i-1].y;
4518 int32_t x1 = (int) verts[i ].
x, y1 = (
int) verts[i ].y;
4520 float x_inter = (
y - y0) / (y1 - y0) * (x1-x0) + x0;
4522 winding += (y0 < y1) ? 1 : -1;
4526 int32_t x0 = (int) verts[i-1].
x , y0 = (
int) verts[i-1].y ;
4527 int32_t x1 = (int) verts[i ].cx, y1 = (
int) verts[i ].cy;
4528 int32_t x2 = (int) verts[i ].
x , y2 = (
int) verts[i ].y ;
4532 float q0[2],q1[2],q2[2];
4541 x0 = (int)verts[i-1].
x;
4542 y0 = (int)verts[i-1].
y;
4543 x1 = (int)verts[i ].
x;
4544 y1 = (int)verts[i ].
y;
4546 float x_inter = (
y - y0) / (y1 - y0) * (x1-x0) + x0;
4548 winding += (y0 < y1) ? 1 : -1;
4554 winding += (hits[0][1] < 0 ? -1 : 1);
4557 winding += (hits[1][1] < 0 ? -1 : 1);
4577 float p = b - a*a / 3;
4578 float q = a * (2*a*a - 9*b) / 27 + c;
4580 float d = q*q + 4*p3 / 27;
4583 float u = (-q +
z) / 2;
4584 float v = (-q -
z) / 2;
4593 float n = (float)
STBTT_cos(v-3.141592/2)*1.732050808f;
4594 r[0] = s + u * 2 * m;
4595 r[1] = s - u * (m + n);
4596 r[2] = s - u * (m - n);
4610 unsigned char *data;
4612 if (
scale == 0)
return nullptr;
4617 if (ix0 == ix1 || iy0 == iy1)
4630 if (xoff ) *xoff = ix0;
4631 if (yoff ) *yoff = iy0;
4638 const float eps = 1./1024, eps2 = eps*eps;
4643 data = (
unsigned char *)
STBTT_malloc(w * h, info->userdata);
4644 precompute = (
float *)
STBTT_malloc(num_verts *
sizeof(
float), info->userdata);
4646 for (i=0,j=num_verts-1; i < num_verts; j=i++) {
4650 float dist = (float)
STBTT_sqrt((x1-x0)*(x1-x0) + (y1-y0)*(y1-y0));
4651 precompute[i] = (dist < eps) ? 0.0f : 1.0f / dist;
4656 float bx = x0 - 2*x1 + x2, by = y0 - 2*y1 + y2;
4657 float len2 = bx*bx + by*by;
4659 precompute[i] = 1.0f / len2;
4661 precompute[i] = 0.0f;
4663 precompute[i] = 0.0f;
4666 for (
y=iy0;
y < iy1; ++
y) {
4667 for (
x=ix0;
x < ix1; ++
x) {
4669 float min_dist = 999999.0f;
4670 float sx = (float)
x + 0.5f;
4671 float sy = (float)
y + 0.5f;
4672 float x_gspace = (sx /
scale_x);
4673 float y_gspace = (sy /
scale_y);
4677 for (i=0; i < num_verts; ++i) {
4683 float dist,dist2 = (x0-sx)*(x0-sx) + (y0-sy)*(y0-sy);
4684 if (dist2 < min_dist*min_dist)
4690 dist = (float)
STBTT_fabs((x1-x0)*(y0-sy) - (y1-y0)*(x0-sx)) * precompute[i];
4692 if (dist < min_dist) {
4696 float dx = x1-x0, dy = y1-y0;
4697 float px = x0-sx, py = y0-sy;
4700 float t = -(px*dx + py*dy) / (dx*dx + dy*dy);
4701 if (
t >= 0.0f &&
t <= 1.0f)
4712 if (sx > box_x0-min_dist && sx < box_x1+min_dist && sy > box_y0-min_dist && sy < box_y1+min_dist) {
4714 float ax = x1-x0, ay = y1-y0;
4715 float bx = x0 - 2*x1 + x2, by = y0 - 2*y1 + y2;
4716 float mx = x0 - sx, my = y0 - sy;
4717 float res[3] = {0.f,0.f,0.f};
4718 float px,py,
t,it,dist2;
4719 float a_inv = precompute[i];
4721 float a = 3*(ax*bx + ay*by);
4722 float b = 2*(ax*ax + ay*ay) + (mx*bx+my*by);
4723 float c = mx*ax+my*ay;
4729 float discriminant = b*b - 4*a*c;
4730 if (discriminant < 0)
4733 float root = (float)
STBTT_sqrt(discriminant);
4734 res[0] = (-b - root)/(2*a);
4735 res[1] = (-b + root)/(2*a);
4740 float b = 3*(ax*bx + ay*by) * a_inv;
4741 float c = (2*(ax*ax + ay*ay) + (mx*bx+my*by)) * a_inv;
4742 float d = (mx*ax+my*ay) * a_inv;
4745 dist2 = (x0-sx)*(x0-sx) + (y0-sy)*(y0-sy);
4746 if (dist2 < min_dist*min_dist)
4749 if (num >= 1 && res[0] >= 0.0f && res[0] <= 1.0f) {
4750 t = res[0], it = 1.0f -
t;
4751 px = it*it*x0 + 2*
t*it*x1 +
t*
t*x2;
4752 py = it*it*y0 + 2*
t*it*y1 +
t*
t*y2;
4753 dist2 = (px-sx)*(px-sx) + (py-sy)*(py-sy);
4754 if (dist2 < min_dist * min_dist)
4757 if (num >= 2 && res[1] >= 0.0f && res[1] <= 1.0f) {
4758 t = res[1], it = 1.0f -
t;
4759 px = it*it*x0 + 2*
t*it*x1 +
t*
t*x2;
4760 py = it*it*y0 + 2*
t*it*y1 +
t*
t*y2;
4761 dist2 = (px-sx)*(px-sx) + (py-sy)*(py-sy);
4762 if (dist2 < min_dist * min_dist)
4765 if (num >= 3 && res[2] >= 0.0f && res[2] <= 1.0f) {
4766 t = res[2], it = 1.0f -
t;
4767 px = it*it*x0 + 2*
t*it*x1 +
t*
t*x2;
4768 py = it*it*y0 + 2*
t*it*y1 +
t*
t*y2;
4769 dist2 = (px-sx)*(px-sx) + (py-sy)*(py-sy);
4770 if (dist2 < min_dist * min_dist)
4777 min_dist = -min_dist;
4778 val = onedge_value + pixel_dist_scale * min_dist;
4783 data[(
y-iy0)*w+(
x-ix0)] = (
unsigned char) val;
4794 return stbtt_GetGlyphSDF(info,
scale,
stbtt_FindGlyphIndex(info, codepoint), padding, onedge_value, pixel_dist_scale,
width,
height, xoff, yoff);
4816 if (i >= len1)
return -1;
4817 if (s1[i++] != ch)
return -1;
4818 }
else if (ch < 0x800) {
4819 if (i+1 >= len1)
return -1;
4820 if (s1[i++] != 0xc0 + (ch >> 6))
return -1;
4821 if (s1[i++] != 0x80 + (ch & 0x3f))
return -1;
4822 }
else if (ch >= 0xd800 && ch < 0xdc00) {
4825 if (i+3 >= len1)
return -1;
4826 c = ((ch - 0xd800) << 10) + (ch2 - 0xdc00) + 0x10000;
4827 if (s1[i++] != 0xf0 + (c >> 18))
return -1;
4828 if (s1[i++] != 0x80 + ((c >> 12) & 0x3f))
return -1;
4829 if (s1[i++] != 0x80 + ((c >> 6) & 0x3f))
return -1;
4830 if (s1[i++] != 0x80 + ((c ) & 0x3f))
return -1;
4833 }
else if (ch >= 0xdc00 && ch < 0xe000) {
4836 if (i+2 >= len1)
return -1;
4837 if (s1[i++] != 0xe0 + (ch >> 12))
return -1;
4838 if (s1[i++] != 0x80 + ((ch >> 6) & 0x3f))
return -1;
4839 if (s1[i++] != 0x80 + ((ch ) & 0x3f))
return -1;
4860 if (!nm)
return nullptr;
4863 stringOffset = nm +
ttUSHORT(fc+nm+4);
4864 for (i=0; i < count; ++i) {
4869 return (
const char *) (fc+stringOffset+
ttUSHORT(fc+loc+10));
4881 for (i=0; i < count; ++i) {
4884 if (
id == target_id) {
4889 if (platform == 0 || (platform == 3 && encoding == 1) || (platform == 3 && encoding == 10)) {
4895 if (matchlen >= 0) {
4897 if (i+1 < count &&
ttUSHORT(fc+loc+12+6) == next_id &&
ttUSHORT(fc+loc+12) == platform &&
ttUSHORT(fc+loc+12+2) == encoding &&
ttUSHORT(fc+loc+12+4) == language) {
4901 if (matchlen == nlen)
4903 }
else if (matchlen < nlen && name[matchlen] ==
' ') {
4910 if (matchlen == nlen)
4931 if ((
ttUSHORT(fc+hd+44) & 7) != (flags & 7))
return 0;
4956 if (off < 0)
return off;
4962#if defined(__GNUC__) || defined(__clang__)
4963#pragma GCC diagnostic push
4964#pragma GCC diagnostic ignored "-Wcast-qual"
4968 float pixel_height,
unsigned char *pixels,
int32_t pw,
int32_t ph,
4999#if defined(__GNUC__) || defined(__clang__)
5000#pragma GCC diagnostic pop
uint32_t scale_y[NUM_LAYERS]
uint32_t scale_x[NUM_LAYERS]
fl::UISlider scale("Scale", 4,.1, 4,.1)
fl::UISlider length("Length", 1.0f, 0.0f, 1.0f, 0.01f)
fl::UISlider offset("Offset", 0.0f, 0.0f, 1.0f, 0.01f)
static int32_t stbtt_CompareUTF8toUTF16_bigendian_internal(char *s1, int32_t len1, char *s2, int32_t len2) FL_NOEXCEPT
void stbtt_MakeGlyphBitmapSubpixelPrefilter(const stbtt_fontinfo *info, unsigned char *output, int32_t out_w, int32_t out_h, int32_t out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int32_t oversample_x, int32_t oversample_y, float *sub_x, float *sub_y, int32_t glyph) FL_NOEXCEPT
static void stbtt__hheap_cleanup(stbtt__hheap *hh, void *userdata) FL_NOEXCEPT
static void stbtt__rasterize(stbtt__bitmap *result, stbtt__point *pts, int32_t *wcount, int32_t windings, float scale_x, float scale_y, float shift_x, float shift_y, int32_t off_x, int32_t off_y, int32_t invert, void *userdata) FL_NOEXCEPT
static void stbtt__csctx_v(stbtt__csctx *c, stbtt_uint8 type, stbtt_int32 x, stbtt_int32 y, stbtt_int32 cx, stbtt_int32 cy, stbtt_int32 cx1, stbtt_int32 cy1) FL_NOEXCEPT
int32_t stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int32_t glyph1, int32_t glyph2) FL_NOEXCEPT
static stbtt__buf stbtt__cff_get_index(stbtt__buf *b) FL_NOEXCEPT
unsigned char * stbtt_FindSVGDoc(const stbtt_fontinfo *info, int32_t gl) FL_NOEXCEPT
void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int32_t codepoint, int32_t *advanceWidth, int32_t *leftSideBearing) FL_NOEXCEPT
int32_t stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int32_t ch1, int32_t ch2) FL_NOEXCEPT
float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float pixels) FL_NOEXCEPT
unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float scale, int32_t glyph, int32_t padding, unsigned char onedge_value, float pixel_dist_scale, int32_t *width, int32_t *height, int32_t *xoff, int32_t *yoff) FL_NOEXCEPT
static int32_t stbtt__matches(stbtt_uint8 *fc, stbtt_uint32 offset, stbtt_uint8 *name, stbtt_int32 flags) FL_NOEXCEPT
static stbtt__buf stbtt__get_subr(stbtt__buf idx, int32_t n) FL_NOEXCEPT
static void stbtt__buf_seek(stbtt__buf *b, int32_t o) FL_NOEXCEPT
void stbtt_PackEnd(stbtt_pack_context *spc) FL_NOEXCEPT
unsigned char stbtt_uint8
static int32_t stbtt__close_shape(stbtt_vertex *vertices, int32_t num_vertices, int32_t was_off, int32_t start_off, stbtt_int32 sx, stbtt_int32 sy, stbtt_int32 scx, stbtt_int32 scy, stbtt_int32 cx, stbtt_int32 cy) FL_NOEXCEPT
static stbtt_uint32 stbtt__cff_int(stbtt__buf *b) FL_NOEXCEPT
void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int32_t codepoint, float scale_x, float scale_y, float shift_x, float shift_y, int32_t *ix0, int32_t *iy0, int32_t *ix1, int32_t *iy1) FL_NOEXCEPT
static void stbtt__track_vertex(stbtt__csctx *c, stbtt_int32 x, stbtt_int32 y) FL_NOEXCEPT
static stbtt__buf stbtt__cff_index_get(stbtt__buf b, int32_t i) FL_NOEXCEPT
char stbtt__check_size16[sizeof(stbtt_int16)==2 ? 1 :-1]
static stbtt__buf stbtt__new_buf(const void *p, size_t size) FL_NOEXCEPT
void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int32_t num_verts, float scale_x, float scale_y, float shift_x, float shift_y, int32_t x_off, int32_t y_off, int32_t invert, void *userdata) FL_NOEXCEPT
static void stbtt__csctx_close_shape(stbtt__csctx *ctx) FL_NOEXCEPT
static void stbtt__csctx_rccurve_to(stbtt__csctx *ctx, float dx1, float dy1, float dx2, float dy2, float dx3, float dy3) FL_NOEXCEPT
void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int32_t *x0, int32_t *y0, int32_t *x1, int32_t *y1) FL_NOEXCEPT
unsigned char * stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int32_t codepoint, int32_t *width, int32_t *height, int32_t *xoff, int32_t *yoff) FL_NOEXCEPT
void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int32_t out_w, int32_t out_h, int32_t out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int32_t codepoint) FL_NOEXCEPT
static void stbtt__v_prefilter(unsigned char *pixels, int32_t w, int32_t h, int32_t stride_in_bytes, uint32_t kernel_width) FL_NOEXCEPT
void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int32_t glyph, float scale_x, float scale_y, int32_t *ix0, int32_t *iy0, int32_t *ix1, int32_t *iy1) FL_NOEXCEPT
static void stbtt__add_point(stbtt__point *points, int32_t n, float x, float y) FL_NOEXCEPT
void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices) FL_NOEXCEPT
static stbtt_int16 ttSHORT(stbtt_uint8 *p) FL_NOEXCEPT
int32_t stbtt_GetFontVMetricsOS2(const stbtt_fontinfo *info, int32_t *typoAscent, int32_t *typoDescent, int32_t *typoLineGap) FL_NOEXCEPT
static int32_t stbtt__compute_crossings_x(float x, float y, int32_t nverts, stbtt_vertex *verts) FL_NOEXCEPT
static int32_t stbtt__tesselate_curve(stbtt__point *points, int32_t *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float objspace_flatness_squared, int32_t n) FL_NOEXCEPT
struct fl::third_party::truetype::stbtt__edge stbtt__edge
static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo *info, int32_t glyph1, int32_t glyph2) FL_NOEXCEPT
static void stbrp_init_target(stbrp_context *con, int32_t pw, int32_t ph, stbrp_node *nodes, int32_t num_nodes) FL_NOEXCEPT
int32_t stbtt_GetCodepointSVG(const stbtt_fontinfo *info, int32_t unicode_codepoint, const char **svg) FL_NOEXCEPT
static void stbtt__sort_edges_ins_sort(stbtt__edge *p, int32_t n) FL_NOEXCEPT
static int32_t stbtt_GetNumberOfFonts_internal(unsigned char *font_collection) FL_NOEXCEPT
static stbtt__buf stbtt__cid_get_glyph_subrs(const stbtt_fontinfo *info, int32_t glyph_index) FL_NOEXCEPT
void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect *rects, int32_t num_rects) FL_NOEXCEPT
void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int32_t pw, int32_t ph, int32_t char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int32_t align_to_integer) FL_NOEXCEPT
static int32_t stbtt__GetGlyphKernInfoAdvance(const stbtt_fontinfo *info, int32_t glyph1, int32_t glyph2) FL_NOEXCEPT
static int32_t equal(float *a, float *b) FL_NOEXCEPT
int32_t stbtt_BakeFontBitmap(const unsigned char *data, int32_t offset, float pixel_height, unsigned char *pixels, int32_t pw, int32_t ph, int32_t first_char, int32_t num_chars, stbtt_bakedchar *chardata) FL_NOEXCEPT
void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int32_t *ascent, int32_t *descent, int32_t *lineGap) FL_NOEXCEPT
int32_t stbtt_GetCodepointShape(const stbtt_fontinfo *info, int32_t unicode_codepoint, stbtt_vertex **vertices) FL_NOEXCEPT
char stbtt__check_size32[sizeof(stbtt_int32)==4 ? 1 :-1]
static int32_t stbtt__GetGlyphShapeT2(const stbtt_fontinfo *info, int32_t glyph_index, stbtt_vertex **pvertices) FL_NOEXCEPT
static stbtt_int32 stbtt__GetGlyphClass(stbtt_uint8 *classDefTable, int32_t glyph) FL_NOEXCEPT
int32_t stbtt_FindMatchingFont(const unsigned char *fontdata, const char *name, int32_t flags) FL_NOEXCEPT
void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata) FL_NOEXCEPT
static int32_t stbtt_BakeFontBitmap_internal(unsigned char *data, int32_t offset, float pixel_height, unsigned char *pixels, int32_t pw, int32_t ph, int32_t first_char, int32_t num_chars, stbtt_bakedchar *chardata) FL_NOEXCEPT
static stbtt__buf stbtt__buf_range(const stbtt__buf *b, int32_t o, int32_t s) FL_NOEXCEPT
static void stbtt__h_prefilter(unsigned char *pixels, int32_t w, int32_t h, int32_t stride_in_bytes, uint32_t kernel_width) FL_NOEXCEPT
int32_t stbtt_PackFontRanges(stbtt_pack_context *spc, const unsigned char *fontdata, int32_t font_index, stbtt_pack_range *ranges, int32_t num_ranges) FL_NOEXCEPT
int32_t stbtt_GetKerningTableLength(const stbtt_fontinfo *info) FL_NOEXCEPT
int32_t stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int32_t num_ranges, stbrp_rect *rects) FL_NOEXCEPT
static void stbtt__cff_skip_operand(stbtt__buf *b) FL_NOEXCEPT
float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels) FL_NOEXCEPT
unsigned char * stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int32_t codepoint, int32_t *width, int32_t *height, int32_t *xoff, int32_t *yoff) FL_NOEXCEPT
static stbtt_int32 ttLONG(stbtt_uint8 *p) FL_NOEXCEPT
static void stbtt__buf_skip(stbtt__buf *b, int32_t o) FL_NOEXCEPT
static stbtt__buf stbtt__get_subrs(stbtt__buf cff, stbtt__buf fontdict) FL_NOEXCEPT
int32_t stbtt_GetKerningTable(const stbtt_fontinfo *info, stbtt_kerningentry *table, int32_t table_length) FL_NOEXCEPT
static stbtt__point * stbtt_FlattenCurves(stbtt_vertex *vertices, int32_t num_verts, float objspace_flatness, int32_t **contour_lengths, int32_t *num_contours, void *userdata) FL_NOEXCEPT
const char * stbtt_GetFontNameString(const stbtt_fontinfo *font, int32_t *length, int32_t platformID, int32_t encodingID, int32_t languageID, int32_t nameID) FL_NOEXCEPT
static stbtt_uint8 stbtt__buf_peek8(stbtt__buf *b) FL_NOEXCEPT
static int32_t stbtt__cff_index_count(stbtt__buf *b) FL_NOEXCEPT
static int32_t stbtt_GetFontOffsetForIndex_internal(unsigned char *font_collection, int32_t index) FL_NOEXCEPT
struct fl::third_party::truetype::stbtt__hheap_chunk stbtt__hheap_chunk
@ STBTT_MS_EID_UNICODE_BMP
@ STBTT_MS_EID_UNICODE_FULL
void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int32_t out_w, int32_t out_h, int32_t out_stride, float scale_x, float scale_y, int32_t glyph) FL_NOEXCEPT
static int32_t stbtt__GetGlyphShapeTT(const stbtt_fontinfo *info, int32_t glyph_index, stbtt_vertex **pvertices) FL_NOEXCEPT
static void stbtt__tesselate_cubic(stbtt__point *points, int32_t *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3, float objspace_flatness_squared, int32_t n) FL_NOEXCEPT
static int32_t stbtt__GetGlyphInfoT2(const stbtt_fontinfo *info, int32_t glyph_index, int32_t *x0, int32_t *y0, int32_t *x1, int32_t *y1) FL_NOEXCEPT
static stbtt__buf stbtt__dict_get(stbtt__buf *b, int32_t key) FL_NOEXCEPT
void stbtt_GetScaledFontVMetrics(const unsigned char *fontdata, int32_t index, float size, float *ascent, float *descent, float *lineGap) FL_NOEXCEPT
int32_t stbtt_PackFontRange(stbtt_pack_context *spc, const unsigned char *fontdata, int32_t font_index, float font_size, int32_t first_unicode_char_in_range, int32_t num_chars_in_range, stbtt_packedchar *chardata_for_range) FL_NOEXCEPT
unsigned char * stbtt_GetCodepointSDF(const stbtt_fontinfo *info, float scale, int32_t codepoint, int32_t padding, unsigned char onedge_value, float pixel_dist_scale, int32_t *width, int32_t *height, int32_t *xoff, int32_t *yoff) FL_NOEXCEPT
struct fl::third_party::truetype::stbtt__hheap stbtt__hheap
static int32_t stbtt__get_svg(stbtt_fontinfo *info) FL_NOEXCEPT
int32_t stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int32_t unicode_codepoint) FL_NOEXCEPT
static void stbtt__csctx_rline_to(stbtt__csctx *ctx, float dx, float dy) FL_NOEXCEPT
int32_t stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int32_t glyph_index) FL_NOEXCEPT
int32_t stbtt_GetNumberOfFonts(const unsigned char *data) FL_NOEXCEPT
static void * stbtt__hheap_alloc(stbtt__hheap *hh, size_t size, void *userdata) FL_NOEXCEPT
void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context *spc, int32_t skip) FL_NOEXCEPT
struct stbtt_pack_context stbtt_pack_context
@ STBTT_MAC_EID_CHINESE_TRAD
unsigned char * stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int32_t glyph, int32_t *width, int32_t *height, int32_t *xoff, int32_t *yoff) FL_NOEXCEPT
static stbtt_int32 stbtt__GetCoverageIndex(stbtt_uint8 *coverageTable, int32_t glyph) FL_NOEXCEPT
static int32_t stbtt_InitFont_internal(stbtt_fontinfo *info, unsigned char *data, int32_t fontstart) FL_NOEXCEPT
int32_t stbtt_GetGlyphBox(const stbtt_fontinfo *info, int32_t glyph_index, int32_t *x0, int32_t *y0, int32_t *x1, int32_t *y1) FL_NOEXCEPT
void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int32_t codepoint, float scale_x, float scale_y, int32_t *ix0, int32_t *iy0, int32_t *ix1, int32_t *iy1) FL_NOEXCEPT
@ STBTT_PLATFORM_ID_MICROSOFT
@ STBTT_PLATFORM_ID_UNICODE
int32_t stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE &(STBTT_MAX_OVERSAMPLE-1))==0 ? 1 :-1]
void stbtt_GetBakedQuad(const stbtt_bakedchar *chardata, int32_t pw, int32_t ph, int32_t char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int32_t opengl_fillrule) FL_NOEXCEPT
static int32_t stbtt__isfont(stbtt_uint8 *font) FL_NOEXCEPT
int32_t stbtt_GetGlyphShape(const stbtt_fontinfo *info, int32_t glyph_index, stbtt_vertex **vertices) FL_NOEXCEPT
void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int32_t glyph, float scale_x, float scale_y, float shift_x, float shift_y, int32_t *ix0, int32_t *iy0, int32_t *ix1, int32_t *iy1) FL_NOEXCEPT
void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int32_t glyph_index, int32_t *advanceWidth, int32_t *leftSideBearing) FL_NOEXCEPT
void stbtt_FreeSDF(unsigned char *bitmap, void *userdata) FL_NOEXCEPT
unsigned char * stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int32_t glyph, int32_t *width, int32_t *height, int32_t *xoff, int32_t *yoff) FL_NOEXCEPT
static void stbrp_pack_rects(stbrp_context *con, stbrp_rect *rects, int32_t num_rects) FL_NOEXCEPT
@ STBTT_UNICODE_EID_UNICODE_2_0_BMP
@ STBTT_UNICODE_EID_UNICODE_1_0
@ STBTT_UNICODE_EID_UNICODE_2_0_FULL
@ STBTT_UNICODE_EID_UNICODE_1_1
@ STBTT_UNICODE_EID_ISO_10646
struct fl::third_party::truetype::stbtt__active_edge stbtt__active_edge
static int32_t stbtt__solve_cubic(float a, float b, float c, float *r) FL_NOEXCEPT
static void stbtt__hheap_free(stbtt__hheap *hh, void *p) FL_NOEXCEPT
static float stbtt__oversample_shift(int32_t oversample) FL_NOEXCEPT
int32_t stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int32_t num_ranges, stbrp_rect *rects) FL_NOEXCEPT
struct fl::third_party::truetype::stbtt_kerningentry stbtt_kerningentry
@ STBTT_MAC_LANG_JAPANESE
@ STBTT_MAC_LANG_CHINESE_TRAD
@ STBTT_MAC_LANG_CHINESE_SIMPLIFIED
static int32_t stbtt__matchpair(stbtt_uint8 *fc, stbtt_uint32 nm, stbtt_uint8 *name, stbtt_int32 nlen, stbtt_int32 target_id, stbtt_int32 next_id) FL_NOEXCEPT
static stbtt_uint32 ttULONG(stbtt_uint8 *p) FL_NOEXCEPT
void stbtt_MakeCodepointBitmapSubpixelPrefilter(const stbtt_fontinfo *info, unsigned char *output, int32_t out_w, int32_t out_h, int32_t out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int32_t oversample_x, int32_t oversample_y, float *sub_x, float *sub_y, int32_t codepoint) FL_NOEXCEPT
static void stbtt_setvertex(stbtt_vertex *v, stbtt_uint8 type, stbtt_int32 x, stbtt_int32 y, stbtt_int32 cx, stbtt_int32 cy) FL_NOEXCEPT
static void stbtt__sort_edges(stbtt__edge *p, int32_t n) FL_NOEXCEPT
struct stbtt_fontinfo stbtt_fontinfo
int32_t stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int32_t width, int32_t height, int32_t stride_in_bytes, int32_t padding, void *alloc_context) FL_NOEXCEPT
static int32_t stbtt__run_charstring(const stbtt_fontinfo *info, int32_t glyph_index, stbtt__csctx *c) FL_NOEXCEPT
static stbtt_uint8 stbtt__buf_get8(stbtt__buf *b) FL_NOEXCEPT
int32_t stbtt_GetCodepointBox(const stbtt_fontinfo *info, int32_t codepoint, int32_t *x0, int32_t *y0, int32_t *x1, int32_t *y1) FL_NOEXCEPT
void stbtt_PackSetOversampling(stbtt_pack_context *spc, uint32_t h_oversample, uint32_t v_oversample) FL_NOEXCEPT
int32_t stbtt_GetGlyphSVG(const stbtt_fontinfo *info, int32_t gl, const char **svg) FL_NOEXCEPT
static stbtt_uint16 ttUSHORT(stbtt_uint8 *p) FL_NOEXCEPT
void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int32_t out_w, int32_t out_h, int32_t out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int32_t glyph) FL_NOEXCEPT
static float stbtt__cuberoot(float x) FL_NOEXCEPT
static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(stbtt_uint8 *s1, stbtt_int32 len1, stbtt_uint8 *s2, stbtt_int32 len2) FL_NOEXCEPT
static stbtt_uint32 stbtt__find_table(stbtt_uint8 *data, stbtt_uint32 fontstart, const char *tag) FL_NOEXCEPT
int32_t stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int32_t offset) FL_NOEXCEPT
int32_t stbtt_GetFontOffsetForIndex(const unsigned char *data, int32_t index) FL_NOEXCEPT
static void stbtt__sort_edges_quicksort(stbtt__edge *p, int32_t n) FL_NOEXCEPT
static int32_t stbtt__GetGlyfOffset(const stbtt_fontinfo *info, int32_t glyph_index) FL_NOEXCEPT
void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int32_t out_w, int32_t out_h, int32_t out_stride, float scale_x, float scale_y, int32_t codepoint) FL_NOEXCEPT
static int32_t stbtt__ray_intersect_bezier(float orig[2], float ray[2], float q0[2], float q1[2], float q2[2], float hits[2][2]) FL_NOEXCEPT
static int32_t stbtt_FindMatchingFont_internal(unsigned char *font_collection, char *name_utf8, stbtt_int32 flags) FL_NOEXCEPT
static void stbtt__dict_get_ints(stbtt__buf *b, int32_t key, int32_t outcount, stbtt_uint32 *out) FL_NOEXCEPT
unsigned short stbtt_uint16
static void stbtt__csctx_rmove_to(stbtt__csctx *ctx, float dx, float dy) FL_NOEXCEPT
int32_t stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int32_t len1, const char *s2, int32_t len2) FL_NOEXCEPT
static stbtt_uint32 stbtt__buf_get(stbtt__buf *b, int32_t n) FL_NOEXCEPT
struct stbtt__hheap_chunk * next
void * user_allocator_context
stbtt_packedchar * chardata_for_range
unsigned char h_oversample
struct stbtt__hheap_chunk * head
int32_t first_unicode_codepoint_in_range
int32_t * array_of_unicode_codepoints
struct stbtt__active_edge * next
unsigned char v_oversample
int32_t num_remaining_in_head_chunk
constexpr T * end(T(&array)[N]) FL_NOEXCEPT
constexpr enable_if< is_fixed_point< T >::value, T >::type floor(T x) FL_NOEXCEPT
float screen(float &a, float &b)
constexpr enable_if< is_fixed_point< T >::value, int >::type sign(T x) FL_NOEXCEPT
FILE * fopen(const char *path, const char *mode)
Open a file.
fl::size_t fread(void *buffer, fl::size_t size, fl::size_t count, FILE *file)
Read from file.
expected< T, E > result
Alias for expected (Rust-style naming)
constexpr enable_if< is_fixed_point< T >::value, T >::type step(T edge, T x) FL_NOEXCEPT
int atoi(const char *str)
fl::string format(const char *fmt)
Format with no arguments.
Base definition for an LED controller.
#define stbtt__buf_get16(b)
#define STBTT__NOTUSED(v)
#define STBTT_MAX_OVERSAMPLE
#define stbtt_tag4(p, c0, c1, c2, c3)
#define STBTT__COMPARE(a, b)
#define STBTT_malloc(x, u)
#define stbtt_tag(p, str)
#define STBTT_CFF_SIZE_LIMIT
#define stbtt__buf_get32(b)
#define stbtt_vertex_type
#define STBTT__CSCTX_INIT(bounds)