generated from bing/readnotes
502 lines
14 KiB
C
502 lines
14 KiB
C
|
#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
|