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