#ifndef __CMAP_TABLES_H__ #define __CMAP_TABLES_H__ #include #include "../../../reader/reader.h" #include #include #include "../../../types/types.h" #define list_uint16 std::vector #define list_uint8 std::vector #define list_int16 std::vector 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 _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 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(std::floor(std::log2(_segCount))); _searchRange = static_cast(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 _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 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 _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 groups() const { return _groups; }; uint16 Format()override{return format();} }; // class CmapTable13 : public CmapTableBase { private: uint32_t _numGroups; std::vector _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 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 _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 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 _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 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 _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 uvsMappings() const { return _uvsMappings; }; }; #endif