File: | home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx |
Warning: | line 261, column 74 Assigned value is garbage or undefined |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | * This file incorporates work covered by the following license notice: | |||
10 | * | |||
11 | * Licensed to the Apache Software Foundation (ASF) under one or more | |||
12 | * contributor license agreements. See the NOTICE file distributed | |||
13 | * with this work for additional information regarding copyright | |||
14 | * ownership. The ASF licenses this file to you under the Apache | |||
15 | * License, Version 2.0 (the "License"); you may not use this file | |||
16 | * except in compliance with the License. You may obtain a copy of | |||
17 | * the License at http://www.apache.org/licenses/LICENSE-2.0 . | |||
18 | */ | |||
19 | ||||
20 | /* | |||
21 | * TrueTypeCreator method implementation | |||
22 | */ | |||
23 | ||||
24 | #include <iomanip> | |||
25 | #include <assert.h> | |||
26 | ||||
27 | #include <sal/log.hxx> | |||
28 | ||||
29 | #include "ttcr.hxx" | |||
30 | #include "list.h" | |||
31 | #include <string.h> | |||
32 | ||||
33 | namespace vcl | |||
34 | { | |||
35 | ||||
36 | /* | |||
37 | * Private Data Types | |||
38 | */ | |||
39 | ||||
40 | struct TrueTypeCreator { | |||
41 | sal_uInt32 tag; /**< TrueType file tag */ | |||
42 | list tables; /**< List of table tags and pointers */ | |||
43 | }; | |||
44 | ||||
45 | namespace { | |||
46 | ||||
47 | struct TableEntry { | |||
48 | sal_uInt32 tag; | |||
49 | sal_uInt32 length; | |||
50 | sal_uInt8 *data; | |||
51 | }; | |||
52 | ||||
53 | } | |||
54 | ||||
55 | /*- Data access macros for data stored in big-endian or little-endian format */ | |||
56 | static sal_Int16 GetInt16( const sal_uInt8* ptr, sal_uInt32 offset) | |||
57 | { | |||
58 | assert(ptr != nullptr)(static_cast <bool> (ptr != nullptr) ? void (0) : __assert_fail ("ptr != nullptr", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 58, __extension__ __PRETTY_FUNCTION__)); | |||
59 | sal_Int16 t = (ptr+offset)[0] << 8 | (ptr+offset)[1]; | |||
60 | return t; | |||
61 | } | |||
62 | ||||
63 | static sal_uInt16 GetUInt16( const sal_uInt8* ptr, sal_uInt32 offset) | |||
64 | { | |||
65 | assert(ptr != nullptr)(static_cast <bool> (ptr != nullptr) ? void (0) : __assert_fail ("ptr != nullptr", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 65, __extension__ __PRETTY_FUNCTION__)); | |||
66 | sal_uInt16 t = (ptr+offset)[0] << 8 | (ptr+offset)[1]; | |||
67 | return t; | |||
68 | } | |||
69 | ||||
70 | static void PutInt16(sal_Int16 val, sal_uInt8 *ptr, sal_uInt32 offset) | |||
71 | { | |||
72 | assert(ptr != nullptr)(static_cast <bool> (ptr != nullptr) ? void (0) : __assert_fail ("ptr != nullptr", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 72, __extension__ __PRETTY_FUNCTION__)); | |||
73 | ||||
74 | ptr[offset] = static_cast<sal_uInt8>((val >> 8) & 0xFF); | |||
75 | ptr[offset+1] = static_cast<sal_uInt8>(val & 0xFF); | |||
76 | } | |||
77 | ||||
78 | static void PutUInt16(sal_uInt16 val, sal_uInt8 *ptr, sal_uInt32 offset) | |||
79 | { | |||
80 | assert(ptr != nullptr)(static_cast <bool> (ptr != nullptr) ? void (0) : __assert_fail ("ptr != nullptr", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 80, __extension__ __PRETTY_FUNCTION__)); | |||
81 | ||||
82 | ptr[offset] = static_cast<sal_uInt8>((val >> 8) & 0xFF); | |||
83 | ptr[offset+1] = static_cast<sal_uInt8>(val & 0xFF); | |||
84 | } | |||
85 | ||||
86 | static void PutUInt32(sal_uInt32 val, sal_uInt8 *ptr, sal_uInt32 offset) | |||
87 | { | |||
88 | assert(ptr != nullptr)(static_cast <bool> (ptr != nullptr) ? void (0) : __assert_fail ("ptr != nullptr", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 88, __extension__ __PRETTY_FUNCTION__)); | |||
89 | ||||
90 | ptr[offset] = static_cast<sal_uInt8>((val >> 24) & 0xFF); | |||
91 | ptr[offset+1] = static_cast<sal_uInt8>((val >> 16) & 0xFF); | |||
92 | ptr[offset+2] = static_cast<sal_uInt8>((val >> 8) & 0xFF); | |||
93 | ptr[offset+3] = static_cast<sal_uInt8>(val & 0xFF); | |||
94 | } | |||
95 | ||||
96 | static int TableEntryCompareF(const void *l, const void *r) | |||
97 | { | |||
98 | sal_uInt32 const ltag(static_cast<TableEntry const*>(l)->tag); | |||
99 | sal_uInt32 const rtag(static_cast<TableEntry const*>(r)->tag); | |||
100 | return (ltag == rtag) ? 0 : (ltag < rtag) ? -1 : 1; | |||
101 | } | |||
102 | ||||
103 | static int NameRecordCompareF(const void *l, const void *r) | |||
104 | { | |||
105 | NameRecord const *ll = static_cast<NameRecord const *>(l); | |||
106 | NameRecord const *rr = static_cast<NameRecord const *>(r); | |||
107 | ||||
108 | if (ll->platformID != rr->platformID) { | |||
109 | return (ll->platformID < rr->platformID) ? -1 : 1; | |||
110 | } else if (ll->encodingID != rr->encodingID) { | |||
111 | return (ll->encodingID < rr->encodingID) ? -1 : 1; | |||
112 | } else if (ll->languageID != rr->languageID) { | |||
113 | return (ll->languageID < rr->languageID) ? -1 : 1; | |||
114 | } else if (ll->nameID != rr->nameID) { | |||
115 | return (ll->nameID < rr->nameID) ? -1 : 1; | |||
116 | } | |||
117 | return 0; | |||
118 | } | |||
119 | ||||
120 | static sal_uInt32 CheckSum(sal_uInt32 *ptr, sal_uInt32 length) | |||
121 | { | |||
122 | sal_uInt32 sum = 0; | |||
123 | sal_uInt32 *endptr = ptr + ((length + 3) & sal_uInt32(~3)) / 4; | |||
124 | ||||
125 | while (ptr < endptr) sum += *ptr++; | |||
126 | ||||
127 | return sum; | |||
128 | } | |||
129 | ||||
130 | static void *smalloc(sal_uInt32 size) | |||
131 | { | |||
132 | void *res = malloc(size); | |||
133 | assert(res != nullptr)(static_cast <bool> (res != nullptr) ? void (0) : __assert_fail ("res != nullptr", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 133, __extension__ __PRETTY_FUNCTION__)); | |||
134 | return res; | |||
135 | } | |||
136 | ||||
137 | static void *scalloc(sal_uInt32 n, sal_uInt32 size) | |||
138 | { | |||
139 | void *res = calloc(n, size); | |||
140 | assert(res != nullptr)(static_cast <bool> (res != nullptr) ? void (0) : __assert_fail ("res != nullptr", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 140, __extension__ __PRETTY_FUNCTION__)); | |||
141 | return res; | |||
142 | } | |||
143 | ||||
144 | /* | |||
145 | * Public functions | |||
146 | */ | |||
147 | ||||
148 | void TrueTypeCreatorNewEmpty(sal_uInt32 tag, TrueTypeCreator **_this) | |||
149 | { | |||
150 | TrueTypeCreator* ptr = static_cast<TrueTypeCreator*>(smalloc(sizeof(TrueTypeCreator))); | |||
151 | ||||
152 | ptr->tables = listNewEmpty(); | |||
153 | listSetElementDtor(ptr->tables, TrueTypeTableDispose); | |||
154 | ||||
155 | ptr->tag = tag; | |||
156 | ||||
157 | *_this = ptr; | |||
158 | } | |||
159 | ||||
160 | void AddTable(TrueTypeCreator *_this, TrueTypeTable *table) | |||
161 | { | |||
162 | if (table != nullptr) { | |||
163 | listAppend(_this->tables, table); | |||
164 | } | |||
165 | } | |||
166 | ||||
167 | void RemoveTable(TrueTypeCreator *_this, sal_uInt32 tag) | |||
168 | { | |||
169 | if (!listCount(_this->tables)) | |||
170 | return; | |||
171 | ||||
172 | listToFirst(_this->tables); | |||
173 | int done = 0; | |||
174 | do { | |||
175 | if (static_cast<TrueTypeTable *>(listCurrent(_this->tables))->tag == tag) | |||
176 | { | |||
177 | listRemove(_this->tables); | |||
178 | } | |||
179 | else | |||
180 | { | |||
181 | if (listNext(_this->tables)) | |||
182 | { | |||
183 | done = 1; | |||
184 | } | |||
185 | } | |||
186 | } while (!done); | |||
187 | } | |||
188 | ||||
189 | static void ProcessTables(TrueTypeCreator *); | |||
190 | ||||
191 | SFErrCodes StreamToMemory(TrueTypeCreator *_this, sal_uInt8 **ptr, sal_uInt32 *length) | |||
192 | { | |||
193 | sal_uInt16 searchRange=1, entrySelector=0, rangeShift; | |||
194 | sal_uInt32 s, offset, checkSumAdjustment = 0; | |||
195 | sal_uInt32 *p; | |||
196 | sal_uInt8 *head = nullptr; /* saved pointer to the head table data for checkSumAdjustment calculation */ | |||
197 | ||||
198 | if (listIsEmpty(_this->tables)) return SFErrCodes::TtFormat; | |||
199 | ||||
200 | ProcessTables(_this); | |||
201 | ||||
202 | /* ProcessTables() adds 'loca' and 'hmtx' */ | |||
203 | ||||
204 | sal_uInt16 numTables = listCount(_this->tables); | |||
205 | ||||
206 | TableEntry* te = static_cast<TableEntry*>(scalloc(numTables, sizeof(TableEntry))); | |||
207 | TableEntry* e = te; | |||
208 | ||||
209 | listToFirst(_this->tables); | |||
210 | do { | |||
211 | GetRawData(static_cast<TrueTypeTable *>(listCurrent(_this->tables)), &e->data, &e->length, &e->tag); | |||
212 | ++e; | |||
213 | } while (listNext(_this->tables)); | |||
214 | ||||
215 | qsort(te, numTables, sizeof(TableEntry), TableEntryCompareF); | |||
216 | ||||
217 | do { | |||
218 | searchRange *= 2; | |||
219 | entrySelector++; | |||
220 | } while (searchRange <= numTables); | |||
221 | ||||
222 | searchRange *= 8; | |||
223 | entrySelector--; | |||
224 | rangeShift = numTables * 16 - searchRange; | |||
225 | ||||
226 | s = offset = 12 + 16 * numTables; | |||
227 | ||||
228 | for (int i = 0; i < numTables; ++i) { | |||
229 | s += (te[i].length + 3) & sal_uInt32(~3); | |||
230 | /* if ((te[i].length & 3) != 0) s += (4 - (te[i].length & 3)) & 3; */ | |||
231 | } | |||
232 | ||||
233 | sal_uInt8* ttf = static_cast<sal_uInt8*>(smalloc(s)); | |||
234 | ||||
235 | /* Offset Table */ | |||
236 | PutUInt32(_this->tag, ttf, 0); | |||
237 | PutUInt16(numTables, ttf, 4); | |||
238 | PutUInt16(searchRange, ttf, 6); | |||
239 | PutUInt16(entrySelector, ttf, 8); | |||
240 | PutUInt16(rangeShift, ttf, 10); | |||
241 | ||||
242 | /* Table Directory */ | |||
243 | for (int i = 0; i
| |||
244 | PutUInt32(te[i].tag, ttf + 12, 16 * i); | |||
245 | PutUInt32(CheckSum(reinterpret_cast<sal_uInt32 *>(te[i].data), te[i].length), ttf + 12, 16 * i + 4); | |||
246 | PutUInt32(offset, ttf + 12, 16 * i + 8); | |||
247 | PutUInt32(te[i].length, ttf + 12, 16 * i + 12); | |||
248 | ||||
249 | if (te[i].tag == T_head) { | |||
250 | head = ttf + offset; | |||
251 | } | |||
252 | ||||
253 | memcpy(ttf+offset, te[i].data, (te[i].length + 3) & sal_uInt32(~3) ); | |||
254 | offset += (te[i].length + 3) & sal_uInt32(~3); | |||
255 | /* if ((te[i].length & 3) != 0) offset += (4 - (te[i].length & 3)) & 3; */ | |||
256 | } | |||
257 | ||||
258 | free(te); | |||
259 | ||||
260 | p = reinterpret_cast<sal_uInt32 *>(ttf); | |||
261 | for (int i = 0; i < static_cast<int>(s) / 4; ++i) checkSumAdjustment += p[i]; | |||
| ||||
262 | PutUInt32(0xB1B0AFBA - checkSumAdjustment, head, 8); | |||
263 | ||||
264 | *ptr = ttf; | |||
265 | *length = s; | |||
266 | ||||
267 | return SFErrCodes::Ok; | |||
268 | } | |||
269 | ||||
270 | SFErrCodes StreamToFile(TrueTypeCreator *_this, const char* fname) | |||
271 | { | |||
272 | sal_uInt8 *ptr; | |||
273 | sal_uInt32 length; | |||
274 | SFErrCodes r; | |||
275 | ||||
276 | if ((r = StreamToMemory(_this, &ptr, &length)) != SFErrCodes::Ok) return r; | |||
| ||||
277 | r = SFErrCodes::BadFile; | |||
278 | if (fname) | |||
279 | { | |||
280 | FILE* fd = fopen(fname, "wb"); | |||
281 | if (fd) | |||
282 | { | |||
283 | if (fwrite(ptr, 1, length, fd) != length) { | |||
284 | r = SFErrCodes::FileIo; | |||
285 | } else { | |||
286 | r = SFErrCodes::Ok; | |||
287 | } | |||
288 | fclose(fd); | |||
289 | } | |||
290 | } | |||
291 | free(ptr); | |||
292 | return r; | |||
293 | } | |||
294 | ||||
295 | /* | |||
296 | * TrueTypeTable private methods | |||
297 | */ | |||
298 | ||||
299 | /* Table data points to | |||
300 | * -------------------------------------------- | |||
301 | * generic tdata_generic struct | |||
302 | * 'head' HEAD_Length bytes of memory | |||
303 | * 'hhea' HHEA_Length bytes of memory | |||
304 | * 'loca' tdata_loca struct | |||
305 | * 'maxp' MAXP_Version1Length bytes of memory | |||
306 | * 'glyf' list of GlyphData structs (defined in sft.h) | |||
307 | * 'name' list of NameRecord structs (defined in sft.h) | |||
308 | * 'post' tdata_post struct | |||
309 | * | |||
310 | */ | |||
311 | ||||
312 | #define CMAP_SUBTABLE_INIT10 10 | |||
313 | #define CMAP_SUBTABLE_INCR10 10 | |||
314 | #define CMAP_PAIR_INIT500 500 | |||
315 | #define CMAP_PAIR_INCR500 500 | |||
316 | ||||
317 | namespace { | |||
318 | ||||
319 | struct CmapSubTable { | |||
320 | sal_uInt32 id; /* subtable ID (platform/encoding ID) */ | |||
321 | sal_uInt32 n; /* number of used translation pairs */ | |||
322 | sal_uInt32 m; /* number of allocated translation pairs */ | |||
323 | sal_uInt32 *xc; /* character array */ | |||
324 | sal_uInt32 *xg; /* glyph array */ | |||
325 | }; | |||
326 | ||||
327 | struct table_cmap { | |||
328 | sal_uInt32 n; /* number of used CMAP sub-tables */ | |||
329 | sal_uInt32 m; /* number of allocated CMAP sub-tables */ | |||
330 | CmapSubTable *s; /* sorted array of sub-tables */ | |||
331 | }; | |||
332 | ||||
333 | struct tdata_generic { | |||
334 | sal_uInt32 tag; | |||
335 | sal_uInt32 nbytes; | |||
336 | sal_uInt8 *ptr; | |||
337 | }; | |||
338 | ||||
339 | struct tdata_loca { | |||
340 | sal_uInt32 nbytes; /* number of bytes in loca table */ | |||
341 | sal_uInt8 *ptr; /* pointer to the data */ | |||
342 | }; | |||
343 | ||||
344 | struct tdata_post { | |||
345 | sal_uInt32 format; | |||
346 | sal_uInt32 italicAngle; | |||
347 | sal_Int16 underlinePosition; | |||
348 | sal_Int16 underlineThickness; | |||
349 | sal_uInt32 isFixedPitch; | |||
350 | void *ptr; /* format-specific pointer */ | |||
351 | }; | |||
352 | ||||
353 | } | |||
354 | ||||
355 | /* allocate memory for a TT table */ | |||
356 | static sal_uInt8 *ttmalloc(sal_uInt32 nbytes) | |||
357 | { | |||
358 | sal_uInt32 n; | |||
359 | ||||
360 | n = (nbytes + 3) & sal_uInt32(~3); | |||
361 | sal_uInt8* res = static_cast<sal_uInt8*>(calloc(n, 1)); | |||
362 | assert(res != nullptr)(static_cast <bool> (res != nullptr) ? void (0) : __assert_fail ("res != nullptr", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 362, __extension__ __PRETTY_FUNCTION__)); | |||
363 | ||||
364 | return res; | |||
365 | } | |||
366 | ||||
367 | static void FreeGlyphData(void *ptr) | |||
368 | { | |||
369 | GlyphData *p = static_cast<GlyphData *>(ptr); | |||
370 | if (p->ptr) free(p->ptr); | |||
371 | free(p); | |||
372 | } | |||
373 | ||||
374 | static void TrueTypeTableDispose_generic(TrueTypeTable *_this) | |||
375 | { | |||
376 | if (_this) { | |||
377 | if (_this->data) { | |||
378 | tdata_generic *pdata = static_cast<tdata_generic *>(_this->data); | |||
379 | if (pdata->nbytes) free(pdata->ptr); | |||
380 | free(_this->data); | |||
381 | } | |||
382 | free(_this); | |||
383 | } | |||
384 | } | |||
385 | ||||
386 | static void TrueTypeTableDispose_head(TrueTypeTable *_this) | |||
387 | { | |||
388 | if (_this) { | |||
389 | if (_this->data) free(_this->data); | |||
390 | free(_this); | |||
391 | } | |||
392 | } | |||
393 | ||||
394 | static void TrueTypeTableDispose_hhea(TrueTypeTable *_this) | |||
395 | { | |||
396 | if (_this) { | |||
397 | if (_this->data) free(_this->data); | |||
398 | free(_this); | |||
399 | } | |||
400 | } | |||
401 | ||||
402 | static void TrueTypeTableDispose_loca(TrueTypeTable *_this) | |||
403 | { | |||
404 | if (_this) { | |||
405 | if (_this->data) { | |||
406 | tdata_loca *p = static_cast<tdata_loca *>(_this->data); | |||
407 | if (p->ptr) free(p->ptr); | |||
408 | free(_this->data); | |||
409 | } | |||
410 | free(_this); | |||
411 | } | |||
412 | } | |||
413 | ||||
414 | static void TrueTypeTableDispose_maxp(TrueTypeTable *_this) | |||
415 | { | |||
416 | if (_this) { | |||
417 | if (_this->data) free(_this->data); | |||
418 | free(_this); | |||
419 | } | |||
420 | } | |||
421 | ||||
422 | static void TrueTypeTableDispose_glyf(TrueTypeTable *_this) | |||
423 | { | |||
424 | if (_this) { | |||
425 | if (_this->data) listDispose(static_cast<list>(_this->data)); | |||
426 | free(_this); | |||
427 | } | |||
428 | } | |||
429 | ||||
430 | static void TrueTypeTableDispose_cmap(TrueTypeTable *_this) | |||
431 | { | |||
432 | if (!_this) return; | |||
433 | ||||
434 | table_cmap *t = static_cast<table_cmap *>(_this->data); | |||
435 | if (t) { | |||
436 | CmapSubTable *s = t->s; | |||
437 | if (s) { | |||
438 | for (sal_uInt32 i = 0; i < t->m; i++) { | |||
439 | if (s[i].xc) free(s[i].xc); | |||
440 | if (s[i].xg) free(s[i].xg); | |||
441 | } | |||
442 | free(s); | |||
443 | } | |||
444 | free(t); | |||
445 | } | |||
446 | free(_this); | |||
447 | } | |||
448 | ||||
449 | static void TrueTypeTableDispose_name(TrueTypeTable *_this) | |||
450 | { | |||
451 | if (_this) { | |||
452 | if (_this->data) listDispose(static_cast<list>(_this->data)); | |||
453 | free(_this); | |||
454 | } | |||
455 | } | |||
456 | ||||
457 | static void TrueTypeTableDispose_post(TrueTypeTable *_this) | |||
458 | { | |||
459 | if (!_this) return; | |||
460 | ||||
461 | tdata_post *p = static_cast<tdata_post *>(_this->data); | |||
462 | if (p) { | |||
463 | if (p->format == 0x00030000) { | |||
464 | /* do nothing */ | |||
465 | } else { | |||
466 | SAL_WARN("vcl.fonts", "Unsupported format of a 'post' table: "do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "vcl.fonts")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Unsupported format of a 'post' table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << ".") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "471" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Unsupported format of a 'post' table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Unsupported format of a 'post' table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "471" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Unsupported format of a 'post' table: " << std::setfill('0') << std::setw(8) << std::hex << std::uppercase << static_cast<int>(p->format) << ".") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "471" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Unsupported format of a 'post' table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Unsupported format of a 'post' table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "471" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
467 | << std::setfill('0')do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "vcl.fonts")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Unsupported format of a 'post' table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << ".") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "471" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Unsupported format of a 'post' table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Unsupported format of a 'post' table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "471" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Unsupported format of a 'post' table: " << std::setfill('0') << std::setw(8) << std::hex << std::uppercase << static_cast<int>(p->format) << ".") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "471" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Unsupported format of a 'post' table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Unsupported format of a 'post' table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "471" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
468 | << std::setw(8)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "vcl.fonts")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Unsupported format of a 'post' table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << ".") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "471" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Unsupported format of a 'post' table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Unsupported format of a 'post' table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "471" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Unsupported format of a 'post' table: " << std::setfill('0') << std::setw(8) << std::hex << std::uppercase << static_cast<int>(p->format) << ".") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "471" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Unsupported format of a 'post' table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Unsupported format of a 'post' table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "471" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
469 | << std::hexdo { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "vcl.fonts")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Unsupported format of a 'post' table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << ".") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "471" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Unsupported format of a 'post' table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Unsupported format of a 'post' table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "471" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Unsupported format of a 'post' table: " << std::setfill('0') << std::setw(8) << std::hex << std::uppercase << static_cast<int>(p->format) << ".") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "471" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Unsupported format of a 'post' table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Unsupported format of a 'post' table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "471" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
470 | << std::uppercasedo { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "vcl.fonts")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Unsupported format of a 'post' table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << ".") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "471" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Unsupported format of a 'post' table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Unsupported format of a 'post' table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "471" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Unsupported format of a 'post' table: " << std::setfill('0') << std::setw(8) << std::hex << std::uppercase << static_cast<int>(p->format) << ".") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "471" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Unsupported format of a 'post' table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Unsupported format of a 'post' table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "471" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
471 | << static_cast<int>(p->format) << ".")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "vcl.fonts")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Unsupported format of a 'post' table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << ".") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "471" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Unsupported format of a 'post' table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Unsupported format of a 'post' table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "471" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Unsupported format of a 'post' table: " << std::setfill('0') << std::setw(8) << std::hex << std::uppercase << static_cast<int>(p->format) << ".") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "471" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Unsupported format of a 'post' table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Unsupported format of a 'post' table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "471" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
472 | } | |||
473 | free(p); | |||
474 | } | |||
475 | free(_this); | |||
476 | } | |||
477 | ||||
478 | /* destructor vtable */ | |||
479 | ||||
480 | struct { | |||
481 | sal_uInt32 tag; | |||
482 | void (*f)(TrueTypeTable *); | |||
483 | } const vtable1[] = | |||
484 | { | |||
485 | {0, TrueTypeTableDispose_generic}, | |||
486 | {T_head, TrueTypeTableDispose_head}, | |||
487 | {T_hhea, TrueTypeTableDispose_hhea}, | |||
488 | {T_loca, TrueTypeTableDispose_loca}, | |||
489 | {T_maxp, TrueTypeTableDispose_maxp}, | |||
490 | {T_glyf, TrueTypeTableDispose_glyf}, | |||
491 | {T_cmap, TrueTypeTableDispose_cmap}, | |||
492 | {T_name, TrueTypeTableDispose_name}, | |||
493 | {T_post, TrueTypeTableDispose_post} | |||
494 | ||||
495 | }; | |||
496 | ||||
497 | static int GetRawData_generic(TrueTypeTable *_this, sal_uInt8 **ptr, sal_uInt32 *len, sal_uInt32 *tag) | |||
498 | { | |||
499 | assert(_this != nullptr)(static_cast <bool> (_this != nullptr) ? void (0) : __assert_fail ("_this != nullptr", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 499, __extension__ __PRETTY_FUNCTION__)); | |||
500 | assert(_this->data != nullptr)(static_cast <bool> (_this->data != nullptr) ? void ( 0) : __assert_fail ("_this->data != nullptr", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 500, __extension__ __PRETTY_FUNCTION__)); | |||
501 | ||||
502 | *ptr = static_cast<tdata_generic *>(_this->data)->ptr; | |||
503 | *len = static_cast<tdata_generic *>(_this->data)->nbytes; | |||
504 | *tag = static_cast<tdata_generic *>(_this->data)->tag; | |||
505 | ||||
506 | return TTCR_OK; | |||
507 | } | |||
508 | ||||
509 | static int GetRawData_head(TrueTypeTable *_this, sal_uInt8 **ptr, sal_uInt32 *len, sal_uInt32 *tag) | |||
510 | { | |||
511 | *len = HEAD_Length; | |||
512 | *ptr = static_cast<sal_uInt8 *>(_this->data); | |||
513 | *tag = T_head; | |||
514 | ||||
515 | return TTCR_OK; | |||
516 | } | |||
517 | ||||
518 | static int GetRawData_hhea(TrueTypeTable *_this, sal_uInt8 **ptr, sal_uInt32 *len, sal_uInt32 *tag) | |||
519 | { | |||
520 | *len = HHEA_Length; | |||
521 | *ptr = static_cast<sal_uInt8 *>(_this->data); | |||
522 | *tag = T_hhea; | |||
523 | ||||
524 | return TTCR_OK; | |||
525 | } | |||
526 | ||||
527 | static int GetRawData_loca(TrueTypeTable *_this, sal_uInt8 **ptr, sal_uInt32 *len, sal_uInt32 *tag) | |||
528 | { | |||
529 | tdata_loca *p; | |||
530 | ||||
531 | assert(_this->data != nullptr)(static_cast <bool> (_this->data != nullptr) ? void ( 0) : __assert_fail ("_this->data != nullptr", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 531, __extension__ __PRETTY_FUNCTION__)); | |||
532 | ||||
533 | p = static_cast<tdata_loca *>(_this->data); | |||
534 | ||||
535 | if (p->nbytes == 0) return TTCR_ZEROGLYPHS; | |||
536 | ||||
537 | *ptr = p->ptr; | |||
538 | *len = p->nbytes; | |||
539 | *tag = T_loca; | |||
540 | ||||
541 | return TTCR_OK; | |||
542 | } | |||
543 | ||||
544 | static int GetRawData_maxp(TrueTypeTable *_this, sal_uInt8 **ptr, sal_uInt32 *len, sal_uInt32 *tag) | |||
545 | { | |||
546 | *len = MAXP_Version1Length; | |||
547 | *ptr = static_cast<sal_uInt8 *>(_this->data); | |||
548 | *tag = T_maxp; | |||
549 | ||||
550 | return TTCR_OK; | |||
551 | } | |||
552 | ||||
553 | static int GetRawData_glyf(TrueTypeTable *_this, sal_uInt8 **ptr, sal_uInt32 *len, sal_uInt32 *tag) | |||
554 | { | |||
555 | sal_uInt32 n, nbytes = 0; | |||
556 | list l = static_cast<list>(_this->data); | |||
557 | /* sal_uInt16 curID = 0; */ /* to check if glyph IDs are sequential and start from zero */ | |||
558 | sal_uInt8 *p; | |||
559 | ||||
560 | *ptr = nullptr; | |||
561 | *len = 0; | |||
562 | *tag = 0; | |||
563 | ||||
564 | if (listCount(l) == 0) return TTCR_ZEROGLYPHS; | |||
565 | ||||
566 | listToFirst(l); | |||
567 | do { | |||
568 | /* if (((GlyphData *) listCurrent(l))->glyphID != curID++) return TTCR_GLYPHSEQ; */ | |||
569 | nbytes += static_cast<GlyphData *>(listCurrent(l))->nbytes; | |||
570 | } while (listNext(l)); | |||
571 | ||||
572 | p = _this->rawdata = ttmalloc(nbytes); | |||
573 | ||||
574 | listToFirst(l); | |||
575 | do { | |||
576 | n = static_cast<GlyphData *>(listCurrent(l))->nbytes; | |||
577 | if (n != 0) { | |||
578 | memcpy(p, static_cast<GlyphData *>(listCurrent(l))->ptr, n); | |||
579 | p += n; | |||
580 | } | |||
581 | } while (listNext(l)); | |||
582 | ||||
583 | *len = nbytes; | |||
584 | *ptr = _this->rawdata; | |||
585 | *tag = T_glyf; | |||
586 | ||||
587 | return TTCR_OK; | |||
588 | } | |||
589 | ||||
590 | /* cmap packers */ | |||
591 | static sal_uInt8 *PackCmapType0(CmapSubTable const *s, sal_uInt32 *length) | |||
592 | { | |||
593 | sal_uInt8* ptr = static_cast<sal_uInt8*>(smalloc(262)); | |||
594 | sal_uInt8 *p = ptr + 6; | |||
595 | sal_uInt32 i, j; | |||
596 | sal_uInt16 g; | |||
597 | ||||
598 | PutUInt16(0, ptr, 0); | |||
599 | PutUInt16(262, ptr, 2); | |||
600 | PutUInt16(0, ptr, 4); | |||
601 | ||||
602 | for (i = 0; i < 256; i++) { | |||
603 | g = 0; | |||
604 | for (j = 0; j < s->n; j++) { | |||
605 | if (s->xc[j] == i) { | |||
606 | g = static_cast<sal_uInt16>(s->xg[j]); | |||
607 | } | |||
608 | } | |||
609 | p[i] = static_cast<sal_uInt8>(g); | |||
610 | } | |||
611 | *length = 262; | |||
612 | return ptr; | |||
613 | } | |||
614 | ||||
615 | static sal_uInt8 *PackCmapType6(CmapSubTable const *s, sal_uInt32 *length) | |||
616 | { | |||
617 | sal_uInt8* ptr = static_cast<sal_uInt8*>(smalloc(s->n*2 + 10)); | |||
618 | sal_uInt8 *p = ptr + 10; | |||
619 | sal_uInt32 i, j; | |||
620 | sal_uInt16 g; | |||
621 | ||||
622 | PutUInt16(6, ptr, 0); | |||
623 | PutUInt16(static_cast<sal_uInt16>(s->n*2+10), ptr, 2); | |||
624 | PutUInt16(0, ptr, 4); | |||
625 | PutUInt16(0, ptr, 6); | |||
626 | PutUInt16(static_cast<sal_uInt16>(s->n), ptr, 8 ); | |||
627 | ||||
628 | for (i = 0; i < s->n; i++) { | |||
629 | g = 0; | |||
630 | for (j = 0; j < s->n; j++) { | |||
631 | if (s->xc[j] == i) { | |||
632 | g = static_cast<sal_uInt16>(s->xg[j]); | |||
633 | } | |||
634 | } | |||
635 | PutUInt16( g, p, 2*i ); | |||
636 | } | |||
637 | *length = s->n*2+10; | |||
638 | return ptr; | |||
639 | } | |||
640 | ||||
641 | /* XXX it only handles Format 0 encoding tables */ | |||
642 | static sal_uInt8 *PackCmap(CmapSubTable const *s, sal_uInt32 *length) | |||
643 | { | |||
644 | if( s->xg[s->n-1] > 0xff ) | |||
645 | return PackCmapType6(s, length); | |||
646 | else | |||
647 | return PackCmapType0(s, length); | |||
648 | } | |||
649 | ||||
650 | static int GetRawData_cmap(TrueTypeTable *_this, sal_uInt8 **ptr, sal_uInt32 *len, sal_uInt32 *tag) | |||
651 | { | |||
652 | table_cmap *t; | |||
653 | sal_uInt32 i; | |||
654 | sal_uInt32 tlen = 0; | |||
655 | sal_uInt32 l; | |||
656 | sal_uInt32 cmapsize; | |||
657 | sal_uInt8 *cmap; | |||
658 | sal_uInt32 coffset; | |||
659 | ||||
660 | assert(_this != nullptr)(static_cast <bool> (_this != nullptr) ? void (0) : __assert_fail ("_this != nullptr", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 660, __extension__ __PRETTY_FUNCTION__)); | |||
661 | t = static_cast<table_cmap *>(_this->data); | |||
662 | assert(t != nullptr)(static_cast <bool> (t != nullptr) ? void (0) : __assert_fail ("t != nullptr", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 662, __extension__ __PRETTY_FUNCTION__)); | |||
663 | assert(t->n != 0)(static_cast <bool> (t->n != 0) ? void (0) : __assert_fail ("t->n != 0", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 663, __extension__ __PRETTY_FUNCTION__)); | |||
664 | ||||
665 | sal_uInt8** subtables = static_cast<sal_uInt8**>(scalloc(t->n, sizeof(sal_uInt8 *))); | |||
666 | sal_uInt32* sizes = static_cast<sal_uInt32*>(scalloc(t->n, sizeof(sal_uInt32))); | |||
667 | ||||
668 | for (i = 0; i < t->n; i++) { | |||
669 | subtables[i] = PackCmap(t->s+i, &l); | |||
670 | sizes[i] = l; | |||
671 | tlen += l; | |||
672 | } | |||
673 | ||||
674 | cmapsize = tlen + 4 + 8 * t->n; | |||
675 | _this->rawdata = cmap = ttmalloc(cmapsize); | |||
676 | ||||
677 | PutUInt16(0, cmap, 0); | |||
678 | PutUInt16(static_cast<sal_uInt16>(t->n), cmap, 2); | |||
679 | coffset = 4 + t->n * 8; | |||
680 | ||||
681 | for (i = 0; i < t->n; i++) { | |||
682 | PutUInt16(static_cast<sal_uInt16>(t->s[i].id >> 16), cmap + 4, i * 8); | |||
683 | PutUInt16(static_cast<sal_uInt16>(t->s[i].id & 0xFF), cmap + 4, 2 + i * 8); | |||
684 | PutUInt32(coffset, cmap + 4, 4 + i * 8); | |||
685 | memcpy(cmap + coffset, subtables[i], sizes[i]); | |||
686 | free(subtables[i]); | |||
687 | coffset += sizes[i]; | |||
688 | } | |||
689 | ||||
690 | free(subtables); | |||
691 | free(sizes); | |||
692 | ||||
693 | *ptr = cmap; | |||
694 | *len = cmapsize; | |||
695 | *tag = T_cmap; | |||
696 | ||||
697 | return TTCR_OK; | |||
698 | } | |||
699 | ||||
700 | static int GetRawData_name(TrueTypeTable *_this, sal_uInt8 **ptr, sal_uInt32 *len, sal_uInt32 *tag) | |||
701 | { | |||
702 | list l; | |||
703 | sal_Int16 i=0, n; /* number of Name Records */ | |||
704 | int stringLen = 0; | |||
705 | sal_uInt8 *p1, *p2; | |||
706 | ||||
707 | *ptr = nullptr; | |||
708 | *len = 0; | |||
709 | *tag = 0; | |||
710 | ||||
711 | assert(_this != nullptr)(static_cast <bool> (_this != nullptr) ? void (0) : __assert_fail ("_this != nullptr", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 711, __extension__ __PRETTY_FUNCTION__)); | |||
712 | l = static_cast<list>(_this->data); | |||
713 | assert(l != nullptr)(static_cast <bool> (l != nullptr) ? void (0) : __assert_fail ("l != nullptr", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 713, __extension__ __PRETTY_FUNCTION__)); | |||
714 | ||||
715 | if ((n = static_cast<sal_Int16>(listCount(l))) == 0) return TTCR_NONAMES; | |||
716 | ||||
717 | NameRecord* nr = static_cast<NameRecord*>(scalloc(n, sizeof(NameRecord))); | |||
718 | ||||
719 | listToFirst(l); | |||
720 | ||||
721 | do { | |||
722 | memcpy(nr+i, listCurrent(l), sizeof(NameRecord)); | |||
723 | stringLen += nr[i].slen; | |||
724 | i++; | |||
725 | } while (listNext(l)); | |||
726 | ||||
727 | if (stringLen > 65535) { | |||
728 | free(nr); | |||
729 | return TTCR_NAMETOOLONG; | |||
730 | } | |||
731 | ||||
732 | qsort(nr, n, sizeof(NameRecord), NameRecordCompareF); | |||
733 | ||||
734 | int nameLen = stringLen + 12 * n + 6; | |||
735 | sal_uInt8* name = ttmalloc(nameLen); | |||
736 | ||||
737 | PutUInt16(0, name, 0); | |||
738 | PutUInt16(n, name, 2); | |||
739 | PutUInt16(static_cast<sal_uInt16>(6 + 12 * n), name, 4); | |||
740 | ||||
741 | p1 = name + 6; | |||
742 | p2 = p1 + 12 * n; | |||
743 | ||||
744 | for (i = 0; i < n; i++) { | |||
745 | PutUInt16(nr[i].platformID, p1, 0); | |||
746 | PutUInt16(nr[i].encodingID, p1, 2); | |||
747 | PutUInt16(static_cast<sal_uInt16>(nr[i].languageID), p1, 4); | |||
748 | PutUInt16(nr[i].nameID, p1, 6); | |||
749 | PutUInt16(nr[i].slen, p1, 8); | |||
750 | PutUInt16(static_cast<sal_uInt16>(p2 - (name + 6 + 12 * n)), p1, 10); | |||
751 | if (nr[i].slen) { | |||
752 | memcpy(p2, nr[i].sptr, nr[i].slen); | |||
753 | } | |||
754 | /* {int j; for(j=0; j<nr[i].slen; j++) printf("%c", nr[i].sptr[j]); printf("\n"); }; */ | |||
755 | p2 += nr[i].slen; | |||
756 | p1 += 12; | |||
757 | } | |||
758 | ||||
759 | free(nr); | |||
760 | _this->rawdata = name; | |||
761 | ||||
762 | *ptr = name; | |||
763 | *len = static_cast<sal_uInt16>(nameLen); | |||
764 | *tag = T_name; | |||
765 | ||||
766 | /*{int j; for(j=0; j<nameLen; j++) printf("%c", name[j]); }; */ | |||
767 | ||||
768 | return TTCR_OK; | |||
769 | } | |||
770 | ||||
771 | static int GetRawData_post(TrueTypeTable *_this, sal_uInt8 **ptr, sal_uInt32 *len, sal_uInt32 *tag) | |||
772 | { | |||
773 | tdata_post *p = static_cast<tdata_post *>(_this->data); | |||
774 | sal_uInt8 *post = nullptr; | |||
775 | sal_uInt32 postLen = 0; | |||
776 | int ret; | |||
777 | ||||
778 | if (_this->rawdata) free(_this->rawdata); | |||
779 | ||||
780 | if (p->format == 0x00030000) { | |||
781 | postLen = 32; | |||
782 | post = ttmalloc(postLen); | |||
783 | PutUInt32(0x00030000, post, 0); | |||
784 | PutUInt32(p->italicAngle, post, 4); | |||
785 | PutUInt16(p->underlinePosition, post, 8); | |||
786 | PutUInt16(p->underlineThickness, post, 10); | |||
787 | PutUInt16(static_cast<sal_uInt16>(p->isFixedPitch), post, 12); | |||
788 | ret = TTCR_OK; | |||
789 | } else { | |||
790 | SAL_WARN("vcl.fonts", "Unrecognized format of a post table: "do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "vcl.fonts")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Unrecognized format of a post table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << ".") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "795" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Unrecognized format of a post table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Unrecognized format of a post table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "795" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Unrecognized format of a post table: " << std ::setfill('0') << std::setw(8) << std::hex << std::uppercase << static_cast<int>(p->format) << ".") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "795" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Unrecognized format of a post table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Unrecognized format of a post table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "795" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
791 | << std::setfill('0')do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "vcl.fonts")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Unrecognized format of a post table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << ".") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "795" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Unrecognized format of a post table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Unrecognized format of a post table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "795" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Unrecognized format of a post table: " << std ::setfill('0') << std::setw(8) << std::hex << std::uppercase << static_cast<int>(p->format) << ".") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "795" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Unrecognized format of a post table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Unrecognized format of a post table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "795" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
792 | << std::setw(8)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "vcl.fonts")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Unrecognized format of a post table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << ".") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "795" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Unrecognized format of a post table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Unrecognized format of a post table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "795" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Unrecognized format of a post table: " << std ::setfill('0') << std::setw(8) << std::hex << std::uppercase << static_cast<int>(p->format) << ".") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "795" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Unrecognized format of a post table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Unrecognized format of a post table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "795" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
793 | << std::hexdo { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "vcl.fonts")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Unrecognized format of a post table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << ".") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "795" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Unrecognized format of a post table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Unrecognized format of a post table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "795" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Unrecognized format of a post table: " << std ::setfill('0') << std::setw(8) << std::hex << std::uppercase << static_cast<int>(p->format) << ".") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "795" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Unrecognized format of a post table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Unrecognized format of a post table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "795" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
794 | << std::uppercasedo { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "vcl.fonts")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Unrecognized format of a post table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << ".") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "795" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Unrecognized format of a post table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Unrecognized format of a post table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "795" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Unrecognized format of a post table: " << std ::setfill('0') << std::setw(8) << std::hex << std::uppercase << static_cast<int>(p->format) << ".") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "795" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Unrecognized format of a post table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Unrecognized format of a post table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "795" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
795 | << static_cast<int>(p->format) << ".")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "vcl.fonts")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Unrecognized format of a post table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << ".") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "795" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Unrecognized format of a post table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Unrecognized format of a post table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "795" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Unrecognized format of a post table: " << std ::setfill('0') << std::setw(8) << std::hex << std::uppercase << static_cast<int>(p->format) << ".") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "795" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Unrecognized format of a post table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Unrecognized format of a post table: " << std::setfill('0') << std::setw(8) << std ::hex << std::uppercase << static_cast<int> (p->format) << "."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl.fonts"), ("/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" ":" "795" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
796 | ret = TTCR_POSTFORMAT; | |||
797 | } | |||
798 | ||||
799 | *ptr = _this->rawdata = post; | |||
800 | *len = postLen; | |||
801 | *tag = T_post; | |||
802 | ||||
803 | return ret; | |||
804 | } | |||
805 | ||||
806 | struct { | |||
807 | sal_uInt32 tag; | |||
808 | int (*f)(TrueTypeTable *, sal_uInt8 **, sal_uInt32 *, sal_uInt32 *); | |||
809 | } const vtable2[] = | |||
810 | { | |||
811 | {0, GetRawData_generic}, | |||
812 | {T_head, GetRawData_head}, | |||
813 | {T_hhea, GetRawData_hhea}, | |||
814 | {T_loca, GetRawData_loca}, | |||
815 | {T_maxp, GetRawData_maxp}, | |||
816 | {T_glyf, GetRawData_glyf}, | |||
817 | {T_cmap, GetRawData_cmap}, | |||
818 | {T_name, GetRawData_name}, | |||
819 | {T_post, GetRawData_post} | |||
820 | ||||
821 | }; | |||
822 | ||||
823 | /* | |||
824 | * TrueTypeTable public methods | |||
825 | */ | |||
826 | ||||
827 | /* Note: Type42 fonts only need these tables: | |||
828 | * head, hhea, loca, maxp, cvt, prep, glyf, hmtx, fpgm | |||
829 | * | |||
830 | * Microsoft required tables | |||
831 | * cmap, glyf, head, hhea, hmtx, loca, maxp, name, post, OS/2 | |||
832 | * | |||
833 | * Apple required tables | |||
834 | * cmap, glyf, head, hhea, hmtx, loca, maxp, name, post | |||
835 | * | |||
836 | */ | |||
837 | ||||
838 | TrueTypeTable *TrueTypeTableNew(sal_uInt32 tag, | |||
839 | sal_uInt32 nbytes, | |||
840 | const sal_uInt8* ptr) | |||
841 | { | |||
842 | TrueTypeTable* table = static_cast<TrueTypeTable*>(smalloc(sizeof(TrueTypeTable))); | |||
843 | tdata_generic* pdata = static_cast<tdata_generic*>(smalloc(sizeof(tdata_generic))); | |||
844 | pdata->nbytes = nbytes; | |||
845 | pdata->tag = tag; | |||
846 | if (nbytes) { | |||
847 | pdata->ptr = ttmalloc(nbytes); | |||
848 | memcpy(pdata->ptr, ptr, nbytes); | |||
849 | } else { | |||
850 | pdata->ptr = nullptr; | |||
851 | } | |||
852 | ||||
853 | table->tag = 0; | |||
854 | table->data = pdata; | |||
855 | table->rawdata = nullptr; | |||
856 | ||||
857 | return table; | |||
858 | } | |||
859 | ||||
860 | TrueTypeTable *TrueTypeTableNew_head(sal_uInt32 fontRevision, | |||
861 | sal_uInt16 flags, | |||
862 | sal_uInt16 unitsPerEm, | |||
863 | const sal_uInt8* created, | |||
864 | sal_uInt16 macStyle, | |||
865 | sal_uInt16 lowestRecPPEM, | |||
866 | sal_Int16 fontDirectionHint) | |||
867 | { | |||
868 | assert(created != nullptr)(static_cast <bool> (created != nullptr) ? void (0) : __assert_fail ("created != nullptr", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 868, __extension__ __PRETTY_FUNCTION__)); | |||
869 | ||||
870 | TrueTypeTable* table = static_cast<TrueTypeTable*>(smalloc(sizeof(TrueTypeTable))); | |||
871 | sal_uInt8* ptr = ttmalloc(HEAD_Length); | |||
872 | ||||
873 | PutUInt32(0x00010000, ptr, 0); /* version */ | |||
874 | PutUInt32(fontRevision, ptr, 4); | |||
875 | PutUInt32(0x5F0F3CF5, ptr, 12); /* magic number */ | |||
876 | PutUInt16(flags, ptr, 16); | |||
877 | PutUInt16(unitsPerEm, ptr, 18); | |||
878 | memcpy(ptr+20, created, 8); /* Created Long Date */ | |||
879 | memset(ptr+28, 0, 8); /* Modified Long Date */ | |||
880 | PutUInt16(macStyle, ptr, 44); | |||
881 | PutUInt16(lowestRecPPEM, ptr, 46); | |||
882 | PutUInt16(fontDirectionHint, ptr, 48); | |||
883 | PutUInt16(0, ptr, 52); /* glyph data format: 0 */ | |||
884 | ||||
885 | table->data = static_cast<void *>(ptr); | |||
886 | table->tag = T_head; | |||
887 | table->rawdata = nullptr; | |||
888 | ||||
889 | return table; | |||
890 | } | |||
891 | ||||
892 | TrueTypeTable *TrueTypeTableNew_hhea(sal_Int16 ascender, | |||
893 | sal_Int16 descender, | |||
894 | sal_Int16 linegap, | |||
895 | sal_Int16 caretSlopeRise, | |||
896 | sal_Int16 caretSlopeRun) | |||
897 | { | |||
898 | TrueTypeTable* table = static_cast<TrueTypeTable*>(smalloc(sizeof(TrueTypeTable))); | |||
899 | sal_uInt8* ptr = ttmalloc(HHEA_Length); | |||
900 | ||||
901 | PutUInt32(0x00010000, ptr, 0); /* version */ | |||
902 | PutUInt16(ascender, ptr, 4); | |||
903 | PutUInt16(descender, ptr, 6); | |||
904 | PutUInt16(linegap, ptr, 8); | |||
905 | PutUInt16(caretSlopeRise, ptr, 18); | |||
906 | PutUInt16(caretSlopeRun, ptr, 20); | |||
907 | PutUInt16(0, ptr, 22); /* reserved 1 */ | |||
908 | PutUInt16(0, ptr, 24); /* reserved 2 */ | |||
909 | PutUInt16(0, ptr, 26); /* reserved 3 */ | |||
910 | PutUInt16(0, ptr, 28); /* reserved 4 */ | |||
911 | PutUInt16(0, ptr, 30); /* reserved 5 */ | |||
912 | PutUInt16(0, ptr, 32); /* metricDataFormat */ | |||
913 | ||||
914 | table->data = static_cast<void *>(ptr); | |||
915 | table->tag = T_hhea; | |||
916 | table->rawdata = nullptr; | |||
917 | ||||
918 | return table; | |||
919 | } | |||
920 | ||||
921 | TrueTypeTable *TrueTypeTableNew_loca() | |||
922 | { | |||
923 | TrueTypeTable* table = static_cast<TrueTypeTable*>(smalloc(sizeof(TrueTypeTable))); | |||
924 | table->data = smalloc(sizeof(tdata_loca)); | |||
925 | ||||
926 | static_cast<tdata_loca *>(table->data)->nbytes = 0; | |||
927 | static_cast<tdata_loca *>(table->data)->ptr = nullptr; | |||
928 | ||||
929 | table->tag = T_loca; | |||
930 | table->rawdata = nullptr; | |||
931 | ||||
932 | return table; | |||
933 | } | |||
934 | ||||
935 | TrueTypeTable *TrueTypeTableNew_maxp( const sal_uInt8* maxp, int size) | |||
936 | { | |||
937 | TrueTypeTable* table = static_cast<TrueTypeTable*>(smalloc(sizeof(TrueTypeTable))); | |||
938 | table->data = ttmalloc(MAXP_Version1Length); | |||
939 | ||||
940 | if (maxp && size == MAXP_Version1Length) { | |||
941 | memcpy(table->data, maxp, MAXP_Version1Length); | |||
942 | } | |||
943 | ||||
944 | table->tag = T_maxp; | |||
945 | table->rawdata = nullptr; | |||
946 | ||||
947 | return table; | |||
948 | } | |||
949 | ||||
950 | TrueTypeTable *TrueTypeTableNew_glyf() | |||
951 | { | |||
952 | TrueTypeTable* table = static_cast<TrueTypeTable*>(smalloc(sizeof(TrueTypeTable))); | |||
953 | list l = listNewEmpty(); | |||
954 | ||||
955 | assert(l != nullptr)(static_cast <bool> (l != nullptr) ? void (0) : __assert_fail ("l != nullptr", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 955, __extension__ __PRETTY_FUNCTION__)); | |||
956 | ||||
957 | listSetElementDtor(l, FreeGlyphData); | |||
958 | ||||
959 | table->data = l; | |||
960 | table->rawdata = nullptr; | |||
961 | table->tag = T_glyf; | |||
962 | ||||
963 | return table; | |||
964 | } | |||
965 | ||||
966 | TrueTypeTable *TrueTypeTableNew_cmap() | |||
967 | { | |||
968 | TrueTypeTable* table = static_cast<TrueTypeTable*>(smalloc(sizeof(TrueTypeTable))); | |||
969 | table_cmap* cmap = static_cast<table_cmap*>(smalloc(sizeof(table_cmap))); | |||
970 | ||||
971 | cmap->n = 0; | |||
972 | cmap->m = CMAP_SUBTABLE_INIT10; | |||
973 | cmap->s = static_cast<CmapSubTable *>(scalloc(CMAP_SUBTABLE_INIT10, sizeof(CmapSubTable))); | |||
974 | ||||
975 | table->data = cmap; | |||
976 | ||||
977 | table->rawdata = nullptr; | |||
978 | table->tag = T_cmap; | |||
979 | ||||
980 | return table; | |||
981 | } | |||
982 | ||||
983 | static void DisposeNameRecord(void *ptr) | |||
984 | { | |||
985 | if (ptr != nullptr) { | |||
986 | NameRecord *nr = static_cast<NameRecord *>(ptr); | |||
987 | if (nr->sptr) free(nr->sptr); | |||
988 | free(ptr); | |||
989 | } | |||
990 | } | |||
991 | ||||
992 | static NameRecord* NameRecordNewCopy(NameRecord const *nr) | |||
993 | { | |||
994 | NameRecord* p = static_cast<NameRecord*>(smalloc(sizeof(NameRecord))); | |||
995 | ||||
996 | memcpy(p, nr, sizeof(NameRecord)); | |||
997 | ||||
998 | if (p->slen) { | |||
999 | p->sptr = static_cast<sal_uInt8*>(smalloc(p->slen)); | |||
1000 | memcpy(p->sptr, nr->sptr, p->slen); | |||
1001 | } | |||
1002 | ||||
1003 | return p; | |||
1004 | } | |||
1005 | ||||
1006 | TrueTypeTable *TrueTypeTableNew_name(int n, NameRecord const *nr) | |||
1007 | { | |||
1008 | TrueTypeTable* table = static_cast<TrueTypeTable*>(smalloc(sizeof(TrueTypeTable))); | |||
1009 | list l = listNewEmpty(); | |||
1010 | ||||
1011 | assert(l != nullptr)(static_cast <bool> (l != nullptr) ? void (0) : __assert_fail ("l != nullptr", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 1011, __extension__ __PRETTY_FUNCTION__)); | |||
1012 | ||||
1013 | listSetElementDtor(l, DisposeNameRecord); | |||
1014 | ||||
1015 | if (n != 0) { | |||
1016 | int i; | |||
1017 | for (i = 0; i < n; i++) { | |||
1018 | listAppend(l, NameRecordNewCopy(nr+i)); | |||
1019 | } | |||
1020 | } | |||
1021 | ||||
1022 | table->data = l; | |||
1023 | table->rawdata = nullptr; | |||
1024 | table->tag = T_name; | |||
1025 | ||||
1026 | return table; | |||
1027 | } | |||
1028 | ||||
1029 | TrueTypeTable *TrueTypeTableNew_post(sal_Int32 format, | |||
1030 | sal_Int32 italicAngle, | |||
1031 | sal_Int16 underlinePosition, | |||
1032 | sal_Int16 underlineThickness, | |||
1033 | sal_uInt32 isFixedPitch) | |||
1034 | { | |||
1035 | assert(format == 0x00030000)(static_cast <bool> (format == 0x00030000) ? void (0) : __assert_fail ("format == 0x00030000", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 1035, __extension__ __PRETTY_FUNCTION__)); /* Only format 3.0 is supported at this time */ | |||
1036 | TrueTypeTable* table = static_cast<TrueTypeTable*>(smalloc(sizeof(TrueTypeTable))); | |||
1037 | tdata_post* post = static_cast<tdata_post*>(smalloc(sizeof(tdata_post))); | |||
1038 | ||||
1039 | post->format = format; | |||
1040 | post->italicAngle = italicAngle; | |||
1041 | post->underlinePosition = underlinePosition; | |||
1042 | post->underlineThickness = underlineThickness; | |||
1043 | post->isFixedPitch = isFixedPitch; | |||
1044 | post->ptr = nullptr; | |||
1045 | ||||
1046 | table->data = post; | |||
1047 | table->rawdata = nullptr; | |||
1048 | table->tag = T_post; | |||
1049 | ||||
1050 | return table; | |||
1051 | } | |||
1052 | ||||
1053 | int GetRawData(TrueTypeTable *_this, sal_uInt8 **ptr, sal_uInt32 *len, sal_uInt32 *tag) | |||
1054 | { | |||
1055 | /* XXX do a binary search */ | |||
1056 | assert(_this != nullptr)(static_cast <bool> (_this != nullptr) ? void (0) : __assert_fail ("_this != nullptr", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 1056, __extension__ __PRETTY_FUNCTION__)); | |||
1057 | assert(ptr != nullptr)(static_cast <bool> (ptr != nullptr) ? void (0) : __assert_fail ("ptr != nullptr", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 1057, __extension__ __PRETTY_FUNCTION__)); | |||
1058 | assert(len != nullptr)(static_cast <bool> (len != nullptr) ? void (0) : __assert_fail ("len != nullptr", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 1058, __extension__ __PRETTY_FUNCTION__)); | |||
1059 | assert(tag != nullptr)(static_cast <bool> (tag != nullptr) ? void (0) : __assert_fail ("tag != nullptr", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 1059, __extension__ __PRETTY_FUNCTION__)); | |||
1060 | ||||
1061 | *ptr = nullptr; *len = 0; *tag = 0; | |||
1062 | ||||
1063 | if (_this->rawdata) { | |||
1064 | free(_this->rawdata); | |||
1065 | _this->rawdata = nullptr; | |||
1066 | } | |||
1067 | ||||
1068 | for(size_t i=0; i < SAL_N_ELEMENTS(vtable2)(sizeof(sal_n_array_size(vtable2))); i++) { | |||
1069 | if (_this->tag == vtable2[i].tag) { | |||
1070 | return vtable2[i].f(_this, ptr, len, tag); | |||
1071 | } | |||
1072 | } | |||
1073 | ||||
1074 | assert(!"Unknown TrueType table.")(static_cast <bool> (!"Unknown TrueType table.") ? void (0) : __assert_fail ("!\"Unknown TrueType table.\"", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 1074, __extension__ __PRETTY_FUNCTION__)); | |||
1075 | return TTCR_UNKNOWN; | |||
1076 | } | |||
1077 | ||||
1078 | void cmapAdd(TrueTypeTable *table, sal_uInt32 id, sal_uInt32 c, sal_uInt32 g) | |||
1079 | { | |||
1080 | sal_uInt32 i, found; | |||
1081 | table_cmap *t; | |||
1082 | CmapSubTable *s; | |||
1083 | ||||
1084 | assert(table != nullptr)(static_cast <bool> (table != nullptr) ? void (0) : __assert_fail ("table != nullptr", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 1084, __extension__ __PRETTY_FUNCTION__)); | |||
1085 | assert(table->tag == T_cmap)(static_cast <bool> (table->tag == T_cmap) ? void (0 ) : __assert_fail ("table->tag == T_cmap", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 1085, __extension__ __PRETTY_FUNCTION__)); | |||
1086 | t = static_cast<table_cmap *>(table->data); assert(t != nullptr)(static_cast <bool> (t != nullptr) ? void (0) : __assert_fail ("t != nullptr", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 1086, __extension__ __PRETTY_FUNCTION__)); | |||
1087 | s = t->s; assert(s != nullptr)(static_cast <bool> (s != nullptr) ? void (0) : __assert_fail ("s != nullptr", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 1087, __extension__ __PRETTY_FUNCTION__)); | |||
1088 | ||||
1089 | found = 0; | |||
1090 | ||||
1091 | for (i = 0; i < t->n; i++) { | |||
1092 | if (s[i].id == id) { | |||
1093 | found = 1; | |||
1094 | break; | |||
1095 | } | |||
1096 | } | |||
1097 | ||||
1098 | if (!found) { | |||
1099 | if (t->n == t->m) { | |||
1100 | CmapSubTable* tmp = static_cast<CmapSubTable*>(scalloc(t->m + CMAP_SUBTABLE_INCR10, sizeof(CmapSubTable))); | |||
1101 | memcpy(tmp, s, sizeof(CmapSubTable) * t->m); | |||
1102 | t->m += CMAP_SUBTABLE_INCR10; | |||
1103 | free(s); | |||
1104 | s = tmp; | |||
1105 | t->s = s; | |||
1106 | } | |||
1107 | ||||
1108 | for (i = 0; i < t->n; i++) { | |||
1109 | if (s[i].id > id) break; | |||
1110 | } | |||
1111 | ||||
1112 | if (i < t->n) { | |||
1113 | memmove(s+i+1, s+i, t->n-i); | |||
1114 | } | |||
1115 | ||||
1116 | t->n++; | |||
1117 | ||||
1118 | s[i].id = id; | |||
1119 | s[i].n = 0; | |||
1120 | s[i].m = CMAP_PAIR_INIT500; | |||
1121 | s[i].xc = static_cast<sal_uInt32*>(scalloc(CMAP_PAIR_INIT500, sizeof(sal_uInt32))); | |||
1122 | s[i].xg = static_cast<sal_uInt32*>(scalloc(CMAP_PAIR_INIT500, sizeof(sal_uInt32))); | |||
1123 | } | |||
1124 | ||||
1125 | if (s[i].n == s[i].m) { | |||
1126 | sal_uInt32* tmp1 = static_cast<sal_uInt32*>(scalloc(s[i].m + CMAP_PAIR_INCR500, sizeof(sal_uInt32))); | |||
1127 | sal_uInt32* tmp2 = static_cast<sal_uInt32*>(scalloc(s[i].m + CMAP_PAIR_INCR500, sizeof(sal_uInt32))); | |||
1128 | assert(tmp1 != nullptr)(static_cast <bool> (tmp1 != nullptr) ? void (0) : __assert_fail ("tmp1 != nullptr", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 1128, __extension__ __PRETTY_FUNCTION__)); | |||
1129 | assert(tmp2 != nullptr)(static_cast <bool> (tmp2 != nullptr) ? void (0) : __assert_fail ("tmp2 != nullptr", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 1129, __extension__ __PRETTY_FUNCTION__)); | |||
1130 | memcpy(tmp1, s[i].xc, sizeof(sal_uInt32) * s[i].m); | |||
1131 | memcpy(tmp2, s[i].xg, sizeof(sal_uInt32) * s[i].m); | |||
1132 | s[i].m += CMAP_PAIR_INCR500; | |||
1133 | free(s[i].xc); | |||
1134 | free(s[i].xg); | |||
1135 | s[i].xc = tmp1; | |||
1136 | s[i].xg = tmp2; | |||
1137 | } | |||
1138 | ||||
1139 | s[i].xc[s[i].n] = c; | |||
1140 | s[i].xg[s[i].n] = g; | |||
1141 | s[i].n++; | |||
1142 | } | |||
1143 | ||||
1144 | sal_uInt32 glyfAdd(TrueTypeTable *table, GlyphData *glyphdata, AbstractTrueTypeFont *fnt) | |||
1145 | { | |||
1146 | list l; | |||
1147 | sal_uInt32 currentID; | |||
1148 | int ret, n, ncomponents; | |||
1149 | ||||
1150 | assert(table != nullptr)(static_cast <bool> (table != nullptr) ? void (0) : __assert_fail ("table != nullptr", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 1150, __extension__ __PRETTY_FUNCTION__)); | |||
1151 | assert(table->tag == T_glyf)(static_cast <bool> (table->tag == T_glyf) ? void (0 ) : __assert_fail ("table->tag == T_glyf", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 1151, __extension__ __PRETTY_FUNCTION__)); | |||
1152 | ||||
1153 | if (!glyphdata) return sal_uInt32(~0); | |||
1154 | ||||
1155 | std::vector< sal_uInt32 > glyphlist; | |||
1156 | ||||
1157 | ncomponents = GetTTGlyphComponents(fnt, glyphdata->glyphID, glyphlist); | |||
1158 | ||||
1159 | l = static_cast<list>(table->data); | |||
1160 | if (listCount(l) > 0) { | |||
1161 | listToLast(l); | |||
1162 | ret = n = static_cast<GlyphData *>(listCurrent(l))->newID + 1; | |||
1163 | } else { | |||
1164 | ret = n = 0; | |||
1165 | } | |||
1166 | glyphdata->newID = n++; | |||
1167 | listAppend(l, glyphdata); | |||
1168 | ||||
1169 | if (ncomponents > 1 && glyphlist.size() > 1 ) | |||
1170 | { | |||
1171 | std::vector< sal_uInt32 >::const_iterator it = glyphlist.begin(); | |||
1172 | ++it; | |||
1173 | /* glyphData->glyphID is always the first glyph on the list */ | |||
1174 | do | |||
1175 | { | |||
1176 | int found = 0; | |||
1177 | currentID = *it; | |||
1178 | /* XXX expensive! should be rewritten with sorted arrays! */ | |||
1179 | listToFirst(l); | |||
1180 | do { | |||
1181 | if (static_cast<GlyphData *>(listCurrent(l))->glyphID == currentID) { | |||
1182 | found = 1; | |||
1183 | break; | |||
1184 | } | |||
1185 | } while (listNext(l)); | |||
1186 | ||||
1187 | if (!found) { | |||
1188 | GlyphData *gd = GetTTRawGlyphData(fnt, currentID); | |||
1189 | gd->newID = n++; | |||
1190 | listAppend(l, gd); | |||
1191 | } | |||
1192 | } while( ++it != glyphlist.end() ); | |||
1193 | } | |||
1194 | ||||
1195 | return ret; | |||
1196 | } | |||
1197 | ||||
1198 | sal_uInt32 glyfCount(const TrueTypeTable *table) | |||
1199 | { | |||
1200 | assert(table != nullptr)(static_cast <bool> (table != nullptr) ? void (0) : __assert_fail ("table != nullptr", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 1200, __extension__ __PRETTY_FUNCTION__)); | |||
1201 | assert(table->tag == T_glyf)(static_cast <bool> (table->tag == T_glyf) ? void (0 ) : __assert_fail ("table->tag == T_glyf", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 1201, __extension__ __PRETTY_FUNCTION__)); | |||
1202 | return listCount(static_cast<list>(table->data)); | |||
1203 | } | |||
1204 | ||||
1205 | static TrueTypeTable *FindTable(TrueTypeCreator *tt, sal_uInt32 tag) | |||
1206 | { | |||
1207 | if (listIsEmpty(tt->tables)) return nullptr; | |||
1208 | ||||
1209 | listToFirst(tt->tables); | |||
1210 | ||||
1211 | do { | |||
1212 | if (static_cast<TrueTypeTable *>(listCurrent(tt->tables))->tag == tag) { | |||
1213 | return static_cast<TrueTypeTable*>(listCurrent(tt->tables)); | |||
1214 | } | |||
1215 | } while (listNext(tt->tables)); | |||
1216 | ||||
1217 | return nullptr; | |||
1218 | } | |||
1219 | ||||
1220 | /* This function processes all the tables and synchronizes them before creating | |||
1221 | * the output TrueType stream. | |||
1222 | * | |||
1223 | * *** It adds two TrueType tables to the font: 'loca' and 'hmtx' *** | |||
1224 | * | |||
1225 | * It does: | |||
1226 | * | |||
1227 | * - Re-numbers glyph IDs and creates 'glyf', 'loca', and 'hmtx' tables. | |||
1228 | * - Calculates xMin, yMin, xMax, and yMax and stores values in 'head' table. | |||
1229 | * - Stores indexToLocFormat in 'head' | |||
1230 | * - updates 'maxp' table | |||
1231 | * - Calculates advanceWidthMax, minLSB, minRSB, xMaxExtent and numberOfHMetrics | |||
1232 | * in 'hhea' table | |||
1233 | * | |||
1234 | */ | |||
1235 | static void ProcessTables(TrueTypeCreator *tt) | |||
1236 | { | |||
1237 | TrueTypeTable *glyf, *loca, *head, *maxp, *hhea; | |||
1238 | list glyphlist; | |||
1239 | sal_uInt32 nGlyphs, locaLen = 0, glyfLen = 0; | |||
1240 | sal_Int16 xMin = 0, yMin = 0, xMax = 0, yMax = 0; | |||
1241 | sal_uInt32 i = 0; | |||
1242 | sal_Int16 indexToLocFormat; | |||
1243 | sal_uInt8 *hmtxPtr, *hheaPtr; | |||
1244 | sal_uInt32 hmtxSize; | |||
1245 | sal_uInt8 *p1, *p2; | |||
1246 | sal_uInt16 maxPoints = 0, maxContours = 0, maxCompositePoints = 0, maxCompositeContours = 0; | |||
1247 | int nlsb = 0; | |||
1248 | sal_uInt32 *gid; /* array of old glyphIDs */ | |||
1249 | ||||
1250 | glyf = FindTable(tt, T_glyf); | |||
1251 | glyphlist = static_cast<list>(glyf->data); | |||
1252 | nGlyphs = listCount(glyphlist); | |||
1253 | assert(nGlyphs != 0)(static_cast <bool> (nGlyphs != 0) ? void (0) : __assert_fail ("nGlyphs != 0", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 1253, __extension__ __PRETTY_FUNCTION__)); | |||
1254 | gid = static_cast<sal_uInt32*>(scalloc(nGlyphs, sizeof(sal_uInt32))); | |||
1255 | ||||
1256 | RemoveTable(tt, T_loca); | |||
1257 | RemoveTable(tt, T_hmtx); | |||
1258 | ||||
1259 | /* XXX Need to make sure that composite glyphs do not break during glyph renumbering */ | |||
1260 | ||||
1261 | listToFirst(glyphlist); | |||
1262 | do { | |||
1263 | GlyphData *gd = static_cast<GlyphData *>(listCurrent(glyphlist)); | |||
1264 | glyfLen += gd->nbytes; | |||
1265 | /* XXX if (gd->nbytes & 1) glyfLen++; */ | |||
1266 | ||||
1267 | assert(gd->newID == i)(static_cast <bool> (gd->newID == i) ? void (0) : __assert_fail ("gd->newID == i", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 1267, __extension__ __PRETTY_FUNCTION__)); | |||
1268 | gid[i++] = gd->glyphID; | |||
1269 | /* gd->glyphID = i++; */ | |||
1270 | ||||
1271 | /* printf("IDs: %d %d.\n", gd->glyphID, gd->newID); */ | |||
1272 | ||||
1273 | if (gd->nbytes != 0) { | |||
1274 | sal_Int16 z = GetInt16(gd->ptr, 2); | |||
1275 | if (z < xMin) xMin = z; | |||
1276 | ||||
1277 | z = GetInt16(gd->ptr, 4); | |||
1278 | if (z < yMin) yMin = z; | |||
1279 | ||||
1280 | z = GetInt16(gd->ptr, 6); | |||
1281 | if (z > xMax) xMax = z; | |||
1282 | ||||
1283 | z = GetInt16(gd->ptr, 8); | |||
1284 | if (z > yMax) yMax = z; | |||
1285 | } | |||
1286 | ||||
1287 | if (!gd->compflag) { /* non-composite glyph */ | |||
1288 | if (gd->npoints > maxPoints) maxPoints = gd->npoints; | |||
1289 | if (gd->ncontours > maxContours) maxContours = gd->ncontours; | |||
1290 | } else { /* composite glyph */ | |||
1291 | if (gd->npoints > maxCompositePoints) maxCompositePoints = gd->npoints; | |||
1292 | if (gd->ncontours > maxCompositeContours) maxCompositeContours = gd->ncontours; | |||
1293 | } | |||
1294 | ||||
1295 | } while (listNext(glyphlist)); | |||
1296 | ||||
1297 | indexToLocFormat = (glyfLen / 2 > 0xFFFF) ? 1 : 0; | |||
1298 | locaLen = indexToLocFormat ? (nGlyphs + 1) << 2 : (nGlyphs + 1) << 1; | |||
1299 | ||||
1300 | sal_uInt8* glyfPtr = ttmalloc(glyfLen); | |||
1301 | sal_uInt8* locaPtr = ttmalloc(locaLen); | |||
1302 | TTSimpleGlyphMetrics* met = static_cast<TTSimpleGlyphMetrics*>(scalloc(nGlyphs, sizeof(TTSimpleGlyphMetrics))); | |||
1303 | i = 0; | |||
1304 | ||||
1305 | listToFirst(glyphlist); | |||
1306 | p1 = glyfPtr; | |||
1307 | p2 = locaPtr; | |||
1308 | do { | |||
1309 | GlyphData *gd = static_cast<GlyphData *>(listCurrent(glyphlist)); | |||
1310 | ||||
1311 | if (gd->compflag) { /* re-number all components */ | |||
1312 | sal_uInt16 flags, index; | |||
1313 | sal_uInt8 *ptr = gd->ptr + 10; | |||
1314 | do { | |||
1315 | sal_uInt32 j; | |||
1316 | flags = GetUInt16(ptr, 0); | |||
1317 | index = GetUInt16(ptr, 2); | |||
1318 | /* XXX use the sorted array of old to new glyphID mapping and do a binary search */ | |||
1319 | for (j = 0; j < nGlyphs; j++) { | |||
1320 | if (gid[j] == index) { | |||
1321 | break; | |||
1322 | } | |||
1323 | } | |||
1324 | /* printf("X: %d -> %d.\n", index, j); */ | |||
1325 | ||||
1326 | PutUInt16(static_cast<sal_uInt16>(j), ptr, 2); | |||
1327 | ||||
1328 | ptr += 4; | |||
1329 | ||||
1330 | if (flags & ARG_1_AND_2_ARE_WORDS) { | |||
1331 | ptr += 4; | |||
1332 | } else { | |||
1333 | ptr += 2; | |||
1334 | } | |||
1335 | ||||
1336 | if (flags & WE_HAVE_A_SCALE) { | |||
1337 | ptr += 2; | |||
1338 | } else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) { | |||
1339 | ptr += 4; | |||
1340 | } else if (flags & WE_HAVE_A_TWO_BY_TWO) { | |||
1341 | ptr += 8; | |||
1342 | } | |||
1343 | } while (flags & MORE_COMPONENTS); | |||
1344 | } | |||
1345 | ||||
1346 | if (gd->nbytes != 0) { | |||
1347 | memcpy(p1, gd->ptr, gd->nbytes); | |||
1348 | } | |||
1349 | if (indexToLocFormat == 1) { | |||
1350 | PutUInt32(p1 - glyfPtr, p2, 0); | |||
1351 | p2 += 4; | |||
1352 | } else { | |||
1353 | PutUInt16(static_cast<sal_uInt16>((p1 - glyfPtr) >> 1), p2, 0); | |||
1354 | p2 += 2; | |||
1355 | } | |||
1356 | p1 += gd->nbytes; | |||
1357 | ||||
1358 | /* fill the array of metrics */ | |||
1359 | met[i].adv = gd->aw; | |||
1360 | met[i].sb = gd->lsb; | |||
1361 | i++; | |||
1362 | } while (listNext(glyphlist)); | |||
1363 | ||||
1364 | free(gid); | |||
1365 | ||||
1366 | if (indexToLocFormat == 1) { | |||
1367 | PutUInt32(p1 - glyfPtr, p2, 0); | |||
1368 | } else { | |||
1369 | PutUInt16(static_cast<sal_uInt16>((p1 - glyfPtr) >> 1), p2, 0); | |||
1370 | } | |||
1371 | ||||
1372 | glyf->rawdata = glyfPtr; | |||
1373 | ||||
1374 | loca = TrueTypeTableNew_loca(); assert(loca != nullptr)(static_cast <bool> (loca != nullptr) ? void (0) : __assert_fail ("loca != nullptr", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 1374, __extension__ __PRETTY_FUNCTION__)); | |||
1375 | static_cast<tdata_loca *>(loca->data)->ptr = locaPtr; | |||
1376 | static_cast<tdata_loca *>(loca->data)->nbytes = locaLen; | |||
1377 | ||||
1378 | AddTable(tt, loca); | |||
1379 | ||||
1380 | head = FindTable(tt, T_head); | |||
1381 | sal_uInt8* const pHeadData = static_cast<sal_uInt8*>(head->data); | |||
1382 | PutInt16(xMin, pHeadData, HEAD_xMin_offset); | |||
1383 | PutInt16(yMin, pHeadData, HEAD_yMin_offset); | |||
1384 | PutInt16(xMax, pHeadData, HEAD_xMax_offset); | |||
1385 | PutInt16(yMax, pHeadData, HEAD_yMax_offset); | |||
1386 | PutInt16(indexToLocFormat, pHeadData, HEAD_indexToLocFormat_offset); | |||
1387 | ||||
1388 | maxp = FindTable(tt, T_maxp); | |||
1389 | ||||
1390 | sal_uInt8* const pMaxpData = static_cast<sal_uInt8*>(maxp->data); | |||
1391 | PutUInt16(static_cast<sal_uInt16>(nGlyphs), pMaxpData, MAXP_numGlyphs_offset); | |||
1392 | PutUInt16(maxPoints, pMaxpData, MAXP_maxPoints_offset); | |||
1393 | PutUInt16(maxContours, pMaxpData, MAXP_maxContours_offset); | |||
1394 | PutUInt16(maxCompositePoints, pMaxpData, MAXP_maxCompositePoints_offset); | |||
1395 | PutUInt16(maxCompositeContours, pMaxpData, MAXP_maxCompositeContours_offset); | |||
1396 | ||||
1397 | /* | |||
1398 | * Generate an htmx table and update hhea table | |||
1399 | */ | |||
1400 | hhea = FindTable(tt, T_hhea); assert(hhea != nullptr)(static_cast <bool> (hhea != nullptr) ? void (0) : __assert_fail ("hhea != nullptr", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 1400, __extension__ __PRETTY_FUNCTION__)); | |||
1401 | hheaPtr = static_cast<sal_uInt8 *>(hhea->data); | |||
1402 | if (nGlyphs > 2) { | |||
1403 | for (i = nGlyphs - 1; i > 0; i--) { | |||
1404 | if (met[i].adv != met[i-1].adv) break; | |||
1405 | } | |||
1406 | nlsb = nGlyphs - 1 - i; | |||
1407 | } | |||
1408 | hmtxSize = (nGlyphs - nlsb) * 4 + nlsb * 2; | |||
1409 | hmtxPtr = ttmalloc(hmtxSize); | |||
1410 | p1 = hmtxPtr; | |||
1411 | ||||
1412 | for (i = 0; i < nGlyphs; i++) { | |||
1413 | if (i < nGlyphs - nlsb) { | |||
1414 | PutUInt16(met[i].adv, p1, 0); | |||
1415 | PutUInt16(met[i].sb, p1, 2); | |||
1416 | p1 += 4; | |||
1417 | } else { | |||
1418 | PutUInt16(met[i].sb, p1, 0); | |||
1419 | p1 += 2; | |||
1420 | } | |||
1421 | } | |||
1422 | ||||
1423 | AddTable(tt, TrueTypeTableNew(T_hmtx, hmtxSize, hmtxPtr)); | |||
1424 | PutUInt16(static_cast<sal_uInt16>(nGlyphs - nlsb), hheaPtr, 34); | |||
1425 | free(hmtxPtr); | |||
1426 | free(met); | |||
1427 | } | |||
1428 | ||||
1429 | } // namespace vcl | |||
1430 | ||||
1431 | extern "C" | |||
1432 | { | |||
1433 | /** | |||
1434 | * TrueTypeCreator destructor. It calls destructors for all TrueTypeTables added to it. | |||
1435 | */ | |||
1436 | void TrueTypeCreatorDispose(vcl::TrueTypeCreator *_this) | |||
1437 | { | |||
1438 | listDispose(_this->tables); | |||
1439 | free(_this); | |||
1440 | } | |||
1441 | ||||
1442 | /** | |||
1443 | * Destructor for the TrueTypeTable object. | |||
1444 | */ | |||
1445 | void TrueTypeTableDispose(void * arg) | |||
1446 | { | |||
1447 | vcl::TrueTypeTable *_this = static_cast<vcl::TrueTypeTable *>(arg); | |||
1448 | /* XXX do a binary search */ | |||
1449 | assert(_this != nullptr)(static_cast <bool> (_this != nullptr) ? void (0) : __assert_fail ("_this != nullptr", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 1449, __extension__ __PRETTY_FUNCTION__)); | |||
1450 | ||||
1451 | if (_this->rawdata) free(_this->rawdata); | |||
1452 | ||||
1453 | for(size_t i=0; i < SAL_N_ELEMENTS(vcl::vtable1)(sizeof(sal_n_array_size(vcl::vtable1))); i++) { | |||
1454 | if (_this->tag == vcl::vtable1[i].tag) { | |||
1455 | vcl::vtable1[i].f(_this); | |||
1456 | return; | |||
1457 | } | |||
1458 | } | |||
1459 | assert(!"Unknown TrueType table.")(static_cast <bool> (!"Unknown TrueType table.") ? void (0) : __assert_fail ("!\"Unknown TrueType table.\"", "/home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx" , 1459, __extension__ __PRETTY_FUNCTION__)); | |||
1460 | } | |||
1461 | } | |||
1462 | ||||
1463 | #ifdef TEST_TTCR | |||
1464 | static sal_uInt32 mkTag(sal_uInt8 a, sal_uInt8 b, sal_uInt8 c, sal_uInt8 d) { | |||
1465 | return (a << 24) | (b << 16) | (c << 8) | d; | |||
1466 | } | |||
1467 | ||||
1468 | int main() | |||
1469 | { | |||
1470 | TrueTypeCreator *ttcr; | |||
1471 | sal_uInt8 *t1, *t2, *t3, *t4, *t5, *t6; | |||
1472 | ||||
1473 | TrueTypeCreatorNewEmpty(mkTag('t','r','u','e'), &ttcr); | |||
1474 | ||||
1475 | t1 = malloc(1000); memset(t1, 'a', 1000); | |||
1476 | t2 = malloc(2000); memset(t2, 'b', 2000); | |||
1477 | t3 = malloc(3000); memset(t3, 'c', 3000); | |||
1478 | t4 = malloc(4000); memset(t4, 'd', 4000); | |||
1479 | t5 = malloc(5000); memset(t5, 'e', 5000); | |||
1480 | t6 = malloc(6000); memset(t6, 'f', 6000); | |||
1481 | ||||
1482 | AddTable(ttcr, TrueTypeTableNew(T_maxp, 1000, t1)); | |||
1483 | AddTable(ttcr, TrueTypeTableNew(T_OS2, 2000, t2)); | |||
1484 | AddTable(ttcr, TrueTypeTableNew(T_cmap, 3000, t3)); | |||
1485 | AddTable(ttcr, TrueTypeTableNew(T_loca, 4000, t4)); | |||
1486 | AddTable(ttcr, TrueTypeTableNew(T_hhea, 5000, t5)); | |||
1487 | AddTable(ttcr, TrueTypeTableNew(T_glyf, 6000, t6)); | |||
1488 | ||||
1489 | free(t1); | |||
1490 | free(t2); | |||
1491 | free(t3); | |||
1492 | free(t4); | |||
1493 | free(t5); | |||
1494 | free(t6); | |||
1495 | ||||
1496 | StreamToFile(ttcr, "ttcrout.ttf"); | |||
1497 | ||||
1498 | TrueTypeCreatorDispose(ttcr); | |||
1499 | return 0; | |||
1500 | } | |||
1501 | #endif | |||
1502 | ||||
1503 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |