281 #define STB_TRUETYPE_IMPLEMENTATION // force following include to generate implementation
284 unsigned char ttf_buffer[1<<20];
285 unsigned char temp_bitmap[512*512];
290 void my_stbtt_initfont(
void)
292 fread(ttf_buffer, 1, 1<<20, fopen(
"c:/windows/fonts/times.ttf",
"rb"));
295 glGenTextures(1, &ftex);
296 glBindTexture(GL_TEXTURE_2D, ftex);
297 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 512,512, 0, GL_ALPHA, GL_UNSIGNED_BYTE, temp_bitmap);
299 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
302 void my_stbtt_print(
float x,
float y,
char *text)
305 glEnable(GL_TEXTURE_2D);
306 glBindTexture(GL_TEXTURE_2D, ftex);
309 if (*text >= 32 && *text < 128) {
312 glTexCoord2f(q.
s0,q.
t1); glVertex2f(q.
x0,q.
y0);
313 glTexCoord2f(q.
s1,q.
t1); glVertex2f(q.
x1,q.
y0);
314 glTexCoord2f(q.
s1,q.
t0); glVertex2f(q.
x1,q.
y1);
315 glTexCoord2f(q.
s0,q.
t0); glVertex2f(q.
x0,q.
y1);
330 #define STB_TRUETYPE_IMPLEMENTATION // force following include to generate implementation
333 char ttf_buffer[1<<25];
335 int main(
int argc,
char **argv)
338 unsigned char *bitmap;
339 int w,h,i,j,c = (argc > 1 ? atoi(argv[1]) :
'a'), s = (argc > 2 ? atoi(argv[2]) : 20);
341 fread(ttf_buffer, 1, 1<<25, fopen(argc > 3 ? argv[3] :
"c:/windows/fonts/arialbd.ttf",
"rb"));
346 for (j=0; j < h; ++j) {
347 for (i=0; i < w; ++i)
348 putchar(
" .:ioVM@"[bitmap[j*w+i]>>5]);
374 unsigned char screen[20][79];
376 int main(
int arg,
char **argv)
379 int i,j,ascent,baseline,ch=0;
381 char *text =
"Heljo World!";
383 fread(buffer, 1, 1000000, fopen(
"c:/windows/fonts/arialbd.ttf",
"rb"));
388 baseline = (
int) (ascent*scale);
391 int advance,lsb,x0,y0,x1,y1;
392 float x_shift = xpos - (float) floor(xpos);
400 xpos += (advance * scale);
406 for (j=0; j < 20; ++j) {
407 for (i=0; i < 78; ++i)
408 putchar(
" .:ioVM@"[screen[j][i]>>5]);
426 #ifdef STB_TRUETYPE_IMPLEMENTATION
429 typedef unsigned char stbtt_uint8;
430 typedef signed char stbtt_int8;
431 typedef unsigned short stbtt_uint16;
432 typedef signed short stbtt_int16;
433 typedef unsigned int stbtt_uint32;
434 typedef signed int stbtt_int32;
437 typedef char stbtt__check_size32[
sizeof(stbtt_int32)==4 ? 1 : -1];
438 typedef char stbtt__check_size16[
sizeof(stbtt_int16)==2 ? 1 : -1];
443 #define STBTT_ifloor(x) ((int) floor(x))
444 #define STBTT_iceil(x) ((int) ceil(x))
449 #define STBTT_sqrt(x) sqrt(x)
450 #define STBTT_pow(x,y) pow(x,y)
455 #define STBTT_fmod(x,y) fmod(x,y)
460 #define STBTT_cos(x) cos(x)
461 #define STBTT_acos(x) acos(x)
466 #define STBTT_fabs(x) fabs(x)
472 #define STBTT_malloc(x,u) ((void)(u),malloc(x))
473 #define STBTT_free(x,u) ((void)(u),free(x))
478 #define STBTT_assert(x) assert(x)
483 #define STBTT_strlen(x) strlen(x)
488 #define STBTT_memcpy memcpy
489 #define STBTT_memset memset
500 #ifndef __STB_INCLUDE_STB_TRUETYPE_H__
501 #define __STB_INCLUDE_STB_TRUETYPE_H__
504 #define STBTT_DEF static
506 #define STBTT_DEF extern
530 unsigned short x0,y0,x1,y1;
531 float xoff,yoff,xadvance;
536 unsigned char *pixels,
int pw,
int ph,
537 int first_char,
int num_chars,
552 float *xpos,
float *ypos,
554 int opengl_fillrule);
578 unsigned short x0,y0,x1,y1;
579 float xoff,yoff,xadvance;
585 #ifndef STB_RECT_PACK_VERSION
603 #define STBTT_POINT_SIZE(x) (-(x))
606 int first_unicode_char_in_range,
int num_chars_in_range,
stbtt_packedchar *chardata_for_range);
623 int first_unicode_codepoint_in_range;
624 int *array_of_unicode_codepoints;
627 unsigned char h_oversample, v_oversample;
660 float *xpos,
float *ypos,
662 int align_to_integer);
717 unsigned char *
data;
812 #ifndef STBTT_vmove // you can predefine these to use different values (but why?)
821 #ifndef stbtt_vertex // you can predefine this to use different values
823 #define stbtt_vertex_type short // can't use stbtt_int16 because that's not visible in the header file
827 unsigned char type,padding;
880 STBTT_DEF void stbtt_MakeCodepointBitmapSubpixelPrefilter(
const stbtt_fontinfo *info,
unsigned char *output,
int out_w,
int out_h,
int out_stride,
float scale_x,
float scale_y,
float shift_x,
float shift_y,
int oversample_x,
int oversample_y,
float *sub_x,
float *sub_y,
int codepoint);
901 STBTT_DEF void stbtt_MakeGlyphBitmapSubpixelPrefilter(
const stbtt_fontinfo *info,
unsigned char *output,
int out_w,
int out_h,
int out_stride,
float scale_x,
float scale_y,
float shift_x,
float shift_y,
int oversample_x,
int oversample_y,
float *sub_x,
float *sub_y,
int glyph);
910 unsigned char *pixels;
915 float flatness_in_pixels,
918 float scale_x,
float scale_y,
919 float shift_x,
float shift_y,
920 int x_off,
int y_off,
931 STBTT_DEF unsigned char *
stbtt_GetGlyphSDF(
const stbtt_fontinfo *info,
float scale,
int glyph,
int padding,
unsigned char onedge_value,
float pixel_dist_scale,
int *width,
int *height,
int *xoff,
int *yoff);
932 STBTT_DEF unsigned char *
stbtt_GetCodepointSDF(
const stbtt_fontinfo *info,
float scale,
int codepoint,
int padding,
unsigned char onedge_value,
float pixel_dist_scale,
int *width,
int *height,
int *xoff,
int *yoff);
1009 #define STBTT_MACSTYLE_DONTCARE 0
1010 #define STBTT_MACSTYLE_BOLD 1
1011 #define STBTT_MACSTYLE_ITALIC 2
1012 #define STBTT_MACSTYLE_UNDERSCORE 4
1013 #define STBTT_MACSTYLE_NONE 8 // <= not same as 0, this makes us check the bitfield is 0
1080 #endif // __STB_INCLUDE_STB_TRUETYPE_H__
1089 #ifdef STB_TRUETYPE_IMPLEMENTATION
1091 #ifndef STBTT_MAX_OVERSAMPLE
1092 #define STBTT_MAX_OVERSAMPLE 8
1095 #if STBTT_MAX_OVERSAMPLE > 255
1096 #error "STBTT_MAX_OVERSAMPLE cannot be > 255"
1099 typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERSAMPLE-1)) == 0 ? 1 : -1];
1101 #ifndef STBTT_RASTERIZER_VERSION
1102 #define STBTT_RASTERIZER_VERSION 2
1106 #define STBTT__NOTUSED(v) (void)(v)
1108 #define STBTT__NOTUSED(v) (void)sizeof(v)
1116 static stbtt_uint8 stbtt__buf_get8(
stbtt__buf *b)
1123 static stbtt_uint8 stbtt__buf_peek8(
stbtt__buf *b)
1130 static void stbtt__buf_seek(
stbtt__buf *b,
int o)
1132 STBTT_assert(!(o > b->
size || o < 0));
1136 static void stbtt__buf_skip(
stbtt__buf *b,
int o)
1138 stbtt__buf_seek(b, b->
cursor + o);
1141 static stbtt_uint32 stbtt__buf_get(
stbtt__buf *b,
int n)
1145 STBTT_assert(n >= 1 && n <= 4);
1146 for (i = 0; i < n; i++)
1147 v = (v << 8) | stbtt__buf_get8(b);
1154 STBTT_assert(size < 0x40000000);
1155 r.
data = (stbtt_uint8*) p;
1161 #define stbtt__buf_get16(b) stbtt__buf_get((b), 2)
1162 #define stbtt__buf_get32(b) stbtt__buf_get((b), 4)
1167 if (o < 0 || s < 0 || o > b->
size || s > b->
size - o)
return r;
1175 int count, start, offsize;
1177 count = stbtt__buf_get16(b);
1179 offsize = stbtt__buf_get8(b);
1180 STBTT_assert(offsize >= 1 && offsize <= 4);
1181 stbtt__buf_skip(b, offsize * count);
1182 stbtt__buf_skip(b, stbtt__buf_get(b, offsize) - 1);
1184 return stbtt__buf_range(b, start, b->
cursor - start);
1187 static stbtt_uint32 stbtt__cff_int(
stbtt__buf *b)
1189 int b0 = stbtt__buf_get8(b);
1190 if (b0 >= 32 && b0 <= 246)
return b0 - 139;
1191 else if (b0 >= 247 && b0 <= 250)
return (b0 - 247)*256 + stbtt__buf_get8(b) + 108;
1192 else if (b0 >= 251 && b0 <= 254)
return -(b0 - 251)*256 - stbtt__buf_get8(b) - 108;
1193 else if (b0 == 28)
return stbtt__buf_get16(b);
1194 else if (b0 == 29)
return stbtt__buf_get32(b);
1199 static void stbtt__cff_skip_operand(
stbtt__buf *b) {
1200 int v, b0 = stbtt__buf_peek8(b);
1201 STBTT_assert(b0 >= 28);
1203 stbtt__buf_skip(b, 1);
1205 v = stbtt__buf_get8(b);
1206 if ((v & 0xF) == 0xF || (v >> 4) == 0xF)
1216 stbtt__buf_seek(b, 0);
1218 int start = b->
cursor, end, op;
1219 while (stbtt__buf_peek8(b) >= 28)
1220 stbtt__cff_skip_operand(b);
1222 op = stbtt__buf_get8(b);
1223 if (op == 12) op = stbtt__buf_get8(b) | 0x100;
1224 if (op == key)
return stbtt__buf_range(b, start, end-start);
1226 return stbtt__buf_range(b, 0, 0);
1229 static void stbtt__dict_get_ints(
stbtt__buf *b,
int key,
int outcount, stbtt_uint32 *out)
1232 stbtt__buf operands = stbtt__dict_get(b, key);
1233 for (i = 0; i < outcount && operands.
cursor < operands.
size; i++)
1234 out[i] = stbtt__cff_int(&operands);
1237 static int stbtt__cff_index_count(
stbtt__buf *b)
1239 stbtt__buf_seek(b, 0);
1240 return stbtt__buf_get16(b);
1245 int count, offsize, start, end;
1246 stbtt__buf_seek(&b, 0);
1247 count = stbtt__buf_get16(&b);
1248 offsize = stbtt__buf_get8(&b);
1249 STBTT_assert(i >= 0 && i < count);
1250 STBTT_assert(offsize >= 1 && offsize <= 4);
1251 stbtt__buf_skip(&b, i*offsize);
1252 start = stbtt__buf_get(&b, offsize);
1253 end = stbtt__buf_get(&b, offsize);
1254 return stbtt__buf_range(&b, 2+(count+1)*offsize+start, end - start);
1265 #define ttBYTE(p) (* (stbtt_uint8 *) (p))
1266 #define ttCHAR(p) (* (stbtt_int8 *) (p))
1267 #define ttFixed(p) ttLONG(p)
1269 static stbtt_uint16 ttUSHORT(stbtt_uint8 *p) {
return p[0]*256 + p[1]; }
1270 static stbtt_int16 ttSHORT(stbtt_uint8 *p) {
return p[0]*256 + p[1]; }
1271 static stbtt_uint32 ttULONG(stbtt_uint8 *p) {
return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; }
1272 static stbtt_int32 ttLONG(stbtt_uint8 *p) {
return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; }
1274 #define stbtt_tag4(p,c0,c1,c2,c3) ((p)[0] == (c0) && (p)[1] == (c1) && (p)[2] == (c2) && (p)[3] == (c3))
1275 #define stbtt_tag(p,str) stbtt_tag4(p,str[0],str[1],str[2],str[3])
1277 static int stbtt__isfont(stbtt_uint8 *font)
1280 if (stbtt_tag4(font,
'1',0,0,0))
return 1;
1281 if (stbtt_tag(font,
"typ1"))
return 1;
1282 if (stbtt_tag(font,
"OTTO"))
return 1;
1283 if (stbtt_tag4(font, 0,1,0,0))
return 1;
1284 if (stbtt_tag(font,
"true"))
return 1;
1289 static stbtt_uint32 stbtt__find_table(stbtt_uint8 *data, stbtt_uint32 fontstart,
const char *tag)
1291 stbtt_int32 num_tables = ttUSHORT(data+fontstart+4);
1292 stbtt_uint32 tabledir = fontstart + 12;
1294 for (i=0; i < num_tables; ++i) {
1295 stbtt_uint32 loc = tabledir + 16*i;
1296 if (stbtt_tag(data+loc+0, tag))
1297 return ttULONG(data+loc+8);
1302 static int stbtt_GetFontOffsetForIndex_internal(
unsigned char *font_collection,
int index)
1305 if (stbtt__isfont(font_collection))
1306 return index == 0 ? 0 : -1;
1309 if (stbtt_tag(font_collection,
"ttcf")) {
1311 if (ttULONG(font_collection+4) == 0x00010000 || ttULONG(font_collection+4) == 0x00020000) {
1312 stbtt_int32 n = ttLONG(font_collection+8);
1315 return ttULONG(font_collection+12+index*4);
1321 static int stbtt_GetNumberOfFonts_internal(
unsigned char *font_collection)
1324 if (stbtt__isfont(font_collection))
1328 if (stbtt_tag(font_collection,
"ttcf")) {
1330 if (ttULONG(font_collection+4) == 0x00010000 || ttULONG(font_collection+4) == 0x00020000) {
1331 return ttLONG(font_collection+8);
1339 stbtt_uint32 subrsoff = 0, private_loc[2] = { 0, 0 };
1341 stbtt__dict_get_ints(&fontdict, 18, 2, private_loc);
1342 if (!private_loc[1] || !private_loc[0])
return stbtt__new_buf(NULL, 0);
1343 pdict = stbtt__buf_range(&cff, private_loc[1], private_loc[0]);
1344 stbtt__dict_get_ints(&pdict, 19, 1, &subrsoff);
1345 if (!subrsoff)
return stbtt__new_buf(NULL, 0);
1346 stbtt__buf_seek(&cff, private_loc[1]+subrsoff);
1347 return stbtt__cff_get_index(&cff);
1350 static int stbtt_InitFont_internal(
stbtt_fontinfo *info,
unsigned char *data,
int fontstart)
1352 stbtt_uint32 cmap, t;
1353 stbtt_int32 i,numTables;
1357 info->
cff = stbtt__new_buf(NULL, 0);
1359 cmap = stbtt__find_table(data, fontstart,
"cmap");
1360 info->
loca = stbtt__find_table(data, fontstart,
"loca");
1361 info->
head = stbtt__find_table(data, fontstart,
"head");
1362 info->
glyf = stbtt__find_table(data, fontstart,
"glyf");
1363 info->
hhea = stbtt__find_table(data, fontstart,
"hhea");
1364 info->
hmtx = stbtt__find_table(data, fontstart,
"hmtx");
1365 info->
kern = stbtt__find_table(data, fontstart,
"kern");
1366 info->
gpos = stbtt__find_table(data, fontstart,
"GPOS");
1368 if (!cmap || !info->
head || !info->
hhea || !info->
hmtx)
1372 if (!info->
loca)
return 0;
1376 stbtt_uint32 cstype = 2, charstrings = 0, fdarrayoff = 0, fdselectoff = 0;
1379 cff = stbtt__find_table(data, fontstart,
"CFF ");
1382 info->
fontdicts = stbtt__new_buf(NULL, 0);
1383 info->
fdselect = stbtt__new_buf(NULL, 0);
1386 info->
cff = stbtt__new_buf(data+cff, 512*1024*1024);
1390 stbtt__buf_skip(&b, 2);
1391 stbtt__buf_seek(&b, stbtt__buf_get8(&b));
1395 stbtt__cff_get_index(&b);
1396 topdictidx = stbtt__cff_get_index(&b);
1397 topdict = stbtt__cff_index_get(topdictidx, 0);
1398 stbtt__cff_get_index(&b);
1399 info->
gsubrs = stbtt__cff_get_index(&b);
1401 stbtt__dict_get_ints(&topdict, 17, 1, &charstrings);
1402 stbtt__dict_get_ints(&topdict, 0x100 | 6, 1, &cstype);
1403 stbtt__dict_get_ints(&topdict, 0x100 | 36, 1, &fdarrayoff);
1404 stbtt__dict_get_ints(&topdict, 0x100 | 37, 1, &fdselectoff);
1405 info->
subrs = stbtt__get_subrs(b, topdict);
1408 if (cstype != 2)
return 0;
1409 if (charstrings == 0)
return 0;
1413 if (!fdselectoff)
return 0;
1414 stbtt__buf_seek(&b, fdarrayoff);
1415 info->
fontdicts = stbtt__cff_get_index(&b);
1416 info->
fdselect = stbtt__buf_range(&b, fdselectoff, b.
size-fdselectoff);
1419 stbtt__buf_seek(&b, charstrings);
1423 t = stbtt__find_table(data, fontstart,
"maxp");
1432 numTables = ttUSHORT(data + cmap + 2);
1434 for (i=0; i < numTables; ++i) {
1435 stbtt_uint32 encoding_record = cmap + 4 + 8 * i;
1437 switch(ttUSHORT(data+encoding_record)) {
1439 switch (ttUSHORT(data+encoding_record+2)) {
1443 info->
index_map = cmap + ttULONG(data+encoding_record+4);
1450 info->
index_map = cmap + ttULONG(data+encoding_record+4);
1463 stbtt_uint8 *data = info->
data;
1464 stbtt_uint32 index_map = info->
index_map;
1466 stbtt_uint16 format = ttUSHORT(data + index_map + 0);
1468 stbtt_int32 bytes = ttUSHORT(data + index_map + 2);
1469 if (unicode_codepoint < bytes-6)
1470 return ttBYTE(data + index_map + 6 + unicode_codepoint);
1472 }
else if (format == 6) {
1473 stbtt_uint32 first = ttUSHORT(data + index_map + 6);
1474 stbtt_uint32 count = ttUSHORT(data + index_map + 8);
1475 if ((stbtt_uint32) unicode_codepoint >= first && (stbtt_uint32) unicode_codepoint < first+count)
1476 return ttUSHORT(data + index_map + 10 + (unicode_codepoint - first)*2);
1478 }
else if (format == 2) {
1481 }
else if (format == 4) {
1482 stbtt_uint16 segcount = ttUSHORT(data+index_map+6) >> 1;
1483 stbtt_uint16 searchRange = ttUSHORT(data+index_map+8) >> 1;
1484 stbtt_uint16 entrySelector = ttUSHORT(data+index_map+10);
1485 stbtt_uint16 rangeShift = ttUSHORT(data+index_map+12) >> 1;
1488 stbtt_uint32 endCount = index_map + 14;
1489 stbtt_uint32 search = endCount;
1491 if (unicode_codepoint > 0xffff)
1496 if (unicode_codepoint >= ttUSHORT(data + search + rangeShift*2))
1497 search += rangeShift*2;
1501 while (entrySelector) {
1504 end = ttUSHORT(data + search + searchRange*2);
1505 if (unicode_codepoint > end)
1506 search += searchRange*2;
1512 stbtt_uint16
offset, start;
1513 stbtt_uint16 item = (stbtt_uint16) ((search - endCount) >> 1);
1515 STBTT_assert(unicode_codepoint <= ttUSHORT(data + endCount + 2*item));
1516 start = ttUSHORT(data + index_map + 14 + segcount*2 + 2 + 2*item);
1517 if (unicode_codepoint < start)
1520 offset = ttUSHORT(data + index_map + 14 + segcount*6 + 2 + 2*item);
1522 return (stbtt_uint16) (unicode_codepoint + ttSHORT(data + index_map + 14 + segcount*4 + 2 + 2*item));
1524 return ttUSHORT(data + offset + (unicode_codepoint-start)*2 + index_map + 14 + segcount*6 + 2 + 2*item);
1526 }
else if (format == 12 || format == 13) {
1527 stbtt_uint32 ngroups = ttULONG(data+index_map+12);
1528 stbtt_int32 low,high;
1529 low = 0; high = (stbtt_int32)ngroups;
1531 while (low < high) {
1532 stbtt_int32 mid = low + ((high-low) >> 1);
1533 stbtt_uint32 start_char = ttULONG(data+index_map+16+mid*12);
1534 stbtt_uint32 end_char = ttULONG(data+index_map+16+mid*12+4);
1535 if ((stbtt_uint32) unicode_codepoint < start_char)
1537 else if ((stbtt_uint32) unicode_codepoint > end_char)
1540 stbtt_uint32 start_glyph = ttULONG(data+index_map+16+mid*12+8);
1542 return start_glyph + unicode_codepoint-start_char;
1559 static void stbtt_setvertex(
stbtt_vertex *v, stbtt_uint8 type, stbtt_int32 x, stbtt_int32 y, stbtt_int32 cx, stbtt_int32 cy)
1562 v->
x = (stbtt_int16) x;
1563 v->
y = (stbtt_int16) y;
1564 v->
cx = (stbtt_int16) cx;
1565 v->
cy = (stbtt_int16) cy;
1568 static int stbtt__GetGlyfOffset(
const stbtt_fontinfo *info,
int glyph_index)
1572 STBTT_assert(!info->
cff.
size);
1574 if (glyph_index >= info->
numGlyphs)
return -1;
1578 g1 = info->
glyf + ttUSHORT(info->
data + info->
loca + glyph_index * 2) * 2;
1579 g2 = info->
glyf + ttUSHORT(info->
data + info->
loca + glyph_index * 2 + 2) * 2;
1581 g1 = info->
glyf + ttULONG (info->
data + info->
loca + glyph_index * 4);
1582 g2 = info->
glyf + ttULONG (info->
data + info->
loca + glyph_index * 4 + 4);
1585 return g1==g2 ? -1 : g1;
1588 static int stbtt__GetGlyphInfoT2(
const stbtt_fontinfo *info,
int glyph_index,
int *x0,
int *y0,
int *x1,
int *y1);
1593 stbtt__GetGlyphInfoT2(info, glyph_index, x0, y0, x1, y1);
1595 int g = stbtt__GetGlyfOffset(info, glyph_index);
1596 if (g < 0)
return 0;
1598 if (x0) *x0 = ttSHORT(info->
data + g + 2);
1599 if (y0) *y0 = ttSHORT(info->
data + g + 4);
1600 if (x1) *x1 = ttSHORT(info->
data + g + 6);
1601 if (y1) *y1 = ttSHORT(info->
data + g + 8);
1613 stbtt_int16 numberOfContours;
1616 return stbtt__GetGlyphInfoT2(info, glyph_index, NULL, NULL, NULL, NULL) == 0;
1617 g = stbtt__GetGlyfOffset(info, glyph_index);
1618 if (g < 0)
return 1;
1619 numberOfContours = ttSHORT(info->
data + g);
1620 return numberOfContours == 0;
1623 static int stbtt__close_shape(
stbtt_vertex *vertices,
int num_vertices,
int was_off,
int start_off,
1624 stbtt_int32 sx, stbtt_int32 sy, stbtt_int32 scx, stbtt_int32 scy, stbtt_int32 cx, stbtt_int32 cy)
1628 stbtt_setvertex(&vertices[num_vertices++],
STBTT_vcurve, (cx+scx)>>1, (cy+scy)>>1, cx,cy);
1629 stbtt_setvertex(&vertices[num_vertices++],
STBTT_vcurve, sx,sy,scx,scy);
1632 stbtt_setvertex(&vertices[num_vertices++],
STBTT_vcurve,sx,sy,cx,cy);
1634 stbtt_setvertex(&vertices[num_vertices++],
STBTT_vline,sx,sy,0,0);
1636 return num_vertices;
1641 stbtt_int16 numberOfContours;
1642 stbtt_uint8 *endPtsOfContours;
1643 stbtt_uint8 *data = info->
data;
1646 int g = stbtt__GetGlyfOffset(info, glyph_index);
1650 if (g < 0)
return 0;
1652 numberOfContours = ttSHORT(data + g);
1654 if (numberOfContours > 0) {
1655 stbtt_uint8 flags=0,flagcount;
1656 stbtt_int32 ins, i,j=0,m,n, next_move, was_off=0, off, start_off=0;
1657 stbtt_int32 x,y,cx,cy,sx,sy, scx,scy;
1658 stbtt_uint8 *points;
1659 endPtsOfContours = (data + g + 10);
1660 ins = ttUSHORT(data + g + 10 + numberOfContours * 2);
1661 points = data + g + 10 + numberOfContours * 2 + 2 + ins;
1663 n = 1+ttUSHORT(endPtsOfContours + numberOfContours*2-2);
1665 m = n + 2*numberOfContours;
1681 for (i=0; i < n; ++i) {
1682 if (flagcount == 0) {
1685 flagcount = *points++;
1688 vertices[off+i].
type = flags;
1693 for (i=0; i < n; ++i) {
1694 flags = vertices[off+i].
type;
1696 stbtt_int16 dx = *points++;
1697 x += (flags & 16) ? dx : -dx;
1699 if (!(flags & 16)) {
1700 x = x + (stbtt_int16) (points[0]*256 + points[1]);
1704 vertices[off+i].
x = (stbtt_int16) x;
1709 for (i=0; i < n; ++i) {
1710 flags = vertices[off+i].
type;
1712 stbtt_int16 dy = *points++;
1713 y += (flags & 32) ? dy : -dy;
1715 if (!(flags & 32)) {
1716 y = y + (stbtt_int16) (points[0]*256 + points[1]);
1720 vertices[off+i].
y = (stbtt_int16) y;
1725 sx = sy = cx = cy = scx = scy = 0;
1726 for (i=0; i < n; ++i) {
1727 flags = vertices[off+i].
type;
1728 x = (stbtt_int16) vertices[off+i].x;
1729 y = (stbtt_int16) vertices[off+i].y;
1731 if (next_move == i) {
1733 num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
1736 start_off = !(flags & 1);
1742 if (!(vertices[off+i+1].type & 1)) {
1744 sx = (x + (stbtt_int32) vertices[off+i+1].x) >> 1;
1745 sy = (y + (stbtt_int32) vertices[off+i+1].y) >> 1;
1748 sx = (stbtt_int32) vertices[off+i+1].x;
1749 sy = (stbtt_int32) vertices[off+i+1].y;
1756 stbtt_setvertex(&vertices[num_vertices++],
STBTT_vmove,sx,sy,0,0);
1758 next_move = 1 + ttUSHORT(endPtsOfContours+j*2);
1763 stbtt_setvertex(&vertices[num_vertices++],
STBTT_vcurve, (cx+x)>>1, (cy+y)>>1, cx, cy);
1769 stbtt_setvertex(&vertices[num_vertices++],
STBTT_vcurve, x,y, cx, cy);
1771 stbtt_setvertex(&vertices[num_vertices++],
STBTT_vline, x,y,0,0);
1776 num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
1777 }
else if (numberOfContours == -1) {
1780 stbtt_uint8 *comp = data + g + 10;
1784 stbtt_uint16 flags, gidx;
1785 int comp_num_verts = 0, i;
1787 float mtx[6] = {1,0,0,1,0,0}, m, n;
1789 flags = ttSHORT(comp); comp+=2;
1790 gidx = ttSHORT(comp); comp+=2;
1794 mtx[4] = ttSHORT(comp); comp+=2;
1795 mtx[5] = ttSHORT(comp); comp+=2;
1797 mtx[4] = ttCHAR(comp); comp+=1;
1798 mtx[5] = ttCHAR(comp); comp+=1;
1805 if (flags & (1<<3)) {
1806 mtx[0] = mtx[3] = ttSHORT(comp)/16384.0f; comp+=2;
1807 mtx[1] = mtx[2] = 0;
1808 }
else if (flags & (1<<6)) {
1809 mtx[0] = ttSHORT(comp)/16384.0f; comp+=2;
1810 mtx[1] = mtx[2] = 0;
1811 mtx[3] = ttSHORT(comp)/16384.0f; comp+=2;
1812 }
else if (flags & (1<<7)) {
1813 mtx[0] = ttSHORT(comp)/16384.0f; comp+=2;
1814 mtx[1] = ttSHORT(comp)/16384.0f; comp+=2;
1815 mtx[2] = ttSHORT(comp)/16384.0f; comp+=2;
1816 mtx[3] = ttSHORT(comp)/16384.0f; comp+=2;
1820 m = (float) STBTT_sqrt(mtx[0]*mtx[0] + mtx[1]*mtx[1]);
1821 n = (float) STBTT_sqrt(mtx[2]*mtx[2] + mtx[3]*mtx[3]);
1825 if (comp_num_verts > 0) {
1827 for (i = 0; i < comp_num_verts; ++i) {
1840 if (vertices) STBTT_free(vertices, info->
userdata);
1841 if (comp_verts) STBTT_free(comp_verts, info->
userdata);
1844 if (num_vertices > 0) STBTT_memcpy(tmp, vertices, num_vertices*
sizeof(
stbtt_vertex));
1845 STBTT_memcpy(tmp+num_vertices, comp_verts, comp_num_verts*
sizeof(
stbtt_vertex));
1846 if (vertices) STBTT_free(vertices, info->
userdata);
1848 STBTT_free(comp_verts, info->
userdata);
1849 num_vertices += comp_num_verts;
1852 more = flags & (1<<5);
1854 }
else if (numberOfContours < 0) {
1861 *pvertices = vertices;
1862 return num_vertices;
1869 float first_x, first_y;
1871 stbtt_int32 min_x, max_x, min_y, max_y;
1877 #define STBTT__CSCTX_INIT(bounds) {bounds,0, 0,0, 0,0, 0,0,0,0, NULL, 0}
1879 static void stbtt__track_vertex(stbtt__csctx *c, stbtt_int32 x, stbtt_int32 y)
1881 if (x > c->max_x || !c->started) c->max_x = x;
1882 if (y > c->max_y || !c->started) c->max_y = y;
1883 if (x < c->min_x || !c->started) c->min_x = x;
1884 if (y < c->min_y || !c->started) c->min_y = y;
1888 static void stbtt__csctx_v(stbtt__csctx *c, stbtt_uint8 type, stbtt_int32 x, stbtt_int32 y, stbtt_int32 cx, stbtt_int32 cy, stbtt_int32 cx1, stbtt_int32 cy1)
1891 stbtt__track_vertex(c, x, y);
1893 stbtt__track_vertex(c, cx, cy);
1894 stbtt__track_vertex(c, cx1, cy1);
1897 stbtt_setvertex(&c->pvertices[c->num_vertices], type, x, y, cx, cy);
1898 c->pvertices[c->num_vertices].cx1 = (stbtt_int16) cx1;
1899 c->pvertices[c->num_vertices].cy1 = (stbtt_int16) cy1;
1904 static void stbtt__csctx_close_shape(stbtt__csctx *ctx)
1906 if (ctx->first_x != ctx->x || ctx->first_y != ctx->y)
1907 stbtt__csctx_v(ctx,
STBTT_vline, (
int)ctx->first_x, (
int)ctx->first_y, 0, 0, 0, 0);
1910 static void stbtt__csctx_rmove_to(stbtt__csctx *ctx,
float dx,
float dy)
1912 stbtt__csctx_close_shape(ctx);
1913 ctx->first_x = ctx->x = ctx->x + dx;
1914 ctx->first_y = ctx->y = ctx->y + dy;
1915 stbtt__csctx_v(ctx,
STBTT_vmove, (
int)ctx->x, (
int)ctx->y, 0, 0, 0, 0);
1918 static void stbtt__csctx_rline_to(stbtt__csctx *ctx,
float dx,
float dy)
1922 stbtt__csctx_v(ctx,
STBTT_vline, (
int)ctx->x, (
int)ctx->y, 0, 0, 0, 0);
1925 static void stbtt__csctx_rccurve_to(stbtt__csctx *ctx,
float dx1,
float dy1,
float dx2,
float dy2,
float dx3,
float dy3)
1927 float cx1 = ctx->x + dx1;
1928 float cy1 = ctx->y + dy1;
1929 float cx2 = cx1 + dx2;
1930 float cy2 = cy1 + dy2;
1933 stbtt__csctx_v(ctx,
STBTT_vcubic, (
int)ctx->x, (
int)ctx->y, (
int)cx1, (
int)cy1, (
int)cx2, (
int)cy2);
1938 int count = stbtt__cff_index_count(&idx);
1942 else if (count >= 1240)
1945 if (n < 0 || n >= count)
1946 return stbtt__new_buf(NULL, 0);
1947 return stbtt__cff_index_get(idx, n);
1953 int nranges, start, end, v, fmt, fdselector = -1, i;
1955 stbtt__buf_seek(&fdselect, 0);
1956 fmt = stbtt__buf_get8(&fdselect);
1959 stbtt__buf_skip(&fdselect, glyph_index);
1960 fdselector = stbtt__buf_get8(&fdselect);
1961 }
else if (fmt == 3) {
1962 nranges = stbtt__buf_get16(&fdselect);
1963 start = stbtt__buf_get16(&fdselect);
1964 for (i = 0; i < nranges; i++) {
1965 v = stbtt__buf_get8(&fdselect);
1966 end = stbtt__buf_get16(&fdselect);
1967 if (glyph_index >= start && glyph_index < end) {
1974 if (fdselector == -1) stbtt__new_buf(NULL, 0);
1975 return stbtt__get_subrs(info->
cff, stbtt__cff_index_get(info->
fontdicts, fdselector));
1978 static int stbtt__run_charstring(
const stbtt_fontinfo *info,
int glyph_index, stbtt__csctx *c)
1980 int in_header = 1, maskbits = 0, subr_stack_height = 0, sp = 0, v, i, b0;
1981 int has_subrs = 0, clear_stack;
1986 #define STBTT__CSERR(s) (0)
1989 b = stbtt__cff_index_get(info->
charstrings, glyph_index);
1993 b0 = stbtt__buf_get8(&b);
1999 maskbits += (sp / 2);
2001 stbtt__buf_skip(&b, (maskbits + 7) / 8);
2008 maskbits += (sp / 2);
2013 if (sp < 2)
return STBTT__CSERR(
"rmoveto stack");
2014 stbtt__csctx_rmove_to(c, s[sp-2], s[sp-1]);
2018 if (sp < 1)
return STBTT__CSERR(
"vmoveto stack");
2019 stbtt__csctx_rmove_to(c, 0, s[sp-1]);
2023 if (sp < 1)
return STBTT__CSERR(
"hmoveto stack");
2024 stbtt__csctx_rmove_to(c, s[sp-1], 0);
2028 if (sp < 2)
return STBTT__CSERR(
"rlineto stack");
2029 for (; i + 1 < sp; i += 2)
2030 stbtt__csctx_rline_to(c, s[i], s[i+1]);
2037 if (sp < 1)
return STBTT__CSERR(
"vlineto stack");
2040 if (sp < 1)
return STBTT__CSERR(
"hlineto stack");
2043 stbtt__csctx_rline_to(c, s[i], 0);
2047 stbtt__csctx_rline_to(c, 0, s[i]);
2053 if (sp < 4)
return STBTT__CSERR(
"hvcurveto stack");
2056 if (sp < 4)
return STBTT__CSERR(
"vhcurveto stack");
2058 if (i + 3 >= sp)
break;
2059 stbtt__csctx_rccurve_to(c, 0, s[i], s[i+1], s[i+2], s[i+3], (sp - i == 5) ? s[i + 4] : 0.0f);
2062 if (i + 3 >= sp)
break;
2063 stbtt__csctx_rccurve_to(c, s[i], 0, s[i+1], s[i+2], (sp - i == 5) ? s[i+4] : 0.0f, s[i+3]);
2069 if (sp < 6)
return STBTT__CSERR(
"rcurveline stack");
2070 for (; i + 5 < sp; i += 6)
2071 stbtt__csctx_rccurve_to(c, s[i], s[i+1], s[i+2], s[i+3], s[i+4], s[i+5]);
2075 if (sp < 8)
return STBTT__CSERR(
"rcurveline stack");
2076 for (; i + 5 < sp - 2; i += 6)
2077 stbtt__csctx_rccurve_to(c, s[i], s[i+1], s[i+2], s[i+3], s[i+4], s[i+5]);
2078 if (i + 1 >= sp)
return STBTT__CSERR(
"rcurveline stack");
2079 stbtt__csctx_rline_to(c, s[i], s[i+1]);
2083 if (sp < 8)
return STBTT__CSERR(
"rlinecurve stack");
2084 for (; i + 1 < sp - 6; i += 2)
2085 stbtt__csctx_rline_to(c, s[i], s[i+1]);
2086 if (i + 5 >= sp)
return STBTT__CSERR(
"rlinecurve stack");
2087 stbtt__csctx_rccurve_to(c, s[i], s[i+1], s[i+2], s[i+3], s[i+4], s[i+5]);
2092 if (sp < 4)
return STBTT__CSERR(
"(vv|hh)curveto stack");
2094 if (sp & 1) { f = s[i]; i++; }
2095 for (; i + 3 < sp; i += 4) {
2097 stbtt__csctx_rccurve_to(c, s[i], f, s[i+1], s[i+2], s[i+3], 0.0);
2099 stbtt__csctx_rccurve_to(c, f, s[i], s[i+1], s[i+2], 0.0, s[i+3]);
2107 subrs = stbtt__cid_get_glyph_subrs(info, glyph_index);
2112 if (sp < 1)
return STBTT__CSERR(
"call(g|)subr stack");
2114 if (subr_stack_height >= 10)
return STBTT__CSERR(
"recursion limit");
2115 subr_stack[subr_stack_height++] = b;
2116 b = stbtt__get_subr(b0 == 0x0A ? subrs : info->
gsubrs, v);
2117 if (b.
size == 0)
return STBTT__CSERR(
"subr not found");
2123 if (subr_stack_height <= 0)
return STBTT__CSERR(
"return outside subr");
2124 b = subr_stack[--subr_stack_height];
2129 stbtt__csctx_close_shape(c);
2133 float dx1, dx2, dx3, dx4, dx5, dx6, dy1, dy2, dy3, dy4, dy5, dy6;
2135 int b1 = stbtt__buf_get8(&b);
2140 if (sp < 7)
return STBTT__CSERR(
"hflex stack");
2148 stbtt__csctx_rccurve_to(c, dx1, 0, dx2, dy2, dx3, 0);
2149 stbtt__csctx_rccurve_to(c, dx4, 0, dx5, -dy2, dx6, 0);
2153 if (sp < 13)
return STBTT__CSERR(
"flex stack");
2167 stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, dy3);
2168 stbtt__csctx_rccurve_to(c, dx4, dy4, dx5, dy5, dx6, dy6);
2172 if (sp < 9)
return STBTT__CSERR(
"hflex1 stack");
2182 stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, 0);
2183 stbtt__csctx_rccurve_to(c, dx4, 0, dx5, dy5, dx6, -(dy1+dy2+dy5));
2187 if (sp < 11)
return STBTT__CSERR(
"flex1 stack");
2199 dx = dx1+dx2+dx3+dx4+dx5;
2200 dy = dy1+dy2+dy3+dy4+dy5;
2201 if (STBTT_fabs(dx) > STBTT_fabs(dy))
2205 stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, dy3);
2206 stbtt__csctx_rccurve_to(c, dx4, dy4, dx5, dy5, dx6, dy6);
2210 return STBTT__CSERR(
"unimplemented");
2215 if (b0 != 255 && b0 != 28 && (b0 < 32 || b0 > 254))
2216 return STBTT__CSERR(
"reserved operator");
2220 f = (float)(stbtt_int32)stbtt__buf_get32(&b) / 0x10000;
2222 stbtt__buf_skip(&b, -1);
2223 f = (float)(stbtt_int16)stbtt__cff_int(&b);
2225 if (sp >= 48)
return STBTT__CSERR(
"push stack overflow");
2230 if (clear_stack) sp = 0;
2232 return STBTT__CSERR(
"no endchar");
2240 stbtt__csctx count_ctx = STBTT__CSCTX_INIT(1);
2241 stbtt__csctx output_ctx = STBTT__CSCTX_INIT(0);
2242 if (stbtt__run_charstring(info, glyph_index, &count_ctx)) {
2244 output_ctx.pvertices = *pvertices;
2245 if (stbtt__run_charstring(info, glyph_index, &output_ctx)) {
2246 STBTT_assert(output_ctx.num_vertices == count_ctx.num_vertices);
2247 return output_ctx.num_vertices;
2254 static int stbtt__GetGlyphInfoT2(
const stbtt_fontinfo *info,
int glyph_index,
int *x0,
int *y0,
int *x1,
int *y1)
2256 stbtt__csctx c = STBTT__CSCTX_INIT(1);
2257 int r = stbtt__run_charstring(info, glyph_index, &c);
2258 if (x0) *x0 = r ? c.min_x : 0;
2259 if (y0) *y0 = r ? c.min_y : 0;
2260 if (x1) *x1 = r ? c.max_x : 0;
2261 if (y1) *y1 = r ? c.max_y : 0;
2262 return r ? c.num_vertices : 0;
2268 return stbtt__GetGlyphShapeTT(info, glyph_index, pvertices);
2270 return stbtt__GetGlyphShapeT2(info, glyph_index, pvertices);
2275 stbtt_uint16 numOfLongHorMetrics = ttUSHORT(info->
data+info->
hhea + 34);
2276 if (glyph_index < numOfLongHorMetrics) {
2277 if (advanceWidth) *advanceWidth = ttSHORT(info->
data + info->
hmtx + 4*glyph_index);
2278 if (leftSideBearing) *leftSideBearing = ttSHORT(info->
data + info->
hmtx + 4*glyph_index + 2);
2280 if (advanceWidth) *advanceWidth = ttSHORT(info->
data + info->
hmtx + 4*(numOfLongHorMetrics-1));
2281 if (leftSideBearing) *leftSideBearing = ttSHORT(info->
data + info->
hmtx + 4*numOfLongHorMetrics + 2*(glyph_index - numOfLongHorMetrics));
2285 static int stbtt__GetGlyphKernInfoAdvance(
const stbtt_fontinfo *info,
int glyph1,
int glyph2)
2287 stbtt_uint8 *data = info->
data + info->
kern;
2288 stbtt_uint32 needle, straw;
2294 if (ttUSHORT(data+2) < 1)
2296 if (ttUSHORT(data+8) != 1)
2300 r = ttUSHORT(data+10) - 1;
2301 needle = glyph1 << 16 | glyph2;
2304 straw = ttULONG(data+18+(m*6));
2307 else if (needle > straw)
2310 return ttSHORT(data+22+(m*6));
2315 static stbtt_int32 stbtt__GetCoverageIndex(stbtt_uint8 *coverageTable,
int glyph)
2317 stbtt_uint16 coverageFormat = ttUSHORT(coverageTable);
2318 switch(coverageFormat) {
2320 stbtt_uint16 glyphCount = ttUSHORT(coverageTable + 2);
2323 stbtt_int32 l=0, r=glyphCount-1, m;
2324 int straw, needle=glyph;
2326 stbtt_uint8 *glyphArray = coverageTable + 4;
2327 stbtt_uint16 glyphID;
2329 glyphID = ttUSHORT(glyphArray + 2 * m);
2333 else if (needle > straw)
2342 stbtt_uint16 rangeCount = ttUSHORT(coverageTable + 2);
2343 stbtt_uint8 *rangeArray = coverageTable + 4;
2346 stbtt_int32 l=0, r=rangeCount-1, m;
2347 int strawStart, strawEnd, needle=glyph;
2349 stbtt_uint8 *rangeRecord;
2351 rangeRecord = rangeArray + 6 * m;
2352 strawStart = ttUSHORT(rangeRecord);
2353 strawEnd = ttUSHORT(rangeRecord + 2);
2354 if (needle < strawStart)
2356 else if (needle > strawEnd)
2359 stbtt_uint16 startCoverageIndex = ttUSHORT(rangeRecord + 4);
2360 return startCoverageIndex + glyph - strawStart;
2374 static stbtt_int32 stbtt__GetGlyphClass(stbtt_uint8 *classDefTable,
int glyph)
2376 stbtt_uint16 classDefFormat = ttUSHORT(classDefTable);
2377 switch(classDefFormat)
2380 stbtt_uint16 startGlyphID = ttUSHORT(classDefTable + 2);
2381 stbtt_uint16 glyphCount = ttUSHORT(classDefTable + 4);
2382 stbtt_uint8 *classDef1ValueArray = classDefTable + 6;
2384 if (glyph >= startGlyphID && glyph < startGlyphID + glyphCount)
2385 return (stbtt_int32)ttUSHORT(classDef1ValueArray + 2 * (glyph - startGlyphID));
2392 stbtt_uint16 classRangeCount = ttUSHORT(classDefTable + 2);
2393 stbtt_uint8 *classRangeRecords = classDefTable + 4;
2396 stbtt_int32 l=0, r=classRangeCount-1, m;
2397 int strawStart, strawEnd, needle=glyph;
2399 stbtt_uint8 *classRangeRecord;
2401 classRangeRecord = classRangeRecords + 6 * m;
2402 strawStart = ttUSHORT(classRangeRecord);
2403 strawEnd = ttUSHORT(classRangeRecord + 2);
2404 if (needle < strawStart)
2406 else if (needle > strawEnd)
2409 return (stbtt_int32)ttUSHORT(classRangeRecord + 4);
2426 #define STBTT_GPOS_TODO_assert(x)
2428 static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(
const stbtt_fontinfo *info,
int glyph1,
int glyph2)
2430 stbtt_uint16 lookupListOffset;
2431 stbtt_uint8 *lookupList;
2432 stbtt_uint16 lookupCount;
2436 if (!info->
gpos)
return 0;
2440 if (ttUSHORT(data+0) != 1)
return 0;
2441 if (ttUSHORT(data+2) != 0)
return 0;
2443 lookupListOffset = ttUSHORT(data+8);
2444 lookupList = data + lookupListOffset;
2445 lookupCount = ttUSHORT(lookupList);
2447 for (i=0; i<lookupCount; ++i) {
2448 stbtt_uint16 lookupOffset = ttUSHORT(lookupList + 2 + 2 * i);
2449 stbtt_uint8 *lookupTable = lookupList + lookupOffset;
2451 stbtt_uint16 lookupType = ttUSHORT(lookupTable);
2452 stbtt_uint16 subTableCount = ttUSHORT(lookupTable + 4);
2453 stbtt_uint8 *subTableOffsets = lookupTable + 6;
2454 switch(lookupType) {
2457 for (sti=0; sti<subTableCount; sti++) {
2458 stbtt_uint16 subtableOffset = ttUSHORT(subTableOffsets + 2 * sti);
2459 stbtt_uint8 *table = lookupTable + subtableOffset;
2460 stbtt_uint16 posFormat = ttUSHORT(table);
2461 stbtt_uint16 coverageOffset = ttUSHORT(table + 2);
2462 stbtt_int32 coverageIndex = stbtt__GetCoverageIndex(table + coverageOffset, glyph1);
2463 if (coverageIndex == -1)
continue;
2465 switch (posFormat) {
2467 stbtt_int32 l, r, m;
2469 stbtt_uint16 valueFormat1 = ttUSHORT(table + 4);
2470 stbtt_uint16 valueFormat2 = ttUSHORT(table + 6);
2471 stbtt_int32 valueRecordPairSizeInBytes = 2;
2472 stbtt_uint16 pairSetCount = ttUSHORT(table + 8);
2473 stbtt_uint16 pairPosOffset = ttUSHORT(table + 10 + 2 * coverageIndex);
2474 stbtt_uint8 *pairValueTable = table + pairPosOffset;
2475 stbtt_uint16 pairValueCount = ttUSHORT(pairValueTable);
2476 stbtt_uint8 *pairValueArray = pairValueTable + 2;
2478 STBTT_GPOS_TODO_assert(valueFormat1 == 4);
2479 if (valueFormat1 != 4)
return 0;
2480 STBTT_GPOS_TODO_assert(valueFormat2 == 0);
2481 if (valueFormat2 != 0)
return 0;
2483 STBTT_assert(coverageIndex < pairSetCount);
2484 STBTT__NOTUSED(pairSetCount);
2492 stbtt_uint16 secondGlyph;
2493 stbtt_uint8 *pairValue;
2495 pairValue = pairValueArray + (2 + valueRecordPairSizeInBytes) * m;
2496 secondGlyph = ttUSHORT(pairValue);
2497 straw = secondGlyph;
2500 else if (needle > straw)
2503 stbtt_int16 xAdvance = ttSHORT(pairValue + 2);
2510 stbtt_uint16 valueFormat1 = ttUSHORT(table + 4);
2511 stbtt_uint16 valueFormat2 = ttUSHORT(table + 6);
2513 stbtt_uint16 classDef1Offset = ttUSHORT(table + 8);
2514 stbtt_uint16 classDef2Offset = ttUSHORT(table + 10);
2515 int glyph1class = stbtt__GetGlyphClass(table + classDef1Offset, glyph1);
2516 int glyph2class = stbtt__GetGlyphClass(table + classDef2Offset, glyph2);
2518 stbtt_uint16 class1Count = ttUSHORT(table + 12);
2519 stbtt_uint16 class2Count = ttUSHORT(table + 14);
2520 STBTT_assert(glyph1class < class1Count);
2521 STBTT_assert(glyph2class < class2Count);
2524 STBTT_GPOS_TODO_assert(valueFormat1 == 4);
2525 if (valueFormat1 != 4)
return 0;
2526 STBTT_GPOS_TODO_assert(valueFormat2 == 0);
2527 if (valueFormat2 != 0)
return 0;
2529 if (glyph1class >= 0 && glyph1class < class1Count && glyph2class >= 0 && glyph2class < class2Count) {
2530 stbtt_uint8 *class1Records = table + 16;
2531 stbtt_uint8 *class2Records = class1Records + 2 * (glyph1class * class2Count);
2532 stbtt_int16 xAdvance = ttSHORT(class2Records + 2 * glyph2class);
2561 xAdvance += stbtt__GetGlyphGPOSInfoAdvance(info, g1, g2);
2564 xAdvance += stbtt__GetGlyphKernInfoAdvance(info, g1, g2);
2583 if (ascent ) *ascent = ttSHORT(info->
data+info->
hhea + 4);
2584 if (descent) *descent = ttSHORT(info->
data+info->
hhea + 6);
2585 if (lineGap) *lineGap = ttSHORT(info->
data+info->
hhea + 8);
2590 int tab = stbtt__find_table(info->
data, info->
fontstart,
"OS/2");
2593 if (typoAscent ) *typoAscent = ttSHORT(info->
data+tab + 68);
2594 if (typoDescent) *typoDescent = ttSHORT(info->
data+tab + 70);
2595 if (typoLineGap) *typoLineGap = ttSHORT(info->
data+tab + 72);
2601 *x0 = ttSHORT(info->
data + info->
head + 36);
2602 *y0 = ttSHORT(info->
data + info->
head + 38);
2603 *x1 = ttSHORT(info->
data + info->
head + 40);
2604 *y1 = ttSHORT(info->
data + info->
head + 42);
2609 int fheight = ttSHORT(info->
data + info->
hhea + 4) - ttSHORT(info->
data + info->
hhea + 6);
2610 return (
float) height / fheight;
2615 int unitsPerEm = ttUSHORT(info->
data + info->
head + 18);
2616 return pixels / unitsPerEm;
2631 int x0=0,y0=0,x1,y1;
2640 if (ix0) *ix0 = STBTT_ifloor( x0 * scale_x + shift_x);
2641 if (iy0) *iy0 = STBTT_ifloor(-y1 * scale_y + shift_y);
2642 if (ix1) *ix1 = STBTT_iceil ( x1 * scale_x + shift_x);
2643 if (iy1) *iy1 = STBTT_iceil (-y0 * scale_y + shift_y);
2654 stbtt_GetGlyphBitmapBoxSubpixel(font,
stbtt_FindGlyphIndex(font,codepoint), scale_x, scale_y,shift_x,shift_y, ix0,iy0,ix1,iy1);
2666 typedef struct stbtt__hheap_chunk
2668 struct stbtt__hheap_chunk *next;
2669 } stbtt__hheap_chunk;
2671 typedef struct stbtt__hheap
2673 struct stbtt__hheap_chunk *head;
2675 int num_remaining_in_head_chunk;
2678 static void *stbtt__hheap_alloc(stbtt__hheap *hh,
size_t size,
void *userdata)
2680 if (hh->first_free) {
2681 void *p = hh->first_free;
2682 hh->first_free = * (
void **) p;
2685 if (hh->num_remaining_in_head_chunk == 0) {
2686 int count = (size < 32 ? 2000 : size < 128 ? 800 : 100);
2687 stbtt__hheap_chunk *c = (stbtt__hheap_chunk *) STBTT_malloc(
sizeof(stbtt__hheap_chunk) + size * count, userdata);
2692 hh->num_remaining_in_head_chunk = count;
2694 --hh->num_remaining_in_head_chunk;
2695 return (
char *) (hh->head) +
sizeof(stbtt__hheap_chunk) + size * hh->num_remaining_in_head_chunk;
2699 static void stbtt__hheap_free(stbtt__hheap *hh,
void *p)
2701 *(
void **) p = hh->first_free;
2705 static void stbtt__hheap_cleanup(stbtt__hheap *hh,
void *userdata)
2707 stbtt__hheap_chunk *c = hh->head;
2709 stbtt__hheap_chunk *n = c->next;
2710 STBTT_free(c, userdata);
2715 typedef struct stbtt__edge {
2721 typedef struct stbtt__active_edge
2723 struct stbtt__active_edge *next;
2724 #if STBTT_RASTERIZER_VERSION==1
2728 #elif STBTT_RASTERIZER_VERSION==2
2734 #error "Unrecognized value of STBTT_RASTERIZER_VERSION"
2736 } stbtt__active_edge;
2738 #if STBTT_RASTERIZER_VERSION == 1
2739 #define STBTT_FIXSHIFT 10
2740 #define STBTT_FIX (1 << STBTT_FIXSHIFT)
2741 #define STBTT_FIXMASK (STBTT_FIX-1)
2743 static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e,
int off_x,
float start_point,
void *userdata)
2745 stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh,
sizeof(*z), userdata);
2746 float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
2747 STBTT_assert(z != NULL);
2752 z->dx = -STBTT_ifloor(STBTT_FIX * -dxdy);
2754 z->dx = STBTT_ifloor(STBTT_FIX * dxdy);
2756 z->x = STBTT_ifloor(STBTT_FIX * e->x0 + z->dx * (start_point - e->y0));
2757 z->x -= off_x * STBTT_FIX;
2761 z->direction = e->invert ? 1 : -1;
2764 #elif STBTT_RASTERIZER_VERSION == 2
2765 static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e,
int off_x,
float start_point,
void *userdata)
2767 stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh,
sizeof(*z), userdata);
2768 float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
2769 STBTT_assert(z != NULL);
2773 z->fdy = dxdy != 0.0f ? (1.0f/dxdy) : 0.0f;
2774 z->fx = e->x0 + dxdy * (start_point - e->y0);
2776 z->direction = e->invert ? 1.0f : -1.0f;
2783 #error "Unrecognized value of STBTT_RASTERIZER_VERSION"
2786 #if STBTT_RASTERIZER_VERSION == 1
2790 static void stbtt__fill_active_edges(
unsigned char *scanline,
int len, stbtt__active_edge *e,
int max_weight)
2798 x0 = e->x; w += e->direction;
2800 int x1 = e->x; w += e->direction;
2803 int i = x0 >> STBTT_FIXSHIFT;
2804 int j = x1 >> STBTT_FIXSHIFT;
2806 if (i < len && j >= 0) {
2809 scanline[i] = scanline[i] + (stbtt_uint8) ((x1 - x0) * max_weight >> STBTT_FIXSHIFT);
2812 scanline[i] = scanline[i] + (stbtt_uint8) (((STBTT_FIX - (x0 & STBTT_FIXMASK)) * max_weight) >> STBTT_FIXSHIFT);
2817 scanline[j] = scanline[j] + (stbtt_uint8) (((x1 & STBTT_FIXMASK) * max_weight) >> STBTT_FIXSHIFT);
2821 for (++i; i < j; ++i)
2822 scanline[i] = scanline[i] + (stbtt_uint8) max_weight;
2832 static void stbtt__rasterize_sorted_edges(
stbtt__bitmap *result, stbtt__edge *e,
int n,
int vsubsample,
int off_x,
int off_y,
void *userdata)
2834 stbtt__hheap hh = { 0, 0, 0 };
2835 stbtt__active_edge *active = NULL;
2837 int max_weight = (255 / vsubsample);
2839 unsigned char scanline_data[512], *scanline;
2841 if (result->
w > 512)
2842 scanline = (
unsigned char *) STBTT_malloc(result->
w, userdata);
2844 scanline = scanline_data;
2846 y = off_y * vsubsample;
2847 e[n].y0 = (off_y + result->
h) * (
float) vsubsample + 1;
2849 while (j < result->h) {
2850 STBTT_memset(scanline, 0, result->
w);
2851 for (s=0; s < vsubsample; ++s) {
2853 float scan_y = y + 0.5f;
2854 stbtt__active_edge **step = &active;
2859 stbtt__active_edge * z = *step;
2860 if (z->ey <= scan_y) {
2862 STBTT_assert(z->direction);
2864 stbtt__hheap_free(&hh, z);
2867 step = &((*step)->next);
2875 while (*step && (*step)->next) {
2876 if ((*step)->x > (*step)->next->x) {
2877 stbtt__active_edge *t = *step;
2878 stbtt__active_edge *q = t->next;
2885 step = &(*step)->next;
2887 if (!changed)
break;
2891 while (e->y0 <= scan_y) {
2892 if (e->y1 > scan_y) {
2893 stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y, userdata);
2898 else if (z->x < active->x) {
2904 stbtt__active_edge *p = active;
2905 while (p->next && p->next->x < z->x)
2918 stbtt__fill_active_edges(scanline, result->
w, active, max_weight);
2922 STBTT_memcpy(result->
pixels + j * result->
stride, scanline, result->
w);
2926 stbtt__hheap_cleanup(&hh, userdata);
2928 if (scanline != scanline_data)
2929 STBTT_free(scanline, userdata);
2932 #elif STBTT_RASTERIZER_VERSION == 2
2936 static void stbtt__handle_clipped_edge(
float *scanline,
int x, stbtt__active_edge *e,
float x0,
float y0,
float x1,
float y1)
2938 if (y0 == y1)
return;
2939 STBTT_assert(y0 < y1);
2940 STBTT_assert(e->sy <= e->ey);
2941 if (y0 > e->ey)
return;
2942 if (y1 < e->sy)
return;
2944 x0 += (x1-x0) * (e->sy - y0) / (y1-y0);
2948 x1 += (x1-x0) * (e->ey - y1) / (y1-y0);
2953 STBTT_assert(x1 <= x+1);
2955 STBTT_assert(x1 >= x);
2957 STBTT_assert(x1 <= x);
2959 STBTT_assert(x1 >= x+1);
2961 STBTT_assert(x1 >= x && x1 <= x+1);
2963 if (x0 <= x && x1 <= x)
2964 scanline[x] += e->direction * (y1-y0);
2965 else if (x0 >= x+1 && x1 >= x+1)
2968 STBTT_assert(x0 >= x && x0 <= x+1 && x1 >= x && x1 <= x+1);
2969 scanline[x] += e->direction * (y1-y0) * (1-((x0-x)+(x1-x))/2);
2973 static void stbtt__fill_active_edges_new(
float *scanline,
float *scanline_fill,
int len, stbtt__active_edge *e,
float y_top)
2975 float y_bottom = y_top+1;
2981 STBTT_assert(e->ey >= y_top);
2987 stbtt__handle_clipped_edge(scanline,(
int) x0,e, x0,y_top, x0,y_bottom);
2988 stbtt__handle_clipped_edge(scanline_fill-1,(
int) x0+1,e, x0,y_top, x0,y_bottom);
2990 stbtt__handle_clipped_edge(scanline_fill-1,0,e, x0,y_top, x0,y_bottom);
2997 float x_top, x_bottom;
3000 STBTT_assert(e->sy <= y_bottom && e->ey >= y_top);
3005 if (e->sy > y_top) {
3006 x_top = x0 + dx * (e->sy - y_top);
3012 if (e->ey < y_bottom) {
3013 x_bottom = x0 + dx * (e->ey - y_top);
3020 if (x_top >= 0 && x_bottom >= 0 && x_top < len && x_bottom < len) {
3023 if ((
int) x_top == (
int) x_bottom) {
3026 int x = (
int) x_top;
3028 STBTT_assert(x >= 0 && x < len);
3029 scanline[x] += e->direction * (1-((x_top - x) + (x_bottom-x))/2) * height;
3030 scanline_fill[x] += e->direction * height;
3033 float y_crossing, step, sign, area;
3035 if (x_top > x_bottom) {
3038 sy0 = y_bottom - (sy0 - y_top);
3039 sy1 = y_bottom - (sy1 - y_top);
3040 t = sy0, sy0 = sy1, sy1 = t;
3041 t = x_bottom, x_bottom = x_top, x_top = t;
3044 t = x0, x0 = xb, xb = t;
3050 x2 = (
int) x_bottom;
3052 y_crossing = (x1+1 - x0) * dy + y_top;
3054 sign = e->direction;
3056 area = sign * (y_crossing-sy0);
3058 scanline[x1] += area * (1-((x_top - x1)+(x1+1-x1))/2);
3061 for (x = x1+1; x < x2; ++x) {
3062 scanline[x] += area + step/2;
3065 y_crossing += dy * (x2 - (x1+1));
3067 STBTT_assert(STBTT_fabs(area) <= 1.01f);
3069 scanline[x2] += area + sign * (1-((x2-x2)+(x_bottom-x2))/2) * (sy1-y_crossing);
3071 scanline_fill[x2] += sign * (sy1-sy0);
3079 for (x=0; x < len; ++x) {
3095 float x1 = (float) (x);
3096 float x2 = (float) (x+1);
3098 float y3 = y_bottom;
3103 float y1 = (x - x0) / dx + y_top;
3104 float y2 = (x+1 - x0) / dx + y_top;
3106 if (x0 < x1 && x3 > x2) {
3107 stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1);
3108 stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x2,y2);
3109 stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3);
3110 }
else if (x3 < x1 && x0 > x2) {
3111 stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2);
3112 stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x1,y1);
3113 stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3);
3114 }
else if (x0 < x1 && x3 > x1) {
3115 stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1);
3116 stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3);
3117 }
else if (x3 < x1 && x0 > x1) {
3118 stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1);
3119 stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3);
3120 }
else if (x0 < x2 && x3 > x2) {
3121 stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2);
3122 stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3);
3123 }
else if (x3 < x2 && x0 > x2) {
3124 stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2);
3125 stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3);
3127 stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x3,y3);
3137 static void stbtt__rasterize_sorted_edges(
stbtt__bitmap *result, stbtt__edge *e,
int n,
int vsubsample,
int off_x,
int off_y,
void *userdata)
3139 stbtt__hheap hh = { 0, 0, 0 };
3140 stbtt__active_edge *active = NULL;
3142 float scanline_data[129], *scanline, *scanline2;
3144 STBTT__NOTUSED(vsubsample);
3147 scanline = (
float *) STBTT_malloc((result->
w*2+1) *
sizeof(float), userdata);
3149 scanline = scanline_data;
3151 scanline2 = scanline + result->
w;
3154 e[n].y0 = (float) (off_y + result->
h) + 1;
3156 while (j < result->h) {
3158 float scan_y_top = y + 0.0f;
3159 float scan_y_bottom = y + 1.0f;
3160 stbtt__active_edge **step = &active;
3162 STBTT_memset(scanline , 0, result->
w*
sizeof(scanline[0]));
3163 STBTT_memset(scanline2, 0, (result->
w+1)*
sizeof(scanline[0]));
3168 stbtt__active_edge * z = *step;
3169 if (z->ey <= scan_y_top) {
3171 STBTT_assert(z->direction);
3173 stbtt__hheap_free(&hh, z);
3175 step = &((*step)->next);
3180 while (e->y0 <= scan_y_bottom) {
3181 if (e->y0 != e->y1) {
3182 stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata);
3184 if (j == 0 && off_y != 0) {
3185 if (z->ey < scan_y_top) {
3190 STBTT_assert(z->ey >= scan_y_top);
3201 stbtt__fill_active_edges_new(scanline, scanline2+1, result->
w, active, scan_y_top);
3205 for (i=0; i < result->
w; ++i) {
3208 sum += scanline2[i];
3209 k = scanline[i] + sum;
3210 k = (float) STBTT_fabs(k)*255 + 0.5f;
3212 if (m > 255) m = 255;
3219 stbtt__active_edge *z = *step;
3221 step = &((*step)->next);
3228 stbtt__hheap_cleanup(&hh, userdata);
3230 if (scanline != scanline_data)
3231 STBTT_free(scanline, userdata);
3234 #error "Unrecognized value of STBTT_RASTERIZER_VERSION"
3237 #define STBTT__COMPARE(a,b) ((a)->y0 < (b)->y0)
3239 static void stbtt__sort_edges_ins_sort(stbtt__edge *p,
int n)
3242 for (i=1; i < n; ++i) {
3243 stbtt__edge t = p[i], *a = &t;
3246 stbtt__edge *b = &p[j-1];
3247 int c = STBTT__COMPARE(a,b);
3257 static void stbtt__sort_edges_quicksort(stbtt__edge *p,
int n)
3262 int c01,c12,c,m,i,j;
3266 c01 = STBTT__COMPARE(&p[0],&p[m]);
3267 c12 = STBTT__COMPARE(&p[m],&p[n-1]);
3272 c = STBTT__COMPARE(&p[0],&p[n-1]);
3275 z = (c == c12) ? 0 : n-1;
3293 if (!STBTT__COMPARE(&p[i], &p[0]))
break;
3296 if (!STBTT__COMPARE(&p[0], &p[j]))
break;
3309 stbtt__sort_edges_quicksort(p,j);
3313 stbtt__sort_edges_quicksort(p+i, n-i);
3319 static void stbtt__sort_edges(stbtt__edge *p,
int n)
3321 stbtt__sort_edges_quicksort(p, n);
3322 stbtt__sort_edges_ins_sort(p, n);
3330 static void stbtt__rasterize(
stbtt__bitmap *result, stbtt__point *pts,
int *wcount,
int windings,
float scale_x,
float scale_y,
float shift_x,
float shift_y,
int off_x,
int off_y,
int invert,
void *userdata)
3332 float y_scale_inv = invert ? -scale_y : scale_y;
3335 #if STBTT_RASTERIZER_VERSION == 1
3336 int vsubsample = result->
h < 8 ? 15 : 5;
3337 #elif STBTT_RASTERIZER_VERSION == 2
3340 #error "Unrecognized value of STBTT_RASTERIZER_VERSION"
3346 for (i=0; i < windings; ++i)
3349 e = (stbtt__edge *) STBTT_malloc(
sizeof(*e) * (n+1), userdata);
3354 for (i=0; i < windings; ++i) {
3355 stbtt__point *p = pts + m;
3358 for (k=0; k < wcount[i]; j=k++) {
3361 if (p[j].y == p[k].y)
3365 if (invert ? p[j].y > p[k].y : p[j].y < p[k].y) {
3369 e[n].x0 = p[a].x * scale_x + shift_x;
3370 e[n].y0 = (p[a].y * y_scale_inv + shift_y) * vsubsample;
3371 e[n].x1 = p[b].x * scale_x + shift_x;
3372 e[n].y1 = (p[b].y * y_scale_inv + shift_y) * vsubsample;
3379 stbtt__sort_edges(e, n);
3382 stbtt__rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y, userdata);
3384 STBTT_free(e, userdata);
3387 static void stbtt__add_point(stbtt__point *points,
int n,
float x,
float y)
3389 if (!points)
return;
3395 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)
3398 float mx = (x0 + 2*x1 + x2)/4;
3399 float my = (y0 + 2*y1 + y2)/4;
3401 float dx = (x0+x2)/2 - mx;
3402 float dy = (y0+y2)/2 - my;
3405 if (dx*dx+dy*dy > objspace_flatness_squared) {
3406 stbtt__tesselate_curve(points, num_points, x0,y0, (x0+x1)/2.0f,(y0+y1)/2.0f, mx,my, objspace_flatness_squared,n+1);
3407 stbtt__tesselate_curve(points, num_points, mx,my, (x1+x2)/2.0f,(y1+y2)/2.0f, x2,y2, objspace_flatness_squared,n+1);
3409 stbtt__add_point(points, *num_points,x2,y2);
3410 *num_points = *num_points+1;
3415 static void stbtt__tesselate_cubic(stbtt__point *points,
int *num_points,
float x0,
float y0,
float x1,
float y1,
float x2,
float y2,
float x3,
float y3,
float objspace_flatness_squared,
int n)
3426 float longlen = (float) (STBTT_sqrt(dx0*dx0+dy0*dy0)+STBTT_sqrt(dx1*dx1+dy1*dy1)+STBTT_sqrt(dx2*dx2+dy2*dy2));
3427 float shortlen = (float) STBTT_sqrt(dx*dx+dy*dy);
3428 float flatness_squared = longlen*longlen-shortlen*shortlen;
3433 if (flatness_squared > objspace_flatness_squared) {
3434 float x01 = (x0+x1)/2;
3435 float y01 = (y0+y1)/2;
3436 float x12 = (x1+x2)/2;
3437 float y12 = (y1+y2)/2;
3438 float x23 = (x2+x3)/2;
3439 float y23 = (y2+y3)/2;
3441 float xa = (x01+x12)/2;
3442 float ya = (y01+y12)/2;
3443 float xb = (x12+x23)/2;
3444 float yb = (y12+y23)/2;
3446 float mx = (xa+xb)/2;
3447 float my = (ya+yb)/2;
3449 stbtt__tesselate_cubic(points, num_points, x0,y0, x01,y01, xa,ya, mx,my, objspace_flatness_squared,n+1);
3450 stbtt__tesselate_cubic(points, num_points, mx,my, xb,yb, x23,y23, x3,y3, objspace_flatness_squared,n+1);
3452 stbtt__add_point(points, *num_points,x3,y3);
3453 *num_points = *num_points+1;
3458 static stbtt__point *stbtt_FlattenCurves(
stbtt_vertex *vertices,
int num_verts,
float objspace_flatness,
int **contour_lengths,
int *num_contours,
void *userdata)
3460 stbtt__point *points=0;
3463 float objspace_flatness_squared = objspace_flatness * objspace_flatness;
3464 int i,n=0,start=0, pass;
3467 for (i=0; i < num_verts; ++i)
3472 if (n == 0)
return 0;
3474 *contour_lengths = (
int *) STBTT_malloc(
sizeof(**contour_lengths) * n, userdata);
3476 if (*contour_lengths == 0) {
3482 for (pass=0; pass < 2; ++pass) {
3485 points = (stbtt__point *) STBTT_malloc(num_points *
sizeof(points[0]), userdata);
3486 if (points == NULL)
goto error;
3490 for (i=0; i < num_verts; ++i) {
3491 switch (vertices[i].type) {
3495 (*contour_lengths)[n] = num_points - start;
3499 x = vertices[i].
x, y = vertices[i].
y;
3500 stbtt__add_point(points, num_points++, x,y);
3503 x = vertices[i].
x, y = vertices[i].
y;
3504 stbtt__add_point(points, num_points++, x, y);
3507 stbtt__tesselate_curve(points, &num_points, x,y,
3508 vertices[i].cx, vertices[i].cy,
3509 vertices[i].x, vertices[i].y,
3510 objspace_flatness_squared, 0);
3511 x = vertices[i].
x, y = vertices[i].
y;
3514 stbtt__tesselate_cubic(points, &num_points, x,y,
3515 vertices[i].cx, vertices[i].cy,
3516 vertices[i].cx1, vertices[i].cy1,
3517 vertices[i].x, vertices[i].y,
3518 objspace_flatness_squared, 0);
3519 x = vertices[i].
x, y = vertices[i].
y;
3523 (*contour_lengths)[n] = num_points - start;
3528 STBTT_free(points, userdata);
3529 STBTT_free(*contour_lengths, userdata);
3530 *contour_lengths = 0;
3535 STBTT_DEF void stbtt_Rasterize(
stbtt__bitmap *result,
float flatness_in_pixels,
stbtt_vertex *vertices,
int num_verts,
float scale_x,
float scale_y,
float shift_x,
float shift_y,
int x_off,
int y_off,
int invert,
void *userdata)
3537 float scale = scale_x > scale_y ? scale_y : scale_x;
3538 int winding_count = 0;
3539 int *winding_lengths = NULL;
3540 stbtt__point *windings = stbtt_FlattenCurves(vertices, num_verts, flatness_in_pixels / scale, &winding_lengths, &winding_count, userdata);
3542 stbtt__rasterize(result, windings, winding_lengths, winding_count, scale_x, scale_y, shift_x, shift_y, x_off, y_off, invert, userdata);
3543 STBTT_free(winding_lengths, userdata);
3544 STBTT_free(windings, userdata);
3550 STBTT_free(bitmap, userdata);
3555 int ix0,iy0,ix1,iy1;
3560 if (scale_x == 0) scale_x = scale_y;
3563 STBTT_free(vertices, info->
userdata);
3572 gbm.
w = (ix1 - ix0);
3573 gbm.
h = (iy1 - iy0);
3576 if (width ) *width = gbm.
w;
3577 if (height) *height = gbm.
h;
3578 if (xoff ) *xoff = ix0;
3579 if (yoff ) *yoff = iy0;
3581 if (gbm.
w && gbm.
h) {
3582 gbm.
pixels = (
unsigned char *) STBTT_malloc(gbm.
w * gbm.
h, info->
userdata);
3586 stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0, iy0, 1, info->
userdata);
3589 STBTT_free(vertices, info->
userdata);
3612 stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0,iy0, 1, info->
userdata);
3614 STBTT_free(vertices, info->
userdata);
3624 return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y,shift_x,shift_y,
stbtt_FindGlyphIndex(info,codepoint), width,height,xoff,yoff);
3627 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)
3629 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));
3634 stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y,
stbtt_FindGlyphIndex(info,codepoint));
3653 static int stbtt_BakeFontBitmap_internal(
unsigned char *data,
int offset,
3655 unsigned char *pixels,
int pw,
int ph,
3656 int first_char,
int num_chars,
3660 int x,y,bottom_y, i;
3665 STBTT_memset(pixels, 0, pw*ph);
3671 for (i=0; i < num_chars; ++i) {
3672 int advance, lsb, x0,y0,x1,y1,gw,gh;
3678 if (x + gw + 1 >= pw)
3679 y = bottom_y, x = 1;
3680 if (y + gh + 1 >= ph)
3682 STBTT_assert(x+gw < pw);
3683 STBTT_assert(y+gh < ph);
3685 chardata[i].
x0 = (stbtt_int16) x;
3686 chardata[i].
y0 = (stbtt_int16) y;
3687 chardata[i].
x1 = (stbtt_int16) (x + gw);
3688 chardata[i].
y1 = (stbtt_int16) (y + gh);
3689 chardata[i].
xadvance = scale * advance;
3690 chardata[i].
xoff = (float) x0;
3691 chardata[i].
yoff = (float) y0;
3693 if (y+gh+1 > bottom_y)
3701 float d3d_bias = opengl_fillrule ? 0 : -0.5f;
3702 float ipw = 1.0f / pw, iph = 1.0f / ph;
3704 int round_x = STBTT_ifloor((*xpos + b->
xoff) + 0.5f);
3705 int round_y = STBTT_ifloor((*ypos + b->
yoff) + 0.5f);
3707 q->
x0 = round_x + d3d_bias;
3708 q->
y0 = round_y + d3d_bias;
3709 q->
x1 = round_x + b->
x1 - b->
x0 + d3d_bias;
3710 q->
y1 = round_y + b->
y1 - b->
y0 + d3d_bias;
3712 q->
s0 = b->
x0 * ipw;
3713 q->
t0 = b->
y0 * iph;
3714 q->
s1 = b->
x1 * ipw;
3715 q->
t1 = b->
y1 * iph;
3725 #ifndef STB_RECT_PACK_VERSION
3764 STBTT__NOTUSED(nodes);
3765 STBTT__NOTUSED(num_nodes);
3771 for (i=0; i < num_rects; ++i) {
3772 if (con->x + rects[i].
w > con->
width) {
3774 con->y = con->bottom_y;
3776 if (con->y + rects[i].
h > con->
height)
3778 rects[i].
x = con->x;
3779 rects[i].
y = con->y;
3781 con->x += rects[i].
w;
3782 if (con->y + rects[i].
h > con->bottom_y)
3783 con->bottom_y = con->y + rects[i].
h;
3785 for ( ; i < num_rects; ++i)
3786 rects[i].was_packed = 0;
3800 int num_nodes = pw - padding;
3803 if (context == NULL || nodes == NULL) {
3804 if (context != NULL) STBTT_free(context, alloc_context);
3805 if (nodes != NULL) STBTT_free(nodes , alloc_context);
3824 STBTT_memset(pixels, 0, pw*ph);
3837 STBTT_assert(h_oversample <= STBTT_MAX_OVERSAMPLE);
3838 STBTT_assert(v_oversample <= STBTT_MAX_OVERSAMPLE);
3839 if (h_oversample <= STBTT_MAX_OVERSAMPLE)
3841 if (v_oversample <= STBTT_MAX_OVERSAMPLE)
3850 #define STBTT__OVER_MASK (STBTT_MAX_OVERSAMPLE-1)
3852 static void stbtt__h_prefilter(
unsigned char *pixels,
int w,
int h,
int stride_in_bytes,
unsigned int kernel_width)
3854 unsigned char buffer[STBTT_MAX_OVERSAMPLE];
3855 int safe_w = w - kernel_width;
3857 STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE);
3858 for (j=0; j < h; ++j) {
3861 STBTT_memset(buffer, 0, kernel_width);
3866 switch (kernel_width) {
3868 for (i=0; i <= safe_w; ++i) {
3869 total += pixels[i] - buffer[i & STBTT__OVER_MASK];
3870 buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
3871 pixels[i] = (
unsigned char) (total / 2);
3875 for (i=0; i <= safe_w; ++i) {
3876 total += pixels[i] - buffer[i & STBTT__OVER_MASK];
3877 buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
3878 pixels[i] = (
unsigned char) (total / 3);
3882 for (i=0; i <= safe_w; ++i) {
3883 total += pixels[i] - buffer[i & STBTT__OVER_MASK];
3884 buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
3885 pixels[i] = (
unsigned char) (total / 4);
3889 for (i=0; i <= safe_w; ++i) {
3890 total += pixels[i] - buffer[i & STBTT__OVER_MASK];
3891 buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
3892 pixels[i] = (
unsigned char) (total / 5);
3896 for (i=0; i <= safe_w; ++i) {
3897 total += pixels[i] - buffer[i & STBTT__OVER_MASK];
3898 buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
3899 pixels[i] = (
unsigned char) (total / kernel_width);
3904 for (; i < w; ++i) {
3905 STBTT_assert(pixels[i] == 0);
3906 total -= buffer[i & STBTT__OVER_MASK];
3907 pixels[i] = (
unsigned char) (total / kernel_width);
3910 pixels += stride_in_bytes;
3914 static void stbtt__v_prefilter(
unsigned char *pixels,
int w,
int h,
int stride_in_bytes,
unsigned int kernel_width)
3916 unsigned char buffer[STBTT_MAX_OVERSAMPLE];
3917 int safe_h = h - kernel_width;
3919 STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE);
3920 for (j=0; j < w; ++j) {
3923 STBTT_memset(buffer, 0, kernel_width);
3928 switch (kernel_width) {
3930 for (i=0; i <= safe_h; ++i) {
3931 total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
3932 buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
3933 pixels[i*stride_in_bytes] = (
unsigned char) (total / 2);
3937 for (i=0; i <= safe_h; ++i) {
3938 total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
3939 buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
3940 pixels[i*stride_in_bytes] = (
unsigned char) (total / 3);
3944 for (i=0; i <= safe_h; ++i) {
3945 total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
3946 buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
3947 pixels[i*stride_in_bytes] = (
unsigned char) (total / 4);
3951 for (i=0; i <= safe_h; ++i) {
3952 total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
3953 buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
3954 pixels[i*stride_in_bytes] = (
unsigned char) (total / 5);
3958 for (i=0; i <= safe_h; ++i) {
3959 total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
3960 buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
3961 pixels[i*stride_in_bytes] = (
unsigned char) (total / kernel_width);
3966 for (; i < h; ++i) {
3967 STBTT_assert(pixels[i*stride_in_bytes] == 0);
3968 total -= buffer[i & STBTT__OVER_MASK];
3969 pixels[i*stride_in_bytes] = (
unsigned char) (total / kernel_width);
3976 static float stbtt__oversample_shift(
int oversample)
3985 return (
float)-(oversample - 1) / (2.0f * (
float)oversample);
3994 for (i=0; i < num_ranges; ++i) {
3999 for (j=0; j < ranges[i].
num_chars; ++j) {
4004 rects[k].
w = rects[k].
h = 0;
4021 STBTT_DEF void stbtt_MakeGlyphBitmapSubpixelPrefilter(
const stbtt_fontinfo *info,
unsigned char *output,
int out_w,
int out_h,
int out_stride,
float scale_x,
float scale_y,
float shift_x,
float shift_y,
int prefilter_x,
int prefilter_y,
float *sub_x,
float *sub_y,
int glyph)
4025 out_w - (prefilter_x - 1),
4026 out_h - (prefilter_y - 1),
4034 if (prefilter_x > 1)
4035 stbtt__h_prefilter(output, out_w, out_h, out_stride, prefilter_x);
4037 if (prefilter_y > 1)
4038 stbtt__v_prefilter(output, out_w, out_h, out_stride, prefilter_y);
4040 *sub_x = stbtt__oversample_shift(prefilter_x);
4041 *sub_y = stbtt__oversample_shift(prefilter_y);
4047 int i,j,k, return_value = 1;
4054 for (i=0; i < num_ranges; ++i) {
4057 float recip_h,recip_v,sub_x,sub_y;
4064 for (j=0; j < ranges[i].
num_chars; ++j) {
4068 int advance, lsb, x0,y0,x1,y1;
4103 bc->
x0 = (stbtt_int16) r->
x;
4104 bc->
y0 = (stbtt_int16) r->
y;
4105 bc->
x1 = (stbtt_int16) (r->
x + r->
w);
4106 bc->
y1 = (stbtt_int16) (r->
y + r->
h);
4108 bc->
xoff = (float) x0 * recip_h + sub_x;
4109 bc->
yoff = (float) y0 * recip_v + sub_y;
4110 bc->
xoff2 = (x0 + r->
w) * recip_h + sub_x;
4111 bc->
yoff2 = (y0 + r->
h) * recip_v + sub_y;
4124 return return_value;
4135 int i,j,n, return_value;
4140 for (i=0; i < num_ranges; ++i)
4142 ranges[i].chardata_for_range[j].x0 =
4143 ranges[i].chardata_for_range[j].y0 =
4144 ranges[i].chardata_for_range[j].x1 =
4145 ranges[i].chardata_for_range[j].y1 = 0;
4148 for (i=0; i < num_ranges; ++i)
4149 n += ranges[i].num_chars;
4165 return return_value;
4169 int first_unicode_codepoint_in_range,
int num_chars_in_range,
stbtt_packedchar *chardata_for_range)
4182 int i_ascent, i_descent, i_lineGap;
4188 *ascent = (float) i_ascent * scale;
4189 *descent = (float) i_descent * scale;
4190 *lineGap = (float) i_lineGap * scale;
4195 float ipw = 1.0f / pw, iph = 1.0f / ph;
4198 if (align_to_integer) {
4199 float x = (float) STBTT_ifloor((*xpos + b->
xoff) + 0.5f);
4200 float y = (float) STBTT_ifloor((*ypos + b->
yoff) + 0.5f);
4212 q->
s0 = b->
x0 * ipw;
4213 q->
t0 = b->
y0 * iph;
4214 q->
s1 = b->
x1 * ipw;
4215 q->
t1 = b->
y1 * iph;
4225 #define STBTT_min(a,b) ((a) < (b) ? (a) : (b))
4226 #define STBTT_max(a,b) ((a) < (b) ? (b) : (a))
4228 static int stbtt__ray_intersect_bezier(
float orig[2],
float ray[2],
float q0[2],
float q1[2],
float q2[2],
float hits[2][2])
4230 float q0perp = q0[1]*ray[0] - q0[0]*ray[1];
4231 float q1perp = q1[1]*ray[0] - q1[0]*ray[1];
4232 float q2perp = q2[1]*ray[0] - q2[0]*ray[1];
4233 float roperp = orig[1]*ray[0] - orig[0]*ray[1];
4235 float a = q0perp - 2*q1perp + q2perp;
4236 float b = q1perp - q0perp;
4237 float c = q0perp - roperp;
4239 float s0 = 0., s1 = 0.;
4243 float discr = b*b - a*c;
4245 float rcpna = -1 / a;
4246 float d = (float) STBTT_sqrt(discr);
4249 if (s0 >= 0.0 && s0 <= 1.0)
4251 if (d > 0.0 && s1 >= 0.0 && s1 <= 1.0) {
4252 if (num_s == 0) s0 = s1;
4260 if (s0 >= 0.0 && s0 <= 1.0)
4267 float rcp_len2 = 1 / (ray[0]*ray[0] + ray[1]*ray[1]);
4268 float rayn_x = ray[0] * rcp_len2, rayn_y = ray[1] * rcp_len2;
4270 float q0d = q0[0]*rayn_x + q0[1]*rayn_y;
4271 float q1d = q1[0]*rayn_x + q1[1]*rayn_y;
4272 float q2d = q2[0]*rayn_x + q2[1]*rayn_y;
4273 float rod = orig[0]*rayn_x + orig[1]*rayn_y;
4275 float q10d = q1d - q0d;
4276 float q20d = q2d - q0d;
4277 float q0rd = q0d - rod;
4279 hits[0][0] = q0rd + s0*(2.0f - 2.0f*s0)*q10d + s0*s0*q20d;
4280 hits[0][1] = a*s0+b;
4283 hits[1][0] = q0rd + s1*(2.0f - 2.0f*s1)*q10d + s1*s1*q20d;
4284 hits[1][1] = a*s1+b;
4292 static int equal(
float *a,
float *b)
4294 return (a[0] == b[0] && a[1] == b[1]);
4297 static int stbtt__compute_crossings_x(
float x,
float y,
int nverts,
stbtt_vertex *verts)
4300 float orig[2], ray[2] = { 1, 0 };
4308 y_frac = (float) STBTT_fmod(y, 1.0f);
4311 else if (y_frac > 0.99f)
4316 for (i=0; i < nverts; ++i) {
4318 int x0 = (
int) verts[i-1].x, y0 = (
int) verts[i-1].
y;
4319 int x1 = (
int) verts[i ].x, y1 = (
int) verts[i ].
y;
4320 if (y > STBTT_min(y0,y1) && y < STBTT_max(y0,y1) && x > STBTT_min(x0,x1)) {
4321 float x_inter = (y - y0) / (y1 - y0) * (x1-x0) + x0;
4323 winding += (y0 < y1) ? 1 : -1;
4327 int x0 = (
int) verts[i-1].x , y0 = (
int) verts[i-1].
y ;
4328 int x1 = (
int) verts[i ].cx, y1 = (
int) verts[i ].
cy;
4329 int x2 = (
int) verts[i ].x , y2 = (
int) verts[i ].
y ;
4330 int ax = STBTT_min(x0,STBTT_min(x1,x2)), ay = STBTT_min(y0,STBTT_min(y1,y2));
4331 int by = STBTT_max(y0,STBTT_max(y1,y2));
4332 if (y > ay && y < by && x > ax) {
4333 float q0[2],q1[2],q2[2];
4341 if (equal(q0,q1) || equal(q1,q2)) {
4342 x0 = (
int)verts[i-1].x;
4343 y0 = (
int)verts[i-1].y;
4344 x1 = (
int)verts[i ].x;
4345 y1 = (
int)verts[i ].y;
4346 if (y > STBTT_min(y0,y1) && y < STBTT_max(y0,y1) && x > STBTT_min(x0,x1)) {
4347 float x_inter = (y - y0) / (y1 - y0) * (x1-x0) + x0;
4349 winding += (y0 < y1) ? 1 : -1;
4352 int num_hits = stbtt__ray_intersect_bezier(orig, ray, q0, q1, q2, hits);
4355 winding += (hits[0][1] < 0 ? -1 : 1);
4358 winding += (hits[1][1] < 0 ? -1 : 1);
4366 static float stbtt__cuberoot(
float x )
4369 return -(float) STBTT_pow(-x,1.0f/3.0f);
4371 return (
float) STBTT_pow( x,1.0f/3.0f);
4375 static int stbtt__solve_cubic(
float a,
float b,
float c,
float* r)
4378 float p = b - a*a / 3;
4379 float q = a * (2*a*a - 9*b) / 27 + c;
4381 float d = q*q + 4*p3 / 27;
4383 float z = (float) STBTT_sqrt(d);
4384 float u = (-q + z) / 2;
4385 float v = (-q - z) / 2;
4386 u = stbtt__cuberoot(u);
4387 v = stbtt__cuberoot(v);
4391 float u = (float) STBTT_sqrt(-p/3);
4392 float v = (float) STBTT_acos(-STBTT_sqrt(-27/p3) * q / 2) / 3;
4393 float m = (float) STBTT_cos(v);
4394 float n = (float) STBTT_cos(v-3.141592/2)*1.732050808f;
4395 r[0] = s + u * 2 * m;
4396 r[1] = s - u * (m + n);
4397 r[2] = s - u * (m - n);
4406 STBTT_DEF unsigned char *
stbtt_GetGlyphSDF(
const stbtt_fontinfo *info,
float scale,
int glyph,
int padding,
unsigned char onedge_value,
float pixel_dist_scale,
int *width,
int *height,
int *xoff,
int *yoff)
4408 float scale_x = scale, scale_y = scale;
4409 int ix0,iy0,ix1,iy1;
4411 unsigned char *data;
4414 if (scale_x == 0) scale_x = scale_y;
4416 if (scale_x == 0)
return NULL;
4423 if (ix0 == ix1 || iy0 == iy1)
4434 if (width ) *width = w;
4435 if (height) *height = h;
4436 if (xoff ) *xoff = ix0;
4437 if (yoff ) *yoff = iy0;
4447 data = (
unsigned char *) STBTT_malloc(w * h, info->
userdata);
4448 precompute = (
float *) STBTT_malloc(num_verts *
sizeof(
float), info->
userdata);
4450 for (i=0,j=num_verts-1; i < num_verts; j=i++) {
4452 float x0 = verts[i].
x*scale_x, y0 = verts[i].
y*scale_y;
4453 float x1 = verts[j].
x*scale_x, y1 = verts[j].
y*scale_y;
4454 float dist = (float) STBTT_sqrt((x1-x0)*(x1-x0) + (y1-y0)*(y1-y0));
4455 precompute[i] = (dist == 0) ? 0.0f : 1.0f / dist;
4457 float x2 = verts[j].
x *scale_x, y2 = verts[j].
y *scale_y;
4458 float x1 = verts[i].
cx*scale_x, y1 = verts[i].
cy*scale_y;
4459 float x0 = verts[i].
x *scale_x, y0 = verts[i].
y *scale_y;
4460 float bx = x0 - 2*x1 + x2, by = y0 - 2*y1 + y2;
4461 float len2 = bx*bx + by*by;
4463 precompute[i] = 1.0f / (bx*bx + by*by);
4465 precompute[i] = 0.0f;
4467 precompute[i] = 0.0f;
4470 for (y=iy0; y < iy1; ++y) {
4471 for (x=ix0; x < ix1; ++x) {
4473 float min_dist = 999999.0f;
4474 float sx = (float) x + 0.5f;
4475 float sy = (float) y + 0.5f;
4476 float x_gspace = (sx / scale_x);
4477 float y_gspace = (sy / scale_y);
4479 int winding = stbtt__compute_crossings_x(x_gspace, y_gspace, num_verts, verts);
4481 for (i=0; i < num_verts; ++i) {
4482 float x0 = verts[i].
x*scale_x, y0 = verts[i].
y*scale_y;
4485 float dist2 = (x0-sx)*(x0-sx) + (y0-sy)*(y0-sy);
4486 if (dist2 < min_dist*min_dist)
4487 min_dist = (float) STBTT_sqrt(dist2);
4490 float x1 = verts[i-1].
x*scale_x, y1 = verts[i-1].
y*scale_y;
4495 float dist = (float) STBTT_fabs((x1-x0)*(y0-sy) - (y1-y0)*(x0-sx)) * precompute[i];
4496 STBTT_assert(i != 0);
4497 if (dist < min_dist) {
4501 float dx = x1-x0, dy = y1-y0;
4502 float px = x0-sx, py = y0-sy;
4505 float t = -(px*dx + py*dy) / (dx*dx + dy*dy);
4506 if (t >= 0.0f && t <= 1.0f)
4510 float x2 = verts[i-1].
x *scale_x, y2 = verts[i-1].
y *scale_y;
4511 float x1 = verts[i ].
cx*scale_x, y1 = verts[i ].
cy*scale_y;
4512 float box_x0 = STBTT_min(STBTT_min(x0,x1),x2);
4513 float box_y0 = STBTT_min(STBTT_min(y0,y1),y2);
4514 float box_x1 = STBTT_max(STBTT_max(x0,x1),x2);
4515 float box_y1 = STBTT_max(STBTT_max(y0,y1),y2);
4517 if (sx > box_x0-min_dist && sx < box_x1+min_dist && sy > box_y0-min_dist && sy < box_y1+min_dist) {
4519 float ax = x1-x0, ay = y1-y0;
4520 float bx = x0 - 2*x1 + x2, by = y0 - 2*y1 + y2;
4521 float mx = x0 - sx, my = y0 - sy;
4522 float res[3],px,py,t,it;
4523 float a_inv = precompute[i];
4525 float a = 3*(ax*bx + ay*by);
4526 float b = 2*(ax*ax + ay*ay) + (mx*bx+my*by);
4527 float c = mx*ax+my*ay;
4533 float discriminant = b*b - 4*a*c;
4534 if (discriminant < 0)
4537 float root = (float) STBTT_sqrt(discriminant);
4538 res[0] = (-b - root)/(2*a);
4539 res[1] = (-b + root)/(2*a);
4544 float b = 3*(ax*bx + ay*by) * a_inv;
4545 float c = (2*(ax*ax + ay*ay) + (mx*bx+my*by)) * a_inv;
4546 float d = (mx*ax+my*ay) * a_inv;
4547 num = stbtt__solve_cubic(b, c, d, res);
4549 if (num >= 1 && res[0] >= 0.0f && res[0] <= 1.0f) {
4550 t = res[0], it = 1.0f - t;
4551 px = it*it*x0 + 2*t*it*x1 + t*t*x2;
4552 py = it*it*y0 + 2*t*it*y1 + t*t*y2;
4553 dist2 = (px-sx)*(px-sx) + (py-sy)*(py-sy);
4554 if (dist2 < min_dist * min_dist)
4555 min_dist = (float) STBTT_sqrt(dist2);
4557 if (num >= 2 && res[1] >= 0.0f && res[1] <= 1.0f) {
4558 t = res[1], it = 1.0f - t;
4559 px = it*it*x0 + 2*t*it*x1 + t*t*x2;
4560 py = it*it*y0 + 2*t*it*y1 + t*t*y2;
4561 dist2 = (px-sx)*(px-sx) + (py-sy)*(py-sy);
4562 if (dist2 < min_dist * min_dist)
4563 min_dist = (float) STBTT_sqrt(dist2);
4565 if (num >= 3 && res[2] >= 0.0f && res[2] <= 1.0f) {
4566 t = res[2], it = 1.0f - t;
4567 px = it*it*x0 + 2*t*it*x1 + t*t*x2;
4568 py = it*it*y0 + 2*t*it*y1 + t*t*y2;
4569 dist2 = (px-sx)*(px-sx) + (py-sy)*(py-sy);
4570 if (dist2 < min_dist * min_dist)
4571 min_dist = (float) STBTT_sqrt(dist2);
4577 min_dist = -min_dist;
4578 val = onedge_value + pixel_dist_scale * min_dist;
4583 data[(y-iy0)*w+(x-ix0)] = (
unsigned char) val;
4586 STBTT_free(precompute, info->
userdata);
4592 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)
4594 return stbtt_GetGlyphSDF(info, scale,
stbtt_FindGlyphIndex(info, codepoint), padding, onedge_value, pixel_dist_scale, width, height, xoff, yoff);
4599 STBTT_free(bitmap, userdata);
4608 static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(stbtt_uint8 *s1, stbtt_int32 len1, stbtt_uint8 *s2, stbtt_int32 len2)
4614 stbtt_uint16 ch = s2[0]*256 + s2[1];
4616 if (i >= len1)
return -1;
4617 if (s1[i++] != ch)
return -1;
4618 }
else if (ch < 0x800) {
4619 if (i+1 >= len1)
return -1;
4620 if (s1[i++] != 0xc0 + (ch >> 6))
return -1;
4621 if (s1[i++] != 0x80 + (ch & 0x3f))
return -1;
4622 }
else if (ch >= 0xd800 && ch < 0xdc00) {
4624 stbtt_uint16 ch2 = s2[2]*256 + s2[3];
4625 if (i+3 >= len1)
return -1;
4626 c = ((ch - 0xd800) << 10) + (ch2 - 0xdc00) + 0x10000;
4627 if (s1[i++] != 0xf0 + (c >> 18))
return -1;
4628 if (s1[i++] != 0x80 + ((c >> 12) & 0x3f))
return -1;
4629 if (s1[i++] != 0x80 + ((c >> 6) & 0x3f))
return -1;
4630 if (s1[i++] != 0x80 + ((c ) & 0x3f))
return -1;
4633 }
else if (ch >= 0xdc00 && ch < 0xe000) {
4636 if (i+2 >= len1)
return -1;
4637 if (s1[i++] != 0xe0 + (ch >> 12))
return -1;
4638 if (s1[i++] != 0x80 + ((ch >> 6) & 0x3f))
return -1;
4639 if (s1[i++] != 0x80 + ((ch ) & 0x3f))
return -1;
4647 static int stbtt_CompareUTF8toUTF16_bigendian_internal(
char *s1,
int len1,
char *s2,
int len2)
4649 return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((stbtt_uint8*) s1, len1, (stbtt_uint8*) s2, len2);
4656 stbtt_int32 i,count,stringOffset;
4657 stbtt_uint8 *fc = font->
data;
4659 stbtt_uint32 nm = stbtt__find_table(fc, offset,
"name");
4660 if (!nm)
return NULL;
4662 count = ttUSHORT(fc+nm+2);
4663 stringOffset = nm + ttUSHORT(fc+nm+4);
4664 for (i=0; i < count; ++i) {
4665 stbtt_uint32 loc = nm + 6 + 12 * i;
4666 if (platformID == ttUSHORT(fc+loc+0) && encodingID == ttUSHORT(fc+loc+2)
4667 && languageID == ttUSHORT(fc+loc+4) && nameID == ttUSHORT(fc+loc+6)) {
4668 *length = ttUSHORT(fc+loc+8);
4669 return (
const char *) (fc+stringOffset+ttUSHORT(fc+loc+10));
4675 static int stbtt__matchpair(stbtt_uint8 *fc, stbtt_uint32 nm, stbtt_uint8 *name, stbtt_int32 nlen, stbtt_int32 target_id, stbtt_int32 next_id)
4678 stbtt_int32 count = ttUSHORT(fc+nm+2);
4679 stbtt_int32 stringOffset = nm + ttUSHORT(fc+nm+4);
4681 for (i=0; i < count; ++i) {
4682 stbtt_uint32 loc = nm + 6 + 12 * i;
4683 stbtt_int32
id = ttUSHORT(fc+loc+6);
4684 if (
id == target_id) {
4686 stbtt_int32 platform = ttUSHORT(fc+loc+0), encoding = ttUSHORT(fc+loc+2), language = ttUSHORT(fc+loc+4);
4689 if (platform == 0 || (platform == 3 && encoding == 1) || (platform == 3 && encoding == 10)) {
4690 stbtt_int32 slen = ttUSHORT(fc+loc+8);
4691 stbtt_int32 off = ttUSHORT(fc+loc+10);
4694 stbtt_int32 matchlen = stbtt__CompareUTF8toUTF16_bigendian_prefix(name, nlen, fc+stringOffset+off,slen);
4695 if (matchlen >= 0) {
4697 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) {
4698 slen = ttUSHORT(fc+loc+12+8);
4699 off = ttUSHORT(fc+loc+12+10);
4701 if (matchlen == nlen)
4703 }
else if (matchlen < nlen && name[matchlen] ==
' ') {
4705 if (stbtt_CompareUTF8toUTF16_bigendian_internal((
char*) (name+matchlen), nlen-matchlen, (
char*)(fc+stringOffset+off),slen))
4710 if (matchlen == nlen)
4722 static int stbtt__matches(stbtt_uint8 *fc, stbtt_uint32 offset, stbtt_uint8 *name, stbtt_int32 flags)
4724 stbtt_int32 nlen = (stbtt_int32) STBTT_strlen((
char *) name);
4726 if (!stbtt__isfont(fc+offset))
return 0;
4730 hd = stbtt__find_table(fc, offset,
"head");
4731 if ((ttUSHORT(fc+hd+44) & 7) != (flags & 7))
return 0;
4734 nm = stbtt__find_table(fc, offset,
"name");
4739 if (stbtt__matchpair(fc, nm, name, nlen, 16, -1))
return 1;
4740 if (stbtt__matchpair(fc, nm, name, nlen, 1, -1))
return 1;
4741 if (stbtt__matchpair(fc, nm, name, nlen, 3, -1))
return 1;
4743 if (stbtt__matchpair(fc, nm, name, nlen, 16, 17))
return 1;
4744 if (stbtt__matchpair(fc, nm, name, nlen, 1, 2))
return 1;
4745 if (stbtt__matchpair(fc, nm, name, nlen, 3, -1))
return 1;
4751 static int stbtt_FindMatchingFont_internal(
unsigned char *font_collection,
char *name_utf8, stbtt_int32 flags)
4756 if (off < 0)
return off;
4757 if (stbtt__matches((stbtt_uint8 *) font_collection, off, (stbtt_uint8*) name_utf8, flags))
4762 #if defined(__GNUC__) || defined(__clang__)
4763 #pragma GCC diagnostic push
4764 #pragma GCC diagnostic ignored "-Wcast-qual"
4768 float pixel_height,
unsigned char *pixels,
int pw,
int ph,
4771 return stbtt_BakeFontBitmap_internal((
unsigned char *) data, offset, pixel_height, pixels, pw, ph, first_char, num_chars, chardata);
4776 return stbtt_GetFontOffsetForIndex_internal((
unsigned char *) data, index);
4781 return stbtt_GetNumberOfFonts_internal((
unsigned char *) data);
4786 return stbtt_InitFont_internal(info, (
unsigned char *) data, offset);
4791 return stbtt_FindMatchingFont_internal((
unsigned char *) fontdata, (
char *) name, flags);
4796 return stbtt_CompareUTF8toUTF16_bigendian_internal((
char *) s1, len1, (
char *) s2, len2);
4799 #if defined(__GNUC__) || defined(__clang__)
4800 #pragma GCC diagnostic pop
4803 #endif // STB_TRUETYPE_IMPLEMENTATION
int w
Definition: stb_truetype.h:893
STBTT_DEF unsigned char * stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff)
STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2)
STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1)
int kern
Definition: stb_truetype.h:707
Definition: stb_truetype.h:1044
int cursor
Definition: stb_truetype.h:511
float t0
Definition: stb_truetype.h:540
unsigned short x1
Definition: stb_truetype.h:524
STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
Definition: stb_truetype.h:1014
STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph)
Definition: stb_truetype.h:522
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)
STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2)
stbtt_packedchar * chardata_for_range
Definition: stb_truetype.h:618
Definition: stb_truetype.h:1036
int index_map
Definition: stb_truetype.h:708
unsigned int v_oversample
Definition: stb_truetype.h:672
Definition: stb_truetype.h:1020
float x1
Definition: stb_truetype.h:541
STBTT_DEF int stbtt_GetNumberOfFonts(const unsigned char *data)
Definition: stb_truetype.h:1056
Definition: stb_truetype.h:1027
float xoff
Definition: stb_truetype.h:525
int * array_of_unicode_codepoints
Definition: stb_truetype.h:616
int stride
Definition: stb_truetype.h:893
float x0
Definition: stb_truetype.h:540
STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **vertices)
Definition: stb_truetype.h:1045
unsigned char type
Definition: stb_truetype.h:811
stbtt_vertex_type cy
Definition: stb_truetype.h:810
Definition: stb_truetype.h:1051
Definition: stb_truetype.h:1047
int height
Definition: stb_rect_pack.h:175
STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, float font_size, int first_unicode_char_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range)
Definition: stb_rect_pack.h:106
Definition: stb_truetype.h:1030
Definition: stb_rect_pack.h:166
Definition: stb_truetype.h:1042
STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects)
STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int width, int height, int stride_in_bytes, int padding, void *alloc_context)
Definition: stb_truetype.h:538
STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1)
Definition: stb_truetype.h:1036
STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes)
Definition: stb_truetype.h:1029
voidpf void uLong size
Definition: ioapi.h:39
STBTT_DEF void stbtt_PackEnd(stbtt_pack_context *spc)
STBTT_DEF void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect *rects, int num_rects)
STBTT_DEF void stbtt_MakeGlyphBitmapSubpixelPrefilter(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int oversample_x, int oversample_y, float *sub_x, float *sub_y, int glyph)
stbtt__buf fdselect
Definition: stb_truetype.h:716
Definition: stb_truetype.h:800
Definition: stb_truetype.h:1043
STBTT_DEF void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata)
Definition: stb_truetype.h:1037
unsigned int h_oversample
Definition: stb_truetype.h:672
unsigned int GLuint
Definition: DtGlTextureBufferObject.h:18
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
Definition: stb_truetype.h:1045
Definition: stb_truetype.h:1035
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)
stbtt__buf cff
Definition: stb_truetype.h:711
unsigned short y1
Definition: stb_truetype.h:570
unsigned char * pixels
Definition: stb_truetype.h:894
STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1)
STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph)
stbtt__buf subrs
Definition: stb_truetype.h:714
Definition: stb_truetype.h:1023
void * nodes
Definition: stb_truetype.h:674
struct stbrp_context stbrp_context
Definition: stb_rect_pack.h:71
Definition: stb_truetype.h:1054
unsigned char v_oversample
Definition: stb_truetype.h:619
unsigned short stbrp_coord
Definition: stb_rect_pack.h:78
stbtt_vertex_type y
Definition: stb_truetype.h:810
int numGlyphs
Definition: stb_truetype.h:705
Definition: stb_truetype.h:1053
Definition: stb_truetype.h:612
stbrp_coord y
Definition: stb_rect_pack.h:115
Definition: stb_truetype.h:1051
Definition: stb_truetype.h:1046
STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, float shift_x, float shift_y, int x_off, int y_off, int invert, void *userdata)
STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1)
STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges)
Definition: stb_truetype.h:1021
STBTT_DEF const char * stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID)
stbtt__buf charstrings
Definition: stb_truetype.h:712
Definition: stb_truetype.h:1054
STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1)
Definition: stb_truetype.h:1055
int hmtx
Definition: stb_truetype.h:707
int was_packed
Definition: stb_rect_pack.h:116
Definition: stb_truetype.h:1044
Definition: stb_truetype.h:1047
STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices)
STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing)
float xadvance
Definition: stb_truetype.h:525
stbtt__buf gsubrs
Definition: stb_truetype.h:713
int height
Definition: stb_truetype.h:669
int head
Definition: stb_truetype.h:707
STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap)
STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset)
int hhea
Definition: stb_truetype.h:707
int glyf
Definition: stb_truetype.h:707
Definition: stb_truetype.h:1028
Definition: stb_truetype.h:1057
stbrp_coord x
Definition: stb_rect_pack.h:115
stbtt_vertex_type x
Definition: stb_truetype.h:810
float yoff2
Definition: stb_truetype.h:572
Definition: stb_truetype.h:1034
unsigned short x1
Definition: stb_truetype.h:570
STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float scale, int glyph, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff)
#define stbtt_vertex_type
Definition: imstb_truetype.h:823
Definition: stb_truetype.h:665
STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2)
float s0
Definition: stb_truetype.h:540
int fontstart
Definition: stb_truetype.h:703
Definition: stb_truetype.h:1055
float yoff
Definition: stb_truetype.h:571
stbrp_coord w
Definition: stb_rect_pack.h:112
STBTT_DEF void stbtt_GetBakedQuad(const stbtt_bakedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int opengl_fillrule)
void * pack_info
Definition: stb_truetype.h:667
STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint)
struct stbrp_node stbrp_node
Definition: stb_rect_pack.h:72
Definition: stb_truetype.h:1035
#define STBTT_DEF
Definition: imstb_truetype.h:506
Definition: stb_truetype.h:799
unsigned short y0
Definition: stb_truetype.h:570
Definition: stb_rect_pack.h:172
float xoff
Definition: stb_truetype.h:571
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)
int skip_missing
Definition: imstb_truetype.h:686
Definition: asyncJobServer.h:39
unsigned char * data
Definition: stb_truetype.h:702
unsigned char h_oversample
Definition: stb_truetype.h:619
STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1)
Definition: stb_truetype.h:568
Definition: stb_truetype.h:1019
void * user_allocator_context
Definition: stb_truetype.h:666
Definition: stb_truetype.h:1015
Definition: stb_truetype.h:508
Definition: stb_truetype.h:1043
stbtt_vertex_type cx
Definition: stb_truetype.h:810
Definition: stb_truetype.h:1034
float s1
Definition: stb_truetype.h:541
Definition: stb_truetype.h:1013
stbtt__buf fontdicts
Definition: stb_truetype.h:715
int width
Definition: stb_rect_pack.h:174
float font_size
Definition: stb_truetype.h:614
unsigned short x0
Definition: stb_truetype.h:524
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)
Definition: stb_truetype.h:1012
Definition: stb_truetype.h:1037
int size
Definition: stb_truetype.h:512
Definition: stb_truetype.h:1053
STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index)
DT_DLL_VRVCORE double length(const makVrv::DtCoordinateSystem &, const std::vector< DtVector > &vertices)
Returns the total distance of a segmented line defined by the provided vector of vertices. Coordinates are in local database coordinates. The coordinate system is used to convert between the local database coordinates and geocentric. All distance is in 2D – the Z value is ignored.
STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1)
unsigned char * data
Definition: stb_truetype.h:510
Definition: stb_truetype.h:699
STBTT_DEF float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels)
stbrp_coord h
Definition: stb_rect_pack.h:112
int first_unicode_codepoint_in_range
Definition: stb_truetype.h:615
float y0
Definition: stb_truetype.h:540
STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing)
Definition: stb_truetype.h:1042
int h
Definition: stb_truetype.h:893
STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample)
STBTT_DEF int stbtt_GetFontVMetricsOS2(const stbtt_fontinfo *info, int *typoAscent, int *typoDescent, int *typoLineGap)
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)
unsigned char * pixels
Definition: stb_truetype.h:673
unsigned short y0
Definition: stb_truetype.h:524
STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint)
int indexToLocFormat
Definition: stb_truetype.h:709
float yoff
Definition: stb_truetype.h:525
STBTT_DEF void stbtt_GetScaledFontVMetrics(const unsigned char *fontdata, int index, float size, float *ascent, float *descent, float *lineGap)
Definition: stb_truetype.h:798
STBTT_DEF void stbtt_FreeSDF(unsigned char *bitmap, void *userdata)
STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, float pixel_height, unsigned char *pixels, int pw, int ph, int first_char, int num_chars, stbtt_bakedchar *chardata)
int id
Definition: stb_rect_pack.h:109
STBTT_DEF void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context *spc, int skip)
Definition: stb_truetype.h:1046
float xadvance
Definition: stb_truetype.h:571
STBTT_DEF float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float pixels)
Definition: stb_truetype.h:1056
unsigned short y1
Definition: stb_truetype.h:524
float xoff2
Definition: stb_truetype.h:572
Definition: stb_truetype.h:1057
voidpf uLong offset
Definition: ioapi.h:42
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)
STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index)
int stride_in_bytes
Definition: stb_truetype.h:670
Definition: stb_truetype.h:808
int gpos
Definition: stb_truetype.h:707
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)
int padding
Definition: stb_truetype.h:671
int num_chars
Definition: stb_truetype.h:617
float y1
Definition: stb_truetype.h:541
void * userdata
Definition: stb_truetype.h:701
Definition: stb_truetype.h:1052
Definition: stb_truetype.h:801
float t1
Definition: stb_truetype.h:541
int loca
Definition: stb_truetype.h:707
STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *fontdata, const char *name, int flags)
Definition: stb_truetype.h:891
unsigned short x0
Definition: stb_truetype.h:570
STBTT_DEF int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices)
Definition: stb_truetype.h:1052
int width
Definition: stb_truetype.h:668
STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects)
Definition: stb_truetype.h:1022