add msdf-atlas-gen libs linux64 & emscripten

This commit is contained in:
jrkb 2023-02-17 16:27:31 +01:00
parent 0bb0e87a33
commit 6fb3f95348
143 changed files with 13729 additions and 0 deletions

View file

@ -0,0 +1,10 @@
#pragma once
#include "types.h"
#include "enums.h"
#include "structures.h"
#include "serialization.h"
// ARTERY ENGINE ATLAS FONT FORMAT LIBRARY v1.0.1
// Author: Viktor Chlumsky (c) 2020 - 2022

View file

@ -0,0 +1,13 @@
#pragma once
#include "types.h"
namespace artery_font {
uint32 crc32Init();
uint32 crc32Update(uint32 crc, byte x);
}
#include "crc32.hpp"

View file

@ -0,0 +1,48 @@
#include "crc32.h"
namespace artery_font {
inline uint32 crc32Init() {
return ~0u;
}
inline uint32 crc32Update(uint32 crc, byte x) {
static const uint32 crc32Table[256] = {
0x00000000u, 0x77073096u, 0xee0e612cu, 0x990951bau, 0x076dc419u, 0x706af48fu, 0xe963a535u, 0x9e6495a3u,
0x0edb8832u, 0x79dcb8a4u, 0xe0d5e91eu, 0x97d2d988u, 0x09b64c2bu, 0x7eb17cbdu, 0xe7b82d07u, 0x90bf1d91u,
0x1db71064u, 0x6ab020f2u, 0xf3b97148u, 0x84be41deu, 0x1adad47du, 0x6ddde4ebu, 0xf4d4b551u, 0x83d385c7u,
0x136c9856u, 0x646ba8c0u, 0xfd62f97au, 0x8a65c9ecu, 0x14015c4fu, 0x63066cd9u, 0xfa0f3d63u, 0x8d080df5u,
0x3b6e20c8u, 0x4c69105eu, 0xd56041e4u, 0xa2677172u, 0x3c03e4d1u, 0x4b04d447u, 0xd20d85fdu, 0xa50ab56bu,
0x35b5a8fau, 0x42b2986cu, 0xdbbbc9d6u, 0xacbcf940u, 0x32d86ce3u, 0x45df5c75u, 0xdcd60dcfu, 0xabd13d59u,
0x26d930acu, 0x51de003au, 0xc8d75180u, 0xbfd06116u, 0x21b4f4b5u, 0x56b3c423u, 0xcfba9599u, 0xb8bda50fu,
0x2802b89eu, 0x5f058808u, 0xc60cd9b2u, 0xb10be924u, 0x2f6f7c87u, 0x58684c11u, 0xc1611dabu, 0xb6662d3du,
0x76dc4190u, 0x01db7106u, 0x98d220bcu, 0xefd5102au, 0x71b18589u, 0x06b6b51fu, 0x9fbfe4a5u, 0xe8b8d433u,
0x7807c9a2u, 0x0f00f934u, 0x9609a88eu, 0xe10e9818u, 0x7f6a0dbbu, 0x086d3d2du, 0x91646c97u, 0xe6635c01u,
0x6b6b51f4u, 0x1c6c6162u, 0x856530d8u, 0xf262004eu, 0x6c0695edu, 0x1b01a57bu, 0x8208f4c1u, 0xf50fc457u,
0x65b0d9c6u, 0x12b7e950u, 0x8bbeb8eau, 0xfcb9887cu, 0x62dd1ddfu, 0x15da2d49u, 0x8cd37cf3u, 0xfbd44c65u,
0x4db26158u, 0x3ab551ceu, 0xa3bc0074u, 0xd4bb30e2u, 0x4adfa541u, 0x3dd895d7u, 0xa4d1c46du, 0xd3d6f4fbu,
0x4369e96au, 0x346ed9fcu, 0xad678846u, 0xda60b8d0u, 0x44042d73u, 0x33031de5u, 0xaa0a4c5fu, 0xdd0d7cc9u,
0x5005713cu, 0x270241aau, 0xbe0b1010u, 0xc90c2086u, 0x5768b525u, 0x206f85b3u, 0xb966d409u, 0xce61e49fu,
0x5edef90eu, 0x29d9c998u, 0xb0d09822u, 0xc7d7a8b4u, 0x59b33d17u, 0x2eb40d81u, 0xb7bd5c3bu, 0xc0ba6cadu,
0xedb88320u, 0x9abfb3b6u, 0x03b6e20cu, 0x74b1d29au, 0xead54739u, 0x9dd277afu, 0x04db2615u, 0x73dc1683u,
0xe3630b12u, 0x94643b84u, 0x0d6d6a3eu, 0x7a6a5aa8u, 0xe40ecf0bu, 0x9309ff9du, 0x0a00ae27u, 0x7d079eb1u,
0xf00f9344u, 0x8708a3d2u, 0x1e01f268u, 0x6906c2feu, 0xf762575du, 0x806567cbu, 0x196c3671u, 0x6e6b06e7u,
0xfed41b76u, 0x89d32be0u, 0x10da7a5au, 0x67dd4accu, 0xf9b9df6fu, 0x8ebeeff9u, 0x17b7be43u, 0x60b08ed5u,
0xd6d6a3e8u, 0xa1d1937eu, 0x38d8c2c4u, 0x4fdff252u, 0xd1bb67f1u, 0xa6bc5767u, 0x3fb506ddu, 0x48b2364bu,
0xd80d2bdau, 0xaf0a1b4cu, 0x36034af6u, 0x41047a60u, 0xdf60efc3u, 0xa867df55u, 0x316e8eefu, 0x4669be79u,
0xcb61b38cu, 0xbc66831au, 0x256fd2a0u, 0x5268e236u, 0xcc0c7795u, 0xbb0b4703u, 0x220216b9u, 0x5505262fu,
0xc5ba3bbeu, 0xb2bd0b28u, 0x2bb45a92u, 0x5cb36a04u, 0xc2d7ffa7u, 0xb5d0cf31u, 0x2cd99e8bu, 0x5bdeae1du,
0x9b64c2b0u, 0xec63f226u, 0x756aa39cu, 0x026d930au, 0x9c0906a9u, 0xeb0e363fu, 0x72076785u, 0x05005713u,
0x95bf4a82u, 0xe2b87a14u, 0x7bb12baeu, 0x0cb61b38u, 0x92d28e9bu, 0xe5d5be0du, 0x7cdcefb7u, 0x0bdbdf21u,
0x86d3d2d4u, 0xf1d4e242u, 0x68ddb3f8u, 0x1fda836eu, 0x81be16cdu, 0xf6b9265bu, 0x6fb077e1u, 0x18b74777u,
0x88085ae6u, 0xff0f6a70u, 0x66063bcau, 0x11010b5cu, 0x8f659effu, 0xf862ae69u, 0x616bffd3u, 0x166ccf45u,
0xa00ae278u, 0xd70dd2eeu, 0x4e048354u, 0x3903b3c2u, 0xa7672661u, 0xd06016f7u, 0x4969474du, 0x3e6e77dbu,
0xaed16a4au, 0xd9d65adcu, 0x40df0b66u, 0x37d83bf0u, 0xa9bcae53u, 0xdebb9ec5u, 0x47b2cf7fu, 0x30b5ffe9u,
0xbdbdf21cu, 0xcabac28au, 0x53b39330u, 0x24b4a3a6u, 0xbad03605u, 0xcdd70693u, 0x54de5729u, 0x23d967bfu,
0xb3667a2eu, 0xc4614ab8u, 0x5d681b02u, 0x2a6f2b94u, 0xb40bbe37u, 0xc30c8ea1u, 0x5a05df1bu, 0x2d02ef8du,
};
return crc32Table[byte(x^crc)]^crc>>8;
}
}

