stb_truetype: GPOS handling formatting changes

Was using 4-character spaces and otherwise formatted unlike the
rest of the code, fix this. Also get rid of the outer switch in
GetGlyphGPOSInfoAdvance with just one case; just use an if.
No behavioral changes.
master
Fabian Giesen ago%!(EXTRA string=4 years)
parent 1252a3e641
commit 9fe3b4bb52
  1. 409
      stb_truetype.h

@ -2353,7 +2353,7 @@ STBTT_DEF int stbtt_GetKerningTable(const stbtt_fontinfo *info, stbtt_kerningent
return length; return length;
} }
static int stbtt__GetGlyphKernInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2) static int stbtt__GetGlyphKernInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2)
{ {
stbtt_uint8 *data = info->data + info->kern; stbtt_uint8 *data = info->data + info->kern;
stbtt_uint32 needle, straw; stbtt_uint32 needle, straw;
@ -2383,232 +2383,223 @@ static int stbtt__GetGlyphKernInfoAdvance(const stbtt_fontinfo *info, int glyph
return 0; return 0;
} }
static stbtt_int32 stbtt__GetCoverageIndex(stbtt_uint8 *coverageTable, int glyph) static stbtt_int32 stbtt__GetCoverageIndex(stbtt_uint8 *coverageTable, int glyph)
{ {
stbtt_uint16 coverageFormat = ttUSHORT(coverageTable); stbtt_uint16 coverageFormat = ttUSHORT(coverageTable);
switch(coverageFormat) { switch (coverageFormat) {
case 1: { case 1: {
stbtt_uint16 glyphCount = ttUSHORT(coverageTable + 2); stbtt_uint16 glyphCount = ttUSHORT(coverageTable + 2);
// Binary search. // Binary search.
stbtt_int32 l=0, r=glyphCount-1, m; stbtt_int32 l=0, r=glyphCount-1, m;
int straw, needle=glyph; int straw, needle=glyph;
while (l <= r) { while (l <= r) {
stbtt_uint8 *glyphArray = coverageTable + 4; stbtt_uint8 *glyphArray = coverageTable + 4;
stbtt_uint16 glyphID; stbtt_uint16 glyphID;
m = (l + r) >> 1; m = (l + r) >> 1;
glyphID = ttUSHORT(glyphArray + 2 * m); glyphID = ttUSHORT(glyphArray + 2 * m);
straw = glyphID; straw = glyphID;
if (needle < straw) if (needle < straw)
r = m - 1; r = m - 1;
else if (needle > straw) else if (needle > straw)
l = m + 1; l = m + 1;
else { else {
return m; return m;
}
} }
} break; }
break;
case 2: { }
stbtt_uint16 rangeCount = ttUSHORT(coverageTable + 2);
stbtt_uint8 *rangeArray = coverageTable + 4; case 2: {
stbtt_uint16 rangeCount = ttUSHORT(coverageTable + 2);
// Binary search. stbtt_uint8 *rangeArray = coverageTable + 4;
stbtt_int32 l=0, r=rangeCount-1, m;
int strawStart, strawEnd, needle=glyph; // Binary search.
while (l <= r) { stbtt_int32 l=0, r=rangeCount-1, m;
stbtt_uint8 *rangeRecord; int strawStart, strawEnd, needle=glyph;
m = (l + r) >> 1; while (l <= r) {
rangeRecord = rangeArray + 6 * m; stbtt_uint8 *rangeRecord;
strawStart = ttUSHORT(rangeRecord); m = (l + r) >> 1;
strawEnd = ttUSHORT(rangeRecord + 2); rangeRecord = rangeArray + 6 * m;
if (needle < strawStart) strawStart = ttUSHORT(rangeRecord);
r = m - 1; strawEnd = ttUSHORT(rangeRecord + 2);
else if (needle > strawEnd) if (needle < strawStart)
l = m + 1; r = m - 1;
else { else if (needle > strawEnd)
stbtt_uint16 startCoverageIndex = ttUSHORT(rangeRecord + 4); l = m + 1;
return startCoverageIndex + glyph - strawStart; else {
} stbtt_uint16 startCoverageIndex = ttUSHORT(rangeRecord + 4);
return startCoverageIndex + glyph - strawStart;
} }
} break; }
break;
}
default: { default: return -1; // unsupported
// There are no other cases. }
STBTT_assert(0);
} break;
}
return -1; return -1;
} }
static stbtt_int32 stbtt__GetGlyphClass(stbtt_uint8 *classDefTable, int glyph) static stbtt_int32 stbtt__GetGlyphClass(stbtt_uint8 *classDefTable, int glyph)
{ {
stbtt_uint16 classDefFormat = ttUSHORT(classDefTable); stbtt_uint16 classDefFormat = ttUSHORT(classDefTable);
switch(classDefFormat) switch (classDefFormat)
{ {
case 1: { case 1: {
stbtt_uint16 startGlyphID = ttUSHORT(classDefTable + 2); stbtt_uint16 startGlyphID = ttUSHORT(classDefTable + 2);
stbtt_uint16 glyphCount = ttUSHORT(classDefTable + 4); stbtt_uint16 glyphCount = ttUSHORT(classDefTable + 4);
stbtt_uint8 *classDef1ValueArray = classDefTable + 6; stbtt_uint8 *classDef1ValueArray = classDefTable + 6;
if (glyph >= startGlyphID && glyph < startGlyphID + glyphCount)
return (stbtt_int32)ttUSHORT(classDef1ValueArray + 2 * (glyph - startGlyphID));
} break;
case 2: {
stbtt_uint16 classRangeCount = ttUSHORT(classDefTable + 2);
stbtt_uint8 *classRangeRecords = classDefTable + 4;
// Binary search.
stbtt_int32 l=0, r=classRangeCount-1, m;
int strawStart, strawEnd, needle=glyph;
while (l <= r) {
stbtt_uint8 *classRangeRecord;
m = (l + r) >> 1;
classRangeRecord = classRangeRecords + 6 * m;
strawStart = ttUSHORT(classRangeRecord);
strawEnd = ttUSHORT(classRangeRecord + 2);
if (needle < strawStart)
r = m - 1;
else if (needle > strawEnd)
l = m + 1;
else
return (stbtt_int32)ttUSHORT(classRangeRecord + 4);
}
} break;
default: { if (glyph >= startGlyphID && glyph < startGlyphID + glyphCount)
// Unsupported defition type; return an error. return (stbtt_int32)ttUSHORT(classDef1ValueArray + 2 * (glyph - startGlyphID));
return -1; break;
} break; }
}
// "All glyphs not assigned to a class fall into class 0". (OpenType spec) case 2: {
return 0; stbtt_uint16 classRangeCount = ttUSHORT(classDefTable + 2);
stbtt_uint8 *classRangeRecords = classDefTable + 4;
// Binary search.
stbtt_int32 l=0, r=classRangeCount-1, m;
int strawStart, strawEnd, needle=glyph;
while (l <= r) {
stbtt_uint8 *classRangeRecord;
m = (l + r) >> 1;
classRangeRecord = classRangeRecords + 6 * m;
strawStart = ttUSHORT(classRangeRecord);
strawEnd = ttUSHORT(classRangeRecord + 2);
if (needle < strawStart)
r = m - 1;
else if (needle > strawEnd)
l = m + 1;
else
return (stbtt_int32)ttUSHORT(classRangeRecord + 4);
}
break;
}
default:
return -1; // Unsupported definition type, return an error.
}
// "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. // Define to STBTT_assert(x) if you want to break on unimplemented formats.
#define STBTT_GPOS_TODO_assert(x) #define STBTT_GPOS_TODO_assert(x)
static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2) static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2)
{ {
stbtt_uint16 lookupListOffset; stbtt_uint16 lookupListOffset;
stbtt_uint8 *lookupList; stbtt_uint8 *lookupList;
stbtt_uint16 lookupCount; stbtt_uint16 lookupCount;
stbtt_uint8 *data; stbtt_uint8 *data;
stbtt_int32 i; stbtt_int32 i, sti;
if (!info->gpos) return 0; if (!info->gpos) return 0;
data = info->data + info->gpos; data = info->data + info->gpos;
if (ttUSHORT(data+0) != 1) return 0; // Major version 1 if (ttUSHORT(data+0) != 1) return 0; // Major version 1
if (ttUSHORT(data+2) != 0) return 0; // Minor version 0 if (ttUSHORT(data+2) != 0) return 0; // Minor version 0
lookupListOffset = ttUSHORT(data+8); lookupListOffset = ttUSHORT(data+8);
lookupList = data + lookupListOffset; lookupList = data + lookupListOffset;
lookupCount = ttUSHORT(lookupList); lookupCount = ttUSHORT(lookupList);
for (i=0; i<lookupCount; ++i) { for (i=0; i<lookupCount; ++i) {
stbtt_uint16 lookupOffset = ttUSHORT(lookupList + 2 + 2 * i); stbtt_uint16 lookupOffset = ttUSHORT(lookupList + 2 + 2 * i);
stbtt_uint8 *lookupTable = lookupList + lookupOffset; stbtt_uint8 *lookupTable = lookupList + lookupOffset;
stbtt_uint16 lookupType = ttUSHORT(lookupTable); stbtt_uint16 lookupType = ttUSHORT(lookupTable);
stbtt_uint16 subTableCount = ttUSHORT(lookupTable + 4); stbtt_uint16 subTableCount = ttUSHORT(lookupTable + 4);
stbtt_uint8 *subTableOffsets = lookupTable + 6; stbtt_uint8 *subTableOffsets = lookupTable + 6;
switch(lookupType) { if (lookupType != 2) // Pair Adjustment Positioning Subtable
case 2: { // Pair Adjustment Positioning Subtable continue;
stbtt_int32 sti;
for (sti=0; sti<subTableCount; sti++) { for (sti=0; sti<subTableCount; sti++) {
stbtt_uint16 subtableOffset = ttUSHORT(subTableOffsets + 2 * sti); stbtt_uint16 subtableOffset = ttUSHORT(subTableOffsets + 2 * sti);
stbtt_uint8 *table = lookupTable + subtableOffset; stbtt_uint8 *table = lookupTable + subtableOffset;
stbtt_uint16 posFormat = ttUSHORT(table); stbtt_uint16 posFormat = ttUSHORT(table);
stbtt_uint16 coverageOffset = ttUSHORT(table + 2); stbtt_uint16 coverageOffset = ttUSHORT(table + 2);
stbtt_int32 coverageIndex = stbtt__GetCoverageIndex(table + coverageOffset, glyph1); stbtt_int32 coverageIndex = stbtt__GetCoverageIndex(table + coverageOffset, glyph1);
if (coverageIndex == -1) continue; if (coverageIndex == -1) continue;
switch (posFormat) { switch (posFormat) {
case 1: { case 1: {
stbtt_int32 l, r, m; stbtt_int32 l, r, m;
int straw, needle; int straw, needle;
stbtt_uint16 valueFormat1 = ttUSHORT(table + 4); stbtt_uint16 valueFormat1 = ttUSHORT(table + 4);
stbtt_uint16 valueFormat2 = ttUSHORT(table + 6); stbtt_uint16 valueFormat2 = ttUSHORT(table + 6);
if (valueFormat1 == 4 && valueFormat2 == 0) { // Support more formats? if (valueFormat1 == 4 && valueFormat2 == 0) { // Support more formats?
stbtt_int32 valueRecordPairSizeInBytes = 2; stbtt_int32 valueRecordPairSizeInBytes = 2;
stbtt_uint16 pairSetCount = ttUSHORT(table + 8); stbtt_uint16 pairSetCount = ttUSHORT(table + 8);
stbtt_uint16 pairPosOffset = ttUSHORT(table + 10 + 2 * coverageIndex); stbtt_uint16 pairPosOffset = ttUSHORT(table + 10 + 2 * coverageIndex);
stbtt_uint8 *pairValueTable = table + pairPosOffset; stbtt_uint8 *pairValueTable = table + pairPosOffset;
stbtt_uint16 pairValueCount = ttUSHORT(pairValueTable); stbtt_uint16 pairValueCount = ttUSHORT(pairValueTable);
stbtt_uint8 *pairValueArray = pairValueTable + 2; stbtt_uint8 *pairValueArray = pairValueTable + 2;
if (coverageIndex >= pairSetCount) return 0; if (coverageIndex >= pairSetCount) return 0;
needle=glyph2; needle=glyph2;
r=pairValueCount-1; r=pairValueCount-1;
l=0; l=0;
// Binary search. // Binary search.
while (l <= r) { while (l <= r) {
stbtt_uint16 secondGlyph; stbtt_uint16 secondGlyph;
stbtt_uint8 *pairValue; stbtt_uint8 *pairValue;
m = (l + r) >> 1; m = (l + r) >> 1;
pairValue = pairValueArray + (2 + valueRecordPairSizeInBytes) * m; pairValue = pairValueArray + (2 + valueRecordPairSizeInBytes) * m;
secondGlyph = ttUSHORT(pairValue); secondGlyph = ttUSHORT(pairValue);
straw = secondGlyph; straw = secondGlyph;
if (needle < straw) if (needle < straw)
r = m - 1; r = m - 1;
else if (needle > straw) else if (needle > straw)
l = m + 1; l = m + 1;
else { else {
stbtt_int16 xAdvance = ttSHORT(pairValue + 2); stbtt_int16 xAdvance = ttSHORT(pairValue + 2);
return xAdvance; return xAdvance;
} }
} }
} else } else
return 0; return 0;
} break; break;
}
case 2: {
stbtt_uint16 valueFormat1 = ttUSHORT(table + 4); case 2: {
stbtt_uint16 valueFormat2 = ttUSHORT(table + 6); stbtt_uint16 valueFormat1 = ttUSHORT(table + 4);
if (valueFormat1 == 4 && valueFormat2 == 0) { // Support more formats? stbtt_uint16 valueFormat2 = ttUSHORT(table + 6);
stbtt_uint16 classDef1Offset = ttUSHORT(table + 8); if (valueFormat1 == 4 && valueFormat2 == 0) { // Support more formats?
stbtt_uint16 classDef2Offset = ttUSHORT(table + 10); stbtt_uint16 classDef1Offset = ttUSHORT(table + 8);
int glyph1class = stbtt__GetGlyphClass(table + classDef1Offset, glyph1); stbtt_uint16 classDef2Offset = ttUSHORT(table + 10);
int glyph2class = stbtt__GetGlyphClass(table + classDef2Offset, glyph2); int glyph1class = stbtt__GetGlyphClass(table + classDef1Offset, glyph1);
int glyph2class = stbtt__GetGlyphClass(table + classDef2Offset, glyph2);
stbtt_uint16 class1Count = ttUSHORT(table + 12);
stbtt_uint16 class2Count = ttUSHORT(table + 14); stbtt_uint16 class1Count = ttUSHORT(table + 12);
stbtt_uint16 class2Count = ttUSHORT(table + 14);
if (glyph1class < 0 || glyph1class >= class1Count) return 0; // malformed
if (glyph2class < 0 || glyph2class >= class2Count) return 0; // malformed if (glyph1class < 0 || glyph1class >= class1Count) return 0; // malformed
if (glyph2class < 0 || glyph2class >= class2Count) return 0; // malformed
stbtt_uint8 *class1Records = table + 16;
stbtt_uint8 *class2Records = class1Records + 2 * (glyph1class * class2Count); stbtt_uint8 *class1Records = table + 16;
stbtt_int16 xAdvance = ttSHORT(class2Records + 2 * glyph2class); stbtt_uint8 *class2Records = class1Records + 2 * (glyph1class * class2Count);
return xAdvance; stbtt_int16 xAdvance = ttSHORT(class2Records + 2 * glyph2class);
} else return xAdvance;
return 0; } else
} break; return 0;
break;
default: { }
// Unsupported definition type
return 0;
break;
};
}
}
break;
};
default: default:
// TODO: Implement other stuff. return 0; // Unsupported position format
break; }
} }
} }
return 0; return 0;
} }
STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int g1, int g2) STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int g1, int g2)

Loading…
Cancel
Save