|
|
|
@ -855,6 +855,7 @@ STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, s |
|
|
|
|
STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices); |
|
|
|
|
// frees the data allocated above
|
|
|
|
|
|
|
|
|
|
STBTT_DEF stbtt_uint8 *stbtt_FindSVGDoc(const stbtt_fontinfo *info, int gl) |
|
|
|
|
STBTT_DEF int stbtt_GetCodepointSVG(const stbtt_fontinfo *info, int unicode_codepoint, const char **svg); |
|
|
|
|
STBTT_DEF int stbtt_GetGlyphSVG(const stbtt_fontinfo *info, int gl, const char **svg); |
|
|
|
|
// fills svg with the character's SVG data.
|
|
|
|
@ -2136,7 +2137,7 @@ static int stbtt__run_charstring(const stbtt_fontinfo *info, int glyph_index, st |
|
|
|
|
subrs = stbtt__cid_get_glyph_subrs(info, glyph_index); |
|
|
|
|
has_subrs = 1; |
|
|
|
|
} |
|
|
|
|
// fallthrough
|
|
|
|
|
// FALLTHROUGH
|
|
|
|
|
case 0x1D: // callgsubr
|
|
|
|
|
if (sp < 1) return STBTT__CSERR("call(g|)subr stack"); |
|
|
|
|
v = (int) s[--sp]; |
|
|
|
@ -2407,7 +2408,8 @@ static stbtt_int32 stbtt__GetCoverageIndex(stbtt_uint8 *coverageTable, int glyp |
|
|
|
|
return m; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} break; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
case 2: { |
|
|
|
|
stbtt_uint16 rangeCount = ttUSHORT(coverageTable + 2); |
|
|
|
@ -2431,12 +2433,10 @@ static stbtt_int32 stbtt__GetCoverageIndex(stbtt_uint8 *coverageTable, int glyp |
|
|
|
|
return startCoverageIndex + glyph - strawStart; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} break; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
default: { |
|
|
|
|
// There are no other cases.
|
|
|
|
|
STBTT_assert(0); |
|
|
|
|
} break; |
|
|
|
|
default: return -1; // unsupported
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return -1; |
|
|
|
@ -2454,7 +2454,8 @@ static stbtt_int32 stbtt__GetGlyphClass(stbtt_uint8 *classDefTable, int glyph) |
|
|
|
|
|
|
|
|
|
if (glyph >= startGlyphID && glyph < startGlyphID + glyphCount) |
|
|
|
|
return (stbtt_int32)ttUSHORT(classDef1ValueArray + 2 * (glyph - startGlyphID)); |
|
|
|
|
} break; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
case 2: { |
|
|
|
|
stbtt_uint16 classRangeCount = ttUSHORT(classDefTable + 2); |
|
|
|
@ -2476,15 +2477,15 @@ static stbtt_int32 stbtt__GetGlyphClass(stbtt_uint8 *classDefTable, int glyph) |
|
|
|
|
else |
|
|
|
|
return (stbtt_int32)ttUSHORT(classRangeRecord + 4); |
|
|
|
|
} |
|
|
|
|
} break; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
default: { |
|
|
|
|
// There are no other cases.
|
|
|
|
|
STBTT_assert(0); |
|
|
|
|
} break; |
|
|
|
|
default: |
|
|
|
|
return -1; // Unsupported definition type, return an error.
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return -1; |
|
|
|
|
// "All glyphs not assigned to a class fall into class 0". (OpenType spec)
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Define to STBTT_assert(x) if you want to break on unimplemented formats.
|
|
|
|
@ -2496,7 +2497,7 @@ static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo *info, i |
|
|
|
|
stbtt_uint8 *lookupList; |
|
|
|
|
stbtt_uint16 lookupCount; |
|
|
|
|
stbtt_uint8 *data; |
|
|
|
|
stbtt_int32 i; |
|
|
|
|
stbtt_int32 i, sti; |
|
|
|
|
|
|
|
|
|
if (!info->gpos) return 0; |
|
|
|
|
|
|
|
|
@ -2516,9 +2517,9 @@ static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo *info, i |
|
|
|
|
stbtt_uint16 lookupType = ttUSHORT(lookupTable); |
|
|
|
|
stbtt_uint16 subTableCount = ttUSHORT(lookupTable + 4); |
|
|
|
|
stbtt_uint8 *subTableOffsets = lookupTable + 6; |
|
|
|
|
switch(lookupType) { |
|
|
|
|
case 2: { // Pair Adjustment Positioning Subtable
|
|
|
|
|
stbtt_int32 sti; |
|
|
|
|
if (lookupType != 2) // Pair Adjustment Positioning Subtable
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
for (sti=0; sti<subTableCount; sti++) { |
|
|
|
|
stbtt_uint16 subtableOffset = ttUSHORT(subTableOffsets + 2 * sti); |
|
|
|
|
stbtt_uint8 *table = lookupTable + subtableOffset; |
|
|
|
@ -2533,20 +2534,15 @@ static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo *info, i |
|
|
|
|
int straw, needle; |
|
|
|
|
stbtt_uint16 valueFormat1 = ttUSHORT(table + 4); |
|
|
|
|
stbtt_uint16 valueFormat2 = ttUSHORT(table + 6); |
|
|
|
|
if (valueFormat1 == 4 && valueFormat2 == 0) { // Support more formats?
|
|
|
|
|
stbtt_int32 valueRecordPairSizeInBytes = 2; |
|
|
|
|
stbtt_uint16 pairSetCount = ttUSHORT(table + 8); |
|
|
|
|
stbtt_uint16 pairPosOffset = ttUSHORT(table + 10 + 2 * coverageIndex); |
|
|
|
|
stbtt_uint8 *pairValueTable = table + pairPosOffset; |
|
|
|
|
stbtt_uint16 pairValueCount = ttUSHORT(pairValueTable); |
|
|
|
|
stbtt_uint8 *pairValueArray = pairValueTable + 2; |
|
|
|
|
// TODO: Support more formats.
|
|
|
|
|
STBTT_GPOS_TODO_assert(valueFormat1 == 4); |
|
|
|
|
if (valueFormat1 != 4) return 0; |
|
|
|
|
STBTT_GPOS_TODO_assert(valueFormat2 == 0); |
|
|
|
|
if (valueFormat2 != 0) return 0; |
|
|
|
|
|
|
|
|
|
STBTT_assert(coverageIndex < pairSetCount); |
|
|
|
|
STBTT__NOTUSED(pairSetCount); |
|
|
|
|
if (coverageIndex >= pairSetCount) return 0; |
|
|
|
|
|
|
|
|
|
needle=glyph2; |
|
|
|
|
r=pairValueCount-1; |
|
|
|
@ -2569,12 +2565,15 @@ static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo *info, i |
|
|
|
|
return xAdvance; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} break; |
|
|
|
|
} else |
|
|
|
|
return 0; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
case 2: { |
|
|
|
|
stbtt_uint16 valueFormat1 = ttUSHORT(table + 4); |
|
|
|
|
stbtt_uint16 valueFormat2 = ttUSHORT(table + 6); |
|
|
|
|
|
|
|
|
|
if (valueFormat1 == 4 && valueFormat2 == 0) { // Support more formats?
|
|
|
|
|
stbtt_uint16 classDef1Offset = ttUSHORT(table + 8); |
|
|
|
|
stbtt_uint16 classDef2Offset = ttUSHORT(table + 10); |
|
|
|
|
int glyph1class = stbtt__GetGlyphClass(table + classDef1Offset, glyph1); |
|
|
|
@ -2582,36 +2581,22 @@ static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo *info, i |
|
|
|
|
|
|
|
|
|
stbtt_uint16 class1Count = ttUSHORT(table + 12); |
|
|
|
|
stbtt_uint16 class2Count = ttUSHORT(table + 14); |
|
|
|
|
STBTT_assert(glyph1class < class1Count); |
|
|
|
|
STBTT_assert(glyph2class < class2Count); |
|
|
|
|
|
|
|
|
|
// TODO: Support more formats.
|
|
|
|
|
STBTT_GPOS_TODO_assert(valueFormat1 == 4); |
|
|
|
|
if (valueFormat1 != 4) return 0; |
|
|
|
|
STBTT_GPOS_TODO_assert(valueFormat2 == 0); |
|
|
|
|
if (valueFormat2 != 0) return 0; |
|
|
|
|
if (glyph1class < 0 || glyph1class >= class1Count) return 0; // malformed
|
|
|
|
|
if (glyph2class < 0 || glyph2class >= class2Count) return 0; // malformed
|
|
|
|
|
|
|
|
|
|
if (glyph1class >= 0 && glyph1class < class1Count && glyph2class >= 0 && glyph2class < class2Count) { |
|
|
|
|
stbtt_uint8 *class1Records = table + 16; |
|
|
|
|
stbtt_uint8 *class2Records = class1Records + 2 * (glyph1class * class2Count); |
|
|
|
|
stbtt_int16 xAdvance = ttSHORT(class2Records + 2 * glyph2class); |
|
|
|
|
return xAdvance; |
|
|
|
|
} |
|
|
|
|
} break; |
|
|
|
|
|
|
|
|
|
default: { |
|
|
|
|
// There are no other cases.
|
|
|
|
|
STBTT_assert(0); |
|
|
|
|
} else |
|
|
|
|
return 0; |
|
|
|
|
break; |
|
|
|
|
}; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
default: |
|
|
|
|
// TODO: Implement other stuff.
|
|
|
|
|
break; |
|
|
|
|
return 0; // Unsupported position format
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -4624,7 +4609,8 @@ STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float sc |
|
|
|
|
float ax = x1-x0, ay = y1-y0; |
|
|
|
|
float bx = x0 - 2*x1 + x2, by = y0 - 2*y1 + y2; |
|
|
|
|
float mx = x0 - sx, my = y0 - sy; |
|
|
|
|
float res[3],px,py,t,it,dist2; |
|
|
|
|
float res[3] = {0.f,0.f,0.f}; |
|
|
|
|
float px,py,t,it,dist2; |
|
|
|
|
float a_inv = precompute[i]; |
|
|
|
|
if (a_inv == 0.0) { // if a_inv is 0, it's 2nd degree so use quadratic formula
|
|
|
|
|
float a = 3*(ax*bx + ay*by); |
|
|
|
|