View file

@ -0,0 +1,66 @@
#pragma once
namespace artery_font {
enum FontFlags {
FONT_BOLD = 0x01,
FONT_LIGHT = 0x02,
FONT_EXTRA_BOLD = 0x04,
FONT_CONDENSED = 0x08,
FONT_ITALIC = 0x10,
FONT_SMALL_CAPS = 0x20,
FONT_ICONOGRAPHIC = 0x0100,
FONT_SANS_SERIF = 0x0200,
FONT_SERIF = 0x0400,
FONT_MONOSPACE = 0x1000,
FONT_CURSIVE = 0x2000
};
enum CodepointType {
CP_UNSPECIFIED = 0,
CP_UNICODE = 1,
CP_INDEXED = 2,
CP_ICONOGRAPHIC = 14
};
enum MetadataFormat {
METADATA_NONE = 0,
METADATA_PLAINTEXT = 1,
METADATA_JSON = 2
};
enum ImageType {
IMAGE_NONE = 0,
IMAGE_SRGB_IMAGE = 1,
IMAGE_LINEAR_MASK = 2,
IMAGE_MASKED_SRGB_IMAGE = 3,
IMAGE_SDF = 4,
IMAGE_PSDF = 5,
IMAGE_MSDF = 6,
IMAGE_MTSDF = 7,
IMAGE_MIXED_CONTENT = 255
};
enum PixelFormat {
PIXEL_UNKNOWN = 0,
PIXEL_BOOLEAN1 = 1,
PIXEL_UNSIGNED8 = 8,
PIXEL_FLOAT32 = 32
};
enum ImageEncoding {
IMAGE_UNKNOWN_ENCODING = 0,
IMAGE_RAW_BINARY = 1,
IMAGE_BMP = 4,
IMAGE_TIFF = 5,
IMAGE_PNG = 8,
IMAGE_TGA = 9
};
enum ImageOrientation {
ORIENTATION_TOP_DOWN = 1,
ORIENTATION_BOTTOM_UP = -1
};
}

