source: svn/newcon3bcm2_21bu/dst/dmw/src/grp/jungle_font/utfEmbed.c

Last change on this file was 76, checked in by megakiss, 10 years ago

1W 대기전력을 만족시키기 위하여 POWEROFF시 튜너를 Standby 상태로 함

  • Property svn:executable set to *
File size: 23.8 KB
Line 
1#include "utfEmbed.h"
2
3/***************************************************************************/
4/* Data Types                                                              */
5/***************************************************************************/
6
7typedef struct UT_EMBED_GLYPH
8{
9        char                    isVolatile;
10        unsigned char   nComponent;
11        unsigned short  id;
12        signed short    width;
13        signed short    height;
14        short                   length;
15        UT_BBOX1                bbox;
16        struct UT_EMBED_GLYPH* next;
17} UT_EMBED_GLYPH;
18
19typedef struct UT_EMBED_CMAP
20{
21        char                    isVolatile;
22        UT_CMAP                 info;
23        int                             offset;
24        int                             nGlyph;
25        int                             nComponent;
26        UT_EMBED_GLYPH* headGlyph;
27        UT_EMBED_GLYPH* headComponent;
28        struct UT_EMBED_CMAP* next;
29} UT_EMBED_CMAP;
30
31typedef struct UT_EMBED_FONT
32{
33        char                    isVolatile;
34        UT_FONT_CAP             cap;
35        UT_EMBED_CMAP*  headCmap;
36        struct UT_EMBED_FONT* next;
37} UT_EMBED_FONT;
38
39typedef struct UT_EMBED_FILE
40{
41        void* handle;
42        int (*write)(void* handle, void* buffer, int length);
43        int offset;
44} UT_EMBED_FILE;
45
46/***************************************************************************/
47/* static API's                                                            */
48/***************************************************************************/
49
50static void* utm_EmbedAllocMemory(UT_EMBED_MAN* embedMan, int size)
51{
52        char* p;
53        if ((embedMan->staticBufferPointer+size) > embedMan->staticBufferSize)
54        {
55                if (!embedMan->AllocMemory) return 0;
56                p = (char*)embedMan->AllocMemory(size);
57                UT_MEMSET(p, 0, size);
58                p[0] = 1;
59        }
60        else
61        {
62                p = embedMan->staticBuffer + embedMan->staticBufferPointer;
63                embedMan->staticBufferPointer += size;
64                UT_MEMSET(p, 0, size);
65        }
66        return p;
67}
68
69static UT_EMBED_FONT* ut_EmbedFindFont(UT_EMBED_MAN* embedMan, UT_FC* fc)
70{
71        UT_EMBED_FONT* font = embedMan->headFont;
72        for (; font; font=font->next)
73        {
74                if (font->cap.info.id != fc->font.info.id) continue;
75                if (font->cap.info.limit != fc->font.info.limit) continue;
76                if (font->cap.info.weight != fc->font.info.weight) continue;
77                if (font->cap.info.isItalic != fc->font.info.isItalic) continue;
78                if (font->cap.info.xLimit != fc->font.info.xLimit) continue;
79                return font;
80        }
81        font = (UT_EMBED_FONT*)utm_EmbedAllocMemory(embedMan, sizeof(UT_EMBED_FONT));
82        if (!font) return 0;
83        font->next = embedMan->headFont;
84        embedMan->headFont = font;
85        UT_MEMCPY(&font->cap, &fc->font, sizeof(UT_FONT_CAP));
86        return font;
87}
88
89static UT_EMBED_CMAP* ut_EmbedFindCmap(UT_EMBED_MAN* embedMan, UT_EMBED_FONT* font, UT_CMAP* uCmap)
90{
91        UT_EMBED_CMAP* cmap = font->headCmap;
92        for (; cmap; cmap=cmap->next)
93        {
94                if (cmap->info.glyphType != uCmap->glyphType) continue;
95                if (cmap->info.glyphType < 0)
96                {
97                        if (cmap->info.depend.emSize != uCmap->depend.emSize) continue;
98                }
99                return cmap;
100        }
101        cmap = (UT_EMBED_CMAP*)utm_EmbedAllocMemory(embedMan, sizeof(UT_EMBED_CMAP));
102        if (!cmap) return 0;
103        cmap->next = font->headCmap;
104        font->headCmap = cmap;
105        cmap->info.glyphType = uCmap->glyphType;
106        cmap->info.isStroke = uCmap->isStroke;
107        cmap->info.startCode = 0xffff;
108        cmap->info.endCode = 0x0000;
109        cmap->info.widthFormat = _UT_METX_FIXED;
110        cmap->info.heightFormat = _UT_METX_FIXED;
111        cmap->info.locaFormat = _UT_LOCA_FIXED;
112        if (cmap->info.glyphType < 0)
113        {
114                cmap->info.depend.emSize = uCmap->depend.emSize;
115        }
116        else
117        {
118                cmap->info.glyphBBoxType = _UT_GLYPH_BBOX_1;
119        }
120        return cmap;
121}
122
123static UT_EMBED_GLYPH* ut_EmbedAddComponent(UT_EMBED_MAN* embedMan, UT_EMBED_CMAP* cmap, int index, UT_DATA* data)
124{
125        int size;
126        UT_EMBED_GLYPH* glyph = cmap->headComponent;
127        if (index >= 0)
128        {
129                for (; glyph; glyph=glyph->next)
130                {
131                        if (glyph->id == index)
132                        {
133                                return glyph;
134                        }
135                }
136        }
137        size = data->end.p - data->p.p;
138        glyph = (UT_EMBED_GLYPH*)utm_EmbedAllocMemory(embedMan, sizeof(UT_EMBED_GLYPH)+size);
139        if (!glyph) return _UT_FALSE;
140        glyph->next = cmap->headComponent;
141        cmap->headComponent = glyph;
142        UT_MEMCPY(glyph+1, data->p.p, size);
143        glyph->id = index;
144        glyph->width = 0;
145        glyph->height = 0;
146        glyph->bbox = data->bbox;
147        glyph->length = size;
148        cmap->nComponent++;
149        return glyph;
150}
151
152static UT_EMBED_GLYPH* ut_EmbedAddGlyph(UT_EMBED_MAN* embedMan, UT_EMBED_CMAP* cmap, UT_CODE code, int width, int height, UT_DATA* data, int length, UT_BOOL* isNew)
153{
154        UT_EMBED_GLYPH* prev = 0;
155        UT_EMBED_GLYPH* glyph = cmap->headGlyph;
156        if (isNew) *isNew = _UT_FALSE;
157        for (; glyph; glyph=glyph->next)
158        {
159                if (glyph->id == code)
160                {
161                        return glyph;
162                }
163                if (glyph->id > code)
164                {
165                        break;
166                }
167                prev = glyph;
168        }
169        if (isNew) *isNew = _UT_TRUE;
170        glyph = (UT_EMBED_GLYPH*)utm_EmbedAllocMemory(embedMan, sizeof(UT_EMBED_GLYPH)+length);
171        if (!glyph) return _UT_FALSE;
172        if (cmap->headGlyph)
173        {
174                if (prev)
175                {
176                        glyph->next = prev->next;
177                        prev->next = glyph;
178                }
179                else
180                {
181                        glyph->next = cmap->headGlyph;
182                        cmap->headGlyph = glyph;
183                }
184        }
185        else
186        {
187                cmap->headGlyph = glyph;
188        }
189        glyph->id = code;
190        glyph->width = width;
191        glyph->height = height;
192        if (data)
193        {
194                if (length)
195                {
196                        UT_MEMCPY(glyph+1, data->p.p, length);
197                        glyph->length = length;
198                }
199                glyph->bbox = data->bbox;
200        }
201        if (cmap->info.startCode > code) cmap->info.startCode = code;
202        if (cmap->info.endCode < code) cmap->info.endCode = code;
203        cmap->nGlyph++;
204        return glyph;
205}
206
207
208static UT_BOOL ut_write(UT_EMBED_FILE* file, void* buffer, int length)
209{
210        file->offset += length;
211        if (file->handle)
212        {
213                if (file->write(file->handle, buffer, length) != length) return _UT_FALSE;
214        }
215        return _UT_TRUE;
216}
217
218static UT_BOOL ut_align(UT_EMBED_FILE* file)
219{
220        int n = file->offset & 3;
221        char zero[] = {0, 0, 0, 0};
222        if (!n) return _UT_TRUE;
223        return ut_write(file, zero, 4-n);
224}
225
226static UT_BOOL ut_EmbedPutNum(UT_EMBED_FILE* file, int num)
227{
228    #define abs(v) ((v) < 0 ? -(v) : v)
229        UT_I8 i8;
230        UT_U8 u8;
231    if (abs(num) < 123)
232    {
233        u8 = num;                                               if (!ut_write(file, &u8, 1)) return _UT_FALSE;
234    }
235    else if (abs(num) <= 256*(128-123))
236    {
237        if (num > 0)
238        {
239            num -= 123;
240            i8 = (num >> 8) + 123;              if (!ut_write(file, &i8, 1)) return _UT_FALSE;
241            u8 = num & 255;                             if (!ut_write(file, &u8, 1)) return _UT_FALSE;
242        }
243        else
244        {
245            num = -num;
246            num -= 123;
247            i8 = -((num >> 8) + 123);   if (!ut_write(file, &i8, 1)) return _UT_FALSE;
248            u8 = num & 255;                             if (!ut_write(file, &u8, 1)) return _UT_FALSE;
249        }
250    }
251    else
252    {
253        i8 = -128;                                              if (!ut_write(file, &i8, 1)) return _UT_FALSE;
254        u8 = num >> 8;                                  if (!ut_write(file, &u8, 1)) return _UT_FALSE;
255        u8 = num & 0xff;                                if (!ut_write(file, &u8, 1)) return _UT_FALSE;
256    }
257        return _UT_TRUE;
258    #undef abs
259}
260
261static UT_BOOL ut_EmbedWriteComponentGlyph(UT_EMBED_FILE* file, UT_EMBED_GLYPH* glyph)
262{
263        if (glyph->nComponent)
264        {
265                int i;
266                UT_EMBED_GLYPH** component = (UT_EMBED_GLYPH**)(glyph + 1);
267                ut_EmbedPutNum(file, -1);
268                for (i=0; i<glyph->nComponent; i++)
269                {
270                        ut_EmbedPutNum(file, 1);
271                        ut_EmbedPutNum(file, component[i]->id);
272                }
273                ut_EmbedPutNum(file, 0);
274        }
275        else
276        {
277                if (!ut_write(file, glyph+1, glyph->length)) return _UT_FALSE;
278        }
279        return _UT_TRUE;
280}
281
282static UT_BOOL ut_EmbedWriteGlyph(UT_EMBED_FILE* file, UT_EMBED_GLYPH* glyph, UT_EMBED_CMAP* cmap)
283{
284        if (cmap->info.widthFormat == _UT_METX_VARIABLE_BYTE)
285        {
286                UT_I8 v = (UT_I8)glyph->width; if (!ut_write(file, &v, 1)) return _UT_FALSE;
287        }
288        else if (cmap->info.widthFormat == _UT_METX_VARIABLE_SHORT)
289        {
290                UT_I16 v = (UT_I16)glyph->width; v = ut_SWAP_I16(v); if (!ut_write(file, &v, 2)) return _UT_FALSE;
291        }
292
293        if (cmap->info.heightFormat == _UT_METX_VARIABLE_BYTE)
294        {
295                UT_I8 v = (UT_I8)glyph->height; if (!ut_write(file, &v, 1)) return _UT_FALSE;
296        }
297        else if (cmap->info.heightFormat == _UT_METX_VARIABLE_SHORT)
298        {
299                UT_I16 v = (UT_I16)glyph->height; v = ut_SWAP_I16(v); if (!ut_write(file, &v, 2)) return _UT_FALSE;
300        }
301
302        if (cmap->info.glyphBBoxType == _UT_GLYPH_BBOX_1)
303        {
304                if (!ut_write(file, &glyph->bbox.ox, 1)) return _UT_FALSE;
305                if (!ut_write(file, &glyph->bbox.oy, 1)) return _UT_FALSE;
306                if (!ut_write(file, &glyph->bbox.sx, 1)) return _UT_FALSE;
307                if (!ut_write(file, &glyph->bbox.sy, 1)) return _UT_FALSE;
308        }
309        else if (cmap->info.glyphBBoxType == _UT_GLYPH_BBOX_X)
310        {
311                if (!ut_write(file, &glyph->bbox.ox, 1)) return _UT_FALSE;
312                if (!ut_write(file, &glyph->bbox.sx, 1)) return _UT_FALSE;
313        }
314        else if (cmap->info.glyphBBoxType == _UT_GLYPH_BBOX_Y)
315        {
316                if (!ut_write(file, &glyph->bbox.oy, 1)) return _UT_FALSE;
317                if (!ut_write(file, &glyph->bbox.sy, 1)) return _UT_FALSE;
318        }
319
320        if (glyph->nComponent)
321        {
322                int i;
323                UT_EMBED_GLYPH** component = (UT_EMBED_GLYPH**)(glyph + 1);
324                ut_EmbedPutNum(file, -1);
325                for (i=0; i<glyph->nComponent; i++)
326                {
327                        ut_EmbedPutNum(file, 1);
328                        ut_EmbedPutNum(file, component[i]->id);
329                }
330                ut_EmbedPutNum(file, 0);
331        }
332        else
333        {
334                if (!ut_write(file, glyph+1, glyph->length)) return _UT_FALSE;
335        }
336
337        return _UT_TRUE;
338}
339
340static UT_BOOL ut_EmbedWriteLoca(UT_EMBED_FILE* file, UT_EMBED_CMAP* cmap, int offset)
341{
342        if (cmap->info.locaFormat == _UT_LOCA_SHORT)
343        {
344                UT_U16 v = (UT_U16)offset; v = ut_SWAP_U16(v); if (!ut_write(file, &v, 2)) return _UT_FALSE;
345        }
346        else if (cmap->info.locaFormat == _UT_LOCA_LONG)
347        {
348                UT_U32 v = (UT_U32)offset; v = ut_SWAP_U32(v); if (!ut_write(file, &v, 4)) return _UT_FALSE;
349        }
350        return _UT_TRUE;
351}
352
353static UT_BOOL ut_EmbedWriteLocaTable(UT_EMBED_FILE* file, UT_EMBED_CMAP* cmap)
354{
355        if (cmap->info.locaFormat != _UT_LOCA_FIXED)
356        {
357                UT_EMBED_FILE temp = {0, 0, 0};
358                UT_EMBED_GLYPH* glyph;
359                cmap->info.loca.offset = file->offset - cmap->offset;
360                glyph = cmap->headGlyph;
361                for (; glyph; glyph=glyph->next)
362                {
363                        if (!ut_EmbedWriteLoca(file, cmap, temp.offset)) return FALSE;
364                        if (!ut_EmbedWriteGlyph(&temp, glyph, cmap)) return FALSE;
365                }
366                glyph = cmap->headComponent;
367                for (; glyph; glyph=glyph->next)
368                {
369                        if (!ut_EmbedWriteLoca(file, cmap, temp.offset)) return FALSE;
370                        if (!ut_EmbedWriteGlyph(&temp, glyph, cmap)) return FALSE;
371                }
372                if (!ut_EmbedWriteLoca(file, cmap, temp.offset)) return FALSE;
373                if (!ut_align(file)) return _UT_FALSE;
374        }
375        return _UT_TRUE;
376}
377
378static UT_BOOL ut_EmbedWriteGlyphTable(UT_EMBED_FILE* file, UT_EMBED_CMAP* cmap)
379{
380        UT_EMBED_GLYPH* glyph;
381        cmap->info.glyfOffset = file->offset - cmap->offset;
382        glyph = cmap->headGlyph;
383        for (; glyph; glyph=glyph->next)
384        {
385                if (!ut_EmbedWriteGlyph(file, glyph, cmap)) return FALSE;
386        }
387        glyph = cmap->headComponent;
388        for (; glyph; glyph=glyph->next)
389        {
390                if (!ut_EmbedWriteGlyph(file, glyph, cmap)) return FALSE;
391        }
392        if (!ut_align(file)) return _UT_FALSE;
393        return _UT_TRUE;
394}
395
396static UT_BOOL ut_EmbedAnalyzeCmap(UT_EMBED_CMAP* cmap)
397{
398        int glyph_data_size = 0;
399        int max_width = cmap->headGlyph->width;
400        int max_height = cmap->headGlyph->height;
401
402        UT_CODE index = cmap->nGlyph;
403        UT_EMBED_GLYPH* glyph;
404        glyph = cmap->headComponent;
405        for (; glyph; glyph=glyph->next)
406        {
407                glyph->id = index++;
408        }
409        glyph = cmap->headGlyph;
410        for (; glyph; glyph=glyph->next)
411        {
412                UT_EMBED_FILE file = {0, 0, 0};
413                ut_EmbedWriteComponentGlyph(&file, glyph);
414                glyph->length = file.offset;
415                glyph_data_size += glyph->length;
416        }
417        glyph = cmap->headComponent;
418        for (; glyph; glyph=glyph->next)
419        {
420                UT_EMBED_FILE file = {0, 0, 0};
421                ut_EmbedWriteGlyph(&file, glyph, cmap);
422                glyph->length = file.offset;
423                glyph_data_size += glyph->length;
424        }
425
426        cmap->info.widthFormat = _UT_METX_FIXED;
427        cmap->info.widthFormat = _UT_METX_FIXED;
428        glyph = cmap->headGlyph;
429        for (; glyph; glyph=glyph->next)
430        {
431                if (max_width != glyph->width)
432                {
433                        if (abs(max_width) < abs(glyph->width))
434                        {
435                                max_width = glyph->width;
436                                if (abs(max_width) < 128) cmap->info.widthFormat = _UT_METX_VARIABLE_BYTE;
437                                else                      cmap->info.widthFormat = _UT_METX_VARIABLE_SHORT;
438                        }
439                }
440                if (max_height != glyph->height)
441                {
442                        if (abs(max_height) < abs(glyph->height))
443                        {
444                                max_height = glyph->height;
445                                if (abs(max_height) < 128) cmap->info.heightFormat = _UT_METX_VARIABLE_BYTE;
446                                else                       cmap->info.heightFormat = _UT_METX_VARIABLE_SHORT;
447                        }
448                }
449        }
450
451        if (glyph_data_size < 0x10000) cmap->info.locaFormat = _UT_LOCA_SHORT;
452        else                           cmap->info.locaFormat = _UT_LOCA_LONG;
453        cmap->info.cmapFormat = _UT_CMAP_SPARSE;
454
455        return _UT_TRUE;
456}
457
458static UT_BOOL ut_EmbedWriteCmap(UT_EMBED_FILE* file, UT_EMBED_CMAP* cmap)
459{
460        UT_U16 v;
461        UT_EMBED_GLYPH* glyph;
462        UT_CMAP t = cmap->info;
463        if (file->handle)
464        {
465                t.startCode     = ut_SWAP_U16(t.startCode    );
466                t.endCode       = ut_SWAP_U16(t.endCode      );
467                t.length        = ut_SWAP_U32(t.length       );
468                t.moreOffset    = ut_SWAP_U32(t.moreOffset   );
469                t.glyfOffset    = ut_SWAP_U32(t.glyfOffset   );
470                if (t.locaFormat   == _UT_LOCA_FIXED) t.loca.fixed    = ut_SWAP_U16(t.loca.fixed   );
471                else                                  t.loca.offset   = ut_SWAP_U32(t.loca.offset  );
472                if (t.widthFormat  == _UT_METX_FIXED) t.width.fixed   = ut_SWAP_U16(t.width.fixed  );
473                else                                  t.width.offset  = ut_SWAP_U32(t.width.offset );
474                if (t.heightFormat == _UT_METX_FIXED) t.height.fixed  = ut_SWAP_U16(t.height.fixed );
475        }
476        cmap->offset = file->offset;
477        ut_write(file, &t, sizeof(t));
478        v = (UT_U16)cmap->nGlyph; v = ut_SWAP_U16(v); if (!ut_write(file, &v, 2)) return _UT_FALSE;
479        glyph = cmap->headGlyph;
480        for (; glyph; glyph=glyph->next)
481        {
482                v = (UT_U16)glyph->id; v = ut_SWAP_U16(v); if (!ut_write(file, &v, 2)) return _UT_FALSE;
483        }
484        if (!ut_EmbedWriteLocaTable(file, cmap)) return _UT_FALSE;
485        cmap->info.length = file->offset - cmap->offset;
486        return _UT_TRUE;
487}
488
489static UT_BOOL ut_EmbedWriteFontHeader(UT_EMBED_FILE* file, UT_FONT* font)
490{
491        UT_FONT t = *font;
492        if (file->handle)
493        {
494                t.identifier = ut_SWAP_U32(t.identifier);
495                t.fileSize   = ut_SWAP_U32(t.fileSize  );
496                t.id         = ut_SWAP_U32(t.id        );
497                t.limit      = ut_SWAP_U16(t.limit     );
498                t.maxPath    = ut_SWAP_U16(t.maxPath   );
499                t.maxPoint   = ut_SWAP_U16(t.maxPoint  );
500                t.xLimit     = ut_SWAP_U16(t.xLimit    );
501                t.moreOffset = ut_SWAP_U32(t.moreOffset);
502        }
503        return ut_write(file, &t, sizeof(t));
504}
505
506static UT_BOOL ut_EmbedWriteFontMoreInfo(UT_EMBED_FILE* file, UT_FONT_CAP* font)
507{
508        UT_U8 ll, u8;
509
510        u8 = _UT_FONT_MORE_OP_VERSION; if (!ut_write(file, &u8, 1)) return _UT_FALSE;
511        u8 = _UT_VERSION_MAJOR; if (!ut_write(file, &u8, 1)) return _UT_FALSE;
512        u8 = _UT_VERSION_MINOR; if (!ut_write(file, &u8, 1)) return _UT_FALSE;
513
514        u8 = _UT_FONT_MORE_OP_CMAP_LENGTH; if (!ut_write(file, &u8, 1)) return _UT_FALSE;
515        u8 = font->cmapLength >> 24; if (!ut_write(file, &u8, 1)) return _UT_FALSE;
516        u8 = font->cmapLength >> 16; if (!ut_write(file, &u8, 1)) return _UT_FALSE;
517        u8 = font->cmapLength >>  8; if (!ut_write(file, &u8, 1)) return _UT_FALSE;
518        u8 = font->cmapLength & 255; if (!ut_write(file, &u8, 1)) return _UT_FALSE;
519
520        u8 = _UT_FONT_MORE_OP_MAX_GLYPH_LENGTH; if (!ut_write(file, &u8, 1)) return _UT_FALSE;
521        u8 = font->maxGlyphLength >> 8;  if (!ut_write(file, &u8, 1)) return _UT_FALSE;
522        u8 = font->maxGlyphLength & 255; if (!ut_write(file, &u8, 1)) return _UT_FALSE;
523
524        u8 = _UT_FONT_MORE_OP_MAX_TWILIGHT_POINT; if (!ut_write(file, &u8, 1)) return _UT_FALSE;
525        u8 = font->maxTwilighitPoint >> 8;  if (!ut_write(file, &u8, 1)) return _UT_FALSE;
526        u8 = font->maxTwilighitPoint & 255; if (!ut_write(file, &u8, 1)) return _UT_FALSE;
527
528        u8 = _UT_FONT_MORE_OP_MAX_STACK; if (!ut_write(file, &u8, 1)) return _UT_FALSE;
529        u8 = font->maxStack >> 8;  if (!ut_write(file, &u8, 1)) return _UT_FALSE;
530        u8 = font->maxStack & 255; if (!ut_write(file, &u8, 1)) return _UT_FALSE;
531
532        u8 = _UT_FONT_MORE_OP_MAX_STORAGE; if (!ut_write(file, &u8, 1)) return _UT_FALSE;
533        u8 = font->maxStorage >> 8;  if (!ut_write(file, &u8, 1)) return _UT_FALSE;
534        u8 = font->maxStorage & 255; if (!ut_write(file, &u8, 1)) return _UT_FALSE;
535
536        u8 = _UT_FONT_MORE_OP_MAX_CVT; if (!ut_write(file, &u8, 1)) return _UT_FALSE;
537        u8 = font->maxCvt >> 8;  if (!ut_write(file, &u8, 1)) return _UT_FALSE;
538        u8 = font->maxCvt & 255; if (!ut_write(file, &u8, 1)) return _UT_FALSE;
539
540        u8 = _UT_FONT_MORE_OP_MAX_FUNCTION; if (!ut_write(file, &u8, 1)) return _UT_FALSE;
541        u8 = font->maxFunction >> 8;  if (!ut_write(file, &u8, 1)) return _UT_FALSE;
542        u8 = font->maxFunction & 255; if (!ut_write(file, &u8, 1)) return _UT_FALSE;
543
544        u8 = _UT_FONT_MORE_OP_MAX_INSTRUCTION; if (!ut_write(file, &u8, 1)) return _UT_FALSE;
545        u8 = font->maxInstruction >> 8;  if (!ut_write(file, &u8, 1)) return _UT_FALSE;
546        u8 = font->maxInstruction & 255; if (!ut_write(file, &u8, 1)) return _UT_FALSE;
547
548        if (font->typefaceName[0])
549        {
550                UT_CODE* p = font->typefaceName;
551                u8 = _UT_FONT_MORE_OP_TYPEFACE_NAME; if (!ut_write(file, &u8, 1)) return _UT_FALSE;
552                ll = 0; while((ll<32) && p[ll]) ll++; if (!ut_write(file, &ll, 1)) return _UT_FALSE;
553                for (; ll; ll--,p++)
554                {
555                        u8 = *p >> 8;  if (!ut_write(file, &u8, 1)) return _UT_FALSE;
556                        u8 = *p & 255; if (!ut_write(file, &u8, 1)) return _UT_FALSE;
557                }
558        }
559
560        if (font->fontName[0])
561        {
562                UT_CODE* p = font->fontName;
563                u8 = _UT_FONT_MORE_OP_FONT_NAME; if (!ut_write(file, &u8, 1)) return _UT_FALSE;
564                ll = 0; while((ll<32) && p[ll]) ll++; if (!ut_write(file, &ll, 1)) return _UT_FALSE;
565                for (; ll; ll--,p++)
566                {
567                        u8 = *p >> 8;  if (!ut_write(file, &u8, 1)) return _UT_FALSE;
568                        u8 = *p & 255; if (!ut_write(file, &u8, 1)) return _UT_FALSE;
569                }
570        }
571
572        if (font->ascent)
573        {
574                u8 = _UT_FONT_MORE_OP_ASCENT; if (!ut_write(file, &u8, 1)) return _UT_FALSE;
575                u8 = font->ascent >> 8;  if (!ut_write(file, &u8, 1)) return _UT_FALSE;
576                u8 = font->ascent & 255; if (!ut_write(file, &u8, 1)) return _UT_FALSE;
577        }
578
579        if (font->descent)
580        {
581                u8 = _UT_FONT_MORE_OP_DESCENT; if (!ut_write(file, &u8, 1)) return _UT_FALSE;
582                u8 = font->descent >> 8;  if (!ut_write(file, &u8, 1)) return _UT_FALSE;
583                u8 = font->descent & 255; if (!ut_write(file, &u8, 1)) return _UT_FALSE;
584        }
585
586        u8 = _UT_END; if (!ut_write(file, &u8, 1)) return _UT_FALSE;
587
588        if (!ut_align(file)) return _UT_FALSE;;
589
590        return _UT_TRUE;
591}
592
593static UT_BOOL ut_EmbedWriteFont(UT_EMBED_FILE* file, UT_EMBED_FONT* font)
594{
595        UT_U32 end = -1;
596        int file_offset;
597        int cmap_offset;
598        UT_EMBED_CMAP* cmap;
599
600        file_offset = file->offset;
601        if (!ut_EmbedWriteFontHeader(file, &font->cap.info)) return _UT_FALSE;
602
603        cmap_offset = file->offset;
604        cmap = font->headCmap;
605        for (; cmap; cmap=cmap->next)
606        {
607                if (!ut_EmbedWriteCmap(file, cmap)) return _UT_FALSE;
608        }
609        if (!ut_write(file, &end, 4)) return _UT_FALSE;
610        font->cap.cmapLength = file->offset - cmap_offset;
611
612        cmap = font->headCmap;
613        for (; cmap; cmap=cmap->next)
614        {
615                if (!ut_EmbedWriteGlyphTable(file, cmap)) return _UT_FALSE;
616        }
617
618        font->cap.info.moreOffset = file->offset - file_offset;
619        if (!ut_EmbedWriteFontMoreInfo(file, &font->cap)) return _UT_FALSE;
620        font->cap.info.fileSize = file->offset - file_offset;
621
622        return _UT_TRUE;
623}
624
625static UT_BOOL ut_EmbedLayoutFont(UT_EMBED_FONT* font)
626{
627        UT_EMBED_FILE file = {0, 0, 0};
628        UT_EMBED_CMAP* cmap = font->headCmap;
629        for (; cmap; cmap=cmap->next)
630        {
631                if (!ut_EmbedAnalyzeCmap(cmap)) return _UT_FALSE;
632        }
633        if (!ut_EmbedWriteFont(&file, font)) return _UT_FALSE;
634        return _UT_TRUE;
635}
636
637/***************************************************************************/
638/* Global API's                                                            */
639/***************************************************************************/
640
641void utm_EmbedInit(UT_EMBED_MAN* embedMan,
642                                   void* (*AllocMemory)(unsigned int), void (*FreeMemory)(void*),
643                                   void* staticBuffer, int staticBufferSize)
644{
645        UT_MEMSET(embedMan, 0, sizeof(UT_EMBED_MAN));
646        embedMan->AllocMemory = AllocMemory;
647        embedMan->FreeMemory = FreeMemory;
648        embedMan->staticBuffer = (char*)staticBuffer;
649        embedMan->staticBufferSize = staticBufferSize;
650}
651
652void utm_EmbedTerm(UT_EMBED_MAN* embedMan)
653{
654        if (embedMan->FreeMemory)
655        {
656                UT_EMBED_FONT* font = embedMan->headFont;
657                while (font)
658                {
659                        UT_EMBED_FONT* next_font = font->next;
660                        UT_EMBED_CMAP* cmap = font->headCmap;
661                        while (cmap)
662                        {
663                                UT_EMBED_CMAP* next_cmap = cmap->next;
664                                UT_EMBED_GLYPH* glyph = cmap->headGlyph;
665                                int i;
666                                for (i=2; i; i--)
667                                {
668                                        while (glyph)
669                                        {
670                                                UT_EMBED_GLYPH* next_glyph = glyph->next;
671                                                if (glyph->isVolatile) embedMan->FreeMemory(glyph);
672                                                glyph = next_glyph;
673                                        }
674                                        glyph = cmap->headComponent;
675                                }
676                                if (cmap->isVolatile) embedMan->FreeMemory(cmap);
677                                cmap = next_cmap;
678                        }
679                        if (font->isVolatile) embedMan->FreeMemory(font);
680                        font = next_font;
681                }
682        }
683        embedMan->headFont = 0;
684        embedMan->staticBufferPointer = 0;
685}
686
687UT_BOOL utm_EmbedAddChar(UT_EMBED_MAN* embedMan, UT_FC* fc, UT_CODE code)
688{
689        UT_GLYPH* glyph = fc->task->glyph;
690        if (utm_GetGlyph(fc, code, glyph))
691        {
692                UT_EMBED_CMAP* cmap;
693                UT_EMBED_FONT* font = ut_EmbedFindFont(embedMan, fc);
694                if (!font) return _UT_FALSE;
695                cmap = ut_EmbedFindCmap(embedMan, font, glyph->cmap);
696                if (!cmap) return _UT_FALSE;
697                if (glyph->count == 0)
698                {
699                        if (!ut_EmbedAddGlyph(embedMan, cmap, code, glyph->width, glyph->height, 0, 0, 0)) return _UT_FALSE;
700                        return _UT_TRUE;
701                }
702                if (glyph->count == 1)
703                {
704                        if (!ut_EmbedAddGlyph(embedMan, cmap, code, glyph->width, glyph->height, glyph->data, glyph->data->end.p-glyph->data->p.p, 0)) return _UT_FALSE;
705                        return _UT_TRUE;
706                }
707                if (glyph->cmap->glyphType < 0)
708                {
709                        int i;
710                        UT_BOOL isNew;
711                        UT_EMBED_GLYPH** component;
712                        UT_EMBED_GLYPH* simple = ut_EmbedAddGlyph(embedMan, cmap, code, glyph->width, glyph->height, 0, sizeof(void*)*font->cap.info.maxDepth, &isNew);
713                        if (!simple) return _UT_FALSE;
714                        if (!isNew) return _UT_TRUE;
715                        component = (UT_EMBED_GLYPH**)(simple + 1);
716                        for (i=glyph->count-1; i>=0; i--)
717                        {
718                                UT_POINTER w = glyph->data[i].p;
719                                int nPoint = ut_DecryptNum(&w);
720                                if (nPoint < 0)
721                                {
722                                        for (;;)
723                                        {
724                                                UT_U8 flag = *w.u8++;
725                                                if (flag)
726                                                {
727                                                        int index = ut_DecryptNum(&w);
728                                                        if (ut_GetIndexedGlyph(fc->task->fontManager, glyph->stream, glyph->cmap, index, glyph))
729                                                        {
730                                                                component[i] = ut_EmbedAddComponent(embedMan, cmap, index, &glyph->data[i+1]);
731                                                                simple->nComponent++;
732                                                                if (!component[i]) return _UT_FALSE;
733                                                        }
734                                                }
735                                                else break;
736                                        }
737                                }
738                                else
739                                {
740                                        component[i] = ut_EmbedAddComponent(embedMan, cmap, -1, &glyph->data[i]);
741                                        simple->nComponent++;
742                                        if (!component[i]) return _UT_FALSE;
743                                }
744                        }
745                }
746                else
747                {
748                        UT_IMAGE image;
749                        UT_FONT_TASK* task = fc->task;
750                        UT_FC local = *fc;
751                        task->emulItalic = 0;
752                        task->emulBold   = 0;
753#ifdef _UT_USE_BITMAP_EFFECT
754                        task->emulEdge   = 0;
755                        task->emulSmooth = 0;
756                        task->emulOutline = 0;
757#endif
758                        local.rasterType = _UT_RASTER_TYPE_BITMAP;
759                        local.bitmapScaleType = 0;
760                        local.isFixedPitch = 0;
761                        ut_PrepareRasterGlyphBitmap(&local, &image);
762                        utm_MakeImageOfBitmapFont(&local, &image);
763                        glyph->data->p.u8 = image.data;
764                        glyph->data->end.p = glyph->data->p.p + image.lSize;
765                        glyph->data->bbox.ox = (UT_I8)image.bbox.ox;
766                        glyph->data->bbox.oy = (UT_I8)image.bbox.oy;
767                        glyph->data->bbox.sx = (UT_U8)image.bbox.sx;
768                        glyph->data->bbox.sy = (UT_U8)image.bbox.sy;
769                        if (!ut_EmbedAddGlyph(embedMan, cmap, code, glyph->width, glyph->height, glyph->data, glyph->data->end.p-glyph->data->p.p, 0)) return _UT_FALSE;
770                }
771        }
772        return _UT_TRUE;
773}
774
775UT_BOOL utm_EmbedWrite(UT_EMBED_MAN* embedMan,
776                                           void* handle, int (*write)(void*,void*,int))
777{
778        UT_U32 end = -1;
779        UT_EMBED_FILE file = {handle, write, 0};
780        UT_EMBED_FONT* font = embedMan->headFont;
781        for (; font; font=font->next)
782        {
783                if (!ut_EmbedLayoutFont(font)) return _UT_FALSE;
784                if (!ut_EmbedWriteFont(&file, font)) return _UT_FALSE;
785        }
786        if (!ut_write(&file, &end, 4)) return _UT_FALSE;
787        return _UT_TRUE;
788}
789
790/***************************************************************************/
Note: See TracBrowser for help on using the repository browser.