hpdf 2.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. data/History +57 -0
  2. data/License +25 -0
  3. data/README +165 -0
  4. data/examples/arc_demo.rb +82 -0
  5. data/examples/demo.rb +92 -0
  6. data/examples/encryption.rb +41 -0
  7. data/examples/ext_gstater_demo.rb +171 -0
  8. data/examples/font_demo.rb +67 -0
  9. data/examples/jpfont_demo.rb +122 -0
  10. data/examples/line_demo.rb +301 -0
  11. data/examples/slide_show_demo.rb +139 -0
  12. data/examples/text_demo2.rb +189 -0
  13. data/examples/ttfont_demo.rb +106 -0
  14. data/ext/extconf.rb +6 -0
  15. data/ext/hpdf.c +3779 -0
  16. data/ext/hpdf_annotation.c +415 -0
  17. data/ext/hpdf_array.c +344 -0
  18. data/ext/hpdf_binary.c +117 -0
  19. data/ext/hpdf_boolean.c +47 -0
  20. data/ext/hpdf_catalog.c +354 -0
  21. data/ext/hpdf_destination.c +339 -0
  22. data/ext/hpdf_dict.c +488 -0
  23. data/ext/hpdf_doc.c +2020 -0
  24. data/ext/hpdf_doc_png.c +137 -0
  25. data/ext/hpdf_encoder.c +2991 -0
  26. data/ext/hpdf_encoder_cns.c +36359 -0
  27. data/ext/hpdf_encoder_cnt.c +15307 -0
  28. data/ext/hpdf_encoder_jp.c +16125 -0
  29. data/ext/hpdf_encoder_kr.c +27978 -0
  30. data/ext/hpdf_encrypt.c +632 -0
  31. data/ext/hpdf_encryptdict.c +240 -0
  32. data/ext/hpdf_error.c +114 -0
  33. data/ext/hpdf_ext_gstate.c +150 -0
  34. data/ext/hpdf_font.c +229 -0
  35. data/ext/hpdf_font_cid.c +1030 -0
  36. data/ext/hpdf_font_tt.c +406 -0
  37. data/ext/hpdf_font_type1.c +391 -0
  38. data/ext/hpdf_fontdef.c +56 -0
  39. data/ext/hpdf_fontdef_base14.c +4506 -0
  40. data/ext/hpdf_fontdef_cid.c +194 -0
  41. data/ext/hpdf_fontdef_cns.c +471 -0
  42. data/ext/hpdf_fontdef_cnt.c +250 -0
  43. data/ext/hpdf_fontdef_jp.c +1904 -0
  44. data/ext/hpdf_fontdef_kr.c +1572 -0
  45. data/ext/hpdf_fontdef_tt.c +2230 -0
  46. data/ext/hpdf_fontdef_type1.c +524 -0
  47. data/ext/hpdf_gstate.c +119 -0
  48. data/ext/hpdf_image.c +568 -0
  49. data/ext/hpdf_image_png.c +424 -0
  50. data/ext/hpdf_info.c +164 -0
  51. data/ext/hpdf_list.c +333 -0
  52. data/ext/hpdf_mmgr.c +243 -0
  53. data/ext/hpdf_name.c +71 -0
  54. data/ext/hpdf_null.c +31 -0
  55. data/ext/hpdf_number.c +49 -0
  56. data/ext/hpdf_objects.c +172 -0
  57. data/ext/hpdf_outline.c +329 -0
  58. data/ext/hpdf_page_label.c +74 -0
  59. data/ext/hpdf_page_operator.c +2764 -0
  60. data/ext/hpdf_pages.c +1508 -0
  61. data/ext/hpdf_real.c +61 -0
  62. data/ext/hpdf_streams.c +1435 -0
  63. data/ext/hpdf_string.c +189 -0
  64. data/ext/hpdf_utils.c +438 -0
  65. data/ext/hpdf_xref.c +348 -0
  66. data/ext/include/hpdf.h +1227 -0
  67. data/ext/include/hpdf_annotation.h +74 -0
  68. data/ext/include/hpdf_catalog.h +81 -0
  69. data/ext/include/hpdf_conf.h +76 -0
  70. data/ext/include/hpdf_consts.h +549 -0
  71. data/ext/include/hpdf_destination.h +41 -0
  72. data/ext/include/hpdf_doc.h +159 -0
  73. data/ext/include/hpdf_encoder.h +311 -0
  74. data/ext/include/hpdf_encrypt.h +156 -0
  75. data/ext/include/hpdf_encryptdict.h +66 -0
  76. data/ext/include/hpdf_error.h +201 -0
  77. data/ext/include/hpdf_ext_gstate.h +38 -0
  78. data/ext/include/hpdf_font.h +112 -0
  79. data/ext/include/hpdf_fontdef.h +403 -0
  80. data/ext/include/hpdf_gstate.h +80 -0
  81. data/ext/include/hpdf_image.h +72 -0
  82. data/ext/include/hpdf_info.h +48 -0
  83. data/ext/include/hpdf_list.h +85 -0
  84. data/ext/include/hpdf_mmgr.h +82 -0
  85. data/ext/include/hpdf_objects.h +587 -0
  86. data/ext/include/hpdf_outline.h +74 -0
  87. data/ext/include/hpdf_page_label.h +35 -0
  88. data/ext/include/hpdf_pages.h +128 -0
  89. data/ext/include/hpdf_streams.h +276 -0
  90. data/ext/include/hpdf_types.h +488 -0
  91. data/ext/include/hpdf_utils.h +161 -0
  92. data/tests/arc_demo.rb +82 -0
  93. data/tests/demo.rb +91 -0
  94. data/tests/encryption.rb +41 -0
  95. data/tests/ext_gstater_demo.rb +171 -0
  96. data/tests/font_demo.rb +67 -0
  97. data/tests/line_demo.rb +301 -0
  98. data/tests/slide_show_demo.rb +139 -0
  99. data/tests/test_all_examples.rb +31 -0
  100. data/tests/text_demo2.rb +189 -0
  101. metadata +147 -0