View file

@ -0,0 +1,21 @@
#pragma once
#include "types.h"
#include "enums.h"
#include "structures.h"
namespace artery_font {
typedef int ReadFunction(void *dst, int limit, void *userData);
typedef int WriteFunction(const void *src, int length, void *userData);
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);
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);
}
#include "serialization.hpp"

View file

@ -0,0 +1,394 @@
#include "serialization.h"
#include <cstring>
#include "crc32.h"
namespace artery_font {
namespace internal {
#define ARTERY_FONT_HEADER_TAG "ARTERY/FONT\0\0\0\0\0"
#define ARTERY_FONT_HEADER_VERSION 1u
#define ARTERY_FONT_HEADER_MAGIC_NO 0x4d276a5cu
#define ARTERY_FONT_FOOTER_MAGIC_NO 0x55ccb363u
struct ArteryFontHeader {
char tag[16];
uint32 magicNo;
uint32 version;
uint32 flags;
uint32 realType;
uint32 reserved[4];
uint32 metadataFormat;
uint32 metadataLength;
uint32 variantCount;
uint32 variantsLength;
uint32 imageCount;
uint32 imagesLength;
uint32 appendixCount;
uint32 appendicesLength;
uint32 reserved2[8];
};
struct ArteryFontFooter {
uint32 salt;
uint32 magicNo;
uint32 reserved[4];
uint32 totalLength;
uint32 checksum;
};
template <typename REAL>
struct FontVariantHeader {
uint32 flags;
uint32 weight;
uint32 codepointType;
uint32 imageType;
uint32 fallbackVariant;
uint32 fallbackGlyph;
uint32 reserved[6];
REAL metrics[32];
uint32 nameLength;
uint32 metadataLength;
uint32 glyphCount;
uint32 kernPairCount;
};
struct ImageHeader {
uint32 flags;
uint32 encoding;
uint32 width, height;
uint32 channels;
uint32 pixelFormat;
uint32 imageType;
uint32 rowLength;
sint32 orientation;
uint32 childImages;
uint32 textureFlags;
uint32 reserved[3];
uint32 metadataLength;
uint32 dataLength;
};
struct AppendixHeader {
uint32 metadataLength;
uint32 dataLength;
};
template <typename REAL>
uint32 realTypeCode();
template <>
inline uint32 realTypeCode<float>() {
return 0x14u;
}
template <>
inline uint32 realTypeCode<double>() {
return 0x18u;
}
inline uint32 paddedLength(uint32 len) {
if (len&0x03u)
len += 0x04u-(len&0x03u);
return len;
}
template <class STRING>
uint32 paddedStringLength(const STRING &str) {
uint32 len = str.length();
return paddedLength(len+(len > 0));
}
}
#ifndef __BIG_ENDIAN__
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) {
uint32 totalLength = 0;
uint32 prevLength = 0;
uint32 checksum = crc32Init();
byte dump[4];
#define ARTERY_FONT_DECODE_READ(target, len) { \
if (READ((target), (len), userData) != int(len)) \
return false; \
totalLength += (len); \
for (int i = 0; i < int(len); ++i) \
checksum = crc32Update(checksum, reinterpret_cast<const byte *>(target)[i]); \
}
#define ARTERY_FONT_DECODE_REALIGN() { \
if (totalLength&0x03u) { \
uint32 len = 0x04u-(totalLength&0x03u); \
ARTERY_FONT_DECODE_READ(dump, len); \
} \
}
#define ARTERY_FONT_DECODE_READ_STRING(str, len) { \
if ((len) > 0) { \
LIST<char> characters((len)+1); \
ARTERY_FONT_DECODE_READ((char *) characters, (len)+1); \
((char *) characters)[len] = '\0'; \
(str) = STRING((const char *) characters, int(len)); \
ARTERY_FONT_DECODE_REALIGN(); \
} else \
(str) = STRING(); \
}
int variantCount = 0;
int imageCount = 0;
int appendixCount = 0;
uint32 variantsLength = 0;
uint32 imagesLength = 0;
uint32 appendicesLength = 0;
// Read header
{
internal::ArteryFontHeader header;
ARTERY_FONT_DECODE_READ(&header, sizeof(header));
if (memcmp(header.tag, ARTERY_FONT_HEADER_TAG, sizeof(header.tag)))
return false;
if (header.magicNo != ARTERY_FONT_HEADER_MAGIC_NO)
return false;
if (header.realType != internal::realTypeCode<REAL>())
return false;
font.metadataFormat = (MetadataFormat) header.metadataFormat;
ARTERY_FONT_DECODE_READ_STRING(font.metadata, header.metadataLength);
variantCount = header.variantCount;
imageCount = header.imageCount;
appendixCount = header.appendixCount;
font.variants = LIST<FontVariant<REAL, LIST, STRING> >(header.variantCount);
font.images = LIST<FontImage<BYTE_ARRAY, STRING> >(header.imageCount);
font.appendices = LIST<FontAppendix<BYTE_ARRAY, STRING> >(header.appendixCount);
variantsLength = header.variantsLength;
imagesLength = header.imagesLength;
appendicesLength = header.appendicesLength;
}
prevLength = totalLength;
// Read variants
for (int i = 0; i < variantCount; ++i) {
FontVariant<REAL, LIST, STRING> &variant = font.variants[i];
internal::FontVariantHeader<REAL> header;
ARTERY_FONT_DECODE_READ(&header, sizeof(header));
variant.flags = header.flags;
variant.weight = header.weight;
variant.codepointType = (CodepointType) header.codepointType;
variant.imageType = (ImageType) header.imageType;
variant.fallbackVariant = header.fallbackVariant;
variant.fallbackGlyph = header.fallbackGlyph;
memcpy(&variant.metrics, header.metrics, sizeof(header.metrics));
ARTERY_FONT_DECODE_READ_STRING(variant.name, header.nameLength);
ARTERY_FONT_DECODE_READ_STRING(variant.metadata, header.metadataLength);
variant.glyphs = LIST<Glyph<REAL> >(header.glyphCount);
variant.kernPairs = LIST<KernPair<REAL> >(header.kernPairCount);
ARTERY_FONT_DECODE_READ((Glyph<REAL> *) variant.glyphs, header.glyphCount*sizeof(Glyph<REAL>));
ARTERY_FONT_DECODE_READ((KernPair<REAL> *) variant.kernPairs, header.kernPairCount*sizeof(KernPair<REAL>));
}
if (totalLength-prevLength != variantsLength)
return false;
prevLength = totalLength;
// Read images
for (int i = 0; i < imageCount; ++i) {
FontImage<BYTE_ARRAY, STRING> &image = font.images[i];
internal::ImageHeader header;
ARTERY_FONT_DECODE_READ(&header, sizeof(header));
image.flags = header.flags;
image.encoding = (ImageEncoding) header.encoding;
image.width = header.width;
image.height = header.height;
image.channels = header.channels;
image.pixelFormat = (PixelFormat) header.pixelFormat;
image.imageType = (ImageType) header.imageType;
image.rawBinaryFormat.rowLength = header.rowLength;
image.rawBinaryFormat.orientation = (ImageOrientation) header.orientation;
image.childImages = header.childImages;
image.textureFlags = header.textureFlags;
ARTERY_FONT_DECODE_READ_STRING(image.metadata, header.metadataLength);
image.data = BYTE_ARRAY(header.dataLength);
ARTERY_FONT_DECODE_READ((unsigned char *) image.data, header.dataLength);
ARTERY_FONT_DECODE_REALIGN();
}
if (totalLength-prevLength != imagesLength)
return false;
prevLength = totalLength;
// Read appendices
for (int i = 0; i < appendixCount; ++i) {
FontAppendix<BYTE_ARRAY, STRING> &appendix = font.appendices[i];
internal::AppendixHeader header;
ARTERY_FONT_DECODE_READ(&header, sizeof(header));
ARTERY_FONT_DECODE_READ_STRING(appendix.metadata, header.metadataLength);
appendix.data = BYTE_ARRAY(header.dataLength);
ARTERY_FONT_DECODE_READ((unsigned char *) appendix.data, header.dataLength);
ARTERY_FONT_DECODE_REALIGN();
}
if (totalLength-prevLength != appendicesLength)
return false;
prevLength = totalLength;
// Read footer
{
internal::ArteryFontFooter footer;
ARTERY_FONT_DECODE_READ(&footer, sizeof(footer)-sizeof(footer.checksum));
if (footer.magicNo != ARTERY_FONT_FOOTER_MAGIC_NO)
return false;
uint32 finalChecksum = checksum;
ARTERY_FONT_DECODE_READ(&footer.checksum, sizeof(footer.checksum));
if (footer.checksum != finalChecksum)
return false;
if (totalLength != footer.totalLength)
return false;
}
return true;
#undef ARTERY_FONT_DECODE_READ
#undef ARTERY_FONT_DECODE_REALIGN
#undef ARTERY_FONT_DECODE_READ_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) {
uint32 totalLength = 0;
uint32 checksum = crc32Init();
const byte padding[4] = { };
#define ARTERY_FONT_ENCODE_WRITE(data, len) { \
if (WRITE((data), (len), userData) != int(len)) \
return false; \
totalLength += (len); \
for (int i = 0; i < int(len); ++i) \
checksum = crc32Update(checksum, reinterpret_cast<const byte *>(data)[i]); \
}
#define ARTERY_FONT_ENCODE_REALIGN() { \
if (totalLength&0x03u) { \
uint32 len = 0x04u-(totalLength&0x03u); \
ARTERY_FONT_ENCODE_WRITE(padding, len); \
} \
}
#define ARTERY_FONT_ENCODE_WRITE_STRING(str) { \
uint32 len = (str).length(); \
if ((len) > 0) { \
ARTERY_FONT_ENCODE_WRITE((const char *) (str), (len)); \
ARTERY_FONT_ENCODE_WRITE(padding, 1) \
ARTERY_FONT_ENCODE_REALIGN(); \
} \
}
int variantCount = 0;
int imageCount = 0;
int appendixCount = 0;
// Write header
{
internal::ArteryFontHeader header;
memcpy(header.tag, ARTERY_FONT_HEADER_TAG, sizeof(header.tag));
header.magicNo = ARTERY_FONT_HEADER_MAGIC_NO;
header.version = ARTERY_FONT_HEADER_VERSION;
header.flags = 0;
header.realType = internal::realTypeCode<REAL>();
memset(header.reserved, 0, sizeof(header.reserved));
header.metadataFormat = (uint32) font.metadataFormat;
header.metadataLength = font.metadata.length();
header.variantCount = variantCount = font.variants.length();
header.variantsLength = 0;
header.imageCount = imageCount = font.images.length();
header.imagesLength = 0;
header.appendixCount = appendixCount = font.appendices.length();
header.appendicesLength = 0;
memset(header.reserved2, 0, sizeof(header.reserved2));
for (int i = 0; i < variantCount; ++i) {
const FontVariant<REAL, LIST, STRING> &variant = font.variants[i];
header.variantsLength += sizeof(internal::FontVariantHeader<REAL>);
header.variantsLength += internal::paddedStringLength(variant.name);
header.variantsLength += internal::paddedStringLength(variant.metadata);
header.variantsLength += variant.glyphs.length()*sizeof(Glyph<REAL>);
header.variantsLength += variant.kernPairs.length()*sizeof(KernPair<REAL>);
}
for (int i = 0; i < imageCount; ++i) {
const FontImage<BYTE_ARRAY, STRING> &image = font.images[i];
header.imagesLength += sizeof(internal::ImageHeader);
header.imagesLength += internal::paddedStringLength(image.metadata);
header.imagesLength += internal::paddedLength(image.data.length());
}
for (int i = 0; i < appendixCount; ++i) {
const FontAppendix<BYTE_ARRAY, STRING> &appendix = font.appendices[i];
header.appendicesLength += sizeof(internal::AppendixHeader);
header.appendicesLength += internal::paddedStringLength(appendix.metadata);
header.appendicesLength += internal::paddedLength(appendix.data.length());
}
ARTERY_FONT_ENCODE_WRITE(&header, sizeof(header));
ARTERY_FONT_ENCODE_WRITE_STRING(font.metadata);
}
// Write variants
for (int i = 0; i < variantCount; ++i) {
const FontVariant<REAL, LIST, STRING> &variant = font.variants[i];
internal::FontVariantHeader<REAL> header;
header.flags = variant.flags;
header.weight = variant.weight;
header.codepointType = (uint32) variant.codepointType;
header.imageType = (uint32) variant.imageType;
header.fallbackVariant = variant.fallbackVariant;
header.fallbackGlyph = variant.fallbackGlyph;
memset(header.reserved, 0, sizeof(header.reserved));
memcpy(header.metrics, &variant.metrics, sizeof(header.metrics));
header.nameLength = variant.name.length();
header.metadataLength = variant.metadata.length();
header.glyphCount = variant.glyphs.length();
header.kernPairCount = variant.kernPairs.length();
ARTERY_FONT_ENCODE_WRITE(&header, sizeof(header));
ARTERY_FONT_ENCODE_WRITE_STRING(variant.name);
ARTERY_FONT_ENCODE_WRITE_STRING(variant.metadata);
ARTERY_FONT_ENCODE_WRITE((const Glyph<REAL> *) variant.glyphs, header.glyphCount*sizeof(Glyph<REAL>));
ARTERY_FONT_ENCODE_WRITE((const KernPair<REAL> *) variant.kernPairs, header.kernPairCount*sizeof(KernPair<REAL>));
}
// Write images
for (int i = 0; i < imageCount; ++i) {
const FontImage<BYTE_ARRAY, STRING> &image = font.images[i];
internal::ImageHeader header;
header.flags = image.flags;
header.encoding = (uint32) image.encoding;
header.width = image.width;
header.height = image.height;
header.channels = image.channels;
header.pixelFormat = (uint32) image.pixelFormat;
header.imageType = (uint32) image.imageType;
header.rowLength = image.rawBinaryFormat.rowLength;
header.orientation = (sint32) image.rawBinaryFormat.orientation;
header.childImages = image.childImages;
header.textureFlags = image.textureFlags;
memset(header.reserved, 0, sizeof(header.reserved));
header.metadataLength = image.metadata.length();
header.dataLength = image.data.length();
ARTERY_FONT_ENCODE_WRITE(&header, sizeof(header));
ARTERY_FONT_ENCODE_WRITE_STRING(image.metadata);
ARTERY_FONT_ENCODE_WRITE((const unsigned char *) image.data, header.dataLength);
ARTERY_FONT_ENCODE_REALIGN();
}
// Write appendices
for (int i = 0; i < appendixCount; ++i) {
const FontAppendix<BYTE_ARRAY, STRING> &appendix = font.appendices[i];
internal::AppendixHeader header;
header.metadataLength = appendix.metadata.length();
header.dataLength = appendix.data.length();
ARTERY_FONT_ENCODE_WRITE(&header, sizeof(header));
ARTERY_FONT_ENCODE_WRITE_STRING(appendix.metadata);
ARTERY_FONT_ENCODE_WRITE((const unsigned char *) appendix.data, header.dataLength);
ARTERY_FONT_ENCODE_REALIGN();
}
// Write footer
{
internal::ArteryFontFooter footer;
footer.salt = 0;
footer.magicNo = ARTERY_FONT_FOOTER_MAGIC_NO;
memset(footer.reserved, 0, sizeof(footer.reserved));
footer.totalLength = totalLength+sizeof(footer);
ARTERY_FONT_ENCODE_WRITE(&footer, sizeof(footer)-sizeof(footer.checksum));
footer.checksum = checksum;
ARTERY_FONT_ENCODE_WRITE(&footer.checksum, sizeof(footer.checksum));
}
return true;
#undef ARTERY_FONT_ENCODE_WRITE
#undef ARTERY_FONT_ENCODE_REALIGN
#undef ARTERY_FONT_ENCODE_WRITE_STRING
}
#endif
#undef ARTERY_FONT_HEADER_TAG
#undef ARTERY_FONT_HEADER_VERSION
#undef ARTERY_FONT_HEADER_MAGIC_NO
#undef ARTERY_FONT_FOOTER_MAGIC_NO
}

