hpdf 2.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+