1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
/*************************************************************************
** TTFTable.hpp **
** **
** This file is part of dvisvgm -- a fast DVI to SVG converter **
** Copyright (C) 2005-2023 Martin Gieseking <martin.gieseking@uos.de> **
** **
** 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 <http://www.gnu.org/licenses/>. **
*************************************************************************/
#pragma once
#include <cstdint>
#include <ostream>
#include <sstream>
#include <vector>
namespace ttf {
/** Class to handle the binary TTF table data. */
class TableBuffer {
friend class TTFWriter;
public:
TableBuffer (uint32_t tag, std::vector<char> data);
TableBuffer (uint32_t tag, std::vector<char> 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 <typename T>
void setData (size_t offset, const T val) {
if (offset+sizeof(T) <= _data.size()) {
typename std::make_unsigned<T>::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<char> _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
|