/************************************************************************* ** TTFTable.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** ** Copyright (C) 2005-2024 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** ** published by the Free Software Foundation; either version 3 of ** ** the License, or (at your option) any later version. ** ** ** ** This program is distributed in the hope that it will be useful, but ** ** WITHOUT ANY WARRANTY; without even the implied warranty of ** ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** ** GNU General Public License for more details. ** ** ** ** You should have received a copy of the GNU General Public License ** ** along with this program; if not, see . ** *************************************************************************/ #pragma once #include #include #include #include namespace ttf { /** Class to handle the binary TTF table data. */ class TableBuffer { friend class TTFWriter; public: TableBuffer (uint32_t tag, std::vector data); TableBuffer (uint32_t tag, std::vector data, size_t checksumExcludeOffset); uint32_t tag () const {return _tag;} uint32_t unpaddedSize () const {return _unpaddedSize;} uint32_t paddedSize () const {return uint32_t(_data.size());} uint32_t compressedSize () const {return _compressedSize;} uint32_t checksum () const {return _checksum;} void compress (); std::string name () const; uint8_t getUInt8 (size_t offs) const {return _data[offs];} uint16_t getUInt16 (size_t offs) const {return getUInt8(offs)*0x100 + getUInt8(offs+1);} uint32_t getUInt32 (size_t offs) const {return getUInt16(offs)*0x10000 + getUInt16(offs+2);} /** Writes the n bytes of a given value in big-endian order to the buffer. * The buffer must be big enough to take the value at the desired position. * It is not resized automatically. * @param[in] offset offset/index the first byte is written to * @param[in] val the value to write */ template void setData (size_t offset, const T val) { if (offset+sizeof(T) <= _data.size()) { typename std::make_unsigned::type uval = val; for (int i = sizeof(T)-1; i >= 0; i--) { _data[offset+i] = uint8_t(uval & 0xff); uval >>= 8; } } } /** Writes the buffer data to the given output stream. */ void write (std::ostream &os) const { os.write(_data.data(), _data.size()); } private: uint32_t _tag; ///< tag/ID of corresponding TTF table uint32_t _unpaddedSize; ///< size of the buffer excluding pad bytes uint32_t _compressedSize; ///< sizeof compressed buffer excluding pad bytes uint32_t _checksum=0; ///< checksum of uncompressed data std::vector _data; ///< the (compressed/uncompressed) table data including pad bytes }; class TTFWriter; /** Abstract base class for all TTF tables. */ class TTFTable { friend class TTFWriter; public: virtual ~TTFTable () =default; virtual uint32_t tag () const =0; virtual void write (std::ostream &os) const =0; bool active () const {return _ttfWriter != nullptr;} TableBuffer createBuffer () const; std::string name () const; static constexpr uint32_t name2id (const char *str) { return (str[0] << 24) | (str[1] << 16) | (str[2] << 8) | str[3]; } protected: void setTTFWriter (TTFWriter *ttfWriter) {_ttfWriter = ttfWriter;} TTFWriter* ttfWriter () const {return _ttfWriter;} static void writeUInt8 (std::ostream &os, uint8_t val) {os.put(val);} static void writeUInt16 (std::ostream &os, uint16_t val) {os.put(val >> 8); os.put(val & 0xff);} static void writeUInt32 (std::ostream &os, uint32_t val) {writeUInt16(os, val >> 16); writeUInt16(os, val & 0xffff);} static void writeInt8 (std::ostream &os, int8_t val) {writeUInt8(os, uint8_t(val));} static void writeInt16 (std::ostream &os, int16_t val) {writeUInt16(os, uint16_t(val));} static void writeInt32 (std::ostream &os, int32_t val) {writeUInt32(os, uint32_t(val));} private: TTFWriter *_ttfWriter=nullptr; }; } // namespace ttf