Bug Summary

File:home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx
Warning:line 261, column 74
Assigned value is garbage or undefined

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ttcr.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/glm -isystem /usr/include/glib-2.0 -isystem /usr/lib64/glib-2.0/include -isystem /usr/include/libmount -isystem /usr/include/blkid -isystem /usr/include/cairo -isystem /usr/include/glib-2.0 -isystem /usr/lib64/glib-2.0/include -isystem /usr/include/pixman-1 -isystem /usr/include/freetype2 -isystem /usr/include/libpng16 -isystem /usr/include/libxml2 -isystem /usr/include/freetype2 -isystem /usr/include/libpng16 -isystem /usr/include/dbus-1.0 -isystem /usr/lib64/dbus-1.0/include -isystem /usr/include/freetype2 -isystem /usr/include/libpng16 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D VCL_DLLIMPLEMENTATION -D DLLIMPLEMENTATION_UITEST -D CUI_DLL_NAME="libcuilo.so" -D DESKTOP_DETECTOR_DLL_NAME="libdesktop_detectorlo.so" -D TK_DLL_NAME="libtklo.so" -D SYSTEM_ZLIB -D GLM_FORCE_CTOR_INIT -D SK_USER_CONFIG_HEADER=</home/maarten/src/libreoffice/core/config_host/config_skia.h> -D SKIA_DLL -D ENABLE_CUPS -D HAVE_VALGRIND_HEADERS -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/epoxy/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/core -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/effects -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/gpu -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/config -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/ports -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/third_party/vulkan -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/tools/gpu -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia -I /home/maarten/src/libreoffice/core/external/skia/inc/ -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/mdds/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/lcms2/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/i18n -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/common -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/harfbuzz/src -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/graphite/include -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/pdfium -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/pdfium/public -D COMPONENT_BUILD -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/libpng -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/libjpeg-turbo -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/vcl/inc -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libxml2 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/vcl/source/fontsubset/ttcr.cxx
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
33namespace 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
45namespace {
46
47struct 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 */
56static 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
63static 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
70static 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
78static 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__))
;
18
'?' condition is true
21
'?' condition is true
24
'?' condition is true
27
'?' condition is true
81
82 ptr[offset] = static_cast<sal_uInt8>((val >> 8) & 0xFF);
83 ptr[offset+1] = static_cast<sal_uInt8>(val & 0xFF);
84}
85
86static 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__))
;
15
'?' condition is true
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
96static 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
103static 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
120static 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
130static void *smalloc(sal_uInt32 size)
131{
132 void *res = malloc(size);
10
Storing uninitialized value
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__))
;
11
Assuming the condition is true
12
'?' condition is true
134 return res;
135}
136
137static 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
148void 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
160void AddTable(TrueTypeCreator *_this, TrueTypeTable *table)
161{
162 if (table != nullptr) {
163 listAppend(_this->tables, table);
164 }
165}
166
167void 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
189static void ProcessTables(TrueTypeCreator *);
190
191SFErrCodes 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;
2
Assuming the condition is false
3
Taking false branch
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 {
4
Loop condition is false. Exiting loop
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 {
6
Loop condition is false. Exiting loop
218 searchRange *= 2;
219 entrySelector++;
220 } while (searchRange <= numTables);
5
Assuming 'searchRange' is > '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) {
7
Assuming 'i' is >= 'numTables'
8
Loop condition is false. Execution continues on line 233
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));
9
Calling 'smalloc'
13
Returning from 'smalloc'
234
235 /* Offset Table */
236 PutUInt32(_this->tag, ttf, 0);
14
Calling 'PutUInt32'
16
Returning from 'PutUInt32'
237 PutUInt16(numTables, ttf, 4);
17
Calling 'PutUInt16'
19
Returning from 'PutUInt16'
238 PutUInt16(searchRange, ttf, 6);
20
Calling 'PutUInt16'
22
Returning from 'PutUInt16'
239 PutUInt16(entrySelector, ttf, 8);
23
Calling 'PutUInt16'
25
Returning from 'PutUInt16'
240 PutUInt16(rangeShift, ttf, 10);
26
Calling 'PutUInt16'
28
Returning from 'PutUInt16'
241
242 /* Table Directory */
243 for (int i = 0; i
28.1
'i' is >= 'numTables'
< numTables; ++i) {
29
Loop condition is false. Execution continues on line 258
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];
30
Assuming the condition is true
31
Loop condition is true. Entering loop body
32
Assuming the condition is true
33
Loop condition is true. Entering loop body
34
Assuming the condition is true
35
Loop condition is true. Entering loop body
36
The value 3 is assigned to 'i'
37
Assuming the condition is true
38
Loop condition is true. Entering loop body
39
Assigned value is garbage or undefined
262 PutUInt32(0xB1B0AFBA - checkSumAdjustment, head, 8);
263
264 *ptr = ttf;
265 *length = s;
266
267 return SFErrCodes::Ok;
268}
269
270SFErrCodes 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;
1
Calling 'StreamToMemory'
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
317namespace {
318
319struct 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
327struct 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
333struct tdata_generic {
334 sal_uInt32 tag;
335 sal_uInt32 nbytes;
336 sal_uInt8 *ptr;
337};
338
339struct tdata_loca {
340 sal_uInt32 nbytes; /* number of bytes in loca table */
341 sal_uInt8 *ptr; /* pointer to the data */
342};
343
344struct 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 */
356static 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
367static void FreeGlyphData(void *ptr)
368{
369 GlyphData *p = static_cast<GlyphData *>(ptr);
370 if (p->ptr) free(p->ptr);
371 free(p);
372}
373
374static 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
386static void TrueTypeTableDispose_head(TrueTypeTable *_this)
387{
388 if (_this) {
389 if (_this->data) free(_this->data);
390 free(_this);
391 }
392}
393
394static void TrueTypeTableDispose_hhea(TrueTypeTable *_this)
395{
396 if (_this) {
397 if (_this->data) free(_this->data);
398 free(_this);
399 }
400}
401
402static 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
414static void TrueTypeTableDispose_maxp(TrueTypeTable *_this)
415{
416 if (_this) {
417 if (_this->data) free(_this->data);
418 free(_this);
419 }
420}
421
422static 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
430static 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
449static 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
457static 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
480struct {
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
497static 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
509static 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
518static 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
527static 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
544static 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
553static 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 */
591static 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
615static 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 */
642static 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
650static 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
700static 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
771static 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
806struct {
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
838TrueTypeTable *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
860TrueTypeTable *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
892TrueTypeTable *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
921TrueTypeTable *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
935TrueTypeTable *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
950TrueTypeTable *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
966TrueTypeTable *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
983static 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
992static 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
1006TrueTypeTable *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
1029TrueTypeTable *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
1053int 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
1078void 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
1144sal_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
1198sal_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
1205static 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 */
1235static 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
1431extern "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
1464static 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
1468int 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: */