View file

@ -0,0 +1,39 @@
#pragma once
#include <vector>
#include <string>
#include "artery-font.h"
namespace artery_font {
template <typename T>
class StdList : private std::vector<T> {
public:
inline StdList() { }
inline explicit StdList(int length) : std::vector<T>((size_t) length) { }
inline int length() const { return (int) std::vector<T>::size(); }
inline explicit operator T *() { return std::vector<T>::data(); }
inline explicit operator const T *() const { return std::vector<T>::data(); }
inline T &operator[](int index) { return std::vector<T>::operator[](index); }
inline const T &operator[](int index) const { return std::vector<T>::operator[](index); }
};
class StdString : private std::string {
public:
inline StdString() { }
inline StdString(const char *characters, int length) : std::string(characters, (size_t) length) { }
inline int length() const { return (int) std::string::size(); }
inline explicit operator const char *() const { return std::string::c_str(); }
};
typedef StdList<unsigned char> StdByteArray;
template <typename REAL>
using StdArteryFont = ArteryFont<REAL, StdList, StdByteArray, StdString>;
}

View file

@ -0,0 +1,23 @@
#pragma once
#include <cstdio>
#include "serialization.h"
namespace artery_font {
template <typename REAL, template <typename> class LIST, class BYTE_ARRAY, class STRING>
bool read(ArteryFont<REAL, LIST, BYTE_ARRAY, STRING> &font, FILE *file);
template <typename REAL, template <typename> class LIST, class BYTE_ARRAY, class STRING>
bool write(const ArteryFont<REAL, LIST, BYTE_ARRAY, STRING> &font, FILE *file);
template <typename REAL, template <typename> class LIST, class BYTE_ARRAY, class STRING>
bool readFile(ArteryFont<REAL, LIST, BYTE_ARRAY, STRING> &font, const char *filename);
template <typename REAL, template <typename> class LIST, class BYTE_ARRAY, class STRING>
bool writeFile(const ArteryFont<REAL, LIST, BYTE_ARRAY, STRING> &font, const char *filename);
}
#include "stdio-serialization.hpp"

