/src/libreoffice/vcl/source/font/EOTConverter.cxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
5 | | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | | */ |
9 | | |
10 | | #include <string.h> |
11 | | #include <vector> |
12 | | #include <tools/vcompat.hxx> |
13 | | #include <cstdio> |
14 | | #include <tools/stream.hxx> |
15 | | #include <vcl/font/EOTConverter.hxx> |
16 | | #include <osl/endian.h> |
17 | | #include <font/TTFStructure.hxx> |
18 | | #include <font/TTFReader.hxx> |
19 | | |
20 | | namespace font |
21 | | { |
22 | | namespace |
23 | | { |
24 | | // Writes padding, length and string data to font output |
25 | | void writeNameTableString(font::TTFFont& rFont, |
26 | | std::unique_ptr<NameTableHandler>& pNameTableHandler, |
27 | | font::NameID eNameID, std::vector<sal_uInt8>& rEotOutput) |
28 | 3.04k | { |
29 | 3.04k | sal_uInt64 nOffset = 0; |
30 | 3.04k | sal_uInt16 nLength = 0; |
31 | | |
32 | | // Padding |
33 | 3.04k | rEotOutput.push_back(0); |
34 | 3.04k | rEotOutput.push_back(0); |
35 | | |
36 | 3.04k | if (pNameTableHandler |
37 | 3.04k | && pNameTableHandler->findEnglishUnicodeNameOffset(eNameID, nOffset, nLength)) |
38 | 297 | { |
39 | | // Length |
40 | 297 | rEotOutput.push_back(sal_uInt8((nLength + 2) & 0xff)); |
41 | 297 | rEotOutput.push_back(sal_uInt8((nLength + 2) >> 8)); |
42 | | |
43 | 297 | OUString aString = rFont.getNameTableString(nOffset, nLength); |
44 | 445k | for (sal_Int32 i = 0; i < aString.getLength(); i++) |
45 | 445k | { |
46 | 445k | sal_Unicode nUniChar = aString[i]; |
47 | 445k | rEotOutput.push_back(sal_uInt8(nUniChar & 0xff)); |
48 | 445k | rEotOutput.push_back(sal_uInt8(nUniChar >> 8)); |
49 | 445k | } |
50 | | // null terminated |
51 | 297 | rEotOutput.push_back(sal_uInt8(0)); |
52 | 297 | rEotOutput.push_back(sal_uInt8(0)); |
53 | 297 | } |
54 | 2.74k | else |
55 | 2.74k | { |
56 | | // Length 0 |
57 | 2.74k | rEotOutput.push_back(sal_uInt8(0)); |
58 | 2.74k | rEotOutput.push_back(sal_uInt8(0)); |
59 | 2.74k | } |
60 | 3.04k | } |
61 | | } |
62 | | |
63 | | bool EOTConverter::convert(std::vector<sal_uInt8>& rEotOutput) |
64 | 767 | { |
65 | 767 | font::TTFFont aFont(mrFontDataContainer); |
66 | | |
67 | 767 | rEotOutput.clear(); |
68 | 767 | rEotOutput.resize(sizeof(EOTHeader)); |
69 | | |
70 | 767 | EOTHeader* pEot = reinterpret_cast<EOTHeader*>(rEotOutput.data()); |
71 | 767 | pEot->nFontDataSize = mrFontDataContainer.size(); |
72 | 767 | pEot->nVersion = 0x00020002; |
73 | 767 | pEot->nFlags = 0; |
74 | 767 | pEot->nCharset = 0; |
75 | 767 | pEot->nMagicNumber = 0x504c; |
76 | 767 | pEot->nReserved1 = 0; |
77 | 767 | pEot->nReserved2 = 0; |
78 | 767 | pEot->nReserved3 = 0; |
79 | 767 | pEot->nReserved4 = 0; |
80 | | |
81 | 767 | auto pHandler = aFont.getTableEntriesHandler(); |
82 | 767 | if (!pHandler) |
83 | 7 | return false; |
84 | | |
85 | 760 | const font::OS2Table* pOS2 = pHandler->getOS2Table(); |
86 | 760 | if (pOS2) |
87 | 38 | { |
88 | 418 | for (sal_uInt32 n = 0; n < 10; n++) |
89 | 380 | pEot->nFontPANOSE[n] = pOS2->nPanose[n]; |
90 | | |
91 | 38 | pEot->nItalic = pOS2->nFsSelection & 0x01; |
92 | 38 | pEot->nWeight = pOS2->nWeightClass; |
93 | | // FIXME: Should use OS2->fsType, but some TrueType fonts set it to an over-restrictive value. |
94 | | // Since ATS does not enforce this on Mac OS X, we do not enforce it either. |
95 | 38 | pEot->nFsType = 0x0000; |
96 | 38 | pEot->nUnicodeRange1 = pOS2->nUnicodeRange1; |
97 | 38 | pEot->nUnicodeRange2 = pOS2->nUnicodeRange2; |
98 | 38 | pEot->nUnicodeRange3 = pOS2->nUnicodeRange3; |
99 | 38 | pEot->nUnicodeRange4 = pOS2->nUnicodeRange4; |
100 | 38 | pEot->nCodePageRange1 = pOS2->nCodePageRange1; |
101 | 38 | pEot->nCodePageRange2 = pOS2->nCodePageRange2; |
102 | 38 | } |
103 | | |
104 | 760 | const font::HeadTable* pHeadTable = pHandler->getHeadTable(); |
105 | 760 | if (pHeadTable) |
106 | 49 | { |
107 | 49 | pEot->nCheckSumAdjustment = pHeadTable->nCheckSumAdjustment; |
108 | 49 | } |
109 | | |
110 | 760 | auto pNameTableHandler = pHandler->getNameTableHandler(); |
111 | | |
112 | 760 | writeNameTableString(aFont, pNameTableHandler, font::NameID::FamilyName, rEotOutput); |
113 | 760 | writeNameTableString(aFont, pNameTableHandler, font::NameID::SubfamilyName, rEotOutput); |
114 | 760 | writeNameTableString(aFont, pNameTableHandler, font::NameID::Version, rEotOutput); |
115 | 760 | writeNameTableString(aFont, pNameTableHandler, font::NameID::FullFontName, rEotOutput); |
116 | | |
117 | | // Padding5 |
118 | 760 | rEotOutput.push_back(0); |
119 | 760 | rEotOutput.push_back(0); |
120 | | |
121 | | // Root String Size |
122 | 760 | rEotOutput.push_back(0); |
123 | 760 | rEotOutput.push_back(0); |
124 | | |
125 | | // Root String CheckSum (for size 0) |
126 | 760 | rEotOutput.push_back(0x42); |
127 | 760 | rEotOutput.push_back(0x53); |
128 | 760 | rEotOutput.push_back(0x47); |
129 | 760 | rEotOutput.push_back(0x50); |
130 | | |
131 | | // EUDC CodePage |
132 | 760 | rEotOutput.push_back(0xE4); |
133 | 760 | rEotOutput.push_back(0x04); |
134 | 760 | rEotOutput.push_back(0x00); |
135 | 760 | rEotOutput.push_back(0x00); |
136 | | |
137 | | // Padding6 |
138 | 760 | rEotOutput.push_back(0); |
139 | 760 | rEotOutput.push_back(0); |
140 | | |
141 | | // Signature Size = should be 0x0000 |
142 | 760 | rEotOutput.push_back(0); |
143 | 760 | rEotOutput.push_back(0); |
144 | | |
145 | | // EUDC Flags |
146 | 760 | rEotOutput.push_back(0); |
147 | 760 | rEotOutput.push_back(0); |
148 | 760 | rEotOutput.push_back(0); |
149 | 760 | rEotOutput.push_back(0); |
150 | | |
151 | | // EUDC Font Size = 0 |
152 | 760 | rEotOutput.push_back(0); |
153 | 760 | rEotOutput.push_back(0); |
154 | 760 | rEotOutput.push_back(0); |
155 | 760 | rEotOutput.push_back(0); |
156 | | |
157 | | // rEOTOutput could've been reallocated - need to reinterpret that. |
158 | 760 | pEot = reinterpret_cast<EOTHeader*>(rEotOutput.data()); |
159 | 760 | pEot->nEotSize = rEotOutput.size() + mrFontDataContainer.size(); |
160 | | |
161 | 760 | rEotOutput.insert(rEotOutput.end(), mrFontDataContainer.begin(), mrFontDataContainer.end()); |
162 | | |
163 | 760 | return true; |
164 | 767 | } |
165 | | |
166 | | } // end font namespace |
167 | | |
168 | | int TestEOT(const void* data, sal_uInt32 size) |
169 | 767 | { |
170 | 767 | const sal_uInt8* bytes = static_cast<const sal_uInt8*>(data); |
171 | 767 | std::vector<sal_uInt8> input(bytes, bytes + size); |
172 | | |
173 | 767 | std::vector<sal_uInt8> aEOT; |
174 | 767 | font::FontDataContainer aContainer(input); |
175 | 767 | font::EOTConverter aConverter(aContainer); |
176 | 767 | return aConverter.convert(aEOT) ? 1 : 0; |
177 | 767 | } |
178 | | |
179 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |