blog/cpp/fonts/core/tables/cmap/tables.h

502 lines
14 KiB
C
Raw Permalink Normal View History

2024-09-13 15:10:58 +08:00
#ifndef __CMAP_TABLES_H__
#define __CMAP_TABLES_H__
#include <cstdint>
#include "../../../reader/reader.h"
#include <vector>
#include <math.h>
#include "../../../types/types.h"
#define list_uint16 std::vector<uint16_t>
#define list_uint8 std::vector<uint8_t>
#define list_int16 std::vector<int16_t>
class CmapTableBase
{
private:
uint16_t _format;
uint16_t _length;
uint16_t _language;
uint16_t _reserved;
public:
CmapTableBase() : _format(0), _length(0), _language(0), _reserved(0) {};
~CmapTableBase() {};
CmapTableBase(reader *rd) { read(rd); };
void read(reader *rd)
{
_format = rd->readUint16();
_reserved = 0;
if (_format == 8 || _format == 10 || _format == 12 || _format == 13)
_reserved = rd->readUint16();
_length = rd->readUint16();
if (_format == 14)
{
return;
}
_language = rd->readUint16();
};
uint16_t format() const { return _format; };
uint16_t length() const { return _length; };
uint16_t language() const { return _language; };
virtual uint16 Format() = 0;
};
class CmapTable0 : public CmapTableBase
{
private:
list_uint8 _glyphldArray;
uint16_t _glyphldCount;
public:
CmapTable0() : CmapTableBase(), _glyphldCount(256) {};
~CmapTable0() {};
CmapTable0(reader *rd) : CmapTableBase(rd), _glyphldCount(256) { read(rd); };
void read(reader *rd)
{
if (format() != 0)
return;
for (auto i = 0; i < _glyphldCount; i++)
{
uint8_t glyph = rd->readUint8();
_glyphldArray.push_back(glyph);
}
};
list_uint8 glyphldArray() const { return _glyphldArray; };
uint16 Format()override{return format();}
};
class CmapTable2SubHeader
{
private:
uint16_t _firstCode;
uint16_t _entryCount;
uint16_t _idDelta;
uint16_t _idRangeOffset;
public:
CmapTable2SubHeader() : _firstCode(0), _entryCount(0), _idDelta(0), _idRangeOffset(0) {};
~CmapTable2SubHeader() {};
CmapTable2SubHeader(reader *rd) { read(rd); };
void read(reader *rd)
{
_firstCode = rd->readUint16();
_entryCount = rd->readUint16();
_idDelta = rd->readUint16();
_idRangeOffset = rd->readUint16();
};
uint16_t firstCode() const { return _firstCode; };
uint16_t entryCount() const { return _entryCount; };
uint16_t idDelta() const { return _idDelta; };
uint16_t idRangeOffset() const { return _idRangeOffset; };
};
// 不常用
class CmapTable2 : public CmapTableBase
{
private:
list_uint16 _subHeaderKey;
std::vector<CmapTable2SubHeader> _subHeader;
list_uint16 _glyphldArray;
uint16_t _searchHeaderKeyCount;
public:
CmapTable2() : _searchHeaderKeyCount(256) {};
~CmapTable2() {};
CmapTable2(reader *rd) : CmapTableBase(rd), _searchHeaderKeyCount(256) { read(rd); };
void read(reader *rd)
{
if (format() != 2)
return;
}; // 计算很复杂
list_uint16 subHeaderKey() const { return _subHeaderKey; };
std::vector<CmapTable2SubHeader> subHeader() { return _subHeader; };
list_uint16 glyphldArray() const { return _glyphldArray; };
uint16 Format()override{return format();}
};
class CmapTable4 : public CmapTableBase
{
private:
uint16_t _segCountX2;
uint16_t _segCount;
uint16_t _searchRange;
uint16_t _entrySelector;
uint16_t _rangeShift;
list_uint16 _endCode;
uint16_t _reservedPad;
list_uint16 _startCode;
list_int16 _idDelta;
list_uint16 _idRangeOffset;
list_uint16 _glyphldArray;
void _calculate()
{
_segCount = _segCountX2 / 2;
_entrySelector = _segCount < 0 ? 0 : static_cast<uint16_t>(std::floor(std::log2(_segCount)));
_searchRange = static_cast<uint16_t>(std::pow(2, _entrySelector + 1));
_rangeShift = _segCountX2 - _searchRange;
return;
};
public:
CmapTable4() : _segCountX2(0), _searchRange(0), _entrySelector(0), _rangeShift(0), _reservedPad(0) {};
~CmapTable4() {};
CmapTable4(reader *rd) : CmapTableBase(rd) { read(rd); };
void read(reader *rd)
{
if (format() != 4)
return;
_segCountX2 = rd->readUint16();
_searchRange = rd->readUint16();
_entrySelector = rd->readUint16();
_rangeShift = rd->readUint16();
_calculate(); // 计算代替读取
for (auto i = 0; i < _segCount; i++)
{
uint16_t code = rd->readUint16();
_endCode.push_back(code);
}
_reservedPad = rd->readUint16();
for (auto i = 0; i < _segCount; i++)
{
uint16_t code = rd->readUint16();
_startCode.push_back(code);
}
for (auto i = 0; i < _segCount; i++)
{
int16_t code = rd->readUint16();
_idDelta.push_back(code);
}
for (auto i = 0; i < _segCount; i++)
{
uint16_t code = rd->readUint16();
_idRangeOffset.push_back(code);
}
while (rd->curr() < rd->getLength())
{
uint16_t glyph = rd->readUint16();
_glyphldArray.push_back(glyph);
}
};
uint16_t segCountX2() const { return _segCountX2; };
uint16_t segCount() const { return _segCount; };
uint16_t searchRange() const { return _searchRange; };
uint16_t entrySelector() const { return _entrySelector; };
uint16_t rangeShift() const { return _rangeShift; };
list_uint16 startCode() const { return _startCode; };
list_uint16 endCode() const { return _endCode; };
uint16_t reservePad() const { return _reservedPad; };
list_int16 idDelta() const { return _idDelta; };
list_uint16 idRangeOffset() const { return _idRangeOffset; };
list_uint16 glyphldArray() const { return _glyphldArray; };
uint16_t glyphId(uint16_t c, int i) const { return *(_idRangeOffset[i] / 2 + (c - _startCode[i]) + &_idRangeOffset[i]); };
uint16 Format()override{return format();}
};
class CmapTable6 : public CmapTableBase
{
private:
uint16_t _firstCode;
uint16_t _entryCount;
list_uint16 _glyphldArray;
public:
CmapTable6() : _firstCode(0), _entryCount(0) {};
~CmapTable6() {};
CmapTable6(reader *rd) : CmapTableBase(rd) { read(rd); };
void read(reader *rd)
{
if (format() != 6)
return;
_firstCode = rd->readUint16();
_entryCount = rd->readUint16();
for (auto i = 0; i < _entryCount; i++)
{
uint16_t glyph = rd->readUint16();
_glyphldArray.push_back(glyph);
}
};
uint16_t firstCode() const { return _firstCode; };
uint16_t entryCount() const { return _entryCount; };
list_uint16 glyphldArray() const { return _glyphldArray; };
uint16 Format()override{return format();}
};
//
class MapGroup
{
private:
uint32_t _startCharCode;
uint32_t _endCharCode;
uint32_t _startGlyphId;
public:
MapGroup() : _startCharCode(0), _endCharCode(0), _startGlyphId(0) {};
~MapGroup() {};
MapGroup(reader *rd) { read(rd); };
void read(reader *rd)
{
_startCharCode = rd->readUint32();
_endCharCode = rd->readUint32();
_startGlyphId = rd->readUint32();
};
uint32_t startCharCode() const { return _startCharCode; };
uint32_t endCharCode() const { return _endCharCode; };
uint32_t startGlyphId() const { return _startGlyphId; };
};
class CmapTable8 : public CmapTableBase
{
private:
list_uint8 _is32;
uint16_t _is32Count;
uint32_t _numGroups;
std::vector<MapGroup> _groups;
public:
CmapTable8() : _is32Count(8192), _numGroups(0) {};
~CmapTable8() {};
CmapTable8(reader *rd) : CmapTableBase(rd) { read(rd); };
void read(reader *rd)
{
if (format() != 8)
return;
for (auto i = 0; i < _is32Count; i++)
{
uint8_t u = rd->readUint8();
_is32.push_back(u);
}
_numGroups = rd->readUint32();
for (auto i = 0; i < _numGroups; i++)
{
MapGroup mg(rd);
_groups.push_back(mg);
}
};
list_uint8 is32() const { return _is32; };
uint16_t numGroups() const { return _numGroups; };
std::vector<MapGroup> groups() const { return _groups; };
uint16 Format()override{return format();}
};
//
class CmapTable10 : public CmapTableBase
{
private:
uint32_t _startCharCode;
uint32_t _numChars;
list_uint16 _glyphldArray;
public:
CmapTable10() : _startCharCode(0), _numChars(0) {};
~CmapTable10() {};
CmapTable10(reader *rd) : CmapTableBase(rd) { read(rd); };
void read(reader *rd)
{
if (format() != 10)
return;
_startCharCode = rd->readUint32();
_numChars = rd->readUint32();
while (rd->curr() < rd->getLength())
{
uint16_t glyph = rd->readUint16();
_glyphldArray.push_back(glyph);
}
};
uint32_t startCharCode() const { return _startCharCode; };
uint32_t numChars() const { return _numChars; };
list_uint16 glyphldArray() const { return _glyphldArray; };
uint16 Format()override{return format();}
};
//
class CmapTable12 : public CmapTableBase
{
private:
uint32_t _numGroups;
std::vector<MapGroup> _groups;
public:
CmapTable12() : _numGroups(0) {};
~CmapTable12() {};
CmapTable12(reader *rd) : CmapTableBase(rd) { read(rd); };
void read(reader *rd)
{
if (format() != 12)
return;
_numGroups = rd->readUint32();
for (auto i = 0; i < _numGroups; i++)
{
MapGroup mg(rd);
_groups.push_back(mg);
}
};
uint16_t numGroups() const { return _numGroups; };
std::vector<MapGroup> groups() const { return _groups; };
uint16 Format()override{return format();}
};
//
class CmapTable13 : public CmapTableBase
{
private:
uint32_t _numGroups;
std::vector<MapGroup> _groups;
public:
CmapTable13() : _numGroups(0) {};
~CmapTable13() {};
CmapTable13(reader *rd) : CmapTableBase(rd) { read(rd); };
void read(reader *rd)
{
if (format() != 13)
return;
_numGroups = rd->readUint32();
for (auto i = 0; i < _numGroups; i++)
{
MapGroup mg(rd);
_groups.push_back(mg);
}
};
uint16_t numGroups() const { return _numGroups; };
std::vector<MapGroup> groups() const { return _groups; };
uint16 Format()override{return format();}
};
//
class VariationSelector
{
private:
uint24 _varSelector; // read 24 bit
uint16_t _defualtUVSOffset;
uint16_t _nonDefaultUVSOffset;
public:
VariationSelector() : _varSelector(0), _defualtUVSOffset(0), _nonDefaultUVSOffset(0) {};
~VariationSelector() {};
VariationSelector(reader *rd) { read(rd); };
void read(reader *rd)
{
_varSelector = rd->readUint24();
_defualtUVSOffset = rd->readUint16();
_nonDefaultUVSOffset = rd->readUint16();
};
uint32_t varSelector() const { return _varSelector; };
uint16_t defaultUVSOffset() const { return _defualtUVSOffset; };
uint16_t nonDefaultUVSOffset() const { return _nonDefaultUVSOffset; };
};
//
class CmapTable14 : public CmapTableBase
{
private:
uint32_t _numVarSelectorRecords;
std::vector<VariationSelector> _varSelector;
public:
CmapTable14() : _numVarSelectorRecords(0) {};
~CmapTable14() {};
CmapTable14(reader *rd) : CmapTableBase(rd) { read(rd); };
void read(reader *rd)
{
if (format() != 14)
return;
_numVarSelectorRecords = rd->readUint32();
for (auto i = 0; i < _numVarSelectorRecords; i++)
{
VariationSelector vs(rd);
_varSelector.push_back(vs);
}
};
uint32_t numVarSelectorRecords() const { return _numVarSelectorRecords; };
std::vector<VariationSelector> varSelector() const { return _varSelector; };
uint16 Format()override{return format();}
};
// default uvs table
class UnicodeRange
{
private:
uint24 _startUnicodeValue;
uint8_t _additionalCount;
public:
UnicodeRange() : _startUnicodeValue(0), _additionalCount(0) {};
~UnicodeRange() {};
UnicodeRange(reader *rd) { read(rd); };
void read(reader *rd)
{
_startUnicodeValue = rd->readUint24();
_additionalCount = rd->readUint8();
};
uint32_t startUnicodeValue() const { return _startUnicodeValue; };
uint8_t additionalCount() const { return _additionalCount; };
};
class DefaultUVS
{
private:
uint32_t _numUnicodeValueRanges;
std::vector<UnicodeRange> _ranges;
public:
DefaultUVS() : _numUnicodeValueRanges(0) {};
~DefaultUVS() {};
DefaultUVS(reader *rd) { read(rd); };
void read(reader *rd)
{
_numUnicodeValueRanges = rd->readInt32();
for (auto i = 0; i < _numUnicodeValueRanges; i++)
{
UnicodeRange ur(rd);
_ranges.push_back(ur);
}
};
uint32_t numUnicodeValueRanges() const { return _numUnicodeValueRanges; };
std::vector<UnicodeRange> range() const { return _ranges; };
};
// non-default uvs table
class UVSMapping
{
private:
uint24 _unicodeValue;
uint16_t _glyphId;
public:
UVSMapping() : _unicodeValue(0), _glyphId(0) {};
~UVSMapping() {};
UVSMapping(reader *rd) { read(rd); };
void read(reader *rd)
{
_unicodeValue = rd->readUint24();
_glyphId = rd->readUint16();
};
uint32_t unicodeValue() const { return _unicodeValue; };
uint16_t glyphId() const { return _glyphId; };
};
class NonDefaultUVS
{
private:
uint32_t _numUVSMappings;
std::vector<UVSMapping> _uvsMappings;
public:
NonDefaultUVS() : _numUVSMappings(0) {};
~NonDefaultUVS() {};
NonDefaultUVS(reader *rd) { read(rd); };
void read(reader *rd)
{
_numUVSMappings = rd->readUint32();
for (auto i = 0; i < _numUVSMappings; i++)
{
UVSMapping um(rd);
_uvsMappings.push_back(um);
}
};
uint32_t numUVSMappings() const { return _numUVSMappings; };
std::vector<UVSMapping> uvsMappings() const { return _uvsMappings; };
};
#endif