View file

@ -0,0 +1,48 @@
#include "stdio-serialization.h"
namespace artery_font {
namespace internal {
inline int fileRead(void *buffer, int length, void *file) {
return fread(buffer, 1, length, reinterpret_cast<FILE *>(file));
}
inline int fileWrite(const void *buffer, int length, void *file) {
return fwrite(buffer, 1, length, reinterpret_cast<FILE *>(file));
}
}
template <typename REAL, template <typename> class LIST, class BYTE_ARRAY, class STRING>
bool read(ArteryFont<REAL, LIST, BYTE_ARRAY, STRING> &font, FILE *file) {
return decode<internal::fileRead>(font, file);
}
template <typename REAL, template <typename> class LIST, class BYTE_ARRAY, class STRING>
bool write(const ArteryFont<REAL, LIST, BYTE_ARRAY, STRING> &font, FILE *file) {
return encode<internal::fileWrite>(font, file);
}
template <typename REAL, template <typename> class LIST, class BYTE_ARRAY, class STRING>
bool readFile(ArteryFont<REAL, LIST, BYTE_ARRAY, STRING> &font, const char *filename) {
FILE *file = fopen(filename, "rb");
if (!file)
return false;
bool result = read(font, file);
fclose(file);
return result;
}
template <typename REAL, template <typename> class LIST, class BYTE_ARRAY, class STRING>
bool writeFile(const ArteryFont<REAL, LIST, BYTE_ARRAY, STRING> &font, const char *filename) {
FILE *file = fopen(filename, "wb");
if (!file)
return false;
bool result = write(font, file);
fclose(file);
return result;
}
}