@@ -0,0 +1,2230 @@
1
+ /*
2
+ * << Haru Free PDF Library 2.0.4 >> -- hpdf_fontdef_tt.c
3
+ *
4
+ * Copyright (c) 1999-2006 Takeshi Kanno <takeshi_kanno@est.hi-ho.ne.jp>
5
+ *
6
+ * Permission to use, copy, modify, distribute and sell this software
7
+ * and its documentation for any purpose is hereby granted without fee,
8
+ * provided that the above copyright notice appear in all copies and
9
+ * that both that copyright notice and this permission notice appear
10
+ * in supporting documentation.
11
+ * It is provided "as is" without express or implied warranty.
12
+ *
13
+ * 2006.08.24 fixed for composite glyph description.
14
+ */
15
+
16
+ #include "hpdf_conf.h"
17
+ #include "hpdf_utils.h"
18
+ #include "hpdf_fontdef.h"
19
+
20
+
21
+ #define HPDF_TTF_MAX_MEM_SIZ 10000
22
+
23
+ #define HPDF_REQUIRED_TAGS_COUNT 13
24
+
25
+ static const char *REQUIRED_TAGS[HPDF_REQUIRED_TAGS_COUNT] = {
26
+ "OS/2",
27
+ "cmap",
28
+ "cvt ",
29
+ "fpgm",
30
+ "glyf",
31
+ "head",
32
+ "hhea",
33
+ "hmtx",
34
+ "loca",
35
+ "maxp",
36
+ "name",
37
+ "post",
38
+ "prep"
39
+ };
40
+
41
+
42
+ static void
43
+ FreeFunc (HPDF_FontDef fontdef);
44
+
45
+
46
+ static HPDF_STATUS
47
+ LoadFontData (HPDF_FontDef fontdef,
48
+ HPDF_Stream stream,
49
+ HPDF_BOOL embedding,
50
+ HPDF_UINT offset);
51
+
52
+
53
+ static HPDF_STATUS
54
+ LoadFontData2 (HPDF_FontDef fontdef,
55
+ HPDF_Stream stream,
56
+ HPDF_UINT index,
57
+ HPDF_BOOL embedding);
58
+
59
+
60
+ static void
61
+ InitAttr (HPDF_FontDef fontdef);
62
+
63
+
64
+ static HPDF_STATUS
65
+ GetUINT32 (HPDF_Stream stream,
66
+ HPDF_UINT32 *value);
67
+
68
+
69
+ static HPDF_STATUS
70
+ GetUINT16 (HPDF_Stream stream,
71
+ HPDF_UINT16 *value);
72
+
73
+
74
+ static HPDF_STATUS
75
+ GetINT16 (HPDF_Stream stream,
76
+ HPDF_INT16 *value);
77
+
78
+
79
+ static HPDF_STATUS
80
+ WriteUINT32 (HPDF_Stream stream,
81
+ HPDF_UINT32 value);
82
+
83
+
84
+ static HPDF_STATUS
85
+ WriteUINT16 (HPDF_Stream stream,
86
+ HPDF_UINT16 value);
87
+
88
+
89
+ static HPDF_STATUS
90
+ WriteINT16 (HPDF_Stream stream,
91
+ HPDF_INT16 value);
92
+
93
+
94
+ static void
95
+ UINT32Swap (HPDF_UINT32 *value);
96
+
97
+
98
+ static void
99
+ UINT16Swap (HPDF_UINT16 *value);
100
+
101
+
102
+ static void
103
+ INT16Swap (HPDF_INT16 *value);
104
+
105
+
106
+ static HPDF_STATUS
107
+ LoadTTFTable (HPDF_FontDef fontdef);
108
+
109
+
110
+ static HPDF_STATUS
111
+ ParseHead (HPDF_FontDef fontdef);
112
+
113
+
114
+ static HPDF_STATUS
115
+ ParseMaxp (HPDF_FontDef fontdef);
116
+
117
+
118
+ static HPDF_STATUS
119
+ ParseHhea (HPDF_FontDef fontdef);
120
+
121
+
122
+ static HPDF_STATUS
123
+ ParseCMap (HPDF_FontDef fontdef);
124
+
125
+
126
+ static HPDF_STATUS
127
+ ParseCMAP_format0 (HPDF_FontDef fontdef,
128
+ HPDF_UINT32 offset);
129
+
130
+
131
+ static HPDF_STATUS
132
+ ParseCMAP_format4 (HPDF_FontDef fontdef,
133
+ HPDF_UINT32 offset);
134
+
135
+
136
+ static HPDF_STATUS
137
+ ParseHmtx (HPDF_FontDef fontdef);
138
+
139
+
140
+ static HPDF_STATUS
141
+ ParseLoca (HPDF_FontDef fontdef);
142
+
143
+
144
+ static HPDF_STATUS
145
+ LoadUnicodeName (HPDF_Stream stream,
146
+ HPDF_UINT offset,
147
+ HPDF_UINT len,
148
+ char *buf);
149
+
150
+ static HPDF_STATUS
151
+ ParseName (HPDF_FontDef fontdef);
152
+
153
+
154
+ static HPDF_STATUS
155
+ ParseOS2 (HPDF_FontDef fontdef);
156
+
157
+
158
+ static HPDF_TTFTable*
159
+ FindTable (HPDF_FontDef fontdef,
160
+ const char *tag);
161
+
162
+
163
+ static void
164
+ CleanFunc (HPDF_FontDef fontdef);
165
+
166
+
167
+ static HPDF_STATUS
168
+ CheckCompositGryph (HPDF_FontDef fontdef,
169
+ HPDF_UINT16 gid);
170
+
171
+
172
+ /*---------------------------------------------------------------------------*/
173
+ /*---------------------------------------------------------------------------*/
174
+
175
+ static void
176
+ FreeFunc (HPDF_FontDef fontdef)
177
+ {
178
+ HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
179
+
180
+ HPDF_PTRACE ((" HPDF_TTFontDef_FreeFunc\n"));
181
+
182
+ if (attr) {
183
+ InitAttr (fontdef);
184
+
185
+ HPDF_FreeMem (fontdef->mmgr, attr);
186
+ }
187
+ }
188
+
189
+
190
+ static void
191
+ CleanFunc (HPDF_FontDef fontdef)
192
+ {
193
+ HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
194
+ HPDF_MemSet (attr->glyph_tbl.flgs, 0,
195
+ sizeof (HPDF_BYTE) * attr->num_glyphs);
196
+ attr->glyph_tbl.flgs[0] = 1;
197
+ }
198
+
199
+
200
+ static void
201
+ InitAttr (HPDF_FontDef fontdef)
202
+ {
203
+ HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
204
+
205
+ if (attr) {
206
+ if (attr->char_set)
207
+ HPDF_FreeMem (fontdef->mmgr, attr->char_set);
208
+
209
+ if (attr->h_metric)
210
+ HPDF_FreeMem (fontdef->mmgr, attr->h_metric);
211
+
212
+ if (attr->name_tbl.name_records)
213
+ HPDF_FreeMem (fontdef->mmgr, attr->name_tbl.name_records);
214
+
215
+ if (attr->cmap.end_count)
216
+ HPDF_FreeMem (fontdef->mmgr, attr->cmap.end_count);
217
+
218
+ if (attr->cmap.start_count)
219
+ HPDF_FreeMem (fontdef->mmgr, attr->cmap.start_count);
220
+
221
+ if (attr->cmap.id_delta)
222
+ HPDF_FreeMem (fontdef->mmgr, attr->cmap.id_delta);
223
+
224
+ if (attr->cmap.id_range_offset)
225
+ HPDF_FreeMem (fontdef->mmgr, attr->cmap.id_range_offset);
226
+
227
+ if (attr->cmap.glyph_id_array)
228
+ HPDF_FreeMem (fontdef->mmgr, attr->cmap.glyph_id_array);
229
+
230
+ if (attr->offset_tbl.table)
231
+ HPDF_FreeMem (fontdef->mmgr, attr->offset_tbl.table);
232
+
233
+ if (attr->glyph_tbl.flgs)
234
+ HPDF_FreeMem (fontdef->mmgr, attr->glyph_tbl.flgs);
235
+
236
+ if (attr->glyph_tbl.offsets)
237
+ HPDF_FreeMem (fontdef->mmgr, attr->glyph_tbl.offsets);
238
+
239
+ if (attr->stream)
240
+ HPDF_Stream_Free (attr->stream);
241
+ }
242
+ }
243
+
244
+
245
+ HPDF_FontDef
246
+ HPDF_TTFontDef_New (HPDF_MMgr mmgr)
247
+ {
248
+ HPDF_FontDef fontdef;
249
+ HPDF_TTFontDefAttr fontdef_attr;
250
+
251
+ HPDF_PTRACE ((" HPDF_TTFontDef_New\n"));
252
+
253
+ if (!mmgr)
254
+ return NULL;
255
+
256
+ fontdef = HPDF_GetMem (mmgr, sizeof(HPDF_FontDef_Rec));
257
+ if (!fontdef)
258
+ return NULL;
259
+
260
+ HPDF_MemSet (fontdef, 0, sizeof(HPDF_FontDef_Rec));
261
+ fontdef->sig_bytes = HPDF_FONTDEF_SIG_BYTES;
262
+ fontdef->mmgr = mmgr;
263
+ fontdef->error = mmgr->error;
264
+ fontdef->type = HPDF_FONTDEF_TYPE_TRUETYPE;
265
+ fontdef->clean_fn = CleanFunc;
266
+ fontdef->free_fn = FreeFunc;
267
+
268
+ fontdef_attr = HPDF_GetMem (mmgr, sizeof(HPDF_TTFontDefAttr_Rec));
269
+ if (!fontdef_attr) {
270
+ HPDF_FreeMem (fontdef->mmgr, fontdef);
271
+ return NULL;
272
+ }
273
+
274
+ fontdef->attr = fontdef_attr;
275
+ HPDF_MemSet ((HPDF_BYTE *)fontdef_attr, 0, sizeof(HPDF_TTFontDefAttr_Rec));
276
+ fontdef->flags = HPDF_FONT_STD_CHARSET;
277
+
278
+ return fontdef;
279
+ }
280
+
281
+
282
+ HPDF_FontDef
283
+ HPDF_TTFontDef_Load (HPDF_MMgr mmgr,
284
+ HPDF_Stream stream,
285
+ HPDF_BOOL embedding)
286
+ {
287
+ HPDF_STATUS ret;
288
+ HPDF_FontDef fontdef;
289
+
290
+ HPDF_PTRACE ((" HPDF_TTFontDef_Load\n"));
291
+
292
+ fontdef = HPDF_TTFontDef_New (mmgr);
293
+
294
+ if (!fontdef) {
295
+ HPDF_Stream_Free (stream);
296
+ return NULL;
297
+ }
298
+
299
+ ret = LoadFontData (fontdef, stream, embedding, 0);
300
+ if (ret != HPDF_OK) {
301
+ HPDF_FontDef_Free (fontdef);
302
+ return NULL;
303
+ }
304
+
305
+ return fontdef;
306
+ }
307
+
308
+
309
+ HPDF_FontDef
310
+ HPDF_TTFontDef_Load2 (HPDF_MMgr mmgr,
311
+ HPDF_Stream stream,
312
+ HPDF_UINT index,
313
+ HPDF_BOOL embedding)
314
+ {
315
+ HPDF_STATUS ret;
316
+ HPDF_FontDef fontdef;
317
+
318
+ HPDF_PTRACE ((" HPDF_TTFontDef_Load\n"));
319
+
320
+ fontdef = HPDF_TTFontDef_New (mmgr);
321
+
322
+ if (!fontdef) {
323
+ HPDF_Stream_Free (stream);
324
+ return NULL;
325
+ }
326
+
327
+ ret = LoadFontData2 (fontdef, stream, index, embedding);
328
+ if (ret != HPDF_OK) {
329
+ HPDF_FontDef_Free (fontdef);
330
+ return NULL;
331
+ }
332
+
333
+ return fontdef;
334
+ }
335
+
336
+
337
+ #ifdef HPDF_TTF_DEBUG
338
+ static void
339
+ DumpTable (HPDF_FontDef fontdef)
340
+ {
341
+ HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
342
+ HPDF_Stream stream;
343
+ HPDF_UINT i;
344
+
345
+ for (i = 0; i < HPDF_REQUIRED_TAGS_COUNT; i++) {
346
+ char fname[9];
347
+ HPDF_TTFTable *tbl = FindTable (fontdef, REQUIRED_TAGS[i]);
348
+
349
+ if (!tbl) {
350
+ HPDF_PTRACE ((" ERR: cannot seek %s\n", fname));
351
+ return;
352
+ }
353
+
354
+ HPDF_MemSet (fname, 0, 9);
355
+ HPDF_MemCpy (fname, REQUIRED_TAGS[i], 4);
356
+ HPDF_MemCpy (fname + 4, ".dat", 4);
357
+ HPDF_PTRACE ((" %s open\n", fname));
358
+
359
+ if (HPDF_MemCmp(fname, "OS/2", 4) == 0)
360
+ fname[2] = '_';
361
+
362
+ stream = HPDF_FileWriter_New (fontdef->mmgr, fname);
363
+
364
+ if (!stream) {
365
+ HPDF_PTRACE ((" ERR: cannot open %s\n", fname));
366
+ } else {
367
+ HPDF_STATUS ret;
368
+ HPDF_UINT tbl_len = tbl->length;
369
+
370
+ ret = HPDF_Stream_Seek (attr->stream, tbl->offset, HPDF_SEEK_SET);
371
+ if (ret != HPDF_OK) {
372
+ HPDF_PTRACE ((" ERR: cannot seek \n"));
373
+ HPDF_Stream_Free (stream);
374
+ return;
375
+ }
376
+
377
+ for (;;) {
378
+ HPDF_BYTE buf[HPDF_STREAM_BUF_SIZ];
379
+ HPDF_UINT len = HPDF_STREAM_BUF_SIZ;
380
+
381
+ if (len > tbl_len)
382
+ len = tbl_len;
383
+
384
+ HPDF_Stream_Read (attr->stream, buf, &len);
385
+ if (len <= 0)
386
+ break;
387
+
388
+ ret = HPDF_Stream_Write (stream, buf, len);
389
+ if (ret != HPDF_OK) {
390
+ HPDF_PTRACE ((" ERR: cannot write\n"));
391
+ break;
392
+ }
393
+
394
+ tbl_len -= len;
395
+ if (tbl_len == 0)
396
+ break;
397
+ }
398
+
399
+ HPDF_Stream_Free (stream);
400
+ }
401
+ }
402
+ }
403
+ #endif
404
+
405
+ static HPDF_STATUS
406
+ LoadFontData (HPDF_FontDef fontdef,
407
+ HPDF_Stream stream,
408
+ HPDF_BOOL embedding,
409
+ HPDF_UINT offset)
410
+ {
411
+ HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
412
+ HPDF_STATUS ret;
413
+ HPDF_TTFTable *tbl;
414
+
415
+ HPDF_PTRACE ((" HPDF_TTFontDef_LoadFontData\n"));
416
+
417
+ attr->stream = stream;
418
+ attr->embedding = embedding;
419
+
420
+ if ((ret = HPDF_Stream_Seek (stream, offset, HPDF_SEEK_SET)) != HPDF_OK)
421
+ return ret;
422
+
423
+ if ((ret = LoadTTFTable (fontdef)) != HPDF_OK)
424
+ return ret;
425
+
426
+ #ifdef HPDF_DUMP_FONTDATA
427
+ DumpTable (fontdef);
428
+ #endif /* HPDF_DUMP_FONTDATA */
429
+
430
+ if ((ret = ParseHead (fontdef)) != HPDF_OK)
431
+ return ret;
432
+
433
+ if ((ret = ParseMaxp (fontdef)) != HPDF_OK)
434
+ return ret;
435
+
436
+ if ((ret = ParseHhea (fontdef)) != HPDF_OK)
437
+ return ret;
438
+
439
+ if ((ret = ParseCMap (fontdef)) != HPDF_OK)
440
+ return ret;
441
+
442
+ if ((ret = ParseHmtx (fontdef)) != HPDF_OK)
443
+ return ret;
444
+
445
+ if ((ret = ParseLoca (fontdef)) != HPDF_OK)
446
+ return ret;
447
+
448
+ if ((ret = ParseName (fontdef)) != HPDF_OK)
449
+ return ret;
450
+
451
+ if ((ret = ParseOS2 (fontdef)) != HPDF_OK)
452
+ return ret;
453
+
454
+ tbl = FindTable (fontdef, "glyf");
455
+ if (!tbl)
456
+ return HPDF_SetError (fontdef->error, HPDF_TTF_MISSING_TABLE, 4);
457
+
458
+ attr->glyph_tbl.base_offset = tbl->offset;
459
+ fontdef->cap_height =
460
+ HPDF_TTFontDef_GetCharBBox (fontdef, (HPDF_UINT16)'H').top;
461
+ fontdef->x_height =
462
+ HPDF_TTFontDef_GetCharBBox (fontdef, (HPDF_UINT16)'x').top;
463
+ fontdef->missing_width = (HPDF_UINT32)attr->h_metric[0].advance_width * 1000 /
464
+ attr->header.units_per_em;
465
+
466
+ HPDF_PTRACE ((" fontdef->cap_height=%d\n", fontdef->cap_height));
467
+ HPDF_PTRACE ((" fontdef->x_height=%d\n", fontdef->x_height));
468
+ HPDF_PTRACE ((" fontdef->missing_width=%d\n", fontdef->missing_width));
469
+
470
+ if (!embedding) {
471
+ HPDF_Stream_Free (attr->stream);
472
+ attr->stream = NULL;
473
+ }
474
+
475
+ return HPDF_OK;
476
+ }
477
+
478
+ static HPDF_STATUS
479
+ LoadFontData2 (HPDF_FontDef fontdef,
480
+ HPDF_Stream stream,
481
+ HPDF_UINT index,
482
+ HPDF_BOOL embedding)
483
+ {
484
+ HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
485
+ HPDF_STATUS ret;
486
+ HPDF_BYTE tag[4];
487
+ HPDF_UINT32 num_fonts;
488
+ HPDF_UINT32 offset;
489
+ HPDF_UINT size;
490
+
491
+ HPDF_PTRACE ((" HPDF_TTFontDef_LoadFontData2\n"));
492
+
493
+ attr->stream = stream;
494
+ attr->embedding = embedding;
495
+
496
+ ret = HPDF_Stream_Seek (stream, 0, HPDF_SEEK_SET);
497
+ if (ret != HPDF_OK)
498
+ return ret;
499
+
500
+ size = 4;
501
+ if ((ret = HPDF_Stream_Read (stream, tag, &size)) != HPDF_OK)
502
+ return ret;
503
+
504
+ if (HPDF_MemCmp (tag, "ttcf", 4) != 0)
505
+ return HPDF_SetError (fontdef->error, HPDF_INVALID_TTC_FILE, 0);
506
+
507
+ if ((ret = HPDF_Stream_Seek (stream, 8, HPDF_SEEK_SET)) != HPDF_OK)
508
+ return ret;
509
+
510
+ if ((ret = GetUINT32 (stream, &num_fonts)) != HPDF_OK)
511
+ return ret;
512
+
513
+ HPDF_PTRACE((" HPDF_TTFontDef_LoadFontData2 num_fonts=%u\n",
514
+ (HPDF_UINT)num_fonts));
515
+
516
+ if (index >= num_fonts)
517
+ return HPDF_SetError (fontdef->error, HPDF_INVALID_TTC_INDEX, 0);
518
+
519
+ /* read offset table for target font and set stream positioning to offset
520
+ * value.
521
+ */
522
+ if ((ret = HPDF_Stream_Seek (stream, 12 + index * 4, HPDF_SEEK_SET)) !=
523
+ HPDF_OK)
524
+ return ret;
525
+
526
+ if ((ret = GetUINT32 (stream, &offset)) != HPDF_OK)
527
+ return ret;
528
+
529
+ return LoadFontData (fontdef, stream, embedding, offset);
530
+ }
531
+
532
+ HPDF_Box
533
+ HPDF_TTFontDef_GetCharBBox (HPDF_FontDef fontdef,
534
+ HPDF_UINT16 unicode)
535
+ {
536
+ HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
537
+ HPDF_UINT16 gid = HPDF_TTFontDef_GetGlyphid(fontdef, unicode);
538
+ HPDF_STATUS ret;
539
+ HPDF_Box bbox = HPDF_ToBox(0, 0, 0, 0);
540
+ HPDF_INT16 i;
541
+ HPDF_INT m;
542
+
543
+ if (gid == 0) {
544
+ HPDF_PTRACE ((" GetCharHeight cannot get gid char=0x%04x\n", unicode));
545
+ return bbox;
546
+ }
547
+
548
+ if (attr->header.index_to_loc_format == 0)
549
+ m = 2;
550
+ else
551
+ m = 1;
552
+
553
+ ret = HPDF_Stream_Seek (attr->stream, attr->glyph_tbl.base_offset +
554
+ attr->glyph_tbl.offsets[gid] * m + 2, HPDF_SEEK_SET);
555
+
556
+ if (ret != HPDF_OK)
557
+ return bbox;
558
+
559
+ ret += GetINT16 (attr->stream, &i);
560
+ bbox.left = (HPDF_INT32)i * 1000 / attr->header.units_per_em;
561
+
562
+ ret += GetINT16 (attr->stream, &i);
563
+ bbox.bottom = (HPDF_INT32)i * 1000 / attr->header.units_per_em;
564
+
565
+ ret += GetINT16 (attr->stream, &i);
566
+ bbox.right = (HPDF_INT32)i * 1000 / attr->header.units_per_em;
567
+
568
+ ret += GetINT16 (attr->stream, &i);
569
+ bbox.top = (HPDF_INT32)i * 1000 / attr->header.units_per_em;
570
+
571
+ if (ret != HPDF_OK)
572
+ return HPDF_ToBox(0, 0, 0, 0);
573
+
574
+ HPDF_PTRACE((" PdfTTFontDef_GetCharBBox char=0x%04X, "
575
+ "box=[%f,%f,%f,%f]\n", unicode, bbox.left, bbox.bottom, bbox.right,
576
+ bbox.top));
577
+
578
+ return bbox;
579
+ }
580
+
581
+
582
+ static HPDF_STATUS
583
+ GetUINT32 (HPDF_Stream stream,
584
+ HPDF_UINT32 *value)
585
+ {
586
+ HPDF_STATUS ret;
587
+ HPDF_UINT size = sizeof (HPDF_UINT32);
588
+
589
+ ret = HPDF_Stream_Read (stream, (HPDF_BYTE *)value, &size);
590
+ if (ret != HPDF_OK) {
591
+ *value = 0;
592
+ return ret;
593
+ }
594
+
595
+ UINT32Swap (value);
596
+
597
+ return HPDF_OK;
598
+ }
599
+
600
+
601
+ static HPDF_STATUS
602
+ GetUINT16 (HPDF_Stream stream,
603
+ HPDF_UINT16 *value)
604
+ {
605
+ HPDF_STATUS ret;
606
+ HPDF_UINT size = sizeof (HPDF_UINT16);
607
+
608
+ ret = HPDF_Stream_Read (stream, (HPDF_BYTE *)value, &size);
609
+ if (ret != HPDF_OK) {
610
+ *value = 0;
611
+ return ret;
612
+ }
613
+
614
+ UINT16Swap (value);
615
+
616
+ return HPDF_OK;
617
+ }
618
+
619
+
620
+ static HPDF_STATUS
621
+ GetINT16 (HPDF_Stream stream,
622
+ HPDF_INT16 *value)
623
+ {
624
+ HPDF_STATUS ret;
625
+ HPDF_UINT size = sizeof (HPDF_INT16);
626
+
627
+ ret = HPDF_Stream_Read (stream, (HPDF_BYTE *)value, &size);
628
+ if (ret != HPDF_OK) {
629
+ *value = 0;
630
+ return ret;
631
+ }
632
+
633
+ INT16Swap (value);
634
+
635
+ return HPDF_OK;
636
+ }
637
+
638
+ static HPDF_STATUS
639
+ WriteUINT32 (HPDF_Stream stream,
640
+ HPDF_UINT32 value)
641
+ {
642
+ HPDF_STATUS ret;
643
+ HPDF_UINT32 tmp = value;
644
+
645
+ UINT32Swap (&tmp);
646
+
647
+ ret = HPDF_Stream_Write (stream, (HPDF_BYTE *)&tmp, sizeof(tmp));
648
+ if (ret != HPDF_OK)
649
+ return ret;
650
+
651
+ return HPDF_OK;
652
+ }
653
+
654
+
655
+ static HPDF_STATUS
656
+ WriteUINT16 (HPDF_Stream stream,
657
+ HPDF_UINT16 value)
658
+ {
659
+ HPDF_STATUS ret;
660
+ HPDF_UINT16 tmp = value;
661
+
662
+ UINT16Swap (&tmp);
663
+
664
+ ret = HPDF_Stream_Write (stream, (HPDF_BYTE *)&tmp, sizeof(tmp));
665
+ if (ret != HPDF_OK)
666
+ return ret;
667
+
668
+ return HPDF_OK;
669
+ }
670
+
671
+
672
+ static HPDF_STATUS
673
+ WriteINT16 (HPDF_Stream stream,
674
+ HPDF_INT16 value)
675
+ {
676
+ HPDF_STATUS ret;
677
+ HPDF_INT16 tmp = value;
678
+
679
+ INT16Swap (&tmp);
680
+
681
+ ret = HPDF_Stream_Write (stream, (HPDF_BYTE *)&tmp, sizeof(tmp));
682
+ if (ret != HPDF_OK)
683
+ return ret;
684
+
685
+ return HPDF_OK;
686
+ }
687
+
688
+
689
+ HPDF_STATUS
690
+ LoadTTFTable (HPDF_FontDef fontdef)
691
+ {
692
+ HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
693
+ HPDF_STATUS ret = HPDF_OK;
694
+ HPDF_INT i;
695
+ HPDF_TTFTable *tbl;
696
+
697
+ HPDF_PTRACE ((" HPDF_TTFontDef_LoadTTFTable\n"));
698
+
699
+ ret += GetUINT32 (attr->stream, &attr->offset_tbl.sfnt_version);
700
+ ret += GetUINT16 (attr->stream, &attr->offset_tbl.num_tables);
701
+ ret += GetUINT16 (attr->stream, &attr->offset_tbl.search_range);
702
+ ret += GetUINT16 (attr->stream, &attr->offset_tbl.entry_selector);
703
+ ret += GetUINT16 (attr->stream, &attr->offset_tbl.range_shift);
704
+
705
+ if (ret != HPDF_OK)
706
+ return HPDF_Error_GetCode (fontdef->error);
707
+
708
+ if (attr->offset_tbl.num_tables * sizeof(HPDF_TTFTable) >
709
+ HPDF_TTF_MAX_MEM_SIZ)
710
+ return HPDF_SetError (fontdef->error, HPDF_TTF_INVALID_FOMAT, 0);
711
+
712
+ attr->offset_tbl.table = HPDF_GetMem (fontdef->mmgr,
713
+ sizeof(HPDF_TTFTable) * attr->offset_tbl.num_tables);
714
+ if (!attr->offset_tbl.table)
715
+ return HPDF_Error_GetCode (fontdef->error);
716
+
717
+ tbl = attr->offset_tbl.table;
718
+ for (i = 0; i < attr->offset_tbl.num_tables; i++) {
719
+ HPDF_UINT siz = 4;
720
+
721
+ ret += HPDF_Stream_Read (attr->stream, tbl->tag, &siz);
722
+ ret += GetUINT32 (attr->stream, &tbl->check_sum);
723
+ ret += GetUINT32 (attr->stream, &tbl->offset);
724
+ ret += GetUINT32 (attr->stream, &tbl->length);
725
+
726
+ HPDF_PTRACE((" [%d] tag=[%c%c%c%c] check_sum=%u offset=%u length=%u\n",
727
+ i, tbl->tag[0], tbl->tag[1], tbl->tag[2], tbl->tag[3],
728
+ (HPDF_UINT)tbl->check_sum, (HPDF_UINT)tbl->offset,
729
+ (HPDF_UINT)tbl->length));
730
+
731
+ if (ret != HPDF_OK)
732
+ return HPDF_Error_GetCode (fontdef->error);;
733
+
734
+ tbl++;
735
+ }
736
+
737
+ return HPDF_OK;
738
+ }
739
+
740
+
741
+ static HPDF_STATUS
742
+ ParseHead (HPDF_FontDef fontdef)
743
+ {
744
+ HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
745
+ HPDF_TTFTable *tbl = FindTable (fontdef, "head");
746
+ HPDF_STATUS ret;
747
+ HPDF_UINT siz;
748
+
749
+ HPDF_PTRACE ((" HPDF_TTFontDef_ParseHead\n"));
750
+
751
+ if (!tbl)
752
+ return HPDF_SetError (fontdef->error, HPDF_TTF_MISSING_TABLE, 5);
753
+
754
+ ret = HPDF_Stream_Seek (attr->stream, tbl->offset, HPDF_SEEK_SET);
755
+ if (ret != HPDF_OK)
756
+ return ret;
757
+
758
+ siz = 4;
759
+ ret += HPDF_Stream_Read (attr->stream,
760
+ (HPDF_BYTE *)&attr->header.version_number, &siz);
761
+ ret += GetUINT32 (attr->stream, &attr->header.font_revision);
762
+ ret += GetUINT32 (attr->stream, &attr->header.check_sum_adjustment);
763
+ ret += GetUINT32 (attr->stream, &attr->header.magic_number);
764
+ ret += GetUINT16 (attr->stream, &attr->header.flags);
765
+ ret += GetUINT16 (attr->stream, &attr->header.units_per_em);
766
+
767
+ siz = 8;
768
+ ret += HPDF_Stream_Read (attr->stream, attr->header.created, &siz);
769
+ siz = 8;
770
+ ret += HPDF_Stream_Read (attr->stream, attr->header.modified, &siz);
771
+
772
+ ret += GetINT16 (attr->stream, &attr->header.x_min);
773
+ ret += GetINT16 (attr->stream, &attr->header.y_min);
774
+ ret += GetINT16 (attr->stream, &attr->header.x_max);
775
+ ret += GetINT16 (attr->stream, &attr->header.y_max);
776
+ ret += GetUINT16 (attr->stream, &attr->header.mac_style);
777
+ ret += GetUINT16 (attr->stream, &attr->header.lowest_rec_ppem);
778
+ ret += GetINT16 (attr->stream, &attr->header.font_direction_hint);
779
+ ret += GetINT16 (attr->stream, &attr->header.index_to_loc_format);
780
+ ret += GetINT16 (attr->stream, &attr->header.glyph_data_format);
781
+
782
+ if (ret != HPDF_OK)
783
+ return HPDF_Error_GetCode (fontdef->error);
784
+
785
+ fontdef->font_bbox. left = (HPDF_INT32)attr->header.x_min * 1000 /
786
+ attr->header.units_per_em;
787
+ fontdef->font_bbox. bottom = (HPDF_INT32)attr->header.y_min * 1000 /
788
+ attr->header.units_per_em;
789
+ fontdef->font_bbox. right = (HPDF_INT32)attr->header.x_max * 1000 /
790
+ attr->header.units_per_em;
791
+ fontdef->font_bbox. top = (HPDF_INT32)attr->header.y_max * 1000 /
792
+ attr->header.units_per_em;
793
+
794
+ return HPDF_OK;
795
+ }
796
+
797
+
798
+ static HPDF_STATUS
799
+ ParseMaxp (HPDF_FontDef fontdef)
800
+ {
801
+ HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
802
+ HPDF_TTFTable *tbl = FindTable (fontdef, "maxp");
803
+ HPDF_STATUS ret;
804
+
805
+ HPDF_PTRACE ((" HPDF_TTFontDef_ParseMaxp\n"));
806
+
807
+ if (!tbl)
808
+ return HPDF_SetError (fontdef->error, HPDF_TTF_MISSING_TABLE, 9);
809
+
810
+ ret = HPDF_Stream_Seek (attr->stream, tbl->offset + 4, HPDF_SEEK_SET);
811
+ if (ret != HPDF_OK)
812
+ return ret;
813
+
814
+ ret = GetUINT16 (attr->stream, &attr->num_glyphs);
815
+
816
+ HPDF_PTRACE((" HPDF_TTFontDef_ParseMaxp num_glyphs=%u\n",
817
+ attr->num_glyphs));
818
+
819
+ return ret;
820
+ }
821
+
822
+
823
+ static HPDF_STATUS
824
+ ParseHhea (HPDF_FontDef fontdef)
825
+ {
826
+ HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
827
+ HPDF_TTFTable *tbl = FindTable (fontdef, "hhea");
828
+ HPDF_STATUS ret;
829
+
830
+ HPDF_PTRACE ((" HPDF_TTFontDef_ParseHhea\n"));
831
+
832
+ if (!tbl)
833
+ return HPDF_SetError (fontdef->error, HPDF_TTF_MISSING_TABLE, 6);
834
+
835
+ ret = HPDF_Stream_Seek (attr->stream, tbl->offset + 4, HPDF_SEEK_SET);
836
+ if (ret != HPDF_OK)
837
+ return ret;
838
+
839
+ ret += GetINT16 (attr->stream, &fontdef->ascent);
840
+ fontdef->ascent = (HPDF_INT32)fontdef->ascent * 1000 /
841
+ attr->header.units_per_em;
842
+ ret += GetINT16 (attr->stream, &fontdef->descent);
843
+ fontdef->descent = (HPDF_INT32)fontdef->descent * 1000 /
844
+ attr->header.units_per_em;
845
+
846
+ if (ret != HPDF_OK)
847
+ return HPDF_Error_GetCode (fontdef->error);
848
+
849
+ ret = HPDF_Stream_Seek (attr->stream, tbl->offset + 34, HPDF_SEEK_SET);
850
+ if (ret != HPDF_OK)
851
+ return ret;
852
+
853
+ ret = GetUINT16 (attr->stream, &attr->num_h_metric);
854
+ if (ret != HPDF_OK)
855
+ return HPDF_Error_GetCode (fontdef->error);
856
+
857
+ HPDF_PTRACE((" HPDF_TTFontDef_ParseHhea num_h_metric=%u\n",
858
+ attr->num_h_metric));
859
+
860
+ return ret;
861
+ }
862
+
863
+
864
+ static HPDF_STATUS
865
+ ParseCMap (HPDF_FontDef fontdef)
866
+ {
867
+ HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
868
+ HPDF_TTFTable *tbl = FindTable (fontdef, "cmap");
869
+ HPDF_STATUS ret;
870
+ HPDF_UINT16 version;
871
+ HPDF_UINT16 num_cmap;
872
+ HPDF_UINT i;
873
+ HPDF_UINT32 ms_unicode_encoding_offset = 0;
874
+ HPDF_UINT32 byte_encoding_offset = 0;
875
+
876
+ HPDF_PTRACE ((" HPDF_TTFontDef_ParseCMap\n"));
877
+
878
+ if (!tbl)
879
+ return HPDF_SetError (fontdef->error, HPDF_TTF_MISSING_TABLE, 1);
880
+
881
+ ret = HPDF_Stream_Seek (attr->stream, tbl->offset, HPDF_SEEK_SET);
882
+ if (ret != HPDF_OK)
883
+ return ret;
884
+
885
+ ret += GetUINT16 (attr->stream, &version);
886
+ if (ret != HPDF_OK)
887
+ return HPDF_Error_GetCode (fontdef->error);
888
+
889
+ if (version != 0)
890
+ return HPDF_SetError (fontdef->error, HPDF_TTF_INVALID_FOMAT, 0);
891
+
892
+ ret += GetUINT16 (attr->stream, &num_cmap);
893
+ if (ret != HPDF_OK)
894
+ return HPDF_Error_GetCode (fontdef->error);
895
+
896
+ for (i = 0; i < num_cmap; i++) {
897
+ HPDF_UINT16 platformID;
898
+ HPDF_UINT16 encodingID;
899
+ HPDF_UINT16 format;
900
+ HPDF_UINT32 offset;
901
+ HPDF_INT32 save_offset;
902
+
903
+ ret += GetUINT16 (attr->stream, &platformID);
904
+ ret += GetUINT16 (attr->stream, &encodingID);
905
+ ret += GetUINT32 (attr->stream, &offset);
906
+ if (ret != HPDF_OK)
907
+ return HPDF_Error_GetCode (fontdef->error);
908
+
909
+ save_offset = HPDF_Stream_Tell (attr->stream);
910
+ if (save_offset < 0)
911
+ return HPDF_Error_GetCode (fontdef->error);
912
+
913
+ ret = HPDF_Stream_Seek (attr->stream, tbl->offset + offset,
914
+ HPDF_SEEK_SET);
915
+ if (ret != HPDF_OK)
916
+ return ret;
917
+
918
+ ret = GetUINT16 (attr->stream, &format);
919
+ if (ret != HPDF_OK)
920
+ return ret;
921
+
922
+ HPDF_PTRACE((" HPDF_TTFontDef_ParseCMap tables[%d] platformID=%u "
923
+ "encodingID=%u format=%u offset=%u\n", i, platformID,
924
+ encodingID, format, (HPDF_UINT)offset));
925
+
926
+ /* MS-Unicode-CMAP is used for priority */
927
+ if (platformID == 3 && encodingID == 1 && format == 4) {
928
+ ms_unicode_encoding_offset = offset;
929
+ break;
930
+ }
931
+
932
+ /* Byte-Encoding-CMAP will be used if MS-Unicode-CMAP is not found */
933
+ if (platformID == 1 && encodingID ==0 && format == 1)
934
+ byte_encoding_offset = offset;
935
+
936
+ ret = HPDF_Stream_Seek (attr->stream, save_offset, HPDF_SEEK_SET);
937
+ if (ret != HPDF_OK)
938
+ return ret;
939
+ }
940
+
941
+ if (ms_unicode_encoding_offset != 0) {
942
+ HPDF_PTRACE((" found microsoft unicode cmap.\n"));
943
+ ret = ParseCMAP_format4(fontdef, ms_unicode_encoding_offset +
944
+ tbl->offset);
945
+ } else if (byte_encoding_offset != 0) {
946
+ HPDF_PTRACE((" found byte encoding cmap.\n"));
947
+ ret = ParseCMAP_format0(fontdef, byte_encoding_offset + tbl->offset);
948
+ } else {
949
+ HPDF_PTRACE((" cannot found target cmap.\n"));
950
+ return HPDF_SetError (fontdef->error, HPDF_TTF_INVALID_FOMAT, 0);
951
+ }
952
+
953
+ return ret;
954
+ }
955
+
956
+
957
+ static HPDF_STATUS
958
+ ParseCMAP_format0 (HPDF_FontDef fontdef,
959
+ HPDF_UINT32 offset)
960
+ {
961
+ HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
962
+ HPDF_STATUS ret;
963
+ HPDF_BYTE array[256];
964
+ HPDF_UINT size;
965
+ HPDF_UINT16 *parray;
966
+ HPDF_UINT i;
967
+
968
+ HPDF_PTRACE((" ParseCMAP_format0\n"));
969
+
970
+ ret = HPDF_Stream_Seek (attr->stream, offset, HPDF_SEEK_SET);
971
+ if (ret != HPDF_OK)
972
+ return ret;
973
+
974
+ ret += GetUINT16 (attr->stream, &attr->cmap.format);
975
+ ret += GetUINT16 (attr->stream, &attr->cmap.length);
976
+ ret += GetUINT16 (attr->stream, &attr->cmap.language);
977
+
978
+ if (ret != HPDF_OK)
979
+ return HPDF_Error_GetCode (fontdef->error);
980
+
981
+ if (attr->cmap.format != 0)
982
+ return HPDF_SetError (fontdef->error, HPDF_TTF_INVALID_FOMAT, 0);
983
+
984
+ size = 256;
985
+ ret = HPDF_Stream_Read (attr->stream, array, &size);
986
+ if (ret != HPDF_OK)
987
+ return ret;
988
+
989
+ attr->cmap.glyph_id_array_count = 256;
990
+ attr->cmap.glyph_id_array = HPDF_GetMem (fontdef->mmgr,
991
+ sizeof (HPDF_UINT16) * 256);
992
+ if (!attr->cmap.glyph_id_array)
993
+ return HPDF_Error_GetCode (fontdef->error);
994
+
995
+ parray = attr->cmap.glyph_id_array;
996
+ for (i = 0; i < 256; i++) {
997
+ *parray = attr->cmap.glyph_id_array[i];
998
+ HPDF_PTRACE((" ParseCMAP_format0 glyph_id_array[%d]=%u\n",
999
+ i, *parray));
1000
+ parray++;
1001
+ }
1002
+
1003
+ return HPDF_OK;
1004
+ }
1005
+
1006
+
1007
+ static HPDF_STATUS
1008
+ ParseCMAP_format4 (HPDF_FontDef fontdef,
1009
+ HPDF_UINT32 offset)
1010
+ {
1011
+ HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
1012
+ HPDF_STATUS ret;
1013
+ HPDF_UINT i;
1014
+ HPDF_UINT16 *pend_count;
1015
+ HPDF_UINT16 *pstart_count;
1016
+ HPDF_INT16 *pid_delta;
1017
+ HPDF_UINT16 *pid_range_offset;
1018
+ HPDF_UINT16 *pglyph_id_array;
1019
+ HPDF_INT32 num_read;
1020
+
1021
+ HPDF_PTRACE((" ParseCMAP_format4\n"));
1022
+
1023
+ if ((ret = HPDF_Stream_Seek (attr->stream, offset, HPDF_SEEK_SET)) !=
1024
+ HPDF_OK)
1025
+ return ret;
1026
+
1027
+ ret += GetUINT16 (attr->stream, &attr->cmap.format);
1028
+ ret += GetUINT16 (attr->stream, &attr->cmap.length);
1029
+ ret += GetUINT16 (attr->stream, &attr->cmap.language);
1030
+
1031
+ if (ret != HPDF_OK)
1032
+ return HPDF_Error_GetCode (fontdef->error);
1033
+
1034
+ if (attr->cmap.format != 4)
1035
+ return HPDF_SetError (fontdef->error, HPDF_TTF_INVALID_FOMAT, 0);
1036
+
1037
+ ret += GetUINT16 (attr->stream, &attr->cmap.seg_count_x2);
1038
+ ret += GetUINT16 (attr->stream, &attr->cmap.search_range);
1039
+ ret += GetUINT16 (attr->stream, &attr->cmap.entry_selector);
1040
+ ret += GetUINT16 (attr->stream, &attr->cmap.range_shift);
1041
+
1042
+ if (ret != HPDF_OK)
1043
+ return HPDF_Error_GetCode (fontdef->error);
1044
+
1045
+ /* end_count */
1046
+ attr->cmap.end_count = HPDF_GetMem (fontdef->mmgr,
1047
+ sizeof(HPDF_UINT16) * attr->cmap.seg_count_x2 / 2);
1048
+ if (!attr->cmap.end_count)
1049
+ return HPDF_Error_GetCode (fontdef->error);
1050
+
1051
+ pend_count = attr->cmap.end_count;
1052
+ for (i = 0; i < attr->cmap.seg_count_x2 / 2; i++)
1053
+ if ((ret = GetUINT16 (attr->stream, pend_count++)) != HPDF_OK)
1054
+ return ret;
1055
+
1056
+ if ((ret = GetUINT16 (attr->stream, &attr->cmap.reserved_pad)) != HPDF_OK)
1057
+ return ret;
1058
+
1059
+ /* start_count */
1060
+ attr->cmap.start_count = HPDF_GetMem (fontdef->mmgr,
1061
+ sizeof(HPDF_UINT16) * attr->cmap.seg_count_x2 / 2);
1062
+ if (!attr->cmap.start_count)
1063
+ return HPDF_Error_GetCode (fontdef->error);
1064
+
1065
+ pstart_count = attr->cmap.start_count;
1066
+ for (i = 0; i < attr->cmap.seg_count_x2 / 2; i++)
1067
+ if ((ret = GetUINT16 (attr->stream, pstart_count++)) != HPDF_OK)
1068
+ return ret;
1069
+
1070
+ /* id_delta */
1071
+ attr->cmap.id_delta = HPDF_GetMem (fontdef->mmgr,
1072
+ sizeof(HPDF_UINT16) * attr->cmap.seg_count_x2 / 2);
1073
+ if (!attr->cmap.id_delta)
1074
+ return HPDF_Error_GetCode (fontdef->error);
1075
+
1076
+ pid_delta = attr->cmap.id_delta;
1077
+ for (i = 0; i < attr->cmap.seg_count_x2 / 2; i++)
1078
+ if ((ret = GetINT16 (attr->stream, pid_delta++)) != HPDF_OK)
1079
+ return ret;
1080
+
1081
+ /* id_range_offset */
1082
+ attr->cmap.id_range_offset = HPDF_GetMem (fontdef->mmgr,
1083
+ sizeof(HPDF_UINT16) * attr->cmap.seg_count_x2 / 2);
1084
+ if (!attr->cmap.id_range_offset)
1085
+ return HPDF_Error_GetCode (fontdef->error);
1086
+
1087
+ pid_range_offset = attr->cmap.id_range_offset;
1088
+ for (i = 0; i < attr->cmap.seg_count_x2 / 2; i++)
1089
+ if ((ret = GetUINT16 (attr->stream, pid_range_offset++)) != HPDF_OK)
1090
+ return ret;
1091
+
1092
+ num_read = HPDF_Stream_Tell (attr->stream) - offset;
1093
+ if (num_read < 0)
1094
+ return HPDF_Error_GetCode (fontdef->error);
1095
+
1096
+ attr->cmap.glyph_id_array_count = (attr->cmap.length - num_read) / 2;
1097
+
1098
+ if (attr->cmap.glyph_id_array_count > 0) {
1099
+ /* glyph_id_array */
1100
+ attr->cmap.glyph_id_array = HPDF_GetMem (fontdef->mmgr,
1101
+ sizeof(HPDF_UINT16) * attr->cmap.glyph_id_array_count);
1102
+ if (!attr->cmap.glyph_id_array)
1103
+ return HPDF_Error_GetCode (fontdef->error);
1104
+
1105
+ pglyph_id_array = attr->cmap.glyph_id_array;
1106
+ for (i = 0; i < attr->cmap.glyph_id_array_count; i++)
1107
+ if ((ret = GetUINT16 (attr->stream, pglyph_id_array++)) != HPDF_OK)
1108
+ return ret;
1109
+ } else
1110
+ attr->cmap.glyph_id_array = NULL;
1111
+
1112
+ #ifdef HPDF_DEBUG
1113
+ /* print all elements of cmap table */
1114
+ for (i = 0; i < attr->cmap.seg_count_x2 / 2; i++) {
1115
+ HPDF_PTRACE((" ParseCMAP_format4[%d] start_count=0x%04X, "
1116
+ "end_count=0x%04X, id_delta=%d, id_range_offset=%u\n", i,
1117
+ attr->cmap.start_count[i], attr->cmap.end_count[i],
1118
+ attr->cmap.id_delta[i], attr->cmap.id_range_offset[i]));
1119
+ }
1120
+ #endif
1121
+
1122
+ return HPDF_OK;
1123
+ }
1124
+
1125
+
1126
+ HPDF_UINT16
1127
+ HPDF_TTFontDef_GetGlyphid (HPDF_FontDef fontdef,
1128
+ HPDF_UINT16 unicode)
1129
+ {
1130
+ HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
1131
+ HPDF_UINT16 *pend_count = attr->cmap.end_count;
1132
+ HPDF_UINT seg_count = attr->cmap.seg_count_x2 / 2;
1133
+ HPDF_UINT i;
1134
+
1135
+ HPDF_PTRACE((" HPDF_TTFontDef_GetGlyphid\n"));
1136
+
1137
+ /* format 0 */
1138
+ if (attr->cmap.format == 0) {
1139
+ unicode &= 0xFF;
1140
+ return attr->cmap.glyph_id_array[unicode];
1141
+ }
1142
+
1143
+ /* format 4 */
1144
+ if (attr->cmap.seg_count_x2 == 0) {
1145
+ HPDF_SetError (fontdef->error, HPDF_TTF_INVALID_CMAP, 0);
1146
+ return 0;
1147
+ }
1148
+
1149
+ for (i = 0; i < seg_count; i++) {
1150
+ if (unicode <= *pend_count)
1151
+ break;
1152
+ pend_count++;
1153
+ }
1154
+
1155
+ if (attr->cmap.start_count[i] > unicode) {
1156
+ HPDF_PTRACE((" HPDF_TTFontDef_GetGlyphid undefined char(0x%04X)\n",
1157
+ unicode));
1158
+ return 0;
1159
+ }
1160
+
1161
+ if (attr->cmap.id_range_offset[i] == 0) {
1162
+ HPDF_PTRACE((" HPDF_TTFontDef_GetGlyphid idx=%u code=%u "
1163
+ " ret=%u\n", i, unicode,
1164
+ unicode + attr->cmap.id_delta[i]));
1165
+
1166
+ return unicode + attr->cmap.id_delta[i];
1167
+ } else {
1168
+ HPDF_UINT idx = attr->cmap.id_range_offset[i] / 2 +
1169
+ (unicode - attr->cmap.start_count[i]) - (seg_count - i);
1170
+
1171
+ if (idx > attr->cmap.glyph_id_array_count) {
1172
+ HPDF_PTRACE((" HPDF_TTFontDef_GetGlyphid[%u] %u > %u\n",
1173
+ i, idx, (HPDF_UINT)attr->cmap.glyph_id_array_count));
1174
+ return 0;
1175
+ } else {
1176
+ HPDF_UINT16 gid = attr->cmap.glyph_id_array[idx] +
1177
+ attr->cmap.id_delta[i];
1178
+ HPDF_PTRACE((" HPDF_TTFontDef_GetGlyphid idx=%u unicode=0x%04X "
1179
+ "id=%u\n", idx, unicode, gid));
1180
+ return gid;
1181
+ }
1182
+ }
1183
+ }
1184
+
1185
+
1186
+ HPDF_INT16
1187
+ HPDF_TTFontDef_GetCharWidth (HPDF_FontDef fontdef,
1188
+ HPDF_UINT16 unicode)
1189
+ {
1190
+ HPDF_UINT16 advance_width;
1191
+ HPDF_TTF_LongHorMetric hmetrics;
1192
+ HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
1193
+ HPDF_UINT16 gid = HPDF_TTFontDef_GetGlyphid (fontdef, unicode);
1194
+
1195
+ HPDF_PTRACE((" HPDF_TTFontDef_GetCharWidth\n"));
1196
+
1197
+ if (gid >= attr->num_glyphs) {
1198
+ HPDF_PTRACE((" HPDF_TTFontDef_GetCharWidth WARNING gid > "
1199
+ "num_glyphs %u > %u\n", gid, attr->num_glyphs));
1200
+ return fontdef->missing_width;
1201
+ }
1202
+
1203
+ hmetrics = attr->h_metric[gid];
1204
+
1205
+ if (!attr->glyph_tbl.flgs[gid]) {
1206
+ attr->glyph_tbl.flgs[gid] = 1;
1207
+
1208
+ if (attr->embedding)
1209
+ CheckCompositGryph (fontdef, gid);
1210
+ }
1211
+
1212
+ advance_width = (HPDF_UINT)hmetrics.advance_width * 1000 /
1213
+ attr->header.units_per_em;
1214
+
1215
+ return (HPDF_INT16)advance_width;
1216
+ }
1217
+
1218
+
1219
+ static HPDF_STATUS
1220
+ CheckCompositGryph (HPDF_FontDef fontdef,
1221
+ HPDF_UINT16 gid)
1222
+ {
1223
+ HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
1224
+ HPDF_UINT offset = attr->glyph_tbl.offsets[gid];
1225
+ // HPDF_UINT len = attr->glyph_tbl.offsets[gid + 1] - offset;
1226
+ HPDF_STATUS ret;
1227
+
1228
+ HPDF_PTRACE ((" CheckCompositGryph\n"));
1229
+
1230
+ if (attr->header.index_to_loc_format == 0)
1231
+ offset *= 2;
1232
+
1233
+ offset += attr->glyph_tbl.base_offset;
1234
+
1235
+ if ((ret = HPDF_Stream_Seek (attr->stream, offset, HPDF_SEEK_SET))
1236
+ != HPDF_OK) {
1237
+ return ret;
1238
+ } else {
1239
+ HPDF_INT16 num_of_contours;
1240
+ HPDF_INT16 flags;
1241
+ HPDF_INT16 glyph_index;
1242
+ const HPDF_UINT16 ARG_1_AND_2_ARE_WORDS = 1;
1243
+ const HPDF_UINT16 WE_HAVE_A_SCALE = 8;
1244
+ const HPDF_UINT16 MORE_COMPONENTS = 32;
1245
+ const HPDF_UINT16 WE_HAVE_AN_X_AND_Y_SCALE = 64;
1246
+ const HPDF_UINT16 WE_HAVE_A_TWO_BY_TWO = 128;
1247
+
1248
+ if ((ret = GetINT16 (attr->stream, &num_of_contours)) != HPDF_OK)
1249
+ return ret;
1250
+
1251
+ if (num_of_contours != -1)
1252
+ return HPDF_OK;
1253
+
1254
+ HPDF_PTRACE ((" CheckCompositGryph composit font gid=%u\n", gid));
1255
+
1256
+ if ((ret = HPDF_Stream_Seek (attr->stream, 8, HPDF_SEEK_CUR))
1257
+ != HPDF_OK)
1258
+ return ret;
1259
+
1260
+ do {
1261
+ if ((ret = GetINT16 (attr->stream, &flags)) != HPDF_OK)
1262
+ return ret;
1263
+
1264
+ if ((ret = GetINT16 (attr->stream, &glyph_index)) != HPDF_OK)
1265
+ return ret;
1266
+
1267
+ if (flags & ARG_1_AND_2_ARE_WORDS) {
1268
+ if ((ret = HPDF_Stream_Seek (attr->stream, 4, HPDF_SEEK_CUR))
1269
+ != HPDF_OK)
1270
+ return ret;
1271
+ } else {
1272
+ if ((ret = HPDF_Stream_Seek (attr->stream, 2, HPDF_SEEK_CUR))
1273
+ != HPDF_OK)
1274
+ return ret;
1275
+ }
1276
+
1277
+ if (flags & WE_HAVE_A_SCALE) {
1278
+ if ((ret = HPDF_Stream_Seek (attr->stream, 2, HPDF_SEEK_CUR))
1279
+ != HPDF_OK)
1280
+ return ret;
1281
+ } else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) {
1282
+ if ((ret = HPDF_Stream_Seek (attr->stream, 4, HPDF_SEEK_CUR))
1283
+ != HPDF_OK)
1284
+ return ret;
1285
+ } else if (flags & WE_HAVE_A_TWO_BY_TWO) {
1286
+ if ((ret = HPDF_Stream_Seek (attr->stream, 8, HPDF_SEEK_CUR))
1287
+ != HPDF_OK)
1288
+ return ret;
1289
+ }
1290
+
1291
+ if (glyph_index > 0 && glyph_index < attr->num_glyphs)
1292
+ attr->glyph_tbl.flgs[glyph_index] = 1;
1293
+
1294
+ HPDF_PTRACE ((" gid=%d, num_of_contours=%d, flags=%d, "
1295
+ "glyph_index=%d\n", gid, num_of_contours, flags,
1296
+ glyph_index));
1297
+
1298
+ } while (flags & MORE_COMPONENTS);
1299
+ }
1300
+
1301
+ return HPDF_OK;
1302
+ }
1303
+
1304
+
1305
+ HPDF_INT16
1306
+ HPDF_TTFontDef_GetGidWidth (HPDF_FontDef fontdef,
1307
+ HPDF_UINT16 gid)
1308
+ {
1309
+ HPDF_UINT16 advance_width;
1310
+ HPDF_TTF_LongHorMetric hmetrics;
1311
+ HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
1312
+
1313
+ HPDF_PTRACE((" HPDF_TTFontDef_GetGidWidth\n"));
1314
+
1315
+ if (gid >= attr->num_glyphs) {
1316
+ HPDF_PTRACE((" HPDF_TTFontDef_GetGidWidth WARNING gid > "
1317
+ "num_glyphs %u > %u\n", gid, attr->num_glyphs));
1318
+ return fontdef->missing_width;
1319
+ }
1320
+
1321
+ hmetrics = attr->h_metric[gid];
1322
+
1323
+ advance_width = (HPDF_UINT)hmetrics.advance_width * 1000 /
1324
+ attr->header.units_per_em;
1325
+
1326
+ HPDF_PTRACE((" HPDF_TTFontDef_GetGidWidth gid=%u, width=%u\n",
1327
+ gid, advance_width));
1328
+
1329
+ return (HPDF_INT16)advance_width;
1330
+ }
1331
+
1332
+
1333
+
1334
+ static HPDF_STATUS
1335
+ ParseHmtx (HPDF_FontDef fontdef)
1336
+ {
1337
+ HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
1338
+ HPDF_TTFTable *tbl = FindTable (fontdef, "hmtx");
1339
+ HPDF_STATUS ret;
1340
+ HPDF_UINT i;
1341
+ HPDF_UINT16 save_aw = 0;
1342
+ HPDF_TTF_LongHorMetric *pmetric;
1343
+
1344
+ HPDF_PTRACE ((" HPDF_TTFontDef_ParseHtmx\n"));
1345
+
1346
+ if (!tbl)
1347
+ return HPDF_SetError (fontdef->error, HPDF_TTF_MISSING_TABLE, 7);
1348
+
1349
+ ret = HPDF_Stream_Seek (attr->stream, tbl->offset, HPDF_SEEK_SET);
1350
+ if (ret != HPDF_OK)
1351
+ return ret;
1352
+
1353
+ /* allocate memory for a table of holizontal matrix.
1354
+ * the count of metric records is same as the number of glyphs
1355
+ */
1356
+ attr->h_metric = HPDF_GetMem (fontdef->mmgr,
1357
+ sizeof (HPDF_TTF_LongHorMetric) * attr->num_glyphs);
1358
+
1359
+ if (!attr->h_metric)
1360
+ return HPDF_Error_GetCode (fontdef->error);
1361
+
1362
+ pmetric = attr->h_metric;
1363
+ for (i = 0; i < attr->num_h_metric; i++) {
1364
+ if ((ret = GetUINT16 (attr->stream, &pmetric->advance_width)) !=
1365
+ HPDF_OK)
1366
+ return ret;
1367
+
1368
+ if ((ret = GetINT16 (attr->stream, &pmetric->lsb)) != HPDF_OK)
1369
+ return ret;
1370
+
1371
+ HPDF_PTRACE((" ParseHmtx metric[%u] aw=%u lsb=%d\n", i,
1372
+ pmetric->advance_width, pmetric->lsb));
1373
+
1374
+ save_aw = pmetric->advance_width;
1375
+ pmetric++;
1376
+ }
1377
+
1378
+ /* pad the advance_width of remaining metrics with the value of last metric */
1379
+ while (i < attr->num_glyphs) {
1380
+ pmetric->advance_width = save_aw;
1381
+
1382
+ if ((ret = GetINT16 (attr->stream, &pmetric->lsb)) != HPDF_OK)
1383
+ return ret;
1384
+
1385
+ pmetric++;
1386
+ i++;
1387
+ }
1388
+
1389
+ return HPDF_OK;
1390
+ }
1391
+
1392
+ static HPDF_STATUS
1393
+ ParseLoca (HPDF_FontDef fontdef)
1394
+ {
1395
+ HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
1396
+ HPDF_TTFTable *tbl = FindTable (fontdef, "loca");
1397
+ HPDF_STATUS ret;
1398
+ HPDF_UINT i;
1399
+ HPDF_UINT32 *poffset;
1400
+
1401
+ HPDF_PTRACE ((" HPDF_TTFontDef_ParseLoca\n"));
1402
+
1403
+ if (!tbl)
1404
+ return HPDF_SetError (fontdef->error, HPDF_TTF_MISSING_TABLE, 8);
1405
+
1406
+ ret = HPDF_Stream_Seek (attr->stream, tbl->offset, HPDF_SEEK_SET);
1407
+ if (ret != HPDF_OK)
1408
+ return ret;
1409
+
1410
+ /* allocate glyph-offset-table. */
1411
+ attr->glyph_tbl.offsets = HPDF_GetMem (fontdef->mmgr,
1412
+ sizeof (HPDF_UINT32) * (attr->num_glyphs + 1));
1413
+
1414
+ if (!attr->glyph_tbl.offsets)
1415
+ return HPDF_Error_GetCode (fontdef->error);
1416
+
1417
+ HPDF_MemSet (attr->glyph_tbl.offsets, 0,
1418
+ sizeof (HPDF_UINT32) * (attr->num_glyphs + 1));
1419
+
1420
+ /* allocate glyph-flg-table.
1421
+ * this flgs are used to judge whether glyphs should be embedded.
1422
+ */
1423
+ attr->glyph_tbl.flgs = HPDF_GetMem (fontdef->mmgr,
1424
+ sizeof (HPDF_BYTE) * attr->num_glyphs);
1425
+
1426
+ if (!attr->glyph_tbl.flgs)
1427
+ return HPDF_Error_GetCode (fontdef->error);
1428
+
1429
+ HPDF_MemSet (attr->glyph_tbl.flgs, 0,
1430
+ sizeof (HPDF_BYTE) * attr->num_glyphs);
1431
+ attr->glyph_tbl.flgs[0] = 1;
1432
+
1433
+ poffset = attr->glyph_tbl.offsets;
1434
+ if (attr->header.index_to_loc_format == 0) {
1435
+ /* short version */
1436
+ for (i = 0; i <= attr->num_glyphs; i++) {
1437
+ HPDF_UINT16 tmp = 0;
1438
+
1439
+ if ((ret = GetUINT16 (attr->stream, &tmp)) != HPDF_OK)
1440
+ return ret;
1441
+
1442
+ *poffset = tmp;
1443
+ poffset++;
1444
+ }
1445
+ } else {
1446
+ /* long version */
1447
+ for (i = 0; i <= attr->num_glyphs; i++) {
1448
+ if ((ret = GetUINT32 (attr->stream, poffset)) != HPDF_OK)
1449
+ return ret;
1450
+
1451
+ poffset++;
1452
+ }
1453
+ }
1454
+
1455
+
1456
+ #ifdef HPDF_DEBUG
1457
+ poffset = attr->glyph_tbl.offsets;
1458
+ for (i = 0; i <= attr->num_glyphs; i++) {
1459
+ HPDF_PTRACE((" ParseLOCA offset[%u]=%u\n", i, (HPDF_UINT)*poffset));
1460
+ poffset++;
1461
+ }
1462
+ #endif
1463
+
1464
+
1465
+ return HPDF_OK;
1466
+ }
1467
+
1468
+
1469
+ static HPDF_STATUS
1470
+ LoadUnicodeName (HPDF_Stream stream,
1471
+ HPDF_UINT offset,
1472
+ HPDF_UINT len,
1473
+ char *buf)
1474
+ {
1475
+ HPDF_BYTE tmp[HPDF_LIMIT_MAX_NAME_LEN * 2 + 1];
1476
+ HPDF_UINT i = 0;
1477
+ HPDF_UINT j = 0;
1478
+ HPDF_STATUS ret;
1479
+
1480
+ HPDF_MemSet (buf, 0, HPDF_LIMIT_MAX_NAME_LEN + 1);
1481
+
1482
+ if ((ret = HPDF_Stream_Seek (stream, offset, HPDF_SEEK_SET)) !=
1483
+ HPDF_OK)
1484
+ return ret;
1485
+
1486
+ if ((ret = HPDF_Stream_Read (stream, tmp, &len))
1487
+ != HPDF_OK)
1488
+ return ret;
1489
+
1490
+ while (i < len) {
1491
+ i++;
1492
+ buf[j] = tmp[i];
1493
+ j++;
1494
+ i++;
1495
+ }
1496
+
1497
+ return HPDF_OK;
1498
+ }
1499
+
1500
+ static HPDF_STATUS
1501
+ ParseName (HPDF_FontDef fontdef)
1502
+ {
1503
+ HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
1504
+ HPDF_TTFTable *tbl = FindTable (fontdef, "name");
1505
+ HPDF_STATUS ret;
1506
+ HPDF_UINT i;
1507
+ HPDF_TTF_NameRecord *name_rec;
1508
+ HPDF_UINT offset_id1 = 0;
1509
+ HPDF_UINT offset_id2 = 0;
1510
+ HPDF_UINT offset_id1u = 0;
1511
+ HPDF_UINT offset_id2u = 0;
1512
+ HPDF_UINT len_id1 = 0;
1513
+ HPDF_UINT len_id2 = 0;
1514
+ HPDF_UINT len_id1u = 0;
1515
+ HPDF_UINT len_id2u = 0;
1516
+ char tmp[HPDF_LIMIT_MAX_NAME_LEN + 1];
1517
+
1518
+ HPDF_PTRACE ((" HPDF_TTFontDef_ParseMaxp\n"));
1519
+
1520
+ if (!tbl)
1521
+ return HPDF_SetError (fontdef->error, HPDF_TTF_MISSING_TABLE, 10);
1522
+
1523
+ ret = HPDF_Stream_Seek (attr->stream, tbl->offset, HPDF_SEEK_SET);
1524
+ if (ret != HPDF_OK)
1525
+ return ret;
1526
+
1527
+ ret += GetUINT16 (attr->stream, &attr->name_tbl.format);
1528
+ ret += GetUINT16 (attr->stream, &attr->name_tbl.count);
1529
+ ret += GetUINT16 (attr->stream, &attr->name_tbl.string_offset);
1530
+ if (ret != HPDF_OK)
1531
+ return HPDF_Error_GetCode (fontdef->error);
1532
+
1533
+ HPDF_PTRACE((" ParseName() format=%u, count=%u, string_offset=%u\n",
1534
+ attr->name_tbl.format, attr->name_tbl.count,
1535
+ attr->name_tbl.string_offset));
1536
+
1537
+ attr->name_tbl.name_records = HPDF_GetMem (fontdef->mmgr,
1538
+ sizeof (HPDF_TTF_NameRecord) * attr->name_tbl.count);
1539
+
1540
+ if (!attr->name_tbl.name_records)
1541
+ return HPDF_Error_GetCode (fontdef->error);
1542
+
1543
+ name_rec = attr->name_tbl.name_records;
1544
+
1545
+ for (i = 0; i < attr->name_tbl.count; i++) {
1546
+ ret += GetUINT16 (attr->stream, &name_rec->platform_id);
1547
+ ret += GetUINT16 (attr->stream, &name_rec->encoding_id);
1548
+ ret += GetUINT16 (attr->stream, &name_rec->language_id);
1549
+ ret += GetUINT16 (attr->stream, &name_rec->name_id);
1550
+ ret += GetUINT16 (attr->stream, &name_rec->length);
1551
+ ret += GetUINT16 (attr->stream, &name_rec->offset);
1552
+
1553
+ if (ret != HPDF_OK)
1554
+ return HPDF_Error_GetCode (fontdef->error);
1555
+
1556
+ HPDF_PTRACE((" ParseName() platformID=%u, encodingID=%d, nameID=%d\n",
1557
+ name_rec->platform_id, name_rec->encoding_id,
1558
+ name_rec->name_id));
1559
+
1560
+ if (name_rec->platform_id == 1 && name_rec->encoding_id == 0 &&
1561
+ name_rec->name_id == 6) {
1562
+ offset_id1 = tbl->offset + name_rec->offset +
1563
+ attr->name_tbl.string_offset;
1564
+ len_id1 = name_rec->length;
1565
+ }
1566
+
1567
+ if (name_rec->platform_id == 1 && name_rec->encoding_id == 0 &&
1568
+ name_rec->name_id == 2) {
1569
+ offset_id2 = tbl->offset + name_rec->offset +
1570
+ attr->name_tbl.string_offset;
1571
+ len_id2 = name_rec->length;
1572
+ }
1573
+
1574
+ if (name_rec->platform_id == 3 && name_rec->encoding_id == 1 &&
1575
+ name_rec->name_id == 6 && name_rec->language_id == 0x0409) {
1576
+ offset_id1u = tbl->offset + name_rec->offset +
1577
+ attr->name_tbl.string_offset;
1578
+ len_id1u = name_rec->length;
1579
+ }
1580
+
1581
+ if (name_rec->platform_id == 3 && name_rec->encoding_id == 1 &&
1582
+ name_rec->name_id == 2 && name_rec->language_id == 0x0409) {
1583
+ offset_id2u = tbl->offset + name_rec->offset +
1584
+ attr->name_tbl.string_offset;
1585
+ len_id2u = name_rec->length;
1586
+ }
1587
+
1588
+ name_rec++;
1589
+ }
1590
+
1591
+ if ((!offset_id1 && !offset_id1u) ||
1592
+ (!offset_id2 && !offset_id2u))
1593
+ return HPDF_SetError (fontdef->error, HPDF_TTF_INVALID_FOMAT, 0);
1594
+
1595
+ if (len_id1 == 0 && len_id1u > 0)
1596
+ len_id1 = len_id1u / 2 + len_id1u % 2;
1597
+
1598
+ if (len_id2 == 0 && len_id2u > 0)
1599
+ len_id2 = len_id2u / 2 + len_id2u % 2;
1600
+
1601
+ if (len_id1 + len_id2 + 8 > 127)
1602
+ return HPDF_SetError (fontdef->error, HPDF_TTF_INVALID_FOMAT, 0);
1603
+
1604
+ HPDF_MemSet (attr->base_font, 0, HPDF_LIMIT_MAX_NAME_LEN + 1);
1605
+
1606
+ if (offset_id1) {
1607
+ if ((ret = HPDF_Stream_Seek (attr->stream, offset_id1,
1608
+ HPDF_SEEK_SET)) != HPDF_OK)
1609
+ return ret;
1610
+
1611
+ if ((ret = HPDF_Stream_Read (attr->stream, attr->base_font, &len_id1))
1612
+ != HPDF_OK)
1613
+ return ret;
1614
+ } else {
1615
+ if ((ret = LoadUnicodeName (attr->stream, offset_id1u, len_id1u,
1616
+ attr->base_font)) != HPDF_OK)
1617
+ return ret;
1618
+ }
1619
+
1620
+ HPDF_MemSet (tmp, 0, HPDF_LIMIT_MAX_NAME_LEN + 1);
1621
+
1622
+ if (offset_id2) {
1623
+ if ((ret = HPDF_Stream_Seek (attr->stream, offset_id2, HPDF_SEEK_SET))
1624
+ != HPDF_OK)
1625
+ return ret;
1626
+
1627
+ if ((ret = HPDF_Stream_Read (attr->stream, tmp, &len_id2)) != HPDF_OK)
1628
+ return ret;
1629
+ } else {
1630
+ if ((ret = LoadUnicodeName (attr->stream, offset_id2u, len_id2u,
1631
+ tmp)) != HPDF_OK)
1632
+ return ret;
1633
+ }
1634
+
1635
+ /*
1636
+ * get "postscript name" of from a "name" table as BaseName.
1637
+ * if subfamily name is not "Regular", add subfamily name to BaseName.
1638
+ * if subfamily name includes the blank character, remove it.
1639
+ * if subfamily name is "Bold" or "Italic" or "BoldItalic", set flags
1640
+ * attribute.
1641
+ */
1642
+ if (HPDF_MemCmp (tmp, "Regular", 7) != 0) {
1643
+ char *dst = attr->base_font + len_id1;
1644
+ char *src = tmp;
1645
+ HPDF_UINT j;
1646
+
1647
+ *dst++ = ',';
1648
+
1649
+ for (j = 0; j < len_id2; j++) {
1650
+ if (*src != ' ')
1651
+ *dst++ = *src++;
1652
+
1653
+ if (dst >= attr->base_font + HPDF_LIMIT_MAX_NAME_LEN)
1654
+ break;
1655
+ }
1656
+
1657
+ *dst = 0;
1658
+
1659
+ if (HPDF_StrStr (tmp, "Bold", len_id2))
1660
+ fontdef->flags |= HPDF_FONT_FOURCE_BOLD;
1661
+ if (HPDF_StrStr (tmp, "Italic", len_id2))
1662
+ fontdef->flags |= HPDF_FONT_ITALIC;
1663
+ }
1664
+
1665
+ HPDF_MemCpy (fontdef->base_font, attr->base_font,
1666
+ HPDF_LIMIT_MAX_NAME_LEN + 1);
1667
+
1668
+ HPDF_PTRACE((" ParseName() base_font=%s\n", attr->base_font));
1669
+
1670
+ return HPDF_OK;
1671
+ }
1672
+
1673
+ static HPDF_STATUS
1674
+ ParseOS2 (HPDF_FontDef fontdef)
1675
+ {
1676
+ HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
1677
+ HPDF_TTFTable *tbl = FindTable (fontdef, "OS/2");
1678
+ HPDF_STATUS ret;
1679
+ HPDF_UINT len;
1680
+
1681
+ HPDF_PTRACE ((" ParseOS2\n"));
1682
+
1683
+ if (!tbl)
1684
+ return HPDF_SetError (fontdef->error, HPDF_TTF_MISSING_TABLE, 0);
1685
+
1686
+ ret = HPDF_Stream_Seek (attr->stream, tbl->offset + 8, HPDF_SEEK_SET);
1687
+ if (ret != HPDF_OK)
1688
+ return ret;
1689
+
1690
+ /* check whether the font is allowed to be embedded. */
1691
+ if ((ret = GetUINT16 (attr->stream, &attr->fs_type)) != HPDF_OK)
1692
+ return ret;
1693
+
1694
+ if (attr->fs_type & (0x0002 | 0x0100 | 0x0200) && attr->embedding)
1695
+ return HPDF_SetError (fontdef->error, HPDF_TTF_CANNOT_EMBEDDING_FONT,
1696
+ 0);
1697
+
1698
+ if ((ret = HPDF_Stream_Seek (attr->stream, tbl->offset + 20, HPDF_SEEK_SET))
1699
+ != HPDF_OK)
1700
+ return ret;
1701
+
1702
+ len = 12;
1703
+ if ((ret = HPDF_Stream_Read (attr->stream, attr->panose, &len)) != HPDF_OK)
1704
+ return ret;
1705
+
1706
+ HPDF_PTRACE((" ParseOS2 PANOSE=%u-%u "
1707
+ "%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n",
1708
+ attr->panose[0], attr->panose[1], attr->panose[2], attr->panose[3],
1709
+ attr->panose[4], attr->panose[5], attr->panose[6], attr->panose[7],
1710
+ attr->panose[8], attr->panose[9], attr->panose[10], attr->panose[11]));
1711
+
1712
+ if (attr->panose[0] == 1 || attr->panose[0] == 4)
1713
+ fontdef->flags = fontdef->flags | HPDF_FONT_SERIF;
1714
+
1715
+ /* get ulCodePageRange1 */
1716
+ if ((ret = HPDF_Stream_Seek (attr->stream, 78, HPDF_SEEK_CUR)) != HPDF_OK)
1717
+ return ret;
1718
+
1719
+ if ((ret = GetUINT32 (attr->stream, &attr->code_page_range1)) != HPDF_OK)
1720
+ return ret;
1721
+
1722
+ if ((ret = GetUINT32 (attr->stream, &attr->code_page_range2)) != HPDF_OK)
1723
+ return ret;
1724
+
1725
+ HPDF_PTRACE((" ParseOS2 CodePageRange1=%08X CodePageRange2=%08X\n",
1726
+ (HPDF_UINT)attr->code_page_range1,
1727
+ (HPDF_UINT)attr->code_page_range2));
1728
+
1729
+ return HPDF_OK;
1730
+ }
1731
+
1732
+
1733
+ static HPDF_STATUS
1734
+ RecreateGLYF (HPDF_FontDef fontdef,
1735
+ HPDF_UINT32 *new_offsets,
1736
+ HPDF_Stream stream)
1737
+ {
1738
+ HPDF_UINT32 save_offset = 0;
1739
+ HPDF_UINT32 start_offset = stream->size;
1740
+ HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
1741
+ HPDF_STATUS ret;
1742
+ HPDF_INT i;
1743
+
1744
+ HPDF_PTRACE ((" RecreateGLYF\n"));
1745
+
1746
+ for (i = 0; i < attr->num_glyphs; i++) {
1747
+ HPDF_BYTE buf[HPDF_STREAM_BUF_SIZ];
1748
+
1749
+ if (attr->glyph_tbl.flgs[i] == 1) {
1750
+ HPDF_UINT offset = attr->glyph_tbl.offsets[i];
1751
+ HPDF_UINT len = attr->glyph_tbl.offsets[i + 1] - offset;
1752
+
1753
+ new_offsets[i] = stream->size - start_offset;
1754
+ if (attr->header.index_to_loc_format == 0) {
1755
+ new_offsets[i] /= 2;
1756
+ len *= 2;
1757
+ }
1758
+
1759
+ HPDF_PTRACE((" RecreateGLYF[%u] move from [%u] to [%u]\n", i,
1760
+ (HPDF_UINT)attr->glyph_tbl.base_offset + offset,
1761
+ (HPDF_UINT)new_offsets[i]));
1762
+
1763
+ if (attr->header.index_to_loc_format == 0)
1764
+ offset *= 2;
1765
+
1766
+ offset += attr->glyph_tbl.base_offset;
1767
+
1768
+ if ((ret = HPDF_Stream_Seek (attr->stream, offset, HPDF_SEEK_SET))
1769
+ != HPDF_OK)
1770
+ return ret;
1771
+
1772
+ while (len > 0) {
1773
+ HPDF_UINT tmp_len =
1774
+ (len > HPDF_STREAM_BUF_SIZ) ? HPDF_STREAM_BUF_SIZ : len;
1775
+
1776
+ HPDF_MemSet (buf, 0, tmp_len);
1777
+
1778
+ if ((ret = HPDF_Stream_Read (attr->stream, buf, &tmp_len))
1779
+ != HPDF_OK)
1780
+ return ret;
1781
+
1782
+ if ((ret = HPDF_Stream_Write (stream, buf, tmp_len)) !=
1783
+ HPDF_OK)
1784
+ return ret;
1785
+
1786
+ len -= tmp_len;
1787
+ }
1788
+
1789
+ save_offset = stream->size - start_offset;
1790
+ if (attr->header.index_to_loc_format == 0)
1791
+ save_offset /= 2;
1792
+ } else {
1793
+ new_offsets[i] = save_offset;
1794
+ }
1795
+ }
1796
+
1797
+ new_offsets[attr->num_glyphs] = save_offset;
1798
+
1799
+ #ifdef DEBUG
1800
+ for (i = 0; i <= attr->num_glyphs; i++) {
1801
+ HPDF_PTRACE((" RecreateGLYF[%u] offset=%u\n", i, new_offsets[i]));
1802
+ }
1803
+ #endif
1804
+
1805
+ return HPDF_OK;
1806
+ }
1807
+
1808
+ static HPDF_STATUS
1809
+ RecreateName (HPDF_FontDef fontdef,
1810
+ HPDF_Stream stream)
1811
+ {
1812
+ HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
1813
+ HPDF_TTFTable *tbl = FindTable (fontdef, "name");
1814
+ HPDF_STATUS ret = HPDF_OK;
1815
+ HPDF_UINT i;
1816
+ HPDF_TTF_NameRecord *name_rec;
1817
+ HPDF_Stream tmp_stream = HPDF_MemStream_New (fontdef->mmgr,
1818
+ HPDF_STREAM_BUF_SIZ);
1819
+
1820
+ HPDF_PTRACE ((" RecreateName\n"));
1821
+
1822
+ if (!tmp_stream)
1823
+ return HPDF_Error_GetCode (fontdef->error);
1824
+
1825
+ ret += WriteUINT16 (stream, attr->name_tbl.format);
1826
+ ret += WriteUINT16 (stream, attr->name_tbl.count);
1827
+ ret += WriteUINT16 (stream, attr->name_tbl.string_offset);
1828
+
1829
+ if (ret != HPDF_OK) {
1830
+ HPDF_Stream_Free (tmp_stream);
1831
+ return HPDF_Error_GetCode (fontdef->error);
1832
+ }
1833
+
1834
+ name_rec = attr->name_tbl.name_records;
1835
+ for (i = 0; i < attr->name_tbl.count; i++) {
1836
+ HPDF_UINT name_len = name_rec->length;
1837
+ HPDF_BYTE buf[HPDF_STREAM_BUF_SIZ];
1838
+ HPDF_UINT tmp_len = name_len;
1839
+ HPDF_UINT offset = tbl->offset + attr->name_tbl.string_offset +
1840
+ name_rec->offset;
1841
+ HPDF_UINT rec_offset = tmp_stream->size;
1842
+
1843
+ /* add suffix to font-name. */
1844
+ if (name_rec->name_id == 1 || name_rec->name_id == 4) {
1845
+ if (name_rec->platform_id == 0 || name_rec->platform_id == 3) {
1846
+ ret += HPDF_Stream_Write (tmp_stream, attr->tag_name2,
1847
+ sizeof(attr->tag_name2));
1848
+ name_len += sizeof(attr->tag_name2);
1849
+ } else {
1850
+ ret += HPDF_Stream_Write (tmp_stream, attr->tag_name,
1851
+ sizeof(attr->tag_name));
1852
+ name_len += sizeof(attr->tag_name);
1853
+ }
1854
+ }
1855
+
1856
+ ret += WriteUINT16 (stream, name_rec->platform_id);
1857
+ ret += WriteUINT16 (stream, name_rec->encoding_id);
1858
+ ret += WriteUINT16 (stream, name_rec->language_id);
1859
+ ret += WriteUINT16 (stream, name_rec->name_id);
1860
+ ret += WriteUINT16 (stream, (HPDF_UINT16)name_len);
1861
+ ret += WriteUINT16 (stream, (HPDF_UINT16)rec_offset);
1862
+
1863
+ ret += HPDF_Stream_Seek (attr->stream, offset, HPDF_SEEK_SET);
1864
+
1865
+ if (ret != HPDF_OK) {
1866
+ HPDF_Stream_Free (tmp_stream);
1867
+ return HPDF_Error_GetCode (fontdef->error);
1868
+ }
1869
+
1870
+ while (tmp_len > 0) {
1871
+ HPDF_UINT len = (tmp_len > HPDF_STREAM_BUF_SIZ) ?
1872
+ HPDF_STREAM_BUF_SIZ : tmp_len;
1873
+
1874
+ if ((ret = HPDF_Stream_Read (attr->stream, buf, &len)) != HPDF_OK) {
1875
+ HPDF_Stream_Free (tmp_stream);
1876
+ return ret;
1877
+ }
1878
+
1879
+ if ((ret = HPDF_Stream_Write (tmp_stream, buf, len)) != HPDF_OK) {
1880
+ HPDF_Stream_Free (tmp_stream);
1881
+ return ret;
1882
+ }
1883
+
1884
+ tmp_len -= len;
1885
+ }
1886
+
1887
+ HPDF_PTRACE((" RecreateNAME name_rec[%u] platform_id=%u "
1888
+ "encoding_id=%u language_id=%u name_rec->name_id=%u "
1889
+ "length=%u offset=%u\n", i, name_rec->platform_id,
1890
+ name_rec->encoding_id, name_rec->language_id,
1891
+ name_rec->name_id, name_len, rec_offset));
1892
+
1893
+ name_rec++;
1894
+ }
1895
+
1896
+ ret = HPDF_Stream_WriteToStream (tmp_stream, stream,
1897
+ HPDF_STREAM_FILTER_NONE, NULL);
1898
+
1899
+ HPDF_Stream_Free (tmp_stream);
1900
+
1901
+ return ret;
1902
+ }
1903
+
1904
+
1905
+ static HPDF_STATUS
1906
+ WriteHeader (HPDF_FontDef fontdef,
1907
+ HPDF_Stream stream,
1908
+ HPDF_UINT32 *check_sum_ptr)
1909
+ {
1910
+ HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
1911
+ HPDF_STATUS ret = HPDF_OK;
1912
+
1913
+ HPDF_PTRACE ((" WriteHeader\n"));
1914
+
1915
+ ret += HPDF_Stream_Write (stream, attr->header.version_number, 4);
1916
+ ret += WriteUINT32 (stream, attr->header.font_revision);
1917
+
1918
+ /* save the address of checkSumAdjustment.
1919
+ * the value is rewrite to computed value after new check-sum-value is
1920
+ * generated.
1921
+ */
1922
+ *check_sum_ptr = stream->size;
1923
+
1924
+ ret += WriteUINT32 (stream, 0);
1925
+ ret += WriteUINT32 (stream, attr->header.magic_number);
1926
+ ret += WriteUINT16 (stream, attr->header.flags);
1927
+ ret += WriteUINT16 (stream, attr->header.units_per_em);
1928
+ ret += HPDF_Stream_Write (stream, attr->header.created, 8);
1929
+ ret += HPDF_Stream_Write (stream, attr->header.modified, 8);
1930
+ ret += WriteINT16 (stream, attr->header.x_min);
1931
+ ret += WriteINT16 (stream, attr->header.y_min);
1932
+ ret += WriteINT16 (stream, attr->header.x_max);
1933
+ ret += WriteINT16 (stream, attr->header.y_max);
1934
+ ret += WriteUINT16 (stream, attr->header.mac_style);
1935
+ ret += WriteUINT16 (stream, attr->header.lowest_rec_ppem);
1936
+ ret += WriteINT16 (stream, attr->header.font_direction_hint);
1937
+ ret += WriteINT16 (stream, attr->header.index_to_loc_format);
1938
+ ret += WriteINT16 (stream, attr->header.glyph_data_format);
1939
+
1940
+ if (ret != HPDF_OK)
1941
+ return HPDF_Error_GetCode (fontdef->error);
1942
+
1943
+ return HPDF_OK;
1944
+ }
1945
+
1946
+
1947
+ HPDF_STATUS
1948
+ HPDF_TTFontDef_SaveFontData (HPDF_FontDef fontdef,
1949
+ HPDF_Stream stream)
1950
+ {
1951
+ HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
1952
+ HPDF_TTFTable tmp_tbl[HPDF_REQUIRED_TAGS_COUNT];
1953
+ HPDF_Stream tmp_stream;
1954
+ HPDF_UINT32 *new_offsets;
1955
+ HPDF_UINT i;
1956
+ HPDF_UINT32 check_sum_ptr;
1957
+ HPDF_STATUS ret;
1958
+ HPDF_UINT32 offset_base;
1959
+ HPDF_UINT32 tmp_check_sum = 0xB1B0AFBA;
1960
+
1961
+ HPDF_PTRACE ((" SaveFontData\n"));
1962
+
1963
+ ret = WriteUINT32 (stream, attr->offset_tbl.sfnt_version);
1964
+ ret += WriteUINT16 (stream, HPDF_REQUIRED_TAGS_COUNT);
1965
+ ret += WriteUINT16 (stream, attr->offset_tbl.search_range);
1966
+ ret += WriteUINT16 (stream, attr->offset_tbl.entry_selector);
1967
+ ret += WriteUINT16 (stream, attr->offset_tbl.range_shift);
1968
+
1969
+ if (ret != HPDF_OK)
1970
+ return HPDF_Error_GetCode (fontdef->error);
1971
+
1972
+ tmp_stream = HPDF_MemStream_New (fontdef->mmgr, HPDF_STREAM_BUF_SIZ);
1973
+ if (!tmp_stream)
1974
+ return HPDF_Error_GetCode (fontdef->error);
1975
+
1976
+ offset_base = 12 + 16 * HPDF_REQUIRED_TAGS_COUNT;
1977
+
1978
+ new_offsets = HPDF_GetMem (fontdef->mmgr,
1979
+ sizeof (HPDF_UINT32) * (attr->num_glyphs + 1));
1980
+ if (!new_offsets) {
1981
+ HPDF_Stream_Free (tmp_stream);
1982
+ return HPDF_Error_GetCode (fontdef->error);
1983
+ }
1984
+
1985
+ for (i = 0; i < HPDF_REQUIRED_TAGS_COUNT; i++) {
1986
+ HPDF_TTFTable *tbl = FindTable (fontdef, REQUIRED_TAGS[i]);
1987
+ HPDF_UINT32 length;
1988
+ HPDF_UINT new_offset;
1989
+ HPDF_UINT32 *poffset;
1990
+ HPDF_UINT32 value;
1991
+
1992
+ if (!tbl) {
1993
+ ret = HPDF_SetError (fontdef->error, HPDF_TTF_MISSING_TABLE, i);
1994
+ goto Exit;
1995
+ }
1996
+
1997
+ ret = HPDF_Stream_Seek (attr->stream, tbl->offset, HPDF_SEEK_SET);
1998
+ if (ret != HPDF_OK)
1999
+ goto Exit;
2000
+
2001
+ length = tbl->length;
2002
+ new_offset = tmp_stream->size;
2003
+
2004
+ if (HPDF_MemCmp (tbl->tag, "head", 4) == 0) {
2005
+ ret = WriteHeader (fontdef, tmp_stream, &check_sum_ptr);
2006
+ } else if (HPDF_MemCmp (tbl->tag, "glyf", 4) == 0) {
2007
+ ret = RecreateGLYF (fontdef, new_offsets, tmp_stream);
2008
+ } else if (HPDF_MemCmp (tbl->tag, "loca", 4) == 0) {
2009
+ HPDF_UINT j;
2010
+
2011
+ HPDF_MemSet (&value, 0, 4);
2012
+ poffset = new_offsets;
2013
+
2014
+ if (attr->header.index_to_loc_format == 0) {
2015
+ for (j = 0; j <= attr->num_glyphs; j++) {
2016
+ ret += WriteUINT16 (tmp_stream, (HPDF_UINT16)*poffset);
2017
+ poffset++;
2018
+ }
2019
+ } else {
2020
+ for (j = 0; j <= attr->num_glyphs; j++) {
2021
+ ret += WriteUINT32 (tmp_stream, *poffset);
2022
+ poffset++;
2023
+ }
2024
+ }
2025
+ } else if (HPDF_MemCmp (tbl->tag, "name", 4) == 0) {
2026
+ ret = RecreateName (fontdef, tmp_stream);
2027
+ } else {
2028
+ HPDF_UINT size = 4;
2029
+
2030
+ while (length > 4) {
2031
+ value = 0;
2032
+ size = 4;
2033
+ ret = HPDF_Stream_Read (attr->stream, (HPDF_BYTE *)&value, &size);
2034
+ ret += HPDF_Stream_Write (tmp_stream, (HPDF_BYTE *)&value, size);
2035
+ length -= 4;
2036
+ }
2037
+
2038
+ value = 0;
2039
+ size = length;
2040
+ ret += HPDF_Stream_Read (attr->stream, (HPDF_BYTE *)&value, &size);
2041
+ ret += HPDF_Stream_Write (tmp_stream, (HPDF_BYTE *)&value, size);
2042
+ }
2043
+
2044
+ tmp_tbl[i].offset = new_offset;
2045
+ tmp_tbl[i].length = tmp_stream->size - new_offset;
2046
+
2047
+ if (ret != HPDF_OK)
2048
+ goto Exit;
2049
+ }
2050
+
2051
+ /* recalcurate checksum */
2052
+ for (i = 0; i < HPDF_REQUIRED_TAGS_COUNT; i++) {
2053
+ HPDF_TTFTable tbl = tmp_tbl[i];
2054
+ HPDF_UINT32 buf;
2055
+ HPDF_UINT length = tbl.length;
2056
+
2057
+ HPDF_PTRACE((" SaveFontData() tag[%s] length=%u\n",
2058
+ REQUIRED_TAGS[i], length));
2059
+
2060
+ if ((ret = HPDF_Stream_Seek (tmp_stream, tbl.offset, HPDF_SEEK_SET))
2061
+ != HPDF_OK)
2062
+ break;
2063
+
2064
+ tbl.check_sum = 0;
2065
+ while (length > 0) {
2066
+ HPDF_UINT rlen = (length > 4) ? 4 : length;
2067
+ buf = 0;
2068
+ if ((ret = HPDF_Stream_Read (tmp_stream, (HPDF_BYTE *)&buf, &rlen))
2069
+ != HPDF_OK)
2070
+ break;
2071
+
2072
+ UINT32Swap (&buf);
2073
+ tbl.check_sum += buf;
2074
+ length -= rlen;
2075
+ }
2076
+
2077
+ if (ret != HPDF_OK)
2078
+ break;
2079
+
2080
+ HPDF_PTRACE((" SaveFontData tag[%s] check-sum=%u offset=%u\n",
2081
+ REQUIRED_TAGS[i], (HPDF_UINT)tbl.check_sum,
2082
+ (HPDF_UINT)tbl.offset));
2083
+
2084
+ ret += HPDF_Stream_Write (stream, REQUIRED_TAGS[i], 4);
2085
+ ret += WriteUINT32 (stream, tbl.check_sum);
2086
+ tbl.offset += offset_base;
2087
+ ret += WriteUINT32 (stream, tbl.offset);
2088
+ ret += WriteUINT32 (stream, tbl.length);
2089
+
2090
+ if (ret != HPDF_OK)
2091
+ break;
2092
+ }
2093
+
2094
+ if (ret != HPDF_OK)
2095
+ goto Exit;
2096
+
2097
+ /* calucurate checkSumAdjustment.*/
2098
+ ret = HPDF_Stream_Seek (tmp_stream, 0, HPDF_SEEK_SET);
2099
+ if (ret != HPDF_OK)
2100
+ goto Exit;
2101
+
2102
+ for (;;) {
2103
+ HPDF_UINT32 buf;
2104
+ HPDF_UINT siz = sizeof(buf);
2105
+
2106
+ ret = HPDF_Stream_Read (tmp_stream, (HPDF_BYTE *)&buf, &siz);
2107
+ if (ret != HPDF_OK || siz <= 0) {
2108
+ if (ret == HPDF_STREAM_EOF)
2109
+ ret = HPDF_OK;
2110
+ break;
2111
+ }
2112
+
2113
+ UINT32Swap (&buf);
2114
+ tmp_check_sum -= buf;
2115
+ }
2116
+
2117
+ if (ret != HPDF_OK)
2118
+ goto Exit;
2119
+
2120
+ HPDF_PTRACE((" SaveFontData new checkSumAdjustment=%u\n",
2121
+ (HPDF_UINT)tmp_check_sum));
2122
+
2123
+ UINT32Swap (&tmp_check_sum);
2124
+
2125
+ ret = HPDF_Stream_Seek (tmp_stream, check_sum_ptr, HPDF_SEEK_SET);
2126
+ if (ret == HPDF_OK) {
2127
+ ret = HPDF_MemStream_Rewrite (tmp_stream, (HPDF_BYTE *)&tmp_check_sum,
2128
+ 4);
2129
+ }
2130
+
2131
+ if (ret != HPDF_OK)
2132
+ goto Exit;
2133
+
2134
+ attr->length1 = tmp_stream->size + offset_base;
2135
+ ret = HPDF_Stream_WriteToStream (tmp_stream, stream, 0, NULL);
2136
+
2137
+ goto Exit;
2138
+
2139
+ Exit:
2140
+ HPDF_FreeMem (fontdef->mmgr, new_offsets);
2141
+ HPDF_Stream_Free (tmp_stream);
2142
+ return ret;
2143
+ }
2144
+
2145
+ void
2146
+ HPDF_TTFontDef_SetTagName (HPDF_FontDef fontdef,
2147
+ char *tag)
2148
+ {
2149
+ HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
2150
+ char buf[HPDF_LIMIT_MAX_NAME_LEN + 1];
2151
+ HPDF_UINT i;
2152
+
2153
+ HPDF_PTRACE ((" HPDF_TTFontDef_SetTagName\n"));
2154
+
2155
+ if (HPDF_StrLen (tag, HPDF_LIMIT_MAX_NAME_LEN) != HPDF_TTF_FONT_TAG_LEN)
2156
+ return;
2157
+
2158
+ HPDF_MemCpy (attr->tag_name, tag, HPDF_TTF_FONT_TAG_LEN);
2159
+ attr->tag_name[HPDF_TTF_FONT_TAG_LEN] = '+';
2160
+
2161
+ for (i = 0; i < HPDF_TTF_FONT_TAG_LEN + 1; i++) {
2162
+ attr->tag_name2[i * 2] = 0x00;
2163
+ attr->tag_name2[i * 2 + 1] = attr->tag_name[i];
2164
+ }
2165
+
2166
+ HPDF_MemSet (buf, 0, HPDF_LIMIT_MAX_NAME_LEN + 1);
2167
+ HPDF_MemCpy (buf, attr->tag_name, HPDF_TTF_FONT_TAG_LEN + 1);
2168
+ HPDF_MemCpy (buf + HPDF_TTF_FONT_TAG_LEN + 1, fontdef->base_font,
2169
+ HPDF_LIMIT_MAX_NAME_LEN - HPDF_TTF_FONT_TAG_LEN - 1);
2170
+
2171
+ HPDF_MemCpy (attr->base_font, buf, HPDF_LIMIT_MAX_NAME_LEN + 1);
2172
+ }
2173
+
2174
+ /*
2175
+ int
2176
+ PdfTTFontDef::GetNameAttr(unsigned char* buf, HPDF_UINT name_id,
2177
+ HPDF_UINT platform_id, HPDF_UINT lang_id, HPDF_UINT max_len)
2178
+
2179
+
2180
+ */
2181
+
2182
+ static HPDF_TTFTable*
2183
+ FindTable (HPDF_FontDef fontdef,
2184
+ const char *tag)
2185
+ {
2186
+ HPDF_TTFontDefAttr attr = (HPDF_TTFontDefAttr)fontdef->attr;
2187
+ HPDF_TTFTable* tbl = attr->offset_tbl.table;
2188
+ HPDF_UINT i;
2189
+
2190
+ for (i = 0; i < attr->offset_tbl.num_tables; i++, tbl++) {
2191
+ if (HPDF_MemCmp (tbl->tag, tag, 4) == 0) {
2192
+ HPDF_PTRACE((" FindTable find table[%c%c%c%c]\n",
2193
+ tbl->tag[0], tbl->tag[1], tbl->tag[2], tbl->tag[3]));
2194
+ return tbl;
2195
+ }
2196
+ }
2197
+
2198
+ return NULL;
2199
+ }
2200
+
2201
+ static void
2202
+ UINT32Swap (HPDF_UINT32 *value)
2203
+ {
2204
+ HPDF_BYTE b[4];
2205
+
2206
+ HPDF_MemCpy (b, (HPDF_BYTE *)value, 4);
2207
+ *value = (HPDF_UINT32)((HPDF_UINT32)b[0] << 24 |
2208
+ (HPDF_UINT32)b[1] << 16 |
2209
+ (HPDF_UINT32)b[2] << 8 |
2210
+ (HPDF_UINT32)b[3]);
2211
+ }
2212
+
2213
+ static void
2214
+ UINT16Swap (HPDF_UINT16 *value)
2215
+ {
2216
+ HPDF_BYTE b[2];
2217
+
2218
+ HPDF_MemCpy (b, (HPDF_BYTE *)value, 2);
2219
+ *value = (HPDF_UINT16)((HPDF_UINT16)b[0] << 8 | (HPDF_UINT16)b[1]);
2220
+ }
2221
+
2222
+ static void
2223
+ INT16Swap (HPDF_INT16 *value)
2224
+ {
2225
+ HPDF_BYTE b[2];
2226
+
2227
+ HPDF_MemCpy (b, (HPDF_BYTE *)value, 2);
2228
+ *value = (HPDF_INT16)((HPDF_INT16)b[0] << 8 | (HPDF_INT16)b[1]);
2229
+ }
2230
+