|
|
|
@ -81,11 +81,11 @@ template <typename REAL>
|
|
|
|
uint32 realTypeCode();
|
|
|
|
uint32 realTypeCode();
|
|
|
|
|
|
|
|
|
|
|
|
template <>
|
|
|
|
template <>
|
|
|
|
uint32 realTypeCode<float>() {
|
|
|
|
inline uint32 realTypeCode<float>() {
|
|
|
|
return 0x14u;
|
|
|
|
return 0x14u;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
template <>
|
|
|
|
template <>
|
|
|
|
uint32 realTypeCode<double>() {
|
|
|
|
inline uint32 realTypeCode<double>() {
|
|
|
|
return 0x18u;
|
|
|
|
return 0x18u;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -97,7 +97,7 @@ inline uint32 paddedLength(uint32 len) {
|
|
|
|
|
|
|
|
|
|
|
|
template <class STRING>
|
|
|
|
template <class STRING>
|
|
|
|
uint32 paddedStringLength(const STRING &str) {
|
|
|
|
uint32 paddedStringLength(const STRING &str) {
|
|
|
|
uint32 len = str.length();
|
|
|
|
uint32 len = (uint32) str.length();
|
|
|
|
return paddedLength(len+(len > 0));
|
|
|
|
return paddedLength(len+(len > 0));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -105,18 +105,18 @@ uint32 paddedStringLength(const STRING &str) {
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef __BIG_ENDIAN__
|
|
|
|
#ifndef __BIG_ENDIAN__
|
|
|
|
|
|
|
|
|
|
|
|
template <int (*READ)(void *, int, void *), typename REAL, template <typename> class LIST, class BYTE_ARRAY, class STRING>
|
|
|
|
template <ReadFunction READ, typename REAL, template <typename> class LIST, class BYTE_ARRAY, class STRING>
|
|
|
|
bool decode(ArteryFont<REAL, LIST, BYTE_ARRAY, STRING> &font, void *userData) {
|
|
|
|
bool decode(ArteryFont<REAL, LIST, BYTE_ARRAY, STRING> &font, void *userData) {
|
|
|
|
uint32 totalLength = 0;
|
|
|
|
uint32 totalLength = 0;
|
|
|
|
uint32 prevLength = 0;
|
|
|
|
uint32 prevLength = 0;
|
|
|
|
uint32 checksum = crc32Init();
|
|
|
|
uint32 checksum = crc32Init();
|
|
|
|
byte dump[4];
|
|
|
|
byte dump[4];
|
|
|
|
#define ARTERY_FONT_DECODE_READ(target, len) { \
|
|
|
|
#define ARTERY_FONT_DECODE_READ(target, len) { \
|
|
|
|
if (READ((void *) (target), (len), userData) != (len)) \
|
|
|
|
if (READ((target), (len), userData) != int(len)) \
|
|
|
|
return false; \
|
|
|
|
return false; \
|
|
|
|
totalLength += (len); \
|
|
|
|
totalLength += (len); \
|
|
|
|
for (int i = 0; i < int(len); ++i) \
|
|
|
|
for (int _i = 0; _i < int(len); ++_i) \
|
|
|
|
checksum = crc32Update(checksum, ((const byte *) (const void *) (target))[i]); \
|
|
|
|
checksum = crc32Update(checksum, reinterpret_cast<const byte *>(target)[_i]); \
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#define ARTERY_FONT_DECODE_REALIGN() { \
|
|
|
|
#define ARTERY_FONT_DECODE_REALIGN() { \
|
|
|
|
if (totalLength&0x03u) { \
|
|
|
|
if (totalLength&0x03u) { \
|
|
|
|
@ -129,7 +129,7 @@ bool decode(ArteryFont<REAL, LIST, BYTE_ARRAY, STRING> &font, void *userData) {
|
|
|
|
LIST<char> characters((len)+1); \
|
|
|
|
LIST<char> characters((len)+1); \
|
|
|
|
ARTERY_FONT_DECODE_READ((char *) characters, (len)+1); \
|
|
|
|
ARTERY_FONT_DECODE_READ((char *) characters, (len)+1); \
|
|
|
|
((char *) characters)[len] = '\0'; \
|
|
|
|
((char *) characters)[len] = '\0'; \
|
|
|
|
(str) = STRING((const char *) characters, uint32(len)); \
|
|
|
|
(str) = STRING((const char *) characters, int(len)); \
|
|
|
|
ARTERY_FONT_DECODE_REALIGN(); \
|
|
|
|
ARTERY_FONT_DECODE_REALIGN(); \
|
|
|
|
} else \
|
|
|
|
} else \
|
|
|
|
(str) = STRING(); \
|
|
|
|
(str) = STRING(); \
|
|
|
|
@ -156,8 +156,8 @@ bool decode(ArteryFont<REAL, LIST, BYTE_ARRAY, STRING> &font, void *userData) {
|
|
|
|
imageCount = header.imageCount;
|
|
|
|
imageCount = header.imageCount;
|
|
|
|
appendixCount = header.appendixCount;
|
|
|
|
appendixCount = header.appendixCount;
|
|
|
|
font.variants = LIST<FontVariant<REAL, LIST, STRING> >(header.variantCount);
|
|
|
|
font.variants = LIST<FontVariant<REAL, LIST, STRING> >(header.variantCount);
|
|
|
|
font.images = LIST<Image<BYTE_ARRAY, STRING> >(header.imageCount);
|
|
|
|
font.images = LIST<FontImage<BYTE_ARRAY, STRING> >(header.imageCount);
|
|
|
|
font.appendices = LIST<Appendix<BYTE_ARRAY, STRING> >(header.appendixCount);
|
|
|
|
font.appendices = LIST<FontAppendix<BYTE_ARRAY, STRING> >(header.appendixCount);
|
|
|
|
variantsLength = header.variantsLength;
|
|
|
|
variantsLength = header.variantsLength;
|
|
|
|
imagesLength = header.imagesLength;
|
|
|
|
imagesLength = header.imagesLength;
|
|
|
|
appendicesLength = header.appendicesLength;
|
|
|
|
appendicesLength = header.appendicesLength;
|
|
|
|
@ -187,7 +187,7 @@ bool decode(ArteryFont<REAL, LIST, BYTE_ARRAY, STRING> &font, void *userData) {
|
|
|
|
prevLength = totalLength;
|
|
|
|
prevLength = totalLength;
|
|
|
|
// Read images
|
|
|
|
// Read images
|
|
|
|
for (int i = 0; i < imageCount; ++i) {
|
|
|
|
for (int i = 0; i < imageCount; ++i) {
|
|
|
|
Image<BYTE_ARRAY, STRING> &image = font.images[i];
|
|
|
|
FontImage<BYTE_ARRAY, STRING> &image = font.images[i];
|
|
|
|
internal::ImageHeader header;
|
|
|
|
internal::ImageHeader header;
|
|
|
|
ARTERY_FONT_DECODE_READ(&header, sizeof(header));
|
|
|
|
ARTERY_FONT_DECODE_READ(&header, sizeof(header));
|
|
|
|
image.flags = header.flags;
|
|
|
|
image.flags = header.flags;
|
|
|
|
@ -211,7 +211,7 @@ bool decode(ArteryFont<REAL, LIST, BYTE_ARRAY, STRING> &font, void *userData) {
|
|
|
|
prevLength = totalLength;
|
|
|
|
prevLength = totalLength;
|
|
|
|
// Read appendices
|
|
|
|
// Read appendices
|
|
|
|
for (int i = 0; i < appendixCount; ++i) {
|
|
|
|
for (int i = 0; i < appendixCount; ++i) {
|
|
|
|
Appendix<BYTE_ARRAY, STRING> &appendix = font.appendices[i];
|
|
|
|
FontAppendix<BYTE_ARRAY, STRING> &appendix = font.appendices[i];
|
|
|
|
internal::AppendixHeader header;
|
|
|
|
internal::AppendixHeader header;
|
|
|
|
ARTERY_FONT_DECODE_READ(&header, sizeof(header));
|
|
|
|
ARTERY_FONT_DECODE_READ(&header, sizeof(header));
|
|
|
|
ARTERY_FONT_DECODE_READ_STRING(appendix.metadata, header.metadataLength);
|
|
|
|
ARTERY_FONT_DECODE_READ_STRING(appendix.metadata, header.metadataLength);
|
|
|
|
@ -228,9 +228,9 @@ bool decode(ArteryFont<REAL, LIST, BYTE_ARRAY, STRING> &font, void *userData) {
|
|
|
|
ARTERY_FONT_DECODE_READ(&footer, sizeof(footer)-sizeof(footer.checksum));
|
|
|
|
ARTERY_FONT_DECODE_READ(&footer, sizeof(footer)-sizeof(footer.checksum));
|
|
|
|
if (footer.magicNo != ARTERY_FONT_FOOTER_MAGIC_NO)
|
|
|
|
if (footer.magicNo != ARTERY_FONT_FOOTER_MAGIC_NO)
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
uint32 prevChecksum = checksum;
|
|
|
|
uint32 finalChecksum = checksum;
|
|
|
|
ARTERY_FONT_DECODE_READ(&footer.checksum, sizeof(footer.checksum));
|
|
|
|
ARTERY_FONT_DECODE_READ(&footer.checksum, sizeof(footer.checksum));
|
|
|
|
if (footer.checksum != prevChecksum)
|
|
|
|
if (footer.checksum != finalChecksum)
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
if (totalLength != footer.totalLength)
|
|
|
|
if (totalLength != footer.totalLength)
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
@ -241,28 +241,28 @@ bool decode(ArteryFont<REAL, LIST, BYTE_ARRAY, STRING> &font, void *userData) {
|
|
|
|
#undef ARTERY_FONT_DECODE_READ_STRING
|
|
|
|
#undef ARTERY_FONT_DECODE_READ_STRING
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template <int (*WRITE)(const void *, int, void *), typename REAL, template <typename> class LIST, class BYTE_ARRAY, class STRING>
|
|
|
|
template <WriteFunction WRITE, typename REAL, template <typename> class LIST, class BYTE_ARRAY, class STRING>
|
|
|
|
bool encode(const ArteryFont<REAL, LIST, BYTE_ARRAY, STRING> &font, void *userData) {
|
|
|
|
bool encode(const ArteryFont<REAL, LIST, BYTE_ARRAY, STRING> &font, void *userData) {
|
|
|
|
uint32 totalLength = 0;
|
|
|
|
uint32 totalLength = 0;
|
|
|
|
uint32 checksum = crc32Init();
|
|
|
|
uint32 checksum = crc32Init();
|
|
|
|
const byte padding[4] = { };
|
|
|
|
const byte padding[4] = { };
|
|
|
|
#define ARTERY_FONT_ENCODE_WRITE(data, len) { \
|
|
|
|
#define ARTERY_FONT_ENCODE_WRITE(data, len) { \
|
|
|
|
if (WRITE((const void *) (data), (len), userData) != (len)) \
|
|
|
|
if (WRITE((data), (len), userData) != int(len)) \
|
|
|
|
return false; \
|
|
|
|
return false; \
|
|
|
|
totalLength += (len); \
|
|
|
|
totalLength += (len); \
|
|
|
|
for (int i = 0; i < int(len); ++i) \
|
|
|
|
for (int _i = 0; _i < int(len); ++_i) \
|
|
|
|
checksum = crc32Update(checksum, ((const byte *) (const void *) (data))[i]); \
|
|
|
|
checksum = crc32Update(checksum, reinterpret_cast<const byte *>(data)[_i]); \
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#define ARTERY_FONT_ENCODE_REALIGN() { \
|
|
|
|
#define ARTERY_FONT_ENCODE_REALIGN() { \
|
|
|
|
if (totalLength&0x03u) { \
|
|
|
|
if (totalLength&0x03u) { \
|
|
|
|
uint32 len = 0x04u-(totalLength&0x03u); \
|
|
|
|
uint32 _len = 0x04u-(totalLength&0x03u); \
|
|
|
|
ARTERY_FONT_ENCODE_WRITE(padding, len); \
|
|
|
|
ARTERY_FONT_ENCODE_WRITE(padding, _len); \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#define ARTERY_FONT_ENCODE_WRITE_STRING(str) { \
|
|
|
|
#define ARTERY_FONT_ENCODE_WRITE_STRING(str) { \
|
|
|
|
uint32 len = (str).length(); \
|
|
|
|
uint32 len = (uint32) (str).length(); \
|
|
|
|
if ((len) > 0) { \
|
|
|
|
if (len > 0) { \
|
|
|
|
ARTERY_FONT_ENCODE_WRITE((const char *) (str), (len)); \
|
|
|
|
ARTERY_FONT_ENCODE_WRITE((const char *) (str), len); \
|
|
|
|
ARTERY_FONT_ENCODE_WRITE(padding, 1) \
|
|
|
|
ARTERY_FONT_ENCODE_WRITE(padding, 1) \
|
|
|
|
ARTERY_FONT_ENCODE_REALIGN(); \
|
|
|
|
ARTERY_FONT_ENCODE_REALIGN(); \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
@ -280,12 +280,12 @@ bool encode(const ArteryFont<REAL, LIST, BYTE_ARRAY, STRING> &font, void *userDa
|
|
|
|
header.realType = internal::realTypeCode<REAL>();
|
|
|
|
header.realType = internal::realTypeCode<REAL>();
|
|
|
|
memset(header.reserved, 0, sizeof(header.reserved));
|
|
|
|
memset(header.reserved, 0, sizeof(header.reserved));
|
|
|
|
header.metadataFormat = (uint32) font.metadataFormat;
|
|
|
|
header.metadataFormat = (uint32) font.metadataFormat;
|
|
|
|
header.metadataLength = font.metadata.length();
|
|
|
|
header.metadataLength = (uint32) font.metadata.length();
|
|
|
|
header.variantCount = variantCount = font.variants.length();
|
|
|
|
header.variantCount = variantCount = (int) font.variants.length();
|
|
|
|
header.variantsLength = 0;
|
|
|
|
header.variantsLength = 0;
|
|
|
|
header.imageCount = imageCount = font.images.length();
|
|
|
|
header.imageCount = imageCount = (int) font.images.length();
|
|
|
|
header.imagesLength = 0;
|
|
|
|
header.imagesLength = 0;
|
|
|
|
header.appendixCount = appendixCount = font.appendices.length();
|
|
|
|
header.appendixCount = appendixCount = (int) font.appendices.length();
|
|
|
|
header.appendicesLength = 0;
|
|
|
|
header.appendicesLength = 0;
|
|
|
|
memset(header.reserved2, 0, sizeof(header.reserved2));
|
|
|
|
memset(header.reserved2, 0, sizeof(header.reserved2));
|
|
|
|
for (int i = 0; i < variantCount; ++i) {
|
|
|
|
for (int i = 0; i < variantCount; ++i) {
|
|
|
|
@ -293,20 +293,20 @@ bool encode(const ArteryFont<REAL, LIST, BYTE_ARRAY, STRING> &font, void *userDa
|
|
|
|
header.variantsLength += sizeof(internal::FontVariantHeader<REAL>);
|
|
|
|
header.variantsLength += sizeof(internal::FontVariantHeader<REAL>);
|
|
|
|
header.variantsLength += internal::paddedStringLength(variant.name);
|
|
|
|
header.variantsLength += internal::paddedStringLength(variant.name);
|
|
|
|
header.variantsLength += internal::paddedStringLength(variant.metadata);
|
|
|
|
header.variantsLength += internal::paddedStringLength(variant.metadata);
|
|
|
|
header.variantsLength += variant.glyphs.length()*sizeof(Glyph<REAL>);
|
|
|
|
header.variantsLength += (uint32) (variant.glyphs.length()*sizeof(Glyph<REAL>));
|
|
|
|
header.variantsLength += variant.kernPairs.length()*sizeof(KernPair<REAL>);
|
|
|
|
header.variantsLength += (uint32) (variant.kernPairs.length()*sizeof(KernPair<REAL>));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (int i = 0; i < imageCount; ++i) {
|
|
|
|
for (int i = 0; i < imageCount; ++i) {
|
|
|
|
const Image<BYTE_ARRAY, STRING> &image = font.images[i];
|
|
|
|
const FontImage<BYTE_ARRAY, STRING> &image = font.images[i];
|
|
|
|
header.imagesLength += sizeof(internal::ImageHeader);
|
|
|
|
header.imagesLength += sizeof(internal::ImageHeader);
|
|
|
|
header.imagesLength += internal::paddedStringLength(image.metadata);
|
|
|
|
header.imagesLength += internal::paddedStringLength(image.metadata);
|
|
|
|
header.imagesLength += internal::paddedLength(image.data.length());
|
|
|
|
header.imagesLength += internal::paddedLength((uint32) image.data.length());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (int i = 0; i < appendixCount; ++i) {
|
|
|
|
for (int i = 0; i < appendixCount; ++i) {
|
|
|
|
const Appendix<BYTE_ARRAY, STRING> &appendix = font.appendices[i];
|
|
|
|
const FontAppendix<BYTE_ARRAY, STRING> &appendix = font.appendices[i];
|
|
|
|
header.appendicesLength += sizeof(internal::AppendixHeader);
|
|
|
|
header.appendicesLength += sizeof(internal::AppendixHeader);
|
|
|
|
header.appendicesLength += internal::paddedStringLength(appendix.metadata);
|
|
|
|
header.appendicesLength += internal::paddedStringLength(appendix.metadata);
|
|
|
|
header.appendicesLength += internal::paddedLength(appendix.data.length());
|
|
|
|
header.appendicesLength += internal::paddedLength((uint32) appendix.data.length());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ARTERY_FONT_ENCODE_WRITE(&header, sizeof(header));
|
|
|
|
ARTERY_FONT_ENCODE_WRITE(&header, sizeof(header));
|
|
|
|
ARTERY_FONT_ENCODE_WRITE_STRING(font.metadata);
|
|
|
|
ARTERY_FONT_ENCODE_WRITE_STRING(font.metadata);
|
|
|
|
@ -323,10 +323,10 @@ bool encode(const ArteryFont<REAL, LIST, BYTE_ARRAY, STRING> &font, void *userDa
|
|
|
|
header.fallbackGlyph = variant.fallbackGlyph;
|
|
|
|
header.fallbackGlyph = variant.fallbackGlyph;
|
|
|
|
memset(header.reserved, 0, sizeof(header.reserved));
|
|
|
|
memset(header.reserved, 0, sizeof(header.reserved));
|
|
|
|
memcpy(header.metrics, &variant.metrics, sizeof(header.metrics));
|
|
|
|
memcpy(header.metrics, &variant.metrics, sizeof(header.metrics));
|
|
|
|
header.nameLength = variant.name.length();
|
|
|
|
header.nameLength = (uint32) variant.name.length();
|
|
|
|
header.metadataLength = variant.metadata.length();
|
|
|
|
header.metadataLength = (uint32) variant.metadata.length();
|
|
|
|
header.glyphCount = variant.glyphs.length();
|
|
|
|
header.glyphCount = (uint32) variant.glyphs.length();
|
|
|
|
header.kernPairCount = variant.kernPairs.length();
|
|
|
|
header.kernPairCount = (uint32) variant.kernPairs.length();
|
|
|
|
ARTERY_FONT_ENCODE_WRITE(&header, sizeof(header));
|
|
|
|
ARTERY_FONT_ENCODE_WRITE(&header, sizeof(header));
|
|
|
|
ARTERY_FONT_ENCODE_WRITE_STRING(variant.name);
|
|
|
|
ARTERY_FONT_ENCODE_WRITE_STRING(variant.name);
|
|
|
|
ARTERY_FONT_ENCODE_WRITE_STRING(variant.metadata);
|
|
|
|
ARTERY_FONT_ENCODE_WRITE_STRING(variant.metadata);
|
|
|
|
@ -335,7 +335,7 @@ bool encode(const ArteryFont<REAL, LIST, BYTE_ARRAY, STRING> &font, void *userDa
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Write images
|
|
|
|
// Write images
|
|
|
|
for (int i = 0; i < imageCount; ++i) {
|
|
|
|
for (int i = 0; i < imageCount; ++i) {
|
|
|
|
const Image<BYTE_ARRAY, STRING> &image = font.images[i];
|
|
|
|
const FontImage<BYTE_ARRAY, STRING> &image = font.images[i];
|
|
|
|
internal::ImageHeader header;
|
|
|
|
internal::ImageHeader header;
|
|
|
|
header.flags = image.flags;
|
|
|
|
header.flags = image.flags;
|
|
|
|
header.encoding = (uint32) image.encoding;
|
|
|
|
header.encoding = (uint32) image.encoding;
|
|
|
|
@ -349,8 +349,8 @@ bool encode(const ArteryFont<REAL, LIST, BYTE_ARRAY, STRING> &font, void *userDa
|
|
|
|
header.childImages = image.childImages;
|
|
|
|
header.childImages = image.childImages;
|
|
|
|
header.textureFlags = image.textureFlags;
|
|
|
|
header.textureFlags = image.textureFlags;
|
|
|
|
memset(header.reserved, 0, sizeof(header.reserved));
|
|
|
|
memset(header.reserved, 0, sizeof(header.reserved));
|
|
|
|
header.metadataLength = image.metadata.length();
|
|
|
|
header.metadataLength = (uint32) image.metadata.length();
|
|
|
|
header.dataLength = image.data.length();
|
|
|
|
header.dataLength = (uint32) image.data.length();
|
|
|
|
ARTERY_FONT_ENCODE_WRITE(&header, sizeof(header));
|
|
|
|
ARTERY_FONT_ENCODE_WRITE(&header, sizeof(header));
|
|
|
|
ARTERY_FONT_ENCODE_WRITE_STRING(image.metadata);
|
|
|
|
ARTERY_FONT_ENCODE_WRITE_STRING(image.metadata);
|
|
|
|
ARTERY_FONT_ENCODE_WRITE((const unsigned char *) image.data, header.dataLength);
|
|
|
|
ARTERY_FONT_ENCODE_WRITE((const unsigned char *) image.data, header.dataLength);
|
|
|
|
@ -358,10 +358,10 @@ bool encode(const ArteryFont<REAL, LIST, BYTE_ARRAY, STRING> &font, void *userDa
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Write appendices
|
|
|
|
// Write appendices
|
|
|
|
for (int i = 0; i < appendixCount; ++i) {
|
|
|
|
for (int i = 0; i < appendixCount; ++i) {
|
|
|
|
const Appendix<BYTE_ARRAY, STRING> &appendix = font.appendices[i];
|
|
|
|
const FontAppendix<BYTE_ARRAY, STRING> &appendix = font.appendices[i];
|
|
|
|
internal::AppendixHeader header;
|
|
|
|
internal::AppendixHeader header;
|
|
|
|
header.metadataLength = appendix.metadata.length();
|
|
|
|
header.metadataLength = (uint32) appendix.metadata.length();
|
|
|
|
header.dataLength = appendix.data.length();
|
|
|
|
header.dataLength = (uint32) appendix.data.length();
|
|
|
|
ARTERY_FONT_ENCODE_WRITE(&header, sizeof(header));
|
|
|
|
ARTERY_FONT_ENCODE_WRITE(&header, sizeof(header));
|
|
|
|
ARTERY_FONT_ENCODE_WRITE_STRING(appendix.metadata);
|
|
|
|
ARTERY_FONT_ENCODE_WRITE_STRING(appendix.metadata);
|
|
|
|
ARTERY_FONT_ENCODE_WRITE((const unsigned char *) appendix.data, header.dataLength);
|
|
|
|
ARTERY_FONT_ENCODE_WRITE((const unsigned char *) appendix.data, header.dataLength);
|
|
|
|
|