View file

@ -0,0 +1,90 @@
#pragma once
#include "types.h"
#include "enums.h"
namespace artery_font {
template <typename REAL>
struct Glyph {
uint32 codepoint;
uint32 image;
struct {
REAL l, b, r, t;
} planeBounds, imageBounds;
struct {
REAL h, v;
} advance;
};
template <typename REAL>
struct KernPair {
uint32 codepoint1, codepoint2;
struct {
REAL h, v;
} advance;
};
template <typename REAL, template <typename> class LIST, class STRING>
struct FontVariant {
uint32 flags;
uint32 weight;
CodepointType codepointType;
ImageType imageType;
uint32 fallbackVariant;
uint32 fallbackGlyph;
struct Metrics {
// In pixels:
REAL fontSize;
REAL distanceRange;
// Proportional to font size:
REAL emSize;
REAL ascender, descender;
REAL lineHeight;
REAL underlineY, underlineThickness;
REAL reserved[24];
} metrics;
STRING name;
STRING metadata;
LIST<Glyph<REAL> > glyphs;
LIST<KernPair<REAL> > kernPairs;
};
template <class BYTE_ARRAY, class STRING>
struct FontImage {
uint32 flags;
ImageEncoding encoding;
uint32 width, height;
uint32 channels;
PixelFormat pixelFormat;
ImageType imageType;
struct {
uint32 rowLength;
ImageOrientation orientation;
} rawBinaryFormat;
uint32 childImages;
uint32 textureFlags;
STRING metadata;
BYTE_ARRAY data;
};
template <class BYTE_ARRAY, class STRING>
struct FontAppendix {
STRING metadata;
BYTE_ARRAY data;
};
template <typename REAL, template <typename> class LIST, class BYTE_ARRAY, class STRING>
struct ArteryFont {
typedef FontVariant<REAL, LIST, STRING> Variant;
typedef FontImage<BYTE_ARRAY, STRING> Image;
typedef FontAppendix<BYTE_ARRAY, STRING> Appendix;
MetadataFormat metadataFormat;
STRING metadata;
LIST<Variant> variants;
LIST<Image> images;
LIST<Appendix> appendices;
};
}

View file

@ -0,0 +1,12 @@
#pragma once
#include <cstdint>
namespace artery_font {
typedef unsigned char byte;
typedef int32_t sint32;
typedef uint32_t uint32;
}