/** Return the number of tables, or if this is a TTC (collection), return the numberoftablesinthefirstelementofthecollection.Ineithercase, ifoffsetToDirisnot-null,setittotheoffsettothebeginningofthe tableheaders(SkSFNTDirEntry),relativetothestartofthestream.
if (!read(stream, header, sizeof(SkSharedTTHeader))) { return0;
}
// by default, SkSFNTHeader is at the start of the stream
size_t offset = 0;
// if we're really a collection, the first 4-bytes will be 'ttcf'
uint32_t tag = SkEndian_SwapBE32(header->fCollection.fTag); if (SkSetFourByteTag('t', 't', 'c', 'f') == tag) { unsigned count = SkEndian_SwapBE32(header->fCollection.fNumOffsets); if ((unsigned)ttcIndex >= count) { return0;
}
if (ttcIndex > 0) { // need to read more of the shared header
stream->rewind();
size_t amount = sizeof(SkSharedTTHeader) + ttcIndex * sizeof(uint32_t);
header = (SkSharedTTHeader*)storage.reset(amount); if (!read(stream, header, amount)) { return0;
}
} // this is the offset to the local SkSFNTHeader
offset = SkEndian_SwapBE32((&header->fCollection.fOffset0)[ttcIndex]);
stream->rewind(); if (!skip(stream, offset)) { return0;
} if (!read(stream, header, sizeof(SkSFNTHeader))) { return0;
}
}
if (offsetToDir) { // add the size of the header, so we will point to the DirEntries
*offsetToDir = offset + sizeof(SkSFNTHeader);
} return SkEndian_SwapBE16(header->fSingle.fNumTables);
}
/** If it returns true, then fCount and fDir are properly initialized. Note:fDirwillpointtotherawarrayofSkSFNTDirEntryvalues, meaningtheywillstillbeinthefile'snativeendianness(BE).
fDirwillbeautomaticallyfreedwhenthisobjectisdestroyed
*/ bool init(SkStream* stream, int ttcIndex) {
stream->rewind();
int SkFontStream::CountTTCEntries(SkStream* stream) {
stream->rewind();
SkSharedTTHeader shared; if (!read(stream, &shared, sizeof(shared))) { return0;
}
// if we're really a collection, the first 4-bytes will be 'ttcf'
uint32_t tag = SkEndian_SwapBE32(shared.fCollection.fTag); if (SkSetFourByteTag('t', 't', 'c', 'f') == tag) { return SkEndian_SwapBE32(shared.fCollection.fNumOffsets);
} else { return1; // normal 'sfnt' has 1 dir entry
}
}
int SkFontStream::GetTableTags(SkStream* stream, int ttcIndex, SkSpan<SkFontTableTag> tags) {
SfntHeader header; if (!header.init(stream, ttcIndex)) { return0;
}
const size_t n = std::min((size_t)header.fCount, tags.size()); for (size_t i = 0; i < n; i++) {
tags[i] = SkEndian_SwapBE32(header.fDir[i].fTag);
} return header.fCount;
}
for (int i = 0; i < header.fCount; i++) { if (SkEndian_SwapBE32(header.fDir[i].fTag) == tag) {
size_t realOffset = SkEndian_SwapBE32(header.fDir[i].fOffset);
size_t realLength = SkEndian_SwapBE32(header.fDir[i].fLength); if (offset >= realLength) { // invalid return0;
} // if the caller is trusting the length from the file, then a // hostile file might choose a value which would overflow offset + // length. if (offset + length < offset) { return0;
} if (length > realLength - offset) {
length = realLength - offset;
} if (data) { // skip the stream to the part of the table we want to copy from
stream->rewind();
size_t bytesToSkip = realOffset + offset; if (!skip(stream, bytesToSkip)) { return0;
} if (!read(stream, data, length)) { return0;
}
} return length;
}
} return0;
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.18 Sekunden
(vorverarbeitet am 2026-08-26)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.